//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Implements serialization for Statements and Expressions.
///
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTRecordWriter.h"
#include "llvm/Bitstream/BitstreamWriter.h"
using namespace clang;

//===----------------------------------------------------------------------===//
// Statement/expression serialization
//===----------------------------------------------------------------------===//

namespace clang {

  class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
    ASTWriter &Writer;
    ASTRecordWriter Record;

    serialization::StmtCode Code;
    unsigned AbbrevToUse;

    /// A helper that can help us to write a packed bit across function
    /// calls. For example, we may write separate bits in separate functions:
    ///
    ///  void VisitA(A* a) {
    ///     Record.push_back(a->isSomething());
    ///  }
    ///
    ///  void Visitb(B *b) {
    ///     VisitA(b);
    ///     Record.push_back(b->isAnother());
    ///  }
    ///
    /// In such cases, it'll be better if we can pack these 2 bits. We achieve
    /// this by writing a zero value in `VisitA` and recorded that first and add
    /// the new bit to the recorded value.
    class PakedBitsWriter {
    public:
      PakedBitsWriter(ASTRecordWriter &Record) : RecordRef(Record) {}
      ~PakedBitsWriter() { assert(!CurrentIndex); }

      void addBit(bool Value) {
        assert(CurrentIndex && "Writing Bits without recording first!");
        PackingBits.addBit(Value);
      }
      void addBits(uint32_t Value, uint32_t BitsWidth) {
        assert(CurrentIndex && "Writing Bits without recording first!");
        PackingBits.addBits(Value, BitsWidth);
      }

      void writeBits() {
        if (!CurrentIndex)
          return;

        RecordRef[*CurrentIndex] = (uint32_t)PackingBits;
        CurrentIndex = std::nullopt;
        PackingBits.reset(0);
      }

      void updateBits() {
        writeBits();

        CurrentIndex = RecordRef.size();
        RecordRef.push_back(0);
      }

    private:
      BitsPacker PackingBits;
      ASTRecordWriter &RecordRef;
      std::optional<unsigned> CurrentIndex;
    };

    PakedBitsWriter CurrentPackingBits;

  public:
    ASTStmtWriter(ASTContext &Context, ASTWriter &Writer,
                  ASTWriter::RecordData &Record)
        : Writer(Writer), Record(Context, Writer, Record),
          Code(serialization::STMT_NULL_PTR), AbbrevToUse(0),
          CurrentPackingBits(this->Record) {}

    ASTStmtWriter(const ASTStmtWriter&) = delete;
    ASTStmtWriter &operator=(const ASTStmtWriter &) = delete;

    uint64_t Emit() {
      CurrentPackingBits.writeBits();
      assert(Code != serialization::STMT_NULL_PTR &&
             "unhandled sub-statement writing AST file");
      return Record.EmitStmt(Code, AbbrevToUse);
    }

    void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
                                  const TemplateArgumentLoc *Args);

    void VisitStmt(Stmt *S);
#define STMT(Type, Base) \
    void Visit##Type(Type *);
#include "clang/AST/StmtNodes.inc"
  };
}

void ASTStmtWriter::AddTemplateKWAndArgsInfo(
    const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
  Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
  Record.AddSourceLocation(ArgInfo.LAngleLoc);
  Record.AddSourceLocation(ArgInfo.RAngleLoc);
  for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
    Record.AddTemplateArgumentLoc(Args[i]);
}

void ASTStmtWriter::VisitStmt(Stmt *S) {
}

void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getSemiLoc());
  Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
  Code = serialization::STMT_NULL;
}

void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
  VisitStmt(S);

  Record.push_back(S->size());
  Record.push_back(S->hasStoredFPFeatures());

  for (auto *CS : S->body())
    Record.AddStmt(CS);
  if (S->hasStoredFPFeatures())
    Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
  Record.AddSourceLocation(S->getLBracLoc());
  Record.AddSourceLocation(S->getRBracLoc());

  if (!S->hasStoredFPFeatures())
    AbbrevToUse = Writer.getCompoundStmtAbbrev();

  Code = serialization::STMT_COMPOUND;
}

void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
  VisitStmt(S);
  Record.push_back(Writer.getSwitchCaseID(S));
  Record.AddSourceLocation(S->getKeywordLoc());
  Record.AddSourceLocation(S->getColonLoc());
}

void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
  VisitSwitchCase(S);
  Record.push_back(S->caseStmtIsGNURange());
  Record.AddStmt(S->getLHS());
  Record.AddStmt(S->getSubStmt());
  if (S->caseStmtIsGNURange()) {
    Record.AddStmt(S->getRHS());
    Record.AddSourceLocation(S->getEllipsisLoc());
  }
  Code = serialization::STMT_CASE;
}

void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
  VisitSwitchCase(S);
  Record.AddStmt(S->getSubStmt());
  Code = serialization::STMT_DEFAULT;
}

void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
  VisitStmt(S);
  Record.push_back(S->isSideEntry());
  Record.AddDeclRef(S->getDecl());
  Record.AddStmt(S->getSubStmt());
  Record.AddSourceLocation(S->getIdentLoc());
  Code = serialization::STMT_LABEL;
}

void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
  VisitStmt(S);
  Record.push_back(S->getAttrs().size());
  Record.AddAttributes(S->getAttrs());
  Record.AddStmt(S->getSubStmt());
  Record.AddSourceLocation(S->getAttrLoc());
  Code = serialization::STMT_ATTRIBUTED;
}

void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
  VisitStmt(S);

  bool HasElse = S->getElse() != nullptr;
  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
  bool HasInit = S->getInit() != nullptr;

  CurrentPackingBits.updateBits();

  CurrentPackingBits.addBit(HasElse);
  CurrentPackingBits.addBit(HasVar);
  CurrentPackingBits.addBit(HasInit);
  Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
  Record.AddStmt(S->getCond());
  Record.AddStmt(S->getThen());
  if (HasElse)
    Record.AddStmt(S->getElse());
  if (HasVar)
    Record.AddStmt(S->getConditionVariableDeclStmt());
  if (HasInit)
    Record.AddStmt(S->getInit());

  Record.AddSourceLocation(S->getIfLoc());
  Record.AddSourceLocation(S->getLParenLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  if (HasElse)
    Record.AddSourceLocation(S->getElseLoc());

  Code = serialization::STMT_IF;
}

void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
  VisitStmt(S);

  bool HasInit = S->getInit() != nullptr;
  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
  Record.push_back(HasInit);
  Record.push_back(HasVar);
  Record.push_back(S->isAllEnumCasesCovered());

  Record.AddStmt(S->getCond());
  Record.AddStmt(S->getBody());
  if (HasInit)
    Record.AddStmt(S->getInit());
  if (HasVar)
    Record.AddStmt(S->getConditionVariableDeclStmt());

  Record.AddSourceLocation(S->getSwitchLoc());
  Record.AddSourceLocation(S->getLParenLoc());
  Record.AddSourceLocation(S->getRParenLoc());

  for (SwitchCase *SC = S->getSwitchCaseList(); SC;
       SC = SC->getNextSwitchCase())
    Record.push_back(Writer.RecordSwitchCaseID(SC));
  Code = serialization::STMT_SWITCH;
}

void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
  VisitStmt(S);

  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
  Record.push_back(HasVar);

  Record.AddStmt(S->getCond());
  Record.AddStmt(S->getBody());
  if (HasVar)
    Record.AddStmt(S->getConditionVariableDeclStmt());

  Record.AddSourceLocation(S->getWhileLoc());
  Record.AddSourceLocation(S->getLParenLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  Code = serialization::STMT_WHILE;
}

void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
  VisitStmt(S);
  Record.AddStmt(S->getCond());
  Record.AddStmt(S->getBody());
  Record.AddSourceLocation(S->getDoLoc());
  Record.AddSourceLocation(S->getWhileLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  Code = serialization::STMT_DO;
}

void ASTStmtWriter::VisitForStmt(ForStmt *S) {
  VisitStmt(S);
  Record.AddStmt(S->getInit());
  Record.AddStmt(S->getCond());
  Record.AddStmt(S->getConditionVariableDeclStmt());
  Record.AddStmt(S->getInc());
  Record.AddStmt(S->getBody());
  Record.AddSourceLocation(S->getForLoc());
  Record.AddSourceLocation(S->getLParenLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  Code = serialization::STMT_FOR;
}

void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
  VisitStmt(S);
  Record.AddDeclRef(S->getLabel());
  Record.AddSourceLocation(S->getGotoLoc());
  Record.AddSourceLocation(S->getLabelLoc());
  Code = serialization::STMT_GOTO;
}

void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getGotoLoc());
  Record.AddSourceLocation(S->getStarLoc());
  Record.AddStmt(S->getTarget());
  Code = serialization::STMT_INDIRECT_GOTO;
}

void ASTStmtWriter::VisitLoopControlStmt(LoopControlStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getKwLoc());
  Record.push_back(S->hasLabelTarget());
  if (S->hasLabelTarget()) {
    Record.AddDeclRef(S->getLabelDecl());
    Record.AddSourceLocation(S->getLabelLoc());
  }
}

void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
  VisitLoopControlStmt(S);
  Code = serialization::STMT_CONTINUE;
}

void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
  VisitLoopControlStmt(S);
  Code = serialization::STMT_BREAK;
}

void ASTStmtWriter::VisitDeferStmt(DeferStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getDeferLoc());
  Record.AddStmt(S->getBody());
  Code = serialization::STMT_DEFER;
}

void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
  VisitStmt(S);

  bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
  Record.push_back(HasNRVOCandidate);

  Record.AddStmt(S->getRetValue());
  if (HasNRVOCandidate)
    Record.AddDeclRef(S->getNRVOCandidate());

  Record.AddSourceLocation(S->getReturnLoc());
  Code = serialization::STMT_RETURN;
}

void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getBeginLoc());
  Record.AddSourceLocation(S->getEndLoc());
  DeclGroupRef DG = S->getDeclGroup();
  for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
    Record.AddDeclRef(*D);
  Code = serialization::STMT_DECL;
}

void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
  VisitStmt(S);
  Record.push_back(S->getNumOutputs());
  Record.push_back(S->getNumInputs());
  Record.push_back(S->getNumClobbers());
  Record.AddSourceLocation(S->getAsmLoc());
  Record.push_back(S->isVolatile());
  Record.push_back(S->isSimple());
}

