Home | History | Annotate | Download | only in Serialization
      1 //===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file implements serialization for Statements and Expressions.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/Serialization/ASTWriter.h"
     15 #include "clang/AST/DeclCXX.h"
     16 #include "clang/AST/DeclObjC.h"
     17 #include "clang/AST/DeclTemplate.h"
     18 #include "clang/AST/StmtVisitor.h"
     19 #include "llvm/Bitcode/BitstreamWriter.h"
     20 using namespace clang;
     21 
     22 //===----------------------------------------------------------------------===//
     23 // Statement/expression serialization
     24 //===----------------------------------------------------------------------===//
     25 
     26 namespace clang {
     27   class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
     28     ASTWriter &Writer;
     29     ASTWriter::RecordData &Record;
     30 
     31   public:
     32     serialization::StmtCode Code;
     33     unsigned AbbrevToUse;
     34 
     35     ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
     36       : Writer(Writer), Record(Record) { }
     37 
     38     void
     39     AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args);
     40 
     41     void VisitStmt(Stmt *S);
     42 #define STMT(Type, Base) \
     43     void Visit##Type(Type *);
     44 #include "clang/AST/StmtNodes.inc"
     45   };
     46 }
     47 
     48 void ASTStmtWriter::
     49 AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args) {
     50   Writer.AddSourceLocation(Args.LAngleLoc, Record);
     51   Writer.AddSourceLocation(Args.RAngleLoc, Record);
     52   for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
     53     Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
     54 }
     55 
     56 void ASTStmtWriter::VisitStmt(Stmt *S) {
     57 }
     58 
     59 void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
     60   VisitStmt(S);
     61   Writer.AddSourceLocation(S->getSemiLoc(), Record);
     62   Writer.AddSourceLocation(S->LeadingEmptyMacro, Record);
     63   Code = serialization::STMT_NULL;
     64 }
     65 
     66 void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
     67   VisitStmt(S);
     68   Record.push_back(S->size());
     69   for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
     70        CS != CSEnd; ++CS)
     71     Writer.AddStmt(*CS);
     72   Writer.AddSourceLocation(S->getLBracLoc(), Record);
     73   Writer.AddSourceLocation(S->getRBracLoc(), Record);
     74   Code = serialization::STMT_COMPOUND;
     75 }
     76 
     77 void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
     78   VisitStmt(S);
     79   Record.push_back(Writer.getSwitchCaseID(S));
     80 }
     81 
     82 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
     83   VisitSwitchCase(S);
     84   Writer.AddStmt(S->getLHS());
     85   Writer.AddStmt(S->getRHS());
     86   Writer.AddStmt(S->getSubStmt());
     87   Writer.AddSourceLocation(S->getCaseLoc(), Record);
     88   Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
     89   Writer.AddSourceLocation(S->getColonLoc(), Record);
     90   Code = serialization::STMT_CASE;
     91 }
     92 
     93 void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
     94   VisitSwitchCase(S);
     95   Writer.AddStmt(S->getSubStmt());
     96   Writer.AddSourceLocation(S->getDefaultLoc(), Record);
     97   Writer.AddSourceLocation(S->getColonLoc(), Record);
     98   Code = serialization::STMT_DEFAULT;
     99 }
    100 
    101 void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
    102   VisitStmt(S);
    103   Writer.AddDeclRef(S->getDecl(), Record);
    104   Writer.AddStmt(S->getSubStmt());
    105   Writer.AddSourceLocation(S->getIdentLoc(), Record);
    106   Code = serialization::STMT_LABEL;
    107 }
    108 
    109 void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
    110   VisitStmt(S);
    111   Writer.AddDeclRef(S->getConditionVariable(), Record);
    112   Writer.AddStmt(S->getCond());
    113   Writer.AddStmt(S->getThen());
    114   Writer.AddStmt(S->getElse());
    115   Writer.AddSourceLocation(S->getIfLoc(), Record);
    116   Writer.AddSourceLocation(S->getElseLoc(), Record);
    117   Code = serialization::STMT_IF;
    118 }
    119 
    120 void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
    121   VisitStmt(S);
    122   Writer.AddDeclRef(S->getConditionVariable(), Record);
    123   Writer.AddStmt(S->getCond());
    124   Writer.AddStmt(S->getBody());
    125   Writer.AddSourceLocation(S->getSwitchLoc(), Record);
    126   Record.push_back(S->isAllEnumCasesCovered());
    127   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
    128        SC = SC->getNextSwitchCase())
    129     Record.push_back(Writer.RecordSwitchCaseID(SC));
    130   Code = serialization::STMT_SWITCH;
    131 }
    132 
    133 void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
    134   VisitStmt(S);
    135   Writer.AddDeclRef(S->getConditionVariable(), Record);
    136   Writer.AddStmt(S->getCond());
    137   Writer.AddStmt(S->getBody());
    138   Writer.AddSourceLocation(S->getWhileLoc(), Record);
    139   Code = serialization::STMT_WHILE;
    140 }
    141 
    142 void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
    143   VisitStmt(S);
    144   Writer.AddStmt(S->getCond());
    145   Writer.AddStmt(S->getBody());
    146   Writer.AddSourceLocation(S->getDoLoc(), Record);
    147   Writer.AddSourceLocation(S->getWhileLoc(), Record);
    148   Writer.AddSourceLocation(S->getRParenLoc(), Record);
    149   Code = serialization::STMT_DO;
    150 }
    151 
    152 void ASTStmtWriter::VisitForStmt(ForStmt *S) {
    153   VisitStmt(S);
    154   Writer.AddStmt(S->getInit());
    155   Writer.AddStmt(S->getCond());
    156   Writer.AddDeclRef(S->getConditionVariable(), Record);
    157   Writer.AddStmt(S->getInc());
    158   Writer.AddStmt(S->getBody());
    159   Writer.AddSourceLocation(S->getForLoc(), Record);
    160   Writer.AddSourceLocation(S->getLParenLoc(), Record);
    161   Writer.AddSourceLocation(S->getRParenLoc(), Record);
    162   Code = serialization::STMT_FOR;
    163 }
    164 
    165 void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
    166   VisitStmt(S);
    167   Writer.AddDeclRef(S->getLabel(), Record);
    168   Writer.AddSourceLocation(S->getGotoLoc(), Record);
    169   Writer.AddSourceLocation(S->getLabelLoc(), Record);
    170   Code = serialization::STMT_GOTO;
    171 }
    172 
    173 void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
    174   VisitStmt(S);
    175   Writer.AddSourceLocation(S->getGotoLoc(), Record);
    176   Writer.AddSourceLocation(S->getStarLoc(), Record);
    177   Writer.AddStmt(S->getTarget());
    178   Code = serialization::STMT_INDIRECT_GOTO;
    179 }
    180 
    181 void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
    182   VisitStmt(S);
    183   Writer.AddSourceLocation(S->getContinueLoc(), Record);
    184   Code = serialization::STMT_CONTINUE;
    185 }
    186 
    187 void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
    188   VisitStmt(S);
    189   Writer.AddSourceLocation(S->getBreakLoc(), Record);
    190   Code = serialization::STMT_BREAK;
    191 }
    192 
    193 void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
    194   VisitStmt(S);
    195   Writer.AddStmt(S->getRetValue());
    196   Writer.AddSourceLocation(S->getReturnLoc(), Record);
    197   Writer.AddDeclRef(S->getNRVOCandidate(), Record);
    198   Code = serialization::STMT_RETURN;
    199 }
    200 
    201 void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
    202   VisitStmt(S);
    203   Writer.AddSourceLocation(S->getStartLoc(), Record);
    204   Writer.AddSourceLocation(S->getEndLoc(), Record);
    205   DeclGroupRef DG = S->getDeclGroup();
    206   for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
    207     Writer.AddDeclRef(*D, Record);
    208   Code = serialization::STMT_DECL;
    209 }
    210 
    211 void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
    212   VisitStmt(S);
    213   Record.push_back(S->getNumOutputs());
    214   Record.push_back(S->getNumInputs());
    215   Record.push_back(S->getNumClobbers());
    216   Writer.AddSourceLocation(S->getAsmLoc(), Record);
    217   Writer.AddSourceLocation(S->getRParenLoc(), Record);
    218   Record.push_back(S->isVolatile());
    219   Record.push_back(S->isSimple());
    220   Record.push_back(S->isMSAsm());
    221   Writer.AddStmt(S->getAsmString());
    222 
    223   // Outputs
    224   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
    225     Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
    226     Writer.AddStmt(S->getOutputConstraintLiteral(I));
    227     Writer.AddStmt(S->getOutputExpr(I));
    228   }
    229 
    230   // Inputs
    231   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
    232     Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
    233     Writer.AddStmt(S->getInputConstraintLiteral(I));
    234     Writer.AddStmt(S->getInputExpr(I));
    235   }
    236 
    237   // Clobbers
    238   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
    239     Writer.AddStmt(S->getClobber(I));
    240 
    241   Code = serialization::STMT_ASM;
    242 }
    243 
    244 void ASTStmtWriter::VisitExpr(Expr *E) {
    245   VisitStmt(E);
    246   Writer.AddTypeRef(E->getType(), Record);
    247   Record.push_back(E->isTypeDependent());
    248   Record.push_back(E->isValueDependent());
    249   Record.push_back(E->isInstantiationDependent());
    250   Record.push_back(E->containsUnexpandedParameterPack());
    251   Record.push_back(E->getValueKind());
    252   Record.push_back(E->getObjectKind());
    253 }
    254 
    255 void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
    256   VisitExpr(E);
    257   Writer.AddSourceLocation(E->getLocation(), Record);
    258   Record.push_back(E->getIdentType()); // FIXME: stable encoding
    259   Code = serialization::EXPR_PREDEFINED;
    260 }
    261 
    262 void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
    263   VisitExpr(E);
    264 
    265   Record.push_back(E->hasQualifier());
    266   Record.push_back(E->getDecl() != E->getFoundDecl());
    267   Record.push_back(E->hasExplicitTemplateArgs());
    268 
    269   if (E->hasExplicitTemplateArgs()) {
    270     unsigned NumTemplateArgs = E->getNumTemplateArgs();
    271     Record.push_back(NumTemplateArgs);
    272   }
    273 
    274   DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
    275 
    276   if ((!E->hasExplicitTemplateArgs()) && (!E->hasQualifier()) &&
    277       (E->getDecl() == E->getFoundDecl()) &&
    278       nk == DeclarationName::Identifier) {
    279     AbbrevToUse = Writer.getDeclRefExprAbbrev();
    280   }
    281 
    282   if (E->hasQualifier())
    283     Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
    284 
    285   if (E->getDecl() != E->getFoundDecl())
    286     Writer.AddDeclRef(E->getFoundDecl(), Record);
    287 
    288   if (E->hasExplicitTemplateArgs())
    289     AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
    290 
    291   Writer.AddDeclRef(E->getDecl(), Record);
    292   Writer.AddSourceLocation(E->getLocation(), Record);
    293   Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
    294   Code = serialization::EXPR_DECL_REF;
    295 }
    296 
    297 void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
    298   VisitExpr(E);
    299   Writer.AddSourceLocation(E->getLocation(), Record);
    300   Writer.AddAPInt(E->getValue(), Record);
    301 
    302   if (E->getValue().getBitWidth() == 32) {
    303     AbbrevToUse = Writer.getIntegerLiteralAbbrev();
    304   }
    305 
    306   Code = serialization::EXPR_INTEGER_LITERAL;
    307 }
    308 
    309 void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
    310   VisitExpr(E);
    311   Writer.AddAPFloat(E->getValue(), Record);
    312   Record.push_back(E->isExact());
    313   Writer.AddSourceLocation(E->getLocation(), Record);
    314   Code = serialization::EXPR_FLOATING_LITERAL;
    315 }
    316 
    317 void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
    318   VisitExpr(E);
    319   Writer.AddStmt(E->getSubExpr());
    320   Code = serialization::EXPR_IMAGINARY_LITERAL;
    321 }
    322 
    323 void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
    324   VisitExpr(E);
    325   Record.push_back(E->getByteLength());
    326   Record.push_back(E->getNumConcatenated());
    327   Record.push_back(E->isWide());
    328   Record.push_back(E->isPascal());
    329   // FIXME: String data should be stored as a blob at the end of the
    330   // StringLiteral. However, we can't do so now because we have no
    331   // provision for coping with abbreviations when we're jumping around
    332   // the AST file during deserialization.
    333   Record.append(E->getString().begin(), E->getString().end());
    334   for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
    335     Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
    336   Code = serialization::EXPR_STRING_LITERAL;
    337 }
    338 
    339 void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
    340   VisitExpr(E);
    341   Record.push_back(E->getValue());
    342   Writer.AddSourceLocation(E->getLocation(), Record);
    343   Record.push_back(E->isWide());
    344 
    345   AbbrevToUse = Writer.getCharacterLiteralAbbrev();
    346 
    347   Code = serialization::EXPR_CHARACTER_LITERAL;
    348 }
    349 
    350 void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
    351   VisitExpr(E);
    352   Writer.AddSourceLocation(E->getLParen(), Record);
    353   Writer.AddSourceLocation(E->getRParen(), Record);
    354   Writer.AddStmt(E->getSubExpr());
    355   Code = serialization::EXPR_PAREN;
    356 }
    357 
    358 void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
    359   VisitExpr(E);
    360   Record.push_back(E->NumExprs);
    361   for (unsigned i=0; i != E->NumExprs; ++i)
    362     Writer.AddStmt(E->Exprs[i]);
    363   Writer.AddSourceLocation(E->LParenLoc, Record);
    364   Writer.AddSourceLocation(E->RParenLoc, Record);
    365   Code = serialization::EXPR_PAREN_LIST;
    366 }
    367 
    368 void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
    369   VisitExpr(E);
    370   Writer.AddStmt(E->getSubExpr());
    371   Record.push_back(E->getOpcode()); // FIXME: stable encoding
    372   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
    373   Code = serialization::EXPR_UNARY_OPERATOR;
    374 }
    375 
    376 void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
    377   VisitExpr(E);
    378   Record.push_back(E->getNumComponents());
    379   Record.push_back(E->getNumExpressions());
    380   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
    381   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    382   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
    383   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
    384     const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
    385     Record.push_back(ON.getKind()); // FIXME: Stable encoding
    386     Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
    387     Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
    388     switch (ON.getKind()) {
    389     case OffsetOfExpr::OffsetOfNode::Array:
    390       Record.push_back(ON.getArrayExprIndex());
    391       break;
    392 
    393     case OffsetOfExpr::OffsetOfNode::Field:
    394       Writer.AddDeclRef(ON.getField(), Record);
    395       break;
    396 
    397     case OffsetOfExpr::OffsetOfNode::Identifier:
    398       Writer.AddIdentifierRef(ON.getFieldName(), Record);
    399       break;
    400 
    401     case OffsetOfExpr::OffsetOfNode::Base:
    402       Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
    403       break;
    404     }
    405   }
    406   for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
    407     Writer.AddStmt(E->getIndexExpr(I));
    408   Code = serialization::EXPR_OFFSETOF;
    409 }
    410 
    411 void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
    412   VisitExpr(E);
    413   Record.push_back(E->getKind());
    414   if (E->isArgumentType())
    415     Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
    416   else {
    417     Record.push_back(0);
    418     Writer.AddStmt(E->getArgumentExpr());
    419   }
    420   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
    421   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    422   Code = serialization::EXPR_SIZEOF_ALIGN_OF;
    423 }
    424 
    425 void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
    426   VisitExpr(E);
    427   Writer.AddStmt(E->getLHS());
    428   Writer.AddStmt(E->getRHS());
    429   Writer.AddSourceLocation(E->getRBracketLoc(), Record);
    430   Code = serialization::EXPR_ARRAY_SUBSCRIPT;
    431 }
    432 
    433 void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
    434   VisitExpr(E);
    435   Record.push_back(E->getNumArgs());
    436   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    437   Writer.AddStmt(E->getCallee());
    438   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
    439        Arg != ArgEnd; ++Arg)
    440     Writer.AddStmt(*Arg);
    441   Code = serialization::EXPR_CALL;
    442 }
    443 
    444 void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
    445   // Don't call VisitExpr, we'll write everything here.
    446 
    447   Record.push_back(E->hasQualifier());
    448   if (E->hasQualifier())
    449     Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
    450 
    451   Record.push_back(E->hasExplicitTemplateArgs());
    452   if (E->hasExplicitTemplateArgs()) {
    453     unsigned NumTemplateArgs = E->getNumTemplateArgs();
    454     Record.push_back(NumTemplateArgs);
    455     Writer.AddSourceLocation(E->getLAngleLoc(), Record);
    456     Writer.AddSourceLocation(E->getRAngleLoc(), Record);
    457     for (unsigned i=0; i != NumTemplateArgs; ++i)
    458       Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
    459   }
    460 
    461   DeclAccessPair FoundDecl = E->getFoundDecl();
    462   Writer.AddDeclRef(FoundDecl.getDecl(), Record);
    463   Record.push_back(FoundDecl.getAccess());
    464 
    465   Writer.AddTypeRef(E->getType(), Record);
    466   Record.push_back(E->getValueKind());
    467   Record.push_back(E->getObjectKind());
    468   Writer.AddStmt(E->getBase());
    469   Writer.AddDeclRef(E->getMemberDecl(), Record);
    470   Writer.AddSourceLocation(E->getMemberLoc(), Record);
    471   Record.push_back(E->isArrow());
    472   Writer.AddDeclarationNameLoc(E->MemberDNLoc,
    473                                E->getMemberDecl()->getDeclName(), Record);
    474   Code = serialization::EXPR_MEMBER;
    475 }
    476 
    477 void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
    478   VisitExpr(E);
    479   Writer.AddStmt(E->getBase());
    480   Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
    481   Record.push_back(E->isArrow());
    482   Code = serialization::EXPR_OBJC_ISA;
    483 }
    484 
    485 void ASTStmtWriter::
    486 VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
    487   VisitExpr(E);
    488   Writer.AddStmt(E->getSubExpr());
    489   Record.push_back(E->shouldCopy());
    490   Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
    491 }
    492 
    493 void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
    494   VisitExplicitCastExpr(E);
    495   Writer.AddSourceLocation(E->getLParenLoc(), Record);
    496   Writer.AddSourceLocation(E->getBridgeKeywordLoc(), Record);
    497   Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
    498   Code = serialization::EXPR_OBJC_BRIDGED_CAST;
    499 }
    500 
    501 void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
    502   VisitExpr(E);
    503   Record.push_back(E->path_size());
    504   Writer.AddStmt(E->getSubExpr());
    505   Record.push_back(E->getCastKind()); // FIXME: stable encoding
    506 
    507   for (CastExpr::path_iterator
    508          PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
    509     Writer.AddCXXBaseSpecifier(**PI, Record);
    510 }
    511 
    512 void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
    513   VisitExpr(E);
    514   Writer.AddStmt(E->getLHS());
    515   Writer.AddStmt(E->getRHS());
    516   Record.push_back(E->getOpcode()); // FIXME: stable encoding
    517   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
    518   Code = serialization::EXPR_BINARY_OPERATOR;
    519 }
    520 
    521 void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
    522   VisitBinaryOperator(E);
    523   Writer.AddTypeRef(E->getComputationLHSType(), Record);
    524   Writer.AddTypeRef(E->getComputationResultType(), Record);
    525   Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
    526 }
    527 
    528 void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
    529   VisitExpr(E);
    530   Writer.AddStmt(E->getCond());
    531   Writer.AddStmt(E->getLHS());
    532   Writer.AddStmt(E->getRHS());
    533   Writer.AddSourceLocation(E->getQuestionLoc(), Record);
    534   Writer.AddSourceLocation(E->getColonLoc(), Record);
    535   Code = serialization::EXPR_CONDITIONAL_OPERATOR;
    536 }
    537 
    538 void
    539 ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
    540   VisitExpr(E);
    541   Writer.AddStmt(E->getOpaqueValue());
    542   Writer.AddStmt(E->getCommon());
    543   Writer.AddStmt(E->getCond());
    544   Writer.AddStmt(E->getTrueExpr());
    545   Writer.AddStmt(E->getFalseExpr());
    546   Writer.AddSourceLocation(E->getQuestionLoc(), Record);
    547   Writer.AddSourceLocation(E->getColonLoc(), Record);
    548   Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
    549 }
    550 
    551 void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
    552   VisitCastExpr(E);
    553   Code = serialization::EXPR_IMPLICIT_CAST;
    554 }
    555 
    556 void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
    557   VisitCastExpr(E);
    558   Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
    559 }
    560 
    561 void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
    562   VisitExplicitCastExpr(E);
    563   Writer.AddSourceLocation(E->getLParenLoc(), Record);
    564   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    565   Code = serialization::EXPR_CSTYLE_CAST;
    566 }
    567 
    568 void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
    569   VisitExpr(E);
    570   Writer.AddSourceLocation(E->getLParenLoc(), Record);
    571   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
    572   Writer.AddStmt(E->getInitializer());
    573   Record.push_back(E->isFileScope());
    574   Code = serialization::EXPR_COMPOUND_LITERAL;
    575 }
    576 
    577 void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
    578   VisitExpr(E);
    579   Writer.AddStmt(E->getBase());
    580   Writer.AddIdentifierRef(&E->getAccessor(), Record);
    581   Writer.AddSourceLocation(E->getAccessorLoc(), Record);
    582   Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
    583 }
    584 
    585 void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
    586   VisitExpr(E);
    587   Writer.AddStmt(E->getSyntacticForm());
    588   Writer.AddSourceLocation(E->getLBraceLoc(), Record);
    589   Writer.AddSourceLocation(E->getRBraceLoc(), Record);
    590   bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
    591   Record.push_back(isArrayFiller);
    592   if (isArrayFiller)
    593     Writer.AddStmt(E->getArrayFiller());
    594   else
    595     Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
    596   Record.push_back(E->hadArrayRangeDesignator());
    597   Record.push_back(E->getNumInits());
    598   if (isArrayFiller) {
    599     // ArrayFiller may have filled "holes" due to designated initializer.
    600     // Replace them by 0 to indicate that the filler goes in that place.
    601     Expr *filler = E->getArrayFiller();
    602     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
    603       Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0);
    604   } else {
    605     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
    606       Writer.AddStmt(E->getInit(I));
    607   }
    608   Code = serialization::EXPR_INIT_LIST;
    609 }
    610 
    611 void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
    612   VisitExpr(E);
    613   Record.push_back(E->getNumSubExprs());
    614   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
    615     Writer.AddStmt(E->getSubExpr(I));
    616   Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
    617   Record.push_back(E->usesGNUSyntax());
    618   for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
    619                                              DEnd = E->designators_end();
    620        D != DEnd; ++D) {
    621     if (D->isFieldDesignator()) {
    622       if (FieldDecl *Field = D->getField()) {
    623         Record.push_back(serialization::DESIG_FIELD_DECL);
    624         Writer.AddDeclRef(Field, Record);
    625       } else {
    626         Record.push_back(serialization::DESIG_FIELD_NAME);
    627         Writer.AddIdentifierRef(D->getFieldName(), Record);
    628       }
    629       Writer.AddSourceLocation(D->getDotLoc(), Record);
    630       Writer.AddSourceLocation(D->getFieldLoc(), Record);
    631     } else if (D->isArrayDesignator()) {
    632       Record.push_back(serialization::DESIG_ARRAY);
    633       Record.push_back(D->getFirstExprIndex());
    634       Writer.AddSourceLocation(D->getLBracketLoc(), Record);
    635       Writer.AddSourceLocation(D->getRBracketLoc(), Record);
    636     } else {
    637       assert(D->isArrayRangeDesignator() && "Unknown designator");
    638       Record.push_back(serialization::DESIG_ARRAY_RANGE);
    639       Record.push_back(D->getFirstExprIndex());
    640       Writer.AddSourceLocation(D->getLBracketLoc(), Record);
    641       Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
    642       Writer.AddSourceLocation(D->getRBracketLoc(), Record);
    643     }
    644   }
    645   Code = serialization::EXPR_DESIGNATED_INIT;
    646 }
    647 
    648 void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
    649   VisitExpr(E);
    650   Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
    651 }
    652 
    653 void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
    654   VisitExpr(E);
    655   Writer.AddStmt(E->getSubExpr());
    656   Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
    657   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
    658   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    659   Code = serialization::EXPR_VA_ARG;
    660 }
    661 
    662 void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
    663   VisitExpr(E);
    664   Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
    665   Writer.AddSourceLocation(E->getLabelLoc(), Record);
    666   Writer.AddDeclRef(E->getLabel(), Record);
    667   Code = serialization::EXPR_ADDR_LABEL;
    668 }
    669 
    670 void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
    671   VisitExpr(E);
    672   Writer.AddStmt(E->getSubStmt());
    673   Writer.AddSourceLocation(E->getLParenLoc(), Record);
    674   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    675   Code = serialization::EXPR_STMT;
    676 }
    677 
    678 void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
    679   VisitExpr(E);
    680   Writer.AddStmt(E->getCond());
    681   Writer.AddStmt(E->getLHS());
    682   Writer.AddStmt(E->getRHS());
    683   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
    684   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    685   Code = serialization::EXPR_CHOOSE;
    686 }
    687 
    688 void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
    689   VisitExpr(E);
    690   Writer.AddSourceLocation(E->getTokenLocation(), Record);
    691   Code = serialization::EXPR_GNU_NULL;
    692 }
    693 
    694 void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
    695   VisitExpr(E);
    696   Record.push_back(E->getNumSubExprs());
    697   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
    698     Writer.AddStmt(E->getExpr(I));
    699   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
    700   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    701   Code = serialization::EXPR_SHUFFLE_VECTOR;
    702 }
    703 
    704 void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
    705   VisitExpr(E);
    706   Writer.AddDeclRef(E->getBlockDecl(), Record);
    707   Code = serialization::EXPR_BLOCK;
    708 }
    709 
    710 void ASTStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
    711   VisitExpr(E);
    712   Writer.AddDeclRef(E->getDecl(), Record);
    713   Writer.AddSourceLocation(E->getLocation(), Record);
    714   Record.push_back(E->isByRef());
    715   Record.push_back(E->isConstQualAdded());
    716   Code = serialization::EXPR_BLOCK_DECL_REF;
    717 }
    718 
    719 void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
    720   VisitExpr(E);
    721   Record.push_back(E->getNumAssocs());
    722 
    723   Writer.AddStmt(E->getControllingExpr());
    724   for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
    725     Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record);
    726     Writer.AddStmt(E->getAssocExpr(I));
    727   }
    728   Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
    729 
    730   Writer.AddSourceLocation(E->getGenericLoc(), Record);
    731   Writer.AddSourceLocation(E->getDefaultLoc(), Record);
    732   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    733   Code = serialization::EXPR_GENERIC_SELECTION;
    734 }
    735 
    736 //===----------------------------------------------------------------------===//
    737 // Objective-C Expressions and Statements.
    738 //===----------------------------------------------------------------------===//
    739 
    740 void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
    741   VisitExpr(E);
    742   Writer.AddStmt(E->getString());
    743   Writer.AddSourceLocation(E->getAtLoc(), Record);
    744   Code = serialization::EXPR_OBJC_STRING_LITERAL;
    745 }
    746 
    747 void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
    748   VisitExpr(E);
    749   Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
    750   Writer.AddSourceLocation(E->getAtLoc(), Record);
    751   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    752   Code = serialization::EXPR_OBJC_ENCODE;
    753 }
    754 
    755 void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
    756   VisitExpr(E);
    757   Writer.AddSelectorRef(E->getSelector(), Record);
    758   Writer.AddSourceLocation(E->getAtLoc(), Record);
    759   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    760   Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
    761 }
    762 
    763 void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
    764   VisitExpr(E);
    765   Writer.AddDeclRef(E->getProtocol(), Record);
    766   Writer.AddSourceLocation(E->getAtLoc(), Record);
    767   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    768   Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
    769 }
    770 
    771 void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
    772   VisitExpr(E);
    773   Writer.AddDeclRef(E->getDecl(), Record);
    774   Writer.AddSourceLocation(E->getLocation(), Record);
    775   Writer.AddStmt(E->getBase());
    776   Record.push_back(E->isArrow());
    777   Record.push_back(E->isFreeIvar());
    778   Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
    779 }
    780 
    781 void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
    782   VisitExpr(E);
    783   Record.push_back(E->isImplicitProperty());
    784   if (E->isImplicitProperty()) {
    785     Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
    786     Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
    787   } else {
    788     Writer.AddDeclRef(E->getExplicitProperty(), Record);
    789   }
    790   Writer.AddSourceLocation(E->getLocation(), Record);
    791   Writer.AddSourceLocation(E->getReceiverLocation(), Record);
    792   if (E->isObjectReceiver()) {
    793     Record.push_back(0);
    794     Writer.AddStmt(E->getBase());
    795   } else if (E->isSuperReceiver()) {
    796     Record.push_back(1);
    797     Writer.AddTypeRef(E->getSuperReceiverType(), Record);
    798   } else {
    799     Record.push_back(2);
    800     Writer.AddDeclRef(E->getClassReceiver(), Record);
    801   }
    802 
    803   Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
    804 }
    805 
    806 void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
    807   VisitExpr(E);
    808   Record.push_back(E->getNumArgs());
    809   Record.push_back(E->isDelegateInitCall());
    810   Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
    811   switch (E->getReceiverKind()) {
    812   case ObjCMessageExpr::Instance:
    813     Writer.AddStmt(E->getInstanceReceiver());
    814     break;
    815 
    816   case ObjCMessageExpr::Class:
    817     Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
    818     break;
    819 
    820   case ObjCMessageExpr::SuperClass:
    821   case ObjCMessageExpr::SuperInstance:
    822     Writer.AddTypeRef(E->getSuperType(), Record);
    823     Writer.AddSourceLocation(E->getSuperLoc(), Record);
    824     break;
    825   }
    826 
    827   if (E->getMethodDecl()) {
    828     Record.push_back(1);
    829     Writer.AddDeclRef(E->getMethodDecl(), Record);
    830   } else {
    831     Record.push_back(0);
    832     Writer.AddSelectorRef(E->getSelector(), Record);
    833   }
    834 
    835   Writer.AddSourceLocation(E->getLeftLoc(), Record);
    836   Writer.AddSourceLocation(E->getRightLoc(), Record);
    837   Writer.AddSourceLocation(E->getSelectorLoc(), Record);
    838 
    839   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
    840        Arg != ArgEnd; ++Arg)
    841     Writer.AddStmt(*Arg);
    842   Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
    843 }
    844 
    845 void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
    846   VisitStmt(S);
    847   Writer.AddStmt(S->getElement());
    848   Writer.AddStmt(S->getCollection());
    849   Writer.AddStmt(S->getBody());
    850   Writer.AddSourceLocation(S->getForLoc(), Record);
    851   Writer.AddSourceLocation(S->getRParenLoc(), Record);
    852   Code = serialization::STMT_OBJC_FOR_COLLECTION;
    853 }
    854 
    855 void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
    856   Writer.AddStmt(S->getCatchBody());
    857   Writer.AddDeclRef(S->getCatchParamDecl(), Record);
    858   Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
    859   Writer.AddSourceLocation(S->getRParenLoc(), Record);
    860   Code = serialization::STMT_OBJC_CATCH;
    861 }
    862 
    863 void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
    864   Writer.AddStmt(S->getFinallyBody());
    865   Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
    866   Code = serialization::STMT_OBJC_FINALLY;
    867 }
    868 
    869 void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
    870   Writer.AddStmt(S->getSubStmt());
    871   Writer.AddSourceLocation(S->getAtLoc(), Record);
    872   Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
    873 }
    874 
    875 void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
    876   Record.push_back(S->getNumCatchStmts());
    877   Record.push_back(S->getFinallyStmt() != 0);
    878   Writer.AddStmt(S->getTryBody());
    879   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
    880     Writer.AddStmt(S->getCatchStmt(I));
    881   if (S->getFinallyStmt())
    882     Writer.AddStmt(S->getFinallyStmt());
    883   Writer.AddSourceLocation(S->getAtTryLoc(), Record);
    884   Code = serialization::STMT_OBJC_AT_TRY;
    885 }
    886 
    887 void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
    888   Writer.AddStmt(S->getSynchExpr());
    889   Writer.AddStmt(S->getSynchBody());
    890   Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
    891   Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
    892 }
    893 
    894 void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
    895   Writer.AddStmt(S->getThrowExpr());
    896   Writer.AddSourceLocation(S->getThrowLoc(), Record);
    897   Code = serialization::STMT_OBJC_AT_THROW;
    898 }
    899 
    900 //===----------------------------------------------------------------------===//
    901 // C++ Expressions and Statements.
    902 //===----------------------------------------------------------------------===//
    903 
    904 void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
    905   VisitStmt(S);
    906   Writer.AddSourceLocation(S->getCatchLoc(), Record);
    907   Writer.AddDeclRef(S->getExceptionDecl(), Record);
    908   Writer.AddStmt(S->getHandlerBlock());
    909   Code = serialization::STMT_CXX_CATCH;
    910 }
    911 
    912 void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
    913   VisitStmt(S);
    914   Record.push_back(S->getNumHandlers());
    915   Writer.AddSourceLocation(S->getTryLoc(), Record);
    916   Writer.AddStmt(S->getTryBlock());
    917   for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
    918     Writer.AddStmt(S->getHandler(i));
    919   Code = serialization::STMT_CXX_TRY;
    920 }
    921 
    922 void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
    923   VisitStmt(S);
    924   Writer.AddSourceLocation(S->getForLoc(), Record);
    925   Writer.AddSourceLocation(S->getColonLoc(), Record);
    926   Writer.AddSourceLocation(S->getRParenLoc(), Record);
    927   Writer.AddStmt(S->getRangeStmt());
    928   Writer.AddStmt(S->getBeginEndStmt());
    929   Writer.AddStmt(S->getCond());
    930   Writer.AddStmt(S->getInc());
    931   Writer.AddStmt(S->getLoopVarStmt());
    932   Writer.AddStmt(S->getBody());
    933   Code = serialization::STMT_CXX_FOR_RANGE;
    934 }
    935 
    936 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
    937   VisitCallExpr(E);
    938   Record.push_back(E->getOperator());
    939   Code = serialization::EXPR_CXX_OPERATOR_CALL;
    940 }
    941 
    942 void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
    943   VisitCallExpr(E);
    944   Code = serialization::EXPR_CXX_MEMBER_CALL;
    945 }
    946 
    947 void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
    948   VisitExpr(E);
    949   Record.push_back(E->getNumArgs());
    950   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
    951     Writer.AddStmt(E->getArg(I));
    952   Writer.AddDeclRef(E->getConstructor(), Record);
    953   Writer.AddSourceLocation(E->getLocation(), Record);
    954   Record.push_back(E->isElidable());
    955   Record.push_back(E->requiresZeroInitialization());
    956   Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
    957   Writer.AddSourceRange(E->getParenRange(), Record);
    958   Code = serialization::EXPR_CXX_CONSTRUCT;
    959 }
    960 
    961 void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
    962   VisitCXXConstructExpr(E);
    963   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
    964   Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
    965 }
    966 
    967 void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
    968   VisitExplicitCastExpr(E);
    969   Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
    970                         Record);
    971 }
    972 
    973 void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
    974   VisitCXXNamedCastExpr(E);
    975   Code = serialization::EXPR_CXX_STATIC_CAST;
    976 }
    977 
    978 void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
    979   VisitCXXNamedCastExpr(E);
    980   Code = serialization::EXPR_CXX_DYNAMIC_CAST;
    981 }
    982 
    983 void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
    984   VisitCXXNamedCastExpr(E);
    985   Code = serialization::EXPR_CXX_REINTERPRET_CAST;
    986 }
    987 
    988 void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
    989   VisitCXXNamedCastExpr(E);
    990   Code = serialization::EXPR_CXX_CONST_CAST;
    991 }
    992 
    993 void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
    994   VisitExplicitCastExpr(E);
    995   Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
    996   Writer.AddSourceLocation(E->getRParenLoc(), Record);
    997   Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
    998 }
    999 
   1000 void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
   1001   VisitExpr(E);
   1002   Record.push_back(E->getValue());
   1003   Writer.AddSourceLocation(E->getLocation(), Record);
   1004   Code = serialization::EXPR_CXX_BOOL_LITERAL;
   1005 }
   1006 
   1007 void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
   1008   VisitExpr(E);
   1009   Writer.AddSourceLocation(E->getLocation(), Record);
   1010   Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
   1011 }
   1012 
   1013 void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
   1014   VisitExpr(E);
   1015   Writer.AddSourceRange(E->getSourceRange(), Record);
   1016   if (E->isTypeOperand()) {
   1017     Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
   1018     Code = serialization::EXPR_CXX_TYPEID_TYPE;
   1019   } else {
   1020     Writer.AddStmt(E->getExprOperand());
   1021     Code = serialization::EXPR_CXX_TYPEID_EXPR;
   1022   }
   1023 }
   1024 
   1025 void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
   1026   VisitExpr(E);
   1027   Writer.AddSourceLocation(E->getLocation(), Record);
   1028   Record.push_back(E->isImplicit());
   1029   Code = serialization::EXPR_CXX_THIS;
   1030 }
   1031 
   1032 void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
   1033   VisitExpr(E);
   1034   Writer.AddSourceLocation(E->getThrowLoc(), Record);
   1035   Writer.AddStmt(E->getSubExpr());
   1036   Record.push_back(E->isThrownVariableInScope());
   1037   Code = serialization::EXPR_CXX_THROW;
   1038 }
   1039 
   1040 void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   1041   VisitExpr(E);
   1042 
   1043   bool HasOtherExprStored = E->Param.getInt();
   1044   // Store these first, the reader reads them before creation.
   1045   Record.push_back(HasOtherExprStored);
   1046   if (HasOtherExprStored)
   1047     Writer.AddStmt(E->getExpr());
   1048   Writer.AddDeclRef(E->getParam(), Record);
   1049   Writer.AddSourceLocation(E->getUsedLocation(), Record);
   1050 
   1051   Code = serialization::EXPR_CXX_DEFAULT_ARG;
   1052 }
   1053 
   1054 void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
   1055   VisitExpr(E);
   1056   Writer.AddCXXTemporary(E->getTemporary(), Record);
   1057   Writer.AddStmt(E->getSubExpr());
   1058   Code = serialization::EXPR_CXX_BIND_TEMPORARY;
   1059 }
   1060 
   1061 void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   1062   VisitExpr(E);
   1063   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
   1064   Writer.AddSourceLocation(E->getRParenLoc(), Record);
   1065   Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
   1066 }
   1067 
   1068 void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
   1069   VisitExpr(E);
   1070   Record.push_back(E->isGlobalNew());
   1071   Record.push_back(E->hasInitializer());
   1072   Record.push_back(E->doesUsualArrayDeleteWantSize());
   1073   Record.push_back(E->isArray());
   1074   Record.push_back(E->getNumPlacementArgs());
   1075   Record.push_back(E->getNumConstructorArgs());
   1076   Writer.AddDeclRef(E->getOperatorNew(), Record);
   1077   Writer.AddDeclRef(E->getOperatorDelete(), Record);
   1078   Writer.AddDeclRef(E->getConstructor(), Record);
   1079   Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
   1080   Writer.AddSourceRange(E->getTypeIdParens(), Record);
   1081   Writer.AddSourceLocation(E->getStartLoc(), Record);
   1082   Writer.AddSourceLocation(E->getEndLoc(), Record);
   1083   Writer.AddSourceLocation(E->getConstructorLParen(), Record);
   1084   Writer.AddSourceLocation(E->getConstructorRParen(), Record);
   1085   for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
   1086        I != e; ++I)
   1087     Writer.AddStmt(*I);
   1088 
   1089   Code = serialization::EXPR_CXX_NEW;
   1090 }
   1091 
   1092 void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
   1093   VisitExpr(E);
   1094   Record.push_back(E->isGlobalDelete());
   1095   Record.push_back(E->isArrayForm());
   1096   Record.push_back(E->isArrayFormAsWritten());
   1097   Record.push_back(E->doesUsualArrayDeleteWantSize());
   1098   Writer.AddDeclRef(E->getOperatorDelete(), Record);
   1099   Writer.AddStmt(E->getArgument());
   1100   Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
   1101 
   1102   Code = serialization::EXPR_CXX_DELETE;
   1103 }
   1104 
   1105 void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
   1106   VisitExpr(E);
   1107 
   1108   Writer.AddStmt(E->getBase());
   1109   Record.push_back(E->isArrow());
   1110   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
   1111   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
   1112   Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
   1113   Writer.AddSourceLocation(E->getColonColonLoc(), Record);
   1114   Writer.AddSourceLocation(E->getTildeLoc(), Record);
   1115 
   1116   // PseudoDestructorTypeStorage.
   1117   Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
   1118   if (E->getDestroyedTypeIdentifier())
   1119     Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
   1120   else
   1121     Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
   1122 
   1123   Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
   1124 }
   1125 
   1126 void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
   1127   VisitExpr(E);
   1128   Record.push_back(E->getNumTemporaries());
   1129   for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i)
   1130     Writer.AddCXXTemporary(E->getTemporary(i), Record);
   1131 
   1132   Writer.AddStmt(E->getSubExpr());
   1133   Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
   1134 }
   1135 
   1136 void
   1137 ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
   1138   VisitExpr(E);
   1139 
   1140   // Don't emit anything here, hasExplicitTemplateArgs() must be
   1141   // emitted first.
   1142 
   1143   Record.push_back(E->hasExplicitTemplateArgs());
   1144   if (E->hasExplicitTemplateArgs()) {
   1145     const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
   1146     Record.push_back(Args.NumTemplateArgs);
   1147     AddExplicitTemplateArgumentList(Args);
   1148   }
   1149 
   1150   if (!E->isImplicitAccess())
   1151     Writer.AddStmt(E->getBase());
   1152   else
   1153     Writer.AddStmt(0);
   1154   Writer.AddTypeRef(E->getBaseType(), Record);
   1155   Record.push_back(E->isArrow());
   1156   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
   1157   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
   1158   Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
   1159   Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
   1160   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
   1161 }
   1162 
   1163 void
   1164 ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
   1165   VisitExpr(E);
   1166 
   1167   // Don't emit anything here, hasExplicitTemplateArgs() must be
   1168   // emitted first.
   1169   Record.push_back(E->hasExplicitTemplateArgs());
   1170   if (E->hasExplicitTemplateArgs()) {
   1171     const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
   1172     Record.push_back(Args.NumTemplateArgs);
   1173     AddExplicitTemplateArgumentList(Args);
   1174   }
   1175 
   1176   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
   1177   Writer.AddDeclarationNameInfo(E->NameInfo, Record);
   1178   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
   1179 }
   1180 
   1181 void
   1182 ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
   1183   VisitExpr(E);
   1184   Record.push_back(E->arg_size());
   1185   for (CXXUnresolvedConstructExpr::arg_iterator
   1186          ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
   1187     Writer.AddStmt(*ArgI);
   1188   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
   1189   Writer.AddSourceLocation(E->getLParenLoc(), Record);
   1190   Writer.AddSourceLocation(E->getRParenLoc(), Record);
   1191   Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
   1192 }
   1193 
   1194 void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
   1195   VisitExpr(E);
   1196 
   1197   // Don't emit anything here, hasExplicitTemplateArgs() must be emitted first.
   1198   Record.push_back(E->hasExplicitTemplateArgs());
   1199   if (E->hasExplicitTemplateArgs()) {
   1200     const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
   1201     Record.push_back(Args.NumTemplateArgs);
   1202     AddExplicitTemplateArgumentList(Args);
   1203   }
   1204 
   1205   Record.push_back(E->getNumDecls());
   1206   for (OverloadExpr::decls_iterator
   1207          OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
   1208     Writer.AddDeclRef(OvI.getDecl(), Record);
   1209     Record.push_back(OvI.getAccess());
   1210   }
   1211 
   1212   Writer.AddDeclarationNameInfo(E->NameInfo, Record);
   1213   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
   1214 }
   1215 
   1216 void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
   1217   VisitOverloadExpr(E);
   1218   Record.push_back(E->isArrow());
   1219   Record.push_back(E->hasUnresolvedUsing());
   1220   Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
   1221   Writer.AddTypeRef(E->getBaseType(), Record);
   1222   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
   1223   Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
   1224 }
   1225 
   1226 void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
   1227   VisitOverloadExpr(E);
   1228   Record.push_back(E->requiresADL());
   1229   if (E->requiresADL())
   1230     Record.push_back(E->isStdAssociatedNamespace());
   1231   Record.push_back(E->isOverloaded());
   1232   Writer.AddDeclRef(E->getNamingClass(), Record);
   1233   Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
   1234 }
   1235 
   1236 void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
   1237   VisitExpr(E);
   1238   Record.push_back(E->getTrait());
   1239   Record.push_back(E->getValue());
   1240   Writer.AddSourceRange(E->getSourceRange(), Record);
   1241   Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
   1242   Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
   1243 }
   1244 
   1245 void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
   1246   VisitExpr(E);
   1247   Record.push_back(E->getTrait());
   1248   Record.push_back(E->getValue());
   1249   Writer.AddSourceRange(E->getSourceRange(), Record);
   1250   Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
   1251   Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
   1252   Code = serialization::EXPR_BINARY_TYPE_TRAIT;
   1253 }
   1254 
   1255 void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
   1256   VisitExpr(E);
   1257   Record.push_back(E->getTrait());
   1258   Record.push_back(E->getValue());
   1259   Writer.AddSourceRange(E->getSourceRange(), Record);
   1260   Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
   1261   Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
   1262 }
   1263 
   1264 void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
   1265   VisitExpr(E);
   1266   Record.push_back(E->getTrait());
   1267   Record.push_back(E->getValue());
   1268   Writer.AddSourceRange(E->getSourceRange(), Record);
   1269   Writer.AddStmt(E->getQueriedExpression());
   1270   Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
   1271 }
   1272 
   1273 void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
   1274   VisitExpr(E);
   1275   Record.push_back(E->getValue());
   1276   Writer.AddSourceRange(E->getSourceRange(), Record);
   1277   Writer.AddStmt(E->getOperand());
   1278   Code = serialization::EXPR_CXX_NOEXCEPT;
   1279 }
   1280 
   1281 void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
   1282   VisitExpr(E);
   1283   Writer.AddSourceLocation(E->getEllipsisLoc(), Record);
   1284   Record.push_back(E->NumExpansions);
   1285   Writer.AddStmt(E->getPattern());
   1286   Code = serialization::EXPR_PACK_EXPANSION;
   1287 }
   1288 
   1289 void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
   1290   VisitExpr(E);
   1291   Writer.AddSourceLocation(E->OperatorLoc, Record);
   1292   Writer.AddSourceLocation(E->PackLoc, Record);
   1293   Writer.AddSourceLocation(E->RParenLoc, Record);
   1294   Record.push_back(E->Length);
   1295   Writer.AddDeclRef(E->Pack, Record);
   1296   Code = serialization::EXPR_SIZEOF_PACK;
   1297 }
   1298 
   1299 void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
   1300                                               SubstNonTypeTemplateParmExpr *E) {
   1301   VisitExpr(E);
   1302   Writer.AddDeclRef(E->getParameter(), Record);
   1303   Writer.AddSourceLocation(E->getNameLoc(), Record);
   1304   Writer.AddStmt(E->getReplacement());
   1305   Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
   1306 }
   1307 
   1308 void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
   1309                                           SubstNonTypeTemplateParmPackExpr *E) {
   1310   VisitExpr(E);
   1311   Writer.AddDeclRef(E->getParameterPack(), Record);
   1312   Writer.AddTemplateArgument(E->getArgumentPack(), Record);
   1313   Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
   1314   Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
   1315 }
   1316 
   1317 void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
   1318   VisitExpr(E);
   1319   Writer.AddStmt(E->Temporary);
   1320   Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
   1321 }
   1322 
   1323 void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
   1324   VisitExpr(E);
   1325   Record.push_back(Writer.getOpaqueValueID(E));
   1326   Writer.AddSourceLocation(E->getLocation(), Record);
   1327   Code = serialization::EXPR_OPAQUE_VALUE;
   1328 }
   1329 
   1330 //===----------------------------------------------------------------------===//
   1331 // CUDA Expressions and Statements.
   1332 //===----------------------------------------------------------------------===//
   1333 
   1334 void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
   1335   VisitCallExpr(E);
   1336   Writer.AddStmt(E->getConfig());
   1337   Code = serialization::EXPR_CUDA_KERNEL_CALL;
   1338 }
   1339 
   1340 //===----------------------------------------------------------------------===//
   1341 // OpenCL Expressions and Statements.
   1342 //===----------------------------------------------------------------------===//
   1343 void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
   1344   VisitExpr(E);
   1345   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
   1346   Writer.AddSourceLocation(E->getRParenLoc(), Record);
   1347   Writer.AddStmt(E->getSrcExpr());
   1348   Code = serialization::EXPR_ASTYPE;
   1349 }
   1350 
   1351 //===----------------------------------------------------------------------===//
   1352 // Microsoft Expressions and Statements.
   1353 //===----------------------------------------------------------------------===//
   1354 void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
   1355   VisitExpr(E);
   1356   Writer.AddSourceRange(E->getSourceRange(), Record);
   1357   if (E->isTypeOperand()) {
   1358     Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
   1359     Code = serialization::EXPR_CXX_UUIDOF_TYPE;
   1360   } else {
   1361     Writer.AddStmt(E->getExprOperand());
   1362     Code = serialization::EXPR_CXX_UUIDOF_EXPR;
   1363   }
   1364 }
   1365 
   1366 void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
   1367   VisitStmt(S);
   1368   Writer.AddSourceLocation(S->getExceptLoc(), Record);
   1369   Writer.AddStmt(S->getFilterExpr());
   1370   Writer.AddStmt(S->getBlock());
   1371   Code = serialization::STMT_SEH_EXCEPT;
   1372 }
   1373 
   1374 void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
   1375   VisitStmt(S);
   1376   Writer.AddSourceLocation(S->getFinallyLoc(), Record);
   1377   Writer.AddStmt(S->getBlock());
   1378   Code = serialization::STMT_SEH_FINALLY;
   1379 }
   1380 
   1381 void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
   1382   VisitStmt(S);
   1383   Record.push_back(S->getIsCXXTry());
   1384   Writer.AddSourceLocation(S->getTryLoc(), Record);
   1385   Writer.AddStmt(S->getTryBlock());
   1386   Writer.AddStmt(S->getHandler());
   1387   Code = serialization::STMT_SEH_TRY;
   1388 }
   1389 
   1390 //===----------------------------------------------------------------------===//
   1391 // ASTWriter Implementation
   1392 //===----------------------------------------------------------------------===//
   1393 
   1394 unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
   1395   assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
   1396          "SwitchCase recorded twice");
   1397   unsigned NextID = SwitchCaseIDs.size();
   1398   SwitchCaseIDs[S] = NextID;
   1399   return NextID;
   1400 }
   1401 
   1402 unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
   1403   assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
   1404          "SwitchCase hasn't been seen yet");
   1405   return SwitchCaseIDs[S];
   1406 }
   1407 
   1408 void ASTWriter::ClearSwitchCaseIDs() {
   1409   SwitchCaseIDs.clear();
   1410 }
   1411 
   1412 unsigned ASTWriter::getOpaqueValueID(OpaqueValueExpr *e) {
   1413   unsigned &entry = OpaqueValues[e];
   1414   if (!entry) entry = OpaqueValues.size();
   1415   return entry;
   1416 }
   1417 
   1418 /// \brief Write the given substatement or subexpression to the
   1419 /// bitstream.
   1420 void ASTWriter::WriteSubStmt(Stmt *S) {
   1421   RecordData Record;
   1422   ASTStmtWriter Writer(*this, Record);
   1423   ++NumStatements;
   1424 
   1425   if (!S) {
   1426     Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
   1427     return;
   1428   }
   1429 
   1430   // Redirect ASTWriter::AddStmt to collect sub stmts.
   1431   llvm::SmallVector<Stmt *, 16> SubStmts;
   1432   CollectedStmts = &SubStmts;
   1433 
   1434   Writer.Code = serialization::STMT_NULL_PTR;
   1435   Writer.AbbrevToUse = 0;
   1436   Writer.Visit(S);
   1437 
   1438 #ifndef NDEBUG
   1439   if (Writer.Code == serialization::STMT_NULL_PTR) {
   1440     SourceManager &SrcMgr
   1441       = DeclIDs.begin()->first->getASTContext().getSourceManager();
   1442     S->dump(SrcMgr);
   1443     assert(0 && "Unhandled sub statement writing AST file");
   1444   }
   1445 #endif
   1446 
   1447   // Revert ASTWriter::AddStmt.
   1448   CollectedStmts = &StmtsToEmit;
   1449 
   1450   // Write the sub stmts in reverse order, last to first. When reading them back
   1451   // we will read them in correct order by "pop"ing them from the Stmts stack.
   1452   // This simplifies reading and allows to store a variable number of sub stmts
   1453   // without knowing it in advance.
   1454   while (!SubStmts.empty())
   1455     WriteSubStmt(SubStmts.pop_back_val());
   1456 
   1457   Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
   1458 }
   1459 
   1460 /// \brief Flush all of the statements that have been added to the
   1461 /// queue via AddStmt().
   1462 void ASTWriter::FlushStmts() {
   1463   RecordData Record;
   1464 
   1465   for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
   1466     WriteSubStmt(StmtsToEmit[I]);
   1467 
   1468     assert(N == StmtsToEmit.size() &&
   1469            "Substatement written via AddStmt rather than WriteSubStmt!");
   1470 
   1471     // Note that we are at the end of a full expression. Any
   1472     // expression records that follow this one are part of a different
   1473     // expression.
   1474     Stream.EmitRecord(serialization::STMT_STOP, Record);
   1475   }
   1476 
   1477   StmtsToEmit.clear();
   1478 }
   1479