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