void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
  VisitAsmStmt(S);
  Record.push_back(S->getNumLabels());
  Record.AddSourceLocation(S->getRParenLoc());
  Record.AddStmt(S->getAsmStringExpr());

  // Outputs
  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
    Record.AddIdentifierRef(S->getOutputIdentifier(I));
    Record.AddStmt(S->getOutputConstraintExpr(I));
    Record.AddStmt(S->getOutputExpr(I));
  }

  // Inputs
  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
    Record.AddIdentifierRef(S->getInputIdentifier(I));
    Record.AddStmt(S->getInputConstraintExpr(I));
    Record.AddStmt(S->getInputExpr(I));
  }

  // Clobbers
  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
    Record.AddStmt(S->getClobberExpr(I));

  // Labels
  for (unsigned I = 0, N = S->getNumLabels(); I != N; ++I) {
    Record.AddIdentifierRef(S->getLabelIdentifier(I));
    Record.AddStmt(S->getLabelExpr(I));
  }

  Code = serialization::STMT_GCCASM;
}

void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
  VisitAsmStmt(S);
  Record.AddSourceLocation(S->getLBraceLoc());
  Record.AddSourceLocation(S->getEndLoc());
  Record.push_back(S->getNumAsmToks());
  Record.AddString(S->getAsmString());

  // Tokens
  for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
    // FIXME: Move this to ASTRecordWriter?
    Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
  }

  // Clobbers
  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
    Record.AddString(S->getClobber(I));
  }

  // Outputs
  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
    Record.AddStmt(S->getOutputExpr(I));
    Record.AddString(S->getOutputConstraint(I));
  }

  // Inputs
  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
    Record.AddStmt(S->getInputExpr(I));
    Record.AddString(S->getInputConstraint(I));
  }

  Code = serialization::STMT_MSASM;
}

void ASTStmtWriter::VisitCoroutineBodyStmt(CoroutineBodyStmt *CoroStmt) {
  VisitStmt(CoroStmt);
  Record.push_back(CoroStmt->getParamMoves().size());
  for (Stmt *S : CoroStmt->children())
    Record.AddStmt(S);
  Code = serialization::STMT_COROUTINE_BODY;
}

void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getKeywordLoc());
  Record.AddStmt(S->getOperand());
  Record.AddStmt(S->getPromiseCall());
  Record.push_back(S->isImplicit());
  Code = serialization::STMT_CORETURN;
}

void ASTStmtWriter::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getKeywordLoc());
  for (Stmt *S : E->children())
    Record.AddStmt(S);
  Record.AddStmt(E->getOpaqueValue());
}

void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
  VisitCoroutineSuspendExpr(E);
  Record.push_back(E->isImplicit());
  Code = serialization::EXPR_COAWAIT;
}

void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
  VisitCoroutineSuspendExpr(E);
  Code = serialization::EXPR_COYIELD;
}

void ASTStmtWriter::VisitCXXReflectExpr(CXXReflectExpr *E) {
  // TODO(Reflection): Implement this.
  assert(false && "not implemented yet");
}

void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getKeywordLoc());
  for (Stmt *S : E->children())
    Record.AddStmt(S);
  Code = serialization::EXPR_DEPENDENT_COAWAIT;
}

static void
addConstraintSatisfaction(ASTRecordWriter &Record,
                          const ASTConstraintSatisfaction &Satisfaction) {
  Record.push_back(Satisfaction.IsSatisfied);
  Record.push_back(Satisfaction.ContainsErrors);
  if (!Satisfaction.IsSatisfied) {
    Record.push_back(Satisfaction.NumRecords);
    for (const auto &DetailRecord : Satisfaction) {
      if (auto *Diag = dyn_cast<const ConstraintSubstitutionDiagnostic *>(
              DetailRecord)) {
        Record.push_back(/*Kind=*/0);
        Record.AddSourceLocation(Diag->first);
        Record.AddString(Diag->second);
        continue;
      }
      if (auto *E = dyn_cast<const Expr *>(DetailRecord)) {
        Record.push_back(/*Kind=*/1);
        Record.AddStmt(const_cast<Expr *>(E));
      } else {
        Record.push_back(/*Kind=*/2);
        auto *CR = cast<const ConceptReference *>(DetailRecord);
        Record.AddConceptReference(CR);
      }
    }
  }
}

static void
addSubstitutionDiagnostic(
    ASTRecordWriter &Record,
    const concepts::Requirement::SubstitutionDiagnostic *D) {
  Record.AddString(D->SubstitutedEntity);
  Record.AddSourceLocation(D->DiagLoc);
  Record.AddString(D->DiagMessage);
}

void ASTStmtWriter::VisitConceptSpecializationExpr(
        ConceptSpecializationExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getSpecializationDecl());
  const ConceptReference *CR = E->getConceptReference();
  Record.push_back(CR != nullptr);
  if (CR)
    Record.AddConceptReference(CR);
  if (!E->isValueDependent())
    addConstraintSatisfaction(Record, E->getSatisfaction());

  Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
}

void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getLocalParameters().size());
  Record.push_back(E->getRequirements().size());
  Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
  Record.push_back(E->RequiresExprBits.IsSatisfied);
  Record.AddDeclRef(E->getBody());
  for (ParmVarDecl *P : E->getLocalParameters())
    Record.AddDeclRef(P);
  for (concepts::Requirement *R : E->getRequirements()) {
    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) {
      Record.push_back(concepts::Requirement::RK_Type);
      Record.push_back(TypeReq->Status);
      if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure)
        addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic());
      else
        Record.AddTypeSourceInfo(TypeReq->getType());
    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
      Record.push_back(ExprReq->getKind());
      Record.push_back(ExprReq->Status);
      if (ExprReq->isExprSubstitutionFailure()) {
        addSubstitutionDiagnostic(
            Record, cast<concepts::Requirement::SubstitutionDiagnostic *>(
                        ExprReq->Value));
      } else
        Record.AddStmt(cast<Expr *>(ExprReq->Value));
      if (ExprReq->getKind() == concepts::Requirement::RK_Compound) {
        Record.AddSourceLocation(ExprReq->NoexceptLoc);
        const auto &RetReq = ExprReq->getReturnTypeRequirement();
        if (RetReq.isSubstitutionFailure()) {
          Record.push_back(2);
          addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic());
        } else if (RetReq.isTypeConstraint()) {
          Record.push_back(1);
          Record.AddTemplateParameterList(
              RetReq.getTypeConstraintTemplateParameterList());
          if (ExprReq->Status >=
              concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
            Record.AddStmt(
                ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr());
        } else {
          assert(RetReq.isEmpty());
          Record.push_back(0);
        }
      }
    } else {
      auto *NestedReq = cast<concepts::NestedRequirement>(R);
      Record.push_back(concepts::Requirement::RK_Nested);
      Record.push_back(NestedReq->hasInvalidConstraint());
      if (NestedReq->hasInvalidConstraint()) {
        Record.AddString(NestedReq->getInvalidConstraintEntity());
        addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
      } else {
        Record.AddStmt(NestedReq->getConstraintExpr());
        if (!NestedReq->isDependent())
          addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
      }
    }
  }
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.AddSourceLocation(E->getEndLoc());

  Code = serialization::EXPR_REQUIRES;
}


void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
  VisitStmt(S);
  // NumCaptures
  Record.push_back(std::distance(S->capture_begin(), S->capture_end()));

  // CapturedDecl and captured region kind
  Record.AddDeclRef(S->getCapturedDecl());
  Record.push_back(S->getCapturedRegionKind());

  Record.AddDeclRef(S->getCapturedRecordDecl());

  // Capture inits
  for (auto *I : S->capture_inits())
    Record.AddStmt(I);

  // Body
  Record.AddStmt(S->getCapturedStmt());

  // Captures
  for (const auto &I : S->captures()) {
    if (I.capturesThis() || I.capturesVariableArrayType())
      Record.AddDeclRef(nullptr);
    else
      Record.AddDeclRef(I.getCapturedVar());
    Record.push_back(I.getCaptureKind());
    Record.AddSourceLocation(I.getLocation());
  }

  Code = serialization::STMT_CAPTURED;
}

void ASTStmtWriter::VisitSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
  VisitStmt(S);
  Record.AddStmt(S->getOriginalStmt());
  Record.AddStmt(S->getKernelLaunchStmt());
  Record.AddDeclRef(S->getOutlinedFunctionDecl());

  Code = serialization::STMT_SYCLKERNELCALL;
}

void ASTStmtWriter::VisitExpr(Expr *E) {
  VisitStmt(E);

  CurrentPackingBits.updateBits();
  CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5);
  CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
  CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);

  Record.AddTypeRef(E->getType());
}

void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
  VisitExpr(E);
  Record.push_back(E->ConstantExprBits.ResultKind);

  Record.push_back(E->ConstantExprBits.APValueKind);
  Record.push_back(E->ConstantExprBits.IsUnsigned);
  Record.push_back(E->ConstantExprBits.BitWidth);
  // HasCleanup not serialized since we can just query the APValue.
  Record.push_back(E->ConstantExprBits.IsImmediateInvocation);

  switch (E->getResultStorageKind()) {
  case ConstantResultStorageKind::None:
    break;
  case ConstantResultStorageKind::Int64:
    Record.push_back(E->Int64Result());
    break;
  case ConstantResultStorageKind::APValue:
    Record.AddAPValue(E->APValueResult());
    break;
  }

  Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_CONSTANT;
}

void ASTStmtWriter::VisitOpenACCAsteriskSizeExpr(OpenACCAsteriskSizeExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getLocation());
  Code = serialization::EXPR_OPENACC_ASTERISK_SIZE;
}

void ASTStmtWriter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
  VisitExpr(E);

  Record.AddSourceLocation(E->getLocation());
  Record.AddSourceLocation(E->getLParenLocation());
  Record.AddSourceLocation(E->getRParenLocation());
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());

  Code = serialization::EXPR_SYCL_UNIQUE_STABLE_NAME;
}

void ASTStmtWriter::VisitUnresolvedSYCLKernelCallStmt(
    UnresolvedSYCLKernelCallStmt *S) {
  VisitStmt(S);

  Record.AddStmt(S->getOriginalStmt());
  Record.AddStmt(S->getKernelLaunchIdExpr());

  Code = serialization::STMT_UNRESOLVED_SYCL_KERNEL_CALL;
}

void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
  VisitExpr(E);

  bool HasFunctionName = E->getFunctionName() != nullptr;
  Record.push_back(HasFunctionName);
  Record.push_back(
      llvm::to_underlying(E->getIdentKind())); // FIXME: stable encoding
  Record.push_back(E->isTransparent());
  Record.AddSourceLocation(E->getLocation());
  if (HasFunctionName)
    Record.AddStmt(E->getFunctionName());
  Code = serialization::EXPR_PREDEFINED;
}

