]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Serialization/ASTWriterStmt.cpp
Update xz to release 5.0.0
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Serialization / ASTWriterStmt.cpp
1 //===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements serialization for Statements and Expressions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/Serialization/ASTWriter.h"
15 #include "clang/AST/DeclCXX.h"
16 #include "clang/AST/DeclObjC.h"
17 #include "clang/AST/StmtVisitor.h"
18 #include "llvm/Bitcode/BitstreamWriter.h"
19 using namespace clang;
20
21 //===----------------------------------------------------------------------===//
22 // Statement/expression serialization
23 //===----------------------------------------------------------------------===//
24
25 namespace clang {
26   class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
27     ASTWriter &Writer;
28     ASTWriter::RecordData &Record;
29
30   public:
31     serialization::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
139     void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
140     void VisitCXXNewExpr(CXXNewExpr *E);
141     void VisitCXXDeleteExpr(CXXDeleteExpr *E);
142     void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
143
144     void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
145     void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
146     void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
147     void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
148
149     void VisitOverloadExpr(OverloadExpr *E);
150     void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
151     void VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
152
153     void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
154   };
155 }
156
157 void ASTStmtWriter::
158 AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args) {
159   Writer.AddSourceLocation(Args.LAngleLoc, Record);
160   Writer.AddSourceLocation(Args.RAngleLoc, Record);
161   for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
162     Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
163 }
164
165 void ASTStmtWriter::VisitStmt(Stmt *S) {
166 }
167
168 void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
169   VisitStmt(S);
170   Writer.AddSourceLocation(S->getSemiLoc(), Record);
171   Code = serialization::STMT_NULL;
172 }
173
174 void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
175   VisitStmt(S);
176   Record.push_back(S->size());
177   for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
178        CS != CSEnd; ++CS)
179     Writer.AddStmt(*CS);
180   Writer.AddSourceLocation(S->getLBracLoc(), Record);
181   Writer.AddSourceLocation(S->getRBracLoc(), Record);
182   Code = serialization::STMT_COMPOUND;
183 }
184
185 void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
186   VisitStmt(S);
187   Record.push_back(Writer.getSwitchCaseID(S));
188 }
189
190 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
191   VisitSwitchCase(S);
192   Writer.AddStmt(S->getLHS());
193   Writer.AddStmt(S->getRHS());
194   Writer.AddStmt(S->getSubStmt());
195   Writer.AddSourceLocation(S->getCaseLoc(), Record);
196   Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
197   Writer.AddSourceLocation(S->getColonLoc(), Record);
198   Code = serialization::STMT_CASE;
199 }
200
201 void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
202   VisitSwitchCase(S);
203   Writer.AddStmt(S->getSubStmt());
204   Writer.AddSourceLocation(S->getDefaultLoc(), Record);
205   Writer.AddSourceLocation(S->getColonLoc(), Record);
206   Code = serialization::STMT_DEFAULT;
207 }
208
209 void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
210   VisitStmt(S);
211   Writer.AddIdentifierRef(S->getID(), Record);
212   Writer.AddStmt(S->getSubStmt());
213   Writer.AddSourceLocation(S->getIdentLoc(), Record);
214   Record.push_back(Writer.GetLabelID(S));
215   Code = serialization::STMT_LABEL;
216 }
217
218 void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
219   VisitStmt(S);
220   Writer.AddDeclRef(S->getConditionVariable(), Record);
221   Writer.AddStmt(S->getCond());
222   Writer.AddStmt(S->getThen());
223   Writer.AddStmt(S->getElse());
224   Writer.AddSourceLocation(S->getIfLoc(), Record);
225   Writer.AddSourceLocation(S->getElseLoc(), Record);
226   Code = serialization::STMT_IF;
227 }
228
229 void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
230   VisitStmt(S);
231   Writer.AddDeclRef(S->getConditionVariable(), Record);
232   Writer.AddStmt(S->getCond());
233   Writer.AddStmt(S->getBody());
234   Writer.AddSourceLocation(S->getSwitchLoc(), Record);
235   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
236        SC = SC->getNextSwitchCase())
237     Record.push_back(Writer.RecordSwitchCaseID(SC));
238   Code = serialization::STMT_SWITCH;
239 }
240
241 void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
242   VisitStmt(S);
243   Writer.AddDeclRef(S->getConditionVariable(), Record);
244   Writer.AddStmt(S->getCond());
245   Writer.AddStmt(S->getBody());
246   Writer.AddSourceLocation(S->getWhileLoc(), Record);
247   Code = serialization::STMT_WHILE;
248 }
249
250 void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
251   VisitStmt(S);
252   Writer.AddStmt(S->getCond());
253   Writer.AddStmt(S->getBody());
254   Writer.AddSourceLocation(S->getDoLoc(), Record);
255   Writer.AddSourceLocation(S->getWhileLoc(), Record);
256   Writer.AddSourceLocation(S->getRParenLoc(), Record);
257   Code = serialization::STMT_DO;
258 }
259
260 void ASTStmtWriter::VisitForStmt(ForStmt *S) {
261   VisitStmt(S);
262   Writer.AddStmt(S->getInit());
263   Writer.AddStmt(S->getCond());
264   Writer.AddDeclRef(S->getConditionVariable(), Record);
265   Writer.AddStmt(S->getInc());
266   Writer.AddStmt(S->getBody());
267   Writer.AddSourceLocation(S->getForLoc(), Record);
268   Writer.AddSourceLocation(S->getLParenLoc(), Record);
269   Writer.AddSourceLocation(S->getRParenLoc(), Record);
270   Code = serialization::STMT_FOR;
271 }
272
273 void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
274   VisitStmt(S);
275   Record.push_back(Writer.GetLabelID(S->getLabel()));
276   Writer.AddSourceLocation(S->getGotoLoc(), Record);
277   Writer.AddSourceLocation(S->getLabelLoc(), Record);
278   Code = serialization::STMT_GOTO;
279 }
280
281 void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
282   VisitStmt(S);
283   Writer.AddSourceLocation(S->getGotoLoc(), Record);
284   Writer.AddSourceLocation(S->getStarLoc(), Record);
285   Writer.AddStmt(S->getTarget());
286   Code = serialization::STMT_INDIRECT_GOTO;
287 }
288
289 void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
290   VisitStmt(S);
291   Writer.AddSourceLocation(S->getContinueLoc(), Record);
292   Code = serialization::STMT_CONTINUE;
293 }
294
295 void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
296   VisitStmt(S);
297   Writer.AddSourceLocation(S->getBreakLoc(), Record);
298   Code = serialization::STMT_BREAK;
299 }
300
301 void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
302   VisitStmt(S);
303   Writer.AddStmt(S->getRetValue());
304   Writer.AddSourceLocation(S->getReturnLoc(), Record);
305   Writer.AddDeclRef(S->getNRVOCandidate(), Record);
306   Code = serialization::STMT_RETURN;
307 }
308
309 void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
310   VisitStmt(S);
311   Writer.AddSourceLocation(S->getStartLoc(), Record);
312   Writer.AddSourceLocation(S->getEndLoc(), Record);
313   DeclGroupRef DG = S->getDeclGroup();
314   for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
315     Writer.AddDeclRef(*D, Record);
316   Code = serialization::STMT_DECL;
317 }
318
319 void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
320   VisitStmt(S);
321   Record.push_back(S->getNumOutputs());
322   Record.push_back(S->getNumInputs());
323   Record.push_back(S->getNumClobbers());
324   Writer.AddSourceLocation(S->getAsmLoc(), Record);
325   Writer.AddSourceLocation(S->getRParenLoc(), Record);
326   Record.push_back(S->isVolatile());
327   Record.push_back(S->isSimple());
328   Record.push_back(S->isMSAsm());
329   Writer.AddStmt(S->getAsmString());
330
331   // Outputs
332   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {      
333     Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
334     Writer.AddStmt(S->getOutputConstraintLiteral(I));
335     Writer.AddStmt(S->getOutputExpr(I));
336   }
337
338   // Inputs
339   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
340     Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
341     Writer.AddStmt(S->getInputConstraintLiteral(I));
342     Writer.AddStmt(S->getInputExpr(I));
343   }
344
345   // Clobbers
346   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
347     Writer.AddStmt(S->getClobber(I));
348
349   Code = serialization::STMT_ASM;
350 }
351
352 void ASTStmtWriter::VisitExpr(Expr *E) {
353   VisitStmt(E);
354   Writer.AddTypeRef(E->getType(), Record);
355   Record.push_back(E->isTypeDependent());
356   Record.push_back(E->isValueDependent());
357 }
358
359 void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
360   VisitExpr(E);
361   Writer.AddSourceLocation(E->getLocation(), Record);
362   Record.push_back(E->getIdentType()); // FIXME: stable encoding
363   Code = serialization::EXPR_PREDEFINED;
364 }
365
366 void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
367   VisitExpr(E);
368
369   Record.push_back(E->hasQualifier());
370   unsigned NumTemplateArgs = E->getNumTemplateArgs();
371   assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
372          "Template args list with no args ?");
373   Record.push_back(NumTemplateArgs);
374
375   if (E->hasQualifier()) {
376     Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
377     Writer.AddSourceRange(E->getQualifierRange(), Record);
378   }
379
380   if (NumTemplateArgs)
381     AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
382
383   Writer.AddDeclRef(E->getDecl(), Record);
384   // FIXME: write DeclarationNameLoc.
385   Writer.AddSourceLocation(E->getLocation(), Record);
386   Code = serialization::EXPR_DECL_REF;
387 }
388
389 void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
390   VisitExpr(E);
391   Writer.AddSourceLocation(E->getLocation(), Record);
392   Writer.AddAPInt(E->getValue(), Record);
393   Code = serialization::EXPR_INTEGER_LITERAL;
394 }
395
396 void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
397   VisitExpr(E);
398   Writer.AddAPFloat(E->getValue(), Record);
399   Record.push_back(E->isExact());
400   Writer.AddSourceLocation(E->getLocation(), Record);
401   Code = serialization::EXPR_FLOATING_LITERAL;
402 }
403
404 void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
405   VisitExpr(E);
406   Writer.AddStmt(E->getSubExpr());
407   Code = serialization::EXPR_IMAGINARY_LITERAL;
408 }
409
410 void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
411   VisitExpr(E);
412   Record.push_back(E->getByteLength());
413   Record.push_back(E->getNumConcatenated());
414   Record.push_back(E->isWide());
415   // FIXME: String data should be stored as a blob at the end of the
416   // StringLiteral. However, we can't do so now because we have no
417   // provision for coping with abbreviations when we're jumping around
418   // the AST file during deserialization.
419   Record.append(E->getString().begin(), E->getString().end());
420   for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
421     Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
422   Code = serialization::EXPR_STRING_LITERAL;
423 }
424
425 void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
426   VisitExpr(E);
427   Record.push_back(E->getValue());
428   Writer.AddSourceLocation(E->getLocation(), Record);
429   Record.push_back(E->isWide());
430   Code = serialization::EXPR_CHARACTER_LITERAL;
431 }
432
433 void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
434   VisitExpr(E);
435   Writer.AddSourceLocation(E->getLParen(), Record);
436   Writer.AddSourceLocation(E->getRParen(), Record);
437   Writer.AddStmt(E->getSubExpr());
438   Code = serialization::EXPR_PAREN;
439 }
440
441 void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
442   VisitExpr(E);
443   Record.push_back(E->NumExprs);
444   for (unsigned i=0; i != E->NumExprs; ++i)
445     Writer.AddStmt(E->Exprs[i]);
446   Writer.AddSourceLocation(E->LParenLoc, Record);
447   Writer.AddSourceLocation(E->RParenLoc, Record);
448   Code = serialization::EXPR_PAREN_LIST;
449 }
450
451 void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
452   VisitExpr(E);
453   Writer.AddStmt(E->getSubExpr());
454   Record.push_back(E->getOpcode()); // FIXME: stable encoding
455   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
456   Code = serialization::EXPR_UNARY_OPERATOR;
457 }
458
459 void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
460   VisitExpr(E);
461   Record.push_back(E->getNumComponents());
462   Record.push_back(E->getNumExpressions());
463   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
464   Writer.AddSourceLocation(E->getRParenLoc(), Record);
465   Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
466   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
467     const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
468     Record.push_back(ON.getKind()); // FIXME: Stable encoding
469     Writer.AddSourceLocation(ON.getRange().getBegin(), Record);
470     Writer.AddSourceLocation(ON.getRange().getEnd(), Record);
471     switch (ON.getKind()) {
472     case OffsetOfExpr::OffsetOfNode::Array:
473       Record.push_back(ON.getArrayExprIndex());
474       break;
475         
476     case OffsetOfExpr::OffsetOfNode::Field:
477       Writer.AddDeclRef(ON.getField(), Record);
478       break;
479         
480     case OffsetOfExpr::OffsetOfNode::Identifier:
481       Writer.AddIdentifierRef(ON.getFieldName(), Record);
482       break;
483         
484     case OffsetOfExpr::OffsetOfNode::Base:
485       Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
486       break;
487     }
488   }
489   for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
490     Writer.AddStmt(E->getIndexExpr(I));
491   Code = serialization::EXPR_OFFSETOF;
492 }
493
494 void ASTStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
495   VisitExpr(E);
496   Record.push_back(E->isSizeOf());
497   if (E->isArgumentType())
498     Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
499   else {
500     Record.push_back(0);
501     Writer.AddStmt(E->getArgumentExpr());
502   }
503   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
504   Writer.AddSourceLocation(E->getRParenLoc(), Record);
505   Code = serialization::EXPR_SIZEOF_ALIGN_OF;
506 }
507
508 void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
509   VisitExpr(E);
510   Writer.AddStmt(E->getLHS());
511   Writer.AddStmt(E->getRHS());
512   Writer.AddSourceLocation(E->getRBracketLoc(), Record);
513   Code = serialization::EXPR_ARRAY_SUBSCRIPT;
514 }
515
516 void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
517   VisitExpr(E);
518   Record.push_back(E->getNumArgs());
519   Writer.AddSourceLocation(E->getRParenLoc(), Record);
520   Writer.AddStmt(E->getCallee());
521   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
522        Arg != ArgEnd; ++Arg)
523     Writer.AddStmt(*Arg);
524   Code = serialization::EXPR_CALL;
525 }
526
527 void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
528   // Don't call VisitExpr, we'll write everything here.
529
530   Record.push_back(E->hasQualifier());
531   if (E->hasQualifier()) {
532     Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
533     Writer.AddSourceRange(E->getQualifierRange(), Record);
534   }
535
536   unsigned NumTemplateArgs = E->getNumTemplateArgs();
537   assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() &&
538          "Template args list with no args ?");
539   Record.push_back(NumTemplateArgs);
540   if (NumTemplateArgs) {
541     Writer.AddSourceLocation(E->getLAngleLoc(), Record);
542     Writer.AddSourceLocation(E->getRAngleLoc(), Record);
543     for (unsigned i=0; i != NumTemplateArgs; ++i)
544       Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
545   }
546   
547   DeclAccessPair FoundDecl = E->getFoundDecl();
548   Writer.AddDeclRef(FoundDecl.getDecl(), Record);
549   Record.push_back(FoundDecl.getAccess());
550
551   Writer.AddTypeRef(E->getType(), Record);
552   Writer.AddStmt(E->getBase());
553   Writer.AddDeclRef(E->getMemberDecl(), Record);
554   // FIXME: write DeclarationNameLoc.
555   Writer.AddSourceLocation(E->getMemberLoc(), Record);
556   Record.push_back(E->isArrow());
557   Code = serialization::EXPR_MEMBER;
558 }
559
560 void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
561   VisitExpr(E);
562   Writer.AddStmt(E->getBase());
563   Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
564   Record.push_back(E->isArrow());
565   Code = serialization::EXPR_OBJC_ISA;
566 }
567
568 void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
569   VisitExpr(E);
570   Record.push_back(E->path_size());
571   Writer.AddStmt(E->getSubExpr());
572   Record.push_back(E->getCastKind()); // FIXME: stable encoding
573
574   for (CastExpr::path_iterator
575          PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
576     Writer.AddCXXBaseSpecifier(**PI, Record);
577 }
578
579 void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
580   VisitExpr(E);
581   Writer.AddStmt(E->getLHS());
582   Writer.AddStmt(E->getRHS());
583   Record.push_back(E->getOpcode()); // FIXME: stable encoding
584   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
585   Code = serialization::EXPR_BINARY_OPERATOR;
586 }
587
588 void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
589   VisitBinaryOperator(E);
590   Writer.AddTypeRef(E->getComputationLHSType(), Record);
591   Writer.AddTypeRef(E->getComputationResultType(), Record);
592   Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
593 }
594
595 void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
596   VisitExpr(E);
597   Writer.AddStmt(E->getCond());
598   Writer.AddStmt(E->getLHS());
599   Writer.AddStmt(E->getRHS());
600   Writer.AddStmt(E->getSAVE());
601   Writer.AddSourceLocation(E->getQuestionLoc(), Record);
602   Writer.AddSourceLocation(E->getColonLoc(), Record);
603   Code = serialization::EXPR_CONDITIONAL_OPERATOR;
604 }
605
606 void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
607   VisitCastExpr(E);
608   Record.push_back(E->getValueKind());
609   Code = serialization::EXPR_IMPLICIT_CAST;
610 }
611
612 void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
613   VisitCastExpr(E);
614   Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
615 }
616
617 void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
618   VisitExplicitCastExpr(E);
619   Writer.AddSourceLocation(E->getLParenLoc(), Record);
620   Writer.AddSourceLocation(E->getRParenLoc(), Record);
621   Code = serialization::EXPR_CSTYLE_CAST;
622 }
623
624 void 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 = serialization::EXPR_COMPOUND_LITERAL;
631 }
632
633 void 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 = serialization::EXPR_EXT_VECTOR_ELEMENT;
639 }
640
641 void 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 = serialization::EXPR_INIT_LIST;
652 }
653
654 void 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(serialization::DESIG_FIELD_DECL);
667         Writer.AddDeclRef(Field, Record);
668       } else {
669         Record.push_back(serialization::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(serialization::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(serialization::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 = serialization::EXPR_DESIGNATED_INIT;
689 }
690
691 void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
692   VisitExpr(E);
693   Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
694 }
695
696 void 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 = serialization::EXPR_VA_ARG;
703 }
704
705 void 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 = serialization::EXPR_ADDR_LABEL;
711 }
712
713 void 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 = serialization::EXPR_STMT;
719 }
720
721 void 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 = serialization::EXPR_TYPES_COMPATIBLE;
728 }
729
730 void 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 = serialization::EXPR_CHOOSE;
738 }
739
740 void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
741   VisitExpr(E);
742   Writer.AddSourceLocation(E->getTokenLocation(), Record);
743   Code = serialization::EXPR_GNU_NULL;
744 }
745
746 void 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 = serialization::EXPR_SHUFFLE_VECTOR;
754 }
755
756 void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
757   VisitExpr(E);
758   Writer.AddDeclRef(E->getBlockDecl(), Record);
759   Record.push_back(E->hasBlockDeclRefExprs());
760   Code = serialization::EXPR_BLOCK;
761 }
762
763 void 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 = serialization::EXPR_BLOCK_DECL_REF;
771 }
772
773 //===----------------------------------------------------------------------===//
774 // Objective-C Expressions and Statements.
775 //===----------------------------------------------------------------------===//
776
777 void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
778   VisitExpr(E);
779   Writer.AddStmt(E->getString());
780   Writer.AddSourceLocation(E->getAtLoc(), Record);
781   Code = serialization::EXPR_OBJC_STRING_LITERAL;
782 }
783
784 void 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 = serialization::EXPR_OBJC_ENCODE;
790 }
791
792 void 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 = serialization::EXPR_OBJC_SELECTOR_EXPR;
798 }
799
800 void 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 = serialization::EXPR_OBJC_PROTOCOL_EXPR;
806 }
807
808 void 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 = serialization::EXPR_OBJC_IVAR_REF_EXPR;
816 }
817
818 void 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 = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
824 }
825
826 void 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 = serialization::EXPR_OBJC_KVC_REF_EXPR;
838 }
839
840 void 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 = serialization::EXPR_OBJC_MESSAGE_EXPR;
875 }
876
877 void ASTStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) {
878   VisitExpr(E);
879   Writer.AddSourceLocation(E->getLoc(), Record);
880   Code = serialization::EXPR_OBJC_SUPER_EXPR;
881 }
882
883 void 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 = serialization::STMT_OBJC_FOR_COLLECTION;
891 }
892
893 void 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 = serialization::STMT_OBJC_CATCH;
899 }
900
901 void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
902   Writer.AddStmt(S->getFinallyBody());
903   Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
904   Code = serialization::STMT_OBJC_FINALLY;
905 }
906
907 void 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 = serialization::STMT_OBJC_AT_TRY;
917 }
918
919 void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
920   Writer.AddStmt(S->getSynchExpr());
921   Writer.AddStmt(S->getSynchBody());
922   Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
923   Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
924 }
925
926 void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
927   Writer.AddStmt(S->getThrowExpr());
928   Writer.AddSourceLocation(S->getThrowLoc(), Record);
929   Code = serialization::STMT_OBJC_AT_THROW;
930 }
931
932 //===----------------------------------------------------------------------===//
933 // C++ Expressions and Statements.
934 //===----------------------------------------------------------------------===//
935
936 void 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 = serialization::STMT_CXX_CATCH;
942 }
943
944 void 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 = serialization::STMT_CXX_TRY;
952 }
953
954 void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
955   VisitCallExpr(E);
956   Record.push_back(E->getOperator());
957   Code = serialization::EXPR_CXX_OPERATOR_CALL;
958 }
959
960 void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
961   VisitCallExpr(E);
962   Code = serialization::EXPR_CXX_MEMBER_CALL;
963 }
964
965 void 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 = serialization::EXPR_CXX_CONSTRUCT;
976 }
977
978 void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
979   VisitCXXConstructExpr(E);
980   Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
981   Writer.AddSourceLocation(E->getRParenLoc(), Record);
982   Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
983 }
984
985 void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
986   VisitExplicitCastExpr(E);
987   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
988 }
989
990 void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
991   VisitCXXNamedCastExpr(E);
992   Code = serialization::EXPR_CXX_STATIC_CAST;
993 }
994
995 void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
996   VisitCXXNamedCastExpr(E);
997   Code = serialization::EXPR_CXX_DYNAMIC_CAST;
998 }
999
1000 void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
1001   VisitCXXNamedCastExpr(E);
1002   Code = serialization::EXPR_CXX_REINTERPRET_CAST;
1003 }
1004
1005 void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
1006   VisitCXXNamedCastExpr(E);
1007   Code = serialization::EXPR_CXX_CONST_CAST;
1008 }
1009
1010 void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
1011   VisitExplicitCastExpr(E);
1012   Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
1013   Writer.AddSourceLocation(E->getRParenLoc(), Record);
1014   Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
1015 }
1016
1017 void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
1018   VisitExpr(E);
1019   Record.push_back(E->getValue());
1020   Writer.AddSourceLocation(E->getLocation(), Record);
1021   Code = serialization::EXPR_CXX_BOOL_LITERAL;
1022 }
1023
1024 void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
1025   VisitExpr(E);
1026   Writer.AddSourceLocation(E->getLocation(), Record);
1027   Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
1028 }
1029
1030 void 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 = serialization::EXPR_CXX_TYPEID_TYPE;
1036   } else {
1037     Writer.AddStmt(E->getExprOperand());
1038     Code = serialization::EXPR_CXX_TYPEID_EXPR;
1039   }
1040 }
1041
1042 void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
1043   VisitExpr(E);
1044   Writer.AddSourceLocation(E->getLocation(), Record);
1045   Record.push_back(E->isImplicit());
1046   Code = serialization::EXPR_CXX_THIS;
1047 }
1048
1049 void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
1050   VisitExpr(E);
1051   Writer.AddSourceLocation(E->getThrowLoc(), Record);
1052   Writer.AddStmt(E->getSubExpr());
1053   Code = serialization::EXPR_CXX_THROW;
1054 }
1055
1056 void 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 = serialization::EXPR_CXX_DEFAULT_ARG;
1068 }
1069
1070 void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
1071   VisitExpr(E);
1072   Writer.AddCXXTemporary(E->getTemporary(), Record);
1073   Writer.AddStmt(E->getSubExpr());
1074   Code = serialization::EXPR_CXX_BIND_TEMPORARY;
1075 }
1076
1077 void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1078   VisitExpr(E);
1079   Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
1080   Writer.AddSourceLocation(E->getRParenLoc(), Record);
1081   Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
1082 }
1083
1084 void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
1085   VisitExpr(E);
1086   Record.push_back(E->isGlobalNew());
1087   Record.push_back(E->hasInitializer());
1088   Record.push_back(E->isArray());
1089   Record.push_back(E->getNumPlacementArgs());
1090   Record.push_back(E->getNumConstructorArgs());
1091   Writer.AddDeclRef(E->getOperatorNew(), Record);
1092   Writer.AddDeclRef(E->getOperatorDelete(), Record);
1093   Writer.AddDeclRef(E->getConstructor(), Record);
1094   Writer.AddSourceRange(E->getTypeIdParens(), Record);
1095   Writer.AddSourceLocation(E->getStartLoc(), Record);
1096   Writer.AddSourceLocation(E->getEndLoc(), Record);
1097   for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
1098        I != e; ++I)
1099     Writer.AddStmt(*I);
1100   
1101   Code = serialization::EXPR_CXX_NEW;
1102 }
1103
1104 void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1105   VisitExpr(E);
1106   Record.push_back(E->isGlobalDelete());
1107   Record.push_back(E->isArrayForm());
1108   Writer.AddDeclRef(E->getOperatorDelete(), Record);
1109   Writer.AddStmt(E->getArgument());
1110   Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
1111   
1112   Code = serialization::EXPR_CXX_DELETE;
1113 }
1114
1115 void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1116   VisitExpr(E);
1117
1118   Writer.AddStmt(E->getBase());
1119   Record.push_back(E->isArrow());
1120   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1121   Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
1122   Writer.AddSourceRange(E->getQualifierRange(), Record);
1123   Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
1124   Writer.AddSourceLocation(E->getColonColonLoc(), Record);
1125   Writer.AddSourceLocation(E->getTildeLoc(), Record);
1126
1127   // PseudoDestructorTypeStorage.
1128   Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
1129   if (E->getDestroyedTypeIdentifier())
1130     Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
1131   else
1132     Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
1133
1134   Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
1135 }
1136
1137 void ASTStmtWriter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
1138   VisitExpr(E);
1139   Record.push_back(E->getNumTemporaries());
1140   for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i)
1141     Writer.AddCXXTemporary(E->getTemporary(i), Record);
1142   
1143   Writer.AddStmt(E->getSubExpr());
1144   Code = serialization::EXPR_CXX_EXPR_WITH_TEMPORARIES;
1145 }
1146
1147 void
1148 ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
1149   VisitExpr(E);
1150   
1151   // Don't emit anything here, NumTemplateArgs must be emitted first.
1152
1153   if (E->hasExplicitTemplateArgs()) {
1154     const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1155     assert(Args.NumTemplateArgs &&
1156            "Num of template args was zero! AST reading will mess up!");
1157     Record.push_back(Args.NumTemplateArgs);
1158     AddExplicitTemplateArgumentList(Args);
1159   } else {
1160     Record.push_back(0);
1161   }
1162   
1163   if (!E->isImplicitAccess())
1164     Writer.AddStmt(E->getBase());
1165   else
1166     Writer.AddStmt(0);
1167   Writer.AddTypeRef(E->getBaseType(), Record);
1168   Record.push_back(E->isArrow());
1169   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1170   Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
1171   Writer.AddSourceRange(E->getQualifierRange(), Record);
1172   Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
1173   // FIXME: write whole DeclarationNameInfo.
1174   Writer.AddDeclarationName(E->getMember(), Record);
1175   Writer.AddSourceLocation(E->getMemberLoc(), Record);
1176   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
1177 }
1178
1179 void
1180 ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1181   VisitExpr(E);
1182   
1183   // Don't emit anything here, NumTemplateArgs must be emitted first.
1184
1185   if (E->hasExplicitTemplateArgs()) {
1186     const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1187     assert(Args.NumTemplateArgs &&
1188            "Num of template args was zero! AST reading will mess up!");
1189     Record.push_back(Args.NumTemplateArgs);
1190     AddExplicitTemplateArgumentList(Args);
1191   } else {
1192     Record.push_back(0);
1193   }
1194
1195   // FIXME: write whole DeclarationNameInfo.
1196   Writer.AddDeclarationName(E->getDeclName(), Record);
1197   Writer.AddSourceLocation(E->getLocation(), Record);
1198   Writer.AddSourceRange(E->getQualifierRange(), Record);
1199   Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
1200   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
1201 }
1202
1203 void
1204 ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
1205   VisitExpr(E);
1206   Record.push_back(E->arg_size());
1207   for (CXXUnresolvedConstructExpr::arg_iterator
1208          ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
1209     Writer.AddStmt(*ArgI);
1210   Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
1211   Writer.AddTypeRef(E->getTypeAsWritten(), Record);
1212   Writer.AddSourceLocation(E->getLParenLoc(), Record);
1213   Writer.AddSourceLocation(E->getRParenLoc(), Record);
1214   Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
1215 }
1216
1217 void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
1218   VisitExpr(E);
1219   
1220   // Don't emit anything here, NumTemplateArgs must be emitted first.
1221
1222   if (E->hasExplicitTemplateArgs()) {
1223     const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1224     assert(Args.NumTemplateArgs &&
1225            "Num of template args was zero! AST reading will mess up!");
1226     Record.push_back(Args.NumTemplateArgs);
1227     AddExplicitTemplateArgumentList(Args);
1228   } else {
1229     Record.push_back(0);
1230   }
1231
1232   Record.push_back(E->getNumDecls());
1233   for (OverloadExpr::decls_iterator
1234          OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
1235     Writer.AddDeclRef(OvI.getDecl(), Record);
1236     Record.push_back(OvI.getAccess());
1237   }
1238
1239   // FIXME: write whole DeclarationNameInfo.
1240   Writer.AddDeclarationName(E->getName(), Record);
1241   Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
1242   Writer.AddSourceRange(E->getQualifierRange(), Record);
1243   Writer.AddSourceLocation(E->getNameLoc(), Record);
1244 }
1245
1246 void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
1247   VisitOverloadExpr(E);
1248   Record.push_back(E->isArrow());
1249   Record.push_back(E->hasUnresolvedUsing());
1250   Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
1251   Writer.AddTypeRef(E->getBaseType(), Record);
1252   Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1253   Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
1254 }
1255
1256 void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
1257   VisitOverloadExpr(E);
1258   Record.push_back(E->requiresADL());
1259   Record.push_back(E->isOverloaded());
1260   Writer.AddDeclRef(E->getNamingClass(), Record);
1261   Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
1262 }
1263
1264 void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1265   VisitExpr(E);
1266   Record.push_back(E->getTrait());
1267   Writer.AddSourceRange(E->getSourceRange(), Record);
1268   Writer.AddTypeRef(E->getQueriedType(), Record);
1269   Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
1270 }
1271
1272 //===----------------------------------------------------------------------===//
1273 // ASTWriter Implementation
1274 //===----------------------------------------------------------------------===//
1275
1276 unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
1277   assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
1278          "SwitchCase recorded twice");
1279   unsigned NextID = SwitchCaseIDs.size();
1280   SwitchCaseIDs[S] = NextID;
1281   return NextID;
1282 }
1283
1284 unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
1285   assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
1286          "SwitchCase hasn't been seen yet");
1287   return SwitchCaseIDs[S];
1288 }
1289
1290 /// \brief Retrieve the ID for the given label statement, which may
1291 /// or may not have been emitted yet.
1292 unsigned ASTWriter::GetLabelID(LabelStmt *S) {
1293   std::map<LabelStmt *, unsigned>::iterator Pos = LabelIDs.find(S);
1294   if (Pos != LabelIDs.end())
1295     return Pos->second;
1296
1297   unsigned NextID = LabelIDs.size();
1298   LabelIDs[S] = NextID;
1299   return NextID;
1300 }
1301
1302 /// \brief Write the given substatement or subexpression to the
1303 /// bitstream.
1304 void ASTWriter::WriteSubStmt(Stmt *S) {
1305   RecordData Record;
1306   ASTStmtWriter Writer(*this, Record);
1307   ++NumStatements;
1308   
1309   if (!S) {
1310     Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
1311     return;
1312   }
1313
1314   // Redirect ASTWriter::AddStmt to collect sub stmts.
1315   llvm::SmallVector<Stmt *, 16> SubStmts;
1316   CollectedStmts = &SubStmts;
1317
1318   Writer.Code = serialization::STMT_NULL_PTR;
1319   Writer.Visit(S);
1320   
1321 #ifndef NDEBUG
1322   if (Writer.Code == serialization::STMT_NULL_PTR) {
1323     SourceManager &SrcMgr
1324       = DeclIDs.begin()->first->getASTContext().getSourceManager();
1325     S->dump(SrcMgr);
1326     assert(0 && "Unhandled sub statement writing AST file");
1327   }
1328 #endif
1329
1330   // Revert ASTWriter::AddStmt.
1331   CollectedStmts = &StmtsToEmit;
1332
1333   // Write the sub stmts in reverse order, last to first. When reading them back
1334   // we will read them in correct order by "pop"ing them from the Stmts stack.
1335   // This simplifies reading and allows to store a variable number of sub stmts
1336   // without knowing it in advance.
1337   while (!SubStmts.empty())
1338     WriteSubStmt(SubStmts.pop_back_val());
1339   
1340   Stream.EmitRecord(Writer.Code, Record);
1341 }
1342
1343 /// \brief Flush all of the statements that have been added to the
1344 /// queue via AddStmt().
1345 void ASTWriter::FlushStmts() {
1346   RecordData Record;
1347
1348   for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
1349     WriteSubStmt(StmtsToEmit[I]);
1350     
1351     assert(N == StmtsToEmit.size() &&
1352            "Substatement writen via AddStmt rather than WriteSubStmt!");
1353
1354     // Note that we are at the end of a full expression. Any
1355     // expression records that follow this one are part of a different
1356     // expression.
1357     Stream.EmitRecord(serialization::STMT_STOP, Record);
1358   }
1359
1360   StmtsToEmit.clear();
1361 }