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