void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
  VisitExpr(E);

  CurrentPackingBits.updateBits();

  CurrentPackingBits.addBit(E->hadMultipleCandidates());
  CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture());
  CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
  CurrentPackingBits.addBit(E->isImmediateEscalating());
  CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl());
  CurrentPackingBits.addBit(E->hasQualifier());
  CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());

  if (E->hasTemplateKWAndArgsInfo()) {
    unsigned NumTemplateArgs = E->getNumTemplateArgs();
    Record.push_back(NumTemplateArgs);
  }

  DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());

  if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
      (E->getDecl() == E->getFoundDecl()) &&
      nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary) {
    AbbrevToUse = Writer.getDeclRefExprAbbrev();
  }

  if (E->hasQualifier())
    Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());

  if (E->getDecl() != E->getFoundDecl())
    Record.AddDeclRef(E->getFoundDecl());

  if (E->hasTemplateKWAndArgsInfo())
    AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
                             E->getTrailingObjects<TemplateArgumentLoc>());

  Record.AddDeclRef(E->getDecl());
  Record.AddSourceLocation(E->getLocation());
  Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
  Code = serialization::EXPR_DECL_REF;
}

void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getLocation());
  Record.AddAPInt(E->getValue());

  if (E->getBitWidth() == 32) {
    AbbrevToUse = Writer.getIntegerLiteralAbbrev();
  }

  Code = serialization::EXPR_INTEGER_LITERAL;
}

void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getLocation());
  Record.push_back(E->getScale());
  Record.AddAPInt(E->getValue());
  Code = serialization::EXPR_FIXEDPOINT_LITERAL;
}

void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
  VisitExpr(E);
  Record.push_back(E->getRawSemantics());
  Record.push_back(E->isExact());
  Record.AddAPFloat(E->getValue());
  Record.AddSourceLocation(E->getLocation());
  Code = serialization::EXPR_FLOATING_LITERAL;
}

void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_IMAGINARY_LITERAL;
}

void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
  VisitExpr(E);

  // Store the various bits of data of StringLiteral.
  Record.push_back(E->getNumConcatenated());
  Record.push_back(E->getLength());
  Record.push_back(E->getCharByteWidth());
  Record.push_back(llvm::to_underlying(E->getKind()));
  Record.push_back(E->isPascal());

  // Store the trailing array of SourceLocation.
  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
    Record.AddSourceLocation(E->getStrTokenLoc(I));

  // Store the trailing array of char holding the string data.
  StringRef StrData = E->getBytes();
  for (unsigned I = 0, N = E->getByteLength(); I != N; ++I)
    Record.push_back(StrData[I]);

  Code = serialization::EXPR_STRING_LITERAL;
}

void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
  VisitExpr(E);
  Record.push_back(E->getValue());
  Record.AddSourceLocation(E->getLocation());
  Record.push_back(llvm::to_underlying(E->getKind()));

  AbbrevToUse = Writer.getCharacterLiteralAbbrev();

  Code = serialization::EXPR_CHARACTER_LITERAL;
}

void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
  VisitExpr(E);
  Record.push_back(E->isProducedByFoldExpansion());
  Record.AddSourceLocation(E->getLParen());
  Record.AddSourceLocation(E->getRParen());
  Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_PAREN;
}

void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumExprs());
  for (auto *SubStmt : E->exprs())
    Record.AddStmt(SubStmt);
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_PAREN_LIST;
}

void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
  VisitExpr(E);
  bool HasFPFeatures = E->hasStoredFPFeatures();
  // Write this first for easy access when deserializing, as they affect the
  // size of the UnaryOperator.
  CurrentPackingBits.addBit(HasFPFeatures);
  Record.AddStmt(E->getSubExpr());
  CurrentPackingBits.addBits(E->getOpcode(),
                             /*Width=*/5); // FIXME: stable encoding
  Record.AddSourceLocation(E->getOperatorLoc());
  CurrentPackingBits.addBit(E->canOverflow());

  if (HasFPFeatures)
    Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
  Code = serialization::EXPR_UNARY_OPERATOR;
}

void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumComponents());
  Record.push_back(E->getNumExpressions());
  Record.AddSourceLocation(E->getOperatorLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
    const OffsetOfNode &ON = E->getComponent(I);
    Record.push_back(ON.getKind()); // FIXME: Stable encoding
    Record.AddSourceLocation(ON.getSourceRange().getBegin());
    Record.AddSourceLocation(ON.getSourceRange().getEnd());
    switch (ON.getKind()) {
    case OffsetOfNode::Array:
      Record.push_back(ON.getArrayExprIndex());
      break;

    case OffsetOfNode::Field:
      Record.AddDeclRef(ON.getField());
      break;

    case OffsetOfNode::Identifier:
      Record.AddIdentifierRef(ON.getFieldName());
      break;

    case OffsetOfNode::Base:
      Record.AddCXXBaseSpecifier(*ON.getBase());
      break;
    }
  }
  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
    Record.AddStmt(E->getIndexExpr(I));
  Code = serialization::EXPR_OFFSETOF;
}

void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getKind());
  if (E->isArgumentType())
    Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
  else {
    Record.push_back(0);
    Record.AddStmt(E->getArgumentExpr());
  }
  Record.AddSourceLocation(E->getOperatorLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_SIZEOF_ALIGN_OF;
}

void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getLHS());
  Record.AddStmt(E->getRHS());
  Record.AddSourceLocation(E->getRBracketLoc());
  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
}

void ASTStmtWriter::VisitMatrixSingleSubscriptExpr(
    MatrixSingleSubscriptExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddStmt(E->getRowIdx());
  Record.AddSourceLocation(E->getRBracketLoc());
  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
}

void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddStmt(E->getRowIdx());
  Record.AddStmt(E->getColumnIdx());
  Record.AddSourceLocation(E->getRBracketLoc());
  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
}

void ASTStmtWriter::VisitArraySectionExpr(ArraySectionExpr *E) {
  VisitExpr(E);
  Record.writeEnum(E->ASType);
  Record.AddStmt(E->getBase());
  Record.AddStmt(E->getLowerBound());
  Record.AddStmt(E->getLength());
  if (E->isOMPArraySection())
    Record.AddStmt(E->getStride());
  Record.AddSourceLocation(E->getColonLocFirst());

  if (E->isOMPArraySection())
    Record.AddSourceLocation(E->getColonLocSecond());

  Record.AddSourceLocation(E->getRBracketLoc());
  Code = serialization::EXPR_ARRAY_SECTION;
}

void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getDimensions().size());
  Record.AddStmt(E->getBase());
  for (Expr *Dim : E->getDimensions())
    Record.AddStmt(Dim);
  for (SourceRange SR : E->getBracketsRanges())
    Record.AddSourceRange(SR);
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_OMP_ARRAY_SHAPING;
}

void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
  VisitExpr(E);
  Record.push_back(E->numOfIterators());
  Record.AddSourceLocation(E->getIteratorKwLoc());
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
    Record.AddDeclRef(E->getIteratorDecl(I));
    Record.AddSourceLocation(E->getAssignLoc(I));
    OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
    Record.AddStmt(Range.Begin);
    Record.AddStmt(Range.End);
    Record.AddStmt(Range.Step);
    Record.AddSourceLocation(E->getColonLoc(I));
    if (Range.Step)
      Record.AddSourceLocation(E->getSecondColonLoc(I));
    // Serialize helpers
    OMPIteratorHelperData &HD = E->getHelper(I);
    Record.AddDeclRef(HD.CounterVD);
    Record.AddStmt(HD.Upper);
    Record.AddStmt(HD.Update);
    Record.AddStmt(HD.CounterUpdate);
  }
  Code = serialization::EXPR_OMP_ITERATOR;
}

void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
  VisitExpr(E);

  Record.push_back(E->getNumArgs());
  CurrentPackingBits.updateBits();
  CurrentPackingBits.addBit(static_cast<bool>(E->getADLCallKind()));
  CurrentPackingBits.addBit(E->hasStoredFPFeatures());
  CurrentPackingBits.addBit(E->isCoroElideSafe());
  CurrentPackingBits.addBit(E->usesMemberSyntax());

  Record.AddSourceLocation(E->getRParenLoc());
  Record.AddStmt(E->getCallee());
  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
       Arg != ArgEnd; ++Arg)
    Record.AddStmt(*Arg);

  if (E->hasStoredFPFeatures())
    Record.push_back(E->getFPFeatures().getAsOpaqueInt());

  if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
      !E->isCoroElideSafe() && !E->usesMemberSyntax() &&
      E->getStmtClass() == Stmt::CallExprClass)
    AbbrevToUse = Writer.getCallExprAbbrev();

  Code = serialization::EXPR_CALL;
}

void ASTStmtWriter::VisitRecoveryExpr(RecoveryExpr *E) {
  VisitExpr(E);
  Record.push_back(std::distance(E->children().begin(), E->children().end()));
  Record.AddSourceLocation(E->getBeginLoc());
  Record.AddSourceLocation(E->getEndLoc());
  for (Stmt *Child : E->children())
    Record.AddStmt(Child);
  Code = serialization::EXPR_RECOVERY;
}

void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
  VisitExpr(E);

  bool HasQualifier = E->hasQualifier();
  bool HasFoundDecl = E->hasFoundDecl();
  bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
  unsigned NumTemplateArgs = E->getNumTemplateArgs();

  // Write these first for easy access when deserializing, as they affect the
  // size of the MemberExpr.
  CurrentPackingBits.updateBits();
  CurrentPackingBits.addBit(HasQualifier);
  CurrentPackingBits.addBit(HasFoundDecl);
  CurrentPackingBits.addBit(HasTemplateInfo);
  Record.push_back(NumTemplateArgs);

  Record.AddStmt(E->getBase());
  Record.AddDeclRef(E->getMemberDecl());
  Record.AddDeclarationNameLoc(E->MemberDNLoc,
                               E->getMemberDecl()->getDeclName());
  Record.AddSourceLocation(E->getMemberLoc());
  CurrentPackingBits.addBit(E->isArrow());
  CurrentPackingBits.addBit(E->hadMultipleCandidates());
  CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
  Record.AddSourceLocation(E->getOperatorLoc());

  if (HasQualifier)
    Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());

  if (HasFoundDecl) {
    DeclAccessPair FoundDecl = E->getFoundDecl();
    Record.AddDeclRef(FoundDecl.getDecl());
    CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
  }

  if (HasTemplateInfo)
    AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
                             E->getTrailingObjects<TemplateArgumentLoc>());

  Code = serialization::EXPR_MEMBER;
}

