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