clang API Documentation

ASTWriterStmt.cpp
Go to the documentation of this file.
00001 //===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 ///
00010 /// \file
00011 /// \brief Implements serialization for Statements and Expressions.
00012 ///
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/Serialization/ASTWriter.h"
00016 #include "clang/AST/ASTContext.h"
00017 #include "clang/AST/DeclCXX.h"
00018 #include "clang/AST/DeclObjC.h"
00019 #include "clang/AST/DeclTemplate.h"
00020 #include "clang/AST/StmtVisitor.h"
00021 #include "clang/Lex/Token.h"
00022 #include "llvm/Bitcode/BitstreamWriter.h"
00023 using namespace clang;
00024 
00025 //===----------------------------------------------------------------------===//
00026 // Statement/expression serialization
00027 //===----------------------------------------------------------------------===//
00028 
00029 namespace clang {
00030 
00031   class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
00032     friend class OMPClauseWriter;
00033     ASTWriter &Writer;
00034     ASTWriter::RecordData &Record;
00035 
00036   public:
00037     serialization::StmtCode Code;
00038     unsigned AbbrevToUse;
00039 
00040     ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
00041       : Writer(Writer), Record(Record) { }
00042 
00043     void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args);
00044 
00045     void VisitStmt(Stmt *S);
00046 #define STMT(Type, Base) \
00047     void Visit##Type(Type *);
00048 #include "clang/AST/StmtNodes.inc"
00049   };
00050 }
00051 
00052 void ASTStmtWriter::
00053 AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) {
00054   Writer.AddSourceLocation(Args.getTemplateKeywordLoc(), Record);
00055   Writer.AddSourceLocation(Args.LAngleLoc, Record);
00056   Writer.AddSourceLocation(Args.RAngleLoc, Record);
00057   for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
00058     Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
00059 }
00060 
00061 void ASTStmtWriter::VisitStmt(Stmt *S) {
00062 }
00063 
00064 void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
00065   VisitStmt(S);
00066   Writer.AddSourceLocation(S->getSemiLoc(), Record);
00067   Record.push_back(S->HasLeadingEmptyMacro);
00068   Code = serialization::STMT_NULL;
00069 }
00070 
00071 void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
00072   VisitStmt(S);
00073   Record.push_back(S->size());
00074   for (auto *CS : S->body())
00075     Writer.AddStmt(CS);
00076   Writer.AddSourceLocation(S->getLBracLoc(), Record);
00077   Writer.AddSourceLocation(S->getRBracLoc(), Record);
00078   Code = serialization::STMT_COMPOUND;
00079 }
00080 
00081 void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
00082   VisitStmt(S);
00083   Record.push_back(Writer.getSwitchCaseID(S));
00084   Writer.AddSourceLocation(S->getKeywordLoc(), Record);
00085   Writer.AddSourceLocation(S->getColonLoc(), Record);
00086 }
00087 
00088 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
00089   VisitSwitchCase(S);
00090   Writer.AddStmt(S->getLHS());
00091   Writer.AddStmt(S->getRHS());
00092   Writer.AddStmt(S->getSubStmt());
00093   Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
00094   Code = serialization::STMT_CASE;
00095 }
00096 
00097 void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
00098   VisitSwitchCase(S);
00099   Writer.AddStmt(S->getSubStmt());
00100   Code = serialization::STMT_DEFAULT;
00101 }
00102 
00103 void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
00104   VisitStmt(S);
00105   Writer.AddDeclRef(S->getDecl(), Record);
00106   Writer.AddStmt(S->getSubStmt());
00107   Writer.AddSourceLocation(S->getIdentLoc(), Record);
00108   Code = serialization::STMT_LABEL;
00109 }
00110 
00111 void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
00112   VisitStmt(S);
00113   Record.push_back(S->getAttrs().size());
00114   Writer.WriteAttributes(S->getAttrs(), Record);
00115   Writer.AddStmt(S->getSubStmt());
00116   Writer.AddSourceLocation(S->getAttrLoc(), Record);
00117   Code = serialization::STMT_ATTRIBUTED;
00118 }
00119 
00120 void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
00121   VisitStmt(S);
00122   Writer.AddDeclRef(S->getConditionVariable(), Record);
00123   Writer.AddStmt(S->getCond());
00124   Writer.AddStmt(S->getThen());
00125   Writer.AddStmt(S->getElse());
00126   Writer.AddSourceLocation(S->getIfLoc(), Record);
00127   Writer.AddSourceLocation(S->getElseLoc(), Record);
00128   Code = serialization::STMT_IF;
00129 }
00130 
00131 void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
00132   VisitStmt(S);
00133   Writer.AddDeclRef(S->getConditionVariable(), Record);
00134   Writer.AddStmt(S->getCond());
00135   Writer.AddStmt(S->getBody());
00136   Writer.AddSourceLocation(S->getSwitchLoc(), Record);
00137   Record.push_back(S->isAllEnumCasesCovered());
00138   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
00139        SC = SC->getNextSwitchCase())
00140     Record.push_back(Writer.RecordSwitchCaseID(SC));
00141   Code = serialization::STMT_SWITCH;
00142 }
00143 
00144 void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
00145   VisitStmt(S);
00146   Writer.AddDeclRef(S->getConditionVariable(), Record);
00147   Writer.AddStmt(S->getCond());
00148   Writer.AddStmt(S->getBody());
00149   Writer.AddSourceLocation(S->getWhileLoc(), Record);
00150   Code = serialization::STMT_WHILE;
00151 }
00152 
00153 void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
00154   VisitStmt(S);
00155   Writer.AddStmt(S->getCond());
00156   Writer.AddStmt(S->getBody());
00157   Writer.AddSourceLocation(S->getDoLoc(), Record);
00158   Writer.AddSourceLocation(S->getWhileLoc(), Record);
00159   Writer.AddSourceLocation(S->getRParenLoc(), Record);
00160   Code = serialization::STMT_DO;
00161 }
00162 
00163 void ASTStmtWriter::VisitForStmt(ForStmt *S) {
00164   VisitStmt(S);
00165   Writer.AddStmt(S->getInit());
00166   Writer.AddStmt(S->getCond());
00167   Writer.AddDeclRef(S->getConditionVariable(), Record);
00168   Writer.AddStmt(S->getInc());
00169   Writer.AddStmt(S->getBody());
00170   Writer.AddSourceLocation(S->getForLoc(), Record);
00171   Writer.AddSourceLocation(S->getLParenLoc(), Record);
00172   Writer.AddSourceLocation(S->getRParenLoc(), Record);
00173   Code = serialization::STMT_FOR;
00174 }
00175 
00176 void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
00177   VisitStmt(S);
00178   Writer.AddDeclRef(S->getLabel(), Record);
00179   Writer.AddSourceLocation(S->getGotoLoc(), Record);
00180   Writer.AddSourceLocation(S->getLabelLoc(), Record);
00181   Code = serialization::STMT_GOTO;
00182 }
00183 
00184 void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
00185   VisitStmt(S);
00186   Writer.AddSourceLocation(S->getGotoLoc(), Record);
00187   Writer.AddSourceLocation(S->getStarLoc(), Record);
00188   Writer.AddStmt(S->getTarget());
00189   Code = serialization::STMT_INDIRECT_GOTO;
00190 }
00191 
00192 void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
00193   VisitStmt(S);
00194   Writer.AddSourceLocation(S->getContinueLoc(), Record);
00195   Code = serialization::STMT_CONTINUE;
00196 }
00197 
00198 void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
00199   VisitStmt(S);
00200   Writer.AddSourceLocation(S->getBreakLoc(), Record);
00201   Code = serialization::STMT_BREAK;
00202 }
00203 
00204 void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
00205   VisitStmt(S);
00206   Writer.AddStmt(S->getRetValue());
00207   Writer.AddSourceLocation(S->getReturnLoc(), Record);
00208   Writer.AddDeclRef(S->getNRVOCandidate(), Record);
00209   Code = serialization::STMT_RETURN;
00210 }
00211 
00212 void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
00213   VisitStmt(S);
00214   Writer.AddSourceLocation(S->getStartLoc(), Record);
00215   Writer.AddSourceLocation(S->getEndLoc(), Record);
00216   DeclGroupRef DG = S->getDeclGroup();
00217   for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
00218     Writer.AddDeclRef(*D, Record);
00219   Code = serialization::STMT_DECL;
00220 }
00221 
00222 void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
00223   VisitStmt(S);
00224   Record.push_back(S->getNumOutputs());
00225   Record.push_back(S->getNumInputs());
00226   Record.push_back(S->getNumClobbers());
00227   Writer.AddSourceLocation(S->getAsmLoc(), Record);
00228   Record.push_back(S->isVolatile());
00229   Record.push_back(S->isSimple());
00230 }
00231 
00232 void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
00233   VisitAsmStmt(S);
00234   Writer.AddSourceLocation(S->getRParenLoc(), Record);
00235   Writer.AddStmt(S->getAsmString());
00236 
00237   // Outputs
00238   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {      
00239     Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
00240     Writer.AddStmt(S->getOutputConstraintLiteral(I));
00241     Writer.AddStmt(S->getOutputExpr(I));
00242   }
00243 
00244   // Inputs
00245   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
00246     Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
00247     Writer.AddStmt(S->getInputConstraintLiteral(I));
00248     Writer.AddStmt(S->getInputExpr(I));
00249   }
00250 
00251   // Clobbers
00252   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
00253     Writer.AddStmt(S->getClobberStringLiteral(I));
00254 
00255   Code = serialization::STMT_GCCASM;
00256 }
00257 
00258 void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
00259   VisitAsmStmt(S);
00260   Writer.AddSourceLocation(S->getLBraceLoc(), Record);
00261   Writer.AddSourceLocation(S->getEndLoc(), Record);
00262   Record.push_back(S->getNumAsmToks());
00263   Writer.AddString(S->getAsmString(), Record);
00264 
00265   // Tokens
00266   for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
00267     Writer.AddToken(S->getAsmToks()[I], Record);
00268   }
00269 
00270   // Clobbers
00271   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
00272     Writer.AddString(S->getClobber(I), Record);
00273   }
00274 
00275   // Outputs
00276   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {      
00277     Writer.AddStmt(S->getOutputExpr(I));
00278     Writer.AddString(S->getOutputConstraint(I), Record);
00279   }
00280 
00281   // Inputs
00282   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
00283     Writer.AddStmt(S->getInputExpr(I));
00284     Writer.AddString(S->getInputConstraint(I), Record);
00285   }
00286 
00287   Code = serialization::STMT_MSASM;
00288 }
00289 
00290 void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
00291   VisitStmt(S);
00292   // NumCaptures
00293   Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
00294 
00295   // CapturedDecl and captured region kind
00296   Writer.AddDeclRef(S->getCapturedDecl(), Record);
00297   Record.push_back(S->getCapturedRegionKind());
00298 
00299   Writer.AddDeclRef(S->getCapturedRecordDecl(), Record);
00300 
00301   // Capture inits
00302   for (auto *I : S->capture_inits())
00303     Writer.AddStmt(I);
00304 
00305   // Body
00306   Writer.AddStmt(S->getCapturedStmt());
00307 
00308   // Captures
00309   for (const auto &I : S->captures()) {
00310     if (I.capturesThis() || I.capturesVariableArrayType())
00311       Writer.AddDeclRef(nullptr, Record);
00312     else
00313       Writer.AddDeclRef(I.getCapturedVar(), Record);
00314     Record.push_back(I.getCaptureKind());
00315     Writer.AddSourceLocation(I.getLocation(), Record);
00316   }
00317 
00318   Code = serialization::STMT_CAPTURED;
00319 }
00320 
00321 void ASTStmtWriter::VisitExpr(Expr *E) {
00322   VisitStmt(E);
00323   Writer.AddTypeRef(E->getType(), Record);
00324   Record.push_back(E->isTypeDependent());
00325   Record.push_back(E->isValueDependent());
00326   Record.push_back(E->isInstantiationDependent());
00327   Record.push_back(E->containsUnexpandedParameterPack());
00328   Record.push_back(E->getValueKind());
00329   Record.push_back(E->getObjectKind());
00330 }
00331 
00332 void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
00333   VisitExpr(E);
00334   Writer.AddSourceLocation(E->getLocation(), Record);
00335   Record.push_back(E->getIdentType()); // FIXME: stable encoding
00336   Writer.AddStmt(E->getFunctionName());
00337   Code = serialization::EXPR_PREDEFINED;
00338 }
00339 
00340 void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
00341   VisitExpr(E);
00342 
00343   Record.push_back(E->hasQualifier());
00344   Record.push_back(E->getDecl() != E->getFoundDecl());
00345   Record.push_back(E->hasTemplateKWAndArgsInfo());
00346   Record.push_back(E->hadMultipleCandidates());
00347   Record.push_back(E->refersToEnclosingLocal());
00348 
00349   if (E->hasTemplateKWAndArgsInfo()) {
00350     unsigned NumTemplateArgs = E->getNumTemplateArgs();
00351     Record.push_back(NumTemplateArgs);
00352   }
00353 
00354   DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
00355 
00356   if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
00357       (E->getDecl() == E->getFoundDecl()) &&
00358       nk == DeclarationName::Identifier) {
00359     AbbrevToUse = Writer.getDeclRefExprAbbrev();
00360   }
00361 
00362   if (E->hasQualifier())
00363     Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
00364 
00365   if (E->getDecl() != E->getFoundDecl())
00366     Writer.AddDeclRef(E->getFoundDecl(), Record);
00367 
00368   if (E->hasTemplateKWAndArgsInfo())
00369     AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo());
00370 
00371   Writer.AddDeclRef(E->getDecl(), Record);
00372   Writer.AddSourceLocation(E->getLocation(), Record);
00373   Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
00374   Code = serialization::EXPR_DECL_REF;
00375 }
00376 
00377 void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
00378   VisitExpr(E);
00379   Writer.AddSourceLocation(E->getLocation(), Record);
00380   Writer.AddAPInt(E->getValue(), Record);
00381 
00382   if (E->getValue().getBitWidth() == 32) {
00383     AbbrevToUse = Writer.getIntegerLiteralAbbrev();
00384   }
00385 
00386   Code = serialization::EXPR_INTEGER_LITERAL;
00387 }
00388 
00389 void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
00390   VisitExpr(E);
00391   Record.push_back(E->getRawSemantics());
00392   Record.push_back(E->isExact());
00393   Writer.AddAPFloat(E->getValue(), Record);
00394   Writer.AddSourceLocation(E->getLocation(), Record);
00395   Code = serialization::EXPR_FLOATING_LITERAL;
00396 }
00397 
00398 void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
00399   VisitExpr(E);
00400   Writer.AddStmt(E->getSubExpr());
00401   Code = serialization::EXPR_IMAGINARY_LITERAL;
00402 }
00403 
00404 void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
00405   VisitExpr(E);
00406   Record.push_back(E->getByteLength());
00407   Record.push_back(E->getNumConcatenated());
00408   Record.push_back(E->getKind());
00409   Record.push_back(E->isPascal());
00410   // FIXME: String data should be stored as a blob at the end of the
00411   // StringLiteral. However, we can't do so now because we have no
00412   // provision for coping with abbreviations when we're jumping around
00413   // the AST file during deserialization.
00414   Record.append(E->getBytes().begin(), E->getBytes().end());
00415   for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
00416     Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
00417   Code = serialization::EXPR_STRING_LITERAL;
00418 }
00419 
00420 void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
00421   VisitExpr(E);
00422   Record.push_back(E->getValue());
00423   Writer.AddSourceLocation(E->getLocation(), Record);
00424   Record.push_back(E->getKind());
00425 
00426   AbbrevToUse = Writer.getCharacterLiteralAbbrev();
00427 
00428   Code = serialization::EXPR_CHARACTER_LITERAL;
00429 }
00430 
00431 void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
00432   VisitExpr(E);
00433   Writer.AddSourceLocation(E->getLParen(), Record);
00434   Writer.AddSourceLocation(E->getRParen(), Record);
00435   Writer.AddStmt(E->getSubExpr());
00436   Code = serialization::EXPR_PAREN;
00437 }
00438 
00439 void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
00440   VisitExpr(E);
00441   Record.push_back(E->NumExprs);
00442   for (unsigned i=0; i != E->NumExprs; ++i)
00443     Writer.AddStmt(E->Exprs[i]);
00444   Writer.AddSourceLocation(E->LParenLoc, Record);
00445   Writer.AddSourceLocation(E->RParenLoc, Record);
00446   Code = serialization::EXPR_PAREN_LIST;
00447 }
00448 
00449 void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
00450   VisitExpr(E);
00451   Writer.AddStmt(E->getSubExpr());
00452   Record.push_back(E->getOpcode()); // FIXME: stable encoding
00453   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
00454   Code = serialization::EXPR_UNARY_OPERATOR;
00455 }
00456 
00457 void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
00458   VisitExpr(E);
00459   Record.push_back(E->getNumComponents());
00460   Record.push_back(E->getNumExpressions());
00461   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
00462   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00463   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
00464   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
00465     const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
00466     Record.push_back(ON.getKind()); // FIXME: Stable encoding
00467     Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
00468     Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
00469     switch (ON.getKind()) {
00470     case OffsetOfExpr::OffsetOfNode::Array:
00471       Record.push_back(ON.getArrayExprIndex());
00472       break;
00473         
00474     case OffsetOfExpr::OffsetOfNode::Field:
00475       Writer.AddDeclRef(ON.getField(), Record);
00476       break;
00477         
00478     case OffsetOfExpr::OffsetOfNode::Identifier:
00479       Writer.AddIdentifierRef(ON.getFieldName(), Record);
00480       break;
00481         
00482     case OffsetOfExpr::OffsetOfNode::Base:
00483       Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
00484       break;
00485     }
00486   }
00487   for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
00488     Writer.AddStmt(E->getIndexExpr(I));
00489   Code = serialization::EXPR_OFFSETOF;
00490 }
00491 
00492 void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
00493   VisitExpr(E);
00494   Record.push_back(E->getKind());
00495   if (E->isArgumentType())
00496     Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
00497   else {
00498     Record.push_back(0);
00499     Writer.AddStmt(E->getArgumentExpr());
00500   }
00501   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
00502   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00503   Code = serialization::EXPR_SIZEOF_ALIGN_OF;
00504 }
00505 
00506 void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
00507   VisitExpr(E);
00508   Writer.AddStmt(E->getLHS());
00509   Writer.AddStmt(E->getRHS());
00510   Writer.AddSourceLocation(E->getRBracketLoc(), Record);
00511   Code = serialization::EXPR_ARRAY_SUBSCRIPT;
00512 }
00513 
00514 void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
00515   VisitExpr(E);
00516   Record.push_back(E->getNumArgs());
00517   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00518   Writer.AddStmt(E->getCallee());
00519   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
00520        Arg != ArgEnd; ++Arg)
00521     Writer.AddStmt(*Arg);
00522   Code = serialization::EXPR_CALL;
00523 }
00524 
00525 void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
00526   // Don't call VisitExpr, we'll write everything here.
00527 
00528   Record.push_back(E->hasQualifier());
00529   if (E->hasQualifier())
00530     Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
00531 
00532   Record.push_back(E->HasTemplateKWAndArgsInfo);
00533   if (E->HasTemplateKWAndArgsInfo) {
00534     Writer.AddSourceLocation(E->getTemplateKeywordLoc(), Record);
00535     unsigned NumTemplateArgs = E->getNumTemplateArgs();
00536     Record.push_back(NumTemplateArgs);
00537     Writer.AddSourceLocation(E->getLAngleLoc(), Record);
00538     Writer.AddSourceLocation(E->getRAngleLoc(), Record);
00539     for (unsigned i=0; i != NumTemplateArgs; ++i)
00540       Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
00541   }
00542 
00543   Record.push_back(E->hadMultipleCandidates());
00544 
00545   DeclAccessPair FoundDecl = E->getFoundDecl();
00546   Writer.AddDeclRef(FoundDecl.getDecl(), Record);
00547   Record.push_back(FoundDecl.getAccess());
00548 
00549   Writer.AddTypeRef(E->getType(), Record);
00550   Record.push_back(E->getValueKind());
00551   Record.push_back(E->getObjectKind());
00552   Writer.AddStmt(E->getBase());
00553   Writer.AddDeclRef(E->getMemberDecl(), Record);
00554   Writer.AddSourceLocation(E->getMemberLoc(), Record);
00555   Record.push_back(E->isArrow());
00556   Writer.AddDeclarationNameLoc(E->MemberDNLoc,
00557                                E->getMemberDecl()->getDeclName(), Record);
00558   Code = serialization::EXPR_MEMBER;
00559 }
00560 
00561 void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
00562   VisitExpr(E);
00563   Writer.AddStmt(E->getBase());
00564   Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
00565   Writer.AddSourceLocation(E->getOpLoc(), Record);
00566   Record.push_back(E->isArrow());
00567   Code = serialization::EXPR_OBJC_ISA;
00568 }
00569 
00570 void ASTStmtWriter::
00571 VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
00572   VisitExpr(E);
00573   Writer.AddStmt(E->getSubExpr());
00574   Record.push_back(E->shouldCopy());
00575   Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
00576 }
00577 
00578 void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
00579   VisitExplicitCastExpr(E);
00580   Writer.AddSourceLocation(E->getLParenLoc(), Record);
00581   Writer.AddSourceLocation(E->getBridgeKeywordLoc(), Record);
00582   Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
00583   Code = serialization::EXPR_OBJC_BRIDGED_CAST;
00584 }
00585 
00586 void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
00587   VisitExpr(E);
00588   Record.push_back(E->path_size());
00589   Writer.AddStmt(E->getSubExpr());
00590   Record.push_back(E->getCastKind()); // FIXME: stable encoding
00591 
00592   for (CastExpr::path_iterator
00593          PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
00594     Writer.AddCXXBaseSpecifier(**PI, Record);
00595 }
00596 
00597 void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
00598   VisitExpr(E);
00599   Writer.AddStmt(E->getLHS());
00600   Writer.AddStmt(E->getRHS());
00601   Record.push_back(E->getOpcode()); // FIXME: stable encoding
00602   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
00603   Record.push_back(E->isFPContractable());
00604   Code = serialization::EXPR_BINARY_OPERATOR;
00605 }
00606 
00607 void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
00608   VisitBinaryOperator(E);
00609   Writer.AddTypeRef(E->getComputationLHSType(), Record);
00610   Writer.AddTypeRef(E->getComputationResultType(), Record);
00611   Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
00612 }
00613 
00614 void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
00615   VisitExpr(E);
00616   Writer.AddStmt(E->getCond());
00617   Writer.AddStmt(E->getLHS());
00618   Writer.AddStmt(E->getRHS());
00619   Writer.AddSourceLocation(E->getQuestionLoc(), Record);
00620   Writer.AddSourceLocation(E->getColonLoc(), Record);
00621   Code = serialization::EXPR_CONDITIONAL_OPERATOR;
00622 }
00623 
00624 void
00625 ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
00626   VisitExpr(E);
00627   Writer.AddStmt(E->getOpaqueValue());
00628   Writer.AddStmt(E->getCommon());
00629   Writer.AddStmt(E->getCond());
00630   Writer.AddStmt(E->getTrueExpr());
00631   Writer.AddStmt(E->getFalseExpr());
00632   Writer.AddSourceLocation(E->getQuestionLoc(), Record);
00633   Writer.AddSourceLocation(E->getColonLoc(), Record);
00634   Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
00635 }
00636 
00637 void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
00638   VisitCastExpr(E);
00639 
00640   if (E->path_size() == 0)
00641     AbbrevToUse = Writer.getExprImplicitCastAbbrev();
00642 
00643   Code = serialization::EXPR_IMPLICIT_CAST;
00644 }
00645 
00646 void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
00647   VisitCastExpr(E);
00648   Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
00649 }
00650 
00651 void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
00652   VisitExplicitCastExpr(E);
00653   Writer.AddSourceLocation(E->getLParenLoc(), Record);
00654   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00655   Code = serialization::EXPR_CSTYLE_CAST;
00656 }
00657 
00658 void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
00659   VisitExpr(E);
00660   Writer.AddSourceLocation(E->getLParenLoc(), Record);
00661   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
00662   Writer.AddStmt(E->getInitializer());
00663   Record.push_back(E->isFileScope());
00664   Code = serialization::EXPR_COMPOUND_LITERAL;
00665 }
00666 
00667 void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
00668   VisitExpr(E);
00669   Writer.AddStmt(E->getBase());
00670   Writer.AddIdentifierRef(&E->getAccessor(), Record);
00671   Writer.AddSourceLocation(E->getAccessorLoc(), Record);
00672   Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
00673 }
00674 
00675 void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
00676   VisitExpr(E);
00677   // NOTE: only add the (possibly null) syntactic form.
00678   // No need to serialize the isSemanticForm flag and the semantic form.
00679   Writer.AddStmt(E->getSyntacticForm());
00680   Writer.AddSourceLocation(E->getLBraceLoc(), Record);
00681   Writer.AddSourceLocation(E->getRBraceLoc(), Record);
00682   bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
00683   Record.push_back(isArrayFiller);
00684   if (isArrayFiller)
00685     Writer.AddStmt(E->getArrayFiller());
00686   else
00687     Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
00688   Record.push_back(E->hadArrayRangeDesignator());
00689   Record.push_back(E->getNumInits());
00690   if (isArrayFiller) {
00691     // ArrayFiller may have filled "holes" due to designated initializer.
00692     // Replace them by 0 to indicate that the filler goes in that place.
00693     Expr *filler = E->getArrayFiller();
00694     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
00695       Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
00696   } else {
00697     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
00698       Writer.AddStmt(E->getInit(I));
00699   }
00700   Code = serialization::EXPR_INIT_LIST;
00701 }
00702 
00703 void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
00704   VisitExpr(E);
00705   Record.push_back(E->getNumSubExprs());
00706   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
00707     Writer.AddStmt(E->getSubExpr(I));
00708   Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
00709   Record.push_back(E->usesGNUSyntax());
00710   for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
00711                                              DEnd = E->designators_end();
00712        D != DEnd; ++D) {
00713     if (D->isFieldDesignator()) {
00714       if (FieldDecl *Field = D->getField()) {
00715         Record.push_back(serialization::DESIG_FIELD_DECL);
00716         Writer.AddDeclRef(Field, Record);
00717       } else {
00718         Record.push_back(serialization::DESIG_FIELD_NAME);
00719         Writer.AddIdentifierRef(D->getFieldName(), Record);
00720       }
00721       Writer.AddSourceLocation(D->getDotLoc(), Record);
00722       Writer.AddSourceLocation(D->getFieldLoc(), Record);
00723     } else if (D->isArrayDesignator()) {
00724       Record.push_back(serialization::DESIG_ARRAY);
00725       Record.push_back(D->getFirstExprIndex());
00726       Writer.AddSourceLocation(D->getLBracketLoc(), Record);
00727       Writer.AddSourceLocation(D->getRBracketLoc(), Record);
00728     } else {
00729       assert(D->isArrayRangeDesignator() && "Unknown designator");
00730       Record.push_back(serialization::DESIG_ARRAY_RANGE);
00731       Record.push_back(D->getFirstExprIndex());
00732       Writer.AddSourceLocation(D->getLBracketLoc(), Record);
00733       Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
00734       Writer.AddSourceLocation(D->getRBracketLoc(), Record);
00735     }
00736   }
00737   Code = serialization::EXPR_DESIGNATED_INIT;
00738 }
00739 
00740 void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
00741   VisitExpr(E);
00742   Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
00743 }
00744 
00745 void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
00746   VisitExpr(E);
00747   Writer.AddStmt(E->getSubExpr());
00748   Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
00749   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
00750   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00751   Code = serialization::EXPR_VA_ARG;
00752 }
00753 
00754 void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
00755   VisitExpr(E);
00756   Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
00757   Writer.AddSourceLocation(E->getLabelLoc(), Record);
00758   Writer.AddDeclRef(E->getLabel(), Record);
00759   Code = serialization::EXPR_ADDR_LABEL;
00760 }
00761 
00762 void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
00763   VisitExpr(E);
00764   Writer.AddStmt(E->getSubStmt());
00765   Writer.AddSourceLocation(E->getLParenLoc(), Record);
00766   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00767   Code = serialization::EXPR_STMT;
00768 }
00769 
00770 void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
00771   VisitExpr(E);
00772   Writer.AddStmt(E->getCond());
00773   Writer.AddStmt(E->getLHS());
00774   Writer.AddStmt(E->getRHS());
00775   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
00776   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00777   Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
00778   Code = serialization::EXPR_CHOOSE;
00779 }
00780 
00781 void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
00782   VisitExpr(E);
00783   Writer.AddSourceLocation(E->getTokenLocation(), Record);
00784   Code = serialization::EXPR_GNU_NULL;
00785 }
00786 
00787 void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
00788   VisitExpr(E);
00789   Record.push_back(E->getNumSubExprs());
00790   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
00791     Writer.AddStmt(E->getExpr(I));
00792   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
00793   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00794   Code = serialization::EXPR_SHUFFLE_VECTOR;
00795 }
00796 
00797 void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
00798   VisitExpr(E);
00799   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
00800   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00801   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
00802   Writer.AddStmt(E->getSrcExpr());
00803   Code = serialization::EXPR_CONVERT_VECTOR;
00804 }
00805 
00806 void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
00807   VisitExpr(E);
00808   Writer.AddDeclRef(E->getBlockDecl(), Record);
00809   Code = serialization::EXPR_BLOCK;
00810 }
00811 
00812 void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
00813   VisitExpr(E);
00814   Record.push_back(E->getNumAssocs());
00815 
00816   Writer.AddStmt(E->getControllingExpr());
00817   for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
00818     Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record);
00819     Writer.AddStmt(E->getAssocExpr(I));
00820   }
00821   Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
00822 
00823   Writer.AddSourceLocation(E->getGenericLoc(), Record);
00824   Writer.AddSourceLocation(E->getDefaultLoc(), Record);
00825   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00826   Code = serialization::EXPR_GENERIC_SELECTION;
00827 }
00828 
00829 void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
00830   VisitExpr(E);
00831   Record.push_back(E->getNumSemanticExprs());
00832 
00833   // Push the result index.  Currently, this needs to exactly match
00834   // the encoding used internally for ResultIndex.
00835   unsigned result = E->getResultExprIndex();
00836   result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
00837   Record.push_back(result);
00838 
00839   Writer.AddStmt(E->getSyntacticForm());
00840   for (PseudoObjectExpr::semantics_iterator
00841          i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
00842     Writer.AddStmt(*i);
00843   }
00844   Code = serialization::EXPR_PSEUDO_OBJECT;
00845 }
00846 
00847 void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
00848   VisitExpr(E);
00849   Record.push_back(E->getOp());
00850   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
00851     Writer.AddStmt(E->getSubExprs()[I]);
00852   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
00853   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00854   Code = serialization::EXPR_ATOMIC;
00855 }
00856 
00857 //===----------------------------------------------------------------------===//
00858 // Objective-C Expressions and Statements.
00859 //===----------------------------------------------------------------------===//
00860 
00861 void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
00862   VisitExpr(E);
00863   Writer.AddStmt(E->getString());
00864   Writer.AddSourceLocation(E->getAtLoc(), Record);
00865   Code = serialization::EXPR_OBJC_STRING_LITERAL;
00866 }
00867 
00868 void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
00869   VisitExpr(E);
00870   Writer.AddStmt(E->getSubExpr());
00871   Writer.AddDeclRef(E->getBoxingMethod(), Record);
00872   Writer.AddSourceRange(E->getSourceRange(), Record);
00873   Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
00874 }
00875 
00876 void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
00877   VisitExpr(E);
00878   Record.push_back(E->getNumElements());
00879   for (unsigned i = 0; i < E->getNumElements(); i++)
00880     Writer.AddStmt(E->getElement(i));
00881   Writer.AddDeclRef(E->getArrayWithObjectsMethod(), Record);
00882   Writer.AddSourceRange(E->getSourceRange(), Record);
00883   Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
00884 }
00885 
00886 void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
00887   VisitExpr(E);
00888   Record.push_back(E->getNumElements());
00889   Record.push_back(E->HasPackExpansions);
00890   for (unsigned i = 0; i < E->getNumElements(); i++) {
00891     ObjCDictionaryElement Element = E->getKeyValueElement(i);
00892     Writer.AddStmt(Element.Key);
00893     Writer.AddStmt(Element.Value);
00894     if (E->HasPackExpansions) {
00895       Writer.AddSourceLocation(Element.EllipsisLoc, Record);
00896       unsigned NumExpansions = 0;
00897       if (Element.NumExpansions)
00898         NumExpansions = *Element.NumExpansions + 1;
00899       Record.push_back(NumExpansions);
00900     }
00901   }
00902     
00903   Writer.AddDeclRef(E->getDictWithObjectsMethod(), Record);
00904   Writer.AddSourceRange(E->getSourceRange(), Record);
00905   Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
00906 }
00907 
00908 void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
00909   VisitExpr(E);
00910   Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
00911   Writer.AddSourceLocation(E->getAtLoc(), Record);
00912   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00913   Code = serialization::EXPR_OBJC_ENCODE;
00914 }
00915 
00916 void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
00917   VisitExpr(E);
00918   Writer.AddSelectorRef(E->getSelector(), Record);
00919   Writer.AddSourceLocation(E->getAtLoc(), Record);
00920   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00921   Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
00922 }
00923 
00924 void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
00925   VisitExpr(E);
00926   Writer.AddDeclRef(E->getProtocol(), Record);
00927   Writer.AddSourceLocation(E->getAtLoc(), Record);
00928   Writer.AddSourceLocation(E->ProtoLoc, Record);
00929   Writer.AddSourceLocation(E->getRParenLoc(), Record);
00930   Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
00931 }
00932 
00933 void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
00934   VisitExpr(E);
00935   Writer.AddDeclRef(E->getDecl(), Record);
00936   Writer.AddSourceLocation(E->getLocation(), Record);
00937   Writer.AddSourceLocation(E->getOpLoc(), Record);
00938   Writer.AddStmt(E->getBase());
00939   Record.push_back(E->isArrow());
00940   Record.push_back(E->isFreeIvar());
00941   Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
00942 }
00943 
00944 void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
00945   VisitExpr(E);
00946   Record.push_back(E->SetterAndMethodRefFlags.getInt());
00947   Record.push_back(E->isImplicitProperty());
00948   if (E->isImplicitProperty()) {
00949     Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
00950     Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
00951   } else {
00952     Writer.AddDeclRef(E->getExplicitProperty(), Record);
00953   }
00954   Writer.AddSourceLocation(E->getLocation(), Record);
00955   Writer.AddSourceLocation(E->getReceiverLocation(), Record);
00956   if (E->isObjectReceiver()) {
00957     Record.push_back(0);
00958     Writer.AddStmt(E->getBase());
00959   } else if (E->isSuperReceiver()) {
00960     Record.push_back(1);
00961     Writer.AddTypeRef(E->getSuperReceiverType(), Record);
00962   } else {
00963     Record.push_back(2);
00964     Writer.AddDeclRef(E->getClassReceiver(), Record);
00965   }
00966   
00967   Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
00968 }
00969 
00970 void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
00971   VisitExpr(E);
00972   Writer.AddSourceLocation(E->getRBracket(), Record);
00973   Writer.AddStmt(E->getBaseExpr());
00974   Writer.AddStmt(E->getKeyExpr());
00975   Writer.AddDeclRef(E->getAtIndexMethodDecl(), Record);
00976   Writer.AddDeclRef(E->setAtIndexMethodDecl(), Record);
00977   
00978   Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
00979 }
00980 
00981 void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
00982   VisitExpr(E);
00983   Record.push_back(E->getNumArgs());
00984   Record.push_back(E->getNumStoredSelLocs());
00985   Record.push_back(E->SelLocsKind);
00986   Record.push_back(E->isDelegateInitCall());
00987   Record.push_back(E->IsImplicit);
00988   Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
00989   switch (E->getReceiverKind()) {
00990   case ObjCMessageExpr::Instance:
00991     Writer.AddStmt(E->getInstanceReceiver());
00992     break;
00993 
00994   case ObjCMessageExpr::Class:
00995     Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
00996     break;
00997 
00998   case ObjCMessageExpr::SuperClass:
00999   case ObjCMessageExpr::SuperInstance:
01000     Writer.AddTypeRef(E->getSuperType(), Record);
01001     Writer.AddSourceLocation(E->getSuperLoc(), Record);
01002     break;
01003   }
01004 
01005   if (E->getMethodDecl()) {
01006     Record.push_back(1);
01007     Writer.AddDeclRef(E->getMethodDecl(), Record);
01008   } else {
01009     Record.push_back(0);
01010     Writer.AddSelectorRef(E->getSelector(), Record);    
01011   }
01012     
01013   Writer.AddSourceLocation(E->getLeftLoc(), Record);
01014   Writer.AddSourceLocation(E->getRightLoc(), Record);
01015 
01016   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
01017        Arg != ArgEnd; ++Arg)
01018     Writer.AddStmt(*Arg);
01019 
01020   SourceLocation *Locs = E->getStoredSelLocs();
01021   for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
01022     Writer.AddSourceLocation(Locs[i], Record);
01023 
01024   Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
01025 }
01026 
01027 void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
01028   VisitStmt(S);
01029   Writer.AddStmt(S->getElement());
01030   Writer.AddStmt(S->getCollection());
01031   Writer.AddStmt(S->getBody());
01032   Writer.AddSourceLocation(S->getForLoc(), Record);
01033   Writer.AddSourceLocation(S->getRParenLoc(), Record);
01034   Code = serialization::STMT_OBJC_FOR_COLLECTION;
01035 }
01036 
01037 void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
01038   Writer.AddStmt(S->getCatchBody());
01039   Writer.AddDeclRef(S->getCatchParamDecl(), Record);
01040   Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
01041   Writer.AddSourceLocation(S->getRParenLoc(), Record);
01042   Code = serialization::STMT_OBJC_CATCH;
01043 }
01044 
01045 void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
01046   Writer.AddStmt(S->getFinallyBody());
01047   Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
01048   Code = serialization::STMT_OBJC_FINALLY;
01049 }
01050 
01051 void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
01052   Writer.AddStmt(S->getSubStmt());
01053   Writer.AddSourceLocation(S->getAtLoc(), Record);
01054   Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
01055 }
01056 
01057 void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
01058   Record.push_back(S->getNumCatchStmts());
01059   Record.push_back(S->getFinallyStmt() != nullptr);
01060   Writer.AddStmt(S->getTryBody());
01061   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
01062     Writer.AddStmt(S->getCatchStmt(I));
01063   if (S->getFinallyStmt())
01064     Writer.AddStmt(S->getFinallyStmt());
01065   Writer.AddSourceLocation(S->getAtTryLoc(), Record);
01066   Code = serialization::STMT_OBJC_AT_TRY;
01067 }
01068 
01069 void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
01070   Writer.AddStmt(S->getSynchExpr());
01071   Writer.AddStmt(S->getSynchBody());
01072   Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
01073   Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
01074 }
01075 
01076 void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
01077   Writer.AddStmt(S->getThrowExpr());
01078   Writer.AddSourceLocation(S->getThrowLoc(), Record);
01079   Code = serialization::STMT_OBJC_AT_THROW;
01080 }
01081 
01082 void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
01083   VisitExpr(E);
01084   Record.push_back(E->getValue());
01085   Writer.AddSourceLocation(E->getLocation(), Record);
01086   Code = serialization::EXPR_OBJC_BOOL_LITERAL;
01087 }
01088 
01089 //===----------------------------------------------------------------------===//
01090 // C++ Expressions and Statements.
01091 //===----------------------------------------------------------------------===//
01092 
01093 void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
01094   VisitStmt(S);
01095   Writer.AddSourceLocation(S->getCatchLoc(), Record);
01096   Writer.AddDeclRef(S->getExceptionDecl(), Record);
01097   Writer.AddStmt(S->getHandlerBlock());
01098   Code = serialization::STMT_CXX_CATCH;
01099 }
01100 
01101 void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
01102   VisitStmt(S);
01103   Record.push_back(S->getNumHandlers());
01104   Writer.AddSourceLocation(S->getTryLoc(), Record);
01105   Writer.AddStmt(S->getTryBlock());
01106   for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
01107     Writer.AddStmt(S->getHandler(i));
01108   Code = serialization::STMT_CXX_TRY;
01109 }
01110 
01111 void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
01112   VisitStmt(S);
01113   Writer.AddSourceLocation(S->getForLoc(), Record);
01114   Writer.AddSourceLocation(S->getColonLoc(), Record);
01115   Writer.AddSourceLocation(S->getRParenLoc(), Record);
01116   Writer.AddStmt(S->getRangeStmt());
01117   Writer.AddStmt(S->getBeginEndStmt());
01118   Writer.AddStmt(S->getCond());
01119   Writer.AddStmt(S->getInc());
01120   Writer.AddStmt(S->getLoopVarStmt());
01121   Writer.AddStmt(S->getBody());
01122   Code = serialization::STMT_CXX_FOR_RANGE;
01123 }
01124 
01125 void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
01126   VisitStmt(S);
01127   Writer.AddSourceLocation(S->getKeywordLoc(), Record);
01128   Record.push_back(S->isIfExists());
01129   Writer.AddNestedNameSpecifierLoc(S->getQualifierLoc(), Record);
01130   Writer.AddDeclarationNameInfo(S->getNameInfo(), Record);
01131   Writer.AddStmt(S->getSubStmt());
01132   Code = serialization::STMT_MS_DEPENDENT_EXISTS;
01133 }
01134 
01135 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
01136   VisitCallExpr(E);
01137   Record.push_back(E->getOperator());
01138   Writer.AddSourceRange(E->Range, Record);
01139   Record.push_back(E->isFPContractable());
01140   Code = serialization::EXPR_CXX_OPERATOR_CALL;
01141 }
01142 
01143 void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
01144   VisitCallExpr(E);
01145   Code = serialization::EXPR_CXX_MEMBER_CALL;
01146 }
01147 
01148 void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
01149   VisitExpr(E);
01150   Record.push_back(E->getNumArgs());
01151   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
01152     Writer.AddStmt(E->getArg(I));
01153   Writer.AddDeclRef(E->getConstructor(), Record);
01154   Writer.AddSourceLocation(E->getLocation(), Record);
01155   Record.push_back(E->isElidable());
01156   Record.push_back(E->hadMultipleCandidates());
01157   Record.push_back(E->isListInitialization());
01158   Record.push_back(E->isStdInitListInitialization());
01159   Record.push_back(E->requiresZeroInitialization());
01160   Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
01161   Writer.AddSourceRange(E->getParenOrBraceRange(), Record);
01162   Code = serialization::EXPR_CXX_CONSTRUCT;
01163 }
01164 
01165 void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
01166   VisitCXXConstructExpr(E);
01167   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
01168   Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
01169 }
01170 
01171 void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
01172   VisitExpr(E);
01173   Record.push_back(E->NumCaptures);
01174   unsigned NumArrayIndexVars = 0;
01175   if (E->HasArrayIndexVars)
01176     NumArrayIndexVars = E->getArrayIndexStarts()[E->NumCaptures];
01177   Record.push_back(NumArrayIndexVars);
01178   Writer.AddSourceRange(E->IntroducerRange, Record);
01179   Record.push_back(E->CaptureDefault); // FIXME: stable encoding
01180   Writer.AddSourceLocation(E->CaptureDefaultLoc, Record);
01181   Record.push_back(E->ExplicitParams);
01182   Record.push_back(E->ExplicitResultType);
01183   Writer.AddSourceLocation(E->ClosingBrace, Record);
01184   
01185   // Add capture initializers.
01186   for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
01187                                       CEnd = E->capture_init_end();
01188        C != CEnd; ++C) {
01189     Writer.AddStmt(*C);
01190   }
01191   
01192   // Add array index variables, if any.
01193   if (NumArrayIndexVars) {
01194     Record.append(E->getArrayIndexStarts(), 
01195                   E->getArrayIndexStarts() + E->NumCaptures + 1);
01196     VarDecl **ArrayIndexVars = E->getArrayIndexVars();
01197     for (unsigned I = 0; I != NumArrayIndexVars; ++I)
01198       Writer.AddDeclRef(ArrayIndexVars[I], Record);
01199   }
01200   
01201   Code = serialization::EXPR_LAMBDA;
01202 }
01203 
01204 void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
01205   VisitExpr(E);
01206   Writer.AddStmt(E->getSubExpr());
01207   Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
01208 }
01209 
01210 void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
01211   VisitExplicitCastExpr(E);
01212   Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
01213                         Record);
01214   Writer.AddSourceRange(E->getAngleBrackets(), Record);
01215 }
01216 
01217 void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
01218   VisitCXXNamedCastExpr(E);
01219   Code = serialization::EXPR_CXX_STATIC_CAST;
01220 }
01221 
01222 void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
01223   VisitCXXNamedCastExpr(E);
01224   Code = serialization::EXPR_CXX_DYNAMIC_CAST;
01225 }
01226 
01227 void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
01228   VisitCXXNamedCastExpr(E);
01229   Code = serialization::EXPR_CXX_REINTERPRET_CAST;
01230 }
01231 
01232 void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
01233   VisitCXXNamedCastExpr(E);
01234   Code = serialization::EXPR_CXX_CONST_CAST;
01235 }
01236 
01237 void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
01238   VisitExplicitCastExpr(E);
01239   Writer.AddSourceLocation(E->getLParenLoc(), Record);
01240   Writer.AddSourceLocation(E->getRParenLoc(), Record);
01241   Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
01242 }
01243 
01244 void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
01245   VisitCallExpr(E);
01246   Writer.AddSourceLocation(E->UDSuffixLoc, Record);
01247   Code = serialization::EXPR_USER_DEFINED_LITERAL;
01248 }
01249 
01250 void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
01251   VisitExpr(E);
01252   Record.push_back(E->getValue());
01253   Writer.AddSourceLocation(E->getLocation(), Record);
01254   Code = serialization::EXPR_CXX_BOOL_LITERAL;
01255 }
01256 
01257 void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
01258   VisitExpr(E);
01259   Writer.AddSourceLocation(E->getLocation(), Record);
01260   Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
01261 }
01262 
01263 void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
01264   VisitExpr(E);
01265   Writer.AddSourceRange(E->getSourceRange(), Record);
01266   if (E->isTypeOperand()) {
01267     Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
01268     Code = serialization::EXPR_CXX_TYPEID_TYPE;
01269   } else {
01270     Writer.AddStmt(E->getExprOperand());
01271     Code = serialization::EXPR_CXX_TYPEID_EXPR;
01272   }
01273 }
01274 
01275 void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
01276   VisitExpr(E);
01277   Writer.AddSourceLocation(E->getLocation(), Record);
01278   Record.push_back(E->isImplicit());
01279   Code = serialization::EXPR_CXX_THIS;
01280 }
01281 
01282 void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
01283   VisitExpr(E);
01284   Writer.AddSourceLocation(E->getThrowLoc(), Record);
01285   Writer.AddStmt(E->getSubExpr());
01286   Record.push_back(E->isThrownVariableInScope());
01287   Code = serialization::EXPR_CXX_THROW;
01288 }
01289 
01290 void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
01291   VisitExpr(E);
01292 
01293   bool HasOtherExprStored = E->Param.getInt();
01294   // Store these first, the reader reads them before creation.
01295   Record.push_back(HasOtherExprStored);
01296   if (HasOtherExprStored)
01297     Writer.AddStmt(E->getExpr());
01298   Writer.AddDeclRef(E->getParam(), Record);
01299   Writer.AddSourceLocation(E->getUsedLocation(), Record);
01300 
01301   Code = serialization::EXPR_CXX_DEFAULT_ARG;
01302 }
01303 
01304 void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
01305   VisitExpr(E);
01306   Writer.AddDeclRef(E->getField(), Record);
01307   Writer.AddSourceLocation(E->getExprLoc(), Record);
01308   Code = serialization::EXPR_CXX_DEFAULT_INIT;
01309 }
01310 
01311 void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
01312   VisitExpr(E);
01313   Writer.AddCXXTemporary(E->getTemporary(), Record);
01314   Writer.AddStmt(E->getSubExpr());
01315   Code = serialization::EXPR_CXX_BIND_TEMPORARY;
01316 }
01317 
01318 void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
01319   VisitExpr(E);
01320   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
01321   Writer.AddSourceLocation(E->getRParenLoc(), Record);
01322   Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
01323 }
01324 
01325 void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
01326   VisitExpr(E);
01327   Record.push_back(E->isGlobalNew());
01328   Record.push_back(E->isArray());
01329   Record.push_back(E->doesUsualArrayDeleteWantSize());
01330   Record.push_back(E->getNumPlacementArgs());
01331   Record.push_back(E->StoredInitializationStyle);
01332   Writer.AddDeclRef(E->getOperatorNew(), Record);
01333   Writer.AddDeclRef(E->getOperatorDelete(), Record);
01334   Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
01335   Writer.AddSourceRange(E->getTypeIdParens(), Record);
01336   Writer.AddSourceRange(E->getSourceRange(), Record);
01337   Writer.AddSourceRange(E->getDirectInitRange(), Record);
01338   for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
01339        I != e; ++I)
01340     Writer.AddStmt(*I);
01341 
01342   Code = serialization::EXPR_CXX_NEW;
01343 }
01344 
01345 void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
01346   VisitExpr(E);
01347   Record.push_back(E->isGlobalDelete());
01348   Record.push_back(E->isArrayForm());
01349   Record.push_back(E->isArrayFormAsWritten());
01350   Record.push_back(E->doesUsualArrayDeleteWantSize());
01351   Writer.AddDeclRef(E->getOperatorDelete(), Record);
01352   Writer.AddStmt(E->getArgument());
01353   Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
01354   
01355   Code = serialization::EXPR_CXX_DELETE;
01356 }
01357 
01358 void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
01359   VisitExpr(E);
01360 
01361   Writer.AddStmt(E->getBase());
01362   Record.push_back(E->isArrow());
01363   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
01364   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
01365   Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
01366   Writer.AddSourceLocation(E->getColonColonLoc(), Record);
01367   Writer.AddSourceLocation(E->getTildeLoc(), Record);
01368 
01369   // PseudoDestructorTypeStorage.
01370   Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
01371   if (E->getDestroyedTypeIdentifier())
01372     Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
01373   else
01374     Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
01375 
01376   Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
01377 }
01378 
01379 void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
01380   VisitExpr(E);
01381   Record.push_back(E->getNumObjects());
01382   for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
01383     Writer.AddDeclRef(E->getObject(i), Record);
01384   
01385   Writer.AddStmt(E->getSubExpr());
01386   Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
01387 }
01388 
01389 void
01390 ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
01391   VisitExpr(E);
01392 
01393   // Don't emit anything here, HasTemplateKWAndArgsInfo must be
01394   // emitted first.
01395 
01396   Record.push_back(E->HasTemplateKWAndArgsInfo);
01397   if (E->HasTemplateKWAndArgsInfo) {
01398     const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
01399     Record.push_back(Args.NumTemplateArgs);
01400     AddTemplateKWAndArgsInfo(Args);
01401   }
01402 
01403   if (!E->isImplicitAccess())
01404     Writer.AddStmt(E->getBase());
01405   else
01406     Writer.AddStmt(nullptr);
01407   Writer.AddTypeRef(E->getBaseType(), Record);
01408   Record.push_back(E->isArrow());
01409   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
01410   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
01411   Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
01412   Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
01413   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
01414 }
01415 
01416 void
01417 ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
01418   VisitExpr(E);
01419 
01420   // Don't emit anything here, HasTemplateKWAndArgsInfo must be
01421   // emitted first.
01422 
01423   Record.push_back(E->HasTemplateKWAndArgsInfo);
01424   if (E->HasTemplateKWAndArgsInfo) {
01425     const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
01426     Record.push_back(Args.NumTemplateArgs);
01427     AddTemplateKWAndArgsInfo(Args);
01428   }
01429 
01430   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
01431   Writer.AddDeclarationNameInfo(E->NameInfo, Record);
01432   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
01433 }
01434 
01435 void
01436 ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
01437   VisitExpr(E);
01438   Record.push_back(E->arg_size());
01439   for (CXXUnresolvedConstructExpr::arg_iterator
01440          ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
01441     Writer.AddStmt(*ArgI);
01442   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
01443   Writer.AddSourceLocation(E->getLParenLoc(), Record);
01444   Writer.AddSourceLocation(E->getRParenLoc(), Record);
01445   Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
01446 }
01447 
01448 void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
01449   VisitExpr(E);
01450 
01451   // Don't emit anything here, HasTemplateKWAndArgsInfo must be
01452   // emitted first.
01453 
01454   Record.push_back(E->HasTemplateKWAndArgsInfo);
01455   if (E->HasTemplateKWAndArgsInfo) {
01456     const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
01457     Record.push_back(Args.NumTemplateArgs);
01458     AddTemplateKWAndArgsInfo(Args);
01459   }
01460 
01461   Record.push_back(E->getNumDecls());
01462   for (OverloadExpr::decls_iterator
01463          OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
01464     Writer.AddDeclRef(OvI.getDecl(), Record);
01465     Record.push_back(OvI.getAccess());
01466   }
01467 
01468   Writer.AddDeclarationNameInfo(E->NameInfo, Record);
01469   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
01470 }
01471 
01472 void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
01473   VisitOverloadExpr(E);
01474   Record.push_back(E->isArrow());
01475   Record.push_back(E->hasUnresolvedUsing());
01476   Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
01477   Writer.AddTypeRef(E->getBaseType(), Record);
01478   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
01479   Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
01480 }
01481 
01482 void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
01483   VisitOverloadExpr(E);
01484   Record.push_back(E->requiresADL());
01485   Record.push_back(E->isOverloaded());
01486   Writer.AddDeclRef(E->getNamingClass(), Record);
01487   Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
01488 }
01489 
01490 void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
01491   VisitExpr(E);
01492   Record.push_back(E->TypeTraitExprBits.NumArgs);
01493   Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
01494   Record.push_back(E->TypeTraitExprBits.Value);
01495   Writer.AddSourceRange(E->getSourceRange(), Record);
01496   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
01497     Writer.AddTypeSourceInfo(E->getArg(I), Record);
01498   Code = serialization::EXPR_TYPE_TRAIT;
01499 }
01500 
01501 void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
01502   VisitExpr(E);
01503   Record.push_back(E->getTrait());
01504   Record.push_back(E->getValue());
01505   Writer.AddSourceRange(E->getSourceRange(), Record);
01506   Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
01507   Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
01508 }
01509 
01510 void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
01511   VisitExpr(E);
01512   Record.push_back(E->getTrait());
01513   Record.push_back(E->getValue());
01514   Writer.AddSourceRange(E->getSourceRange(), Record);
01515   Writer.AddStmt(E->getQueriedExpression());
01516   Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
01517 }
01518 
01519 void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
01520   VisitExpr(E);
01521   Record.push_back(E->getValue());
01522   Writer.AddSourceRange(E->getSourceRange(), Record);
01523   Writer.AddStmt(E->getOperand());
01524   Code = serialization::EXPR_CXX_NOEXCEPT;
01525 }
01526 
01527 void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
01528   VisitExpr(E);
01529   Writer.AddSourceLocation(E->getEllipsisLoc(), Record);
01530   Record.push_back(E->NumExpansions);
01531   Writer.AddStmt(E->getPattern());
01532   Code = serialization::EXPR_PACK_EXPANSION;
01533 }
01534 
01535 void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
01536   VisitExpr(E);
01537   Writer.AddSourceLocation(E->OperatorLoc, Record);
01538   Writer.AddSourceLocation(E->PackLoc, Record);
01539   Writer.AddSourceLocation(E->RParenLoc, Record);
01540   Record.push_back(E->Length);
01541   Writer.AddDeclRef(E->Pack, Record);
01542   Code = serialization::EXPR_SIZEOF_PACK;
01543 }
01544 
01545 void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
01546                                               SubstNonTypeTemplateParmExpr *E) {
01547   VisitExpr(E);
01548   Writer.AddDeclRef(E->getParameter(), Record);
01549   Writer.AddSourceLocation(E->getNameLoc(), Record);
01550   Writer.AddStmt(E->getReplacement());
01551   Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
01552 }
01553 
01554 void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
01555                                           SubstNonTypeTemplateParmPackExpr *E) {
01556   VisitExpr(E);
01557   Writer.AddDeclRef(E->getParameterPack(), Record);
01558   Writer.AddTemplateArgument(E->getArgumentPack(), Record);
01559   Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
01560   Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
01561 }
01562 
01563 void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
01564   VisitExpr(E);
01565   Record.push_back(E->getNumExpansions());
01566   Writer.AddDeclRef(E->getParameterPack(), Record);
01567   Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
01568   for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
01569        I != End; ++I)
01570     Writer.AddDeclRef(*I, Record);
01571   Code = serialization::EXPR_FUNCTION_PARM_PACK;
01572 }
01573 
01574 void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
01575   VisitExpr(E);
01576   Writer.AddStmt(E->getTemporary());
01577   Writer.AddDeclRef(E->getExtendingDecl(), Record);
01578   Record.push_back(E->getManglingNumber());
01579   Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
01580 }
01581 
01582 void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
01583   VisitExpr(E);
01584   Writer.AddSourceLocation(E->LParenLoc, Record);
01585   Writer.AddSourceLocation(E->EllipsisLoc, Record);
01586   Writer.AddSourceLocation(E->RParenLoc, Record);
01587   Writer.AddStmt(E->SubExprs[0]);
01588   Writer.AddStmt(E->SubExprs[1]);
01589   Record.push_back(E->Opcode);
01590   Code = serialization::EXPR_CXX_FOLD;
01591 }
01592 
01593 void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
01594   VisitExpr(E);
01595   Writer.AddStmt(E->getSourceExpr());
01596   Writer.AddSourceLocation(E->getLocation(), Record);
01597   Code = serialization::EXPR_OPAQUE_VALUE;
01598 }
01599 
01600 void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
01601   VisitExpr(E);
01602   // TODO: Figure out sane writer behavior for a TypoExpr, if necessary
01603   assert(false && "Cannot write TypoExpr nodes");
01604 }
01605 
01606 //===----------------------------------------------------------------------===//
01607 // CUDA Expressions and Statements.
01608 //===----------------------------------------------------------------------===//
01609 
01610 void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
01611   VisitCallExpr(E);
01612   Writer.AddStmt(E->getConfig());
01613   Code = serialization::EXPR_CUDA_KERNEL_CALL;
01614 }
01615 
01616 //===----------------------------------------------------------------------===//
01617 // OpenCL Expressions and Statements.
01618 //===----------------------------------------------------------------------===//
01619 void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
01620   VisitExpr(E);
01621   Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
01622   Writer.AddSourceLocation(E->getRParenLoc(), Record);
01623   Writer.AddStmt(E->getSrcExpr());
01624   Code = serialization::EXPR_ASTYPE;
01625 }
01626 
01627 //===----------------------------------------------------------------------===//
01628 // Microsoft Expressions and Statements.
01629 //===----------------------------------------------------------------------===//
01630 void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
01631   VisitExpr(E);
01632   Record.push_back(E->isArrow());
01633   Writer.AddStmt(E->getBaseExpr());
01634   Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
01635   Writer.AddSourceLocation(E->getMemberLoc(), Record);
01636   Writer.AddDeclRef(E->getPropertyDecl(), Record);
01637   Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
01638 }
01639 
01640 void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
01641   VisitExpr(E);
01642   Writer.AddSourceRange(E->getSourceRange(), Record);
01643   if (E->isTypeOperand()) {
01644     Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
01645     Code = serialization::EXPR_CXX_UUIDOF_TYPE;
01646   } else {
01647     Writer.AddStmt(E->getExprOperand());
01648     Code = serialization::EXPR_CXX_UUIDOF_EXPR;
01649   }
01650 }
01651 
01652 void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
01653   VisitStmt(S);
01654   Writer.AddSourceLocation(S->getExceptLoc(), Record);
01655   Writer.AddStmt(S->getFilterExpr());
01656   Writer.AddStmt(S->getBlock());
01657   Code = serialization::STMT_SEH_EXCEPT;
01658 }
01659 
01660 void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
01661   VisitStmt(S);
01662   Writer.AddSourceLocation(S->getFinallyLoc(), Record);
01663   Writer.AddStmt(S->getBlock());
01664   Code = serialization::STMT_SEH_FINALLY;
01665 }
01666 
01667 void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
01668   VisitStmt(S);
01669   Record.push_back(S->getIsCXXTry());
01670   Writer.AddSourceLocation(S->getTryLoc(), Record);
01671   Writer.AddStmt(S->getTryBlock());
01672   Writer.AddStmt(S->getHandler());
01673   Code = serialization::STMT_SEH_TRY;
01674 }
01675 
01676 void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
01677   VisitStmt(S);
01678   Writer.AddSourceLocation(S->getLeaveLoc(), Record);
01679   Code = serialization::STMT_SEH_LEAVE;
01680 }
01681 
01682 //===----------------------------------------------------------------------===//
01683 // OpenMP Clauses.
01684 //===----------------------------------------------------------------------===//
01685 
01686 namespace clang {
01687 class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
01688   ASTStmtWriter *Writer;
01689   ASTWriter::RecordData &Record;
01690 public:
01691   OMPClauseWriter(ASTStmtWriter *W, ASTWriter::RecordData &Record)
01692     : Writer(W), Record(Record) { }
01693 #define OPENMP_CLAUSE(Name, Class)    \
01694   void Visit##Class(Class *S);
01695 #include "clang/Basic/OpenMPKinds.def"
01696   void writeClause(OMPClause *C);
01697 };
01698 }
01699 
01700 void OMPClauseWriter::writeClause(OMPClause *C) {
01701   Record.push_back(C->getClauseKind());
01702   Visit(C);
01703   Writer->Writer.AddSourceLocation(C->getLocStart(), Record);
01704   Writer->Writer.AddSourceLocation(C->getLocEnd(), Record);
01705 }
01706 
01707 void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
01708   Writer->Writer.AddStmt(C->getCondition());
01709   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01710 }
01711 
01712 void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
01713   Writer->Writer.AddStmt(C->getCondition());
01714   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01715 }
01716 
01717 void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
01718   Writer->Writer.AddStmt(C->getNumThreads());
01719   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01720 }
01721 
01722 void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
01723   Writer->Writer.AddStmt(C->getSafelen());
01724   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01725 }
01726 
01727 void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
01728   Writer->Writer.AddStmt(C->getNumForLoops());
01729   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01730 }
01731 
01732 void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
01733   Record.push_back(C->getDefaultKind());
01734   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01735   Writer->Writer.AddSourceLocation(C->getDefaultKindKwLoc(), Record);
01736 }
01737 
01738 void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
01739   Record.push_back(C->getProcBindKind());
01740   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01741   Writer->Writer.AddSourceLocation(C->getProcBindKindKwLoc(), Record);
01742 }
01743 
01744 void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
01745   Record.push_back(C->getScheduleKind());
01746   Writer->Writer.AddStmt(C->getChunkSize());
01747   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01748   Writer->Writer.AddSourceLocation(C->getScheduleKindLoc(), Record);
01749   Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record);
01750 }
01751 
01752 void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *) {}
01753 
01754 void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {}
01755 
01756 void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
01757 
01758 void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
01759 
01760 void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}
01761 
01762 void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
01763 
01764 void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {}
01765 
01766 void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
01767 
01768 void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
01769 
01770 void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
01771   Record.push_back(C->varlist_size());
01772   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01773   for (auto *VE : C->varlists()) {
01774     Writer->Writer.AddStmt(VE);
01775   }
01776   for (auto *VE : C->private_copies()) {
01777     Writer->Writer.AddStmt(VE);
01778   }
01779 }
01780 
01781 void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
01782   Record.push_back(C->varlist_size());
01783   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01784   for (auto *VE : C->varlists()) {
01785     Writer->Writer.AddStmt(VE);
01786   }
01787   for (auto *VE : C->private_copies()) {
01788     Writer->Writer.AddStmt(VE);
01789   }
01790   for (auto *VE : C->inits()) {
01791     Writer->Writer.AddStmt(VE);
01792   }
01793 }
01794 
01795 void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
01796   Record.push_back(C->varlist_size());
01797   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01798   for (auto *VE : C->varlists())
01799     Writer->Writer.AddStmt(VE);
01800 }
01801 
01802 void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
01803   Record.push_back(C->varlist_size());
01804   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01805   for (auto *VE : C->varlists())
01806     Writer->Writer.AddStmt(VE);
01807 }
01808 
01809 void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
01810   Record.push_back(C->varlist_size());
01811   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01812   Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
01813   Writer->Writer.AddNestedNameSpecifierLoc(C->getQualifierLoc(), Record);
01814   Writer->Writer.AddDeclarationNameInfo(C->getNameInfo(), Record);
01815   for (auto *VE : C->varlists())
01816     Writer->Writer.AddStmt(VE);
01817 }
01818 
01819 void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
01820   Record.push_back(C->varlist_size());
01821   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01822   Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
01823   for (auto *VE : C->varlists())
01824     Writer->Writer.AddStmt(VE);
01825   Writer->Writer.AddStmt(C->getStep());
01826 }
01827 
01828 void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
01829   Record.push_back(C->varlist_size());
01830   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01831   Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
01832   for (auto *VE : C->varlists())
01833     Writer->Writer.AddStmt(VE);
01834   Writer->Writer.AddStmt(C->getAlignment());
01835 }
01836 
01837 void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
01838   Record.push_back(C->varlist_size());
01839   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01840   for (auto *VE : C->varlists())
01841     Writer->Writer.AddStmt(VE);
01842 }
01843 
01844 void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
01845   Record.push_back(C->varlist_size());
01846   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01847   for (auto *VE : C->varlists())
01848     Writer->Writer.AddStmt(VE);
01849 }
01850 
01851 void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
01852   Record.push_back(C->varlist_size());
01853   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
01854   for (auto *VE : C->varlists())
01855     Writer->Writer.AddStmt(VE);
01856 }
01857 
01858 //===----------------------------------------------------------------------===//
01859 // OpenMP Directives.
01860 //===----------------------------------------------------------------------===//
01861 void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
01862   Writer.AddSourceLocation(E->getLocStart(), Record);
01863   Writer.AddSourceLocation(E->getLocEnd(), Record);
01864   OMPClauseWriter ClauseWriter(this, Record);
01865   for (unsigned i = 0; i < E->getNumClauses(); ++i) {
01866     ClauseWriter.writeClause(E->getClause(i));
01867   }
01868   if (E->hasAssociatedStmt())
01869     Writer.AddStmt(E->getAssociatedStmt());
01870 }
01871 
01872 void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
01873   VisitStmt(D);
01874   Record.push_back(D->getNumClauses());
01875   Record.push_back(D->getCollapsedNumber());
01876   VisitOMPExecutableDirective(D);
01877   Writer.AddStmt(D->getIterationVariable());
01878   Writer.AddStmt(D->getLastIteration());
01879   Writer.AddStmt(D->getCalcLastIteration());
01880   Writer.AddStmt(D->getPreCond());
01881   Writer.AddStmt(D->getCond(/* SeparateIter */ false));
01882   Writer.AddStmt(D->getCond(/* SeparateIter */ true));
01883   Writer.AddStmt(D->getInit());
01884   Writer.AddStmt(D->getInc());
01885   for (auto I : D->counters()) {
01886     Writer.AddStmt(I);
01887   }
01888   for (auto I : D->updates()) {
01889     Writer.AddStmt(I);
01890   }
01891   for (auto I : D->finals()) {
01892     Writer.AddStmt(I);
01893   }
01894 }
01895 
01896 void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
01897   VisitStmt(D);
01898   Record.push_back(D->getNumClauses());
01899   VisitOMPExecutableDirective(D);
01900   Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
01901 }
01902 
01903 void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
01904   VisitOMPLoopDirective(D);
01905   Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
01906 }
01907 
01908 void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
01909   VisitOMPLoopDirective(D);
01910   Code = serialization::STMT_OMP_FOR_DIRECTIVE;
01911 }
01912 
01913 void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
01914   VisitOMPLoopDirective(D);
01915   Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
01916 }
01917 
01918 void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
01919   VisitStmt(D);
01920   Record.push_back(D->getNumClauses());
01921   VisitOMPExecutableDirective(D);
01922   Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
01923 }
01924 
01925 void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
01926   VisitStmt(D);
01927   VisitOMPExecutableDirective(D);
01928   Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
01929 }
01930 
01931 void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
01932   VisitStmt(D);
01933   Record.push_back(D->getNumClauses());
01934   VisitOMPExecutableDirective(D);
01935   Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
01936 }
01937 
01938 void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
01939   VisitStmt(D);
01940   VisitOMPExecutableDirective(D);
01941   Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
01942 }
01943 
01944 void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
01945   VisitStmt(D);
01946   VisitOMPExecutableDirective(D);
01947   Writer.AddDeclarationNameInfo(D->getDirectiveName(), Record);
01948   Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
01949 }
01950 
01951 void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
01952   VisitOMPLoopDirective(D);
01953   Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
01954 }
01955 
01956 void ASTStmtWriter::VisitOMPParallelForSimdDirective(
01957     OMPParallelForSimdDirective *D) {
01958   VisitOMPLoopDirective(D);
01959   Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
01960 }
01961 
01962 void ASTStmtWriter::VisitOMPParallelSectionsDirective(
01963     OMPParallelSectionsDirective *D) {
01964   VisitStmt(D);
01965   Record.push_back(D->getNumClauses());
01966   VisitOMPExecutableDirective(D);
01967   Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
01968 }
01969 
01970 void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
01971   VisitStmt(D);
01972   Record.push_back(D->getNumClauses());
01973   VisitOMPExecutableDirective(D);
01974   Code = serialization::STMT_OMP_TASK_DIRECTIVE;
01975 }
01976 
01977 void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
01978   VisitStmt(D);
01979   Record.push_back(D->getNumClauses());
01980   VisitOMPExecutableDirective(D);
01981   Writer.AddStmt(D->getX());
01982   Writer.AddStmt(D->getV());
01983   Writer.AddStmt(D->getExpr());
01984   Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
01985 }
01986 
01987 void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
01988   VisitStmt(D);
01989   Record.push_back(D->getNumClauses());
01990   VisitOMPExecutableDirective(D);
01991   Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
01992 }
01993 
01994 void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
01995   VisitStmt(D);
01996   VisitOMPExecutableDirective(D);
01997   Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
01998 }
01999 
02000 void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
02001   VisitStmt(D);
02002   VisitOMPExecutableDirective(D);
02003   Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
02004 }
02005 
02006 void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
02007   VisitStmt(D);
02008   VisitOMPExecutableDirective(D);
02009   Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
02010 }
02011 
02012 void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
02013   VisitStmt(D);
02014   Record.push_back(D->getNumClauses());
02015   VisitOMPExecutableDirective(D);
02016   Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
02017 }
02018 
02019 void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
02020   VisitStmt(D);
02021   VisitOMPExecutableDirective(D);
02022   Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
02023 }
02024 
02025 void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
02026   VisitStmt(D);
02027   Record.push_back(D->getNumClauses());
02028   VisitOMPExecutableDirective(D);
02029   Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
02030 }
02031 
02032 //===----------------------------------------------------------------------===//
02033 // ASTWriter Implementation
02034 //===----------------------------------------------------------------------===//
02035 
02036 unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
02037   assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
02038          "SwitchCase recorded twice");
02039   unsigned NextID = SwitchCaseIDs.size();
02040   SwitchCaseIDs[S] = NextID;
02041   return NextID;
02042 }
02043 
02044 unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
02045   assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
02046          "SwitchCase hasn't been seen yet");
02047   return SwitchCaseIDs[S];
02048 }
02049 
02050 void ASTWriter::ClearSwitchCaseIDs() {
02051   SwitchCaseIDs.clear();
02052 }
02053 
02054 /// \brief Write the given substatement or subexpression to the
02055 /// bitstream.
02056 void ASTWriter::WriteSubStmt(Stmt *S,
02057                              llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
02058                              llvm::DenseSet<Stmt *> &ParentStmts) {
02059   RecordData Record;
02060   ASTStmtWriter Writer(*this, Record);
02061   ++NumStatements;
02062   
02063   if (!S) {
02064     Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
02065     return;
02066   }
02067 
02068   llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
02069   if (I != SubStmtEntries.end()) {
02070     Record.push_back(I->second);
02071     Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
02072     return;
02073   }
02074 
02075 #ifndef NDEBUG
02076   assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
02077 
02078   struct ParentStmtInserterRAII {
02079     Stmt *S;
02080     llvm::DenseSet<Stmt *> &ParentStmts;
02081 
02082     ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
02083       : S(S), ParentStmts(ParentStmts) {
02084       ParentStmts.insert(S);
02085     }
02086     ~ParentStmtInserterRAII() {
02087       ParentStmts.erase(S);
02088     }
02089   };
02090 
02091   ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
02092 #endif
02093 
02094   // Redirect ASTWriter::AddStmt to collect sub-stmts.
02095   SmallVector<Stmt *, 16> SubStmts;
02096   CollectedStmts = &SubStmts;
02097 
02098   Writer.Code = serialization::STMT_NULL_PTR;
02099   Writer.AbbrevToUse = 0;
02100   Writer.Visit(S);
02101   
02102 #ifndef NDEBUG
02103   if (Writer.Code == serialization::STMT_NULL_PTR) {
02104     SourceManager &SrcMgr
02105       = DeclIDs.begin()->first->getASTContext().getSourceManager();
02106     S->dump(SrcMgr);
02107     llvm_unreachable("Unhandled sub-statement writing AST file");
02108   }
02109 #endif
02110 
02111   // Revert ASTWriter::AddStmt.
02112   CollectedStmts = &StmtsToEmit;
02113 
02114   // Write the sub-stmts in reverse order, last to first. When reading them back
02115   // we will read them in correct order by "pop"ing them from the Stmts stack.
02116   // This simplifies reading and allows to store a variable number of sub-stmts
02117   // without knowing it in advance.
02118   while (!SubStmts.empty())
02119     WriteSubStmt(SubStmts.pop_back_val(), SubStmtEntries, ParentStmts);
02120   
02121   Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
02122  
02123   SubStmtEntries[S] = Stream.GetCurrentBitNo();
02124 }
02125 
02126 /// \brief Flush all of the statements that have been added to the
02127 /// queue via AddStmt().
02128 void ASTWriter::FlushStmts() {
02129   RecordData Record;
02130 
02131   // We expect to be the only consumer of the two temporary statement maps,
02132   // assert that they are empty.
02133   assert(SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
02134   assert(ParentStmts.empty() && "unexpected entries in parent stmt map");
02135 
02136   for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
02137     WriteSubStmt(StmtsToEmit[I], SubStmtEntries, ParentStmts);
02138     
02139     assert(N == StmtsToEmit.size() &&
02140            "Substatement written via AddStmt rather than WriteSubStmt!");
02141 
02142     // Note that we are at the end of a full expression. Any
02143     // expression records that follow this one are part of a different
02144     // expression.
02145     Stream.EmitRecord(serialization::STMT_STOP, Record);
02146 
02147     SubStmtEntries.clear();
02148     ParentStmts.clear();
02149   }
02150 
02151   StmtsToEmit.clear();
02152 }