void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddSourceLocation(E->getIsaMemberLoc());
  Record.AddSourceLocation(E->getOpLoc());
  Record.push_back(E->isArrow());
  Code = serialization::EXPR_OBJC_ISA;
}

void ASTStmtWriter::
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSubExpr());
  Record.push_back(E->shouldCopy());
  Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
}

void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
  VisitExplicitCastExpr(E);
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getBridgeKeywordLoc());
  Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
  Code = serialization::EXPR_OBJC_BRIDGED_CAST;
}

void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
  VisitExpr(E);

  Record.push_back(E->path_size());
  CurrentPackingBits.updateBits();
  // 7 bits should be enough to store the casting kinds.
  CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7);
  CurrentPackingBits.addBit(E->hasStoredFPFeatures());
  Record.AddStmt(E->getSubExpr());

  for (CastExpr::path_iterator
         PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
    Record.AddCXXBaseSpecifier(**PI);

  if (E->hasStoredFPFeatures())
    Record.push_back(E->getFPFeatures().getAsOpaqueInt());
}

void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
  VisitExpr(E);

  // Write this first for easy access when deserializing, as they affect the
  // size of the UnaryOperator.
  CurrentPackingBits.updateBits();
  CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6);
  bool HasFPFeatures = E->hasStoredFPFeatures();
  CurrentPackingBits.addBit(HasFPFeatures);
  CurrentPackingBits.addBit(E->hasExcludedOverflowPattern());
  Record.AddStmt(E->getLHS());
  Record.AddStmt(E->getRHS());
  Record.AddSourceLocation(E->getOperatorLoc());
  if (HasFPFeatures)
    Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());

  if (!HasFPFeatures && E->getValueKind() == VK_PRValue &&
      E->getObjectKind() == OK_Ordinary)
    AbbrevToUse = Writer.getBinaryOperatorAbbrev();

  Code = serialization::EXPR_BINARY_OPERATOR;
}

void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
  VisitBinaryOperator(E);
  Record.AddTypeRef(E->getComputationLHSType());
  Record.AddTypeRef(E->getComputationResultType());

  if (!E->hasStoredFPFeatures() && E->getValueKind() == VK_PRValue &&
      E->getObjectKind() == OK_Ordinary)
    AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev();

  Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
}

void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
  VisitExpr(E);
  Record.AddStmt(E->getCond());
  Record.AddStmt(E->getLHS());
  Record.AddStmt(E->getRHS());
  Record.AddSourceLocation(E->getQuestionLoc());
  Record.AddSourceLocation(E->getColonLoc());
  Code = serialization::EXPR_CONDITIONAL_OPERATOR;
}

void
ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
  VisitExpr(E);
  Record.AddStmt(E->getOpaqueValue());
  Record.AddStmt(E->getCommon());
  Record.AddStmt(E->getCond());
  Record.AddStmt(E->getTrueExpr());
  Record.AddStmt(E->getFalseExpr());
  Record.AddSourceLocation(E->getQuestionLoc());
  Record.AddSourceLocation(E->getColonLoc());
  Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
}

void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
  VisitCastExpr(E);
  CurrentPackingBits.addBit(E->isPartOfExplicitCast());

  if (E->path_size() == 0 && !E->hasStoredFPFeatures())
    AbbrevToUse = Writer.getExprImplicitCastAbbrev();

  Code = serialization::EXPR_IMPLICIT_CAST;
}

void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
  VisitCastExpr(E);
  Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
}

void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
  VisitExplicitCastExpr(E);
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_CSTYLE_CAST;
}

void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
  Record.AddStmt(E->getInitializer());
  Record.push_back(E->isFileScope());
  Code = serialization::EXPR_COMPOUND_LITERAL;
}

void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddIdentifierRef(&E->getAccessor());
  Record.AddSourceLocation(E->getAccessorLoc());
  Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
}

void ASTStmtWriter::VisitMatrixElementExpr(MatrixElementExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddIdentifierRef(&E->getAccessor());
  Record.AddSourceLocation(E->getAccessorLoc());
  Code = serialization::EXPR_MATRIX_ELEMENT;
}

void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
  VisitExpr(E);
  // NOTE: only add the (possibly null) syntactic form.
  // No need to serialize the isSemanticForm flag and the semantic form.
  Record.AddStmt(E->getSyntacticForm());
  Record.AddSourceLocation(E->getLBraceLoc());
  Record.AddSourceLocation(E->getRBraceLoc());
  bool isArrayFiller = isa<Expr *>(E->ArrayFillerOrUnionFieldInit);
  Record.push_back(isArrayFiller);
  if (isArrayFiller)
    Record.AddStmt(E->getArrayFiller());
  else
    Record.AddDeclRef(E->getInitializedFieldInUnion());
  Record.push_back(E->hadArrayRangeDesignator());
  Record.push_back(E->getNumInits());
  if (isArrayFiller) {
    // ArrayFiller may have filled "holes" due to designated initializer.
    // Replace them by 0 to indicate that the filler goes in that place.
    Expr *filler = E->getArrayFiller();
    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
      Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
  } else {
    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
      Record.AddStmt(E->getInit(I));
  }
  Code = serialization::EXPR_INIT_LIST;
}

void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumSubExprs());
  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
    Record.AddStmt(E->getSubExpr(I));
  Record.AddSourceLocation(E->getEqualOrColonLoc());
  Record.push_back(E->usesGNUSyntax());
  for (const DesignatedInitExpr::Designator &D : E->designators()) {
    if (D.isFieldDesignator()) {
      if (FieldDecl *Field = D.getFieldDecl()) {
        Record.push_back(serialization::DESIG_FIELD_DECL);
        Record.AddDeclRef(Field);
      } else {
        Record.push_back(serialization::DESIG_FIELD_NAME);
        Record.AddIdentifierRef(D.getFieldName());
      }
      Record.AddSourceLocation(D.getDotLoc());
      Record.AddSourceLocation(D.getFieldLoc());
    } else if (D.isArrayDesignator()) {
      Record.push_back(serialization::DESIG_ARRAY);
      Record.push_back(D.getArrayIndex());
      Record.AddSourceLocation(D.getLBracketLoc());
      Record.AddSourceLocation(D.getRBracketLoc());
    } else {
      assert(D.isArrayRangeDesignator() && "Unknown designator");
      Record.push_back(serialization::DESIG_ARRAY_RANGE);
      Record.push_back(D.getArrayIndex());
      Record.AddSourceLocation(D.getLBracketLoc());
      Record.AddSourceLocation(D.getEllipsisLoc());
      Record.AddSourceLocation(D.getRBracketLoc());
    }
  }
  Code = serialization::EXPR_DESIGNATED_INIT;
}

void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddStmt(E->getUpdater());
  Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
}

void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
  VisitExpr(E);
  Code = serialization::EXPR_NO_INIT;
}

void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->SubExprs[0]);
  Record.AddStmt(E->SubExprs[1]);
  Code = serialization::EXPR_ARRAY_INIT_LOOP;
}

void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
  VisitExpr(E);
  Code = serialization::EXPR_ARRAY_INIT_INDEX;
}

void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
  VisitExpr(E);
  Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
}

void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSubExpr());
  Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
  Record.AddSourceLocation(E->getBuiltinLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.push_back(E->isMicrosoftABI());
  Code = serialization::EXPR_VA_ARG;
}

void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
  Record.AddSourceLocation(E->getBeginLoc());
  Record.AddSourceLocation(E->getEndLoc());
  Record.push_back(llvm::to_underlying(E->getIdentKind()));
  Code = serialization::EXPR_SOURCE_LOC;
}

void ASTStmtWriter::VisitEmbedExpr(EmbedExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getBeginLoc());
  Record.AddSourceLocation(E->getEndLoc());
  Record.AddStmt(E->getDataStringLiteral());
  Record.writeUInt32(E->getStartingElementPos());
  Record.writeUInt32(E->getDataElementCount());
  Code = serialization::EXPR_BUILTIN_PP_EMBED;
}

void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getAmpAmpLoc());
  Record.AddSourceLocation(E->getLabelLoc());
  Record.AddDeclRef(E->getLabel());
  Code = serialization::EXPR_ADDR_LABEL;
}

void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSubStmt());
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.push_back(E->getTemplateDepth());
  Code = serialization::EXPR_STMT;
}

void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getCond());
  Record.AddStmt(E->getLHS());
  Record.AddStmt(E->getRHS());
  Record.AddSourceLocation(E->getBuiltinLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
  Code = serialization::EXPR_CHOOSE;
}

void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getTokenLocation());
  Code = serialization::EXPR_GNU_NULL;
}

void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumSubExprs());
  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
    Record.AddStmt(E->getExpr(I));
  Record.AddSourceLocation(E->getBuiltinLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_SHUFFLE_VECTOR;
}

void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
  VisitExpr(E);
  bool HasFPFeatures = E->hasStoredFPFeatures();
  CurrentPackingBits.addBit(HasFPFeatures);
  Record.AddSourceLocation(E->getBuiltinLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
  Record.AddStmt(E->getSrcExpr());
  Code = serialization::EXPR_CONVERT_VECTOR;
  if (HasFPFeatures)
    Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
}

void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getBlockDecl());
  Code = serialization::EXPR_BLOCK;
}

void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
  VisitExpr(E);

  Record.push_back(E->getNumAssocs());
  Record.push_back(E->isExprPredicate());
  Record.push_back(E->ResultIndex);
  Record.AddSourceLocation(E->getGenericLoc());
  Record.AddSourceLocation(E->getDefaultLoc());
  Record.AddSourceLocation(E->getRParenLoc());

  Stmt **Stmts = E->getTrailingObjects<Stmt *>();
  // Add 1 to account for the controlling expression which is the first
  // expression in the trailing array of Stmt *. This is not needed for
  // the trailing array of TypeSourceInfo *.
  for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
    Record.AddStmt(Stmts[I]);

  TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
  for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
    Record.AddTypeSourceInfo(TSIs[I]);

  Code = serialization::EXPR_GENERIC_SELECTION;
}

