1//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// Implements serialization for Statements and Expressions.
11///
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ExprOpenMP.h"
15#include "clang/Serialization/ASTRecordWriter.h"
16#include "clang/Sema/DeclSpec.h"
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/StmtVisitor.h"
22#include "clang/Lex/Token.h"
23#include "llvm/Bitstream/BitstreamWriter.h"
24using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// Statement/expression serialization
28//===----------------------------------------------------------------------===//
29
30namespace clang {
31
32  class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
33    ASTWriter &Writer;
34    ASTRecordWriter Record;
35
36    serialization::StmtCode Code;
37    unsigned AbbrevToUse;
38
39  public:
40    ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
41        : Writer(Writer), Record(Writer, Record),
42          Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
43
44    ASTStmtWriter(const ASTStmtWriter&) = delete;
45
46    uint64_t Emit() {
47      assert(Code != serialization::STMT_NULL_PTR &&
48             "unhandled sub-statement writing AST file");
49      return Record.EmitStmt(Code, AbbrevToUse);
50    }
51
52    void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
53                                  const TemplateArgumentLoc *Args);
54
55    void VisitStmt(Stmt *S);
56#define STMT(Type, Base) \
57    void Visit##Type(Type *);
58#include "clang/AST/StmtNodes.inc"
59  };
60}
61
62void ASTStmtWriter::AddTemplateKWAndArgsInfo(
63    const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
64  Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
65  Record.AddSourceLocation(ArgInfo.LAngleLoc);
66  Record.AddSourceLocation(ArgInfo.RAngleLoc);
67  for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
68    Record.AddTemplateArgumentLoc(Args[i]);
69}
70
71void ASTStmtWriter::VisitStmt(Stmt *S) {
72}
73
74void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
75  VisitStmt(S);
76  Record.AddSourceLocation(S->getSemiLoc());
77  Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
78  Code = serialization::STMT_NULL;
79}
80
81void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
82  VisitStmt(S);
83  Record.push_back(S->size());
84  for (auto *CS : S->body())
85    Record.AddStmt(CS);
86  Record.AddSourceLocation(S->getLBracLoc());
87  Record.AddSourceLocation(S->getRBracLoc());
88  Code = serialization::STMT_COMPOUND;
89}
90
91void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
92  VisitStmt(S);
93  Record.push_back(Writer.getSwitchCaseID(S));
94  Record.AddSourceLocation(S->getKeywordLoc());
95  Record.AddSourceLocation(S->getColonLoc());
96}
97
98void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
99  VisitSwitchCase(S);
100  Record.push_back(S->caseStmtIsGNURange());
101  Record.AddStmt(S->getLHS());
102  Record.AddStmt(S->getSubStmt());
103  if (S->caseStmtIsGNURange()) {
104    Record.AddStmt(S->getRHS());
105    Record.AddSourceLocation(S->getEllipsisLoc());
106  }
107  Code = serialization::STMT_CASE;
108}
109
110void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
111  VisitSwitchCase(S);
112  Record.AddStmt(S->getSubStmt());
113  Code = serialization::STMT_DEFAULT;
114}
115
116void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
117  VisitStmt(S);
118  Record.AddDeclRef(S->getDecl());
119  Record.AddStmt(S->getSubStmt());
120  Record.AddSourceLocation(S->getIdentLoc());
121  Code = serialization::STMT_LABEL;
122}
123
124void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
125  VisitStmt(S);
126  Record.push_back(S->getAttrs().size());
127  Record.AddAttributes(S->getAttrs());
128  Record.AddStmt(S->getSubStmt());
129  Record.AddSourceLocation(S->getAttrLoc());
130  Code = serialization::STMT_ATTRIBUTED;
131}
132
133void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
134  VisitStmt(S);
135
136  bool HasElse = S->getElse() != nullptr;
137  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
138  bool HasInit = S->getInit() != nullptr;
139
140  Record.push_back(S->isConstexpr());
141  Record.push_back(HasElse);
142  Record.push_back(HasVar);
143  Record.push_back(HasInit);
144
145  Record.AddStmt(S->getCond());
146  Record.AddStmt(S->getThen());
147  if (HasElse)
148    Record.AddStmt(S->getElse());
149  if (HasVar)
150    Record.AddDeclRef(S->getConditionVariable());
151  if (HasInit)
152    Record.AddStmt(S->getInit());
153
154  Record.AddSourceLocation(S->getIfLoc());
155  if (HasElse)
156    Record.AddSourceLocation(S->getElseLoc());
157
158  Code = serialization::STMT_IF;
159}
160
161void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
162  VisitStmt(S);
163
164  bool HasInit = S->getInit() != nullptr;
165  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
166  Record.push_back(HasInit);
167  Record.push_back(HasVar);
168  Record.push_back(S->isAllEnumCasesCovered());
169
170  Record.AddStmt(S->getCond());
171  Record.AddStmt(S->getBody());
172  if (HasInit)
173    Record.AddStmt(S->getInit());
174  if (HasVar)
175    Record.AddDeclRef(S->getConditionVariable());
176
177  Record.AddSourceLocation(S->getSwitchLoc());
178
179  for (SwitchCase *SC = S->getSwitchCaseList(); SC;
180       SC = SC->getNextSwitchCase())
181    Record.push_back(Writer.RecordSwitchCaseID(SC));
182  Code = serialization::STMT_SWITCH;
183}
184
185void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
186  VisitStmt(S);
187
188  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
189  Record.push_back(HasVar);
190
191  Record.AddStmt(S->getCond());
192  Record.AddStmt(S->getBody());
193  if (HasVar)
194    Record.AddDeclRef(S->getConditionVariable());
195
196  Record.AddSourceLocation(S->getWhileLoc());
197  Record.AddSourceLocation(S->getLParenLoc());
198  Record.AddSourceLocation(S->getRParenLoc());
199  Code = serialization::STMT_WHILE;
200}
201
202void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
203  VisitStmt(S);
204  Record.AddStmt(S->getCond());
205  Record.AddStmt(S->getBody());
206  Record.AddSourceLocation(S->getDoLoc());
207  Record.AddSourceLocation(S->getWhileLoc());
208  Record.AddSourceLocation(S->getRParenLoc());
209  Code = serialization::STMT_DO;
210}
211
212void ASTStmtWriter::VisitForStmt(ForStmt *S) {
213  VisitStmt(S);
214  Record.AddStmt(S->getInit());
215  Record.AddStmt(S->getCond());
216  Record.AddDeclRef(S->getConditionVariable());
217  Record.AddStmt(S->getInc());
218  Record.AddStmt(S->getBody());
219  Record.AddSourceLocation(S->getForLoc());
220  Record.AddSourceLocation(S->getLParenLoc());
221  Record.AddSourceLocation(S->getRParenLoc());
222  Code = serialization::STMT_FOR;
223}
224
225void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
226  VisitStmt(S);
227  Record.AddDeclRef(S->getLabel());
228  Record.AddSourceLocation(S->getGotoLoc());
229  Record.AddSourceLocation(S->getLabelLoc());
230  Code = serialization::STMT_GOTO;
231}
232
233void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
234  VisitStmt(S);
235  Record.AddSourceLocation(S->getGotoLoc());
236  Record.AddSourceLocation(S->getStarLoc());
237  Record.AddStmt(S->getTarget());
238  Code = serialization::STMT_INDIRECT_GOTO;
239}
240
241void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
242  VisitStmt(S);
243  Record.AddSourceLocation(S->getContinueLoc());
244  Code = serialization::STMT_CONTINUE;
245}
246
247void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
248  VisitStmt(S);
249  Record.AddSourceLocation(S->getBreakLoc());
250  Code = serialization::STMT_BREAK;
251}
252
253void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
254  VisitStmt(S);
255
256  bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
257  Record.push_back(HasNRVOCandidate);
258
259  Record.AddStmt(S->getRetValue());
260  if (HasNRVOCandidate)
261    Record.AddDeclRef(S->getNRVOCandidate());
262
263  Record.AddSourceLocation(S->getReturnLoc());
264  Code = serialization::STMT_RETURN;
265}
266
267void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
268  VisitStmt(S);
269  Record.AddSourceLocation(S->getBeginLoc());
270  Record.AddSourceLocation(S->getEndLoc());
271  DeclGroupRef DG = S->getDeclGroup();
272  for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
273    Record.AddDeclRef(*D);
274  Code = serialization::STMT_DECL;
275}
276
277void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
278  VisitStmt(S);
279  Record.push_back(S->getNumOutputs());
280  Record.push_back(S->getNumInputs());
281  Record.push_back(S->getNumClobbers());
282  Record.AddSourceLocation(S->getAsmLoc());
283  Record.push_back(S->isVolatile());
284  Record.push_back(S->isSimple());
285}
286
287void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
288  VisitAsmStmt(S);
289  Record.push_back(S->getNumLabels());
290  Record.AddSourceLocation(S->getRParenLoc());
291  Record.AddStmt(S->getAsmString());
292
293  // Outputs
294  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
295    Record.AddIdentifierRef(S->getOutputIdentifier(I));
296    Record.AddStmt(S->getOutputConstraintLiteral(I));
297    Record.AddStmt(S->getOutputExpr(I));
298  }
299
300  // Inputs
301  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
302    Record.AddIdentifierRef(S->getInputIdentifier(I));
303    Record.AddStmt(S->getInputConstraintLiteral(I));
304    Record.AddStmt(S->getInputExpr(I));
305  }
306
307  // Clobbers
308  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
309    Record.AddStmt(S->getClobberStringLiteral(I));
310
311  // Labels
312  for (auto *E : S->labels()) Record.AddStmt(E);
313
314  Code = serialization::STMT_GCCASM;
315}
316
317void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
318  VisitAsmStmt(S);
319  Record.AddSourceLocation(S->getLBraceLoc());
320  Record.AddSourceLocation(S->getEndLoc());
321  Record.push_back(S->getNumAsmToks());
322  Record.AddString(S->getAsmString());
323
324  // Tokens
325  for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
326    // FIXME: Move this to ASTRecordWriter?
327    Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
328  }
329
330  // Clobbers
331  for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
332    Record.AddString(S->getClobber(I));
333  }
334
335  // Outputs
336  for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
337    Record.AddStmt(S->getOutputExpr(I));
338    Record.AddString(S->getOutputConstraint(I));
339  }
340
341  // Inputs
342  for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
343    Record.AddStmt(S->getInputExpr(I));
344    Record.AddString(S->getInputConstraint(I));
345  }
346
347  Code = serialization::STMT_MSASM;
348}
349
350void ASTStmtWriter::VisitCoroutineBodyStmt(CoroutineBodyStmt *CoroStmt) {
351  VisitStmt(CoroStmt);
352  Record.push_back(CoroStmt->getParamMoves().size());
353  for (Stmt *S : CoroStmt->children())
354    Record.AddStmt(S);
355  Code = serialization::STMT_COROUTINE_BODY;
356}
357
358void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
359  VisitStmt(S);
360  Record.AddSourceLocation(S->getKeywordLoc());
361  Record.AddStmt(S->getOperand());
362  Record.AddStmt(S->getPromiseCall());
363  Record.push_back(S->isImplicit());
364  Code = serialization::STMT_CORETURN;
365}
366
367void ASTStmtWriter::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) {
368  VisitExpr(E);
369  Record.AddSourceLocation(E->getKeywordLoc());
370  for (Stmt *S : E->children())
371    Record.AddStmt(S);
372  Record.AddStmt(E->getOpaqueValue());
373}
374
375void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
376  VisitCoroutineSuspendExpr(E);
377  Record.push_back(E->isImplicit());
378  Code = serialization::EXPR_COAWAIT;
379}
380
381void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
382  VisitCoroutineSuspendExpr(E);
383  Code = serialization::EXPR_COYIELD;
384}
385
386void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
387  VisitExpr(E);
388  Record.AddSourceLocation(E->getKeywordLoc());
389  for (Stmt *S : E->children())
390    Record.AddStmt(S);
391  Code = serialization::EXPR_DEPENDENT_COAWAIT;
392}
393
394static void
395addConstraintSatisfaction(ASTRecordWriter &Record,
396                          const ASTConstraintSatisfaction &Satisfaction) {
397  Record.push_back(Satisfaction.IsSatisfied);
398  if (!Satisfaction.IsSatisfied) {
399    Record.push_back(Satisfaction.NumRecords);
400    for (const auto &DetailRecord : Satisfaction) {
401      Record.AddStmt(const_cast<Expr *>(DetailRecord.first));
402      auto *E = DetailRecord.second.dyn_cast<Expr *>();
403      Record.push_back(E == nullptr);
404      if (E)
405        Record.AddStmt(E);
406      else {
407        auto *Diag = DetailRecord.second.get<std::pair<SourceLocation,
408                                                       StringRef> *>();
409        Record.AddSourceLocation(Diag->first);
410        Record.AddString(Diag->second);
411      }
412    }
413  }
414}
415
416static void
417addSubstitutionDiagnostic(
418    ASTRecordWriter &Record,
419    const concepts::Requirement::SubstitutionDiagnostic *D) {
420  Record.AddString(D->SubstitutedEntity);
421  Record.AddSourceLocation(D->DiagLoc);
422  Record.AddString(D->DiagMessage);
423}
424
425void ASTStmtWriter::VisitConceptSpecializationExpr(
426        ConceptSpecializationExpr *E) {
427  VisitExpr(E);
428  ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments();
429  Record.push_back(TemplateArgs.size());
430  Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc());
431  Record.AddSourceLocation(E->getTemplateKWLoc());
432  Record.AddDeclarationNameInfo(E->getConceptNameInfo());
433  Record.AddDeclRef(E->getNamedConcept());
434  Record.AddDeclRef(E->getFoundDecl());
435  Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
436  for (const TemplateArgument &Arg : TemplateArgs)
437    Record.AddTemplateArgument(Arg);
438  if (!E->isValueDependent())
439    addConstraintSatisfaction(Record, E->getSatisfaction());
440
441  Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
442}
443
444void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
445  VisitExpr(E);
446  Record.push_back(E->getLocalParameters().size());
447  Record.push_back(E->getRequirements().size());
448  Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
449  Record.push_back(E->RequiresExprBits.IsSatisfied);
450  Record.AddDeclRef(E->getBody());
451  for (ParmVarDecl *P : E->getLocalParameters())
452    Record.AddDeclRef(P);
453  for (concepts::Requirement *R : E->getRequirements()) {
454    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) {
455      Record.push_back(concepts::Requirement::RK_Type);
456      Record.push_back(TypeReq->Status);
457      if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure)
458        addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic());
459      else
460        Record.AddTypeSourceInfo(TypeReq->getType());
461    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
462      Record.push_back(ExprReq->getKind());
463      Record.push_back(ExprReq->Status);
464      if (ExprReq->isExprSubstitutionFailure()) {
465        addSubstitutionDiagnostic(Record,
466         ExprReq->Value.get<concepts::Requirement::SubstitutionDiagnostic *>());
467      } else
468        Record.AddStmt(ExprReq->Value.get<Expr *>());
469      if (ExprReq->getKind() == concepts::Requirement::RK_Compound) {
470        Record.AddSourceLocation(ExprReq->NoexceptLoc);
471        const auto &RetReq = ExprReq->getReturnTypeRequirement();
472        if (RetReq.isSubstitutionFailure()) {
473          Record.push_back(2);
474          addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic());
475        } else if (RetReq.isTypeConstraint()) {
476          Record.push_back(1);
477          Record.AddTemplateParameterList(
478              RetReq.getTypeConstraintTemplateParameterList());
479          if (ExprReq->Status >=
480              concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
481            Record.AddStmt(
482                ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr());
483        } else {
484          assert(RetReq.isEmpty());
485          Record.push_back(0);
486        }
487      }
488    } else {
489      auto *NestedReq = cast<concepts::NestedRequirement>(R);
490      Record.push_back(concepts::Requirement::RK_Nested);
491      Record.push_back(NestedReq->isSubstitutionFailure());
492      if (NestedReq->isSubstitutionFailure()){
493        addSubstitutionDiagnostic(Record,
494                                  NestedReq->getSubstitutionDiagnostic());
495      } else {
496        Record.AddStmt(NestedReq->Value.get<Expr *>());
497        if (!NestedReq->isDependent())
498          addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
499      }
500    }
501  }
502  Record.AddSourceLocation(E->getEndLoc());
503
504  Code = serialization::EXPR_REQUIRES;
505}
506
507
508void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
509  VisitStmt(S);
510  // NumCaptures
511  Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
512
513  // CapturedDecl and captured region kind
514  Record.AddDeclRef(S->getCapturedDecl());
515  Record.push_back(S->getCapturedRegionKind());
516
517  Record.AddDeclRef(S->getCapturedRecordDecl());
518
519  // Capture inits
520  for (auto *I : S->capture_inits())
521    Record.AddStmt(I);
522
523  // Body
524  Record.AddStmt(S->getCapturedStmt());
525
526  // Captures
527  for (const auto &I : S->captures()) {
528    if (I.capturesThis() || I.capturesVariableArrayType())
529      Record.AddDeclRef(nullptr);
530    else
531      Record.AddDeclRef(I.getCapturedVar());
532    Record.push_back(I.getCaptureKind());
533    Record.AddSourceLocation(I.getLocation());
534  }
535
536  Code = serialization::STMT_CAPTURED;
537}
538
539void ASTStmtWriter::VisitExpr(Expr *E) {
540  VisitStmt(E);
541  Record.AddTypeRef(E->getType());
542  Record.push_back(E->isTypeDependent());
543  Record.push_back(E->isValueDependent());
544  Record.push_back(E->isInstantiationDependent());
545  Record.push_back(E->containsUnexpandedParameterPack());
546  Record.push_back(E->containsErrors());
547  Record.push_back(E->getValueKind());
548  Record.push_back(E->getObjectKind());
549}
550
551void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
552  VisitExpr(E);
553  Record.push_back(E->ConstantExprBits.ResultKind);
554
555  Record.push_back(E->ConstantExprBits.APValueKind);
556  Record.push_back(E->ConstantExprBits.IsUnsigned);
557  Record.push_back(E->ConstantExprBits.BitWidth);
558  // HasCleanup not serialized since we can just query the APValue.
559  Record.push_back(E->ConstantExprBits.IsImmediateInvocation);
560
561  switch (E->ConstantExprBits.ResultKind) {
562  case ConstantExpr::RSK_None:
563    break;
564  case ConstantExpr::RSK_Int64:
565    Record.push_back(E->Int64Result());
566    break;
567  case ConstantExpr::RSK_APValue:
568    Record.AddAPValue(E->APValueResult());
569    break;
570  default:
571    llvm_unreachable("unexpected ResultKind!");
572  }
573
574  Record.AddStmt(E->getSubExpr());
575  Code = serialization::EXPR_CONSTANT;
576}
577
578void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
579  VisitExpr(E);
580
581  bool HasFunctionName = E->getFunctionName() != nullptr;
582  Record.push_back(HasFunctionName);
583  Record.push_back(E->getIdentKind()); // FIXME: stable encoding
584  Record.AddSourceLocation(E->getLocation());
585  if (HasFunctionName)
586    Record.AddStmt(E->getFunctionName());
587  Code = serialization::EXPR_PREDEFINED;
588}
589
590void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
591  VisitExpr(E);
592
593  Record.push_back(E->hasQualifier());
594  Record.push_back(E->getDecl() != E->getFoundDecl());
595  Record.push_back(E->hasTemplateKWAndArgsInfo());
596  Record.push_back(E->hadMultipleCandidates());
597  Record.push_back(E->refersToEnclosingVariableOrCapture());
598  Record.push_back(E->isNonOdrUse());
599
600  if (E->hasTemplateKWAndArgsInfo()) {
601    unsigned NumTemplateArgs = E->getNumTemplateArgs();
602    Record.push_back(NumTemplateArgs);
603  }
604
605  DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
606
607  if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
608      (E->getDecl() == E->getFoundDecl()) &&
609      nk == DeclarationName::Identifier &&
610      !E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse()) {
611    AbbrevToUse = Writer.getDeclRefExprAbbrev();
612  }
613
614  if (E->hasQualifier())
615    Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
616
617  if (E->getDecl() != E->getFoundDecl())
618    Record.AddDeclRef(E->getFoundDecl());
619
620  if (E->hasTemplateKWAndArgsInfo())
621    AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
622                             E->getTrailingObjects<TemplateArgumentLoc>());
623
624  Record.AddDeclRef(E->getDecl());
625  Record.AddSourceLocation(E->getLocation());
626  Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
627  Code = serialization::EXPR_DECL_REF;
628}
629
630void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
631  VisitExpr(E);
632  Record.AddSourceLocation(E->getLocation());
633  Record.AddAPInt(E->getValue());
634
635  if (E->getValue().getBitWidth() == 32) {
636    AbbrevToUse = Writer.getIntegerLiteralAbbrev();
637  }
638
639  Code = serialization::EXPR_INTEGER_LITERAL;
640}
641
642void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
643  VisitExpr(E);
644  Record.AddSourceLocation(E->getLocation());
645  Record.push_back(E->getScale());
646  Record.AddAPInt(E->getValue());
647  Code = serialization::EXPR_FIXEDPOINT_LITERAL;
648}
649
650void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
651  VisitExpr(E);
652  Record.push_back(E->getRawSemantics());
653  Record.push_back(E->isExact());
654  Record.AddAPFloat(E->getValue());
655  Record.AddSourceLocation(E->getLocation());
656  Code = serialization::EXPR_FLOATING_LITERAL;
657}
658
659void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
660  VisitExpr(E);
661  Record.AddStmt(E->getSubExpr());
662  Code = serialization::EXPR_IMAGINARY_LITERAL;
663}
664
665void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
666  VisitExpr(E);
667
668  // Store the various bits of data of StringLiteral.
669  Record.push_back(E->getNumConcatenated());
670  Record.push_back(E->getLength());
671  Record.push_back(E->getCharByteWidth());
672  Record.push_back(E->getKind());
673  Record.push_back(E->isPascal());
674
675  // Store the trailing array of SourceLocation.
676  for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
677    Record.AddSourceLocation(E->getStrTokenLoc(I));
678
679  // Store the trailing array of char holding the string data.
680  StringRef StrData = E->getBytes();
681  for (unsigned I = 0, N = E->getByteLength(); I != N; ++I)
682    Record.push_back(StrData[I]);
683
684  Code = serialization::EXPR_STRING_LITERAL;
685}
686
687void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
688  VisitExpr(E);
689  Record.push_back(E->getValue());
690  Record.AddSourceLocation(E->getLocation());
691  Record.push_back(E->getKind());
692
693  AbbrevToUse = Writer.getCharacterLiteralAbbrev();
694
695  Code = serialization::EXPR_CHARACTER_LITERAL;
696}
697
698void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
699  VisitExpr(E);
700  Record.AddSourceLocation(E->getLParen());
701  Record.AddSourceLocation(E->getRParen());
702  Record.AddStmt(E->getSubExpr());
703  Code = serialization::EXPR_PAREN;
704}
705
706void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
707  VisitExpr(E);
708  Record.push_back(E->getNumExprs());
709  for (auto *SubStmt : E->exprs())
710    Record.AddStmt(SubStmt);
711  Record.AddSourceLocation(E->getLParenLoc());
712  Record.AddSourceLocation(E->getRParenLoc());
713  Code = serialization::EXPR_PAREN_LIST;
714}
715
716void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
717  VisitExpr(E);
718  bool HasFPFeatures = E->hasStoredFPFeatures();
719  // Write this first for easy access when deserializing, as they affect the
720  // size of the UnaryOperator.
721  Record.push_back(HasFPFeatures);
722  Record.AddStmt(E->getSubExpr());
723  Record.push_back(E->getOpcode()); // FIXME: stable encoding
724  Record.AddSourceLocation(E->getOperatorLoc());
725  Record.push_back(E->canOverflow());
726  if (HasFPFeatures)
727    Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
728  Code = serialization::EXPR_UNARY_OPERATOR;
729}
730
731void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
732  VisitExpr(E);
733  Record.push_back(E->getNumComponents());
734  Record.push_back(E->getNumExpressions());
735  Record.AddSourceLocation(E->getOperatorLoc());
736  Record.AddSourceLocation(E->getRParenLoc());
737  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
738  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
739    const OffsetOfNode &ON = E->getComponent(I);
740    Record.push_back(ON.getKind()); // FIXME: Stable encoding
741    Record.AddSourceLocation(ON.getSourceRange().getBegin());
742    Record.AddSourceLocation(ON.getSourceRange().getEnd());
743    switch (ON.getKind()) {
744    case OffsetOfNode::Array:
745      Record.push_back(ON.getArrayExprIndex());
746      break;
747
748    case OffsetOfNode::Field:
749      Record.AddDeclRef(ON.getField());
750      break;
751
752    case OffsetOfNode::Identifier:
753      Record.AddIdentifierRef(ON.getFieldName());
754      break;
755
756    case OffsetOfNode::Base:
757      Record.AddCXXBaseSpecifier(*ON.getBase());
758      break;
759    }
760  }
761  for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
762    Record.AddStmt(E->getIndexExpr(I));
763  Code = serialization::EXPR_OFFSETOF;
764}
765
766void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
767  VisitExpr(E);
768  Record.push_back(E->getKind());
769  if (E->isArgumentType())
770    Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
771  else {
772    Record.push_back(0);
773    Record.AddStmt(E->getArgumentExpr());
774  }
775  Record.AddSourceLocation(E->getOperatorLoc());
776  Record.AddSourceLocation(E->getRParenLoc());
777  Code = serialization::EXPR_SIZEOF_ALIGN_OF;
778}
779
780void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
781  VisitExpr(E);
782  Record.AddStmt(E->getLHS());
783  Record.AddStmt(E->getRHS());
784  Record.AddSourceLocation(E->getRBracketLoc());
785  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
786}
787
788void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
789  VisitExpr(E);
790  Record.AddStmt(E->getBase());
791  Record.AddStmt(E->getRowIdx());
792  Record.AddStmt(E->getColumnIdx());
793  Record.AddSourceLocation(E->getRBracketLoc());
794  Code = serialization::EXPR_ARRAY_SUBSCRIPT;
795}
796
797void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
798  VisitExpr(E);
799  Record.AddStmt(E->getBase());
800  Record.AddStmt(E->getLowerBound());
801  Record.AddStmt(E->getLength());
802  Record.AddStmt(E->getStride());
803  Record.AddSourceLocation(E->getColonLocFirst());
804  Record.AddSourceLocation(E->getColonLocSecond());
805  Record.AddSourceLocation(E->getRBracketLoc());
806  Code = serialization::EXPR_OMP_ARRAY_SECTION;
807}
808
809void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
810  VisitExpr(E);
811  Record.push_back(E->getDimensions().size());
812  Record.AddStmt(E->getBase());
813  for (Expr *Dim : E->getDimensions())
814    Record.AddStmt(Dim);
815  for (SourceRange SR : E->getBracketsRanges())
816    Record.AddSourceRange(SR);
817  Record.AddSourceLocation(E->getLParenLoc());
818  Record.AddSourceLocation(E->getRParenLoc());
819  Code = serialization::EXPR_OMP_ARRAY_SHAPING;
820}
821
822void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
823  VisitExpr(E);
824  Record.push_back(E->numOfIterators());
825  Record.AddSourceLocation(E->getIteratorKwLoc());
826  Record.AddSourceLocation(E->getLParenLoc());
827  Record.AddSourceLocation(E->getRParenLoc());
828  for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
829    Record.AddDeclRef(E->getIteratorDecl(I));
830    Record.AddSourceLocation(E->getAssignLoc(I));
831    OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
832    Record.AddStmt(Range.Begin);
833    Record.AddStmt(Range.End);
834    Record.AddStmt(Range.Step);
835    Record.AddSourceLocation(E->getColonLoc(I));
836    if (Range.Step)
837      Record.AddSourceLocation(E->getSecondColonLoc(I));
838    // Serialize helpers
839    OMPIteratorHelperData &HD = E->getHelper(I);
840    Record.AddDeclRef(HD.CounterVD);
841    Record.AddStmt(HD.Upper);
842    Record.AddStmt(HD.Update);
843    Record.AddStmt(HD.CounterUpdate);
844  }
845  Code = serialization::EXPR_OMP_ITERATOR;
846}
847
848void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
849  VisitExpr(E);
850  Record.push_back(E->getNumArgs());
851  Record.AddSourceLocation(E->getRParenLoc());
852  Record.AddStmt(E->getCallee());
853  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
854       Arg != ArgEnd; ++Arg)
855    Record.AddStmt(*Arg);
856  Record.push_back(static_cast<unsigned>(E->getADLCallKind()));
857  Code = serialization::EXPR_CALL;
858}
859
860void ASTStmtWriter::VisitRecoveryExpr(RecoveryExpr *E) {
861  VisitExpr(E);
862  Record.push_back(std::distance(E->children().begin(), E->children().end()));
863  Record.AddSourceLocation(E->getBeginLoc());
864  Record.AddSourceLocation(E->getEndLoc());
865  for (Stmt *Child : E->children())
866    Record.AddStmt(Child);
867  Code = serialization::EXPR_RECOVERY;
868}
869
870void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
871  VisitExpr(E);
872
873  bool HasQualifier = E->hasQualifier();
874  bool HasFoundDecl =
875      E->hasQualifierOrFoundDecl() &&
876      (E->getFoundDecl().getDecl() != E->getMemberDecl() ||
877       E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess());
878  bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
879  unsigned NumTemplateArgs = E->getNumTemplateArgs();
880
881  // Write these first for easy access when deserializing, as they affect the
882  // size of the MemberExpr.
883  Record.push_back(HasQualifier);
884  Record.push_back(HasFoundDecl);
885  Record.push_back(HasTemplateInfo);
886  Record.push_back(NumTemplateArgs);
887
888  Record.AddStmt(E->getBase());
889  Record.AddDeclRef(E->getMemberDecl());
890  Record.AddDeclarationNameLoc(E->MemberDNLoc,
891                               E->getMemberDecl()->getDeclName());
892  Record.AddSourceLocation(E->getMemberLoc());
893  Record.push_back(E->isArrow());
894  Record.push_back(E->hadMultipleCandidates());
895  Record.push_back(E->isNonOdrUse());
896  Record.AddSourceLocation(E->getOperatorLoc());
897
898  if (HasFoundDecl) {
899    DeclAccessPair FoundDecl = E->getFoundDecl();
900    Record.AddDeclRef(FoundDecl.getDecl());
901    Record.push_back(FoundDecl.getAccess());
902  }
903
904  if (HasQualifier)
905    Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
906
907  if (HasTemplateInfo)
908    AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
909                             E->getTrailingObjects<TemplateArgumentLoc>());
910
911  Code = serialization::EXPR_MEMBER;
912}
913
914void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
915  VisitExpr(E);
916  Record.AddStmt(E->getBase());
917  Record.AddSourceLocation(E->getIsaMemberLoc());
918  Record.AddSourceLocation(E->getOpLoc());
919  Record.push_back(E->isArrow());
920  Code = serialization::EXPR_OBJC_ISA;
921}
922
923void ASTStmtWriter::
924VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
925  VisitExpr(E);
926  Record.AddStmt(E->getSubExpr());
927  Record.push_back(E->shouldCopy());
928  Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
929}
930
931void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
932  VisitExplicitCastExpr(E);
933  Record.AddSourceLocation(E->getLParenLoc());
934  Record.AddSourceLocation(E->getBridgeKeywordLoc());
935  Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
936  Code = serialization::EXPR_OBJC_BRIDGED_CAST;
937}
938
939void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
940  VisitExpr(E);
941  Record.push_back(E->path_size());
942  Record.AddStmt(E->getSubExpr());
943  Record.push_back(E->getCastKind()); // FIXME: stable encoding
944
945  for (CastExpr::path_iterator
946         PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
947    Record.AddCXXBaseSpecifier(**PI);
948}
949
950void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
951  VisitExpr(E);
952  bool HasFPFeatures = E->hasStoredFPFeatures();
953  // Write this first for easy access when deserializing, as they affect the
954  // size of the UnaryOperator.
955  Record.push_back(HasFPFeatures);
956  Record.push_back(E->getOpcode()); // FIXME: stable encoding
957  Record.AddStmt(E->getLHS());
958  Record.AddStmt(E->getRHS());
959  Record.AddSourceLocation(E->getOperatorLoc());
960  if (HasFPFeatures)
961    Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
962  Code = serialization::EXPR_BINARY_OPERATOR;
963}
964
965void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
966  VisitBinaryOperator(E);
967  Record.AddTypeRef(E->getComputationLHSType());
968  Record.AddTypeRef(E->getComputationResultType());
969  Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
970}
971
972void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
973  VisitExpr(E);
974  Record.AddStmt(E->getCond());
975  Record.AddStmt(E->getLHS());
976  Record.AddStmt(E->getRHS());
977  Record.AddSourceLocation(E->getQuestionLoc());
978  Record.AddSourceLocation(E->getColonLoc());
979  Code = serialization::EXPR_CONDITIONAL_OPERATOR;
980}
981
982void
983ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
984  VisitExpr(E);
985  Record.AddStmt(E->getOpaqueValue());
986  Record.AddStmt(E->getCommon());
987  Record.AddStmt(E->getCond());
988  Record.AddStmt(E->getTrueExpr());
989  Record.AddStmt(E->getFalseExpr());
990  Record.AddSourceLocation(E->getQuestionLoc());
991  Record.AddSourceLocation(E->getColonLoc());
992  Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
993}
994
995void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
996  VisitCastExpr(E);
997  Record.push_back(E->isPartOfExplicitCast());
998
999  if (E->path_size() == 0)
1000    AbbrevToUse = Writer.getExprImplicitCastAbbrev();
1001
1002  Code = serialization::EXPR_IMPLICIT_CAST;
1003}
1004
1005void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
1006  VisitCastExpr(E);
1007  Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
1008}
1009
1010void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
1011  VisitExplicitCastExpr(E);
1012  Record.AddSourceLocation(E->getLParenLoc());
1013  Record.AddSourceLocation(E->getRParenLoc());
1014  Code = serialization::EXPR_CSTYLE_CAST;
1015}
1016
1017void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
1018  VisitExpr(E);
1019  Record.AddSourceLocation(E->getLParenLoc());
1020  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
1021  Record.AddStmt(E->getInitializer());
1022  Record.push_back(E->isFileScope());
1023  Code = serialization::EXPR_COMPOUND_LITERAL;
1024}
1025
1026void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
1027  VisitExpr(E);
1028  Record.AddStmt(E->getBase());
1029  Record.AddIdentifierRef(&E->getAccessor());
1030  Record.AddSourceLocation(E->getAccessorLoc());
1031  Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
1032}
1033
1034void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
1035  VisitExpr(E);
1036  // NOTE: only add the (possibly null) syntactic form.
1037  // No need to serialize the isSemanticForm flag and the semantic form.
1038  Record.AddStmt(E->getSyntacticForm());
1039  Record.AddSourceLocation(E->getLBraceLoc());
1040  Record.AddSourceLocation(E->getRBraceLoc());
1041  bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
1042  Record.push_back(isArrayFiller);
1043  if (isArrayFiller)
1044    Record.AddStmt(E->getArrayFiller());
1045  else
1046    Record.AddDeclRef(E->getInitializedFieldInUnion());
1047  Record.push_back(E->hadArrayRangeDesignator());
1048  Record.push_back(E->getNumInits());
1049  if (isArrayFiller) {
1050    // ArrayFiller may have filled "holes" due to designated initializer.
1051    // Replace them by 0 to indicate that the filler goes in that place.
1052    Expr *filler = E->getArrayFiller();
1053    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
1054      Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
1055  } else {
1056    for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
1057      Record.AddStmt(E->getInit(I));
1058  }
1059  Code = serialization::EXPR_INIT_LIST;
1060}
1061
1062void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
1063  VisitExpr(E);
1064  Record.push_back(E->getNumSubExprs());
1065  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
1066    Record.AddStmt(E->getSubExpr(I));
1067  Record.AddSourceLocation(E->getEqualOrColonLoc());
1068  Record.push_back(E->usesGNUSyntax());
1069  for (const DesignatedInitExpr::Designator &D : E->designators()) {
1070    if (D.isFieldDesignator()) {
1071      if (FieldDecl *Field = D.getField()) {
1072        Record.push_back(serialization::DESIG_FIELD_DECL);
1073        Record.AddDeclRef(Field);
1074      } else {
1075        Record.push_back(serialization::DESIG_FIELD_NAME);
1076        Record.AddIdentifierRef(D.getFieldName());
1077      }
1078      Record.AddSourceLocation(D.getDotLoc());
1079      Record.AddSourceLocation(D.getFieldLoc());
1080    } else if (D.isArrayDesignator()) {
1081      Record.push_back(serialization::DESIG_ARRAY);
1082      Record.push_back(D.getFirstExprIndex());
1083      Record.AddSourceLocation(D.getLBracketLoc());
1084      Record.AddSourceLocation(D.getRBracketLoc());
1085    } else {
1086      assert(D.isArrayRangeDesignator() && "Unknown designator");
1087      Record.push_back(serialization::DESIG_ARRAY_RANGE);
1088      Record.push_back(D.getFirstExprIndex());
1089      Record.AddSourceLocation(D.getLBracketLoc());
1090      Record.AddSourceLocation(D.getEllipsisLoc());
1091      Record.AddSourceLocation(D.getRBracketLoc());
1092    }
1093  }
1094  Code = serialization::EXPR_DESIGNATED_INIT;
1095}
1096
1097void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
1098  VisitExpr(E);
1099  Record.AddStmt(E->getBase());
1100  Record.AddStmt(E->getUpdater());
1101  Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
1102}
1103
1104void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
1105  VisitExpr(E);
1106  Code = serialization::EXPR_NO_INIT;
1107}
1108
1109void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
1110  VisitExpr(E);
1111  Record.AddStmt(E->SubExprs[0]);
1112  Record.AddStmt(E->SubExprs[1]);
1113  Code = serialization::EXPR_ARRAY_INIT_LOOP;
1114}
1115
1116void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
1117  VisitExpr(E);
1118  Code = serialization::EXPR_ARRAY_INIT_INDEX;
1119}
1120
1121void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
1122  VisitExpr(E);
1123  Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
1124}
1125
1126void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
1127  VisitExpr(E);
1128  Record.AddStmt(E->getSubExpr());
1129  Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
1130  Record.AddSourceLocation(E->getBuiltinLoc());
1131  Record.AddSourceLocation(E->getRParenLoc());
1132  Record.push_back(E->isMicrosoftABI());
1133  Code = serialization::EXPR_VA_ARG;
1134}
1135
1136void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
1137  VisitExpr(E);
1138  Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
1139  Record.AddSourceLocation(E->getBeginLoc());
1140  Record.AddSourceLocation(E->getEndLoc());
1141  Record.push_back(E->getIdentKind());
1142  Code = serialization::EXPR_SOURCE_LOC;
1143}
1144
1145void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
1146  VisitExpr(E);
1147  Record.AddSourceLocation(E->getAmpAmpLoc());
1148  Record.AddSourceLocation(E->getLabelLoc());
1149  Record.AddDeclRef(E->getLabel());
1150  Code = serialization::EXPR_ADDR_LABEL;
1151}
1152
1153void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
1154  VisitExpr(E);
1155  Record.AddStmt(E->getSubStmt());
1156  Record.AddSourceLocation(E->getLParenLoc());
1157  Record.AddSourceLocation(E->getRParenLoc());
1158  Record.push_back(E->getTemplateDepth());
1159  Code = serialization::EXPR_STMT;
1160}
1161
1162void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
1163  VisitExpr(E);
1164  Record.AddStmt(E->getCond());
1165  Record.AddStmt(E->getLHS());
1166  Record.AddStmt(E->getRHS());
1167  Record.AddSourceLocation(E->getBuiltinLoc());
1168  Record.AddSourceLocation(E->getRParenLoc());
1169  Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
1170  Code = serialization::EXPR_CHOOSE;
1171}
1172
1173void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
1174  VisitExpr(E);
1175  Record.AddSourceLocation(E->getTokenLocation());
1176  Code = serialization::EXPR_GNU_NULL;
1177}
1178
1179void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
1180  VisitExpr(E);
1181  Record.push_back(E->getNumSubExprs());
1182  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
1183    Record.AddStmt(E->getExpr(I));
1184  Record.AddSourceLocation(E->getBuiltinLoc());
1185  Record.AddSourceLocation(E->getRParenLoc());
1186  Code = serialization::EXPR_SHUFFLE_VECTOR;
1187}
1188
1189void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
1190  VisitExpr(E);
1191  Record.AddSourceLocation(E->getBuiltinLoc());
1192  Record.AddSourceLocation(E->getRParenLoc());
1193  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
1194  Record.AddStmt(E->getSrcExpr());
1195  Code = serialization::EXPR_CONVERT_VECTOR;
1196}
1197
1198void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
1199  VisitExpr(E);
1200  Record.AddDeclRef(E->getBlockDecl());
1201  Code = serialization::EXPR_BLOCK;
1202}
1203
1204void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
1205  VisitExpr(E);
1206
1207  Record.push_back(E->getNumAssocs());
1208  Record.push_back(E->ResultIndex);
1209  Record.AddSourceLocation(E->getGenericLoc());
1210  Record.AddSourceLocation(E->getDefaultLoc());
1211  Record.AddSourceLocation(E->getRParenLoc());
1212
1213  Stmt **Stmts = E->getTrailingObjects<Stmt *>();
1214  // Add 1 to account for the controlling expression which is the first
1215  // expression in the trailing array of Stmt *. This is not needed for
1216  // the trailing array of TypeSourceInfo *.
1217  for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
1218    Record.AddStmt(Stmts[I]);
1219
1220  TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
1221  for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
1222    Record.AddTypeSourceInfo(TSIs[I]);
1223
1224  Code = serialization::EXPR_GENERIC_SELECTION;
1225}
1226
1227void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
1228  VisitExpr(E);
1229  Record.push_back(E->getNumSemanticExprs());
1230
1231  // Push the result index.  Currently, this needs to exactly match
1232  // the encoding used internally for ResultIndex.
1233  unsigned result = E->getResultExprIndex();
1234  result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
1235  Record.push_back(result);
1236
1237  Record.AddStmt(E->getSyntacticForm());
1238  for (PseudoObjectExpr::semantics_iterator
1239         i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
1240    Record.AddStmt(*i);
1241  }
1242  Code = serialization::EXPR_PSEUDO_OBJECT;
1243}
1244
1245void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
1246  VisitExpr(E);
1247  Record.push_back(E->getOp());
1248  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
1249    Record.AddStmt(E->getSubExprs()[I]);
1250  Record.AddSourceLocation(E->getBuiltinLoc());
1251  Record.AddSourceLocation(E->getRParenLoc());
1252  Code = serialization::EXPR_ATOMIC;
1253}
1254
1255//===----------------------------------------------------------------------===//
1256// Objective-C Expressions and Statements.
1257//===----------------------------------------------------------------------===//
1258
1259void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
1260  VisitExpr(E);
1261  Record.AddStmt(E->getString());
1262  Record.AddSourceLocation(E->getAtLoc());
1263  Code = serialization::EXPR_OBJC_STRING_LITERAL;
1264}
1265
1266void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
1267  VisitExpr(E);
1268  Record.AddStmt(E->getSubExpr());
1269  Record.AddDeclRef(E->getBoxingMethod());
1270  Record.AddSourceRange(E->getSourceRange());
1271  Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
1272}
1273
1274void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
1275  VisitExpr(E);
1276  Record.push_back(E->getNumElements());
1277  for (unsigned i = 0; i < E->getNumElements(); i++)
1278    Record.AddStmt(E->getElement(i));
1279  Record.AddDeclRef(E->getArrayWithObjectsMethod());
1280  Record.AddSourceRange(E->getSourceRange());
1281  Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
1282}
1283
1284void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
1285  VisitExpr(E);
1286  Record.push_back(E->getNumElements());
1287  Record.push_back(E->HasPackExpansions);
1288  for (unsigned i = 0; i < E->getNumElements(); i++) {
1289    ObjCDictionaryElement Element = E->getKeyValueElement(i);
1290    Record.AddStmt(Element.Key);
1291    Record.AddStmt(Element.Value);
1292    if (E->HasPackExpansions) {
1293      Record.AddSourceLocation(Element.EllipsisLoc);
1294      unsigned NumExpansions = 0;
1295      if (Element.NumExpansions)
1296        NumExpansions = *Element.NumExpansions + 1;
1297      Record.push_back(NumExpansions);
1298    }
1299  }
1300
1301  Record.AddDeclRef(E->getDictWithObjectsMethod());
1302  Record.AddSourceRange(E->getSourceRange());
1303  Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
1304}
1305
1306void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
1307  VisitExpr(E);
1308  Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
1309  Record.AddSourceLocation(E->getAtLoc());
1310  Record.AddSourceLocation(E->getRParenLoc());
1311  Code = serialization::EXPR_OBJC_ENCODE;
1312}
1313
1314void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
1315  VisitExpr(E);
1316  Record.AddSelectorRef(E->getSelector());
1317  Record.AddSourceLocation(E->getAtLoc());
1318  Record.AddSourceLocation(E->getRParenLoc());
1319  Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
1320}
1321
1322void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
1323  VisitExpr(E);
1324  Record.AddDeclRef(E->getProtocol());
1325  Record.AddSourceLocation(E->getAtLoc());
1326  Record.AddSourceLocation(E->ProtoLoc);
1327  Record.AddSourceLocation(E->getRParenLoc());
1328  Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
1329}
1330
1331void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
1332  VisitExpr(E);
1333  Record.AddDeclRef(E->getDecl());
1334  Record.AddSourceLocation(E->getLocation());
1335  Record.AddSourceLocation(E->getOpLoc());
1336  Record.AddStmt(E->getBase());
1337  Record.push_back(E->isArrow());
1338  Record.push_back(E->isFreeIvar());
1339  Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
1340}
1341
1342void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
1343  VisitExpr(E);
1344  Record.push_back(E->SetterAndMethodRefFlags.getInt());
1345  Record.push_back(E->isImplicitProperty());
1346  if (E->isImplicitProperty()) {
1347    Record.AddDeclRef(E->getImplicitPropertyGetter());
1348    Record.AddDeclRef(E->getImplicitPropertySetter());
1349  } else {
1350    Record.AddDeclRef(E->getExplicitProperty());
1351  }
1352  Record.AddSourceLocation(E->getLocation());
1353  Record.AddSourceLocation(E->getReceiverLocation());
1354  if (E->isObjectReceiver()) {
1355    Record.push_back(0);
1356    Record.AddStmt(E->getBase());
1357  } else if (E->isSuperReceiver()) {
1358    Record.push_back(1);
1359    Record.AddTypeRef(E->getSuperReceiverType());
1360  } else {
1361    Record.push_back(2);
1362    Record.AddDeclRef(E->getClassReceiver());
1363  }
1364
1365  Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
1366}
1367
1368void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
1369  VisitExpr(E);
1370  Record.AddSourceLocation(E->getRBracket());
1371  Record.AddStmt(E->getBaseExpr());
1372  Record.AddStmt(E->getKeyExpr());
1373  Record.AddDeclRef(E->getAtIndexMethodDecl());
1374  Record.AddDeclRef(E->setAtIndexMethodDecl());
1375
1376  Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
1377}
1378
1379void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
1380  VisitExpr(E);
1381  Record.push_back(E->getNumArgs());
1382  Record.push_back(E->getNumStoredSelLocs());
1383  Record.push_back(E->SelLocsKind);
1384  Record.push_back(E->isDelegateInitCall());
1385  Record.push_back(E->IsImplicit);
1386  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
1387  switch (E->getReceiverKind()) {
1388  case ObjCMessageExpr::Instance:
1389    Record.AddStmt(E->getInstanceReceiver());
1390    break;
1391
1392  case ObjCMessageExpr::Class:
1393    Record.AddTypeSourceInfo(E->getClassReceiverTypeInfo());
1394    break;
1395
1396  case ObjCMessageExpr::SuperClass:
1397  case ObjCMessageExpr::SuperInstance:
1398    Record.AddTypeRef(E->getSuperType());
1399    Record.AddSourceLocation(E->getSuperLoc());
1400    break;
1401  }
1402
1403  if (E->getMethodDecl()) {
1404    Record.push_back(1);
1405    Record.AddDeclRef(E->getMethodDecl());
1406  } else {
1407    Record.push_back(0);
1408    Record.AddSelectorRef(E->getSelector());
1409  }
1410
1411  Record.AddSourceLocation(E->getLeftLoc());
1412  Record.AddSourceLocation(E->getRightLoc());
1413
1414  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
1415       Arg != ArgEnd; ++Arg)
1416    Record.AddStmt(*Arg);
1417
1418  SourceLocation *Locs = E->getStoredSelLocs();
1419  for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
1420    Record.AddSourceLocation(Locs[i]);
1421
1422  Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
1423}
1424
1425void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
1426  VisitStmt(S);
1427  Record.AddStmt(S->getElement());
1428  Record.AddStmt(S->getCollection());
1429  Record.AddStmt(S->getBody());
1430  Record.AddSourceLocation(S->getForLoc());
1431  Record.AddSourceLocation(S->getRParenLoc());
1432  Code = serialization::STMT_OBJC_FOR_COLLECTION;
1433}
1434
1435void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
1436  VisitStmt(S);
1437  Record.AddStmt(S->getCatchBody());
1438  Record.AddDeclRef(S->getCatchParamDecl());
1439  Record.AddSourceLocation(S->getAtCatchLoc());
1440  Record.AddSourceLocation(S->getRParenLoc());
1441  Code = serialization::STMT_OBJC_CATCH;
1442}
1443
1444void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
1445  VisitStmt(S);
1446  Record.AddStmt(S->getFinallyBody());
1447  Record.AddSourceLocation(S->getAtFinallyLoc());
1448  Code = serialization::STMT_OBJC_FINALLY;
1449}
1450
1451void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
1452  VisitStmt(S); // FIXME: no test coverage.
1453  Record.AddStmt(S->getSubStmt());
1454  Record.AddSourceLocation(S->getAtLoc());
1455  Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
1456}
1457
1458void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
1459  VisitStmt(S);
1460  Record.push_back(S->getNumCatchStmts());
1461  Record.push_back(S->getFinallyStmt() != nullptr);
1462  Record.AddStmt(S->getTryBody());
1463  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
1464    Record.AddStmt(S->getCatchStmt(I));
1465  if (S->getFinallyStmt())
1466    Record.AddStmt(S->getFinallyStmt());
1467  Record.AddSourceLocation(S->getAtTryLoc());
1468  Code = serialization::STMT_OBJC_AT_TRY;
1469}
1470
1471void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
1472  VisitStmt(S); // FIXME: no test coverage.
1473  Record.AddStmt(S->getSynchExpr());
1474  Record.AddStmt(S->getSynchBody());
1475  Record.AddSourceLocation(S->getAtSynchronizedLoc());
1476  Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
1477}
1478
1479void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
1480  VisitStmt(S); // FIXME: no test coverage.
1481  Record.AddStmt(S->getThrowExpr());
1482  Record.AddSourceLocation(S->getThrowLoc());
1483  Code = serialization::STMT_OBJC_AT_THROW;
1484}
1485
1486void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
1487  VisitExpr(E);
1488  Record.push_back(E->getValue());
1489  Record.AddSourceLocation(E->getLocation());
1490  Code = serialization::EXPR_OBJC_BOOL_LITERAL;
1491}
1492
1493void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
1494  VisitExpr(E);
1495  Record.AddSourceRange(E->getSourceRange());
1496  Record.AddVersionTuple(E->getVersion());
1497  Code = serialization::EXPR_OBJC_AVAILABILITY_CHECK;
1498}
1499
1500//===----------------------------------------------------------------------===//
1501// C++ Expressions and Statements.
1502//===----------------------------------------------------------------------===//
1503
1504void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
1505  VisitStmt(S);
1506  Record.AddSourceLocation(S->getCatchLoc());
1507  Record.AddDeclRef(S->getExceptionDecl());
1508  Record.AddStmt(S->getHandlerBlock());
1509  Code = serialization::STMT_CXX_CATCH;
1510}
1511
1512void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
1513  VisitStmt(S);
1514  Record.push_back(S->getNumHandlers());
1515  Record.AddSourceLocation(S->getTryLoc());
1516  Record.AddStmt(S->getTryBlock());
1517  for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
1518    Record.AddStmt(S->getHandler(i));
1519  Code = serialization::STMT_CXX_TRY;
1520}
1521
1522void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
1523  VisitStmt(S);
1524  Record.AddSourceLocation(S->getForLoc());
1525  Record.AddSourceLocation(S->getCoawaitLoc());
1526  Record.AddSourceLocation(S->getColonLoc());
1527  Record.AddSourceLocation(S->getRParenLoc());
1528  Record.AddStmt(S->getInit());
1529  Record.AddStmt(S->getRangeStmt());
1530  Record.AddStmt(S->getBeginStmt());
1531  Record.AddStmt(S->getEndStmt());
1532  Record.AddStmt(S->getCond());
1533  Record.AddStmt(S->getInc());
1534  Record.AddStmt(S->getLoopVarStmt());
1535  Record.AddStmt(S->getBody());
1536  Code = serialization::STMT_CXX_FOR_RANGE;
1537}
1538
1539void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
1540  VisitStmt(S);
1541  Record.AddSourceLocation(S->getKeywordLoc());
1542  Record.push_back(S->isIfExists());
1543  Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
1544  Record.AddDeclarationNameInfo(S->getNameInfo());
1545  Record.AddStmt(S->getSubStmt());
1546  Code = serialization::STMT_MS_DEPENDENT_EXISTS;
1547}
1548
1549void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
1550  VisitCallExpr(E);
1551  Record.push_back(E->getOperator());
1552  Record.AddSourceRange(E->Range);
1553  Record.push_back(E->getFPFeatures().getAsOpaqueInt());
1554  Code = serialization::EXPR_CXX_OPERATOR_CALL;
1555}
1556
1557void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
1558  VisitCallExpr(E);
1559  Code = serialization::EXPR_CXX_MEMBER_CALL;
1560}
1561
1562void ASTStmtWriter::VisitCXXRewrittenBinaryOperator(
1563    CXXRewrittenBinaryOperator *E) {
1564  VisitExpr(E);
1565  Record.push_back(E->isReversed());
1566  Record.AddStmt(E->getSemanticForm());
1567  Code = serialization::EXPR_CXX_REWRITTEN_BINARY_OPERATOR;
1568}
1569
1570void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
1571  VisitExpr(E);
1572
1573  Record.push_back(E->getNumArgs());
1574  Record.push_back(E->isElidable());
1575  Record.push_back(E->hadMultipleCandidates());
1576  Record.push_back(E->isListInitialization());
1577  Record.push_back(E->isStdInitListInitialization());
1578  Record.push_back(E->requiresZeroInitialization());
1579  Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
1580  Record.AddSourceLocation(E->getLocation());
1581  Record.AddDeclRef(E->getConstructor());
1582  Record.AddSourceRange(E->getParenOrBraceRange());
1583
1584  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
1585    Record.AddStmt(E->getArg(I));
1586
1587  Code = serialization::EXPR_CXX_CONSTRUCT;
1588}
1589
1590void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
1591  VisitExpr(E);
1592  Record.AddDeclRef(E->getConstructor());
1593  Record.AddSourceLocation(E->getLocation());
1594  Record.push_back(E->constructsVBase());
1595  Record.push_back(E->inheritedFromVBase());
1596  Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
1597}
1598
1599void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
1600  VisitCXXConstructExpr(E);
1601  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
1602  Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
1603}
1604
1605void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
1606  VisitExpr(E);
1607  Record.push_back(E->LambdaExprBits.NumCaptures);
1608  Record.AddSourceRange(E->IntroducerRange);
1609  Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
1610  Record.AddSourceLocation(E->CaptureDefaultLoc);
1611  Record.push_back(E->LambdaExprBits.ExplicitParams);
1612  Record.push_back(E->LambdaExprBits.ExplicitResultType);
1613  Record.AddSourceLocation(E->ClosingBrace);
1614
1615  // Add capture initializers.
1616  for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
1617                                      CEnd = E->capture_init_end();
1618       C != CEnd; ++C) {
1619    Record.AddStmt(*C);
1620  }
1621
1622  // Don't serialize the body. It belongs to the call operator declaration.
1623  // LambdaExpr only stores a copy of the Stmt *.
1624
1625  Code = serialization::EXPR_LAMBDA;
1626}
1627
1628void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
1629  VisitExpr(E);
1630  Record.AddStmt(E->getSubExpr());
1631  Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
1632}
1633
1634void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
1635  VisitExplicitCastExpr(E);
1636  Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
1637  Record.AddSourceRange(E->getAngleBrackets());
1638}
1639
1640void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
1641  VisitCXXNamedCastExpr(E);
1642  Code = serialization::EXPR_CXX_STATIC_CAST;
1643}
1644
1645void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
1646  VisitCXXNamedCastExpr(E);
1647  Code = serialization::EXPR_CXX_DYNAMIC_CAST;
1648}
1649
1650void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
1651  VisitCXXNamedCastExpr(E);
1652  Code = serialization::EXPR_CXX_REINTERPRET_CAST;
1653}
1654
1655void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
1656  VisitCXXNamedCastExpr(E);
1657  Code = serialization::EXPR_CXX_CONST_CAST;
1658}
1659
1660void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
1661  VisitCXXNamedCastExpr(E);
1662  Code = serialization::EXPR_CXX_ADDRSPACE_CAST;
1663}
1664
1665void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
1666  VisitExplicitCastExpr(E);
1667  Record.AddSourceLocation(E->getLParenLoc());
1668  Record.AddSourceLocation(E->getRParenLoc());
1669  Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
1670}
1671
1672void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) {
1673  VisitExplicitCastExpr(E);
1674  Record.AddSourceLocation(E->getBeginLoc());
1675  Record.AddSourceLocation(E->getEndLoc());
1676  Code = serialization::EXPR_BUILTIN_BIT_CAST;
1677}
1678
1679void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
1680  VisitCallExpr(E);
1681  Record.AddSourceLocation(E->UDSuffixLoc);
1682  Code = serialization::EXPR_USER_DEFINED_LITERAL;
1683}
1684
1685void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
1686  VisitExpr(E);
1687  Record.push_back(E->getValue());
1688  Record.AddSourceLocation(E->getLocation());
1689  Code = serialization::EXPR_CXX_BOOL_LITERAL;
1690}
1691
1692void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
1693  VisitExpr(E);
1694  Record.AddSourceLocation(E->getLocation());
1695  Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
1696}
1697
1698void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
1699  VisitExpr(E);
1700  Record.AddSourceRange(E->getSourceRange());
1701  if (E->isTypeOperand()) {
1702    Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
1703    Code = serialization::EXPR_CXX_TYPEID_TYPE;
1704  } else {
1705    Record.AddStmt(E->getExprOperand());
1706    Code = serialization::EXPR_CXX_TYPEID_EXPR;
1707  }
1708}
1709
1710void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
1711  VisitExpr(E);
1712  Record.AddSourceLocation(E->getLocation());
1713  Record.push_back(E->isImplicit());
1714  Code = serialization::EXPR_CXX_THIS;
1715}
1716
1717void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
1718  VisitExpr(E);
1719  Record.AddSourceLocation(E->getThrowLoc());
1720  Record.AddStmt(E->getSubExpr());
1721  Record.push_back(E->isThrownVariableInScope());
1722  Code = serialization::EXPR_CXX_THROW;
1723}
1724
1725void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
1726  VisitExpr(E);
1727  Record.AddDeclRef(E->getParam());
1728  Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
1729  Record.AddSourceLocation(E->getUsedLocation());
1730  Code = serialization::EXPR_CXX_DEFAULT_ARG;
1731}
1732
1733void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
1734  VisitExpr(E);
1735  Record.AddDeclRef(E->getField());
1736  Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
1737  Record.AddSourceLocation(E->getExprLoc());
1738  Code = serialization::EXPR_CXX_DEFAULT_INIT;
1739}
1740
1741void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
1742  VisitExpr(E);
1743  Record.AddCXXTemporary(E->getTemporary());
1744  Record.AddStmt(E->getSubExpr());
1745  Code = serialization::EXPR_CXX_BIND_TEMPORARY;
1746}
1747
1748void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
1749  VisitExpr(E);
1750  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
1751  Record.AddSourceLocation(E->getRParenLoc());
1752  Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
1753}
1754
1755void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
1756  VisitExpr(E);
1757
1758  Record.push_back(E->isArray());
1759  Record.push_back(E->hasInitializer());
1760  Record.push_back(E->getNumPlacementArgs());
1761  Record.push_back(E->isParenTypeId());
1762
1763  Record.push_back(E->isGlobalNew());
1764  Record.push_back(E->passAlignment());
1765  Record.push_back(E->doesUsualArrayDeleteWantSize());
1766  Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
1767
1768  Record.AddDeclRef(E->getOperatorNew());
1769  Record.AddDeclRef(E->getOperatorDelete());
1770  Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
1771  if (E->isParenTypeId())
1772    Record.AddSourceRange(E->getTypeIdParens());
1773  Record.AddSourceRange(E->getSourceRange());
1774  Record.AddSourceRange(E->getDirectInitRange());
1775
1776  for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
1777       I != N; ++I)
1778    Record.AddStmt(*I);
1779
1780  Code = serialization::EXPR_CXX_NEW;
1781}
1782
1783void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
1784  VisitExpr(E);
1785  Record.push_back(E->isGlobalDelete());
1786  Record.push_back(E->isArrayForm());
1787  Record.push_back(E->isArrayFormAsWritten());
1788  Record.push_back(E->doesUsualArrayDeleteWantSize());
1789  Record.AddDeclRef(E->getOperatorDelete());
1790  Record.AddStmt(E->getArgument());
1791  Record.AddSourceLocation(E->getBeginLoc());
1792
1793  Code = serialization::EXPR_CXX_DELETE;
1794}
1795
1796void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
1797  VisitExpr(E);
1798
1799  Record.AddStmt(E->getBase());
1800  Record.push_back(E->isArrow());
1801  Record.AddSourceLocation(E->getOperatorLoc());
1802  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
1803  Record.AddTypeSourceInfo(E->getScopeTypeInfo());
1804  Record.AddSourceLocation(E->getColonColonLoc());
1805  Record.AddSourceLocation(E->getTildeLoc());
1806
1807  // PseudoDestructorTypeStorage.
1808  Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
1809  if (E->getDestroyedTypeIdentifier())
1810    Record.AddSourceLocation(E->getDestroyedTypeLoc());
1811  else
1812    Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());
1813
1814  Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
1815}
1816
1817void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
1818  VisitExpr(E);
1819  Record.push_back(E->getNumObjects());
1820  for (auto &Obj : E->getObjects()) {
1821    if (auto *BD = Obj.dyn_cast<BlockDecl *>()) {
1822      Record.push_back(serialization::COK_Block);
1823      Record.AddDeclRef(BD);
1824    } else if (auto *CLE = Obj.dyn_cast<CompoundLiteralExpr *>()) {
1825      Record.push_back(serialization::COK_CompoundLiteral);
1826      Record.AddStmt(CLE);
1827    }
1828  }
1829
1830  Record.push_back(E->cleanupsHaveSideEffects());
1831  Record.AddStmt(E->getSubExpr());
1832  Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
1833}
1834
1835void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
1836    CXXDependentScopeMemberExpr *E) {
1837  VisitExpr(E);
1838
1839  // Don't emit anything here (or if you do you will have to update
1840  // the corresponding deserialization function).
1841
1842  Record.push_back(E->hasTemplateKWAndArgsInfo());
1843  Record.push_back(E->getNumTemplateArgs());
1844  Record.push_back(E->hasFirstQualifierFoundInScope());
1845
1846  if (E->hasTemplateKWAndArgsInfo()) {
1847    const ASTTemplateKWAndArgsInfo &ArgInfo =
1848        *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
1849    AddTemplateKWAndArgsInfo(ArgInfo,
1850                             E->getTrailingObjects<TemplateArgumentLoc>());
1851  }
1852
1853  Record.push_back(E->isArrow());
1854  Record.AddSourceLocation(E->getOperatorLoc());
1855  Record.AddTypeRef(E->getBaseType());
1856  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
1857  if (!E->isImplicitAccess())
1858    Record.AddStmt(E->getBase());
1859  else
1860    Record.AddStmt(nullptr);
1861
1862  if (E->hasFirstQualifierFoundInScope())
1863    Record.AddDeclRef(E->getFirstQualifierFoundInScope());
1864
1865  Record.AddDeclarationNameInfo(E->MemberNameInfo);
1866  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
1867}
1868
1869void
1870ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
1871  VisitExpr(E);
1872
1873  // Don't emit anything here, HasTemplateKWAndArgsInfo must be
1874  // emitted first.
1875
1876  Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
1877  if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
1878    const ASTTemplateKWAndArgsInfo &ArgInfo =
1879        *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
1880    Record.push_back(ArgInfo.NumTemplateArgs);
1881    AddTemplateKWAndArgsInfo(ArgInfo,
1882                             E->getTrailingObjects<TemplateArgumentLoc>());
1883  }
1884
1885  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
1886  Record.AddDeclarationNameInfo(E->NameInfo);
1887  Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
1888}
1889
1890void
1891ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
1892  VisitExpr(E);
1893  Record.push_back(E->arg_size());
1894  for (CXXUnresolvedConstructExpr::arg_iterator
1895         ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
1896    Record.AddStmt(*ArgI);
1897  Record.AddTypeSourceInfo(E->getTypeSourceInfo());
1898  Record.AddSourceLocation(E->getLParenLoc());
1899  Record.AddSourceLocation(E->getRParenLoc());
1900  Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
1901}
1902
1903void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
1904  VisitExpr(E);
1905
1906  Record.push_back(E->getNumDecls());
1907  Record.push_back(E->hasTemplateKWAndArgsInfo());
1908  if (E->hasTemplateKWAndArgsInfo()) {
1909    const ASTTemplateKWAndArgsInfo &ArgInfo =
1910        *E->getTrailingASTTemplateKWAndArgsInfo();
1911    Record.push_back(ArgInfo.NumTemplateArgs);
1912    AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
1913  }
1914
1915  for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
1916                                    OvE = E->decls_end();
1917       OvI != OvE; ++OvI) {
1918    Record.AddDeclRef(OvI.getDecl());
1919    Record.push_back(OvI.getAccess());
1920  }
1921
1922  Record.AddDeclarationNameInfo(E->getNameInfo());
1923  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
1924}
1925
1926void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
1927  VisitOverloadExpr(E);
1928  Record.push_back(E->isArrow());
1929  Record.push_back(E->hasUnresolvedUsing());
1930  Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
1931  Record.AddTypeRef(E->getBaseType());
1932  Record.AddSourceLocation(E->getOperatorLoc());
1933  Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
1934}
1935
1936void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
1937  VisitOverloadExpr(E);
1938  Record.push_back(E->requiresADL());
1939  Record.push_back(E->isOverloaded());
1940  Record.AddDeclRef(E->getNamingClass());
1941  Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
1942}
1943
1944void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
1945  VisitExpr(E);
1946  Record.push_back(E->TypeTraitExprBits.NumArgs);
1947  Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
1948  Record.push_back(E->TypeTraitExprBits.Value);
1949  Record.AddSourceRange(E->getSourceRange());
1950  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
1951    Record.AddTypeSourceInfo(E->getArg(I));
1952  Code = serialization::EXPR_TYPE_TRAIT;
1953}
1954
1955void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
1956  VisitExpr(E);
1957  Record.push_back(E->getTrait());
1958  Record.push_back(E->getValue());
1959  Record.AddSourceRange(E->getSourceRange());
1960  Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
1961  Record.AddStmt(E->getDimensionExpression());
1962  Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
1963}
1964
1965void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
1966  VisitExpr(E);
1967  Record.push_back(E->getTrait());
1968  Record.push_back(E->getValue());
1969  Record.AddSourceRange(E->getSourceRange());
1970  Record.AddStmt(E->getQueriedExpression());
1971  Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
1972}
1973
1974void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
1975  VisitExpr(E);
1976  Record.push_back(E->getValue());
1977  Record.AddSourceRange(E->getSourceRange());
1978  Record.AddStmt(E->getOperand());
1979  Code = serialization::EXPR_CXX_NOEXCEPT;
1980}
1981
1982void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
1983  VisitExpr(E);
1984  Record.AddSourceLocation(E->getEllipsisLoc());
1985  Record.push_back(E->NumExpansions);
1986  Record.AddStmt(E->getPattern());
1987  Code = serialization::EXPR_PACK_EXPANSION;
1988}
1989
1990void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
1991  VisitExpr(E);
1992  Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
1993                                               : 0);
1994  Record.AddSourceLocation(E->OperatorLoc);
1995  Record.AddSourceLocation(E->PackLoc);
1996  Record.AddSourceLocation(E->RParenLoc);
1997  Record.AddDeclRef(E->Pack);
1998  if (E->isPartiallySubstituted()) {
1999    for (const auto &TA : E->getPartialArguments())
2000      Record.AddTemplateArgument(TA);
2001  } else if (!E->isValueDependent()) {
2002    Record.push_back(E->getPackLength());
2003  }
2004  Code = serialization::EXPR_SIZEOF_PACK;
2005}
2006
2007void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
2008                                              SubstNonTypeTemplateParmExpr *E) {
2009  VisitExpr(E);
2010  Record.AddDeclRef(E->getParameter());
2011  Record.AddSourceLocation(E->getNameLoc());
2012  Record.AddStmt(E->getReplacement());
2013  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
2014}
2015
2016void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
2017                                          SubstNonTypeTemplateParmPackExpr *E) {
2018  VisitExpr(E);
2019  Record.AddDeclRef(E->getParameterPack());
2020  Record.AddTemplateArgument(E->getArgumentPack());
2021  Record.AddSourceLocation(E->getParameterPackLocation());
2022  Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
2023}
2024
2025void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
2026  VisitExpr(E);
2027  Record.push_back(E->getNumExpansions());
2028  Record.AddDeclRef(E->getParameterPack());
2029  Record.AddSourceLocation(E->getParameterPackLocation());
2030  for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
2031       I != End; ++I)
2032    Record.AddDeclRef(*I);
2033  Code = serialization::EXPR_FUNCTION_PARM_PACK;
2034}
2035
2036void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
2037  VisitExpr(E);
2038  Record.push_back(static_cast<bool>(E->getLifetimeExtendedTemporaryDecl()));
2039  if (E->getLifetimeExtendedTemporaryDecl())
2040    Record.AddDeclRef(E->getLifetimeExtendedTemporaryDecl());
2041  else
2042    Record.AddStmt(E->getSubExpr());
2043  Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
2044}
2045
2046void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
2047  VisitExpr(E);
2048  Record.AddSourceLocation(E->LParenLoc);
2049  Record.AddSourceLocation(E->EllipsisLoc);
2050  Record.AddSourceLocation(E->RParenLoc);
2051  Record.push_back(E->NumExpansions);
2052  Record.AddStmt(E->SubExprs[0]);
2053  Record.AddStmt(E->SubExprs[1]);
2054  Record.push_back(E->Opcode);
2055  Code = serialization::EXPR_CXX_FOLD;
2056}
2057
2058void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
2059  VisitExpr(E);
2060  Record.AddStmt(E->getSourceExpr());
2061  Record.AddSourceLocation(E->getLocation());
2062  Record.push_back(E->isUnique());
2063  Code = serialization::EXPR_OPAQUE_VALUE;
2064}
2065
2066void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
2067  VisitExpr(E);
2068  // TODO: Figure out sane writer behavior for a TypoExpr, if necessary
2069  llvm_unreachable("Cannot write TypoExpr nodes");
2070}
2071
2072//===----------------------------------------------------------------------===//
2073// CUDA Expressions and Statements.
2074//===----------------------------------------------------------------------===//
2075
2076void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
2077  VisitCallExpr(E);
2078  Record.AddStmt(E->getConfig());
2079  Code = serialization::EXPR_CUDA_KERNEL_CALL;
2080}
2081
2082//===----------------------------------------------------------------------===//
2083// OpenCL Expressions and Statements.
2084//===----------------------------------------------------------------------===//
2085void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
2086  VisitExpr(E);
2087  Record.AddSourceLocation(E->getBuiltinLoc());
2088  Record.AddSourceLocation(E->getRParenLoc());
2089  Record.AddStmt(E->getSrcExpr());
2090  Code = serialization::EXPR_ASTYPE;
2091}
2092
2093//===----------------------------------------------------------------------===//
2094// Microsoft Expressions and Statements.
2095//===----------------------------------------------------------------------===//
2096void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
2097  VisitExpr(E);
2098  Record.push_back(E->isArrow());
2099  Record.AddStmt(E->getBaseExpr());
2100  Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
2101  Record.AddSourceLocation(E->getMemberLoc());
2102  Record.AddDeclRef(E->getPropertyDecl());
2103  Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
2104}
2105
2106void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
2107  VisitExpr(E);
2108  Record.AddStmt(E->getBase());
2109  Record.AddStmt(E->getIdx());
2110  Record.AddSourceLocation(E->getRBracketLoc());
2111  Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
2112}
2113
2114void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
2115  VisitExpr(E);
2116  Record.AddSourceRange(E->getSourceRange());
2117  Record.AddDeclRef(E->getGuidDecl());
2118  if (E->isTypeOperand()) {
2119    Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
2120    Code = serialization::EXPR_CXX_UUIDOF_TYPE;
2121  } else {
2122    Record.AddStmt(E->getExprOperand());
2123    Code = serialization::EXPR_CXX_UUIDOF_EXPR;
2124  }
2125}
2126
2127void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
2128  VisitStmt(S);
2129  Record.AddSourceLocation(S->getExceptLoc());
2130  Record.AddStmt(S->getFilterExpr());
2131  Record.AddStmt(S->getBlock());
2132  Code = serialization::STMT_SEH_EXCEPT;
2133}
2134
2135void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
2136  VisitStmt(S);
2137  Record.AddSourceLocation(S->getFinallyLoc());
2138  Record.AddStmt(S->getBlock());
2139  Code = serialization::STMT_SEH_FINALLY;
2140}
2141
2142void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
2143  VisitStmt(S);
2144  Record.push_back(S->getIsCXXTry());
2145  Record.AddSourceLocation(S->getTryLoc());
2146  Record.AddStmt(S->getTryBlock());
2147  Record.AddStmt(S->getHandler());
2148  Code = serialization::STMT_SEH_TRY;
2149}
2150
2151void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
2152  VisitStmt(S);
2153  Record.AddSourceLocation(S->getLeaveLoc());
2154  Code = serialization::STMT_SEH_LEAVE;
2155}
2156
2157//===----------------------------------------------------------------------===//
2158// OpenMP Directives.
2159//===----------------------------------------------------------------------===//
2160void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
2161  Record.AddSourceLocation(E->getBeginLoc());
2162  Record.AddSourceLocation(E->getEndLoc());
2163  for (unsigned i = 0; i < E->getNumClauses(); ++i) {
2164    Record.writeOMPClause(E->getClause(i));
2165  }
2166  if (E->hasAssociatedStmt())
2167    Record.AddStmt(E->getAssociatedStmt());
2168}
2169
2170void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
2171  VisitStmt(D);
2172  Record.push_back(D->getNumClauses());
2173  Record.push_back(D->getCollapsedNumber());
2174  VisitOMPExecutableDirective(D);
2175  Record.AddStmt(D->getIterationVariable());
2176  Record.AddStmt(D->getLastIteration());
2177  Record.AddStmt(D->getCalcLastIteration());
2178  Record.AddStmt(D->getPreCond());
2179  Record.AddStmt(D->getCond());
2180  Record.AddStmt(D->getInit());
2181  Record.AddStmt(D->getInc());
2182  Record.AddStmt(D->getPreInits());
2183  if (isOpenMPWorksharingDirective(D->getDirectiveKind()) ||
2184      isOpenMPTaskLoopDirective(D->getDirectiveKind()) ||
2185      isOpenMPDistributeDirective(D->getDirectiveKind())) {
2186    Record.AddStmt(D->getIsLastIterVariable());
2187    Record.AddStmt(D->getLowerBoundVariable());
2188    Record.AddStmt(D->getUpperBoundVariable());
2189    Record.AddStmt(D->getStrideVariable());
2190    Record.AddStmt(D->getEnsureUpperBound());
2191    Record.AddStmt(D->getNextLowerBound());
2192    Record.AddStmt(D->getNextUpperBound());
2193    Record.AddStmt(D->getNumIterations());
2194  }
2195  if (isOpenMPLoopBoundSharingDirective(D->getDirectiveKind())) {
2196    Record.AddStmt(D->getPrevLowerBoundVariable());
2197    Record.AddStmt(D->getPrevUpperBoundVariable());
2198    Record.AddStmt(D->getDistInc());
2199    Record.AddStmt(D->getPrevEnsureUpperBound());
2200    Record.AddStmt(D->getCombinedLowerBoundVariable());
2201    Record.AddStmt(D->getCombinedUpperBoundVariable());
2202    Record.AddStmt(D->getCombinedEnsureUpperBound());
2203    Record.AddStmt(D->getCombinedInit());
2204    Record.AddStmt(D->getCombinedCond());
2205    Record.AddStmt(D->getCombinedNextLowerBound());
2206    Record.AddStmt(D->getCombinedNextUpperBound());
2207    Record.AddStmt(D->getCombinedDistCond());
2208    Record.AddStmt(D->getCombinedParForInDistCond());
2209  }
2210  for (auto I : D->counters()) {
2211    Record.AddStmt(I);
2212  }
2213  for (auto I : D->private_counters()) {
2214    Record.AddStmt(I);
2215  }
2216  for (auto I : D->inits()) {
2217    Record.AddStmt(I);
2218  }
2219  for (auto I : D->updates()) {
2220    Record.AddStmt(I);
2221  }
2222  for (auto I : D->finals()) {
2223    Record.AddStmt(I);
2224  }
2225  for (Stmt *S : D->dependent_counters())
2226    Record.AddStmt(S);
2227  for (Stmt *S : D->dependent_inits())
2228    Record.AddStmt(S);
2229  for (Stmt *S : D->finals_conditions())
2230    Record.AddStmt(S);
2231}
2232
2233void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
2234  VisitStmt(D);
2235  Record.push_back(D->getNumClauses());
2236  VisitOMPExecutableDirective(D);
2237  Record.AddStmt(D->getTaskReductionRefExpr());
2238  Record.push_back(D->hasCancel() ? 1 : 0);
2239  Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
2240}
2241
2242void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
2243  VisitOMPLoopDirective(D);
2244  Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
2245}
2246
2247void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
2248  VisitOMPLoopDirective(D);
2249  Record.AddStmt(D->getTaskReductionRefExpr());
2250  Record.push_back(D->hasCancel() ? 1 : 0);
2251  Code = serialization::STMT_OMP_FOR_DIRECTIVE;
2252}
2253
2254void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
2255  VisitOMPLoopDirective(D);
2256  Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
2257}
2258
2259void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
2260  VisitStmt(D);
2261  Record.push_back(D->getNumClauses());
2262  VisitOMPExecutableDirective(D);
2263  Record.AddStmt(D->getTaskReductionRefExpr());
2264  Record.push_back(D->hasCancel() ? 1 : 0);
2265  Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
2266}
2267
2268void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
2269  VisitStmt(D);
2270  VisitOMPExecutableDirective(D);
2271  Record.push_back(D->hasCancel() ? 1 : 0);
2272  Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
2273}
2274
2275void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
2276  VisitStmt(D);
2277  Record.push_back(D->getNumClauses());
2278  VisitOMPExecutableDirective(D);
2279  Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
2280}
2281
2282void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
2283  VisitStmt(D);
2284  VisitOMPExecutableDirective(D);
2285  Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
2286}
2287
2288void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
2289  VisitStmt(D);
2290  Record.push_back(D->getNumClauses());
2291  VisitOMPExecutableDirective(D);
2292  Record.AddDeclarationNameInfo(D->getDirectiveName());
2293  Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
2294}
2295
2296void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
2297  VisitOMPLoopDirective(D);
2298  Record.AddStmt(D->getTaskReductionRefExpr());
2299  Record.push_back(D->hasCancel() ? 1 : 0);
2300  Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
2301}
2302
2303void ASTStmtWriter::VisitOMPParallelForSimdDirective(
2304    OMPParallelForSimdDirective *D) {
2305  VisitOMPLoopDirective(D);
2306  Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
2307}
2308
2309void ASTStmtWriter::VisitOMPParallelMasterDirective(
2310    OMPParallelMasterDirective *D) {
2311  VisitStmt(D);
2312  Record.push_back(D->getNumClauses());
2313  VisitOMPExecutableDirective(D);
2314  Record.AddStmt(D->getTaskReductionRefExpr());
2315  Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE;
2316}
2317
2318void ASTStmtWriter::VisitOMPParallelSectionsDirective(
2319    OMPParallelSectionsDirective *D) {
2320  VisitStmt(D);
2321  Record.push_back(D->getNumClauses());
2322  VisitOMPExecutableDirective(D);
2323  Record.AddStmt(D->getTaskReductionRefExpr());
2324  Record.push_back(D->hasCancel() ? 1 : 0);
2325  Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
2326}
2327
2328void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
2329  VisitStmt(D);
2330  Record.push_back(D->getNumClauses());
2331  VisitOMPExecutableDirective(D);
2332  Record.push_back(D->hasCancel() ? 1 : 0);
2333  Code = serialization::STMT_OMP_TASK_DIRECTIVE;
2334}
2335
2336void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
2337  VisitStmt(D);
2338  Record.push_back(D->getNumClauses());
2339  VisitOMPExecutableDirective(D);
2340  Record.AddStmt(D->getX());
2341  Record.AddStmt(D->getV());
2342  Record.AddStmt(D->getExpr());
2343  Record.AddStmt(D->getUpdateExpr());
2344  Record.push_back(D->isXLHSInRHSPart() ? 1 : 0);
2345  Record.push_back(D->isPostfixUpdate() ? 1 : 0);
2346  Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
2347}
2348
2349void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
2350  VisitStmt(D);
2351  Record.push_back(D->getNumClauses());
2352  VisitOMPExecutableDirective(D);
2353  Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
2354}
2355
2356void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
2357  VisitStmt(D);
2358  Record.push_back(D->getNumClauses());
2359  VisitOMPExecutableDirective(D);
2360  Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
2361}
2362
2363void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
2364    OMPTargetEnterDataDirective *D) {
2365  VisitStmt(D);
2366  Record.push_back(D->getNumClauses());
2367  VisitOMPExecutableDirective(D);
2368  Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
2369}
2370
2371void ASTStmtWriter::VisitOMPTargetExitDataDirective(
2372    OMPTargetExitDataDirective *D) {
2373  VisitStmt(D);
2374  Record.push_back(D->getNumClauses());
2375  VisitOMPExecutableDirective(D);
2376  Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
2377}
2378
2379void ASTStmtWriter::VisitOMPTargetParallelDirective(
2380    OMPTargetParallelDirective *D) {
2381  VisitStmt(D);
2382  Record.push_back(D->getNumClauses());
2383  VisitOMPExecutableDirective(D);
2384  Record.AddStmt(D->getTaskReductionRefExpr());
2385  Record.writeBool(D->hasCancel());
2386  Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
2387}
2388
2389void ASTStmtWriter::VisitOMPTargetParallelForDirective(
2390    OMPTargetParallelForDirective *D) {
2391  VisitOMPLoopDirective(D);
2392  Record.AddStmt(D->getTaskReductionRefExpr());
2393  Record.push_back(D->hasCancel() ? 1 : 0);
2394  Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
2395}
2396
2397void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
2398  VisitStmt(D);
2399  VisitOMPExecutableDirective(D);
2400  Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
2401}
2402
2403void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
2404  VisitStmt(D);
2405  VisitOMPExecutableDirective(D);
2406  Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
2407}
2408
2409void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
2410  VisitStmt(D);
2411  VisitOMPExecutableDirective(D);
2412  Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
2413}
2414
2415void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
2416  VisitStmt(D);
2417  Record.push_back(D->getNumClauses());
2418  VisitOMPExecutableDirective(D);
2419  Record.AddStmt(D->getReductionRef());
2420  Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
2421}
2422
2423void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
2424  VisitStmt(D);
2425  Record.push_back(D->getNumClauses());
2426  VisitOMPExecutableDirective(D);
2427  Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
2428}
2429
2430void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
2431  VisitStmt(D);
2432  Record.push_back(D->getNumClauses());
2433  VisitOMPExecutableDirective(D);
2434  Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
2435}
2436
2437void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) {
2438  VisitStmt(D);
2439  Record.push_back(D->getNumClauses());
2440  VisitOMPExecutableDirective(D);
2441  Code = serialization::STMT_OMP_SCAN_DIRECTIVE;
2442}
2443
2444void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
2445  VisitStmt(D);
2446  Record.push_back(D->getNumClauses());
2447  VisitOMPExecutableDirective(D);
2448  Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
2449}
2450
2451void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
2452  VisitStmt(D);
2453  Record.push_back(D->getNumClauses());
2454  VisitOMPExecutableDirective(D);
2455  Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
2456}
2457
2458void ASTStmtWriter::VisitOMPCancellationPointDirective(
2459    OMPCancellationPointDirective *D) {
2460  VisitStmt(D);
2461  VisitOMPExecutableDirective(D);
2462  Record.push_back(uint64_t(D->getCancelRegion()));
2463  Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
2464}
2465
2466void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
2467  VisitStmt(D);
2468  Record.push_back(D->getNumClauses());
2469  VisitOMPExecutableDirective(D);
2470  Record.push_back(uint64_t(D->getCancelRegion()));
2471  Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
2472}
2473
2474void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
2475  VisitOMPLoopDirective(D);
2476  Record.push_back(D->hasCancel() ? 1 : 0);
2477  Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
2478}
2479
2480void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
2481  VisitOMPLoopDirective(D);
2482  Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
2483}
2484
2485void ASTStmtWriter::VisitOMPMasterTaskLoopDirective(
2486    OMPMasterTaskLoopDirective *D) {
2487  VisitOMPLoopDirective(D);
2488  Record.push_back(D->hasCancel() ? 1 : 0);
2489  Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE;
2490}
2491
2492void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective(
2493    OMPMasterTaskLoopSimdDirective *D) {
2494  VisitOMPLoopDirective(D);
2495  Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE;
2496}
2497
2498void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective(
2499    OMPParallelMasterTaskLoopDirective *D) {
2500  VisitOMPLoopDirective(D);
2501  Record.push_back(D->hasCancel() ? 1 : 0);
2502  Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE;
2503}
2504
2505void ASTStmtWriter::VisitOMPParallelMasterTaskLoopSimdDirective(
2506    OMPParallelMasterTaskLoopSimdDirective *D) {
2507  VisitOMPLoopDirective(D);
2508  Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE;
2509}
2510
2511void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
2512  VisitOMPLoopDirective(D);
2513  Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
2514}
2515
2516void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
2517  VisitStmt(D);
2518  Record.push_back(D->getNumClauses());
2519  VisitOMPExecutableDirective(D);
2520  Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
2521}
2522
2523void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
2524    OMPDistributeParallelForDirective *D) {
2525  VisitOMPLoopDirective(D);
2526  Record.AddStmt(D->getTaskReductionRefExpr());
2527  Record.push_back(D->hasCancel() ? 1 : 0);
2528  Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
2529}
2530
2531void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
2532    OMPDistributeParallelForSimdDirective *D) {
2533  VisitOMPLoopDirective(D);
2534  Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
2535}
2536
2537void ASTStmtWriter::VisitOMPDistributeSimdDirective(
2538    OMPDistributeSimdDirective *D) {
2539  VisitOMPLoopDirective(D);
2540  Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
2541}
2542
2543void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
2544    OMPTargetParallelForSimdDirective *D) {
2545  VisitOMPLoopDirective(D);
2546  Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
2547}
2548
2549void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
2550  VisitOMPLoopDirective(D);
2551  Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
2552}
2553
2554void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
2555    OMPTeamsDistributeDirective *D) {
2556  VisitOMPLoopDirective(D);
2557  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
2558}
2559
2560void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
2561    OMPTeamsDistributeSimdDirective *D) {
2562  VisitOMPLoopDirective(D);
2563  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
2564}
2565
2566void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
2567    OMPTeamsDistributeParallelForSimdDirective *D) {
2568  VisitOMPLoopDirective(D);
2569  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
2570}
2571
2572void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
2573    OMPTeamsDistributeParallelForDirective *D) {
2574  VisitOMPLoopDirective(D);
2575  Record.AddStmt(D->getTaskReductionRefExpr());
2576  Record.push_back(D->hasCancel() ? 1 : 0);
2577  Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
2578}
2579
2580void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
2581  VisitStmt(D);
2582  Record.push_back(D->getNumClauses());
2583  VisitOMPExecutableDirective(D);
2584  Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
2585}
2586
2587void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
2588    OMPTargetTeamsDistributeDirective *D) {
2589  VisitOMPLoopDirective(D);
2590  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
2591}
2592
2593void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
2594    OMPTargetTeamsDistributeParallelForDirective *D) {
2595  VisitOMPLoopDirective(D);
2596  Record.AddStmt(D->getTaskReductionRefExpr());
2597  Record.push_back(D->hasCancel() ? 1 : 0);
2598  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
2599}
2600
2601void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2602    OMPTargetTeamsDistributeParallelForSimdDirective *D) {
2603  VisitOMPLoopDirective(D);
2604  Code = serialization::
2605      STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
2606}
2607
2608void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
2609    OMPTargetTeamsDistributeSimdDirective *D) {
2610  VisitOMPLoopDirective(D);
2611  Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
2612}
2613
2614//===----------------------------------------------------------------------===//
2615// ASTWriter Implementation
2616//===----------------------------------------------------------------------===//
2617
2618unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
2619  assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
2620         "SwitchCase recorded twice");
2621  unsigned NextID = SwitchCaseIDs.size();
2622  SwitchCaseIDs[S] = NextID;
2623  return NextID;
2624}
2625
2626unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
2627  assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
2628         "SwitchCase hasn't been seen yet");
2629  return SwitchCaseIDs[S];
2630}
2631
2632void ASTWriter::ClearSwitchCaseIDs() {
2633  SwitchCaseIDs.clear();
2634}
2635
2636/// Write the given substatement or subexpression to the
2637/// bitstream.
2638void ASTWriter::WriteSubStmt(Stmt *S) {
2639  RecordData Record;
2640  ASTStmtWriter Writer(*this, Record);
2641  ++NumStatements;
2642
2643  if (!S) {
2644    Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
2645    return;
2646  }
2647
2648  llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
2649  if (I != SubStmtEntries.end()) {
2650    Record.push_back(I->second);
2651    Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
2652    return;
2653  }
2654
2655#ifndef NDEBUG
2656  assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
2657
2658  struct ParentStmtInserterRAII {
2659    Stmt *S;
2660    llvm::DenseSet<Stmt *> &ParentStmts;
2661
2662    ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
2663      : S(S), ParentStmts(ParentStmts) {
2664      ParentStmts.insert(S);
2665    }
2666    ~ParentStmtInserterRAII() {
2667      ParentStmts.erase(S);
2668    }
2669  };
2670
2671  ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
2672#endif
2673
2674  Writer.Visit(S);
2675
2676  uint64_t Offset = Writer.Emit();
2677  SubStmtEntries[S] = Offset;
2678}
2679
2680/// Flush all of the statements that have been added to the
2681/// queue via AddStmt().
2682void ASTRecordWriter::FlushStmts() {
2683  // We expect to be the only consumer of the two temporary statement maps,
2684  // assert that they are empty.
2685  assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
2686  assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
2687
2688  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
2689    Writer->WriteSubStmt(StmtsToEmit[I]);
2690
2691    assert(N == StmtsToEmit.size() && "record modified while being written!");
2692
2693    // Note that we are at the end of a full expression. Any
2694    // expression records that follow this one are part of a different
2695    // expression.
2696    Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());
2697
2698    Writer->SubStmtEntries.clear();
2699    Writer->ParentStmts.clear();
2700  }
2701
2702  StmtsToEmit.clear();
2703}
2704
2705void ASTRecordWriter::FlushSubStmts() {
2706  // For a nested statement, write out the substatements in reverse order (so
2707  // that a simple stack machine can be used when loading), and don't emit a
2708  // STMT_STOP after each one.
2709  for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
2710    Writer->WriteSubStmt(StmtsToEmit[N - I - 1]);
2711    assert(N == StmtsToEmit.size() && "record modified while being written!");
2712  }
2713
2714  StmtsToEmit.clear();
2715}
2716