//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements serialization for Statements and Expressions.
//
//===----------------------------------------------------------------------===//

#include "clang/Serialization/ASTWriter.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/StmtVisitor.h"
#include "llvm/Bitcode/BitstreamWriter.h"
using namespace clang;

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

namespace clang {
  class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
    ASTWriter &Writer;
    ASTWriter::RecordData &Record;

  public:
    serialization::StmtCode Code;
    unsigned AbbrevToUse;

    ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
      : Writer(Writer), Record(Record) { }
    
    void
    AddExplicitTemplateArgumentList(const ASTTemplateArgumentListInfo &Args);

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

void ASTStmtWriter::
AddExplicitTemplateArgumentList(const ASTTemplateArgumentListInfo &Args) {
  Writer.AddSourceLocation(Args.LAngleLoc, Record);
  Writer.AddSourceLocation(Args.RAngleLoc, Record);
  for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
    Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
}

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

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

void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
  VisitStmt(S);
  Record.push_back(S->size());
  for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
       CS != CSEnd; ++CS)
    Writer.AddStmt(*CS);
  Writer.AddSourceLocation(S->getLBracLoc(), Record);
  Writer.AddSourceLocation(S->getRBracLoc(), Record);
  Code = serialization::STMT_COMPOUND;
}

void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
  VisitStmt(S);
  Record.push_back(Writer.getSwitchCaseID(S));
}

void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
  VisitSwitchCase(S);
  Writer.AddStmt(S->getLHS());
  Writer.AddStmt(S->getRHS());
  Writer.AddStmt(S->getSubStmt());
  Writer.AddSourceLocation(S->getCaseLoc(), Record);
  Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
  Writer.AddSourceLocation(S->getColonLoc(), Record);
  Code = serialization::STMT_CASE;
}

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

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

void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
  VisitStmt(S);
  Writer.AddDeclRef(S->getConditionVariable(), Record);
  Writer.AddStmt(S->getCond());
  Writer.AddStmt(S->getThen());
  Writer.AddStmt(S->getElse());
  Writer.AddSourceLocation(S->getIfLoc(), Record);
  Writer.AddSourceLocation(S->getElseLoc(), Record);
  Code = serialization::STMT_IF;
}

void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
  VisitStmt(S);
  Writer.AddDeclRef(S->getConditionVariable(), Record);
  Writer.AddStmt(S->getCond());
  Writer.AddStmt(S->getBody());
  Writer.AddSourceLocation(S->getSwitchLoc(), Record);
  Record.push_back(S->isAllEnumCasesCovered());
  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);
  Writer.AddDeclRef(S->getConditionVariable(), Record);
  Writer.AddStmt(S->getCond());
  Writer.AddStmt(S->getBody());
  Writer.AddSourceLocation(S->getWhileLoc(), Record);
  Code = serialization::STMT_WHILE;
}

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

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

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

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

void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
  VisitStmt(S);
  Writer.AddSourceLocation(S->getContinueLoc(), Record);
  Code = serialization::STMT_CONTINUE;
}

void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
  VisitStmt(S);
  Writer.AddSourceLocation(S->getBreakLoc(), Record);
  Code = serialization::STMT_BREAK;
}

void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
  VisitStmt(S);
  Writer.AddStmt(S->getRetValue());
  Writer.AddSourceLocation(S->getReturnLoc(), Record);
  Writer.AddDeclRef(S->getNRVOCandidate(), Record);
  Code = serialization::STMT_RETURN;
}

void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
  VisitStmt(S);
  Writer.AddSourceLocation(S->getStartLoc(), Record);
  Writer.AddSourceLocation(S->getEndLoc(), Record);
  DeclGroupRef DG = S->getDeclGroup();
  for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
    Writer.AddDeclRef(*D, Record);
  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());
  Writer.AddSourceLocation(S->getAsmLoc(), Record);
  Writer.AddSourceLocation(S->getRParenLoc(), Record);
  Record.push_back(S->isVolatile());
  Record.push_back(S->isSimple());
  Record.push_back(S->isMSAsm());
  Writer.AddStmt(S->getAsmString());

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

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

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

  Code = serialization::STMT_ASM;
}