void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumSemanticExprs());

  // Push the result index.  Currently, this needs to exactly match
  // the encoding used internally for ResultIndex.
  unsigned result = E->getResultExprIndex();
  result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
  Record.push_back(result);

  Record.AddStmt(E->getSyntacticForm());
  for (PseudoObjectExpr::semantics_iterator
         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
    Record.AddStmt(*i);
  }
  Code = serialization::EXPR_PSEUDO_OBJECT;
}

void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getOp());
  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
    Record.AddStmt(E->getSubExprs()[I]);
  Record.AddSourceLocation(E->getBuiltinLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_ATOMIC;
}

//===----------------------------------------------------------------------===//
// Objective-C Expressions and Statements.
//===----------------------------------------------------------------------===//

void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
  VisitExpr(E);
  Record.AddStmt(E->getString());
  Record.AddSourceLocation(E->getAtLoc());
  Code = serialization::EXPR_OBJC_STRING_LITERAL;
}

void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSubExpr());
  Record.AddDeclRef(E->getBoxingMethod());
  Record.AddSourceRange(E->getSourceRange());
  Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
}

void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
  VisitExpr(E);
  Record.push_back(E->getNumElements());
  for (unsigned i = 0; i < E->getNumElements(); i++)
    Record.AddStmt(E->getElement(i));
  Record.AddDeclRef(E->getArrayWithObjectsMethod());
  Record.AddSourceRange(E->getSourceRange());
  Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
}

void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
  VisitExpr(E);
  Record.push_back(E->getNumElements());
  Record.push_back(E->HasPackExpansions);
  for (unsigned i = 0; i < E->getNumElements(); i++) {
    ObjCDictionaryElement Element = E->getKeyValueElement(i);
    Record.AddStmt(Element.Key);
    Record.AddStmt(Element.Value);
    if (E->HasPackExpansions) {
      Record.AddSourceLocation(Element.EllipsisLoc);
      unsigned NumExpansions = 0;
      if (Element.NumExpansions)
        NumExpansions = *Element.NumExpansions + 1;
      Record.push_back(NumExpansions);
    }
  }

  Record.AddDeclRef(E->getDictWithObjectsMethod());
  Record.AddSourceRange(E->getSourceRange());
  Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
}

void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
  VisitExpr(E);
  Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
  Record.AddSourceLocation(E->getAtLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_OBJC_ENCODE;
}

void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
  VisitExpr(E);
  Record.AddSelectorRef(E->getSelector());
  Record.AddSourceLocation(E->getAtLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
}

void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getProtocol());
  Record.AddSourceLocation(E->getAtLoc());
  Record.AddSourceLocation(E->ProtoLoc);
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
}

void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getDecl());
  Record.AddSourceLocation(E->getLocation());
  Record.AddSourceLocation(E->getOpLoc());
  Record.AddStmt(E->getBase());
  Record.push_back(E->isArrow());
  Record.push_back(E->isFreeIvar());
  Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
}

void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
  VisitExpr(E);
  Record.push_back(E->SetterAndMethodRefFlags.getInt());
  Record.push_back(E->isImplicitProperty());
  if (E->isImplicitProperty()) {
    Record.AddDeclRef(E->getImplicitPropertyGetter());
    Record.AddDeclRef(E->getImplicitPropertySetter());
  } else {
    Record.AddDeclRef(E->getExplicitProperty());
  }
  Record.AddSourceLocation(E->getLocation());
  Record.AddSourceLocation(E->getReceiverLocation());
  if (E->isObjectReceiver()) {
    Record.push_back(0);
    Record.AddStmt(E->getBase());
  } else if (E->isSuperReceiver()) {
    Record.push_back(1);
    Record.AddTypeRef(E->getSuperReceiverType());
  } else {
    Record.push_back(2);
    Record.AddDeclRef(E->getClassReceiver());
  }

  Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
}

void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getRBracket());
  Record.AddStmt(E->getBaseExpr());
  Record.AddStmt(E->getKeyExpr());
  Record.AddDeclRef(E->getAtIndexMethodDecl());
  Record.AddDeclRef(E->setAtIndexMethodDecl());

  Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
}

void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumArgs());
  Record.push_back(E->getNumStoredSelLocs());
  Record.push_back(E->SelLocsKind);
  Record.push_back(E->isDelegateInitCall());
  Record.push_back(E->IsImplicit);
  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
  switch (E->getReceiverKind()) {
  case ObjCMessageExpr::Instance:
    Record.AddStmt(E->getInstanceReceiver());
    break;

  case ObjCMessageExpr::Class:
    Record.AddTypeSourceInfo(E->getClassReceiverTypeInfo());
    break;

  case ObjCMessageExpr::SuperClass:
  case ObjCMessageExpr::SuperInstance:
    Record.AddTypeRef(E->getSuperType());
    Record.AddSourceLocation(E->getSuperLoc());
    break;
  }

  if (E->getMethodDecl()) {
    Record.push_back(1);
    Record.AddDeclRef(E->getMethodDecl());
  } else {
    Record.push_back(0);
    Record.AddSelectorRef(E->getSelector());
  }

  Record.AddSourceLocation(E->getLeftLoc());
  Record.AddSourceLocation(E->getRightLoc());

  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
       Arg != ArgEnd; ++Arg)
    Record.AddStmt(*Arg);

  SourceLocation *Locs = E->getStoredSelLocs();
  for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
    Record.AddSourceLocation(Locs[i]);

  Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
}

void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
  VisitStmt(S);
  Record.AddStmt(S->getElement());
  Record.AddStmt(S->getCollection());
  Record.AddStmt(S->getBody());
  Record.AddSourceLocation(S->getForLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  Code = serialization::STMT_OBJC_FOR_COLLECTION;
}

void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
  VisitStmt(S);
  Record.AddStmt(S->getCatchBody());
  Record.AddDeclRef(S->getCatchParamDecl());
  Record.AddSourceLocation(S->getAtCatchLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  Code = serialization::STMT_OBJC_CATCH;
}

void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
  VisitStmt(S);
  Record.AddStmt(S->getFinallyBody());
  Record.AddSourceLocation(S->getAtFinallyLoc());
  Code = serialization::STMT_OBJC_FINALLY;
}

void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
  VisitStmt(S); // FIXME: no test coverage.
  Record.AddStmt(S->getSubStmt());
  Record.AddSourceLocation(S->getAtLoc());
  Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
}

void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
  VisitStmt(S);
  Record.push_back(S->getNumCatchStmts());
  Record.push_back(S->getFinallyStmt() != nullptr);
  Record.AddStmt(S->getTryBody());
  for (ObjCAtCatchStmt *C : S->catch_stmts())
    Record.AddStmt(C);
  if (S->getFinallyStmt())
    Record.AddStmt(S->getFinallyStmt());
  Record.AddSourceLocation(S->getAtTryLoc());
  Code = serialization::STMT_OBJC_AT_TRY;
}

void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
  VisitStmt(S); // FIXME: no test coverage.
  Record.AddStmt(S->getSynchExpr());
  Record.AddStmt(S->getSynchBody());
  Record.AddSourceLocation(S->getAtSynchronizedLoc());
  Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
}

void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
  VisitStmt(S); // FIXME: no test coverage.
  Record.AddStmt(S->getThrowExpr());
  Record.AddSourceLocation(S->getThrowLoc());
  Code = serialization::STMT_OBJC_AT_THROW;
}

void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getValue());
  Record.AddSourceLocation(E->getLocation());
  Code = serialization::EXPR_OBJC_BOOL_LITERAL;
}

void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
  VisitExpr(E);
  Record.AddSourceRange(E->getSourceRange());
  Record.AddVersionTuple(E->getVersion());
  Code = serialization::EXPR_OBJC_AVAILABILITY_CHECK;
}

//===----------------------------------------------------------------------===//
// C++ Expressions and Statements.
//===----------------------------------------------------------------------===//

void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getCatchLoc());
  Record.AddDeclRef(S->getExceptionDecl());
  Record.AddStmt(S->getHandlerBlock());
  Code = serialization::STMT_CXX_CATCH;
}

void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
  VisitStmt(S);
  Record.push_back(S->getNumHandlers());
  Record.AddSourceLocation(S->getTryLoc());
  Record.AddStmt(S->getTryBlock());
  for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
    Record.AddStmt(S->getHandler(i));
  Code = serialization::STMT_CXX_TRY;
}

void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getForLoc());
  Record.AddSourceLocation(S->getCoawaitLoc());
  Record.AddSourceLocation(S->getColonLoc());
  Record.AddSourceLocation(S->getRParenLoc());
  Record.AddStmt(S->getInit());
  Record.AddStmt(S->getRangeStmt());
  Record.AddStmt(S->getBeginStmt());
  Record.AddStmt(S->getEndStmt());
  Record.AddStmt(S->getCond());
  Record.AddStmt(S->getInc());
  Record.AddStmt(S->getLoopVarStmt());
  Record.AddStmt(S->getBody());
  Code = serialization::STMT_CXX_FOR_RANGE;
}

void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getKeywordLoc());
  Record.push_back(S->isIfExists());
  Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
  Record.AddDeclarationNameInfo(S->getNameInfo());
  Record.AddStmt(S->getSubStmt());
  Code = serialization::STMT_MS_DEPENDENT_EXISTS;
}

void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
  VisitCallExpr(E);
  Record.push_back(E->getOperator());
  Record.AddSourceLocation(E->BeginLoc);

  if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
      !E->isCoroElideSafe() && !E->usesMemberSyntax())
    AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev();

  Code = serialization::EXPR_CXX_OPERATOR_CALL;
}

void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
  VisitCallExpr(E);

  if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
      !E->isCoroElideSafe() && !E->usesMemberSyntax())
    AbbrevToUse = Writer.getCXXMemberCallExprAbbrev();

  Code = serialization::EXPR_CXX_MEMBER_CALL;
}

void ASTStmtWriter::VisitCXXRewrittenBinaryOperator(
    CXXRewrittenBinaryOperator *E) {
  VisitExpr(E);
  Record.push_back(E->isReversed());
  Record.AddStmt(E->getSemanticForm());
  Code = serialization::EXPR_CXX_REWRITTEN_BINARY_OPERATOR;
}

void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
  VisitExpr(E);

  Record.push_back(E->getNumArgs());
  Record.push_back(E->isElidable());
  Record.push_back(E->hadMultipleCandidates());
  Record.push_back(E->isListInitialization());
  Record.push_back(E->isStdInitListInitialization());
  Record.push_back(E->requiresZeroInitialization());
  Record.push_back(
      llvm::to_underlying(E->getConstructionKind())); // FIXME: stable encoding
  Record.push_back(E->isImmediateEscalating());
  Record.AddSourceLocation(E->getLocation());
  Record.AddDeclRef(E->getConstructor());
  Record.AddSourceRange(E->getParenOrBraceRange());

  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
    Record.AddStmt(E->getArg(I));

  Code = serialization::EXPR_CXX_CONSTRUCT;
}

