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//===----------------------------------------------------------------------===//
9263509Sdim///
10263509Sdim/// \file
11263509Sdim/// \brief Implements serialization for Statements and Expressions.
12263509Sdim///
13212795Sdim//===----------------------------------------------------------------------===//
14212795Sdim
15212795Sdim#include "clang/Serialization/ASTWriter.h"
16245431Sdim#include "clang/AST/ASTContext.h"
17212795Sdim#include "clang/AST/DeclCXX.h"
18212795Sdim#include "clang/AST/DeclObjC.h"
19218893Sdim#include "clang/AST/DeclTemplate.h"
20212795Sdim#include "clang/AST/StmtVisitor.h"
21252723Sdim#include "clang/Lex/Token.h"
22212795Sdim#include "llvm/Bitcode/BitstreamWriter.h"
23212795Sdimusing namespace clang;
24212795Sdim
25212795Sdim//===----------------------------------------------------------------------===//
26212795Sdim// Statement/expression serialization
27212795Sdim//===----------------------------------------------------------------------===//
28212795Sdim
29212795Sdimnamespace clang {
30263509Sdim
31212795Sdim  class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
32263509Sdim    friend class OMPClauseWriter;
33212795Sdim    ASTWriter &Writer;
34212795Sdim    ASTWriter::RecordData &Record;
35212795Sdim
36212795Sdim  public:
37212795Sdim    serialization::StmtCode Code;
38223017Sdim    unsigned AbbrevToUse;
39212795Sdim
40212795Sdim    ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
41212795Sdim      : Writer(Writer), Record(Record) { }
42212795Sdim
43235633Sdim    void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args);
44235633Sdim
45212795Sdim    void VisitStmt(Stmt *S);
46224145Sdim#define STMT(Type, Base) \
47224145Sdim    void Visit##Type(Type *);
48224145Sdim#include "clang/AST/StmtNodes.inc"
49212795Sdim  };
50212795Sdim}
51212795Sdim
52212795Sdimvoid ASTStmtWriter::
53235633SdimAddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) {
54235633Sdim  Writer.AddSourceLocation(Args.getTemplateKeywordLoc(), Record);
55212795Sdim  Writer.AddSourceLocation(Args.LAngleLoc, Record);
56212795Sdim  Writer.AddSourceLocation(Args.RAngleLoc, Record);
57212795Sdim  for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
58212795Sdim    Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
59212795Sdim}
60212795Sdim
61212795Sdimvoid ASTStmtWriter::VisitStmt(Stmt *S) {
62212795Sdim}
63212795Sdim
64212795Sdimvoid ASTStmtWriter::VisitNullStmt(NullStmt *S) {
65212795Sdim  VisitStmt(S);
66212795Sdim  Writer.AddSourceLocation(S->getSemiLoc(), Record);
67226890Sdim  Record.push_back(S->HasLeadingEmptyMacro);
68212795Sdim  Code = serialization::STMT_NULL;
69212795Sdim}
70212795Sdim
71212795Sdimvoid ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
72212795Sdim  VisitStmt(S);
73212795Sdim  Record.push_back(S->size());
74212795Sdim  for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
75212795Sdim       CS != CSEnd; ++CS)
76212795Sdim    Writer.AddStmt(*CS);
77212795Sdim  Writer.AddSourceLocation(S->getLBracLoc(), Record);
78212795Sdim  Writer.AddSourceLocation(S->getRBracLoc(), Record);
79212795Sdim  Code = serialization::STMT_COMPOUND;
80212795Sdim}
81212795Sdim
82212795Sdimvoid ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
83212795Sdim  VisitStmt(S);
84212795Sdim  Record.push_back(Writer.getSwitchCaseID(S));
85252723Sdim  Writer.AddSourceLocation(S->getKeywordLoc(), Record);
86252723Sdim  Writer.AddSourceLocation(S->getColonLoc(), Record);
87212795Sdim}
88212795Sdim
89212795Sdimvoid ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
90212795Sdim  VisitSwitchCase(S);
91212795Sdim  Writer.AddStmt(S->getLHS());
92212795Sdim  Writer.AddStmt(S->getRHS());
93212795Sdim  Writer.AddStmt(S->getSubStmt());
94212795Sdim  Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
95212795Sdim  Code = serialization::STMT_CASE;
96212795Sdim}
97212795Sdim
98212795Sdimvoid ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
99212795Sdim  VisitSwitchCase(S);
100212795Sdim  Writer.AddStmt(S->getSubStmt());
101212795Sdim  Code = serialization::STMT_DEFAULT;
102212795Sdim}
103212795Sdim
104212795Sdimvoid ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
105212795Sdim  VisitStmt(S);
106218893Sdim  Writer.AddDeclRef(S->getDecl(), Record);
107212795Sdim  Writer.AddStmt(S->getSubStmt());
108212795Sdim  Writer.AddSourceLocation(S->getIdentLoc(), Record);
109212795Sdim  Code = serialization::STMT_LABEL;
110212795Sdim}
111212795Sdim
112235633Sdimvoid ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
113235633Sdim  VisitStmt(S);
114245431Sdim  Record.push_back(S->getAttrs().size());
115235633Sdim  Writer.WriteAttributes(S->getAttrs(), Record);
116235633Sdim  Writer.AddStmt(S->getSubStmt());
117235633Sdim  Writer.AddSourceLocation(S->getAttrLoc(), Record);
118235633Sdim  Code = serialization::STMT_ATTRIBUTED;
119235633Sdim}
120235633Sdim
121212795Sdimvoid ASTStmtWriter::VisitIfStmt(IfStmt *S) {
122212795Sdim  VisitStmt(S);
123212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
124212795Sdim  Writer.AddStmt(S->getCond());
125212795Sdim  Writer.AddStmt(S->getThen());
126212795Sdim  Writer.AddStmt(S->getElse());
127212795Sdim  Writer.AddSourceLocation(S->getIfLoc(), Record);
128212795Sdim  Writer.AddSourceLocation(S->getElseLoc(), Record);
129212795Sdim  Code = serialization::STMT_IF;
130212795Sdim}
131212795Sdim
132212795Sdimvoid ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
133212795Sdim  VisitStmt(S);
134212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
135212795Sdim  Writer.AddStmt(S->getCond());
136212795Sdim  Writer.AddStmt(S->getBody());
137212795Sdim  Writer.AddSourceLocation(S->getSwitchLoc(), Record);
138218893Sdim  Record.push_back(S->isAllEnumCasesCovered());
139212795Sdim  for (SwitchCase *SC = S->getSwitchCaseList(); SC;
140212795Sdim       SC = SC->getNextSwitchCase())
141212795Sdim    Record.push_back(Writer.RecordSwitchCaseID(SC));
142212795Sdim  Code = serialization::STMT_SWITCH;
143212795Sdim}
144212795Sdim
145212795Sdimvoid ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
146212795Sdim  VisitStmt(S);
147212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
148212795Sdim  Writer.AddStmt(S->getCond());
149212795Sdim  Writer.AddStmt(S->getBody());
150212795Sdim  Writer.AddSourceLocation(S->getWhileLoc(), Record);
151212795Sdim  Code = serialization::STMT_WHILE;
152212795Sdim}
153212795Sdim
154212795Sdimvoid ASTStmtWriter::VisitDoStmt(DoStmt *S) {
155212795Sdim  VisitStmt(S);
156212795Sdim  Writer.AddStmt(S->getCond());
157212795Sdim  Writer.AddStmt(S->getBody());
158212795Sdim  Writer.AddSourceLocation(S->getDoLoc(), Record);
159212795Sdim  Writer.AddSourceLocation(S->getWhileLoc(), Record);
160212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
161212795Sdim  Code = serialization::STMT_DO;
162212795Sdim}
163212795Sdim
164212795Sdimvoid ASTStmtWriter::VisitForStmt(ForStmt *S) {
165212795Sdim  VisitStmt(S);
166212795Sdim  Writer.AddStmt(S->getInit());
167212795Sdim  Writer.AddStmt(S->getCond());
168212795Sdim  Writer.AddDeclRef(S->getConditionVariable(), Record);
169212795Sdim  Writer.AddStmt(S->getInc());
170212795Sdim  Writer.AddStmt(S->getBody());
171212795Sdim  Writer.AddSourceLocation(S->getForLoc(), Record);
172212795Sdim  Writer.AddSourceLocation(S->getLParenLoc(), Record);
173212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
174212795Sdim  Code = serialization::STMT_FOR;
175212795Sdim}
176212795Sdim
177212795Sdimvoid ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
178212795Sdim  VisitStmt(S);
179218893Sdim  Writer.AddDeclRef(S->getLabel(), Record);
180212795Sdim  Writer.AddSourceLocation(S->getGotoLoc(), Record);
181212795Sdim  Writer.AddSourceLocation(S->getLabelLoc(), Record);
182212795Sdim  Code = serialization::STMT_GOTO;
183212795Sdim}
184212795Sdim
185212795Sdimvoid ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
186212795Sdim  VisitStmt(S);
187212795Sdim  Writer.AddSourceLocation(S->getGotoLoc(), Record);
188212795Sdim  Writer.AddSourceLocation(S->getStarLoc(), Record);
189212795Sdim  Writer.AddStmt(S->getTarget());
190212795Sdim  Code = serialization::STMT_INDIRECT_GOTO;
191212795Sdim}
192212795Sdim
193212795Sdimvoid ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
194212795Sdim  VisitStmt(S);
195212795Sdim  Writer.AddSourceLocation(S->getContinueLoc(), Record);
196212795Sdim  Code = serialization::STMT_CONTINUE;
197212795Sdim}
198212795Sdim
199212795Sdimvoid ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
200212795Sdim  VisitStmt(S);
201212795Sdim  Writer.AddSourceLocation(S->getBreakLoc(), Record);
202212795Sdim  Code = serialization::STMT_BREAK;
203212795Sdim}
204212795Sdim
205212795Sdimvoid ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
206212795Sdim  VisitStmt(S);
207212795Sdim  Writer.AddStmt(S->getRetValue());
208212795Sdim  Writer.AddSourceLocation(S->getReturnLoc(), Record);
209212795Sdim  Writer.AddDeclRef(S->getNRVOCandidate(), Record);
210212795Sdim  Code = serialization::STMT_RETURN;
211212795Sdim}
212212795Sdim
213212795Sdimvoid ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
214212795Sdim  VisitStmt(S);
215212795Sdim  Writer.AddSourceLocation(S->getStartLoc(), Record);
216212795Sdim  Writer.AddSourceLocation(S->getEndLoc(), Record);
217212795Sdim  DeclGroupRef DG = S->getDeclGroup();
218212795Sdim  for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
219212795Sdim    Writer.AddDeclRef(*D, Record);
220212795Sdim  Code = serialization::STMT_DECL;
221212795Sdim}
222212795Sdim
223252723Sdimvoid ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
224212795Sdim  VisitStmt(S);
225212795Sdim  Record.push_back(S->getNumOutputs());
226212795Sdim  Record.push_back(S->getNumInputs());
227212795Sdim  Record.push_back(S->getNumClobbers());
228212795Sdim  Writer.AddSourceLocation(S->getAsmLoc(), Record);
229212795Sdim  Record.push_back(S->isVolatile());
230212795Sdim  Record.push_back(S->isSimple());
231252723Sdim}
232252723Sdim
233252723Sdimvoid ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
234252723Sdim  VisitAsmStmt(S);
235252723Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
236212795Sdim  Writer.AddStmt(S->getAsmString());
237212795Sdim
238212795Sdim  // Outputs
239212795Sdim  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
240212795Sdim    Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
241212795Sdim    Writer.AddStmt(S->getOutputConstraintLiteral(I));
242212795Sdim    Writer.AddStmt(S->getOutputExpr(I));
243212795Sdim  }
244212795Sdim
245212795Sdim  // Inputs
246212795Sdim  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
247212795Sdim    Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
248212795Sdim    Writer.AddStmt(S->getInputConstraintLiteral(I));
249212795Sdim    Writer.AddStmt(S->getInputExpr(I));
250212795Sdim  }
251212795Sdim
252212795Sdim  // Clobbers
253212795Sdim  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
254245431Sdim    Writer.AddStmt(S->getClobberStringLiteral(I));
255212795Sdim
256245431Sdim  Code = serialization::STMT_GCCASM;
257212795Sdim}
258212795Sdim
259245431Sdimvoid ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
260252723Sdim  VisitAsmStmt(S);
261252723Sdim  Writer.AddSourceLocation(S->getLBraceLoc(), Record);
262252723Sdim  Writer.AddSourceLocation(S->getEndLoc(), Record);
263252723Sdim  Record.push_back(S->getNumAsmToks());
264252723Sdim  Writer.AddString(S->getAsmString(), Record);
265245431Sdim
266252723Sdim  // Tokens
267252723Sdim  for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
268252723Sdim    Writer.AddToken(S->getAsmToks()[I], Record);
269252723Sdim  }
270252723Sdim
271252723Sdim  // Clobbers
272252723Sdim  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
273252723Sdim    Writer.AddString(S->getClobber(I), Record);
274252723Sdim  }
275252723Sdim
276252723Sdim  // Outputs
277252723Sdim  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
278252723Sdim    Writer.AddStmt(S->getOutputExpr(I));
279252723Sdim    Writer.AddString(S->getOutputConstraint(I), Record);
280252723Sdim  }
281252723Sdim
282252723Sdim  // Inputs
283252723Sdim  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
284252723Sdim    Writer.AddStmt(S->getInputExpr(I));
285252723Sdim    Writer.AddString(S->getInputConstraint(I), Record);
286252723Sdim  }
287252723Sdim
288245431Sdim  Code = serialization::STMT_MSASM;
289245431Sdim}
290245431Sdim
291252723Sdimvoid ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
292252723Sdim  VisitStmt(S);
293252723Sdim  // NumCaptures
294252723Sdim  Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
295252723Sdim
296252723Sdim  // CapturedDecl and captured region kind
297252723Sdim  Writer.AddDeclRef(S->getCapturedDecl(), Record);
298252723Sdim  Record.push_back(S->getCapturedRegionKind());
299252723Sdim
300252723Sdim  Writer.AddDeclRef(S->getCapturedRecordDecl(), Record);
301252723Sdim
302252723Sdim  // Capture inits
303252723Sdim  for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(),
304252723Sdim                                           E = S->capture_init_end();
305252723Sdim       I != E; ++I)
306252723Sdim    Writer.AddStmt(*I);
307252723Sdim
308252723Sdim  // Body
309252723Sdim  Writer.AddStmt(S->getCapturedStmt());
310252723Sdim
311252723Sdim  // Captures
312252723Sdim  for (CapturedStmt::capture_iterator I = S->capture_begin(),
313252723Sdim                                      E = S->capture_end();
314252723Sdim       I != E; ++I) {
315252723Sdim    if (I->capturesThis())
316252723Sdim      Writer.AddDeclRef(0, Record);
317252723Sdim    else
318252723Sdim      Writer.AddDeclRef(I->getCapturedVar(), Record);
319252723Sdim    Record.push_back(I->getCaptureKind());
320252723Sdim    Writer.AddSourceLocation(I->getLocation(), Record);
321252723Sdim  }
322252723Sdim
323252723Sdim  Code = serialization::STMT_CAPTURED;
324252723Sdim}
325252723Sdim
326212795Sdimvoid ASTStmtWriter::VisitExpr(Expr *E) {
327212795Sdim  VisitStmt(E);
328212795Sdim  Writer.AddTypeRef(E->getType(), Record);
329212795Sdim  Record.push_back(E->isTypeDependent());
330212795Sdim  Record.push_back(E->isValueDependent());
331224145Sdim  Record.push_back(E->isInstantiationDependent());
332218893Sdim  Record.push_back(E->containsUnexpandedParameterPack());
333218893Sdim  Record.push_back(E->getValueKind());
334218893Sdim  Record.push_back(E->getObjectKind());
335212795Sdim}
336212795Sdim
337212795Sdimvoid ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
338212795Sdim  VisitExpr(E);
339212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
340212795Sdim  Record.push_back(E->getIdentType()); // FIXME: stable encoding
341212795Sdim  Code = serialization::EXPR_PREDEFINED;
342212795Sdim}
343212795Sdim
344212795Sdimvoid ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
345212795Sdim  VisitExpr(E);
346212795Sdim
347212795Sdim  Record.push_back(E->hasQualifier());
348221345Sdim  Record.push_back(E->getDecl() != E->getFoundDecl());
349235633Sdim  Record.push_back(E->hasTemplateKWAndArgsInfo());
350226890Sdim  Record.push_back(E->hadMultipleCandidates());
351235633Sdim  Record.push_back(E->refersToEnclosingLocal());
352212795Sdim
353235633Sdim  if (E->hasTemplateKWAndArgsInfo()) {
354218893Sdim    unsigned NumTemplateArgs = E->getNumTemplateArgs();
355218893Sdim    Record.push_back(NumTemplateArgs);
356218893Sdim  }
357212795Sdim
358223017Sdim  DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
359223017Sdim
360235633Sdim  if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
361223017Sdim      (E->getDecl() == E->getFoundDecl()) &&
362223017Sdim      nk == DeclarationName::Identifier) {
363223017Sdim    AbbrevToUse = Writer.getDeclRefExprAbbrev();
364223017Sdim  }
365223017Sdim
366221345Sdim  if (E->hasQualifier())
367221345Sdim    Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
368221345Sdim
369221345Sdim  if (E->getDecl() != E->getFoundDecl())
370221345Sdim    Writer.AddDeclRef(E->getFoundDecl(), Record);
371221345Sdim
372235633Sdim  if (E->hasTemplateKWAndArgsInfo())
373235633Sdim    AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo());
374221345Sdim
375212795Sdim  Writer.AddDeclRef(E->getDecl(), Record);
376212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
377218893Sdim  Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
378212795Sdim  Code = serialization::EXPR_DECL_REF;
379212795Sdim}
380212795Sdim
381212795Sdimvoid ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
382212795Sdim  VisitExpr(E);
383212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
384212795Sdim  Writer.AddAPInt(E->getValue(), Record);
385223017Sdim
386223017Sdim  if (E->getValue().getBitWidth() == 32) {
387223017Sdim    AbbrevToUse = Writer.getIntegerLiteralAbbrev();
388223017Sdim  }
389223017Sdim
390212795Sdim  Code = serialization::EXPR_INTEGER_LITERAL;
391212795Sdim}
392212795Sdim
393212795Sdimvoid ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
394212795Sdim  VisitExpr(E);
395252723Sdim  Record.push_back(E->getRawSemantics());
396252723Sdim  Record.push_back(E->isExact());
397212795Sdim  Writer.AddAPFloat(E->getValue(), Record);
398212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
399212795Sdim  Code = serialization::EXPR_FLOATING_LITERAL;
400212795Sdim}
401212795Sdim
402212795Sdimvoid ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
403212795Sdim  VisitExpr(E);
404212795Sdim  Writer.AddStmt(E->getSubExpr());
405212795Sdim  Code = serialization::EXPR_IMAGINARY_LITERAL;
406212795Sdim}
407212795Sdim
408212795Sdimvoid ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
409212795Sdim  VisitExpr(E);
410212795Sdim  Record.push_back(E->getByteLength());
411212795Sdim  Record.push_back(E->getNumConcatenated());
412226890Sdim  Record.push_back(E->getKind());
413221345Sdim  Record.push_back(E->isPascal());
414212795Sdim  // FIXME: String data should be stored as a blob at the end of the
415212795Sdim  // StringLiteral. However, we can't do so now because we have no
416212795Sdim  // provision for coping with abbreviations when we're jumping around
417212795Sdim  // the AST file during deserialization.
418235633Sdim  Record.append(E->getBytes().begin(), E->getBytes().end());
419212795Sdim  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
420212795Sdim    Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
421212795Sdim  Code = serialization::EXPR_STRING_LITERAL;
422212795Sdim}
423212795Sdim
424212795Sdimvoid ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
425212795Sdim  VisitExpr(E);
426212795Sdim  Record.push_back(E->getValue());
427212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
428226890Sdim  Record.push_back(E->getKind());
429223017Sdim
430223017Sdim  AbbrevToUse = Writer.getCharacterLiteralAbbrev();
431223017Sdim
432212795Sdim  Code = serialization::EXPR_CHARACTER_LITERAL;
433212795Sdim}
434212795Sdim
435212795Sdimvoid ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
436212795Sdim  VisitExpr(E);
437212795Sdim  Writer.AddSourceLocation(E->getLParen(), Record);
438212795Sdim  Writer.AddSourceLocation(E->getRParen(), Record);
439212795Sdim  Writer.AddStmt(E->getSubExpr());
440212795Sdim  Code = serialization::EXPR_PAREN;
441212795Sdim}
442212795Sdim
443212795Sdimvoid ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
444212795Sdim  VisitExpr(E);
445212795Sdim  Record.push_back(E->NumExprs);
446212795Sdim  for (unsigned i=0; i != E->NumExprs; ++i)
447212795Sdim    Writer.AddStmt(E->Exprs[i]);
448212795Sdim  Writer.AddSourceLocation(E->LParenLoc, Record);
449212795Sdim  Writer.AddSourceLocation(E->RParenLoc, Record);
450212795Sdim  Code = serialization::EXPR_PAREN_LIST;
451212795Sdim}
452212795Sdim
453212795Sdimvoid ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
454212795Sdim  VisitExpr(E);
455212795Sdim  Writer.AddStmt(E->getSubExpr());
456212795Sdim  Record.push_back(E->getOpcode()); // FIXME: stable encoding
457212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
458212795Sdim  Code = serialization::EXPR_UNARY_OPERATOR;
459212795Sdim}
460212795Sdim
461212795Sdimvoid ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
462212795Sdim  VisitExpr(E);
463212795Sdim  Record.push_back(E->getNumComponents());
464212795Sdim  Record.push_back(E->getNumExpressions());
465212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
466212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
467212795Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
468212795Sdim  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
469212795Sdim    const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
470212795Sdim    Record.push_back(ON.getKind()); // FIXME: Stable encoding
471221345Sdim    Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
472221345Sdim    Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
473212795Sdim    switch (ON.getKind()) {
474212795Sdim    case OffsetOfExpr::OffsetOfNode::Array:
475212795Sdim      Record.push_back(ON.getArrayExprIndex());
476212795Sdim      break;
477212795Sdim
478212795Sdim    case OffsetOfExpr::OffsetOfNode::Field:
479212795Sdim      Writer.AddDeclRef(ON.getField(), Record);
480212795Sdim      break;
481212795Sdim
482212795Sdim    case OffsetOfExpr::OffsetOfNode::Identifier:
483212795Sdim      Writer.AddIdentifierRef(ON.getFieldName(), Record);
484212795Sdim      break;
485212795Sdim
486212795Sdim    case OffsetOfExpr::OffsetOfNode::Base:
487212795Sdim      Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
488212795Sdim      break;
489212795Sdim    }
490212795Sdim  }
491212795Sdim  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
492212795Sdim    Writer.AddStmt(E->getIndexExpr(I));
493212795Sdim  Code = serialization::EXPR_OFFSETOF;
494212795Sdim}
495212795Sdim
496221345Sdimvoid ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
497212795Sdim  VisitExpr(E);
498221345Sdim  Record.push_back(E->getKind());
499212795Sdim  if (E->isArgumentType())
500212795Sdim    Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
501212795Sdim  else {
502212795Sdim    Record.push_back(0);
503212795Sdim    Writer.AddStmt(E->getArgumentExpr());
504212795Sdim  }
505212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
506212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
507212795Sdim  Code = serialization::EXPR_SIZEOF_ALIGN_OF;
508212795Sdim}
509212795Sdim
510212795Sdimvoid ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
511212795Sdim  VisitExpr(E);
512212795Sdim  Writer.AddStmt(E->getLHS());
513212795Sdim  Writer.AddStmt(E->getRHS());
514212795Sdim  Writer.AddSourceLocation(E->getRBracketLoc(), Record);
515212795Sdim  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
516212795Sdim}
517212795Sdim
518212795Sdimvoid ASTStmtWriter::VisitCallExpr(CallExpr *E) {
519212795Sdim  VisitExpr(E);
520212795Sdim  Record.push_back(E->getNumArgs());
521212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
522212795Sdim  Writer.AddStmt(E->getCallee());
523212795Sdim  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
524212795Sdim       Arg != ArgEnd; ++Arg)
525212795Sdim    Writer.AddStmt(*Arg);
526212795Sdim  Code = serialization::EXPR_CALL;
527212795Sdim}
528212795Sdim
529212795Sdimvoid ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
530212795Sdim  // Don't call VisitExpr, we'll write everything here.
531212795Sdim
532212795Sdim  Record.push_back(E->hasQualifier());
533221345Sdim  if (E->hasQualifier())
534221345Sdim    Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
535212795Sdim
536235633Sdim  Record.push_back(E->HasTemplateKWAndArgsInfo);
537235633Sdim  if (E->HasTemplateKWAndArgsInfo) {
538235633Sdim    Writer.AddSourceLocation(E->getTemplateKeywordLoc(), Record);
539218893Sdim    unsigned NumTemplateArgs = E->getNumTemplateArgs();
540218893Sdim    Record.push_back(NumTemplateArgs);
541212795Sdim    Writer.AddSourceLocation(E->getLAngleLoc(), Record);
542212795Sdim    Writer.AddSourceLocation(E->getRAngleLoc(), Record);
543212795Sdim    for (unsigned i=0; i != NumTemplateArgs; ++i)
544212795Sdim      Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
545212795Sdim  }
546226890Sdim
547226890Sdim  Record.push_back(E->hadMultipleCandidates());
548226890Sdim
549212795Sdim  DeclAccessPair FoundDecl = E->getFoundDecl();
550212795Sdim  Writer.AddDeclRef(FoundDecl.getDecl(), Record);
551212795Sdim  Record.push_back(FoundDecl.getAccess());
552212795Sdim
553212795Sdim  Writer.AddTypeRef(E->getType(), Record);
554218893Sdim  Record.push_back(E->getValueKind());
555218893Sdim  Record.push_back(E->getObjectKind());
556212795Sdim  Writer.AddStmt(E->getBase());
557212795Sdim  Writer.AddDeclRef(E->getMemberDecl(), Record);
558212795Sdim  Writer.AddSourceLocation(E->getMemberLoc(), Record);
559212795Sdim  Record.push_back(E->isArrow());
560218893Sdim  Writer.AddDeclarationNameLoc(E->MemberDNLoc,
561218893Sdim                               E->getMemberDecl()->getDeclName(), Record);
562212795Sdim  Code = serialization::EXPR_MEMBER;
563212795Sdim}
564212795Sdim
565212795Sdimvoid ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
566212795Sdim  VisitExpr(E);
567212795Sdim  Writer.AddStmt(E->getBase());
568212795Sdim  Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
569252723Sdim  Writer.AddSourceLocation(E->getOpLoc(), Record);
570212795Sdim  Record.push_back(E->isArrow());
571212795Sdim  Code = serialization::EXPR_OBJC_ISA;
572212795Sdim}
573212795Sdim
574224145Sdimvoid ASTStmtWriter::
575224145SdimVisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
576224145Sdim  VisitExpr(E);
577224145Sdim  Writer.AddStmt(E->getSubExpr());
578224145Sdim  Record.push_back(E->shouldCopy());
579224145Sdim  Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
580224145Sdim}
581224145Sdim
582224145Sdimvoid ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
583224145Sdim  VisitExplicitCastExpr(E);
584224145Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
585224145Sdim  Writer.AddSourceLocation(E->getBridgeKeywordLoc(), Record);
586224145Sdim  Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
587224145Sdim  Code = serialization::EXPR_OBJC_BRIDGED_CAST;
588224145Sdim}
589224145Sdim
590212795Sdimvoid ASTStmtWriter::VisitCastExpr(CastExpr *E) {
591212795Sdim  VisitExpr(E);
592212795Sdim  Record.push_back(E->path_size());
593212795Sdim  Writer.AddStmt(E->getSubExpr());
594212795Sdim  Record.push_back(E->getCastKind()); // FIXME: stable encoding
595212795Sdim
596212795Sdim  for (CastExpr::path_iterator
597212795Sdim         PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
598212795Sdim    Writer.AddCXXBaseSpecifier(**PI, Record);
599212795Sdim}
600212795Sdim
601212795Sdimvoid ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
602212795Sdim  VisitExpr(E);
603212795Sdim  Writer.AddStmt(E->getLHS());
604212795Sdim  Writer.AddStmt(E->getRHS());
605212795Sdim  Record.push_back(E->getOpcode()); // FIXME: stable encoding
606212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
607245431Sdim  Record.push_back(E->isFPContractable());
608212795Sdim  Code = serialization::EXPR_BINARY_OPERATOR;
609212795Sdim}
610212795Sdim
611212795Sdimvoid ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
612212795Sdim  VisitBinaryOperator(E);
613212795Sdim  Writer.AddTypeRef(E->getComputationLHSType(), Record);
614212795Sdim  Writer.AddTypeRef(E->getComputationResultType(), Record);
615212795Sdim  Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
616212795Sdim}
617212795Sdim
618212795Sdimvoid ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
619212795Sdim  VisitExpr(E);
620212795Sdim  Writer.AddStmt(E->getCond());
621212795Sdim  Writer.AddStmt(E->getLHS());
622212795Sdim  Writer.AddStmt(E->getRHS());
623212795Sdim  Writer.AddSourceLocation(E->getQuestionLoc(), Record);
624212795Sdim  Writer.AddSourceLocation(E->getColonLoc(), Record);
625212795Sdim  Code = serialization::EXPR_CONDITIONAL_OPERATOR;
626212795Sdim}
627212795Sdim
628218893Sdimvoid
629218893SdimASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
630218893Sdim  VisitExpr(E);
631218893Sdim  Writer.AddStmt(E->getOpaqueValue());
632218893Sdim  Writer.AddStmt(E->getCommon());
633218893Sdim  Writer.AddStmt(E->getCond());
634218893Sdim  Writer.AddStmt(E->getTrueExpr());
635218893Sdim  Writer.AddStmt(E->getFalseExpr());
636218893Sdim  Writer.AddSourceLocation(E->getQuestionLoc(), Record);
637218893Sdim  Writer.AddSourceLocation(E->getColonLoc(), Record);
638218893Sdim  Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
639218893Sdim}
640218893Sdim
641212795Sdimvoid ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
642212795Sdim  VisitCastExpr(E);
643212795Sdim  Code = serialization::EXPR_IMPLICIT_CAST;
644212795Sdim}
645212795Sdim
646212795Sdimvoid ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
647212795Sdim  VisitCastExpr(E);
648212795Sdim  Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
649212795Sdim}
650212795Sdim
651212795Sdimvoid ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
652212795Sdim  VisitExplicitCastExpr(E);
653212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
654212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
655212795Sdim  Code = serialization::EXPR_CSTYLE_CAST;
656212795Sdim}
657212795Sdim
658212795Sdimvoid ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
659212795Sdim  VisitExpr(E);
660212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
661212795Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
662212795Sdim  Writer.AddStmt(E->getInitializer());
663212795Sdim  Record.push_back(E->isFileScope());
664212795Sdim  Code = serialization::EXPR_COMPOUND_LITERAL;
665212795Sdim}
666212795Sdim
667212795Sdimvoid ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
668212795Sdim  VisitExpr(E);
669212795Sdim  Writer.AddStmt(E->getBase());
670212795Sdim  Writer.AddIdentifierRef(&E->getAccessor(), Record);
671212795Sdim  Writer.AddSourceLocation(E->getAccessorLoc(), Record);
672212795Sdim  Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
673212795Sdim}
674212795Sdim
675212795Sdimvoid ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
676212795Sdim  VisitExpr(E);
677245431Sdim  // NOTE: only add the (possibly null) syntactic form.
678245431Sdim  // No need to serialize the isSemanticForm flag and the semantic form.
679212795Sdim  Writer.AddStmt(E->getSyntacticForm());
680212795Sdim  Writer.AddSourceLocation(E->getLBraceLoc(), Record);
681212795Sdim  Writer.AddSourceLocation(E->getRBraceLoc(), Record);
682221345Sdim  bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
683221345Sdim  Record.push_back(isArrayFiller);
684221345Sdim  if (isArrayFiller)
685221345Sdim    Writer.AddStmt(E->getArrayFiller());
686221345Sdim  else
687221345Sdim    Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
688212795Sdim  Record.push_back(E->hadArrayRangeDesignator());
689221345Sdim  Record.push_back(E->getNumInits());
690221345Sdim  if (isArrayFiller) {
691221345Sdim    // ArrayFiller may have filled "holes" due to designated initializer.
692221345Sdim    // Replace them by 0 to indicate that the filler goes in that place.
693221345Sdim    Expr *filler = E->getArrayFiller();
694221345Sdim    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
695221345Sdim      Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0);
696221345Sdim  } else {
697221345Sdim    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
698221345Sdim      Writer.AddStmt(E->getInit(I));
699221345Sdim  }
700212795Sdim  Code = serialization::EXPR_INIT_LIST;
701212795Sdim}
702212795Sdim
703212795Sdimvoid ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
704212795Sdim  VisitExpr(E);
705212795Sdim  Record.push_back(E->getNumSubExprs());
706212795Sdim  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
707212795Sdim    Writer.AddStmt(E->getSubExpr(I));
708212795Sdim  Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
709212795Sdim  Record.push_back(E->usesGNUSyntax());
710212795Sdim  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
711212795Sdim                                             DEnd = E->designators_end();
712212795Sdim       D != DEnd; ++D) {
713212795Sdim    if (D->isFieldDesignator()) {
714212795Sdim      if (FieldDecl *Field = D->getField()) {
715212795Sdim        Record.push_back(serialization::DESIG_FIELD_DECL);
716212795Sdim        Writer.AddDeclRef(Field, Record);
717212795Sdim      } else {
718212795Sdim        Record.push_back(serialization::DESIG_FIELD_NAME);
719212795Sdim        Writer.AddIdentifierRef(D->getFieldName(), Record);
720212795Sdim      }
721212795Sdim      Writer.AddSourceLocation(D->getDotLoc(), Record);
722212795Sdim      Writer.AddSourceLocation(D->getFieldLoc(), Record);
723212795Sdim    } else if (D->isArrayDesignator()) {
724212795Sdim      Record.push_back(serialization::DESIG_ARRAY);
725212795Sdim      Record.push_back(D->getFirstExprIndex());
726212795Sdim      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
727212795Sdim      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
728212795Sdim    } else {
729212795Sdim      assert(D->isArrayRangeDesignator() && "Unknown designator");
730212795Sdim      Record.push_back(serialization::DESIG_ARRAY_RANGE);
731212795Sdim      Record.push_back(D->getFirstExprIndex());
732212795Sdim      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
733212795Sdim      Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
734212795Sdim      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
735212795Sdim    }
736212795Sdim  }
737212795Sdim  Code = serialization::EXPR_DESIGNATED_INIT;
738212795Sdim}
739212795Sdim
740212795Sdimvoid ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
741212795Sdim  VisitExpr(E);
742212795Sdim  Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
743212795Sdim}
744212795Sdim
745212795Sdimvoid ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
746212795Sdim  VisitExpr(E);
747212795Sdim  Writer.AddStmt(E->getSubExpr());
748212795Sdim  Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
749212795Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
750212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
751212795Sdim  Code = serialization::EXPR_VA_ARG;
752212795Sdim}
753212795Sdim
754212795Sdimvoid ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
755212795Sdim  VisitExpr(E);
756212795Sdim  Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
757212795Sdim  Writer.AddSourceLocation(E->getLabelLoc(), Record);
758218893Sdim  Writer.AddDeclRef(E->getLabel(), Record);
759212795Sdim  Code = serialization::EXPR_ADDR_LABEL;
760212795Sdim}
761212795Sdim
762212795Sdimvoid ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
763212795Sdim  VisitExpr(E);
764212795Sdim  Writer.AddStmt(E->getSubStmt());
765212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
766212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
767212795Sdim  Code = serialization::EXPR_STMT;
768212795Sdim}
769212795Sdim
770212795Sdimvoid ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
771212795Sdim  VisitExpr(E);
772212795Sdim  Writer.AddStmt(E->getCond());
773212795Sdim  Writer.AddStmt(E->getLHS());
774212795Sdim  Writer.AddStmt(E->getRHS());
775212795Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
776212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
777263509Sdim  Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
778212795Sdim  Code = serialization::EXPR_CHOOSE;
779212795Sdim}
780212795Sdim
781212795Sdimvoid ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
782212795Sdim  VisitExpr(E);
783212795Sdim  Writer.AddSourceLocation(E->getTokenLocation(), Record);
784212795Sdim  Code = serialization::EXPR_GNU_NULL;
785212795Sdim}
786212795Sdim
787212795Sdimvoid ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
788212795Sdim  VisitExpr(E);
789212795Sdim  Record.push_back(E->getNumSubExprs());
790212795Sdim  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
791212795Sdim    Writer.AddStmt(E->getExpr(I));
792212795Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
793212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
794212795Sdim  Code = serialization::EXPR_SHUFFLE_VECTOR;
795212795Sdim}
796212795Sdim
797263509Sdimvoid ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
798263509Sdim  VisitExpr(E);
799263509Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
800263509Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
801263509Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
802263509Sdim  Writer.AddStmt(E->getSrcExpr());
803263509Sdim  Code = serialization::EXPR_CONVERT_VECTOR;
804263509Sdim}
805263509Sdim
806212795Sdimvoid ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
807212795Sdim  VisitExpr(E);
808212795Sdim  Writer.AddDeclRef(E->getBlockDecl(), Record);
809212795Sdim  Code = serialization::EXPR_BLOCK;
810212795Sdim}
811212795Sdim
812221345Sdimvoid ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
813221345Sdim  VisitExpr(E);
814221345Sdim  Record.push_back(E->getNumAssocs());
815221345Sdim
816221345Sdim  Writer.AddStmt(E->getControllingExpr());
817221345Sdim  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
818221345Sdim    Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record);
819221345Sdim    Writer.AddStmt(E->getAssocExpr(I));
820221345Sdim  }
821221345Sdim  Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
822221345Sdim
823221345Sdim  Writer.AddSourceLocation(E->getGenericLoc(), Record);
824221345Sdim  Writer.AddSourceLocation(E->getDefaultLoc(), Record);
825221345Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
826221345Sdim  Code = serialization::EXPR_GENERIC_SELECTION;
827221345Sdim}
828221345Sdim
829235633Sdimvoid ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
830235633Sdim  VisitExpr(E);
831235633Sdim  Record.push_back(E->getNumSemanticExprs());
832235633Sdim
833235633Sdim  // Push the result index.  Currently, this needs to exactly match
834235633Sdim  // the encoding used internally for ResultIndex.
835235633Sdim  unsigned result = E->getResultExprIndex();
836235633Sdim  result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
837235633Sdim  Record.push_back(result);
838235633Sdim
839235633Sdim  Writer.AddStmt(E->getSyntacticForm());
840235633Sdim  for (PseudoObjectExpr::semantics_iterator
841235633Sdim         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
842235633Sdim    Writer.AddStmt(*i);
843235633Sdim  }
844235633Sdim  Code = serialization::EXPR_PSEUDO_OBJECT;
845235633Sdim}
846235633Sdim
847226890Sdimvoid ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
848226890Sdim  VisitExpr(E);
849226890Sdim  Record.push_back(E->getOp());
850235633Sdim  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
851235633Sdim    Writer.AddStmt(E->getSubExprs()[I]);
852226890Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
853226890Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
854235633Sdim  Code = serialization::EXPR_ATOMIC;
855226890Sdim}
856226890Sdim
857212795Sdim//===----------------------------------------------------------------------===//
858212795Sdim// Objective-C Expressions and Statements.
859212795Sdim//===----------------------------------------------------------------------===//
860212795Sdim
861212795Sdimvoid ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
862212795Sdim  VisitExpr(E);
863212795Sdim  Writer.AddStmt(E->getString());
864212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
865212795Sdim  Code = serialization::EXPR_OBJC_STRING_LITERAL;
866212795Sdim}
867212795Sdim
868245431Sdimvoid ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
869235633Sdim  VisitExpr(E);
870245431Sdim  Writer.AddStmt(E->getSubExpr());
871245431Sdim  Writer.AddDeclRef(E->getBoxingMethod(), Record);
872245431Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
873245431Sdim  Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
874235633Sdim}
875235633Sdim
876235633Sdimvoid ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
877235633Sdim  VisitExpr(E);
878235633Sdim  Record.push_back(E->getNumElements());
879235633Sdim  for (unsigned i = 0; i < E->getNumElements(); i++)
880235633Sdim    Writer.AddStmt(E->getElement(i));
881235633Sdim  Writer.AddDeclRef(E->getArrayWithObjectsMethod(), Record);
882235633Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
883235633Sdim  Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
884235633Sdim}
885235633Sdim
886235633Sdimvoid ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
887235633Sdim  VisitExpr(E);
888235633Sdim  Record.push_back(E->getNumElements());
889235633Sdim  Record.push_back(E->HasPackExpansions);
890235633Sdim  for (unsigned i = 0; i < E->getNumElements(); i++) {
891235633Sdim    ObjCDictionaryElement Element = E->getKeyValueElement(i);
892235633Sdim    Writer.AddStmt(Element.Key);
893235633Sdim    Writer.AddStmt(Element.Value);
894235633Sdim    if (E->HasPackExpansions) {
895235633Sdim      Writer.AddSourceLocation(Element.EllipsisLoc, Record);
896235633Sdim      unsigned NumExpansions = 0;
897235633Sdim      if (Element.NumExpansions)
898235633Sdim        NumExpansions = *Element.NumExpansions + 1;
899235633Sdim      Record.push_back(NumExpansions);
900235633Sdim    }
901235633Sdim  }
902235633Sdim
903235633Sdim  Writer.AddDeclRef(E->getDictWithObjectsMethod(), Record);
904235633Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
905235633Sdim  Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
906235633Sdim}
907235633Sdim
908212795Sdimvoid ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
909212795Sdim  VisitExpr(E);
910212795Sdim  Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
911212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
912212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
913212795Sdim  Code = serialization::EXPR_OBJC_ENCODE;
914212795Sdim}
915212795Sdim
916212795Sdimvoid ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
917212795Sdim  VisitExpr(E);
918212795Sdim  Writer.AddSelectorRef(E->getSelector(), Record);
919212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
920212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
921212795Sdim  Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
922212795Sdim}
923212795Sdim
924212795Sdimvoid ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
925212795Sdim  VisitExpr(E);
926212795Sdim  Writer.AddDeclRef(E->getProtocol(), Record);
927212795Sdim  Writer.AddSourceLocation(E->getAtLoc(), Record);
928245431Sdim  Writer.AddSourceLocation(E->ProtoLoc, Record);
929212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
930212795Sdim  Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
931212795Sdim}
932212795Sdim
933212795Sdimvoid ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
934212795Sdim  VisitExpr(E);
935212795Sdim  Writer.AddDeclRef(E->getDecl(), Record);
936212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
937252723Sdim  Writer.AddSourceLocation(E->getOpLoc(), Record);
938212795Sdim  Writer.AddStmt(E->getBase());
939212795Sdim  Record.push_back(E->isArrow());
940212795Sdim  Record.push_back(E->isFreeIvar());
941212795Sdim  Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
942212795Sdim}
943212795Sdim
944212795Sdimvoid ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
945212795Sdim  VisitExpr(E);
946235633Sdim  Record.push_back(E->SetterAndMethodRefFlags.getInt());
947218893Sdim  Record.push_back(E->isImplicitProperty());
948218893Sdim  if (E->isImplicitProperty()) {
949218893Sdim    Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
950218893Sdim    Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
951218893Sdim  } else {
952218893Sdim    Writer.AddDeclRef(E->getExplicitProperty(), Record);
953218893Sdim  }
954212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
955218893Sdim  Writer.AddSourceLocation(E->getReceiverLocation(), Record);
956218893Sdim  if (E->isObjectReceiver()) {
957218893Sdim    Record.push_back(0);
958218893Sdim    Writer.AddStmt(E->getBase());
959218893Sdim  } else if (E->isSuperReceiver()) {
960218893Sdim    Record.push_back(1);
961218893Sdim    Writer.AddTypeRef(E->getSuperReceiverType(), Record);
962218893Sdim  } else {
963218893Sdim    Record.push_back(2);
964218893Sdim    Writer.AddDeclRef(E->getClassReceiver(), Record);
965218893Sdim  }
966218893Sdim
967212795Sdim  Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
968212795Sdim}
969212795Sdim
970235633Sdimvoid ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
971235633Sdim  VisitExpr(E);
972235633Sdim  Writer.AddSourceLocation(E->getRBracket(), Record);
973235633Sdim  Writer.AddStmt(E->getBaseExpr());
974235633Sdim  Writer.AddStmt(E->getKeyExpr());
975235633Sdim  Writer.AddDeclRef(E->getAtIndexMethodDecl(), Record);
976235633Sdim  Writer.AddDeclRef(E->setAtIndexMethodDecl(), Record);
977235633Sdim
978235633Sdim  Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
979235633Sdim}
980235633Sdim
981212795Sdimvoid ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
982212795Sdim  VisitExpr(E);
983212795Sdim  Record.push_back(E->getNumArgs());
984226890Sdim  Record.push_back(E->getNumStoredSelLocs());
985226890Sdim  Record.push_back(E->SelLocsKind);
986224145Sdim  Record.push_back(E->isDelegateInitCall());
987235633Sdim  Record.push_back(E->IsImplicit);
988212795Sdim  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
989212795Sdim  switch (E->getReceiverKind()) {
990212795Sdim  case ObjCMessageExpr::Instance:
991212795Sdim    Writer.AddStmt(E->getInstanceReceiver());
992212795Sdim    break;
993212795Sdim
994212795Sdim  case ObjCMessageExpr::Class:
995212795Sdim    Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
996212795Sdim    break;
997212795Sdim
998212795Sdim  case ObjCMessageExpr::SuperClass:
999212795Sdim  case ObjCMessageExpr::SuperInstance:
1000212795Sdim    Writer.AddTypeRef(E->getSuperType(), Record);
1001212795Sdim    Writer.AddSourceLocation(E->getSuperLoc(), Record);
1002212795Sdim    break;
1003212795Sdim  }
1004212795Sdim
1005212795Sdim  if (E->getMethodDecl()) {
1006212795Sdim    Record.push_back(1);
1007212795Sdim    Writer.AddDeclRef(E->getMethodDecl(), Record);
1008212795Sdim  } else {
1009212795Sdim    Record.push_back(0);
1010212795Sdim    Writer.AddSelectorRef(E->getSelector(), Record);
1011212795Sdim  }
1012212795Sdim
1013212795Sdim  Writer.AddSourceLocation(E->getLeftLoc(), Record);
1014212795Sdim  Writer.AddSourceLocation(E->getRightLoc(), Record);
1015212795Sdim
1016212795Sdim  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
1017212795Sdim       Arg != ArgEnd; ++Arg)
1018212795Sdim    Writer.AddStmt(*Arg);
1019226890Sdim
1020226890Sdim  SourceLocation *Locs = E->getStoredSelLocs();
1021226890Sdim  for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
1022226890Sdim    Writer.AddSourceLocation(Locs[i], Record);
1023226890Sdim
1024212795Sdim  Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
1025212795Sdim}
1026212795Sdim
1027212795Sdimvoid ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
1028212795Sdim  VisitStmt(S);
1029212795Sdim  Writer.AddStmt(S->getElement());
1030212795Sdim  Writer.AddStmt(S->getCollection());
1031212795Sdim  Writer.AddStmt(S->getBody());
1032212795Sdim  Writer.AddSourceLocation(S->getForLoc(), Record);
1033212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
1034212795Sdim  Code = serialization::STMT_OBJC_FOR_COLLECTION;
1035212795Sdim}
1036212795Sdim
1037212795Sdimvoid ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
1038212795Sdim  Writer.AddStmt(S->getCatchBody());
1039212795Sdim  Writer.AddDeclRef(S->getCatchParamDecl(), Record);
1040212795Sdim  Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
1041212795Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
1042212795Sdim  Code = serialization::STMT_OBJC_CATCH;
1043212795Sdim}
1044212795Sdim
1045212795Sdimvoid ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
1046212795Sdim  Writer.AddStmt(S->getFinallyBody());
1047212795Sdim  Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
1048212795Sdim  Code = serialization::STMT_OBJC_FINALLY;
1049212795Sdim}
1050212795Sdim
1051224145Sdimvoid ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
1052224145Sdim  Writer.AddStmt(S->getSubStmt());
1053224145Sdim  Writer.AddSourceLocation(S->getAtLoc(), Record);
1054224145Sdim  Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
1055224145Sdim}
1056224145Sdim
1057212795Sdimvoid ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
1058212795Sdim  Record.push_back(S->getNumCatchStmts());
1059212795Sdim  Record.push_back(S->getFinallyStmt() != 0);
1060212795Sdim  Writer.AddStmt(S->getTryBody());
1061212795Sdim  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
1062212795Sdim    Writer.AddStmt(S->getCatchStmt(I));
1063212795Sdim  if (S->getFinallyStmt())
1064212795Sdim    Writer.AddStmt(S->getFinallyStmt());
1065212795Sdim  Writer.AddSourceLocation(S->getAtTryLoc(), Record);
1066212795Sdim  Code = serialization::STMT_OBJC_AT_TRY;
1067212795Sdim}
1068212795Sdim
1069212795Sdimvoid ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
1070212795Sdim  Writer.AddStmt(S->getSynchExpr());
1071212795Sdim  Writer.AddStmt(S->getSynchBody());
1072212795Sdim  Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
1073212795Sdim  Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
1074212795Sdim}
1075212795Sdim
1076212795Sdimvoid ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
1077212795Sdim  Writer.AddStmt(S->getThrowExpr());
1078212795Sdim  Writer.AddSourceLocation(S->getThrowLoc(), Record);
1079212795Sdim  Code = serialization::STMT_OBJC_AT_THROW;
1080212795Sdim}
1081212795Sdim
1082235633Sdimvoid ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
1083235633Sdim  VisitExpr(E);
1084235633Sdim  Record.push_back(E->getValue());
1085235633Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1086235633Sdim  Code = serialization::EXPR_OBJC_BOOL_LITERAL;
1087235633Sdim}
1088235633Sdim
1089212795Sdim//===----------------------------------------------------------------------===//
1090212795Sdim// C++ Expressions and Statements.
1091212795Sdim//===----------------------------------------------------------------------===//
1092212795Sdim
1093212795Sdimvoid ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
1094212795Sdim  VisitStmt(S);
1095212795Sdim  Writer.AddSourceLocation(S->getCatchLoc(), Record);
1096212795Sdim  Writer.AddDeclRef(S->getExceptionDecl(), Record);
1097212795Sdim  Writer.AddStmt(S->getHandlerBlock());
1098212795Sdim  Code = serialization::STMT_CXX_CATCH;
1099212795Sdim}
1100212795Sdim
1101212795Sdimvoid ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
1102212795Sdim  VisitStmt(S);
1103212795Sdim  Record.push_back(S->getNumHandlers());
1104212795Sdim  Writer.AddSourceLocation(S->getTryLoc(), Record);
1105212795Sdim  Writer.AddStmt(S->getTryBlock());
1106212795Sdim  for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
1107212795Sdim    Writer.AddStmt(S->getHandler(i));
1108212795Sdim  Code = serialization::STMT_CXX_TRY;
1109212795Sdim}
1110212795Sdim
1111221345Sdimvoid ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
1112221345Sdim  VisitStmt(S);
1113221345Sdim  Writer.AddSourceLocation(S->getForLoc(), Record);
1114221345Sdim  Writer.AddSourceLocation(S->getColonLoc(), Record);
1115221345Sdim  Writer.AddSourceLocation(S->getRParenLoc(), Record);
1116221345Sdim  Writer.AddStmt(S->getRangeStmt());
1117221345Sdim  Writer.AddStmt(S->getBeginEndStmt());
1118221345Sdim  Writer.AddStmt(S->getCond());
1119221345Sdim  Writer.AddStmt(S->getInc());
1120221345Sdim  Writer.AddStmt(S->getLoopVarStmt());
1121221345Sdim  Writer.AddStmt(S->getBody());
1122221345Sdim  Code = serialization::STMT_CXX_FOR_RANGE;
1123221345Sdim}
1124221345Sdim
1125235633Sdimvoid ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
1126235633Sdim  VisitStmt(S);
1127235633Sdim  Writer.AddSourceLocation(S->getKeywordLoc(), Record);
1128235633Sdim  Record.push_back(S->isIfExists());
1129235633Sdim  Writer.AddNestedNameSpecifierLoc(S->getQualifierLoc(), Record);
1130235633Sdim  Writer.AddDeclarationNameInfo(S->getNameInfo(), Record);
1131235633Sdim  Writer.AddStmt(S->getSubStmt());
1132235633Sdim  Code = serialization::STMT_MS_DEPENDENT_EXISTS;
1133235633Sdim}
1134235633Sdim
1135212795Sdimvoid ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
1136212795Sdim  VisitCallExpr(E);
1137212795Sdim  Record.push_back(E->getOperator());
1138245431Sdim  Writer.AddSourceRange(E->Range, Record);
1139245431Sdim  Record.push_back(E->isFPContractable());
1140212795Sdim  Code = serialization::EXPR_CXX_OPERATOR_CALL;
1141212795Sdim}
1142212795Sdim
1143212795Sdimvoid ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
1144212795Sdim  VisitCallExpr(E);
1145212795Sdim  Code = serialization::EXPR_CXX_MEMBER_CALL;
1146212795Sdim}
1147212795Sdim
1148212795Sdimvoid ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1149212795Sdim  VisitExpr(E);
1150212795Sdim  Record.push_back(E->getNumArgs());
1151212795Sdim  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
1152212795Sdim    Writer.AddStmt(E->getArg(I));
1153212795Sdim  Writer.AddDeclRef(E->getConstructor(), Record);
1154212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1155212795Sdim  Record.push_back(E->isElidable());
1156226890Sdim  Record.push_back(E->hadMultipleCandidates());
1157252723Sdim  Record.push_back(E->isListInitialization());
1158212795Sdim  Record.push_back(E->requiresZeroInitialization());
1159212795Sdim  Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
1160263509Sdim  Writer.AddSourceRange(E->getParenOrBraceRange(), Record);
1161212795Sdim  Code = serialization::EXPR_CXX_CONSTRUCT;
1162212795Sdim}
1163212795Sdim
1164212795Sdimvoid ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1165212795Sdim  VisitCXXConstructExpr(E);
1166218893Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
1167212795Sdim  Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
1168212795Sdim}
1169212795Sdim
1170235633Sdimvoid ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
1171235633Sdim  VisitExpr(E);
1172235633Sdim  Record.push_back(E->NumCaptures);
1173235633Sdim  unsigned NumArrayIndexVars = 0;
1174235633Sdim  if (E->HasArrayIndexVars)
1175235633Sdim    NumArrayIndexVars = E->getArrayIndexStarts()[E->NumCaptures];
1176235633Sdim  Record.push_back(NumArrayIndexVars);
1177235633Sdim  Writer.AddSourceRange(E->IntroducerRange, Record);
1178235633Sdim  Record.push_back(E->CaptureDefault); // FIXME: stable encoding
1179263509Sdim  Writer.AddSourceLocation(E->CaptureDefaultLoc, Record);
1180235633Sdim  Record.push_back(E->ExplicitParams);
1181235633Sdim  Record.push_back(E->ExplicitResultType);
1182235633Sdim  Writer.AddSourceLocation(E->ClosingBrace, Record);
1183235633Sdim
1184235633Sdim  // Add capture initializers.
1185235633Sdim  for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
1186235633Sdim                                      CEnd = E->capture_init_end();
1187235633Sdim       C != CEnd; ++C) {
1188235633Sdim    Writer.AddStmt(*C);
1189235633Sdim  }
1190235633Sdim
1191235633Sdim  // Add array index variables, if any.
1192235633Sdim  if (NumArrayIndexVars) {
1193235633Sdim    Record.append(E->getArrayIndexStarts(),
1194235633Sdim                  E->getArrayIndexStarts() + E->NumCaptures + 1);
1195235633Sdim    VarDecl **ArrayIndexVars = E->getArrayIndexVars();
1196235633Sdim    for (unsigned I = 0; I != NumArrayIndexVars; ++I)
1197235633Sdim      Writer.AddDeclRef(ArrayIndexVars[I], Record);
1198235633Sdim  }
1199235633Sdim
1200235633Sdim  Code = serialization::EXPR_LAMBDA;
1201235633Sdim}
1202235633Sdim
1203263509Sdimvoid ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
1204263509Sdim  VisitExpr(E);
1205263509Sdim  Writer.AddStmt(E->getSubExpr());
1206263509Sdim  Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
1207263509Sdim}
1208263509Sdim
1209212795Sdimvoid ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
1210212795Sdim  VisitExplicitCastExpr(E);
1211218893Sdim  Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
1212218893Sdim                        Record);
1213252723Sdim  Writer.AddSourceRange(E->getAngleBrackets(), Record);
1214212795Sdim}
1215212795Sdim
1216212795Sdimvoid ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
1217212795Sdim  VisitCXXNamedCastExpr(E);
1218212795Sdim  Code = serialization::EXPR_CXX_STATIC_CAST;
1219212795Sdim}
1220212795Sdim
1221212795Sdimvoid ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
1222212795Sdim  VisitCXXNamedCastExpr(E);
1223212795Sdim  Code = serialization::EXPR_CXX_DYNAMIC_CAST;
1224212795Sdim}
1225212795Sdim
1226212795Sdimvoid ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
1227212795Sdim  VisitCXXNamedCastExpr(E);
1228212795Sdim  Code = serialization::EXPR_CXX_REINTERPRET_CAST;
1229212795Sdim}
1230212795Sdim
1231212795Sdimvoid ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
1232212795Sdim  VisitCXXNamedCastExpr(E);
1233212795Sdim  Code = serialization::EXPR_CXX_CONST_CAST;
1234212795Sdim}
1235212795Sdim
1236212795Sdimvoid ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
1237212795Sdim  VisitExplicitCastExpr(E);
1238263509Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
1239212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1240212795Sdim  Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
1241212795Sdim}
1242212795Sdim
1243235633Sdimvoid ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
1244235633Sdim  VisitCallExpr(E);
1245235633Sdim  Writer.AddSourceLocation(E->UDSuffixLoc, Record);
1246235633Sdim  Code = serialization::EXPR_USER_DEFINED_LITERAL;
1247235633Sdim}
1248235633Sdim
1249212795Sdimvoid ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
1250212795Sdim  VisitExpr(E);
1251212795Sdim  Record.push_back(E->getValue());
1252212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1253212795Sdim  Code = serialization::EXPR_CXX_BOOL_LITERAL;
1254212795Sdim}
1255212795Sdim
1256212795Sdimvoid ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
1257212795Sdim  VisitExpr(E);
1258212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1259212795Sdim  Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
1260212795Sdim}
1261212795Sdim
1262212795Sdimvoid ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1263212795Sdim  VisitExpr(E);
1264212795Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1265212795Sdim  if (E->isTypeOperand()) {
1266212795Sdim    Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
1267212795Sdim    Code = serialization::EXPR_CXX_TYPEID_TYPE;
1268212795Sdim  } else {
1269212795Sdim    Writer.AddStmt(E->getExprOperand());
1270212795Sdim    Code = serialization::EXPR_CXX_TYPEID_EXPR;
1271212795Sdim  }
1272212795Sdim}
1273212795Sdim
1274212795Sdimvoid ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
1275212795Sdim  VisitExpr(E);
1276212795Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1277212795Sdim  Record.push_back(E->isImplicit());
1278212795Sdim  Code = serialization::EXPR_CXX_THIS;
1279212795Sdim}
1280212795Sdim
1281212795Sdimvoid ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
1282212795Sdim  VisitExpr(E);
1283212795Sdim  Writer.AddSourceLocation(E->getThrowLoc(), Record);
1284212795Sdim  Writer.AddStmt(E->getSubExpr());
1285224145Sdim  Record.push_back(E->isThrownVariableInScope());
1286212795Sdim  Code = serialization::EXPR_CXX_THROW;
1287212795Sdim}
1288212795Sdim
1289212795Sdimvoid ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
1290212795Sdim  VisitExpr(E);
1291212795Sdim
1292212795Sdim  bool HasOtherExprStored = E->Param.getInt();
1293212795Sdim  // Store these first, the reader reads them before creation.
1294212795Sdim  Record.push_back(HasOtherExprStored);
1295212795Sdim  if (HasOtherExprStored)
1296212795Sdim    Writer.AddStmt(E->getExpr());
1297212795Sdim  Writer.AddDeclRef(E->getParam(), Record);
1298212795Sdim  Writer.AddSourceLocation(E->getUsedLocation(), Record);
1299212795Sdim
1300212795Sdim  Code = serialization::EXPR_CXX_DEFAULT_ARG;
1301212795Sdim}
1302212795Sdim
1303252723Sdimvoid ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
1304252723Sdim  VisitExpr(E);
1305252723Sdim  Writer.AddDeclRef(E->getField(), Record);
1306252723Sdim  Writer.AddSourceLocation(E->getExprLoc(), Record);
1307252723Sdim  Code = serialization::EXPR_CXX_DEFAULT_INIT;
1308252723Sdim}
1309252723Sdim
1310212795Sdimvoid ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
1311212795Sdim  VisitExpr(E);
1312212795Sdim  Writer.AddCXXTemporary(E->getTemporary(), Record);
1313212795Sdim  Writer.AddStmt(E->getSubExpr());
1314212795Sdim  Code = serialization::EXPR_CXX_BIND_TEMPORARY;
1315212795Sdim}
1316212795Sdim
1317212795Sdimvoid ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1318212795Sdim  VisitExpr(E);
1319218893Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
1320212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1321212795Sdim  Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
1322212795Sdim}
1323212795Sdim
1324212795Sdimvoid ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
1325212795Sdim  VisitExpr(E);
1326212795Sdim  Record.push_back(E->isGlobalNew());
1327235633Sdim  Record.push_back(E->isArray());
1328218893Sdim  Record.push_back(E->doesUsualArrayDeleteWantSize());
1329212795Sdim  Record.push_back(E->getNumPlacementArgs());
1330235633Sdim  Record.push_back(E->StoredInitializationStyle);
1331212795Sdim  Writer.AddDeclRef(E->getOperatorNew(), Record);
1332212795Sdim  Writer.AddDeclRef(E->getOperatorDelete(), Record);
1333218893Sdim  Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
1334212795Sdim  Writer.AddSourceRange(E->getTypeIdParens(), Record);
1335245431Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1336235633Sdim  Writer.AddSourceRange(E->getDirectInitRange(), Record);
1337212795Sdim  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
1338212795Sdim       I != e; ++I)
1339212795Sdim    Writer.AddStmt(*I);
1340235633Sdim
1341212795Sdim  Code = serialization::EXPR_CXX_NEW;
1342212795Sdim}
1343212795Sdim
1344212795Sdimvoid ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1345212795Sdim  VisitExpr(E);
1346212795Sdim  Record.push_back(E->isGlobalDelete());
1347212795Sdim  Record.push_back(E->isArrayForm());
1348218893Sdim  Record.push_back(E->isArrayFormAsWritten());
1349218893Sdim  Record.push_back(E->doesUsualArrayDeleteWantSize());
1350212795Sdim  Writer.AddDeclRef(E->getOperatorDelete(), Record);
1351212795Sdim  Writer.AddStmt(E->getArgument());
1352212795Sdim  Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
1353212795Sdim
1354212795Sdim  Code = serialization::EXPR_CXX_DELETE;
1355212795Sdim}
1356212795Sdim
1357212795Sdimvoid ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1358212795Sdim  VisitExpr(E);
1359212795Sdim
1360212795Sdim  Writer.AddStmt(E->getBase());
1361212795Sdim  Record.push_back(E->isArrow());
1362212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1363219077Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1364212795Sdim  Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
1365212795Sdim  Writer.AddSourceLocation(E->getColonColonLoc(), Record);
1366212795Sdim  Writer.AddSourceLocation(E->getTildeLoc(), Record);
1367212795Sdim
1368212795Sdim  // PseudoDestructorTypeStorage.
1369212795Sdim  Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
1370212795Sdim  if (E->getDestroyedTypeIdentifier())
1371212795Sdim    Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
1372212795Sdim  else
1373212795Sdim    Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
1374212795Sdim
1375212795Sdim  Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
1376212795Sdim}
1377212795Sdim
1378218893Sdimvoid ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
1379212795Sdim  VisitExpr(E);
1380235633Sdim  Record.push_back(E->getNumObjects());
1381235633Sdim  for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
1382235633Sdim    Writer.AddDeclRef(E->getObject(i), Record);
1383212795Sdim
1384212795Sdim  Writer.AddStmt(E->getSubExpr());
1385218893Sdim  Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
1386212795Sdim}
1387212795Sdim
1388212795Sdimvoid
1389212795SdimASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
1390212795Sdim  VisitExpr(E);
1391235633Sdim
1392235633Sdim  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
1393218893Sdim  // emitted first.
1394212795Sdim
1395235633Sdim  Record.push_back(E->HasTemplateKWAndArgsInfo);
1396235633Sdim  if (E->HasTemplateKWAndArgsInfo) {
1397235633Sdim    const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
1398212795Sdim    Record.push_back(Args.NumTemplateArgs);
1399235633Sdim    AddTemplateKWAndArgsInfo(Args);
1400212795Sdim  }
1401235633Sdim
1402212795Sdim  if (!E->isImplicitAccess())
1403212795Sdim    Writer.AddStmt(E->getBase());
1404212795Sdim  else
1405212795Sdim    Writer.AddStmt(0);
1406212795Sdim  Writer.AddTypeRef(E->getBaseType(), Record);
1407212795Sdim  Record.push_back(E->isArrow());
1408212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1409221345Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1410212795Sdim  Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
1411218893Sdim  Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
1412212795Sdim  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
1413212795Sdim}
1414212795Sdim
1415212795Sdimvoid
1416212795SdimASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1417212795Sdim  VisitExpr(E);
1418235633Sdim
1419235633Sdim  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
1420218893Sdim  // emitted first.
1421235633Sdim
1422235633Sdim  Record.push_back(E->HasTemplateKWAndArgsInfo);
1423235633Sdim  if (E->HasTemplateKWAndArgsInfo) {
1424235633Sdim    const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
1425212795Sdim    Record.push_back(Args.NumTemplateArgs);
1426235633Sdim    AddTemplateKWAndArgsInfo(Args);
1427212795Sdim  }
1428212795Sdim
1429219077Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1430218893Sdim  Writer.AddDeclarationNameInfo(E->NameInfo, Record);
1431212795Sdim  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
1432212795Sdim}
1433212795Sdim
1434212795Sdimvoid
1435212795SdimASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
1436212795Sdim  VisitExpr(E);
1437212795Sdim  Record.push_back(E->arg_size());
1438212795Sdim  for (CXXUnresolvedConstructExpr::arg_iterator
1439212795Sdim         ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
1440212795Sdim    Writer.AddStmt(*ArgI);
1441218893Sdim  Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
1442212795Sdim  Writer.AddSourceLocation(E->getLParenLoc(), Record);
1443212795Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1444212795Sdim  Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
1445212795Sdim}
1446212795Sdim
1447212795Sdimvoid ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
1448212795Sdim  VisitExpr(E);
1449235633Sdim
1450235633Sdim  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
1451235633Sdim  // emitted first.
1452235633Sdim
1453235633Sdim  Record.push_back(E->HasTemplateKWAndArgsInfo);
1454235633Sdim  if (E->HasTemplateKWAndArgsInfo) {
1455235633Sdim    const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
1456212795Sdim    Record.push_back(Args.NumTemplateArgs);
1457235633Sdim    AddTemplateKWAndArgsInfo(Args);
1458212795Sdim  }
1459212795Sdim
1460212795Sdim  Record.push_back(E->getNumDecls());
1461212795Sdim  for (OverloadExpr::decls_iterator
1462212795Sdim         OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
1463212795Sdim    Writer.AddDeclRef(OvI.getDecl(), Record);
1464212795Sdim    Record.push_back(OvI.getAccess());
1465212795Sdim  }
1466212795Sdim
1467218893Sdim  Writer.AddDeclarationNameInfo(E->NameInfo, Record);
1468221345Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1469212795Sdim}
1470212795Sdim
1471212795Sdimvoid ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
1472212795Sdim  VisitOverloadExpr(E);
1473212795Sdim  Record.push_back(E->isArrow());
1474212795Sdim  Record.push_back(E->hasUnresolvedUsing());
1475212795Sdim  Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
1476212795Sdim  Writer.AddTypeRef(E->getBaseType(), Record);
1477212795Sdim  Writer.AddSourceLocation(E->getOperatorLoc(), Record);
1478212795Sdim  Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
1479212795Sdim}
1480212795Sdim
1481212795Sdimvoid ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
1482212795Sdim  VisitOverloadExpr(E);
1483212795Sdim  Record.push_back(E->requiresADL());
1484212795Sdim  Record.push_back(E->isOverloaded());
1485212795Sdim  Writer.AddDeclRef(E->getNamingClass(), Record);
1486212795Sdim  Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
1487212795Sdim}
1488212795Sdim
1489212795Sdimvoid ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
1490212795Sdim  VisitExpr(E);
1491212795Sdim  Record.push_back(E->getTrait());
1492218893Sdim  Record.push_back(E->getValue());
1493212795Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1494218893Sdim  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
1495212795Sdim  Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
1496212795Sdim}
1497212795Sdim
1498218893Sdimvoid ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
1499218893Sdim  VisitExpr(E);
1500218893Sdim  Record.push_back(E->getTrait());
1501218893Sdim  Record.push_back(E->getValue());
1502218893Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1503218893Sdim  Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
1504218893Sdim  Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
1505218893Sdim  Code = serialization::EXPR_BINARY_TYPE_TRAIT;
1506218893Sdim}
1507218893Sdim
1508235633Sdimvoid ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
1509235633Sdim  VisitExpr(E);
1510235633Sdim  Record.push_back(E->TypeTraitExprBits.NumArgs);
1511235633Sdim  Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
1512235633Sdim  Record.push_back(E->TypeTraitExprBits.Value);
1513235633Sdim  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
1514235633Sdim    Writer.AddTypeSourceInfo(E->getArg(I), Record);
1515235633Sdim  Code = serialization::EXPR_TYPE_TRAIT;
1516235633Sdim}
1517235633Sdim
1518221345Sdimvoid ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
1519221345Sdim  VisitExpr(E);
1520221345Sdim  Record.push_back(E->getTrait());
1521221345Sdim  Record.push_back(E->getValue());
1522221345Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1523221345Sdim  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
1524221345Sdim  Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
1525221345Sdim}
1526221345Sdim
1527221345Sdimvoid ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
1528221345Sdim  VisitExpr(E);
1529221345Sdim  Record.push_back(E->getTrait());
1530221345Sdim  Record.push_back(E->getValue());
1531221345Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1532221345Sdim  Writer.AddStmt(E->getQueriedExpression());
1533221345Sdim  Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
1534221345Sdim}
1535221345Sdim
1536218893Sdimvoid ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
1537218893Sdim  VisitExpr(E);
1538218893Sdim  Record.push_back(E->getValue());
1539218893Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1540218893Sdim  Writer.AddStmt(E->getOperand());
1541218893Sdim  Code = serialization::EXPR_CXX_NOEXCEPT;
1542218893Sdim}
1543218893Sdim
1544218893Sdimvoid ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
1545218893Sdim  VisitExpr(E);
1546218893Sdim  Writer.AddSourceLocation(E->getEllipsisLoc(), Record);
1547218893Sdim  Record.push_back(E->NumExpansions);
1548218893Sdim  Writer.AddStmt(E->getPattern());
1549218893Sdim  Code = serialization::EXPR_PACK_EXPANSION;
1550218893Sdim}
1551218893Sdim
1552218893Sdimvoid ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
1553218893Sdim  VisitExpr(E);
1554218893Sdim  Writer.AddSourceLocation(E->OperatorLoc, Record);
1555218893Sdim  Writer.AddSourceLocation(E->PackLoc, Record);
1556218893Sdim  Writer.AddSourceLocation(E->RParenLoc, Record);
1557218893Sdim  Record.push_back(E->Length);
1558218893Sdim  Writer.AddDeclRef(E->Pack, Record);
1559218893Sdim  Code = serialization::EXPR_SIZEOF_PACK;
1560218893Sdim}
1561218893Sdim
1562224145Sdimvoid ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
1563224145Sdim                                              SubstNonTypeTemplateParmExpr *E) {
1564224145Sdim  VisitExpr(E);
1565224145Sdim  Writer.AddDeclRef(E->getParameter(), Record);
1566224145Sdim  Writer.AddSourceLocation(E->getNameLoc(), Record);
1567224145Sdim  Writer.AddStmt(E->getReplacement());
1568224145Sdim  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
1569224145Sdim}
1570224145Sdim
1571218893Sdimvoid ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
1572218893Sdim                                          SubstNonTypeTemplateParmPackExpr *E) {
1573218893Sdim  VisitExpr(E);
1574224145Sdim  Writer.AddDeclRef(E->getParameterPack(), Record);
1575218893Sdim  Writer.AddTemplateArgument(E->getArgumentPack(), Record);
1576224145Sdim  Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
1577218893Sdim  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
1578218893Sdim}
1579218893Sdim
1580245431Sdimvoid ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
1581245431Sdim  VisitExpr(E);
1582245431Sdim  Record.push_back(E->getNumExpansions());
1583245431Sdim  Writer.AddDeclRef(E->getParameterPack(), Record);
1584245431Sdim  Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
1585245431Sdim  for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
1586245431Sdim       I != End; ++I)
1587245431Sdim    Writer.AddDeclRef(*I, Record);
1588245431Sdim  Code = serialization::EXPR_FUNCTION_PARM_PACK;
1589245431Sdim}
1590245431Sdim
1591224145Sdimvoid ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
1592224145Sdim  VisitExpr(E);
1593224145Sdim  Writer.AddStmt(E->Temporary);
1594263509Sdim  Writer.AddDeclRef(E->ExtendingDecl, Record);
1595224145Sdim  Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
1596224145Sdim}
1597224145Sdim
1598218893Sdimvoid ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
1599218893Sdim  VisitExpr(E);
1600235633Sdim  Writer.AddStmt(E->getSourceExpr());
1601218893Sdim  Writer.AddSourceLocation(E->getLocation(), Record);
1602218893Sdim  Code = serialization::EXPR_OPAQUE_VALUE;
1603218893Sdim}
1604218893Sdim
1605212795Sdim//===----------------------------------------------------------------------===//
1606218893Sdim// CUDA Expressions and Statements.
1607218893Sdim//===----------------------------------------------------------------------===//
1608218893Sdim
1609218893Sdimvoid ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
1610218893Sdim  VisitCallExpr(E);
1611218893Sdim  Writer.AddStmt(E->getConfig());
1612218893Sdim  Code = serialization::EXPR_CUDA_KERNEL_CALL;
1613218893Sdim}
1614218893Sdim
1615218893Sdim//===----------------------------------------------------------------------===//
1616223017Sdim// OpenCL Expressions and Statements.
1617223017Sdim//===----------------------------------------------------------------------===//
1618223017Sdimvoid ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
1619223017Sdim  VisitExpr(E);
1620224145Sdim  Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
1621224145Sdim  Writer.AddSourceLocation(E->getRParenLoc(), Record);
1622223017Sdim  Writer.AddStmt(E->getSrcExpr());
1623223017Sdim  Code = serialization::EXPR_ASTYPE;
1624223017Sdim}
1625223017Sdim
1626223017Sdim//===----------------------------------------------------------------------===//
1627224145Sdim// Microsoft Expressions and Statements.
1628224145Sdim//===----------------------------------------------------------------------===//
1629252723Sdimvoid ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
1630252723Sdim  VisitExpr(E);
1631252723Sdim  Record.push_back(E->isArrow());
1632252723Sdim  Writer.AddStmt(E->getBaseExpr());
1633252723Sdim  Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
1634252723Sdim  Writer.AddSourceLocation(E->getMemberLoc(), Record);
1635252723Sdim  Writer.AddDeclRef(E->getPropertyDecl(), Record);
1636252723Sdim  Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
1637252723Sdim}
1638252723Sdim
1639224145Sdimvoid ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
1640224145Sdim  VisitExpr(E);
1641224145Sdim  Writer.AddSourceRange(E->getSourceRange(), Record);
1642224145Sdim  if (E->isTypeOperand()) {
1643224145Sdim    Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
1644224145Sdim    Code = serialization::EXPR_CXX_UUIDOF_TYPE;
1645224145Sdim  } else {
1646224145Sdim    Writer.AddStmt(E->getExprOperand());
1647224145Sdim    Code = serialization::EXPR_CXX_UUIDOF_EXPR;
1648224145Sdim  }
1649224145Sdim}
1650224145Sdim
1651224145Sdimvoid ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
1652224145Sdim  VisitStmt(S);
1653224145Sdim  Writer.AddSourceLocation(S->getExceptLoc(), Record);
1654224145Sdim  Writer.AddStmt(S->getFilterExpr());
1655224145Sdim  Writer.AddStmt(S->getBlock());
1656224145Sdim  Code = serialization::STMT_SEH_EXCEPT;
1657224145Sdim}
1658224145Sdim
1659224145Sdimvoid ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
1660224145Sdim  VisitStmt(S);
1661224145Sdim  Writer.AddSourceLocation(S->getFinallyLoc(), Record);
1662224145Sdim  Writer.AddStmt(S->getBlock());
1663224145Sdim  Code = serialization::STMT_SEH_FINALLY;
1664224145Sdim}
1665224145Sdim
1666224145Sdimvoid ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
1667224145Sdim  VisitStmt(S);
1668224145Sdim  Record.push_back(S->getIsCXXTry());
1669224145Sdim  Writer.AddSourceLocation(S->getTryLoc(), Record);
1670224145Sdim  Writer.AddStmt(S->getTryBlock());
1671224145Sdim  Writer.AddStmt(S->getHandler());
1672224145Sdim  Code = serialization::STMT_SEH_TRY;
1673224145Sdim}
1674224145Sdim
1675224145Sdim//===----------------------------------------------------------------------===//
1676263509Sdim// OpenMP Clauses.
1677263509Sdim//===----------------------------------------------------------------------===//
1678263509Sdim
1679263509Sdimnamespace clang {
1680263509Sdimclass OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
1681263509Sdim  ASTStmtWriter *Writer;
1682263509Sdim  ASTWriter::RecordData &Record;
1683263509Sdimpublic:
1684263509Sdim  OMPClauseWriter(ASTStmtWriter *W, ASTWriter::RecordData &Record)
1685263509Sdim    : Writer(W), Record(Record) { }
1686263509Sdim#define OPENMP_CLAUSE(Name, Class)    \
1687263509Sdim  void Visit##Class(Class *S);
1688263509Sdim#include "clang/Basic/OpenMPKinds.def"
1689263509Sdim  void writeClause(OMPClause *C);
1690263509Sdim};
1691263509Sdim}
1692263509Sdim
1693263509Sdimvoid OMPClauseWriter::writeClause(OMPClause *C) {
1694263509Sdim  Record.push_back(C->getClauseKind());
1695263509Sdim  Visit(C);
1696263509Sdim  Writer->Writer.AddSourceLocation(C->getLocStart(), Record);
1697263509Sdim  Writer->Writer.AddSourceLocation(C->getLocEnd(), Record);
1698263509Sdim}
1699263509Sdim
1700263509Sdimvoid OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
1701263509Sdim  Record.push_back(C->getDefaultKind());
1702263509Sdim  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
1703263509Sdim  Writer->Writer.AddSourceLocation(C->getDefaultKindKwLoc(), Record);
1704263509Sdim}
1705263509Sdim
1706263509Sdimvoid OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
1707263509Sdim  Record.push_back(C->varlist_size());
1708263509Sdim  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
1709263509Sdim  for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(),
1710263509Sdim                                          E = C->varlist_end();
1711263509Sdim       I != E; ++I)
1712263509Sdim    Writer->Writer.AddStmt(*I);
1713263509Sdim}
1714263509Sdim
1715263509Sdimvoid OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
1716263509Sdim  Record.push_back(C->varlist_size());
1717263509Sdim  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
1718263509Sdim  for (OMPFirstprivateClause::varlist_iterator I = C->varlist_begin(),
1719263509Sdim                                               E = C->varlist_end();
1720263509Sdim       I != E; ++I)
1721263509Sdim    Writer->Writer.AddStmt(*I);
1722263509Sdim}
1723263509Sdim
1724263509Sdimvoid OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
1725263509Sdim  Record.push_back(C->varlist_size());
1726263509Sdim  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
1727263509Sdim  for (OMPSharedClause::varlist_iterator I = C->varlist_begin(),
1728263509Sdim                                         E = C->varlist_end();
1729263509Sdim       I != E; ++I)
1730263509Sdim    Writer->Writer.AddStmt(*I);
1731263509Sdim}
1732263509Sdim
1733263509Sdim//===----------------------------------------------------------------------===//
1734263509Sdim// OpenMP Directives.
1735263509Sdim//===----------------------------------------------------------------------===//
1736263509Sdimvoid ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
1737263509Sdim  VisitStmt(E);
1738263509Sdim  Record.push_back(E->getNumClauses());
1739263509Sdim  Writer.AddSourceLocation(E->getLocStart(), Record);
1740263509Sdim  Writer.AddSourceLocation(E->getLocEnd(), Record);
1741263509Sdim  OMPClauseWriter ClauseWriter(this, Record);
1742263509Sdim  for (unsigned i = 0; i < E->getNumClauses(); ++i) {
1743263509Sdim    ClauseWriter.writeClause(E->getClause(i));
1744263509Sdim  }
1745263509Sdim  Writer.AddStmt(E->getAssociatedStmt());
1746263509Sdim}
1747263509Sdim
1748263509Sdimvoid ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
1749263509Sdim  VisitOMPExecutableDirective(D);
1750263509Sdim  Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
1751263509Sdim}
1752263509Sdim
1753263509Sdim//===----------------------------------------------------------------------===//
1754212795Sdim// ASTWriter Implementation
1755212795Sdim//===----------------------------------------------------------------------===//
1756212795Sdim
1757212795Sdimunsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
1758212795Sdim  assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
1759212795Sdim         "SwitchCase recorded twice");
1760212795Sdim  unsigned NextID = SwitchCaseIDs.size();
1761212795Sdim  SwitchCaseIDs[S] = NextID;
1762212795Sdim  return NextID;
1763212795Sdim}
1764212795Sdim
1765212795Sdimunsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
1766212795Sdim  assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
1767212795Sdim         "SwitchCase hasn't been seen yet");
1768212795Sdim  return SwitchCaseIDs[S];
1769212795Sdim}
1770212795Sdim
1771218893Sdimvoid ASTWriter::ClearSwitchCaseIDs() {
1772218893Sdim  SwitchCaseIDs.clear();
1773218893Sdim}
1774212795Sdim
1775212795Sdim/// \brief Write the given substatement or subexpression to the
1776212795Sdim/// bitstream.
1777235633Sdimvoid ASTWriter::WriteSubStmt(Stmt *S,
1778235633Sdim                             llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
1779235633Sdim                             llvm::DenseSet<Stmt *> &ParentStmts) {
1780212795Sdim  RecordData Record;
1781212795Sdim  ASTStmtWriter Writer(*this, Record);
1782212795Sdim  ++NumStatements;
1783212795Sdim
1784212795Sdim  if (!S) {
1785212795Sdim    Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
1786212795Sdim    return;
1787212795Sdim  }
1788212795Sdim
1789235633Sdim  llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
1790235633Sdim  if (I != SubStmtEntries.end()) {
1791235633Sdim    Record.push_back(I->second);
1792235633Sdim    Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
1793235633Sdim    return;
1794235633Sdim  }
1795235633Sdim
1796235633Sdim#ifndef NDEBUG
1797235633Sdim  assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
1798235633Sdim
1799235633Sdim  struct ParentStmtInserterRAII {
1800235633Sdim    Stmt *S;
1801235633Sdim    llvm::DenseSet<Stmt *> &ParentStmts;
1802235633Sdim
1803235633Sdim    ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
1804235633Sdim      : S(S), ParentStmts(ParentStmts) {
1805235633Sdim      ParentStmts.insert(S);
1806235633Sdim    }
1807235633Sdim    ~ParentStmtInserterRAII() {
1808235633Sdim      ParentStmts.erase(S);
1809235633Sdim    }
1810235633Sdim  };
1811235633Sdim
1812235633Sdim  ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
1813235633Sdim#endif
1814235633Sdim
1815212795Sdim  // Redirect ASTWriter::AddStmt to collect sub stmts.
1816226890Sdim  SmallVector<Stmt *, 16> SubStmts;
1817212795Sdim  CollectedStmts = &SubStmts;
1818212795Sdim
1819212795Sdim  Writer.Code = serialization::STMT_NULL_PTR;
1820223017Sdim  Writer.AbbrevToUse = 0;
1821212795Sdim  Writer.Visit(S);
1822212795Sdim
1823212795Sdim#ifndef NDEBUG
1824212795Sdim  if (Writer.Code == serialization::STMT_NULL_PTR) {
1825212795Sdim    SourceManager &SrcMgr
1826212795Sdim      = DeclIDs.begin()->first->getASTContext().getSourceManager();
1827212795Sdim    S->dump(SrcMgr);
1828226890Sdim    llvm_unreachable("Unhandled sub statement writing AST file");
1829212795Sdim  }
1830212795Sdim#endif
1831212795Sdim
1832212795Sdim  // Revert ASTWriter::AddStmt.
1833212795Sdim  CollectedStmts = &StmtsToEmit;
1834212795Sdim
1835212795Sdim  // Write the sub stmts in reverse order, last to first. When reading them back
1836212795Sdim  // we will read them in correct order by "pop"ing them from the Stmts stack.
1837212795Sdim  // This simplifies reading and allows to store a variable number of sub stmts
1838212795Sdim  // without knowing it in advance.
1839212795Sdim  while (!SubStmts.empty())
1840235633Sdim    WriteSubStmt(SubStmts.pop_back_val(), SubStmtEntries, ParentStmts);
1841212795Sdim
1842223017Sdim  Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
1843235633Sdim
1844235633Sdim  SubStmtEntries[S] = Stream.GetCurrentBitNo();
1845212795Sdim}
1846212795Sdim
1847212795Sdim/// \brief Flush all of the statements that have been added to the
1848212795Sdim/// queue via AddStmt().
1849212795Sdimvoid ASTWriter::FlushStmts() {
1850212795Sdim  RecordData Record;
1851212795Sdim
1852235633Sdim  // We expect to be the only consumer of the two temporary statement maps,
1853235633Sdim  // assert that they are empty.
1854235633Sdim  assert(SubStmtEntries.empty() && "unexpected entries in sub stmt map");
1855235633Sdim  assert(ParentStmts.empty() && "unexpected entries in parent stmt map");
1856235633Sdim
1857212795Sdim  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
1858235633Sdim    WriteSubStmt(StmtsToEmit[I], SubStmtEntries, ParentStmts);
1859212795Sdim
1860212795Sdim    assert(N == StmtsToEmit.size() &&
1861221345Sdim           "Substatement written via AddStmt rather than WriteSubStmt!");
1862212795Sdim
1863212795Sdim    // Note that we are at the end of a full expression. Any
1864212795Sdim    // expression records that follow this one are part of a different
1865212795Sdim    // expression.
1866212795Sdim    Stream.EmitRecord(serialization::STMT_STOP, Record);
1867235633Sdim
1868235633Sdim    SubStmtEntries.clear();
1869235633Sdim    ParentStmts.clear();
1870212795Sdim  }
1871212795Sdim
1872212795Sdim  StmtsToEmit.clear();
1873212795Sdim}
1874