void ASTStmtWriter::VisitExpr(Expr *E) {
  VisitStmt(E);
  Writer.AddTypeRef(E->getType(), Record);
  Record.push_back(E->isTypeDependent());
  Record.push_back(E->isValueDependent());
  Record.push_back(E->isInstantiationDependent());
  Record.push_back(E->containsUnexpandedParameterPack());
  Record.push_back(E->getValueKind());
  Record.push_back(E->getObjectKind());
}

void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
  VisitExpr(E);
  Writer.AddSourceLocation(E->getLocation(), Record);
  Record.push_back(E->getIdentType()); // FIXME: stable encoding
  Code = serialization::EXPR_PREDEFINED;
}

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

  Record.push_back(E->hasQualifier());
  Record.push_back(E->getDecl() != E->getFoundDecl());
  Record.push_back(E->hasExplicitTemplateArgs());
  Record.push_back(E->hadMultipleCandidates());

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

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

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

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

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

  if (E->hasExplicitTemplateArgs())
    AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());

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

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

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

  Code = serialization::EXPR_INTEGER_LITERAL;
}

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

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

void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
  VisitExpr(E);
  Record.push_back(E->getByteLength());
  Record.push_back(E->getNumConcatenated());
  Record.push_back(E->getKind());
  Record.push_back(E->isPascal());
  // FIXME: String data should be stored as a blob at the end of the
  // StringLiteral. However, we can't do so now because we have no
  // provision for coping with abbreviations when we're jumping around
  // the AST file during deserialization.
  Record.append(E->getString().begin(), E->getString().end());
  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
    Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
  Code = serialization::EXPR_STRING_LITERAL;
}

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

  AbbrevToUse = Writer.getCharacterLiteralAbbrev();

  Code = serialization::EXPR_CHARACTER_LITERAL;
}

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

void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
  VisitExpr(E);
  Record.push_back(E->NumExprs);
  for (unsigned i=0; i != E->NumExprs; ++i)
    Writer.AddStmt(E->Exprs[i]);
  Writer.AddSourceLocation(E->LParenLoc, Record);
  Writer.AddSourceLocation(E->RParenLoc, Record);
  Code = serialization::EXPR_PAREN_LIST;
}

void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
  VisitExpr(E);
  Writer.AddStmt(E->getSubExpr());
  Record.push_back(E->getOpcode()); // FIXME: stable encoding
  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
  Code = serialization::EXPR_UNARY_OPERATOR;
}

void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumComponents());
  Record.push_back(E->getNumExpressions());
  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
  Writer.AddSourceLocation(E->getRParenLoc(), Record);
  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
    const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
    Record.push_back(ON.getKind()); // FIXME: Stable encoding
    Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
    Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
    switch (ON.getKind()) {
    case OffsetOfExpr::OffsetOfNode::Array:
      Record.push_back(ON.getArrayExprIndex());
      break;
        
    case OffsetOfExpr::OffsetOfNode::Field:
      Writer.AddDeclRef(ON.getField(), Record);
      break;
        
    case OffsetOfExpr::OffsetOfNode::Identifier:
      Writer.AddIdentifierRef(ON.getFieldName(), Record);
      break;
        
    case OffsetOfExpr::OffsetOfNode::Base:
      Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
      break;
    }
  }
  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
    Writer.AddStmt(E->getIndexExpr(I));
  Code = serialization::EXPR_OFFSETOF;
}

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

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

void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumArgs());
  Writer.AddSourceLocation(E->getRParenLoc(), Record);
  Writer.AddStmt(E->getCallee());
  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
       Arg != ArgEnd; ++Arg)
    Writer.AddStmt(*Arg);
  Code = serialization::EXPR_CALL;
}

void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
  // Don't call VisitExpr, we'll write everything here.

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

  Record.push_back(E->hasExplicitTemplateArgs());
  if (E->hasExplicitTemplateArgs()) {
    unsigned NumTemplateArgs = E->getNumTemplateArgs();
    Record.push_back(NumTemplateArgs);
    Writer.AddSourceLocation(E->getLAngleLoc(), Record);
    Writer.AddSourceLocation(E->getRAngleLoc(), Record);
    for (unsigned i=0; i != NumTemplateArgs; ++i)
      Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
  }

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

  DeclAccessPair FoundDecl = E->getFoundDecl();
  Writer.AddDeclRef(FoundDecl.getDecl(), Record);
  Record.push_back(FoundDecl.getAccess());

  Writer.AddTypeRef(E->getType(), Record);
  Record.push_back(E->getValueKind());
  Record.push_back(E->getObjectKind());
  Writer.AddStmt(E->getBase());
  Writer.AddDeclRef(E->getMemberDecl(), Record);
  Writer.AddSourceLocation(E->getMemberLoc(), Record);
  Record.push_back(E->isArrow());
  Writer.AddDeclarationNameLoc(E->MemberDNLoc,
                               E->getMemberDecl()->getDeclName(), Record);
  Code = serialization::EXPR_MEMBER;
}

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

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