void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getConstructor());
  Record.AddSourceLocation(E->getLocation());
  Record.push_back(E->constructsVBase());
  Record.push_back(E->inheritedFromVBase());
  Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
}

void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
  VisitCXXConstructExpr(E);
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
  Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
}

void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
  VisitExpr(E);
  Record.push_back(E->LambdaExprBits.NumCaptures);
  Record.AddSourceRange(E->IntroducerRange);
  Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
  Record.AddSourceLocation(E->CaptureDefaultLoc);
  Record.push_back(E->LambdaExprBits.ExplicitParams);
  Record.push_back(E->LambdaExprBits.ExplicitResultType);
  Record.AddSourceLocation(E->ClosingBrace);

  // Add capture initializers.
  for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
                                      CEnd = E->capture_init_end();
       C != CEnd; ++C) {
    Record.AddStmt(*C);
  }

  // Don't serialize the body. It belongs to the call operator declaration.
  // LambdaExpr only stores a copy of the Stmt *.

  Code = serialization::EXPR_LAMBDA;
}

void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
}

void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
  VisitExplicitCastExpr(E);
  Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
  CurrentPackingBits.addBit(E->getAngleBrackets().isValid());
  if (E->getAngleBrackets().isValid())
    Record.AddSourceRange(E->getAngleBrackets());
}

void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
  VisitCXXNamedCastExpr(E);
  Code = serialization::EXPR_CXX_STATIC_CAST;
}

void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
  VisitCXXNamedCastExpr(E);
  Code = serialization::EXPR_CXX_DYNAMIC_CAST;
}

void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
  VisitCXXNamedCastExpr(E);
  Code = serialization::EXPR_CXX_REINTERPRET_CAST;
}

void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
  VisitCXXNamedCastExpr(E);
  Code = serialization::EXPR_CXX_CONST_CAST;
}

void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
  VisitCXXNamedCastExpr(E);
  Code = serialization::EXPR_CXX_ADDRSPACE_CAST;
}

void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
  VisitExplicitCastExpr(E);
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
}

void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) {
  VisitExplicitCastExpr(E);
  Record.AddSourceLocation(E->getBeginLoc());
  Record.AddSourceLocation(E->getEndLoc());
  Code = serialization::EXPR_BUILTIN_BIT_CAST;
}

void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
  VisitCallExpr(E);
  Record.AddSourceLocation(E->UDSuffixLoc);
  Code = serialization::EXPR_USER_DEFINED_LITERAL;
}

void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getValue());
  Record.AddSourceLocation(E->getLocation());
  Code = serialization::EXPR_CXX_BOOL_LITERAL;
}

void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getLocation());
  Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
}

void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
  VisitExpr(E);
  Record.AddSourceRange(E->getSourceRange());
  if (E->isTypeOperand()) {
    Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
    Code = serialization::EXPR_CXX_TYPEID_TYPE;
  } else {
    Record.AddStmt(E->getExprOperand());
    Code = serialization::EXPR_CXX_TYPEID_EXPR;
  }
}

void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getLocation());
  Record.push_back(E->isImplicit());
  Record.push_back(E->isCapturedByCopyInLambdaWithExplicitObjectParameter());

  Code = serialization::EXPR_CXX_THIS;
}

void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getThrowLoc());
  Record.AddStmt(E->getSubExpr());
  Record.push_back(E->isThrownVariableInScope());
  Code = serialization::EXPR_CXX_THROW;
}

void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getParam());
  Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
  Record.AddSourceLocation(E->getUsedLocation());
  Record.push_back(E->hasRewrittenInit());
  if (E->hasRewrittenInit())
    Record.AddStmt(E->getRewrittenExpr());
  Code = serialization::EXPR_CXX_DEFAULT_ARG;
}

void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->hasRewrittenInit());
  Record.AddDeclRef(E->getField());
  Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
  Record.AddSourceLocation(E->getExprLoc());
  if (E->hasRewrittenInit())
    Record.AddStmt(E->getRewrittenExpr());
  Code = serialization::EXPR_CXX_DEFAULT_INIT;
}

void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
  VisitExpr(E);
  Record.AddCXXTemporary(E->getTemporary());
  Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_CXX_BIND_TEMPORARY;
}

void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
  VisitExpr(E);
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
  Record.AddSourceLocation(E->getRParenLoc());
  Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
}

void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
  VisitExpr(E);

  Record.push_back(E->isArray());
  Record.push_back(E->hasInitializer());
  Record.push_back(E->getNumPlacementArgs());
  Record.push_back(E->isParenTypeId());

  Record.push_back(E->isGlobalNew());
  ImplicitAllocationParameters IAP = E->implicitAllocationParameters();
  Record.push_back(isAlignedAllocation(IAP.PassAlignment));
  Record.push_back(isTypeAwareAllocation(IAP.PassTypeIdentity));
  Record.push_back(E->doesUsualArrayDeleteWantSize());
  Record.push_back(E->CXXNewExprBits.HasInitializer);
  Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);

  Record.AddDeclRef(E->getOperatorNew());
  Record.AddDeclRef(E->getOperatorDelete());
  Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
  if (E->isParenTypeId())
    Record.AddSourceRange(E->getTypeIdParens());
  Record.AddSourceRange(E->getSourceRange());
  Record.AddSourceRange(E->getDirectInitRange());

  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
       I != N; ++I)
    Record.AddStmt(*I);

  Code = serialization::EXPR_CXX_NEW;
}

void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
  VisitExpr(E);
  Record.push_back(E->isGlobalDelete());
  Record.push_back(E->isArrayForm());
  Record.push_back(E->isArrayFormAsWritten());
  Record.push_back(E->doesUsualArrayDeleteWantSize());
  Record.AddDeclRef(E->getOperatorDelete());
  Record.AddStmt(E->getArgument());
  Record.AddSourceLocation(E->getBeginLoc());

  Code = serialization::EXPR_CXX_DELETE;
}

void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
  VisitExpr(E);

  Record.AddStmt(E->getBase());
  Record.push_back(E->isArrow());
  Record.AddSourceLocation(E->getOperatorLoc());
  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
  Record.AddTypeSourceInfo(E->getScopeTypeInfo());
  Record.AddSourceLocation(E->getColonColonLoc());
  Record.AddSourceLocation(E->getTildeLoc());

  // PseudoDestructorTypeStorage.
  Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
  if (E->getDestroyedTypeIdentifier())
    Record.AddSourceLocation(E->getDestroyedTypeLoc());
  else
    Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());

  Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
}

void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
  VisitExpr(E);
  Record.push_back(E->getNumObjects());
  for (auto &Obj : E->getObjects()) {
    if (auto *BD = Obj.dyn_cast<BlockDecl *>()) {
      Record.push_back(serialization::COK_Block);
      Record.AddDeclRef(BD);
    } else if (auto *CLE = Obj.dyn_cast<CompoundLiteralExpr *>()) {
      Record.push_back(serialization::COK_CompoundLiteral);
      Record.AddStmt(CLE);
    }
  }

  Record.push_back(E->cleanupsHaveSideEffects());
  Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
}

void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
    CXXDependentScopeMemberExpr *E) {
  VisitExpr(E);

  // Don't emit anything here (or if you do you will have to update
  // the corresponding deserialization function).
  Record.push_back(E->getNumTemplateArgs());
  CurrentPackingBits.updateBits();
  CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
  CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope());

  if (E->hasTemplateKWAndArgsInfo()) {
    const ASTTemplateKWAndArgsInfo &ArgInfo =
        *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
    AddTemplateKWAndArgsInfo(ArgInfo,
                             E->getTrailingObjects<TemplateArgumentLoc>());
  }

  CurrentPackingBits.addBit(E->isArrow());

  Record.AddTypeRef(E->getBaseType());
  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
  CurrentPackingBits.addBit(!E->isImplicitAccess());
  if (!E->isImplicitAccess())
    Record.AddStmt(E->getBase());

  Record.AddSourceLocation(E->getOperatorLoc());

  if (E->hasFirstQualifierFoundInScope())
    Record.AddDeclRef(E->getFirstQualifierFoundInScope());

  Record.AddDeclarationNameInfo(E->MemberNameInfo);
  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
}

void
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
  VisitExpr(E);

  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
  // emitted first.
  CurrentPackingBits.addBit(
      E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);

  if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
    const ASTTemplateKWAndArgsInfo &ArgInfo =
        *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
    // 16 bits should be enought to store the number of args
    CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16);
    AddTemplateKWAndArgsInfo(ArgInfo,
                             E->getTrailingObjects<TemplateArgumentLoc>());
  }

  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
  Record.AddDeclarationNameInfo(E->NameInfo);
  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
}

void
ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumArgs());
  for (CXXUnresolvedConstructExpr::arg_iterator
         ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
    Record.AddStmt(*ArgI);
  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
  Record.AddSourceLocation(E->getLParenLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.push_back(E->isListInitialization());
  Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
}

void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
  VisitExpr(E);

  Record.push_back(E->getNumDecls());

  CurrentPackingBits.updateBits();
  CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
  if (E->hasTemplateKWAndArgsInfo()) {
    const ASTTemplateKWAndArgsInfo &ArgInfo =
        *E->getTrailingASTTemplateKWAndArgsInfo();
    Record.push_back(ArgInfo.NumTemplateArgs);
    AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
  }

  for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
                                    OvE = E->decls_end();
       OvI != OvE; ++OvI) {
    Record.AddDeclRef(OvI.getDecl());
    Record.push_back(OvI.getAccess());
  }

  Record.AddDeclarationNameInfo(E->getNameInfo());
  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
}

void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
  VisitOverloadExpr(E);
  CurrentPackingBits.addBit(E->isArrow());
  CurrentPackingBits.addBit(E->hasUnresolvedUsing());
  CurrentPackingBits.addBit(!E->isImplicitAccess());
  if (!E->isImplicitAccess())
    Record.AddStmt(E->getBase());

  Record.AddSourceLocation(E->getOperatorLoc());

  Record.AddTypeRef(E->getBaseType());
  Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
}

