ASTWriterStmt.cpp revision 224145
1212795Sdim//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
2212795Sdim//
3212795Sdim//                     The LLVM Compiler Infrastructure
4212795Sdim//
5212795Sdim// This file is distributed under the University of Illinois Open Source
6212795Sdim// License. See LICENSE.TXT for details.
7212795Sdim//
8212795Sdim//===----------------------------------------------------------------------===//
9212795Sdim//
10212795Sdim//  This file implements serialization for Statements and Expressions.
11212795Sdim//
12212795Sdim//===----------------------------------------------------------------------===//
13212795Sdim
14212795Sdim#include "clang/Serialization/ASTWriter.h"
15212795Sdim#include "clang/AST/DeclCXX.h"
16212795Sdim#include "clang/AST/DeclObjC.h"
17218893Sdim#include "clang/AST/DeclTemplate.h"
18212795Sdim#include "clang/AST/StmtVisitor.h"
19212795Sdim#include "llvm/Bitcode/BitstreamWriter.h"
20212795Sdimusing namespace clang;
21212795Sdim
22212795Sdim//===----------------------------------------------------------------------===//
23212795Sdim// Statement/expression serialization
24212795Sdim//===----------------------------------------------------------------------===//
25212795Sdim
26212795Sdimnamespace clang {
27212795Sdim  class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
28212795Sdim    ASTWriter &Writer;
29212795Sdim    ASTWriter::RecordData &Record;
30212795Sdim
31212795Sdim  public:
32212795Sdim    serialization::StmtCode Code;
33223017Sdim    unsigned AbbrevToUse;
34212795Sdim
35212795Sdim    ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
36212795Sdim      : Writer(Writer), Record(Record) { }
37212795Sdim
38212795Sdim    void
39212795Sdim    AddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args);
40212795Sdim
41212795Sdim    void VisitStmt(Stmt *S);
42224145Sdim#define STMT(Type, Base) \
43224145Sdim    void Visit##Type(Type *);
44224145Sdim#include "clang/AST/StmtNodes.inc"
45212795Sdim  };
46212795Sdim}
47212795Sdim
48212795Sdimvoid ASTStmtWriter::
49212795SdimAddExplicitTemplateArgumentList(const ExplicitTemplateArgumentList &Args) {
50212795Sdim  Writer.AddSourceLocation(Args.LAngleLoc, Record);
51212795Sdim  Writer.AddSourceLocation(Args.RAngleLoc, Record);
52212795Sdim  for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
53212795Sdim    Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
54212795Sdim}
55212795Sdim
56212795Sdimvoid ASTStmtWriter::VisitStmt(Stmt *S) {
57212795Sdim}
58212795Sdim
59212795Sdimvoid ASTStmtWriter::VisitNullStmt(NullStmt *S) {
60212795Sdim  VisitStmt(S);
61212795Sdim  Writer.AddSourceLocation(S->getSemiLoc(), Record);
62221345Sdim  Writer.AddSourceLocation(S->LeadingEmptyMacro, Record);
63212795Sdim  Code = serialization::STMT_NULL;
64212795Sdim}
65212795Sdim
66212795Sdimvoid ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
67212795Sdim  VisitStmt(S);
68212795Sdim  Record.push_back(S->size());
69212795Sdim  for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
70212795Sdim       CS != CSEnd; ++CS)
71212795Sdim    Writer.AddStmt(*CS);
72212795Sdim  Writer.AddSourceLocation(S->getLBracLoc(), Record);
73212795Sdim  Writer.AddSourceLocation(S->getRBracLoc(), Record);
74212795Sdim  Code = serialization::STMT_COMPOUND;
75212795Sdim}
76212795Sdim
77212795Sdimvoid ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
78212795Sdim  VisitStmt(S);
79212795Sdim  Record.push_back(Writer.getSwitchCaseID(S));
80212795Sdim}
81212795Sdim
82212795Sdimvoid ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
83212795Sdim  VisitSwitchCase(S);
84212795Sdim  Writer.AddStmt(S->getLHS());
85212795Sdim  Writer.AddStmt(S->getRHS());
86212795Sdim  Writer.AddStmt(S->getSubStmt());
87212795Sdim  Writer.AddSourceLocation(S->getCaseLoc(), Record);
88212795Sdim  Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
89212795Sdim  Writer.AddSourceLocation(S->getColonLoc(), Record);
90212795Sdim  Code = serialization::STMT_CASE;
91212795Sdim}
92212795Sdim
93212795Sdimvoid ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
94212795Sdim  VisitSwitchCase(S);
95212795Sdim  Writer.AddStmt(S->getSubStmt());
96212795Sdim  Writer.AddSourceLocation(S->getDefaultLoc(), Record);
97212795Sdim  Writer.AddSourceLocation(S->getColonLoc(), Record);
98212795Sdim  Code = serialization::STMT_DEFAULT;
99212795Sdim}
100212795Sdim
101212795Sdimvoid ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
102212795Sdim  VisitStmt(S);
103218893Sdim  Writer.AddDeclRef(S->getDecl(), Record);
104212795Sdim  Writer.AddStmt(S->getSubStmt());
105212795Sdim  Writer.AddSourceLocation(S->getIdentLoc(), Record);
106212795Sdim  Code = serialization::STMT_LABEL;
107212795Sdim}
108212795Sdim
109212795Sdimvoid ASTStmtWriter::VisitIfStmt(IfStmt *S) {
110212795Sdim  VisitStmt(S);
111212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
112212795Sdim  Writer.AddStmt(S->getCond());
113212795Sdim  Writer.AddStmt(S->getThen());
114212795Sdim  Writer.AddStmt(S->getElse());
115212795Sdim  Writer.AddSourceLocation(S->getIfLoc(), Record);
116212795Sdim  Writer.AddSourceLocation(S->getElseLoc(), Record);
117212795Sdim  Code = serialization::STMT_IF;
118212795Sdim}
119212795Sdim
120212795Sdimvoid ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
121212795Sdim  VisitStmt(S);
122212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
123212795Sdim  Writer.AddStmt(S->getCond());
124212795Sdim  Writer.AddStmt(S->getBody());
125212795Sdim  Writer.AddSourceLocation(S->getSwitchLoc(), Record);
126218893Sdim  Record.push_back(S->isAllEnumCasesCovered());
127212795Sdim  for (SwitchCase *SC = S->getSwitchCaseList(); SC;
128212795Sdim       SC = SC->getNextSwitchCase())
129212795Sdim    Record.push_back(Writer.RecordSwitchCaseID(SC));
130212795Sdim  Code = serialization::STMT_SWITCH;
131212795Sdim}
132212795Sdim
133212795Sdimvoid ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
134212795Sdim  VisitStmt(S);
135212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
136212795Sdim  Writer.AddStmt(S->getCond());
137212795Sdim  Writer.AddStmt(S->getBody());
138212795Sdim  Writer.AddSourceLocation(S->getWhileLoc(), Record);
139212795Sdim  Code = serialization::STMT_WHILE;
140212795Sdim}
141212795Sdim
142212795Sdimvoid ASTStmtWriter::VisitDoStmt(DoStmt *S) {
143212795Sdim  VisitStmt(S);
144212795Sdim  Writer.AddStmt(S->getCond());
145212795Sdim  Writer.AddStmt(S->getBody());
146212795Sdim  Writer.AddSourceLocation(S->getDoLoc(), Record);
147212795Sdim  Writer.AddSourceLocation(S->getWhileLoc(), Record);
148212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
149212795Sdim  Code = serialization::STMT_DO;
150212795Sdim}
151212795Sdim
152212795Sdimvoid ASTStmtWriter::VisitForStmt(ForStmt *S) {
153212795Sdim  VisitStmt(S);
154212795Sdim  Writer.AddStmt(S->getInit());
155212795Sdim  Writer.AddStmt(S->getCond());
156212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
157212795Sdim  Writer.AddStmt(S->getInc());
158212795Sdim  Writer.AddStmt(S->getBody());
159212795Sdim  Writer.AddSourceLocation(S->getForLoc(), Record);
160212795Sdim  Writer.AddSourceLocation(S->getLParenLoc(), Record);
161212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
162212795Sdim  Code = serialization::STMT_FOR;
163212795Sdim}
164212795Sdim
165212795Sdimvoid ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
166212795Sdim  VisitStmt(S);
167218893Sdim  Writer.AddDeclRef(S->getLabel(), Record);
168212795Sdim  Writer.AddSourceLocation(S->getGotoLoc(), Record);
169212795Sdim  Writer.AddSourceLocation(S->getLabelLoc(), Record);
170212795Sdim  Code = serialization::STMT_GOTO;
171212795Sdim}
172212795Sdim
173212795Sdimvoid ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
174212795Sdim  VisitStmt(S);
175212795Sdim  Writer.AddSourceLocation(S->getGotoLoc(), Record);
176212795Sdim  Writer.AddSourceLocation(S->getStarLoc(), Record);
177212795Sdim  Writer.AddStmt(S->getTarget());
178212795Sdim  Code = serialization::STMT_INDIRECT_GOTO;
179212795Sdim}
180212795Sdim
181212795Sdimvoid ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
182212795Sdim  VisitStmt(S);
183212795Sdim  Writer.AddSourceLocation(S->getContinueLoc(), Record);
184212795Sdim  Code = serialization::STMT_CONTINUE;
185212795Sdim}
186212795Sdim
187212795Sdimvoid ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
188212795Sdim  VisitStmt(S);
189212795Sdim  Writer.AddSourceLocation(S->getBreakLoc(), Record);
190212795Sdim  Code = serialization::STMT_BREAK;
191212795Sdim}
192212795Sdim
193212795Sdimvoid ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
194212795Sdim  VisitStmt(S);
195212795Sdim  Writer.AddStmt(S->getRetValue());
196212795Sdim  Writer.AddSourceLocation(S->getReturnLoc(), Record);
197212795Sdim  Writer.AddDeclRef(S->getNRVOCandidate(), Record);
198212795Sdim  Code = serialization::STMT_RETURN;
199212795Sdim}
200212795Sdim
201212795Sdimvoid ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
202212795Sdim  VisitStmt(S);
203212795Sdim  Writer.AddSourceLocation(S->getStartLoc(), Record);
204212795Sdim  Writer.AddSourceLocation(S->getEndLoc(), Record);
205212795Sdim  DeclGroupRef DG = S->getDeclGroup();
206212795Sdim  for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
207212795Sdim    Writer.AddDeclRef(*D, Record);
208212795Sdim  Code = serialization::STMT_DECL;
209212795Sdim}
210212795Sdim
211212795Sdimvoid ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
212212795Sdim  VisitStmt(S);
213212795Sdim  Record.push_back(S->getNumOutputs());
214212795Sdim  Record.push_back(S->getNumInputs());
215212795Sdim  Record.push_back(S->getNumClobbers());
216212795Sdim  Writer.AddSourceLocation(S->getAsmLoc(), Record);
217212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
218212795Sdim  Record.push_back(S->isVolatile());
219212795Sdim  Record.push_back(S->isSimple());
220212795Sdim  Record.push_back(S->isMSAsm());
221212795Sdim  Writer.AddStmt(S->getAsmString());
222212795Sdim
223212795Sdim  // Outputs
224212795Sdim  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
225212795Sdim    Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
226212795Sdim    Writer.AddStmt(S->getOutputConstraintLiteral(I));
227212795Sdim    Writer.AddStmt(S->getOutputExpr(I));
228212795Sdim  }
229212795Sdim
230212795Sdim  // Inputs
231212795Sdim  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
232212795Sdim    Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
233212795Sdim    Writer.AddStmt(S->getInputConstraintLiteral(I));
234212795Sdim    Writer.AddStmt(S->getInputExpr(I));
235212795Sdim  }
236212795Sdim
237212795Sdim  // Clobbers
238212795Sdim  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
239212795Sdim    Writer.AddStmt(S->getClobber(I));
240212795Sdim
241212795Sdim  Code = serialization::STMT_ASM;
242212795Sdim}
243212795Sdim
244212795Sdimvoid ASTStmtWriter::VisitExpr(Expr *E) {
245212795Sdim  VisitStmt(E);
246212795Sdim  Writer.AddTypeRef(E->getType(), Record);
247212795Sdim  Record.push_back(E->isTypeDependent());
248212795Sdim  Record.push_back(E->isValueDependent());
249224145Sdim  Record.push_back(E->isInstantiationDependent());
250218893Sdim  Record.push_back(E->containsUnexpandedParameterPack());
251218893Sdim  Record.push_back(E->getValueKind());
252218893Sdim  Record.push_back(E->getObjectKind());
253212795Sdim}
254212795Sdim
255212795Sdimvoid ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
256212795Sdim  VisitExpr(E);
257212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
258212795Sdim  Record.push_back(E->getIdentType()); // FIXME: stable encoding
259212795Sdim  Code = serialization::EXPR_PREDEFINED;
260212795Sdim}
261212795Sdim
262212795Sdimvoid ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
263212795Sdim  VisitExpr(E);
264212795Sdim
265212795Sdim  Record.push_back(E->hasQualifier());
266221345Sdim  Record.push_back(E->getDecl() != E->getFoundDecl());
267218893Sdim  Record.push_back(E->hasExplicitTemplateArgs());
268212795Sdim
269218893Sdim  if (E->hasExplicitTemplateArgs()) {
270218893Sdim    unsigned NumTemplateArgs = E->getNumTemplateArgs();
271218893Sdim    Record.push_back(NumTemplateArgs);
272218893Sdim  }
273212795Sdim
274223017Sdim  DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
275223017Sdim
276223017Sdim  if ((!E->hasExplicitTemplateArgs()) && (!E->hasQualifier()) &&
277223017Sdim      (E->getDecl() == E->getFoundDecl()) &&
278223017Sdim      nk == DeclarationName::Identifier) {
279223017Sdim    AbbrevToUse = Writer.getDeclRefExprAbbrev();
280223017Sdim  }
281223017Sdim
282221345Sdim  if (E->hasQualifier())
283221345Sdim    Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
284221345Sdim
285221345Sdim  if (E->getDecl() != E->getFoundDecl())
286221345Sdim    Writer.AddDeclRef(E->getFoundDecl(), Record);
287221345Sdim
288221345Sdim  if (E->hasExplicitTemplateArgs())
289221345Sdim    AddExplicitTemplateArgumentList(E->getExplicitTemplateArgs());
290221345Sdim
291212795Sdim  Writer.AddDeclRef(E->getDecl(), Record);
292212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
293218893Sdim  Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
294212795Sdim  Code = serialization::EXPR_DECL_REF;
295212795Sdim}
296212795Sdim
297212795Sdimvoid ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
298212795Sdim  VisitExpr(E);
299212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
300212795Sdim  Writer.AddAPInt(E->getValue(), Record);
301223017Sdim
302223017Sdim  if (E->getValue().getBitWidth() == 32) {
303223017Sdim    AbbrevToUse = Writer.getIntegerLiteralAbbrev();
304223017Sdim  }
305223017Sdim
306212795Sdim  Code = serialization::EXPR_INTEGER_LITERAL;
307212795Sdim}
308212795Sdim
309212795Sdimvoid ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
310212795Sdim  VisitExpr(E);
311212795Sdim  Writer.AddAPFloat(E->getValue(), Record);
312212795Sdim  Record.push_back(E->isExact());
313212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
314212795Sdim  Code = serialization::EXPR_FLOATING_LITERAL;
315212795Sdim}
316212795Sdim
317212795Sdimvoid ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
318212795Sdim  VisitExpr(E);
319212795Sdim  Writer.AddStmt(E->getSubExpr());
320212795Sdim  Code = serialization::EXPR_IMAGINARY_LITERAL;
321212795Sdim}
322212795Sdim
323212795Sdimvoid ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
324212795Sdim  VisitExpr(E);
325212795Sdim  Record.push_back(E->getByteLength());
326212795Sdim  Record.push_back(E->getNumConcatenated());
327212795Sdim  Record.push_back(E->isWide());
328221345Sdim  Record.push_back(E->isPascal());
329212795Sdim  // FIXME: String data should be stored as a blob at the end of the
330212795Sdim  // StringLiteral. However, we can't do so now because we have no
331212795Sdim  // provision for coping with abbreviations when we're jumping around
332212795Sdim  // the AST file during deserialization.
333212795Sdim  Record.append(E->getString().begin(), E->getString().end());
334212795Sdim  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
335212795Sdim    Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
336212795Sdim  Code = serialization::EXPR_STRING_LITERAL;
337212795Sdim}
338212795Sdim
339212795Sdimvoid ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
340212795Sdim  VisitExpr(E);
341212795Sdim  Record.push_back(E->getValue());
342212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
343212795Sdim  Record.push_back(E->isWide());
344223017Sdim
345223017Sdim  AbbrevToUse = Writer.getCharacterLiteralAbbrev();
346223017Sdim
347212795Sdim  Code = serialization::EXPR_CHARACTER_LITERAL;
348212795Sdim}
349212795Sdim
350212795Sdimvoid ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
351212795Sdim  VisitExpr(E);
352212795Sdim  Writer.AddSourceLocation(E->getLParen(), Record);
353212795Sdim  Writer.AddSourceLocation(E->getRParen(), Record);
354212795Sdim  Writer.AddStmt(E->getSubExpr());
355212795Sdim  Code = serialization::EXPR_PAREN;
356212795Sdim}
357212795Sdim
358212795Sdimvoid ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
359212795Sdim  VisitExpr(E);
360212795Sdim  Record.push_back(E->NumExprs);
361212795Sdim  for (unsigned i=0; i != E->NumExprs; ++i)
362212795Sdim    Writer.AddStmt(E->Exprs[i]);
363212795Sdim  Writer.AddSourceLocation(E->LParenLoc, Record);
364212795Sdim  Writer.AddSourceLocation(E->RParenLoc, Record);
365212795Sdim  Code = serialization::EXPR_PAREN_LIST;
366212795Sdim}
367212795Sdim
368212795Sdimvoid ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
369212795Sdim  VisitExpr(E);
370212795Sdim  Writer.AddStmt(E->getSubExpr());
371212795Sdim  Record.push_back(E->getOpcode()); // FIXME: stable encoding
372212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
373212795Sdim  Code = serialization::EXPR_UNARY_OPERATOR;
374212795Sdim}
375212795Sdim
376212795Sdimvoid ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
377212795Sdim  VisitExpr(E);
378212795Sdim  Record.push_back(E->getNumComponents());
379212795Sdim  Record.push_back(E->getNumExpressions());
380212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
381212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
382212795Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
383212795Sdim  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
384212795Sdim    const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
385212795Sdim    Record.push_back(ON.getKind()); // FIXME: Stable encoding
386221345Sdim    Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
387221345Sdim    Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
388212795Sdim    switch (ON.getKind()) {
389212795Sdim    case OffsetOfExpr::OffsetOfNode::Array:
390212795Sdim      Record.push_back(ON.getArrayExprIndex());
391212795Sdim      break;
392212795Sdim
393212795Sdim    case OffsetOfExpr::OffsetOfNode::Field:
394212795Sdim      Writer.AddDeclRef(ON.getField(), Record);
395212795Sdim      break;
396212795Sdim
397212795Sdim    case OffsetOfExpr::OffsetOfNode::Identifier:
398212795Sdim      Writer.AddIdentifierRef(ON.getFieldName(), Record);
399212795Sdim      break;
400212795Sdim
401212795Sdim    case OffsetOfExpr::OffsetOfNode::Base:
402212795Sdim      Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
403212795Sdim      break;
404212795Sdim    }
405212795Sdim  }
406212795Sdim  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
407212795Sdim    Writer.AddStmt(E->getIndexExpr(I));
408212795Sdim  Code = serialization::EXPR_OFFSETOF;
409212795Sdim}
410212795Sdim
411221345Sdimvoid ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
412212795Sdim  VisitExpr(E);
413221345Sdim  Record.push_back(E->getKind());
414212795Sdim  if (E->isArgumentType())
415212795Sdim    Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
416212795Sdim  else {
417212795Sdim    Record.push_back(0);
418212795Sdim    Writer.AddStmt(E->getArgumentExpr());
419212795Sdim  }
420212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
421212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
422212795Sdim  Code = serialization::EXPR_SIZEOF_ALIGN_OF;
423212795Sdim}
424212795Sdim
425212795Sdimvoid ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
426212795Sdim  VisitExpr(E);
427212795Sdim  Writer.AddStmt(E->getLHS());
428212795Sdim  Writer.AddStmt(E->getRHS());
429212795Sdim  Writer.AddSourceLocation(E->getRBracketLoc(), Record);
430212795Sdim  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
431212795Sdim}
432212795Sdim
433212795Sdimvoid ASTStmtWriter::VisitCallExpr(CallExpr *E) {
434212795Sdim  VisitExpr(E);
435212795Sdim  Record.push_back(E->getNumArgs());
436212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
437212795Sdim  Writer.AddStmt(E->getCallee());
438212795Sdim  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
439212795Sdim       Arg != ArgEnd; ++Arg)
440212795Sdim    Writer.AddStmt(*Arg);
441212795Sdim  Code = serialization::EXPR_CALL;
442212795Sdim}
443212795Sdim
444212795Sdimvoid ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
445212795Sdim  // Don't call VisitExpr, we'll write everything here.
446212795Sdim
447212795Sdim  Record.push_back(E->hasQualifier());
448221345Sdim  if (E->hasQualifier())
449221345Sdim    Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
450212795Sdim
451218893Sdim  Record.push_back(E->hasExplicitTemplateArgs());
452218893Sdim  if (E->hasExplicitTemplateArgs()) {
453218893Sdim    unsigned NumTemplateArgs = E->getNumTemplateArgs();
454218893Sdim    Record.push_back(NumTemplateArgs);
455212795Sdim    Writer.AddSourceLocation(E->getLAngleLoc(), Record);
456212795Sdim    Writer.AddSourceLocation(E->getRAngleLoc(), Record);
457212795Sdim    for (unsigned i=0; i != NumTemplateArgs; ++i)
458212795Sdim      Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
459212795Sdim  }
460212795Sdim
461212795Sdim  DeclAccessPair FoundDecl = E->getFoundDecl();
462212795Sdim  Writer.AddDeclRef(FoundDecl.getDecl(), Record);
463212795Sdim  Record.push_back(FoundDecl.getAccess());
464212795Sdim
465212795Sdim  Writer.AddTypeRef(E->getType(), Record);
466218893Sdim  Record.push_back(E->getValueKind());
467218893Sdim  Record.push_back(E->getObjectKind());
468212795Sdim  Writer.AddStmt(E->getBase());
469212795Sdim  Writer.AddDeclRef(E->getMemberDecl(), Record);
470212795Sdim  Writer.AddSourceLocation(E->getMemberLoc(), Record);
471212795Sdim  Record.push_back(E->isArrow());
472218893Sdim  Writer.AddDeclarationNameLoc(E->MemberDNLoc,
473218893Sdim                               E->getMemberDecl()->getDeclName(), Record);
474212795Sdim  Code = serialization::EXPR_MEMBER;
475212795Sdim}
476212795Sdim
477212795Sdimvoid ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
478212795Sdim  VisitExpr(E);
479212795Sdim  Writer.AddStmt(E->getBase());
480212795Sdim  Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
481212795Sdim  Record.push_back(E->isArrow());
482212795Sdim  Code = serialization::EXPR_OBJC_ISA;
483212795Sdim}
484212795Sdim
485224145Sdimvoid ASTStmtWriter::
486224145SdimVisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
487224145Sdim  VisitExpr(E);
488224145Sdim  Writer.AddStmt(E->getSubExpr());
489224145Sdim  Record.push_back(E->shouldCopy());
490224145Sdim  Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
491224145Sdim}
492224145Sdim
493224145Sdimvoid ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
494224145Sdim  VisitExplicitCastExpr(E);
495224145Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
496224145Sdim  Writer.AddSourceLocation(E->getBridgeKeywordLoc(), Record);
497224145Sdim  Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
498224145Sdim  Code = serialization::EXPR_OBJC_BRIDGED_CAST;
499224145Sdim}
500224145Sdim
501212795Sdimvoid ASTStmtWriter::VisitCastExpr(CastExpr *E) {
502212795Sdim  VisitExpr(E);
503212795Sdim  Record.push_back(E->path_size());
504212795Sdim  Writer.AddStmt(E->getSubExpr());
505212795Sdim  Record.push_back(E->getCastKind()); // FIXME: stable encoding
506212795Sdim
507212795Sdim  for (CastExpr::path_iterator
508212795Sdim         PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
509212795Sdim    Writer.AddCXXBaseSpecifier(**PI, Record);
510212795Sdim}
511212795Sdim
512212795Sdimvoid ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
513212795Sdim  VisitExpr(E);
514212795Sdim  Writer.AddStmt(E->getLHS());
515212795Sdim  Writer.AddStmt(E->getRHS());
516212795Sdim  Record.push_back(E->getOpcode()); // FIXME: stable encoding
517212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
518212795Sdim  Code = serialization::EXPR_BINARY_OPERATOR;
519212795Sdim}
520212795Sdim
521212795Sdimvoid ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
522212795Sdim  VisitBinaryOperator(E);
523212795Sdim  Writer.AddTypeRef(E->getComputationLHSType(), Record);
524212795Sdim  Writer.AddTypeRef(E->getComputationResultType(), Record);
525212795Sdim  Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
526212795Sdim}
527212795Sdim
528212795Sdimvoid ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
529212795Sdim  VisitExpr(E);
530212795Sdim  Writer.AddStmt(E->getCond());
531212795Sdim  Writer.AddStmt(E->getLHS());
532212795Sdim  Writer.AddStmt(E->getRHS());
533212795Sdim  Writer.AddSourceLocation(E->getQuestionLoc(), Record);
534212795Sdim  Writer.AddSourceLocation(E->getColonLoc(), Record);
535212795Sdim  Code = serialization::EXPR_CONDITIONAL_OPERATOR;
536212795Sdim}
537212795Sdim
538218893Sdimvoid
539218893SdimASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
540218893Sdim  VisitExpr(E);
541218893Sdim  Writer.AddStmt(E->getOpaqueValue());
542218893Sdim  Writer.AddStmt(E->getCommon());
543218893Sdim  Writer.AddStmt(E->getCond());
544218893Sdim  Writer.AddStmt(E->getTrueExpr());
545218893Sdim  Writer.AddStmt(E->getFalseExpr());
546218893Sdim  Writer.AddSourceLocation(E->getQuestionLoc(), Record);
547218893Sdim  Writer.AddSourceLocation(E->getColonLoc(), Record);
548218893Sdim  Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
549218893Sdim}
550218893Sdim
551212795Sdimvoid ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
552212795Sdim  VisitCastExpr(E);
553212795Sdim  Code = serialization::EXPR_IMPLICIT_CAST;
554212795Sdim}
555212795Sdim
556212795Sdimvoid ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
557212795Sdim  VisitCastExpr(E);
558212795Sdim  Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
559212795Sdim}
560212795Sdim
561212795Sdimvoid ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
562212795Sdim  VisitExplicitCastExpr(E);
563212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
564212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
565212795Sdim  Code = serialization::EXPR_CSTYLE_CAST;
566212795Sdim}
567212795Sdim
568212795Sdimvoid ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
569212795Sdim  VisitExpr(E);
570212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
571212795Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
572212795Sdim  Writer.AddStmt(E->getInitializer());
573212795Sdim  Record.push_back(E->isFileScope());
574212795Sdim  Code = serialization::EXPR_COMPOUND_LITERAL;
575212795Sdim}
576212795Sdim
577212795Sdimvoid ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
578212795Sdim  VisitExpr(E);
579212795Sdim  Writer.AddStmt(E->getBase());
580212795Sdim  Writer.AddIdentifierRef(&E->getAccessor(), Record);
581212795Sdim  Writer.AddSourceLocation(E->getAccessorLoc(), Record);
582212795Sdim  Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
583212795Sdim}
584212795Sdim
585212795Sdimvoid ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
586212795Sdim  VisitExpr(E);
587212795Sdim  Writer.AddStmt(E->getSyntacticForm());
588212795Sdim  Writer.AddSourceLocation(E->getLBraceLoc(), Record);
589212795Sdim  Writer.AddSourceLocation(E->getRBraceLoc(), Record);
590221345Sdim  bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
591221345Sdim  Record.push_back(isArrayFiller);
592221345Sdim  if (isArrayFiller)
593221345Sdim    Writer.AddStmt(E->getArrayFiller());
594221345Sdim  else
595221345Sdim    Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
596212795Sdim  Record.push_back(E->hadArrayRangeDesignator());
597221345Sdim  Record.push_back(E->getNumInits());
598221345Sdim  if (isArrayFiller) {
599221345Sdim    // ArrayFiller may have filled "holes" due to designated initializer.
600221345Sdim    // Replace them by 0 to indicate that the filler goes in that place.
601221345Sdim    Expr *filler = E->getArrayFiller();
602221345Sdim    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
603221345Sdim      Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0);
604221345Sdim  } else {
605221345Sdim    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
606221345Sdim      Writer.AddStmt(E->getInit(I));
607221345Sdim  }
608212795Sdim  Code = serialization::EXPR_INIT_LIST;
609212795Sdim}
610212795Sdim
611212795Sdimvoid ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
612212795Sdim  VisitExpr(E);
613212795Sdim  Record.push_back(E->getNumSubExprs());
614212795Sdim  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
615212795Sdim    Writer.AddStmt(E->getSubExpr(I));
616212795Sdim  Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
617212795Sdim  Record.push_back(E->usesGNUSyntax());
618212795Sdim  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
619212795Sdim                                             DEnd = E->designators_end();
620212795Sdim       D != DEnd; ++D) {
621212795Sdim    if (D->isFieldDesignator()) {
622212795Sdim      if (FieldDecl *Field = D->getField()) {
623212795Sdim        Record.push_back(serialization::DESIG_FIELD_DECL);
624212795Sdim        Writer.AddDeclRef(Field, Record);
625212795Sdim      } else {
626212795Sdim        Record.push_back(serialization::DESIG_FIELD_NAME);
627212795Sdim        Writer.AddIdentifierRef(D->getFieldName(), Record);
628212795Sdim      }
629212795Sdim      Writer.AddSourceLocation(D->getDotLoc(), Record);
630212795Sdim      Writer.AddSourceLocation(D->getFieldLoc(), Record);
631212795Sdim    } else if (D->isArrayDesignator()) {
632212795Sdim      Record.push_back(serialization::DESIG_ARRAY);
633212795Sdim      Record.push_back(D->getFirstExprIndex());
634212795Sdim      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
635212795Sdim      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
636212795Sdim    } else {
637212795Sdim      assert(D->isArrayRangeDesignator() && "Unknown designator");
638212795Sdim      Record.push_back(serialization::DESIG_ARRAY_RANGE);
639212795Sdim      Record.push_back(D->getFirstExprIndex());
640212795Sdim      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
641212795Sdim      Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
642212795Sdim      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
643212795Sdim    }
644212795Sdim  }
645212795Sdim  Code = serialization::EXPR_DESIGNATED_INIT;
646212795Sdim}
647212795Sdim
648212795Sdimvoid ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
649212795Sdim  VisitExpr(E);
650212795Sdim  Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
651212795Sdim}
652212795Sdim
653212795Sdimvoid ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
654212795Sdim  VisitExpr(E);
655212795Sdim  Writer.AddStmt(E->getSubExpr());
656212795Sdim  Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
657212795Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
658212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
659212795Sdim  Code = serialization::EXPR_VA_ARG;
660212795Sdim}
661212795Sdim
662212795Sdimvoid ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
663212795Sdim  VisitExpr(E);
664212795Sdim  Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
665212795Sdim  Writer.AddSourceLocation(E->getLabelLoc(), Record);
666218893Sdim  Writer.AddDeclRef(E->getLabel(), Record);
667212795Sdim  Code = serialization::EXPR_ADDR_LABEL;
668212795Sdim}
669212795Sdim
670212795Sdimvoid ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
671212795Sdim  VisitExpr(E);
672212795Sdim  Writer.AddStmt(E->getSubStmt());
673212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
674212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
675212795Sdim  Code = serialization::EXPR_STMT;
676212795Sdim}
677212795Sdim
678212795Sdimvoid ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
679212795Sdim  VisitExpr(E);
680212795Sdim  Writer.AddStmt(E->getCond());
681212795Sdim  Writer.AddStmt(E->getLHS());
682212795Sdim  Writer.AddStmt(E->getRHS());
683212795Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
684212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
685212795Sdim  Code = serialization::EXPR_CHOOSE;
686212795Sdim}
687212795Sdim
688212795Sdimvoid ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
689212795Sdim  VisitExpr(E);
690212795Sdim  Writer.AddSourceLocation(E->getTokenLocation(), Record);
691212795Sdim  Code = serialization::EXPR_GNU_NULL;
692212795Sdim}
693212795Sdim
694212795Sdimvoid ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
695212795Sdim  VisitExpr(E);
696212795Sdim  Record.push_back(E->getNumSubExprs());
697212795Sdim  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
698212795Sdim    Writer.AddStmt(E->getExpr(I));
699212795Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
700212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
701212795Sdim  Code = serialization::EXPR_SHUFFLE_VECTOR;
702212795Sdim}
703212795Sdim
704212795Sdimvoid ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
705212795Sdim  VisitExpr(E);
706212795Sdim  Writer.AddDeclRef(E->getBlockDecl(), Record);
707212795Sdim  Code = serialization::EXPR_BLOCK;
708212795Sdim}
709212795Sdim
710212795Sdimvoid ASTStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
711212795Sdim  VisitExpr(E);
712212795Sdim  Writer.AddDeclRef(E->getDecl(), Record);
713212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
714212795Sdim  Record.push_back(E->isByRef());
715212795Sdim  Record.push_back(E->isConstQualAdded());
716212795Sdim  Code = serialization::EXPR_BLOCK_DECL_REF;
717212795Sdim}
718212795Sdim
719221345Sdimvoid ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
720221345Sdim  VisitExpr(E);
721221345Sdim  Record.push_back(E->getNumAssocs());
722221345Sdim
723221345Sdim  Writer.AddStmt(E->getControllingExpr());
724221345Sdim  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
725221345Sdim    Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record);
726221345Sdim    Writer.AddStmt(E->getAssocExpr(I));
727221345Sdim  }
728221345Sdim  Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
729221345Sdim
730221345Sdim  Writer.AddSourceLocation(E->getGenericLoc(), Record);
731221345Sdim  Writer.AddSourceLocation(E->getDefaultLoc(), Record);
732221345Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
733221345Sdim  Code = serialization::EXPR_GENERIC_SELECTION;
734221345Sdim}
735221345Sdim
736212795Sdim//===----------------------------------------------------------------------===//
737212795Sdim// Objective-C Expressions and Statements.
738212795Sdim//===----------------------------------------------------------------------===//
739212795Sdim
740212795Sdimvoid ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
741212795Sdim  VisitExpr(E);
742212795Sdim  Writer.AddStmt(E->getString());
743212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
744212795Sdim  Code = serialization::EXPR_OBJC_STRING_LITERAL;
745212795Sdim}
746212795Sdim
747212795Sdimvoid ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
748212795Sdim  VisitExpr(E);
749212795Sdim  Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
750212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
751212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
752212795Sdim  Code = serialization::EXPR_OBJC_ENCODE;
753212795Sdim}
754212795Sdim
755212795Sdimvoid ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
756212795Sdim  VisitExpr(E);
757212795Sdim  Writer.AddSelectorRef(E->getSelector(), Record);
758212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
759212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
760212795Sdim  Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
761212795Sdim}
762212795Sdim
763212795Sdimvoid ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
764212795Sdim  VisitExpr(E);
765212795Sdim  Writer.AddDeclRef(E->getProtocol(), Record);
766212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
767212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
768212795Sdim  Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
769212795Sdim}
770212795Sdim
771212795Sdimvoid ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
772212795Sdim  VisitExpr(E);
773212795Sdim  Writer.AddDeclRef(E->getDecl(), Record);
774212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
775212795Sdim  Writer.AddStmt(E->getBase());
776212795Sdim  Record.push_back(E->isArrow());
777212795Sdim  Record.push_back(E->isFreeIvar());
778212795Sdim  Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
779212795Sdim}
780212795Sdim
781212795Sdimvoid ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
782212795Sdim  VisitExpr(E);
783218893Sdim  Record.push_back(E->isImplicitProperty());
784218893Sdim  if (E->isImplicitProperty()) {
785218893Sdim    Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
786218893Sdim    Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
787218893Sdim  } else {
788218893Sdim    Writer.AddDeclRef(E->getExplicitProperty(), Record);
789218893Sdim  }
790212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
791218893Sdim  Writer.AddSourceLocation(E->getReceiverLocation(), Record);
792218893Sdim  if (E->isObjectReceiver()) {
793218893Sdim    Record.push_back(0);
794218893Sdim    Writer.AddStmt(E->getBase());
795218893Sdim  } else if (E->isSuperReceiver()) {
796218893Sdim    Record.push_back(1);
797218893Sdim    Writer.AddTypeRef(E->getSuperReceiverType(), Record);
798218893Sdim  } else {
799218893Sdim    Record.push_back(2);
800218893Sdim    Writer.AddDeclRef(E->getClassReceiver(), Record);
801218893Sdim  }
802218893Sdim
803212795Sdim  Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
804212795Sdim}
805212795Sdim
806212795Sdimvoid ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
807212795Sdim  VisitExpr(E);
808212795Sdim  Record.push_back(E->getNumArgs());
809224145Sdim  Record.push_back(E->isDelegateInitCall());
810212795Sdim  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
811212795Sdim  switch (E->getReceiverKind()) {
812212795Sdim  case ObjCMessageExpr::Instance:
813212795Sdim    Writer.AddStmt(E->getInstanceReceiver());
814212795Sdim    break;
815212795Sdim
816212795Sdim  case ObjCMessageExpr::Class:
817212795Sdim    Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
818212795Sdim    break;
819212795Sdim
820212795Sdim  case ObjCMessageExpr::SuperClass:
821212795Sdim  case ObjCMessageExpr::SuperInstance:
822212795Sdim    Writer.AddTypeRef(E->getSuperType(), Record);
823212795Sdim    Writer.AddSourceLocation(E->getSuperLoc(), Record);
824212795Sdim    break;
825212795Sdim  }
826212795Sdim
827212795Sdim  if (E->getMethodDecl()) {
828212795Sdim    Record.push_back(1);
829212795Sdim    Writer.AddDeclRef(E->getMethodDecl(), Record);
830212795Sdim  } else {
831212795Sdim    Record.push_back(0);
832212795Sdim    Writer.AddSelectorRef(E->getSelector(), Record);
833212795Sdim  }
834212795Sdim
835212795Sdim  Writer.AddSourceLocation(E->getLeftLoc(), Record);
836212795Sdim  Writer.AddSourceLocation(E->getRightLoc(), Record);
837218893Sdim  Writer.AddSourceLocation(E->getSelectorLoc(), Record);
838212795Sdim
839212795Sdim  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
840212795Sdim       Arg != ArgEnd; ++Arg)
841212795Sdim    Writer.AddStmt(*Arg);
842212795Sdim  Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
843212795Sdim}
844212795Sdim
845212795Sdimvoid ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
846212795Sdim  VisitStmt(S);
847212795Sdim  Writer.AddStmt(S->getElement());
848212795Sdim  Writer.AddStmt(S->getCollection());
849212795Sdim  Writer.AddStmt(S->getBody());
850212795Sdim  Writer.AddSourceLocation(S->getForLoc(), Record);
851212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
852212795Sdim  Code = serialization::STMT_OBJC_FOR_COLLECTION;
853212795Sdim}
854212795Sdim
855212795Sdimvoid ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
856212795Sdim  Writer.AddStmt(S->getCatchBody());
857212795Sdim  Writer.AddDeclRef(S->getCatchParamDecl(), Record);
858212795Sdim  Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
859212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
860212795Sdim  Code = serialization::STMT_OBJC_CATCH;
861212795Sdim}
862212795Sdim
863212795Sdimvoid ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
864212795Sdim  Writer.AddStmt(S->getFinallyBody());
865212795Sdim  Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
866212795Sdim  Code = serialization::STMT_OBJC_FINALLY;
867212795Sdim}
868212795Sdim
869224145Sdimvoid ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
870224145Sdim  Writer.AddStmt(S->getSubStmt());
871224145Sdim  Writer.AddSourceLocation(S->getAtLoc(), Record);
872224145Sdim  Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
873224145Sdim}
874224145Sdim
875212795Sdimvoid ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
876212795Sdim  Record.push_back(S->getNumCatchStmts());
877212795Sdim  Record.push_back(S->getFinallyStmt() != 0);
878212795Sdim  Writer.AddStmt(S->getTryBody());
879212795Sdim  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
880212795Sdim    Writer.AddStmt(S->getCatchStmt(I));
881212795Sdim  if (S->getFinallyStmt())
882212795Sdim    Writer.AddStmt(S->getFinallyStmt());
883212795Sdim  Writer.AddSourceLocation(S->getAtTryLoc(), Record);
884212795Sdim  Code = serialization::STMT_OBJC_AT_TRY;
885212795Sdim}
886212795Sdim
887212795Sdimvoid ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
888212795Sdim  Writer.AddStmt(S->getSynchExpr());
889212795Sdim  Writer.AddStmt(S->getSynchBody());
890212795Sdim  Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
891212795Sdim  Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
892212795Sdim}
893212795Sdim
894212795Sdimvoid ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
895212795Sdim  Writer.AddStmt(S->getThrowExpr());
896212795Sdim  Writer.AddSourceLocation(S->getThrowLoc(), Record);
897212795Sdim  Code = serialization::STMT_OBJC_AT_THROW;
898212795Sdim}
899212795Sdim
900212795Sdim//===----------------------------------------------------------------------===//
901212795Sdim// C++ Expressions and Statements.
902212795Sdim//===----------------------------------------------------------------------===//
903212795Sdim
904212795Sdimvoid ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
905212795Sdim  VisitStmt(S);
906212795Sdim  Writer.AddSourceLocation(S->getCatchLoc(), Record);
907212795Sdim  Writer.AddDeclRef(S->getExceptionDecl(), Record);
908212795Sdim  Writer.AddStmt(S->getHandlerBlock());
909212795Sdim  Code = serialization::STMT_CXX_CATCH;
910212795Sdim}
911212795Sdim
912212795Sdimvoid ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
913212795Sdim  VisitStmt(S);
914212795Sdim  Record.push_back(S->getNumHandlers());
915212795Sdim  Writer.AddSourceLocation(S->getTryLoc(), Record);
916212795Sdim  Writer.AddStmt(S->getTryBlock());
917212795Sdim  for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
918212795Sdim    Writer.AddStmt(S->getHandler(i));
919212795Sdim  Code = serialization::STMT_CXX_TRY;
920212795Sdim}
921212795Sdim
922221345Sdimvoid ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
923221345Sdim  VisitStmt(S);
924221345Sdim  Writer.AddSourceLocation(S->getForLoc(), Record);
925221345Sdim  Writer.AddSourceLocation(S->getColonLoc(), Record);
926221345Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
927221345Sdim  Writer.AddStmt(S->getRangeStmt());
928221345Sdim  Writer.AddStmt(S->getBeginEndStmt());
929221345Sdim  Writer.AddStmt(S->getCond());
930221345Sdim  Writer.AddStmt(S->getInc());
931221345Sdim  Writer.AddStmt(S->getLoopVarStmt());
932221345Sdim  Writer.AddStmt(S->getBody());
933221345Sdim  Code = serialization::STMT_CXX_FOR_RANGE;
934221345Sdim}
935221345Sdim
936212795Sdimvoid ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
937212795Sdim  VisitCallExpr(E);
938212795Sdim  Record.push_back(E->getOperator());
939212795Sdim  Code = serialization::EXPR_CXX_OPERATOR_CALL;
940212795Sdim}
941212795Sdim
942212795Sdimvoid ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
943212795Sdim  VisitCallExpr(E);
944212795Sdim  Code = serialization::EXPR_CXX_MEMBER_CALL;
945212795Sdim}
946212795Sdim
947212795Sdimvoid ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
948212795Sdim  VisitExpr(E);
949212795Sdim  Record.push_back(E->getNumArgs());
950212795Sdim  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
951212795Sdim    Writer.AddStmt(E->getArg(I));
952212795Sdim  Writer.AddDeclRef(E->getConstructor(), Record);
953212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
954212795Sdim  Record.push_back(E->isElidable());
955212795Sdim  Record.push_back(E->requiresZeroInitialization());
956212795Sdim  Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
957218893Sdim  Writer.AddSourceRange(E->getParenRange(), Record);
958212795Sdim  Code = serialization::EXPR_CXX_CONSTRUCT;
959212795Sdim}
960212795Sdim
961212795Sdimvoid ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
962212795Sdim  VisitCXXConstructExpr(E);
963218893Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
964212795Sdim  Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
965212795Sdim}
966212795Sdim
967212795Sdimvoid ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
968212795Sdim  VisitExplicitCastExpr(E);
969218893Sdim  Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
970218893Sdim                        Record);
971212795Sdim}
972212795Sdim
973212795Sdimvoid ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
974212795Sdim  VisitCXXNamedCastExpr(E);
975212795Sdim  Code = serialization::EXPR_CXX_STATIC_CAST;
976212795Sdim}
977212795Sdim
978212795Sdimvoid ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
979212795Sdim  VisitCXXNamedCastExpr(E);
980212795Sdim  Code = serialization::EXPR_CXX_DYNAMIC_CAST;
981212795Sdim}
982212795Sdim
983212795Sdimvoid ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
984212795Sdim  VisitCXXNamedCastExpr(E);
985212795Sdim  Code = serialization::EXPR_CXX_REINTERPRET_CAST;
986212795Sdim}
987212795Sdim
988212795Sdimvoid ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
989212795Sdim  VisitCXXNamedCastExpr(E);
990212795Sdim  Code = serialization::EXPR_CXX_CONST_CAST;
991212795Sdim}
992212795Sdim
993212795Sdimvoid ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
994212795Sdim  VisitExplicitCastExpr(E);
995212795Sdim  Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
996212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
997212795Sdim  Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
998212795Sdim}
999212795Sdim
1000212795Sdimvoid ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
1001212795Sdim  VisitExpr(E);
1002212795Sdim  Record.push_back(E->getValue());
1003212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1004212795Sdim  Code = serialization::EXPR_CXX_BOOL_LITERAL;
1005212795Sdim}
1006212795Sdim
1007212795Sdimvoid ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
1008212795Sdim  VisitExpr(E);
1009212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1010212795Sdim  Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
1011212795Sdim}
1012212795Sdim
1013212795Sdimvoid ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1014212795Sdim  VisitExpr(E);
1015212795Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1016212795Sdim  if (E->isTypeOperand()) {
1017212795Sdim    Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
1018212795Sdim    Code = serialization::EXPR_CXX_TYPEID_TYPE;
1019212795Sdim  } else {
1020212795Sdim    Writer.AddStmt(E->getExprOperand());
1021212795Sdim    Code = serialization::EXPR_CXX_TYPEID_EXPR;
1022212795Sdim  }
1023212795Sdim}
1024212795Sdim
1025212795Sdimvoid ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
1026212795Sdim  VisitExpr(E);
1027212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1028212795Sdim  Record.push_back(E->isImplicit());
1029212795Sdim  Code = serialization::EXPR_CXX_THIS;
1030212795Sdim}
1031212795Sdim
1032212795Sdimvoid ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
1033212795Sdim  VisitExpr(E);
1034212795Sdim  Writer.AddSourceLocation(E->getThrowLoc(), Record);
1035212795Sdim  Writer.AddStmt(E->getSubExpr());
1036224145Sdim  Record.push_back(E->isThrownVariableInScope());
1037212795Sdim  Code = serialization::EXPR_CXX_THROW;
1038212795Sdim}
1039212795Sdim
1040212795Sdimvoid ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
1041212795Sdim  VisitExpr(E);
1042212795Sdim
1043212795Sdim  bool HasOtherExprStored = E->Param.getInt();
1044212795Sdim  // Store these first, the reader reads them before creation.
1045212795Sdim  Record.push_back(HasOtherExprStored);
1046212795Sdim  if (HasOtherExprStored)
1047212795Sdim    Writer.AddStmt(E->getExpr());
1048212795Sdim  Writer.AddDeclRef(E->getParam(), Record);
1049212795Sdim  Writer.AddSourceLocation(E->getUsedLocation(), Record);
1050212795Sdim
1051212795Sdim  Code = serialization::EXPR_CXX_DEFAULT_ARG;
1052212795Sdim}
1053212795Sdim
1054212795Sdimvoid ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
1055212795Sdim  VisitExpr(E);
1056212795Sdim  Writer.AddCXXTemporary(E->getTemporary(), Record);
1057212795Sdim  Writer.AddStmt(E->getSubExpr());
1058212795Sdim  Code = serialization::EXPR_CXX_BIND_TEMPORARY;
1059212795Sdim}
1060212795Sdim
1061212795Sdimvoid ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1062212795Sdim  VisitExpr(E);
1063218893Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
1064212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1065212795Sdim  Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
1066212795Sdim}
1067212795Sdim
1068212795Sdimvoid ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
1069212795Sdim  VisitExpr(E);
1070212795Sdim  Record.push_back(E->isGlobalNew());
1071212795Sdim  Record.push_back(E->hasInitializer());
1072218893Sdim  Record.push_back(E->doesUsualArrayDeleteWantSize());
1073212795Sdim  Record.push_back(E->isArray());
1074212795Sdim  Record.push_back(E->getNumPlacementArgs());
1075212795Sdim  Record.push_back(E->getNumConstructorArgs());
1076212795Sdim  Writer.AddDeclRef(E->getOperatorNew(), Record);
1077212795Sdim  Writer.AddDeclRef(E->getOperatorDelete(), Record);
1078212795Sdim  Writer.AddDeclRef(E->getConstructor(), Record);
1079218893Sdim  Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
1080212795Sdim  Writer.AddSourceRange(E->getTypeIdParens(), Record);
1081212795Sdim  Writer.AddSourceLocation(E->getStartLoc(), Record);
1082212795Sdim  Writer.AddSourceLocation(E->getEndLoc(), Record);
1083218893Sdim  Writer.AddSourceLocation(E->getConstructorLParen(), Record);
1084218893Sdim  Writer.AddSourceLocation(E->getConstructorRParen(), Record);
1085212795Sdim  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
1086212795Sdim       I != e; ++I)
1087212795Sdim    Writer.AddStmt(*I);
1088212795Sdim
1089212795Sdim  Code = serialization::EXPR_CXX_NEW;
1090212795Sdim}
1091212795Sdim
1092212795Sdimvoid ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1093212795Sdim  VisitExpr(E);
1094212795Sdim  Record.push_back(E->isGlobalDelete());
1095212795Sdim  Record.push_back(E->isArrayForm());
1096218893Sdim  Record.push_back(E->isArrayFormAsWritten());
1097218893Sdim  Record.push_back(E->doesUsualArrayDeleteWantSize());
1098212795Sdim  Writer.AddDeclRef(E->getOperatorDelete(), Record);
1099212795Sdim  Writer.AddStmt(E->getArgument());
1100212795Sdim  Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
1101212795Sdim
1102212795Sdim  Code = serialization::EXPR_CXX_DELETE;
1103212795Sdim}
1104212795Sdim
1105212795Sdimvoid ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1106212795Sdim  VisitExpr(E);
1107212795Sdim
1108212795Sdim  Writer.AddStmt(E->getBase());
1109212795Sdim  Record.push_back(E->isArrow());
1110212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1111219077Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1112212795Sdim  Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
1113212795Sdim  Writer.AddSourceLocation(E->getColonColonLoc(), Record);
1114212795Sdim  Writer.AddSourceLocation(E->getTildeLoc(), Record);
1115212795Sdim
1116212795Sdim  // PseudoDestructorTypeStorage.
1117212795Sdim  Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
1118212795Sdim  if (E->getDestroyedTypeIdentifier())
1119212795Sdim    Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
1120212795Sdim  else
1121212795Sdim    Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
1122212795Sdim
1123212795Sdim  Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
1124212795Sdim}
1125212795Sdim
1126218893Sdimvoid ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
1127212795Sdim  VisitExpr(E);
1128212795Sdim  Record.push_back(E->getNumTemporaries());
1129212795Sdim  for (unsigned i = 0, e = E->getNumTemporaries(); i != e; ++i)
1130212795Sdim    Writer.AddCXXTemporary(E->getTemporary(i), Record);
1131212795Sdim
1132212795Sdim  Writer.AddStmt(E->getSubExpr());
1133218893Sdim  Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
1134212795Sdim}
1135212795Sdim
1136212795Sdimvoid
1137212795SdimASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
1138212795Sdim  VisitExpr(E);
1139212795Sdim
1140218893Sdim  // Don't emit anything here, hasExplicitTemplateArgs() must be
1141218893Sdim  // emitted first.
1142212795Sdim
1143218893Sdim  Record.push_back(E->hasExplicitTemplateArgs());
1144212795Sdim  if (E->hasExplicitTemplateArgs()) {
1145212795Sdim    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1146212795Sdim    Record.push_back(Args.NumTemplateArgs);
1147212795Sdim    AddExplicitTemplateArgumentList(Args);
1148212795Sdim  }
1149212795Sdim
1150212795Sdim  if (!E->isImplicitAccess())
1151212795Sdim    Writer.AddStmt(E->getBase());
1152212795Sdim  else
1153212795Sdim    Writer.AddStmt(0);
1154212795Sdim  Writer.AddTypeRef(E->getBaseType(), Record);
1155212795Sdim  Record.push_back(E->isArrow());
1156212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1157221345Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1158212795Sdim  Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
1159218893Sdim  Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
1160212795Sdim  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
1161212795Sdim}
1162212795Sdim
1163212795Sdimvoid
1164212795SdimASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1165212795Sdim  VisitExpr(E);
1166212795Sdim
1167218893Sdim  // Don't emit anything here, hasExplicitTemplateArgs() must be
1168218893Sdim  // emitted first.
1169218893Sdim  Record.push_back(E->hasExplicitTemplateArgs());
1170212795Sdim  if (E->hasExplicitTemplateArgs()) {
1171212795Sdim    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1172212795Sdim    Record.push_back(Args.NumTemplateArgs);
1173212795Sdim    AddExplicitTemplateArgumentList(Args);
1174212795Sdim  }
1175212795Sdim
1176219077Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1177218893Sdim  Writer.AddDeclarationNameInfo(E->NameInfo, Record);
1178212795Sdim  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
1179212795Sdim}
1180212795Sdim
1181212795Sdimvoid
1182212795SdimASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
1183212795Sdim  VisitExpr(E);
1184212795Sdim  Record.push_back(E->arg_size());
1185212795Sdim  for (CXXUnresolvedConstructExpr::arg_iterator
1186212795Sdim         ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
1187212795Sdim    Writer.AddStmt(*ArgI);
1188218893Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
1189212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
1190212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1191212795Sdim  Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
1192212795Sdim}
1193212795Sdim
1194212795Sdimvoid ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
1195212795Sdim  VisitExpr(E);
1196212795Sdim
1197218893Sdim  // Don't emit anything here, hasExplicitTemplateArgs() must be emitted first.
1198218893Sdim  Record.push_back(E->hasExplicitTemplateArgs());
1199212795Sdim  if (E->hasExplicitTemplateArgs()) {
1200212795Sdim    const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs();
1201212795Sdim    Record.push_back(Args.NumTemplateArgs);
1202212795Sdim    AddExplicitTemplateArgumentList(Args);
1203212795Sdim  }
1204212795Sdim
1205212795Sdim  Record.push_back(E->getNumDecls());
1206212795Sdim  for (OverloadExpr::decls_iterator
1207212795Sdim         OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
1208212795Sdim    Writer.AddDeclRef(OvI.getDecl(), Record);
1209212795Sdim    Record.push_back(OvI.getAccess());
1210212795Sdim  }
1211212795Sdim
1212218893Sdim  Writer.AddDeclarationNameInfo(E->NameInfo, Record);
1213221345Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1214212795Sdim}
1215212795Sdim
1216212795Sdimvoid ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
1217212795Sdim  VisitOverloadExpr(E);
1218212795Sdim  Record.push_back(E->isArrow());
1219212795Sdim  Record.push_back(E->hasUnresolvedUsing());
1220212795Sdim  Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
1221212795Sdim  Writer.AddTypeRef(E->getBaseType(), Record);
1222212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1223212795Sdim  Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
1224212795Sdim}
1225212795Sdim
1226212795Sdimvoid ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
1227212795Sdim  VisitOverloadExpr(E);
1228212795Sdim  Record.push_back(E->requiresADL());
1229221345Sdim  if (E->requiresADL())
1230221345Sdim    Record.push_back(E->isStdAssociatedNamespace());
1231212795Sdim  Record.push_back(E->isOverloaded());
1232212795Sdim  Writer.AddDeclRef(E->getNamingClass(), Record);
1233212795Sdim  Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
1234212795Sdim}
1235212795Sdim
1236212795Sdimvoid ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1237212795Sdim  VisitExpr(E);
1238212795Sdim  Record.push_back(E->getTrait());
1239218893Sdim  Record.push_back(E->getValue());
1240212795Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1241218893Sdim  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
1242212795Sdim  Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
1243212795Sdim}
1244212795Sdim
1245218893Sdimvoid ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
1246218893Sdim  VisitExpr(E);
1247218893Sdim  Record.push_back(E->getTrait());
1248218893Sdim  Record.push_back(E->getValue());
1249218893Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1250218893Sdim  Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
1251218893Sdim  Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
1252218893Sdim  Code = serialization::EXPR_BINARY_TYPE_TRAIT;
1253218893Sdim}
1254218893Sdim
1255221345Sdimvoid ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
1256221345Sdim  VisitExpr(E);
1257221345Sdim  Record.push_back(E->getTrait());
1258221345Sdim  Record.push_back(E->getValue());
1259221345Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1260221345Sdim  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
1261221345Sdim  Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
1262221345Sdim}
1263221345Sdim
1264221345Sdimvoid ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
1265221345Sdim  VisitExpr(E);
1266221345Sdim  Record.push_back(E->getTrait());
1267221345Sdim  Record.push_back(E->getValue());
1268221345Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1269221345Sdim  Writer.AddStmt(E->getQueriedExpression());
1270221345Sdim  Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
1271221345Sdim}
1272221345Sdim
1273218893Sdimvoid ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
1274218893Sdim  VisitExpr(E);
1275218893Sdim  Record.push_back(E->getValue());
1276218893Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1277218893Sdim  Writer.AddStmt(E->getOperand());
1278218893Sdim  Code = serialization::EXPR_CXX_NOEXCEPT;
1279218893Sdim}
1280218893Sdim
1281218893Sdimvoid ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
1282218893Sdim  VisitExpr(E);
1283218893Sdim  Writer.AddSourceLocation(E->getEllipsisLoc(), Record);
1284218893Sdim  Record.push_back(E->NumExpansions);
1285218893Sdim  Writer.AddStmt(E->getPattern());
1286218893Sdim  Code = serialization::EXPR_PACK_EXPANSION;
1287218893Sdim}
1288218893Sdim
1289218893Sdimvoid ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
1290218893Sdim  VisitExpr(E);
1291218893Sdim  Writer.AddSourceLocation(E->OperatorLoc, Record);
1292218893Sdim  Writer.AddSourceLocation(E->PackLoc, Record);
1293218893Sdim  Writer.AddSourceLocation(E->RParenLoc, Record);
1294218893Sdim  Record.push_back(E->Length);
1295218893Sdim  Writer.AddDeclRef(E->Pack, Record);
1296218893Sdim  Code = serialization::EXPR_SIZEOF_PACK;
1297218893Sdim}
1298218893Sdim
1299224145Sdimvoid ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
1300224145Sdim                                              SubstNonTypeTemplateParmExpr *E) {
1301224145Sdim  VisitExpr(E);
1302224145Sdim  Writer.AddDeclRef(E->getParameter(), Record);
1303224145Sdim  Writer.AddSourceLocation(E->getNameLoc(), Record);
1304224145Sdim  Writer.AddStmt(E->getReplacement());
1305224145Sdim  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
1306224145Sdim}
1307224145Sdim
1308218893Sdimvoid ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
1309218893Sdim                                          SubstNonTypeTemplateParmPackExpr *E) {
1310218893Sdim  VisitExpr(E);
1311224145Sdim  Writer.AddDeclRef(E->getParameterPack(), Record);
1312218893Sdim  Writer.AddTemplateArgument(E->getArgumentPack(), Record);
1313224145Sdim  Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
1314218893Sdim  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
1315218893Sdim}
1316218893Sdim
1317224145Sdimvoid ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
1318224145Sdim  VisitExpr(E);
1319224145Sdim  Writer.AddStmt(E->Temporary);
1320224145Sdim  Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
1321224145Sdim}
1322224145Sdim
1323218893Sdimvoid ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
1324218893Sdim  VisitExpr(E);
1325218893Sdim  Record.push_back(Writer.getOpaqueValueID(E));
1326218893Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1327218893Sdim  Code = serialization::EXPR_OPAQUE_VALUE;
1328218893Sdim}
1329218893Sdim
1330212795Sdim//===----------------------------------------------------------------------===//
1331218893Sdim// CUDA Expressions and Statements.
1332218893Sdim//===----------------------------------------------------------------------===//
1333218893Sdim
1334218893Sdimvoid ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
1335218893Sdim  VisitCallExpr(E);
1336218893Sdim  Writer.AddStmt(E->getConfig());
1337218893Sdim  Code = serialization::EXPR_CUDA_KERNEL_CALL;
1338218893Sdim}
1339218893Sdim
1340218893Sdim//===----------------------------------------------------------------------===//
1341223017Sdim// OpenCL Expressions and Statements.
1342223017Sdim//===----------------------------------------------------------------------===//
1343223017Sdimvoid ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
1344223017Sdim  VisitExpr(E);
1345224145Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
1346224145Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1347223017Sdim  Writer.AddStmt(E->getSrcExpr());
1348223017Sdim  Code = serialization::EXPR_ASTYPE;
1349223017Sdim}
1350223017Sdim
1351223017Sdim//===----------------------------------------------------------------------===//
1352224145Sdim// Microsoft Expressions and Statements.
1353224145Sdim//===----------------------------------------------------------------------===//
1354224145Sdimvoid ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1355224145Sdim  VisitExpr(E);
1356224145Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1357224145Sdim  if (E->isTypeOperand()) {
1358224145Sdim    Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
1359224145Sdim    Code = serialization::EXPR_CXX_UUIDOF_TYPE;
1360224145Sdim  } else {
1361224145Sdim    Writer.AddStmt(E->getExprOperand());
1362224145Sdim    Code = serialization::EXPR_CXX_UUIDOF_EXPR;
1363224145Sdim  }
1364224145Sdim}
1365224145Sdim
1366224145Sdimvoid ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
1367224145Sdim  VisitStmt(S);
1368224145Sdim  Writer.AddSourceLocation(S->getExceptLoc(), Record);
1369224145Sdim  Writer.AddStmt(S->getFilterExpr());
1370224145Sdim  Writer.AddStmt(S->getBlock());
1371224145Sdim  Code = serialization::STMT_SEH_EXCEPT;
1372224145Sdim}
1373224145Sdim
1374224145Sdimvoid ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
1375224145Sdim  VisitStmt(S);
1376224145Sdim  Writer.AddSourceLocation(S->getFinallyLoc(), Record);
1377224145Sdim  Writer.AddStmt(S->getBlock());
1378224145Sdim  Code = serialization::STMT_SEH_FINALLY;
1379224145Sdim}
1380224145Sdim
1381224145Sdimvoid ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
1382224145Sdim  VisitStmt(S);
1383224145Sdim  Record.push_back(S->getIsCXXTry());
1384224145Sdim  Writer.AddSourceLocation(S->getTryLoc(), Record);
1385224145Sdim  Writer.AddStmt(S->getTryBlock());
1386224145Sdim  Writer.AddStmt(S->getHandler());
1387224145Sdim  Code = serialization::STMT_SEH_TRY;
1388224145Sdim}
1389224145Sdim
1390224145Sdim//===----------------------------------------------------------------------===//
1391212795Sdim// ASTWriter Implementation
1392212795Sdim//===----------------------------------------------------------------------===//
1393212795Sdim
1394212795Sdimunsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
1395212795Sdim  assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
1396212795Sdim         "SwitchCase recorded twice");
1397212795Sdim  unsigned NextID = SwitchCaseIDs.size();
1398212795Sdim  SwitchCaseIDs[S] = NextID;
1399212795Sdim  return NextID;
1400212795Sdim}
1401212795Sdim
1402212795Sdimunsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
1403212795Sdim  assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
1404212795Sdim         "SwitchCase hasn't been seen yet");
1405212795Sdim  return SwitchCaseIDs[S];
1406212795Sdim}
1407212795Sdim
1408218893Sdimvoid ASTWriter::ClearSwitchCaseIDs() {
1409218893Sdim  SwitchCaseIDs.clear();
1410218893Sdim}
1411212795Sdim
1412218893Sdimunsigned ASTWriter::getOpaqueValueID(OpaqueValueExpr *e) {
1413218893Sdim  unsigned &entry = OpaqueValues[e];
1414218893Sdim  if (!entry) entry = OpaqueValues.size();
1415218893Sdim  return entry;
1416212795Sdim}
1417212795Sdim
1418212795Sdim/// \brief Write the given substatement or subexpression to the
1419212795Sdim/// bitstream.
1420212795Sdimvoid ASTWriter::WriteSubStmt(Stmt *S) {
1421212795Sdim  RecordData Record;
1422212795Sdim  ASTStmtWriter Writer(*this, Record);
1423212795Sdim  ++NumStatements;
1424212795Sdim
1425212795Sdim  if (!S) {
1426212795Sdim    Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
1427212795Sdim    return;
1428212795Sdim  }
1429212795Sdim
1430212795Sdim  // Redirect ASTWriter::AddStmt to collect sub stmts.
1431212795Sdim  llvm::SmallVector<Stmt *, 16> SubStmts;
1432212795Sdim  CollectedStmts = &SubStmts;
1433212795Sdim
1434212795Sdim  Writer.Code = serialization::STMT_NULL_PTR;
1435223017Sdim  Writer.AbbrevToUse = 0;
1436212795Sdim  Writer.Visit(S);
1437212795Sdim
1438212795Sdim#ifndef NDEBUG
1439212795Sdim  if (Writer.Code == serialization::STMT_NULL_PTR) {
1440212795Sdim    SourceManager &SrcMgr
1441212795Sdim      = DeclIDs.begin()->first->getASTContext().getSourceManager();
1442212795Sdim    S->dump(SrcMgr);
1443212795Sdim    assert(0 && "Unhandled sub statement writing AST file");
1444212795Sdim  }
1445212795Sdim#endif
1446212795Sdim
1447212795Sdim  // Revert ASTWriter::AddStmt.
1448212795Sdim  CollectedStmts = &StmtsToEmit;
1449212795Sdim
1450212795Sdim  // Write the sub stmts in reverse order, last to first. When reading them back
1451212795Sdim  // we will read them in correct order by "pop"ing them from the Stmts stack.
1452212795Sdim  // This simplifies reading and allows to store a variable number of sub stmts
1453212795Sdim  // without knowing it in advance.
1454212795Sdim  while (!SubStmts.empty())
1455212795Sdim    WriteSubStmt(SubStmts.pop_back_val());
1456212795Sdim
1457223017Sdim  Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
1458212795Sdim}
1459212795Sdim
1460212795Sdim/// \brief Flush all of the statements that have been added to the
1461212795Sdim/// queue via AddStmt().
1462212795Sdimvoid ASTWriter::FlushStmts() {
1463212795Sdim  RecordData Record;
1464212795Sdim
1465212795Sdim  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
1466212795Sdim    WriteSubStmt(StmtsToEmit[I]);
1467212795Sdim
1468212795Sdim    assert(N == StmtsToEmit.size() &&
1469221345Sdim           "Substatement written via AddStmt rather than WriteSubStmt!");
1470212795Sdim
1471212795Sdim    // Note that we are at the end of a full expression. Any
1472212795Sdim    // expression records that follow this one are part of a different
1473212795Sdim    // expression.
1474212795Sdim    Stream.EmitRecord(serialization::STMT_STOP, Record);
1475212795Sdim  }
1476212795Sdim
1477212795Sdim  StmtsToEmit.clear();
1478212795Sdim}
1479