void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
  VisitExplicitCastExpr(E);
  Writer.AddSourceLocation(E->getLParenLoc(), Record);
  Writer.AddSourceLocation(E->getBridgeKeywordLoc(), Record);
  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());
  Writer.AddStmt(E->getSubExpr());
  Record.push_back(E->getCastKind()); // FIXME: stable encoding

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

void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
  VisitExpr(E);
  Writer.AddStmt(E->getLHS());
  Writer.AddStmt(E->getRHS());
  Record.push_back(E->getOpcode()); // FIXME: stable encoding
  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
  Code = serialization::EXPR_BINARY_OPERATOR;
}

void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
  VisitBinaryOperator(E);
  Writer.AddTypeRef(E->getComputationLHSType(), Record);
  Writer.AddTypeRef(E->getComputationResultType(), Record);
  Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
}

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

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

void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
  VisitCastExpr(E);
  Code = serialization::EXPR_IMPLICIT_CAST;
}

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

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

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

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

void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
  VisitExpr(E);
  Writer.AddStmt(E->getSyntacticForm());
  Writer.AddSourceLocation(E->getLBraceLoc(), Record);
  Writer.AddSourceLocation(E->getRBraceLoc(), Record);
  bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
  Record.push_back(isArrayFiller);
  if (isArrayFiller)
    Writer.AddStmt(E->getArrayFiller());
  else
    Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
  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)
      Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0);
  } else {
    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
      Writer.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)
    Writer.AddStmt(E->getSubExpr(I));
  Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
  Record.push_back(E->usesGNUSyntax());
  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
                                             DEnd = E->designators_end();
       D != DEnd; ++D) {
    if (D->isFieldDesignator()) {
      if (FieldDecl *Field = D->getField()) {
        Record.push_back(serialization::DESIG_FIELD_DECL);
        Writer.AddDeclRef(Field, Record);
      } else {
        Record.push_back(serialization::DESIG_FIELD_NAME);
        Writer.AddIdentifierRef(D->getFieldName(), Record);
      }
      Writer.AddSourceLocation(D->getDotLoc(), Record);
      Writer.AddSourceLocation(D->getFieldLoc(), Record);
    } else if (D->isArrayDesignator()) {
      Record.push_back(serialization::DESIG_ARRAY);
      Record.push_back(D->getFirstExprIndex());
      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
    } else {
      assert(D->isArrayRangeDesignator() && "Unknown designator");
      Record.push_back(serialization::DESIG_ARRAY_RANGE);
      Record.push_back(D->getFirstExprIndex());
      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
      Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
    }
  }
  Code = serialization::EXPR_DESIGNATED_INIT;
}

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

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

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

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

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

void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
  VisitExpr(E);
  Writer.AddSourceLocation(E->getTokenLocation(), Record);
  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)
    Writer.AddStmt(E->getExpr(I));
  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
  Writer.AddSourceLocation(E->getRParenLoc(), Record);
  Code = serialization::EXPR_SHUFFLE_VECTOR;
}

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

void ASTStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
  VisitExpr(E);
  Writer.AddDeclRef(E->getDecl(), Record);
  Writer.AddSourceLocation(E->getLocation(), Record);
  Record.push_back(E->isByRef());
  Record.push_back(E->isConstQualAdded());
  Code = serialization::EXPR_BLOCK_DECL_REF;
}

void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumAssocs());

  Writer.AddStmt(E->getControllingExpr());
  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
    Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record);
    Writer.AddStmt(E->getAssocExpr(I));
  }
  Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());

  Writer.AddSourceLocation(E->getGenericLoc(), Record);
  Writer.AddSourceLocation(E->getDefaultLoc(), Record);
  Writer.AddSourceLocation(E->getRParenLoc(), Record);
  Code = serialization::EXPR_GENERIC_SELECTION;
}