void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
  VisitOverloadExpr(E);
  CurrentPackingBits.addBit(E->requiresADL());
  Record.AddDeclRef(E->getNamingClass());
  Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;

  if (Writer.isWritingStdCXXNamedModules() && Writer.getChain()) {
    // Referencing all the possible declarations to make sure the change get
    // propagted.
    DeclarationName Name = E->getName();
    for (auto *Found :
         Record.getASTContext().getTranslationUnitDecl()->lookup(Name))
      if (Found->isFromASTFile())
        Writer.GetDeclRef(Found);

    llvm::SmallVector<NamespaceDecl *> ExternalNSs;
    Writer.getChain()->ReadKnownNamespaces(ExternalNSs);
    for (auto *NS : ExternalNSs)
      for (auto *Found : NS->lookup(Name))
        Writer.GetDeclRef(Found);
  }
}

void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->TypeTraitExprBits.IsBooleanTypeTrait);
  Record.push_back(E->TypeTraitExprBits.NumArgs);
  Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding

  if (E->TypeTraitExprBits.IsBooleanTypeTrait)
    Record.push_back(E->TypeTraitExprBits.Value);
  else
    Record.AddAPValue(E->getAPValue());

  Record.AddSourceRange(E->getSourceRange());
  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
    Record.AddTypeSourceInfo(E->getArg(I));
  Code = serialization::EXPR_TYPE_TRAIT;
}

void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getTrait());
  Record.push_back(E->getValue());
  Record.AddSourceRange(E->getSourceRange());
  Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
  Record.AddStmt(E->getDimensionExpression());
  Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
}

void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getTrait());
  Record.push_back(E->getValue());
  Record.AddSourceRange(E->getSourceRange());
  Record.AddStmt(E->getQueriedExpression());
  Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
}

void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getValue());
  Record.AddSourceRange(E->getSourceRange());
  Record.AddStmt(E->getOperand());
  Code = serialization::EXPR_CXX_NOEXCEPT;
}

void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getEllipsisLoc());
  Record.push_back(E->NumExpansions);
  Record.AddStmt(E->getPattern());
  Code = serialization::EXPR_PACK_EXPANSION;
}

void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
  VisitExpr(E);
  Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
                                               : 0);
  Record.AddSourceLocation(E->OperatorLoc);
  Record.AddSourceLocation(E->PackLoc);
  Record.AddSourceLocation(E->RParenLoc);
  Record.AddDeclRef(E->Pack);
  if (E->isPartiallySubstituted()) {
    for (const auto &TA : E->getPartialArguments())
      Record.AddTemplateArgument(TA);
  } else if (!E->isValueDependent()) {
    Record.push_back(E->getPackLength());
  }
  Code = serialization::EXPR_SIZEOF_PACK;
}

void ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) {
  VisitExpr(E);
  Record.push_back(E->PackIndexingExprBits.TransformedExpressions);
  Record.push_back(E->PackIndexingExprBits.FullySubstituted);
  Record.AddSourceLocation(E->getEllipsisLoc());
  Record.AddSourceLocation(E->getRSquareLoc());
  Record.AddStmt(E->getPackIdExpression());
  Record.AddStmt(E->getIndexExpr());
  for (Expr *Sub : E->getExpressions())
    Record.AddStmt(Sub);
  Code = serialization::EXPR_PACK_INDEXING;
}

void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
                                              SubstNonTypeTemplateParmExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getAssociatedDecl());
  CurrentPackingBits.addBit(E->isReferenceParameter());
  CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12);
  Record.writeUnsignedOrNone(E->getPackIndex());
  CurrentPackingBits.addBit(E->getFinal());

  Record.AddSourceLocation(E->getNameLoc());
  Record.AddStmt(E->getReplacement());
  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
}

void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
                                          SubstNonTypeTemplateParmPackExpr *E) {
  VisitExpr(E);
  Record.AddDeclRef(E->getAssociatedDecl());
  CurrentPackingBits.addBit(E->getFinal());
  Record.push_back(E->getIndex());
  Record.AddTemplateArgument(E->getArgumentPack());
  Record.AddSourceLocation(E->getParameterPackLocation());
  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
}

void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumExpansions());
  Record.AddDeclRef(E->getParameterPack());
  Record.AddSourceLocation(E->getParameterPackLocation());
  for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
       I != End; ++I)
    Record.AddDeclRef(*I);
  Code = serialization::EXPR_FUNCTION_PARM_PACK;
}

void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
  VisitExpr(E);
  Record.push_back(static_cast<bool>(E->getLifetimeExtendedTemporaryDecl()));
  if (E->getLifetimeExtendedTemporaryDecl())
    Record.AddDeclRef(E->getLifetimeExtendedTemporaryDecl());
  else
    Record.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
}

void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->LParenLoc);
  Record.AddSourceLocation(E->EllipsisLoc);
  Record.AddSourceLocation(E->RParenLoc);
  Record.push_back(E->NumExpansions.toInternalRepresentation());
  Record.AddStmt(E->SubExprs[0]);
  Record.AddStmt(E->SubExprs[1]);
  Record.AddStmt(E->SubExprs[2]);
  Record.push_back(E->CXXFoldExprBits.Opcode);
  Code = serialization::EXPR_CXX_FOLD;
}

void ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
  VisitExpr(E);
  ArrayRef<Expr *> InitExprs = E->getInitExprs();
  Record.push_back(InitExprs.size());
  Record.push_back(E->getUserSpecifiedInitExprs().size());
  Record.AddSourceLocation(E->getInitLoc());
  Record.AddSourceLocation(E->getBeginLoc());
  Record.AddSourceLocation(E->getEndLoc());
  for (Expr *InitExpr : E->getInitExprs())
    Record.AddStmt(InitExpr);
  Expr *ArrayFiller = E->getArrayFiller();
  FieldDecl *UnionField = E->getInitializedFieldInUnion();
  bool HasArrayFillerOrUnionDecl = ArrayFiller || UnionField;
  Record.push_back(HasArrayFillerOrUnionDecl);
  if (HasArrayFillerOrUnionDecl) {
    Record.push_back(static_cast<bool>(ArrayFiller));
    if (ArrayFiller)
      Record.AddStmt(ArrayFiller);
    else
      Record.AddDeclRef(UnionField);
  }
  Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
}

void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getSourceExpr());
  Record.AddSourceLocation(E->getLocation());
  Record.push_back(E->isUnique());
  Code = serialization::EXPR_OPAQUE_VALUE;
}

//===----------------------------------------------------------------------===//
// CUDA Expressions and Statements.
//===----------------------------------------------------------------------===//

void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
  VisitCallExpr(E);
  Record.AddStmt(E->getConfig());
  Code = serialization::EXPR_CUDA_KERNEL_CALL;
}

//===----------------------------------------------------------------------===//
// OpenCL Expressions and Statements.
//===----------------------------------------------------------------------===//
void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
  VisitExpr(E);
  Record.AddSourceLocation(E->getBuiltinLoc());
  Record.AddSourceLocation(E->getRParenLoc());
  Record.AddStmt(E->getSrcExpr());
  Code = serialization::EXPR_ASTYPE;
}

//===----------------------------------------------------------------------===//
// Microsoft Expressions and Statements.
//===----------------------------------------------------------------------===//
void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
  VisitExpr(E);
  Record.push_back(E->isArrow());
  Record.AddStmt(E->getBaseExpr());
  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
  Record.AddSourceLocation(E->getMemberLoc());
  Record.AddDeclRef(E->getPropertyDecl());
  Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
}

void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
  VisitExpr(E);
  Record.AddStmt(E->getBase());
  Record.AddStmt(E->getIdx());
  Record.AddSourceLocation(E->getRBracketLoc());
  Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
}

void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
  VisitExpr(E);
  Record.AddSourceRange(E->getSourceRange());
  Record.AddDeclRef(E->getGuidDecl());
  if (E->isTypeOperand()) {
    Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
    Code = serialization::EXPR_CXX_UUIDOF_TYPE;
  } else {
    Record.AddStmt(E->getExprOperand());
    Code = serialization::EXPR_CXX_UUIDOF_EXPR;
  }
}

void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getExceptLoc());
  Record.AddStmt(S->getFilterExpr());
  Record.AddStmt(S->getBlock());
  Code = serialization::STMT_SEH_EXCEPT;
}

void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getFinallyLoc());
  Record.AddStmt(S->getBlock());
  Code = serialization::STMT_SEH_FINALLY;
}

void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
  VisitStmt(S);
  Record.push_back(S->getIsCXXTry());
  Record.AddSourceLocation(S->getTryLoc());
  Record.AddStmt(S->getTryBlock());
  Record.AddStmt(S->getHandler());
  Code = serialization::STMT_SEH_TRY;
}

void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
  VisitStmt(S);
  Record.AddSourceLocation(S->getLeaveLoc());
  Code = serialization::STMT_SEH_LEAVE;
}

//===----------------------------------------------------------------------===//
// OpenMP Directives.
//===----------------------------------------------------------------------===//

void ASTStmtWriter::VisitOMPCanonicalLoop(OMPCanonicalLoop *S) {
  VisitStmt(S);
  for (Stmt *SubStmt : S->SubStmts)
    Record.AddStmt(SubStmt);
  Code = serialization::STMT_OMP_CANONICAL_LOOP;
}

void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
  Record.writeOMPChildren(E->Data);
  Record.AddSourceLocation(E->getBeginLoc());
  Record.AddSourceLocation(E->getEndLoc());
}

void ASTStmtWriter::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) {
  VisitStmt(D);
  Record.writeUInt32(D->getLoopsNumber());
  VisitOMPExecutableDirective(D);
}

void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
  VisitOMPLoopBasedDirective(D);
}