void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getOp());
  Writer.AddStmt(E->getPtr());
  Writer.AddStmt(E->getOrder());
  if (E->getOp() != AtomicExpr::Load)
    Writer.AddStmt(E->getVal1());
  if (E->isCmpXChg()) {
    Writer.AddStmt(E->getOrderFail());
    Writer.AddStmt(E->getVal2());
  }
  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
  Writer.AddSourceLocation(E->getRParenLoc(), Record);
}

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

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

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

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

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

void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
  VisitExpr(E);
  Writer.AddDeclRef(E->getDecl(), Record);
  Writer.AddSourceLocation(E->getLocation(), Record);
  Writer.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->isImplicitProperty());
  if (E->isImplicitProperty()) {
    Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
    Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
  } else {
    Writer.AddDeclRef(E->getExplicitProperty(), Record);
  }
  Writer.AddSourceLocation(E->getLocation(), Record);
  Writer.AddSourceLocation(E->getReceiverLocation(), Record);
  if (E->isObjectReceiver()) {
    Record.push_back(0);
    Writer.AddStmt(E->getBase());
  } else if (E->isSuperReceiver()) {
    Record.push_back(1);
    Writer.AddTypeRef(E->getSuperReceiverType(), Record);
  } else {
    Record.push_back(2);
    Writer.AddDeclRef(E->getClassReceiver(), Record);
  }
  
  Code = serialization::EXPR_OBJC_PROPERTY_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((unsigned)E->getReceiverKind()); // FIXME: stable encoding
  switch (E->getReceiverKind()) {
  case ObjCMessageExpr::Instance:
    Writer.AddStmt(E->getInstanceReceiver());
    break;

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

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

  if (E->getMethodDecl()) {
    Record.push_back(1);
    Writer.AddDeclRef(E->getMethodDecl(), Record);
  } else {
    Record.push_back(0);
    Writer.AddSelectorRef(E->getSelector(), Record);    
  }
    
  Writer.AddSourceLocation(E->getLeftLoc(), Record);
  Writer.AddSourceLocation(E->getRightLoc(), Record);

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

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

  Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
}

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

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

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

void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
  Writer.AddStmt(S->getSubStmt());
  Writer.AddSourceLocation(S->getAtLoc(), Record);
  Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
}

void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
  Record.push_back(S->getNumCatchStmts());
  Record.push_back(S->getFinallyStmt() != 0);
  Writer.AddStmt(S->getTryBody());
  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
    Writer.AddStmt(S->getCatchStmt(I));
  if (S->getFinallyStmt())
    Writer.AddStmt(S->getFinallyStmt());
  Writer.AddSourceLocation(S->getAtTryLoc(), Record);
  Code = serialization::STMT_OBJC_AT_TRY;
}

void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
  Writer.AddStmt(S->getSynchExpr());
  Writer.AddStmt(S->getSynchBody());
  Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
  Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
}

void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
  Writer.AddStmt(S->getThrowExpr());
  Writer.AddSourceLocation(S->getThrowLoc(), Record);
  Code = serialization::STMT_OBJC_AT_THROW;
}

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

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

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

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

void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
  VisitCallExpr(E);
  Record.push_back(E->getOperator());
  Code = serialization::EXPR_CXX_OPERATOR_CALL;
}

void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
  VisitCallExpr(E);
  Code = serialization::EXPR_CXX_MEMBER_CALL;
}

void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getNumArgs());
  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
    Writer.AddStmt(E->getArg(I));
  Writer.AddDeclRef(E->getConstructor(), Record);
  Writer.AddSourceLocation(E->getLocation(), Record);
  Record.push_back(E->isElidable());
  Record.push_back(E->hadMultipleCandidates());
  Record.push_back(E->requiresZeroInitialization());
  Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
  Writer.AddSourceRange(E->getParenRange(), Record);
  Code = serialization::EXPR_CXX_CONSTRUCT;
}

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

void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
  VisitExplicitCastExpr(E);
  Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
                        Record);
}

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::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
  VisitExplicitCastExpr(E);
  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
  Writer.AddSourceLocation(E->getRParenLoc(), Record);
  Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
}

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

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

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