void ASTStmtWriter::VisitOMPMetaDirective(OMPMetaDirective *D) {
  VisitStmt(D);
  Record.push_back(D->getNumClauses());
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_META_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPCanonicalLoopNestTransformationDirective(
    OMPCanonicalLoopNestTransformationDirective *D) {
  VisitOMPLoopBasedDirective(D);
  Record.writeUInt32(D->getNumGeneratedTopLevelLoops());
}

void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) {
  VisitOMPCanonicalLoopNestTransformationDirective(D);
  Code = serialization::STMT_OMP_TILE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPStripeDirective(OMPStripeDirective *D) {
  VisitOMPCanonicalLoopNestTransformationDirective(D);
  Code = serialization::STMP_OMP_STRIPE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
  VisitOMPCanonicalLoopNestTransformationDirective(D);
  Code = serialization::STMT_OMP_UNROLL_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPReverseDirective(OMPReverseDirective *D) {
  VisitOMPCanonicalLoopNestTransformationDirective(D);
  Code = serialization::STMT_OMP_REVERSE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) {
  VisitOMPCanonicalLoopNestTransformationDirective(D);
  Code = serialization::STMT_OMP_INTERCHANGE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPCanonicalLoopSequenceTransformationDirective(
    OMPCanonicalLoopSequenceTransformationDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeUInt32(D->getNumGeneratedTopLevelLoops());
}

void ASTStmtWriter::VisitOMPFuseDirective(OMPFuseDirective *D) {
  VisitOMPCanonicalLoopSequenceTransformationDirective(D);
  Code = serialization::STMT_OMP_FUSE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_FOR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPScopeDirective(OMPScopeDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_SCOPE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.AddDeclarationNameInfo(D->getDirectiveName());
  Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelForSimdDirective(
    OMPParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelMasterDirective(
    OMPParallelMasterDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelMaskedDirective(
    OMPParallelMaskedDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_PARALLEL_MASKED_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelSectionsDirective(
    OMPParallelSectionsDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_TASK_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->isXLHSInRHSPart());
  Record.writeBool(D->isPostfixUpdate());
  Record.writeBool(D->isFailOnly());
  Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
    OMPTargetEnterDataDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetExitDataDirective(
    OMPTargetExitDataDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetParallelDirective(
    OMPTargetParallelDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetParallelForDirective(
    OMPTargetParallelForDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
  VisitStmt(D);
  Record.push_back(D->getNumClauses());
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPAssumeDirective(OMPAssumeDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_ASSUME_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPErrorDirective(OMPErrorDirective *D) {
  VisitStmt(D);
  Record.push_back(D->getNumClauses());
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_ERROR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_SCAN_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPCancellationPointDirective(
    OMPCancellationPointDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeEnum(D->getCancelRegion());
  Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.writeEnum(D->getCancelRegion());
  Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPMasterTaskLoopDirective(
    OMPMasterTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPMaskedTaskLoopDirective(
    OMPMaskedTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_MASKED_TASKLOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective(
    OMPMasterTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPMaskedTaskLoopSimdDirective(
    OMPMaskedTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_MASKED_TASKLOOP_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective(
    OMPParallelMasterTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopDirective(
    OMPParallelMaskedTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelMasterTaskLoopSimdDirective(
    OMPParallelMasterTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopSimdDirective(
    OMPParallelMaskedTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
    OMPDistributeParallelForDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
    OMPDistributeParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPDistributeSimdDirective(
    OMPDistributeSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
    OMPTargetParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
    OMPTeamsDistributeDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
    OMPTeamsDistributeSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
    OMPTeamsDistributeParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
    OMPTeamsDistributeParallelForDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
    OMPTargetTeamsDistributeDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
    OMPTargetTeamsDistributeParallelForDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->hasCancel());
  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
    OMPTargetTeamsDistributeParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::
      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
    OMPTargetTeamsDistributeSimdDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPInteropDirective(OMPInteropDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_INTEROP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPDispatchDirective(OMPDispatchDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Record.AddSourceLocation(D->getTargetCallLoc());
  Code = serialization::STMT_OMP_DISPATCH_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPMaskedDirective(OMPMaskedDirective *D) {
  VisitStmt(D);
  VisitOMPExecutableDirective(D);
  Code = serialization::STMT_OMP_MASKED_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_GENERIC_LOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTeamsGenericLoopDirective(
    OMPTeamsGenericLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetTeamsGenericLoopDirective(
    OMPTargetTeamsGenericLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Record.writeBool(D->canBeParallelFor());
  Code = serialization::STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPParallelGenericLoopDirective(
    OMPParallelGenericLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE;
}

void ASTStmtWriter::VisitOMPTargetParallelGenericLoopDirective(
    OMPTargetParallelGenericLoopDirective *D) {
  VisitOMPLoopDirective(D);
  Code = serialization::STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE;
}

//===----------------------------------------------------------------------===//
// OpenACC Constructs/Directives.
//===----------------------------------------------------------------------===//
void ASTStmtWriter::VisitOpenACCConstructStmt(OpenACCConstructStmt *S) {
  Record.push_back(S->clauses().size());
  Record.writeEnum(S->Kind);
  Record.AddSourceRange(S->Range);
  Record.AddSourceLocation(S->DirectiveLoc);
  Record.writeOpenACCClauseList(S->clauses());
}

void ASTStmtWriter::VisitOpenACCAssociatedStmtConstruct(
    OpenACCAssociatedStmtConstruct *S) {
  VisitOpenACCConstructStmt(S);
  Record.AddStmt(S->getAssociatedStmt());
}

void ASTStmtWriter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
  VisitStmt(S);
  VisitOpenACCAssociatedStmtConstruct(S);
  Code = serialization::STMT_OPENACC_COMPUTE_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
  VisitStmt(S);
  VisitOpenACCAssociatedStmtConstruct(S);
  Record.writeEnum(S->getParentComputeConstructKind());
  Code = serialization::STMT_OPENACC_LOOP_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) {
  VisitStmt(S);
  VisitOpenACCAssociatedStmtConstruct(S);
  Code = serialization::STMT_OPENACC_COMBINED_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) {
  VisitStmt(S);
  VisitOpenACCAssociatedStmtConstruct(S);
  Code = serialization::STMT_OPENACC_DATA_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCEnterDataConstruct(
    OpenACCEnterDataConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Code = serialization::STMT_OPENACC_ENTER_DATA_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Code = serialization::STMT_OPENACC_EXIT_DATA_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCInitConstruct(OpenACCInitConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Code = serialization::STMT_OPENACC_INIT_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCShutdownConstruct(OpenACCShutdownConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Code = serialization::STMT_OPENACC_SHUTDOWN_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCSetConstruct(OpenACCSetConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Code = serialization::STMT_OPENACC_SET_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCUpdateConstruct(OpenACCUpdateConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Code = serialization::STMT_OPENACC_UPDATE_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) {
  VisitStmt(S);
  VisitOpenACCAssociatedStmtConstruct(S);
  Code = serialization::STMT_OPENACC_HOST_DATA_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCWaitConstruct(OpenACCWaitConstruct *S) {
  VisitStmt(S);
  Record.push_back(S->getExprs().size());
  VisitOpenACCConstructStmt(S);
  Record.AddSourceLocation(S->LParenLoc);
  Record.AddSourceLocation(S->RParenLoc);
  Record.AddSourceLocation(S->QueuesLoc);

  for(Expr *E : S->getExprs())
    Record.AddStmt(E);

  Code = serialization::STMT_OPENACC_WAIT_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCAtomicConstruct(OpenACCAtomicConstruct *S) {
  VisitStmt(S);
  VisitOpenACCConstructStmt(S);
  Record.writeEnum(S->getAtomicKind());
  Record.AddStmt(S->getAssociatedStmt());

  Code = serialization::STMT_OPENACC_ATOMIC_CONSTRUCT;
}

void ASTStmtWriter::VisitOpenACCCacheConstruct(OpenACCCacheConstruct *S) {
  VisitStmt(S);
  Record.push_back(S->getVarList().size());
  VisitOpenACCConstructStmt(S);
  Record.AddSourceRange(S->ParensLoc);
  Record.AddSourceLocation(S->ReadOnlyLoc);

  for (Expr *E : S->getVarList())
    Record.AddStmt(E);
  Code = serialization::STMT_OPENACC_CACHE_CONSTRUCT;
}

//===----------------------------------------------------------------------===//
// HLSL Constructs/Directives.
//===----------------------------------------------------------------------===//

void ASTStmtWriter::VisitHLSLOutArgExpr(HLSLOutArgExpr *S) {
  VisitExpr(S);
  Record.AddStmt(S->getOpaqueArgLValue());
  Record.AddStmt(S->getCastedTemporary());
  Record.AddStmt(S->getWritebackCast());
  Record.writeBool(S->isInOut());
  Code = serialization::EXPR_HLSL_OUT_ARG;
}

//===----------------------------------------------------------------------===//
// ASTWriter Implementation
//===----------------------------------------------------------------------===//

unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
  assert(!SwitchCaseIDs.contains(S) && "SwitchCase recorded twice");
  unsigned NextID = SwitchCaseIDs.size();
  SwitchCaseIDs[S] = NextID;
  return NextID;
}

unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
  assert(SwitchCaseIDs.contains(S) && "SwitchCase hasn't been seen yet");
  return SwitchCaseIDs[S];
}

void ASTWriter::ClearSwitchCaseIDs() {
  SwitchCaseIDs.clear();
}

/// Write the given substatement or subexpression to the
/// bitstream.
void ASTWriter::WriteSubStmt(ASTContext &Context, Stmt *S) {
  RecordData Record;
  ASTStmtWriter Writer(Context, *this, Record);
  ++NumStatements;

  if (!S) {
    Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
    return;
  }

  llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
  if (I != SubStmtEntries.end()) {
    Record.push_back(I->second);
    Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
    return;
  }

#ifndef NDEBUG
  assert(!ParentStmts.count(S) && "There is a Stmt cycle!");

  struct ParentStmtInserterRAII {
    Stmt *S;
    llvm::DenseSet<Stmt *> &ParentStmts;

    ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
      : S(S), ParentStmts(ParentStmts) {
      ParentStmts.insert(S);
    }
    ~ParentStmtInserterRAII() {
      ParentStmts.erase(S);
    }
  };

  ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
#endif

  Writer.Visit(S);

  uint64_t Offset = Writer.Emit();
  SubStmtEntries[S] = Offset;
}

/// Flush all of the statements that have been added to the
/// queue via AddStmt().
void ASTRecordWriter::FlushStmts() {
  // We expect to be the only consumer of the two temporary statement maps,
  // assert that they are empty.
  assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
  assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");

  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
    Writer->WriteSubStmt(getASTContext(), StmtsToEmit[I]);

    assert(N == StmtsToEmit.size() && "record modified while being written!");

    // Note that we are at the end of a full expression. Any
    // expression records that follow this one are part of a different
    // expression.
    Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());

    Writer->SubStmtEntries.clear();
    Writer->ParentStmts.clear();
  }

  StmtsToEmit.clear();
}

void ASTRecordWriter::FlushSubStmts() {
  // For a nested statement, write out the substatements in reverse order (so
  // that a simple stack machine can be used when loading), and don't emit a
  // STMT_STOP after each one.
  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
    Writer->WriteSubStmt(getASTContext(), StmtsToEmit[N - I - 1]);
    assert(N == StmtsToEmit.size() && "record modified while being written!");
  }

  StmtsToEmit.clear();
}