void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
  VisitExpr(E);
  Writer.AddSourceLocation(E->getLocation(), Record);
  Record.push_back(E->isImplicit());
  Code = serialization::EXPR_CXX_THIS;
}

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

void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
  VisitExpr(E);

  bool HasOtherExprStored = E->Param.getInt();
  // Store these first, the reader reads them before creation.
  Record.push_back(HasOtherExprStored);
  if (HasOtherExprStored)
    Writer.AddStmt(E->getExpr());
  Writer.AddDeclRef(E->getParam(), Record);
  Writer.AddSourceLocation(E->getUsedLocation(), Record);

  Code = serialization::EXPR_CXX_DEFAULT_ARG;
}

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

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

void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
  VisitExpr(E);
  Record.push_back(E->isGlobalNew());
  Record.push_back(E->hasInitializer());
  Record.push_back(E->doesUsualArrayDeleteWantSize());
  Record.push_back(E->isArray());
  Record.push_back(E->hadMultipleCandidates());
  Record.push_back(E->getNumPlacementArgs());
  Record.push_back(E->getNumConstructorArgs());
  Writer.AddDeclRef(E->getOperatorNew(), Record);
  Writer.AddDeclRef(E->getOperatorDelete(), Record);
  Writer.AddDeclRef(E->getConstructor(), Record);
  Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
  Writer.AddSourceRange(E->getTypeIdParens(), Record);
  Writer.AddSourceLocation(E->getStartLoc(), Record);
  Writer.AddSourceLocation(E->getEndLoc(), Record);
  Writer.AddSourceLocation(E->getConstructorLParen(), Record);
  Writer.AddSourceLocation(E->getConstructorRParen(), Record);
  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
       I != e; ++I)
    Writer.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());
  Writer.AddDeclRef(E->getOperatorDelete(), Record);
  Writer.AddStmt(E->getArgument());
  Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
  
  Code = serialization::EXPR_CXX_DELETE;
}

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

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

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

  Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
}

void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
  VisitExpr(E);
  Record.push_back(E->getNumTemporaries());
  for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i)
    Writer.AddCXXTemporary(E->getTemporary(i), Record);
  
  Writer.AddStmt(E->getSubExpr());
  Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
}

void
ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
  VisitExpr(E);
  
  // Don't emit anything here, hasExplicitTemplateArgs() must be
  // emitted first.

  Record.push_back(E->hasExplicitTemplateArgs());
  if (E->hasExplicitTemplateArgs()) {
    const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs();
    Record.push_back(Args.NumTemplateArgs);
    AddExplicitTemplateArgumentList(Args);
  }
  
  if (!E->isImplicitAccess())
    Writer.AddStmt(E->getBase());
  else
    Writer.AddStmt(0);
  Writer.AddTypeRef(E->getBaseType(), Record);
  Record.push_back(E->isArrow());
  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
  Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
  Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
}

void
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
  VisitExpr(E);
  
  // Don't emit anything here, hasExplicitTemplateArgs() must be
  // emitted first.
  Record.push_back(E->hasExplicitTemplateArgs());
  if (E->hasExplicitTemplateArgs()) {
    const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs();
    Record.push_back(Args.NumTemplateArgs);
    AddExplicitTemplateArgumentList(Args);
  }

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

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

void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
  VisitExpr(E);
  
  // Don't emit anything here, hasExplicitTemplateArgs() must be emitted first.
  Record.push_back(E->hasExplicitTemplateArgs());
  if (E->hasExplicitTemplateArgs()) {
    const ASTTemplateArgumentListInfo &Args = E->getExplicitTemplateArgs();
    Record.push_back(Args.NumTemplateArgs);
    AddExplicitTemplateArgumentList(Args);
  }

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

  Writer.AddDeclarationNameInfo(E->NameInfo, Record);
  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
}

void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
  VisitOverloadExpr(E);
  Record.push_back(E->isArrow());
  Record.push_back(E->hasUnresolvedUsing());
  Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
  Writer.AddTypeRef(E->getBaseType(), Record);
  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
  Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
}

void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
  VisitOverloadExpr(E);
  Record.push_back(E->requiresADL());
  if (E->requiresADL())
    Record.push_back(E->isStdAssociatedNamespace());
  Record.push_back(E->isOverloaded());
  Writer.AddDeclRef(E->getNamingClass(), Record);
  Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
}

void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getTrait());
  Record.push_back(E->getValue());
  Writer.AddSourceRange(E->getSourceRange(), Record);
  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
  Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
}

void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
  VisitExpr(E);
  Record.push_back(E->getTrait());
  Record.push_back(E->getValue());
  Writer.AddSourceRange(E->getSourceRange(), Record);
  Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
  Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
  Code = serialization::EXPR_BINARY_TYPE_TRAIT;
}

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

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

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

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

void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
  VisitExpr(E);
  Writer.AddSourceLocation(E->OperatorLoc, Record);
  Writer.AddSourceLocation(E->PackLoc, Record);
  Writer.AddSourceLocation(E->RParenLoc, Record);
  Record.push_back(E->Length);
  Writer.AddDeclRef(E->Pack, Record);
  Code = serialization::EXPR_SIZEOF_PACK;
}

void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
                                              SubstNonTypeTemplateParmExpr *E) {
  VisitExpr(E);
  Writer.AddDeclRef(E->getParameter(), Record);
  Writer.AddSourceLocation(E->getNameLoc(), Record);
  Writer.AddStmt(E->getReplacement());
  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
}

void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
                                          SubstNonTypeTemplateParmPackExpr *E) {
  VisitExpr(E);
  Writer.AddDeclRef(E->getParameterPack(), Record);
  Writer.AddTemplateArgument(E->getArgumentPack(), Record);
  Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
}

void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
  VisitExpr(E);
  Writer.AddStmt(E->Temporary);
  Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
}

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

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

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

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

//===----------------------------------------------------------------------===//
// Microsoft Expressions and Statements.
//===----------------------------------------------------------------------===//
void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
  VisitExpr(E);
  Writer.AddSourceRange(E->getSourceRange(), Record);
  if (E->isTypeOperand()) {
    Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
    Code = serialization::EXPR_CXX_UUIDOF_TYPE;
  } else {
    Writer.AddStmt(E->getExprOperand());
    Code = serialization::EXPR_CXX_UUIDOF_EXPR;
  }
}

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

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

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

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

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

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

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

unsigned ASTWriter::getOpaqueValueID(OpaqueValueExpr *e) {
  unsigned &entry = OpaqueValues[e];
  if (!entry) entry = OpaqueValues.size();
  return entry;
}

/// \brief Write the given substatement or subexpression to the
/// bitstream.
void ASTWriter::WriteSubStmt(Stmt *S) {
  RecordData Record;
  ASTStmtWriter Writer(*this, Record);
  ++NumStatements;
  
  if (!S) {
    Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
    return;
  }

  // Redirect ASTWriter::AddStmt to collect sub stmts.
  SmallVector<Stmt *, 16> SubStmts;
  CollectedStmts = &SubStmts;

  Writer.Code = serialization::STMT_NULL_PTR;
  Writer.AbbrevToUse = 0;
  Writer.Visit(S);
  
#ifndef NDEBUG
  if (Writer.Code == serialization::STMT_NULL_PTR) {
    SourceManager &SrcMgr
      = DeclIDs.begin()->first->getASTContext().getSourceManager();
    S->dump(SrcMgr);
    llvm_unreachable("Unhandled sub statement writing AST file");
  }
#endif

  // Revert ASTWriter::AddStmt.
  CollectedStmts = &StmtsToEmit;

  // Write the sub stmts in reverse order, last to first. When reading them back
  // we will read them in correct order by "pop"ing them from the Stmts stack.
  // This simplifies reading and allows to store a variable number of sub stmts
  // without knowing it in advance.
  while (!SubStmts.empty())
    WriteSubStmt(SubStmts.pop_back_val());
  
  Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
}

/// \brief Flush all of the statements that have been added to the
/// queue via AddStmt().
void ASTWriter::FlushStmts() {
  RecordData Record;

  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
    WriteSubStmt(StmtsToEmit[I]);
    
    assert(N == StmtsToEmit.size() &&
           "Substatement written via AddStmt rather than WriteSubStmt!");

    // Note that we are at the end of a full expression. Any
    // expression records that follow this one are part of a different
    // expression.
    Stream.EmitRecord(serialization::STMT_STOP, Record);
  }

  StmtsToEmit.clear();
}
