xref: /freebsd-src/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Implements serialization for Statements and Expressions.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
145f757f3fSDimitry Andric #include "clang/AST/ASTConcept.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
195f757f3fSDimitry Andric #include "clang/AST/ExprOpenMP.h"
200b57cec5SDimitry Andric #include "clang/AST/StmtVisitor.h"
210b57cec5SDimitry Andric #include "clang/Lex/Token.h"
22*0fca6ea1SDimitry Andric #include "clang/Serialization/ASTReader.h"
235f757f3fSDimitry Andric #include "clang/Serialization/ASTRecordWriter.h"
240b57cec5SDimitry Andric #include "llvm/Bitstream/BitstreamWriter.h"
250b57cec5SDimitry Andric using namespace clang;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
280b57cec5SDimitry Andric // Statement/expression serialization
290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric namespace clang {
320b57cec5SDimitry Andric 
330b57cec5SDimitry Andric   class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
340b57cec5SDimitry Andric     ASTWriter &Writer;
350b57cec5SDimitry Andric     ASTRecordWriter Record;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric     serialization::StmtCode Code;
380b57cec5SDimitry Andric     unsigned AbbrevToUse;
390b57cec5SDimitry Andric 
40cb14a3feSDimitry Andric     /// A helper that can help us to write a packed bit across function
41*0fca6ea1SDimitry Andric     /// calls. For example, we may write separate bits in separate functions:
42cb14a3feSDimitry Andric     ///
43cb14a3feSDimitry Andric     ///  void VisitA(A* a) {
44cb14a3feSDimitry Andric     ///     Record.push_back(a->isSomething());
45cb14a3feSDimitry Andric     ///  }
46cb14a3feSDimitry Andric     ///
47cb14a3feSDimitry Andric     ///  void Visitb(B *b) {
48cb14a3feSDimitry Andric     ///     VisitA(b);
49cb14a3feSDimitry Andric     ///     Record.push_back(b->isAnother());
50cb14a3feSDimitry Andric     ///  }
51cb14a3feSDimitry Andric     ///
52cb14a3feSDimitry Andric     /// In such cases, it'll be better if we can pack these 2 bits. We achieve
53cb14a3feSDimitry Andric     /// this by writing a zero value in `VisitA` and recorded that first and add
54cb14a3feSDimitry Andric     /// the new bit to the recorded value.
55cb14a3feSDimitry Andric     class PakedBitsWriter {
56cb14a3feSDimitry Andric     public:
57cb14a3feSDimitry Andric       PakedBitsWriter(ASTRecordWriter &Record) : RecordRef(Record) {}
58cb14a3feSDimitry Andric       ~PakedBitsWriter() { assert(!CurrentIndex); }
59cb14a3feSDimitry Andric 
60cb14a3feSDimitry Andric       void addBit(bool Value) {
61cb14a3feSDimitry Andric         assert(CurrentIndex && "Writing Bits without recording first!");
62cb14a3feSDimitry Andric         PackingBits.addBit(Value);
63cb14a3feSDimitry Andric       }
64cb14a3feSDimitry Andric       void addBits(uint32_t Value, uint32_t BitsWidth) {
65cb14a3feSDimitry Andric         assert(CurrentIndex && "Writing Bits without recording first!");
66cb14a3feSDimitry Andric         PackingBits.addBits(Value, BitsWidth);
67cb14a3feSDimitry Andric       }
68cb14a3feSDimitry Andric 
69cb14a3feSDimitry Andric       void writeBits() {
70cb14a3feSDimitry Andric         if (!CurrentIndex)
71cb14a3feSDimitry Andric           return;
72cb14a3feSDimitry Andric 
73cb14a3feSDimitry Andric         RecordRef[*CurrentIndex] = (uint32_t)PackingBits;
74cb14a3feSDimitry Andric         CurrentIndex = std::nullopt;
75cb14a3feSDimitry Andric         PackingBits.reset(0);
76cb14a3feSDimitry Andric       }
77cb14a3feSDimitry Andric 
78cb14a3feSDimitry Andric       void updateBits() {
79cb14a3feSDimitry Andric         writeBits();
80cb14a3feSDimitry Andric 
81cb14a3feSDimitry Andric         CurrentIndex = RecordRef.size();
82cb14a3feSDimitry Andric         RecordRef.push_back(0);
83cb14a3feSDimitry Andric       }
84cb14a3feSDimitry Andric 
85cb14a3feSDimitry Andric     private:
86cb14a3feSDimitry Andric       BitsPacker PackingBits;
87cb14a3feSDimitry Andric       ASTRecordWriter &RecordRef;
88cb14a3feSDimitry Andric       std::optional<unsigned> CurrentIndex;
89cb14a3feSDimitry Andric     };
90cb14a3feSDimitry Andric 
91cb14a3feSDimitry Andric     PakedBitsWriter CurrentPackingBits;
92cb14a3feSDimitry Andric 
930b57cec5SDimitry Andric   public:
940b57cec5SDimitry Andric     ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
950b57cec5SDimitry Andric         : Writer(Writer), Record(Writer, Record),
96cb14a3feSDimitry Andric           Code(serialization::STMT_NULL_PTR), AbbrevToUse(0),
97cb14a3feSDimitry Andric           CurrentPackingBits(this->Record) {}
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric     ASTStmtWriter(const ASTStmtWriter&) = delete;
10006c3fb27SDimitry Andric     ASTStmtWriter &operator=(const ASTStmtWriter &) = delete;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric     uint64_t Emit() {
103cb14a3feSDimitry Andric       CurrentPackingBits.writeBits();
1040b57cec5SDimitry Andric       assert(Code != serialization::STMT_NULL_PTR &&
1050b57cec5SDimitry Andric              "unhandled sub-statement writing AST file");
1060b57cec5SDimitry Andric       return Record.EmitStmt(Code, AbbrevToUse);
1070b57cec5SDimitry Andric     }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric     void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
1100b57cec5SDimitry Andric                                   const TemplateArgumentLoc *Args);
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric     void VisitStmt(Stmt *S);
1130b57cec5SDimitry Andric #define STMT(Type, Base) \
1140b57cec5SDimitry Andric     void Visit##Type(Type *);
1150b57cec5SDimitry Andric #include "clang/AST/StmtNodes.inc"
1160b57cec5SDimitry Andric   };
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric void ASTStmtWriter::AddTemplateKWAndArgsInfo(
1200b57cec5SDimitry Andric     const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
1210b57cec5SDimitry Andric   Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
1220b57cec5SDimitry Andric   Record.AddSourceLocation(ArgInfo.LAngleLoc);
1230b57cec5SDimitry Andric   Record.AddSourceLocation(ArgInfo.RAngleLoc);
1240b57cec5SDimitry Andric   for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
1250b57cec5SDimitry Andric     Record.AddTemplateArgumentLoc(Args[i]);
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric void ASTStmtWriter::VisitStmt(Stmt *S) {
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
1320b57cec5SDimitry Andric   VisitStmt(S);
1330b57cec5SDimitry Andric   Record.AddSourceLocation(S->getSemiLoc());
1340b57cec5SDimitry Andric   Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
1350b57cec5SDimitry Andric   Code = serialization::STMT_NULL;
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
1390b57cec5SDimitry Andric   VisitStmt(S);
140cb14a3feSDimitry Andric 
1410b57cec5SDimitry Andric   Record.push_back(S->size());
14281ad6265SDimitry Andric   Record.push_back(S->hasStoredFPFeatures());
143cb14a3feSDimitry Andric 
1440b57cec5SDimitry Andric   for (auto *CS : S->body())
1450b57cec5SDimitry Andric     Record.AddStmt(CS);
14681ad6265SDimitry Andric   if (S->hasStoredFPFeatures())
14781ad6265SDimitry Andric     Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
1480b57cec5SDimitry Andric   Record.AddSourceLocation(S->getLBracLoc());
1490b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRBracLoc());
150cb14a3feSDimitry Andric 
151cb14a3feSDimitry Andric   if (!S->hasStoredFPFeatures())
152cb14a3feSDimitry Andric     AbbrevToUse = Writer.getCompoundStmtAbbrev();
153cb14a3feSDimitry Andric 
1540b57cec5SDimitry Andric   Code = serialization::STMT_COMPOUND;
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
1580b57cec5SDimitry Andric   VisitStmt(S);
1590b57cec5SDimitry Andric   Record.push_back(Writer.getSwitchCaseID(S));
1600b57cec5SDimitry Andric   Record.AddSourceLocation(S->getKeywordLoc());
1610b57cec5SDimitry Andric   Record.AddSourceLocation(S->getColonLoc());
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
1650b57cec5SDimitry Andric   VisitSwitchCase(S);
1660b57cec5SDimitry Andric   Record.push_back(S->caseStmtIsGNURange());
1670b57cec5SDimitry Andric   Record.AddStmt(S->getLHS());
1680b57cec5SDimitry Andric   Record.AddStmt(S->getSubStmt());
1690b57cec5SDimitry Andric   if (S->caseStmtIsGNURange()) {
1700b57cec5SDimitry Andric     Record.AddStmt(S->getRHS());
1710b57cec5SDimitry Andric     Record.AddSourceLocation(S->getEllipsisLoc());
1720b57cec5SDimitry Andric   }
1730b57cec5SDimitry Andric   Code = serialization::STMT_CASE;
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
1770b57cec5SDimitry Andric   VisitSwitchCase(S);
1780b57cec5SDimitry Andric   Record.AddStmt(S->getSubStmt());
1790b57cec5SDimitry Andric   Code = serialization::STMT_DEFAULT;
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
1830b57cec5SDimitry Andric   VisitStmt(S);
184fe6060f1SDimitry Andric   Record.push_back(S->isSideEntry());
1850b57cec5SDimitry Andric   Record.AddDeclRef(S->getDecl());
1860b57cec5SDimitry Andric   Record.AddStmt(S->getSubStmt());
1870b57cec5SDimitry Andric   Record.AddSourceLocation(S->getIdentLoc());
1880b57cec5SDimitry Andric   Code = serialization::STMT_LABEL;
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
1920b57cec5SDimitry Andric   VisitStmt(S);
1930b57cec5SDimitry Andric   Record.push_back(S->getAttrs().size());
1940b57cec5SDimitry Andric   Record.AddAttributes(S->getAttrs());
1950b57cec5SDimitry Andric   Record.AddStmt(S->getSubStmt());
1960b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAttrLoc());
1970b57cec5SDimitry Andric   Code = serialization::STMT_ATTRIBUTED;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
2000b57cec5SDimitry Andric void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
2010b57cec5SDimitry Andric   VisitStmt(S);
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   bool HasElse = S->getElse() != nullptr;
2040b57cec5SDimitry Andric   bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
2050b57cec5SDimitry Andric   bool HasInit = S->getInit() != nullptr;
2060b57cec5SDimitry Andric 
207cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
208cb14a3feSDimitry Andric 
209cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasElse);
210cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasVar);
211cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasInit);
212349cc55cSDimitry Andric   Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
2130b57cec5SDimitry Andric   Record.AddStmt(S->getCond());
2140b57cec5SDimitry Andric   Record.AddStmt(S->getThen());
2150b57cec5SDimitry Andric   if (HasElse)
2160b57cec5SDimitry Andric     Record.AddStmt(S->getElse());
2170b57cec5SDimitry Andric   if (HasVar)
21806c3fb27SDimitry Andric     Record.AddStmt(S->getConditionVariableDeclStmt());
2190b57cec5SDimitry Andric   if (HasInit)
2200b57cec5SDimitry Andric     Record.AddStmt(S->getInit());
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   Record.AddSourceLocation(S->getIfLoc());
223e8d8bef9SDimitry Andric   Record.AddSourceLocation(S->getLParenLoc());
224e8d8bef9SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
2250b57cec5SDimitry Andric   if (HasElse)
2260b57cec5SDimitry Andric     Record.AddSourceLocation(S->getElseLoc());
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   Code = serialization::STMT_IF;
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
2320b57cec5SDimitry Andric   VisitStmt(S);
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   bool HasInit = S->getInit() != nullptr;
2350b57cec5SDimitry Andric   bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
2360b57cec5SDimitry Andric   Record.push_back(HasInit);
2370b57cec5SDimitry Andric   Record.push_back(HasVar);
2380b57cec5SDimitry Andric   Record.push_back(S->isAllEnumCasesCovered());
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   Record.AddStmt(S->getCond());
2410b57cec5SDimitry Andric   Record.AddStmt(S->getBody());
2420b57cec5SDimitry Andric   if (HasInit)
2430b57cec5SDimitry Andric     Record.AddStmt(S->getInit());
2440b57cec5SDimitry Andric   if (HasVar)
24506c3fb27SDimitry Andric     Record.AddStmt(S->getConditionVariableDeclStmt());
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric   Record.AddSourceLocation(S->getSwitchLoc());
248e8d8bef9SDimitry Andric   Record.AddSourceLocation(S->getLParenLoc());
249e8d8bef9SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
2520b57cec5SDimitry Andric        SC = SC->getNextSwitchCase())
2530b57cec5SDimitry Andric     Record.push_back(Writer.RecordSwitchCaseID(SC));
2540b57cec5SDimitry Andric   Code = serialization::STMT_SWITCH;
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
2580b57cec5SDimitry Andric   VisitStmt(S);
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
2610b57cec5SDimitry Andric   Record.push_back(HasVar);
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric   Record.AddStmt(S->getCond());
2640b57cec5SDimitry Andric   Record.AddStmt(S->getBody());
2650b57cec5SDimitry Andric   if (HasVar)
26606c3fb27SDimitry Andric     Record.AddStmt(S->getConditionVariableDeclStmt());
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   Record.AddSourceLocation(S->getWhileLoc());
2695ffd83dbSDimitry Andric   Record.AddSourceLocation(S->getLParenLoc());
2705ffd83dbSDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
2710b57cec5SDimitry Andric   Code = serialization::STMT_WHILE;
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
2750b57cec5SDimitry Andric   VisitStmt(S);
2760b57cec5SDimitry Andric   Record.AddStmt(S->getCond());
2770b57cec5SDimitry Andric   Record.AddStmt(S->getBody());
2780b57cec5SDimitry Andric   Record.AddSourceLocation(S->getDoLoc());
2790b57cec5SDimitry Andric   Record.AddSourceLocation(S->getWhileLoc());
2800b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
2810b57cec5SDimitry Andric   Code = serialization::STMT_DO;
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric void ASTStmtWriter::VisitForStmt(ForStmt *S) {
2850b57cec5SDimitry Andric   VisitStmt(S);
2860b57cec5SDimitry Andric   Record.AddStmt(S->getInit());
2870b57cec5SDimitry Andric   Record.AddStmt(S->getCond());
28806c3fb27SDimitry Andric   Record.AddStmt(S->getConditionVariableDeclStmt());
2890b57cec5SDimitry Andric   Record.AddStmt(S->getInc());
2900b57cec5SDimitry Andric   Record.AddStmt(S->getBody());
2910b57cec5SDimitry Andric   Record.AddSourceLocation(S->getForLoc());
2920b57cec5SDimitry Andric   Record.AddSourceLocation(S->getLParenLoc());
2930b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
2940b57cec5SDimitry Andric   Code = serialization::STMT_FOR;
2950b57cec5SDimitry Andric }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
2980b57cec5SDimitry Andric   VisitStmt(S);
2990b57cec5SDimitry Andric   Record.AddDeclRef(S->getLabel());
3000b57cec5SDimitry Andric   Record.AddSourceLocation(S->getGotoLoc());
3010b57cec5SDimitry Andric   Record.AddSourceLocation(S->getLabelLoc());
3020b57cec5SDimitry Andric   Code = serialization::STMT_GOTO;
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
3060b57cec5SDimitry Andric   VisitStmt(S);
3070b57cec5SDimitry Andric   Record.AddSourceLocation(S->getGotoLoc());
3080b57cec5SDimitry Andric   Record.AddSourceLocation(S->getStarLoc());
3090b57cec5SDimitry Andric   Record.AddStmt(S->getTarget());
3100b57cec5SDimitry Andric   Code = serialization::STMT_INDIRECT_GOTO;
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
3140b57cec5SDimitry Andric   VisitStmt(S);
3150b57cec5SDimitry Andric   Record.AddSourceLocation(S->getContinueLoc());
3160b57cec5SDimitry Andric   Code = serialization::STMT_CONTINUE;
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
3200b57cec5SDimitry Andric   VisitStmt(S);
3210b57cec5SDimitry Andric   Record.AddSourceLocation(S->getBreakLoc());
3220b57cec5SDimitry Andric   Code = serialization::STMT_BREAK;
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
3260b57cec5SDimitry Andric   VisitStmt(S);
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
3290b57cec5SDimitry Andric   Record.push_back(HasNRVOCandidate);
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   Record.AddStmt(S->getRetValue());
3320b57cec5SDimitry Andric   if (HasNRVOCandidate)
3330b57cec5SDimitry Andric     Record.AddDeclRef(S->getNRVOCandidate());
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   Record.AddSourceLocation(S->getReturnLoc());
3360b57cec5SDimitry Andric   Code = serialization::STMT_RETURN;
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
3400b57cec5SDimitry Andric   VisitStmt(S);
3410b57cec5SDimitry Andric   Record.AddSourceLocation(S->getBeginLoc());
3420b57cec5SDimitry Andric   Record.AddSourceLocation(S->getEndLoc());
3430b57cec5SDimitry Andric   DeclGroupRef DG = S->getDeclGroup();
3440b57cec5SDimitry Andric   for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
3450b57cec5SDimitry Andric     Record.AddDeclRef(*D);
3460b57cec5SDimitry Andric   Code = serialization::STMT_DECL;
3470b57cec5SDimitry Andric }
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
3500b57cec5SDimitry Andric   VisitStmt(S);
3510b57cec5SDimitry Andric   Record.push_back(S->getNumOutputs());
3520b57cec5SDimitry Andric   Record.push_back(S->getNumInputs());
3530b57cec5SDimitry Andric   Record.push_back(S->getNumClobbers());
3540b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAsmLoc());
3550b57cec5SDimitry Andric   Record.push_back(S->isVolatile());
3560b57cec5SDimitry Andric   Record.push_back(S->isSimple());
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
3600b57cec5SDimitry Andric   VisitAsmStmt(S);
3610b57cec5SDimitry Andric   Record.push_back(S->getNumLabels());
3620b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
3630b57cec5SDimitry Andric   Record.AddStmt(S->getAsmString());
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric   // Outputs
3660b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
3670b57cec5SDimitry Andric     Record.AddIdentifierRef(S->getOutputIdentifier(I));
3680b57cec5SDimitry Andric     Record.AddStmt(S->getOutputConstraintLiteral(I));
3690b57cec5SDimitry Andric     Record.AddStmt(S->getOutputExpr(I));
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   // Inputs
3730b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
3740b57cec5SDimitry Andric     Record.AddIdentifierRef(S->getInputIdentifier(I));
3750b57cec5SDimitry Andric     Record.AddStmt(S->getInputConstraintLiteral(I));
3760b57cec5SDimitry Andric     Record.AddStmt(S->getInputExpr(I));
3770b57cec5SDimitry Andric   }
3780b57cec5SDimitry Andric 
3790b57cec5SDimitry Andric   // Clobbers
3800b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
3810b57cec5SDimitry Andric     Record.AddStmt(S->getClobberStringLiteral(I));
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   // Labels
38406c3fb27SDimitry Andric   for (unsigned I = 0, N = S->getNumLabels(); I != N; ++I) {
38506c3fb27SDimitry Andric     Record.AddIdentifierRef(S->getLabelIdentifier(I));
38606c3fb27SDimitry Andric     Record.AddStmt(S->getLabelExpr(I));
38706c3fb27SDimitry Andric   }
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   Code = serialization::STMT_GCCASM;
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
3930b57cec5SDimitry Andric   VisitAsmStmt(S);
3940b57cec5SDimitry Andric   Record.AddSourceLocation(S->getLBraceLoc());
3950b57cec5SDimitry Andric   Record.AddSourceLocation(S->getEndLoc());
3960b57cec5SDimitry Andric   Record.push_back(S->getNumAsmToks());
3970b57cec5SDimitry Andric   Record.AddString(S->getAsmString());
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric   // Tokens
4000b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
4010b57cec5SDimitry Andric     // FIXME: Move this to ASTRecordWriter?
4020b57cec5SDimitry Andric     Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
4030b57cec5SDimitry Andric   }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric   // Clobbers
4060b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
4070b57cec5SDimitry Andric     Record.AddString(S->getClobber(I));
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric   // Outputs
4110b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
4120b57cec5SDimitry Andric     Record.AddStmt(S->getOutputExpr(I));
4130b57cec5SDimitry Andric     Record.AddString(S->getOutputConstraint(I));
4140b57cec5SDimitry Andric   }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   // Inputs
4170b57cec5SDimitry Andric   for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
4180b57cec5SDimitry Andric     Record.AddStmt(S->getInputExpr(I));
4190b57cec5SDimitry Andric     Record.AddString(S->getInputConstraint(I));
4200b57cec5SDimitry Andric   }
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric   Code = serialization::STMT_MSASM;
4230b57cec5SDimitry Andric }
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric void ASTStmtWriter::VisitCoroutineBodyStmt(CoroutineBodyStmt *CoroStmt) {
4260b57cec5SDimitry Andric   VisitStmt(CoroStmt);
4270b57cec5SDimitry Andric   Record.push_back(CoroStmt->getParamMoves().size());
4280b57cec5SDimitry Andric   for (Stmt *S : CoroStmt->children())
4290b57cec5SDimitry Andric     Record.AddStmt(S);
4300b57cec5SDimitry Andric   Code = serialization::STMT_COROUTINE_BODY;
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
4340b57cec5SDimitry Andric   VisitStmt(S);
4350b57cec5SDimitry Andric   Record.AddSourceLocation(S->getKeywordLoc());
4360b57cec5SDimitry Andric   Record.AddStmt(S->getOperand());
4370b57cec5SDimitry Andric   Record.AddStmt(S->getPromiseCall());
4380b57cec5SDimitry Andric   Record.push_back(S->isImplicit());
4390b57cec5SDimitry Andric   Code = serialization::STMT_CORETURN;
4400b57cec5SDimitry Andric }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric void ASTStmtWriter::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) {
4430b57cec5SDimitry Andric   VisitExpr(E);
4440b57cec5SDimitry Andric   Record.AddSourceLocation(E->getKeywordLoc());
4450b57cec5SDimitry Andric   for (Stmt *S : E->children())
4460b57cec5SDimitry Andric     Record.AddStmt(S);
4470b57cec5SDimitry Andric   Record.AddStmt(E->getOpaqueValue());
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
4510b57cec5SDimitry Andric   VisitCoroutineSuspendExpr(E);
4520b57cec5SDimitry Andric   Record.push_back(E->isImplicit());
4530b57cec5SDimitry Andric   Code = serialization::EXPR_COAWAIT;
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
4570b57cec5SDimitry Andric   VisitCoroutineSuspendExpr(E);
4580b57cec5SDimitry Andric   Code = serialization::EXPR_COYIELD;
4590b57cec5SDimitry Andric }
4600b57cec5SDimitry Andric 
4610b57cec5SDimitry Andric void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
4620b57cec5SDimitry Andric   VisitExpr(E);
4630b57cec5SDimitry Andric   Record.AddSourceLocation(E->getKeywordLoc());
4640b57cec5SDimitry Andric   for (Stmt *S : E->children())
4650b57cec5SDimitry Andric     Record.AddStmt(S);
4660b57cec5SDimitry Andric   Code = serialization::EXPR_DEPENDENT_COAWAIT;
4670b57cec5SDimitry Andric }
4680b57cec5SDimitry Andric 
46955e4f9d5SDimitry Andric static void
47055e4f9d5SDimitry Andric addConstraintSatisfaction(ASTRecordWriter &Record,
47155e4f9d5SDimitry Andric                           const ASTConstraintSatisfaction &Satisfaction) {
472480093f4SDimitry Andric   Record.push_back(Satisfaction.IsSatisfied);
473bdd1243dSDimitry Andric   Record.push_back(Satisfaction.ContainsErrors);
474480093f4SDimitry Andric   if (!Satisfaction.IsSatisfied) {
475480093f4SDimitry Andric     Record.push_back(Satisfaction.NumRecords);
476480093f4SDimitry Andric     for (const auto &DetailRecord : Satisfaction) {
477*0fca6ea1SDimitry Andric       auto *E = DetailRecord.dyn_cast<Expr *>();
478*0fca6ea1SDimitry Andric       Record.push_back(/* IsDiagnostic */ E == nullptr);
479480093f4SDimitry Andric       if (E)
480480093f4SDimitry Andric         Record.AddStmt(E);
481480093f4SDimitry Andric       else {
482*0fca6ea1SDimitry Andric         auto *Diag = DetailRecord.get<std::pair<SourceLocation, StringRef> *>();
483480093f4SDimitry Andric         Record.AddSourceLocation(Diag->first);
484480093f4SDimitry Andric         Record.AddString(Diag->second);
485480093f4SDimitry Andric       }
486480093f4SDimitry Andric     }
487480093f4SDimitry Andric   }
48855e4f9d5SDimitry Andric }
48955e4f9d5SDimitry Andric 
49055e4f9d5SDimitry Andric static void
49155e4f9d5SDimitry Andric addSubstitutionDiagnostic(
49255e4f9d5SDimitry Andric     ASTRecordWriter &Record,
49355e4f9d5SDimitry Andric     const concepts::Requirement::SubstitutionDiagnostic *D) {
49455e4f9d5SDimitry Andric   Record.AddString(D->SubstitutedEntity);
49555e4f9d5SDimitry Andric   Record.AddSourceLocation(D->DiagLoc);
49655e4f9d5SDimitry Andric   Record.AddString(D->DiagMessage);
49755e4f9d5SDimitry Andric }
49855e4f9d5SDimitry Andric 
49955e4f9d5SDimitry Andric void ASTStmtWriter::VisitConceptSpecializationExpr(
50055e4f9d5SDimitry Andric         ConceptSpecializationExpr *E) {
50155e4f9d5SDimitry Andric   VisitExpr(E);
502bdd1243dSDimitry Andric   Record.AddDeclRef(E->getSpecializationDecl());
5035f757f3fSDimitry Andric   const ConceptReference *CR = E->getConceptReference();
5045f757f3fSDimitry Andric   Record.push_back(CR != nullptr);
5055f757f3fSDimitry Andric   if (CR)
5065f757f3fSDimitry Andric     Record.AddConceptReference(CR);
50755e4f9d5SDimitry Andric   if (!E->isValueDependent())
50855e4f9d5SDimitry Andric     addConstraintSatisfaction(Record, E->getSatisfaction());
509480093f4SDimitry Andric 
510a7dea167SDimitry Andric   Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
511a7dea167SDimitry Andric }
512a7dea167SDimitry Andric 
51355e4f9d5SDimitry Andric void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
51455e4f9d5SDimitry Andric   VisitExpr(E);
51555e4f9d5SDimitry Andric   Record.push_back(E->getLocalParameters().size());
51655e4f9d5SDimitry Andric   Record.push_back(E->getRequirements().size());
51755e4f9d5SDimitry Andric   Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
51855e4f9d5SDimitry Andric   Record.push_back(E->RequiresExprBits.IsSatisfied);
51955e4f9d5SDimitry Andric   Record.AddDeclRef(E->getBody());
52055e4f9d5SDimitry Andric   for (ParmVarDecl *P : E->getLocalParameters())
52155e4f9d5SDimitry Andric     Record.AddDeclRef(P);
52255e4f9d5SDimitry Andric   for (concepts::Requirement *R : E->getRequirements()) {
52355e4f9d5SDimitry Andric     if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) {
52455e4f9d5SDimitry Andric       Record.push_back(concepts::Requirement::RK_Type);
52555e4f9d5SDimitry Andric       Record.push_back(TypeReq->Status);
52655e4f9d5SDimitry Andric       if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure)
52755e4f9d5SDimitry Andric         addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic());
52855e4f9d5SDimitry Andric       else
52955e4f9d5SDimitry Andric         Record.AddTypeSourceInfo(TypeReq->getType());
53055e4f9d5SDimitry Andric     } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
53155e4f9d5SDimitry Andric       Record.push_back(ExprReq->getKind());
53255e4f9d5SDimitry Andric       Record.push_back(ExprReq->Status);
53355e4f9d5SDimitry Andric       if (ExprReq->isExprSubstitutionFailure()) {
53455e4f9d5SDimitry Andric         addSubstitutionDiagnostic(Record,
53555e4f9d5SDimitry Andric          ExprReq->Value.get<concepts::Requirement::SubstitutionDiagnostic *>());
53655e4f9d5SDimitry Andric       } else
53755e4f9d5SDimitry Andric         Record.AddStmt(ExprReq->Value.get<Expr *>());
53855e4f9d5SDimitry Andric       if (ExprReq->getKind() == concepts::Requirement::RK_Compound) {
53955e4f9d5SDimitry Andric         Record.AddSourceLocation(ExprReq->NoexceptLoc);
54055e4f9d5SDimitry Andric         const auto &RetReq = ExprReq->getReturnTypeRequirement();
54155e4f9d5SDimitry Andric         if (RetReq.isSubstitutionFailure()) {
54255e4f9d5SDimitry Andric           Record.push_back(2);
54355e4f9d5SDimitry Andric           addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic());
54455e4f9d5SDimitry Andric         } else if (RetReq.isTypeConstraint()) {
54555e4f9d5SDimitry Andric           Record.push_back(1);
54655e4f9d5SDimitry Andric           Record.AddTemplateParameterList(
54755e4f9d5SDimitry Andric               RetReq.getTypeConstraintTemplateParameterList());
54855e4f9d5SDimitry Andric           if (ExprReq->Status >=
54955e4f9d5SDimitry Andric               concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
55055e4f9d5SDimitry Andric             Record.AddStmt(
55155e4f9d5SDimitry Andric                 ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr());
55255e4f9d5SDimitry Andric         } else {
55355e4f9d5SDimitry Andric           assert(RetReq.isEmpty());
55455e4f9d5SDimitry Andric           Record.push_back(0);
55555e4f9d5SDimitry Andric         }
55655e4f9d5SDimitry Andric       }
55755e4f9d5SDimitry Andric     } else {
55855e4f9d5SDimitry Andric       auto *NestedReq = cast<concepts::NestedRequirement>(R);
55955e4f9d5SDimitry Andric       Record.push_back(concepts::Requirement::RK_Nested);
560bdd1243dSDimitry Andric       Record.push_back(NestedReq->hasInvalidConstraint());
561bdd1243dSDimitry Andric       if (NestedReq->hasInvalidConstraint()) {
562bdd1243dSDimitry Andric         Record.AddString(NestedReq->getInvalidConstraintEntity());
563bdd1243dSDimitry Andric         addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
56455e4f9d5SDimitry Andric       } else {
565bdd1243dSDimitry Andric         Record.AddStmt(NestedReq->getConstraintExpr());
56655e4f9d5SDimitry Andric         if (!NestedReq->isDependent())
56755e4f9d5SDimitry Andric           addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
56855e4f9d5SDimitry Andric       }
56955e4f9d5SDimitry Andric     }
57055e4f9d5SDimitry Andric   }
5715f757f3fSDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
5725f757f3fSDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
57355e4f9d5SDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
57455e4f9d5SDimitry Andric 
57555e4f9d5SDimitry Andric   Code = serialization::EXPR_REQUIRES;
57655e4f9d5SDimitry Andric }
57755e4f9d5SDimitry Andric 
578a7dea167SDimitry Andric 
5790b57cec5SDimitry Andric void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
5800b57cec5SDimitry Andric   VisitStmt(S);
5810b57cec5SDimitry Andric   // NumCaptures
5820b57cec5SDimitry Andric   Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric   // CapturedDecl and captured region kind
5850b57cec5SDimitry Andric   Record.AddDeclRef(S->getCapturedDecl());
5860b57cec5SDimitry Andric   Record.push_back(S->getCapturedRegionKind());
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   Record.AddDeclRef(S->getCapturedRecordDecl());
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric   // Capture inits
5910b57cec5SDimitry Andric   for (auto *I : S->capture_inits())
5920b57cec5SDimitry Andric     Record.AddStmt(I);
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   // Body
5950b57cec5SDimitry Andric   Record.AddStmt(S->getCapturedStmt());
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric   // Captures
5980b57cec5SDimitry Andric   for (const auto &I : S->captures()) {
5990b57cec5SDimitry Andric     if (I.capturesThis() || I.capturesVariableArrayType())
6000b57cec5SDimitry Andric       Record.AddDeclRef(nullptr);
6010b57cec5SDimitry Andric     else
6020b57cec5SDimitry Andric       Record.AddDeclRef(I.getCapturedVar());
6030b57cec5SDimitry Andric     Record.push_back(I.getCaptureKind());
6040b57cec5SDimitry Andric     Record.AddSourceLocation(I.getLocation());
6050b57cec5SDimitry Andric   }
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric   Code = serialization::STMT_CAPTURED;
6080b57cec5SDimitry Andric }
6090b57cec5SDimitry Andric 
6100b57cec5SDimitry Andric void ASTStmtWriter::VisitExpr(Expr *E) {
6110b57cec5SDimitry Andric   VisitStmt(E);
612cb14a3feSDimitry Andric 
613cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
614cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getDependence(), /*BitsWidth=*/5);
615cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getValueKind(), /*BitsWidth=*/2);
616cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getObjectKind(), /*BitsWidth=*/3);
617cb14a3feSDimitry Andric 
6180b57cec5SDimitry Andric   Record.AddTypeRef(E->getType());
6190b57cec5SDimitry Andric }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
6220b57cec5SDimitry Andric   VisitExpr(E);
6235ffd83dbSDimitry Andric   Record.push_back(E->ConstantExprBits.ResultKind);
6245ffd83dbSDimitry Andric 
6255ffd83dbSDimitry Andric   Record.push_back(E->ConstantExprBits.APValueKind);
6265ffd83dbSDimitry Andric   Record.push_back(E->ConstantExprBits.IsUnsigned);
6275ffd83dbSDimitry Andric   Record.push_back(E->ConstantExprBits.BitWidth);
6285ffd83dbSDimitry Andric   // HasCleanup not serialized since we can just query the APValue.
6295ffd83dbSDimitry Andric   Record.push_back(E->ConstantExprBits.IsImmediateInvocation);
6305ffd83dbSDimitry Andric 
6315f757f3fSDimitry Andric   switch (E->getResultStorageKind()) {
6325f757f3fSDimitry Andric   case ConstantResultStorageKind::None:
6335ffd83dbSDimitry Andric     break;
6345f757f3fSDimitry Andric   case ConstantResultStorageKind::Int64:
6350b57cec5SDimitry Andric     Record.push_back(E->Int64Result());
6360b57cec5SDimitry Andric     break;
6375f757f3fSDimitry Andric   case ConstantResultStorageKind::APValue:
6380b57cec5SDimitry Andric     Record.AddAPValue(E->APValueResult());
6395ffd83dbSDimitry Andric     break;
6400b57cec5SDimitry Andric   }
6415ffd83dbSDimitry Andric 
6420b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
6430b57cec5SDimitry Andric   Code = serialization::EXPR_CONSTANT;
6440b57cec5SDimitry Andric }
6450b57cec5SDimitry Andric 
646fe6060f1SDimitry Andric void ASTStmtWriter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
647fe6060f1SDimitry Andric   VisitExpr(E);
648fe6060f1SDimitry Andric 
649fe6060f1SDimitry Andric   Record.AddSourceLocation(E->getLocation());
650fe6060f1SDimitry Andric   Record.AddSourceLocation(E->getLParenLocation());
651fe6060f1SDimitry Andric   Record.AddSourceLocation(E->getRParenLocation());
652fe6060f1SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
653fe6060f1SDimitry Andric 
654fe6060f1SDimitry Andric   Code = serialization::EXPR_SYCL_UNIQUE_STABLE_NAME;
655fe6060f1SDimitry Andric }
656fe6060f1SDimitry Andric 
6570b57cec5SDimitry Andric void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
6580b57cec5SDimitry Andric   VisitExpr(E);
6590b57cec5SDimitry Andric 
6600b57cec5SDimitry Andric   bool HasFunctionName = E->getFunctionName() != nullptr;
6610b57cec5SDimitry Andric   Record.push_back(HasFunctionName);
6625f757f3fSDimitry Andric   Record.push_back(
6635f757f3fSDimitry Andric       llvm::to_underlying(E->getIdentKind())); // FIXME: stable encoding
66406c3fb27SDimitry Andric   Record.push_back(E->isTransparent());
6650b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
6660b57cec5SDimitry Andric   if (HasFunctionName)
6670b57cec5SDimitry Andric     Record.AddStmt(E->getFunctionName());
6680b57cec5SDimitry Andric   Code = serialization::EXPR_PREDEFINED;
6690b57cec5SDimitry Andric }
6700b57cec5SDimitry Andric 
6710b57cec5SDimitry Andric void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
6720b57cec5SDimitry Andric   VisitExpr(E);
6730b57cec5SDimitry Andric 
674cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
675cb14a3feSDimitry Andric 
676cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hadMultipleCandidates());
677cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->refersToEnclosingVariableOrCapture());
678cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
679cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->isImmediateEscalating());
680cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->getDecl() != E->getFoundDecl());
681cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasQualifier());
682cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric   if (E->hasTemplateKWAndArgsInfo()) {
6850b57cec5SDimitry Andric     unsigned NumTemplateArgs = E->getNumTemplateArgs();
6860b57cec5SDimitry Andric     Record.push_back(NumTemplateArgs);
6870b57cec5SDimitry Andric   }
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric   DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
6920b57cec5SDimitry Andric       (E->getDecl() == E->getFoundDecl()) &&
693cb14a3feSDimitry Andric       nk == DeclarationName::Identifier && E->getObjectKind() == OK_Ordinary) {
6940b57cec5SDimitry Andric     AbbrevToUse = Writer.getDeclRefExprAbbrev();
6950b57cec5SDimitry Andric   }
6960b57cec5SDimitry Andric 
6970b57cec5SDimitry Andric   if (E->hasQualifier())
6980b57cec5SDimitry Andric     Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric   if (E->getDecl() != E->getFoundDecl())
7010b57cec5SDimitry Andric     Record.AddDeclRef(E->getFoundDecl());
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   if (E->hasTemplateKWAndArgsInfo())
7040b57cec5SDimitry Andric     AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
7050b57cec5SDimitry Andric                              E->getTrailingObjects<TemplateArgumentLoc>());
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric   Record.AddDeclRef(E->getDecl());
7080b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
7090b57cec5SDimitry Andric   Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
7100b57cec5SDimitry Andric   Code = serialization::EXPR_DECL_REF;
7110b57cec5SDimitry Andric }
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
7140b57cec5SDimitry Andric   VisitExpr(E);
7150b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
7160b57cec5SDimitry Andric   Record.AddAPInt(E->getValue());
7170b57cec5SDimitry Andric 
7180b57cec5SDimitry Andric   if (E->getValue().getBitWidth() == 32) {
7190b57cec5SDimitry Andric     AbbrevToUse = Writer.getIntegerLiteralAbbrev();
7200b57cec5SDimitry Andric   }
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   Code = serialization::EXPR_INTEGER_LITERAL;
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
7260b57cec5SDimitry Andric   VisitExpr(E);
7270b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
7285ffd83dbSDimitry Andric   Record.push_back(E->getScale());
7290b57cec5SDimitry Andric   Record.AddAPInt(E->getValue());
7305ffd83dbSDimitry Andric   Code = serialization::EXPR_FIXEDPOINT_LITERAL;
7310b57cec5SDimitry Andric }
7320b57cec5SDimitry Andric 
7330b57cec5SDimitry Andric void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
7340b57cec5SDimitry Andric   VisitExpr(E);
7350b57cec5SDimitry Andric   Record.push_back(E->getRawSemantics());
7360b57cec5SDimitry Andric   Record.push_back(E->isExact());
7370b57cec5SDimitry Andric   Record.AddAPFloat(E->getValue());
7380b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
7390b57cec5SDimitry Andric   Code = serialization::EXPR_FLOATING_LITERAL;
7400b57cec5SDimitry Andric }
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
7430b57cec5SDimitry Andric   VisitExpr(E);
7440b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
7450b57cec5SDimitry Andric   Code = serialization::EXPR_IMAGINARY_LITERAL;
7460b57cec5SDimitry Andric }
7470b57cec5SDimitry Andric 
7480b57cec5SDimitry Andric void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
7490b57cec5SDimitry Andric   VisitExpr(E);
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric   // Store the various bits of data of StringLiteral.
7520b57cec5SDimitry Andric   Record.push_back(E->getNumConcatenated());
7530b57cec5SDimitry Andric   Record.push_back(E->getLength());
7540b57cec5SDimitry Andric   Record.push_back(E->getCharByteWidth());
7555f757f3fSDimitry Andric   Record.push_back(llvm::to_underlying(E->getKind()));
7560b57cec5SDimitry Andric   Record.push_back(E->isPascal());
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   // Store the trailing array of SourceLocation.
7590b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
7600b57cec5SDimitry Andric     Record.AddSourceLocation(E->getStrTokenLoc(I));
7610b57cec5SDimitry Andric 
7620b57cec5SDimitry Andric   // Store the trailing array of char holding the string data.
7630b57cec5SDimitry Andric   StringRef StrData = E->getBytes();
7640b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getByteLength(); I != N; ++I)
7650b57cec5SDimitry Andric     Record.push_back(StrData[I]);
7660b57cec5SDimitry Andric 
7670b57cec5SDimitry Andric   Code = serialization::EXPR_STRING_LITERAL;
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
7710b57cec5SDimitry Andric   VisitExpr(E);
7720b57cec5SDimitry Andric   Record.push_back(E->getValue());
7730b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
7745f757f3fSDimitry Andric   Record.push_back(llvm::to_underlying(E->getKind()));
7750b57cec5SDimitry Andric 
7760b57cec5SDimitry Andric   AbbrevToUse = Writer.getCharacterLiteralAbbrev();
7770b57cec5SDimitry Andric 
7780b57cec5SDimitry Andric   Code = serialization::EXPR_CHARACTER_LITERAL;
7790b57cec5SDimitry Andric }
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
7820b57cec5SDimitry Andric   VisitExpr(E);
7830b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParen());
7840b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParen());
7850b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
7860b57cec5SDimitry Andric   Code = serialization::EXPR_PAREN;
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric 
7890b57cec5SDimitry Andric void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
7900b57cec5SDimitry Andric   VisitExpr(E);
7910b57cec5SDimitry Andric   Record.push_back(E->getNumExprs());
7920b57cec5SDimitry Andric   for (auto *SubStmt : E->exprs())
7930b57cec5SDimitry Andric     Record.AddStmt(SubStmt);
7940b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
7950b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
7960b57cec5SDimitry Andric   Code = serialization::EXPR_PAREN_LIST;
7970b57cec5SDimitry Andric }
7980b57cec5SDimitry Andric 
7990b57cec5SDimitry Andric void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
8000b57cec5SDimitry Andric   VisitExpr(E);
8015ffd83dbSDimitry Andric   bool HasFPFeatures = E->hasStoredFPFeatures();
8025ffd83dbSDimitry Andric   // Write this first for easy access when deserializing, as they affect the
8035ffd83dbSDimitry Andric   // size of the UnaryOperator.
804cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasFPFeatures);
8050b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
806cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getOpcode(),
807cb14a3feSDimitry Andric                              /*Width=*/5); // FIXME: stable encoding
8080b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
809cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->canOverflow());
810cb14a3feSDimitry Andric 
8115ffd83dbSDimitry Andric   if (HasFPFeatures)
8125ffd83dbSDimitry Andric     Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
8130b57cec5SDimitry Andric   Code = serialization::EXPR_UNARY_OPERATOR;
8140b57cec5SDimitry Andric }
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
8170b57cec5SDimitry Andric   VisitExpr(E);
8180b57cec5SDimitry Andric   Record.push_back(E->getNumComponents());
8190b57cec5SDimitry Andric   Record.push_back(E->getNumExpressions());
8200b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
8210b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
8220b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
8230b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
8240b57cec5SDimitry Andric     const OffsetOfNode &ON = E->getComponent(I);
8250b57cec5SDimitry Andric     Record.push_back(ON.getKind()); // FIXME: Stable encoding
8260b57cec5SDimitry Andric     Record.AddSourceLocation(ON.getSourceRange().getBegin());
8270b57cec5SDimitry Andric     Record.AddSourceLocation(ON.getSourceRange().getEnd());
8280b57cec5SDimitry Andric     switch (ON.getKind()) {
8290b57cec5SDimitry Andric     case OffsetOfNode::Array:
8300b57cec5SDimitry Andric       Record.push_back(ON.getArrayExprIndex());
8310b57cec5SDimitry Andric       break;
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric     case OffsetOfNode::Field:
8340b57cec5SDimitry Andric       Record.AddDeclRef(ON.getField());
8350b57cec5SDimitry Andric       break;
8360b57cec5SDimitry Andric 
8370b57cec5SDimitry Andric     case OffsetOfNode::Identifier:
8380b57cec5SDimitry Andric       Record.AddIdentifierRef(ON.getFieldName());
8390b57cec5SDimitry Andric       break;
8400b57cec5SDimitry Andric 
8410b57cec5SDimitry Andric     case OffsetOfNode::Base:
8420b57cec5SDimitry Andric       Record.AddCXXBaseSpecifier(*ON.getBase());
8430b57cec5SDimitry Andric       break;
8440b57cec5SDimitry Andric     }
8450b57cec5SDimitry Andric   }
8460b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
8470b57cec5SDimitry Andric     Record.AddStmt(E->getIndexExpr(I));
8480b57cec5SDimitry Andric   Code = serialization::EXPR_OFFSETOF;
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
8520b57cec5SDimitry Andric   VisitExpr(E);
8530b57cec5SDimitry Andric   Record.push_back(E->getKind());
8540b57cec5SDimitry Andric   if (E->isArgumentType())
8550b57cec5SDimitry Andric     Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
8560b57cec5SDimitry Andric   else {
8570b57cec5SDimitry Andric     Record.push_back(0);
8580b57cec5SDimitry Andric     Record.AddStmt(E->getArgumentExpr());
8590b57cec5SDimitry Andric   }
8600b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
8610b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
8620b57cec5SDimitry Andric   Code = serialization::EXPR_SIZEOF_ALIGN_OF;
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
8660b57cec5SDimitry Andric   VisitExpr(E);
8670b57cec5SDimitry Andric   Record.AddStmt(E->getLHS());
8680b57cec5SDimitry Andric   Record.AddStmt(E->getRHS());
8690b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRBracketLoc());
8700b57cec5SDimitry Andric   Code = serialization::EXPR_ARRAY_SUBSCRIPT;
8710b57cec5SDimitry Andric }
8720b57cec5SDimitry Andric 
8735ffd83dbSDimitry Andric void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
8745ffd83dbSDimitry Andric   VisitExpr(E);
8755ffd83dbSDimitry Andric   Record.AddStmt(E->getBase());
8765ffd83dbSDimitry Andric   Record.AddStmt(E->getRowIdx());
8775ffd83dbSDimitry Andric   Record.AddStmt(E->getColumnIdx());
8785ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getRBracketLoc());
8795ffd83dbSDimitry Andric   Code = serialization::EXPR_ARRAY_SUBSCRIPT;
8805ffd83dbSDimitry Andric }
8815ffd83dbSDimitry Andric 
882*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitArraySectionExpr(ArraySectionExpr *E) {
8830b57cec5SDimitry Andric   VisitExpr(E);
884*0fca6ea1SDimitry Andric   Record.writeEnum(E->ASType);
8850b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
8860b57cec5SDimitry Andric   Record.AddStmt(E->getLowerBound());
8870b57cec5SDimitry Andric   Record.AddStmt(E->getLength());
888*0fca6ea1SDimitry Andric   if (E->isOMPArraySection())
8895ffd83dbSDimitry Andric     Record.AddStmt(E->getStride());
8905ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getColonLocFirst());
891*0fca6ea1SDimitry Andric 
892*0fca6ea1SDimitry Andric   if (E->isOMPArraySection())
8935ffd83dbSDimitry Andric     Record.AddSourceLocation(E->getColonLocSecond());
894*0fca6ea1SDimitry Andric 
8950b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRBracketLoc());
896*0fca6ea1SDimitry Andric   Code = serialization::EXPR_ARRAY_SECTION;
8970b57cec5SDimitry Andric }
8980b57cec5SDimitry Andric 
8995ffd83dbSDimitry Andric void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
9005ffd83dbSDimitry Andric   VisitExpr(E);
9015ffd83dbSDimitry Andric   Record.push_back(E->getDimensions().size());
9025ffd83dbSDimitry Andric   Record.AddStmt(E->getBase());
9035ffd83dbSDimitry Andric   for (Expr *Dim : E->getDimensions())
9045ffd83dbSDimitry Andric     Record.AddStmt(Dim);
9055ffd83dbSDimitry Andric   for (SourceRange SR : E->getBracketsRanges())
9065ffd83dbSDimitry Andric     Record.AddSourceRange(SR);
9075ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
9085ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
9095ffd83dbSDimitry Andric   Code = serialization::EXPR_OMP_ARRAY_SHAPING;
9105ffd83dbSDimitry Andric }
9115ffd83dbSDimitry Andric 
9125ffd83dbSDimitry Andric void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
9135ffd83dbSDimitry Andric   VisitExpr(E);
9145ffd83dbSDimitry Andric   Record.push_back(E->numOfIterators());
9155ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getIteratorKwLoc());
9165ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
9175ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
9185ffd83dbSDimitry Andric   for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
9195ffd83dbSDimitry Andric     Record.AddDeclRef(E->getIteratorDecl(I));
9205ffd83dbSDimitry Andric     Record.AddSourceLocation(E->getAssignLoc(I));
9215ffd83dbSDimitry Andric     OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
9225ffd83dbSDimitry Andric     Record.AddStmt(Range.Begin);
9235ffd83dbSDimitry Andric     Record.AddStmt(Range.End);
9245ffd83dbSDimitry Andric     Record.AddStmt(Range.Step);
9255ffd83dbSDimitry Andric     Record.AddSourceLocation(E->getColonLoc(I));
9265ffd83dbSDimitry Andric     if (Range.Step)
9275ffd83dbSDimitry Andric       Record.AddSourceLocation(E->getSecondColonLoc(I));
9285ffd83dbSDimitry Andric     // Serialize helpers
9295ffd83dbSDimitry Andric     OMPIteratorHelperData &HD = E->getHelper(I);
9305ffd83dbSDimitry Andric     Record.AddDeclRef(HD.CounterVD);
9315ffd83dbSDimitry Andric     Record.AddStmt(HD.Upper);
9325ffd83dbSDimitry Andric     Record.AddStmt(HD.Update);
9335ffd83dbSDimitry Andric     Record.AddStmt(HD.CounterUpdate);
9345ffd83dbSDimitry Andric   }
9355ffd83dbSDimitry Andric   Code = serialization::EXPR_OMP_ITERATOR;
9365ffd83dbSDimitry Andric }
9375ffd83dbSDimitry Andric 
9380b57cec5SDimitry Andric void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
9390b57cec5SDimitry Andric   VisitExpr(E);
9405f757f3fSDimitry Andric 
941cb14a3feSDimitry Andric   Record.push_back(E->getNumArgs());
942cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
943cb14a3feSDimitry Andric   CurrentPackingBits.addBit(static_cast<bool>(E->getADLCallKind()));
944cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasStoredFPFeatures());
9455f757f3fSDimitry Andric 
9460b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
9470b57cec5SDimitry Andric   Record.AddStmt(E->getCallee());
9480b57cec5SDimitry Andric   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
9490b57cec5SDimitry Andric        Arg != ArgEnd; ++Arg)
9500b57cec5SDimitry Andric     Record.AddStmt(*Arg);
9515f757f3fSDimitry Andric 
952e8d8bef9SDimitry Andric   if (E->hasStoredFPFeatures())
953e8d8bef9SDimitry Andric     Record.push_back(E->getFPFeatures().getAsOpaqueInt());
954cb14a3feSDimitry Andric 
955cb14a3feSDimitry Andric   if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()) &&
956cb14a3feSDimitry Andric       E->getStmtClass() == Stmt::CallExprClass)
957cb14a3feSDimitry Andric     AbbrevToUse = Writer.getCallExprAbbrev();
958cb14a3feSDimitry Andric 
9590b57cec5SDimitry Andric   Code = serialization::EXPR_CALL;
9600b57cec5SDimitry Andric }
9610b57cec5SDimitry Andric 
9625ffd83dbSDimitry Andric void ASTStmtWriter::VisitRecoveryExpr(RecoveryExpr *E) {
9635ffd83dbSDimitry Andric   VisitExpr(E);
9645ffd83dbSDimitry Andric   Record.push_back(std::distance(E->children().begin(), E->children().end()));
9655ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
9665ffd83dbSDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
9675ffd83dbSDimitry Andric   for (Stmt *Child : E->children())
9685ffd83dbSDimitry Andric     Record.AddStmt(Child);
9695ffd83dbSDimitry Andric   Code = serialization::EXPR_RECOVERY;
9705ffd83dbSDimitry Andric }
9715ffd83dbSDimitry Andric 
9720b57cec5SDimitry Andric void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
9730b57cec5SDimitry Andric   VisitExpr(E);
9740b57cec5SDimitry Andric 
9750b57cec5SDimitry Andric   bool HasQualifier = E->hasQualifier();
976*0fca6ea1SDimitry Andric   bool HasFoundDecl = E->hasFoundDecl();
9770b57cec5SDimitry Andric   bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
9780b57cec5SDimitry Andric   unsigned NumTemplateArgs = E->getNumTemplateArgs();
9790b57cec5SDimitry Andric 
9800b57cec5SDimitry Andric   // Write these first for easy access when deserializing, as they affect the
9810b57cec5SDimitry Andric   // size of the MemberExpr.
982cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
983cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasQualifier);
984cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasFoundDecl);
985cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasTemplateInfo);
9860b57cec5SDimitry Andric   Record.push_back(NumTemplateArgs);
9870b57cec5SDimitry Andric 
9880b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
9890b57cec5SDimitry Andric   Record.AddDeclRef(E->getMemberDecl());
9900b57cec5SDimitry Andric   Record.AddDeclarationNameLoc(E->MemberDNLoc,
9910b57cec5SDimitry Andric                                E->getMemberDecl()->getDeclName());
9920b57cec5SDimitry Andric   Record.AddSourceLocation(E->getMemberLoc());
993cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->isArrow());
994cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hadMultipleCandidates());
995cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->isNonOdrUse(), /*Width=*/2);
9960b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
9970b57cec5SDimitry Andric 
998*0fca6ea1SDimitry Andric   if (HasQualifier)
999*0fca6ea1SDimitry Andric     Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
1000*0fca6ea1SDimitry Andric 
10010b57cec5SDimitry Andric   if (HasFoundDecl) {
10020b57cec5SDimitry Andric     DeclAccessPair FoundDecl = E->getFoundDecl();
10030b57cec5SDimitry Andric     Record.AddDeclRef(FoundDecl.getDecl());
1004cb14a3feSDimitry Andric     CurrentPackingBits.addBits(FoundDecl.getAccess(), /*BitWidth=*/2);
10050b57cec5SDimitry Andric   }
10060b57cec5SDimitry Andric 
10070b57cec5SDimitry Andric   if (HasTemplateInfo)
10080b57cec5SDimitry Andric     AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
10090b57cec5SDimitry Andric                              E->getTrailingObjects<TemplateArgumentLoc>());
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric   Code = serialization::EXPR_MEMBER;
10120b57cec5SDimitry Andric }
10130b57cec5SDimitry Andric 
10140b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
10150b57cec5SDimitry Andric   VisitExpr(E);
10160b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
10170b57cec5SDimitry Andric   Record.AddSourceLocation(E->getIsaMemberLoc());
10180b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOpLoc());
10190b57cec5SDimitry Andric   Record.push_back(E->isArrow());
10200b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_ISA;
10210b57cec5SDimitry Andric }
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric void ASTStmtWriter::
10240b57cec5SDimitry Andric VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
10250b57cec5SDimitry Andric   VisitExpr(E);
10260b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
10270b57cec5SDimitry Andric   Record.push_back(E->shouldCopy());
10280b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
10290b57cec5SDimitry Andric }
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
10320b57cec5SDimitry Andric   VisitExplicitCastExpr(E);
10330b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
10340b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBridgeKeywordLoc());
10350b57cec5SDimitry Andric   Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
10360b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_BRIDGED_CAST;
10370b57cec5SDimitry Andric }
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
10400b57cec5SDimitry Andric   VisitExpr(E);
1041cb14a3feSDimitry Andric 
10420b57cec5SDimitry Andric   Record.push_back(E->path_size());
1043cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
1044cb14a3feSDimitry Andric   // 7 bits should be enough to store the casting kinds.
1045cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getCastKind(), /*Width=*/7);
1046cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasStoredFPFeatures());
10470b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
10480b57cec5SDimitry Andric 
10490b57cec5SDimitry Andric   for (CastExpr::path_iterator
10500b57cec5SDimitry Andric          PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
10510b57cec5SDimitry Andric     Record.AddCXXBaseSpecifier(**PI);
1052e8d8bef9SDimitry Andric 
1053e8d8bef9SDimitry Andric   if (E->hasStoredFPFeatures())
1054e8d8bef9SDimitry Andric     Record.push_back(E->getFPFeatures().getAsOpaqueInt());
10550b57cec5SDimitry Andric }
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
10580b57cec5SDimitry Andric   VisitExpr(E);
1059cb14a3feSDimitry Andric 
10605ffd83dbSDimitry Andric   // Write this first for easy access when deserializing, as they affect the
10615ffd83dbSDimitry Andric   // size of the UnaryOperator.
1062cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
1063cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getOpcode(), /*Width=*/6);
1064cb14a3feSDimitry Andric   bool HasFPFeatures = E->hasStoredFPFeatures();
1065cb14a3feSDimitry Andric   CurrentPackingBits.addBit(HasFPFeatures);
10660b57cec5SDimitry Andric   Record.AddStmt(E->getLHS());
10670b57cec5SDimitry Andric   Record.AddStmt(E->getRHS());
10680b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
10695ffd83dbSDimitry Andric   if (HasFPFeatures)
10705ffd83dbSDimitry Andric     Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
1071cb14a3feSDimitry Andric 
1072cb14a3feSDimitry Andric   if (!HasFPFeatures && E->getValueKind() == VK_PRValue &&
1073cb14a3feSDimitry Andric       E->getObjectKind() == OK_Ordinary)
1074cb14a3feSDimitry Andric     AbbrevToUse = Writer.getBinaryOperatorAbbrev();
1075cb14a3feSDimitry Andric 
10760b57cec5SDimitry Andric   Code = serialization::EXPR_BINARY_OPERATOR;
10770b57cec5SDimitry Andric }
10780b57cec5SDimitry Andric 
10790b57cec5SDimitry Andric void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
10800b57cec5SDimitry Andric   VisitBinaryOperator(E);
10810b57cec5SDimitry Andric   Record.AddTypeRef(E->getComputationLHSType());
10820b57cec5SDimitry Andric   Record.AddTypeRef(E->getComputationResultType());
1083cb14a3feSDimitry Andric 
1084cb14a3feSDimitry Andric   if (!E->hasStoredFPFeatures() && E->getValueKind() == VK_PRValue &&
1085cb14a3feSDimitry Andric       E->getObjectKind() == OK_Ordinary)
1086cb14a3feSDimitry Andric     AbbrevToUse = Writer.getCompoundAssignOperatorAbbrev();
1087cb14a3feSDimitry Andric 
10880b57cec5SDimitry Andric   Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
10890b57cec5SDimitry Andric }
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
10920b57cec5SDimitry Andric   VisitExpr(E);
10930b57cec5SDimitry Andric   Record.AddStmt(E->getCond());
10940b57cec5SDimitry Andric   Record.AddStmt(E->getLHS());
10950b57cec5SDimitry Andric   Record.AddStmt(E->getRHS());
10960b57cec5SDimitry Andric   Record.AddSourceLocation(E->getQuestionLoc());
10970b57cec5SDimitry Andric   Record.AddSourceLocation(E->getColonLoc());
10980b57cec5SDimitry Andric   Code = serialization::EXPR_CONDITIONAL_OPERATOR;
10990b57cec5SDimitry Andric }
11000b57cec5SDimitry Andric 
11010b57cec5SDimitry Andric void
11020b57cec5SDimitry Andric ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
11030b57cec5SDimitry Andric   VisitExpr(E);
11040b57cec5SDimitry Andric   Record.AddStmt(E->getOpaqueValue());
11050b57cec5SDimitry Andric   Record.AddStmt(E->getCommon());
11060b57cec5SDimitry Andric   Record.AddStmt(E->getCond());
11070b57cec5SDimitry Andric   Record.AddStmt(E->getTrueExpr());
11080b57cec5SDimitry Andric   Record.AddStmt(E->getFalseExpr());
11090b57cec5SDimitry Andric   Record.AddSourceLocation(E->getQuestionLoc());
11100b57cec5SDimitry Andric   Record.AddSourceLocation(E->getColonLoc());
11110b57cec5SDimitry Andric   Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
11120b57cec5SDimitry Andric }
11130b57cec5SDimitry Andric 
11140b57cec5SDimitry Andric void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
11150b57cec5SDimitry Andric   VisitCastExpr(E);
1116cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->isPartOfExplicitCast());
11170b57cec5SDimitry Andric 
1118e8d8bef9SDimitry Andric   if (E->path_size() == 0 && !E->hasStoredFPFeatures())
11190b57cec5SDimitry Andric     AbbrevToUse = Writer.getExprImplicitCastAbbrev();
11200b57cec5SDimitry Andric 
11210b57cec5SDimitry Andric   Code = serialization::EXPR_IMPLICIT_CAST;
11220b57cec5SDimitry Andric }
11230b57cec5SDimitry Andric 
11240b57cec5SDimitry Andric void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
11250b57cec5SDimitry Andric   VisitCastExpr(E);
11260b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
11270b57cec5SDimitry Andric }
11280b57cec5SDimitry Andric 
11290b57cec5SDimitry Andric void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
11300b57cec5SDimitry Andric   VisitExplicitCastExpr(E);
11310b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
11320b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
11330b57cec5SDimitry Andric   Code = serialization::EXPR_CSTYLE_CAST;
11340b57cec5SDimitry Andric }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
11370b57cec5SDimitry Andric   VisitExpr(E);
11380b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
11390b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
11400b57cec5SDimitry Andric   Record.AddStmt(E->getInitializer());
11410b57cec5SDimitry Andric   Record.push_back(E->isFileScope());
11420b57cec5SDimitry Andric   Code = serialization::EXPR_COMPOUND_LITERAL;
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
11460b57cec5SDimitry Andric   VisitExpr(E);
11470b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
11480b57cec5SDimitry Andric   Record.AddIdentifierRef(&E->getAccessor());
11490b57cec5SDimitry Andric   Record.AddSourceLocation(E->getAccessorLoc());
11500b57cec5SDimitry Andric   Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
11510b57cec5SDimitry Andric }
11520b57cec5SDimitry Andric 
11530b57cec5SDimitry Andric void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
11540b57cec5SDimitry Andric   VisitExpr(E);
11550b57cec5SDimitry Andric   // NOTE: only add the (possibly null) syntactic form.
11560b57cec5SDimitry Andric   // No need to serialize the isSemanticForm flag and the semantic form.
11570b57cec5SDimitry Andric   Record.AddStmt(E->getSyntacticForm());
11580b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLBraceLoc());
11590b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRBraceLoc());
11600b57cec5SDimitry Andric   bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
11610b57cec5SDimitry Andric   Record.push_back(isArrayFiller);
11620b57cec5SDimitry Andric   if (isArrayFiller)
11630b57cec5SDimitry Andric     Record.AddStmt(E->getArrayFiller());
11640b57cec5SDimitry Andric   else
11650b57cec5SDimitry Andric     Record.AddDeclRef(E->getInitializedFieldInUnion());
11660b57cec5SDimitry Andric   Record.push_back(E->hadArrayRangeDesignator());
11670b57cec5SDimitry Andric   Record.push_back(E->getNumInits());
11680b57cec5SDimitry Andric   if (isArrayFiller) {
11690b57cec5SDimitry Andric     // ArrayFiller may have filled "holes" due to designated initializer.
11700b57cec5SDimitry Andric     // Replace them by 0 to indicate that the filler goes in that place.
11710b57cec5SDimitry Andric     Expr *filler = E->getArrayFiller();
11720b57cec5SDimitry Andric     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
11730b57cec5SDimitry Andric       Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
11740b57cec5SDimitry Andric   } else {
11750b57cec5SDimitry Andric     for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
11760b57cec5SDimitry Andric       Record.AddStmt(E->getInit(I));
11770b57cec5SDimitry Andric   }
11780b57cec5SDimitry Andric   Code = serialization::EXPR_INIT_LIST;
11790b57cec5SDimitry Andric }
11800b57cec5SDimitry Andric 
11810b57cec5SDimitry Andric void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
11820b57cec5SDimitry Andric   VisitExpr(E);
11830b57cec5SDimitry Andric   Record.push_back(E->getNumSubExprs());
11840b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
11850b57cec5SDimitry Andric     Record.AddStmt(E->getSubExpr(I));
11860b57cec5SDimitry Andric   Record.AddSourceLocation(E->getEqualOrColonLoc());
11870b57cec5SDimitry Andric   Record.push_back(E->usesGNUSyntax());
11880b57cec5SDimitry Andric   for (const DesignatedInitExpr::Designator &D : E->designators()) {
11890b57cec5SDimitry Andric     if (D.isFieldDesignator()) {
119006c3fb27SDimitry Andric       if (FieldDecl *Field = D.getFieldDecl()) {
11910b57cec5SDimitry Andric         Record.push_back(serialization::DESIG_FIELD_DECL);
11920b57cec5SDimitry Andric         Record.AddDeclRef(Field);
11930b57cec5SDimitry Andric       } else {
11940b57cec5SDimitry Andric         Record.push_back(serialization::DESIG_FIELD_NAME);
11950b57cec5SDimitry Andric         Record.AddIdentifierRef(D.getFieldName());
11960b57cec5SDimitry Andric       }
11970b57cec5SDimitry Andric       Record.AddSourceLocation(D.getDotLoc());
11980b57cec5SDimitry Andric       Record.AddSourceLocation(D.getFieldLoc());
11990b57cec5SDimitry Andric     } else if (D.isArrayDesignator()) {
12000b57cec5SDimitry Andric       Record.push_back(serialization::DESIG_ARRAY);
120106c3fb27SDimitry Andric       Record.push_back(D.getArrayIndex());
12020b57cec5SDimitry Andric       Record.AddSourceLocation(D.getLBracketLoc());
12030b57cec5SDimitry Andric       Record.AddSourceLocation(D.getRBracketLoc());
12040b57cec5SDimitry Andric     } else {
12050b57cec5SDimitry Andric       assert(D.isArrayRangeDesignator() && "Unknown designator");
12060b57cec5SDimitry Andric       Record.push_back(serialization::DESIG_ARRAY_RANGE);
120706c3fb27SDimitry Andric       Record.push_back(D.getArrayIndex());
12080b57cec5SDimitry Andric       Record.AddSourceLocation(D.getLBracketLoc());
12090b57cec5SDimitry Andric       Record.AddSourceLocation(D.getEllipsisLoc());
12100b57cec5SDimitry Andric       Record.AddSourceLocation(D.getRBracketLoc());
12110b57cec5SDimitry Andric     }
12120b57cec5SDimitry Andric   }
12130b57cec5SDimitry Andric   Code = serialization::EXPR_DESIGNATED_INIT;
12140b57cec5SDimitry Andric }
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
12170b57cec5SDimitry Andric   VisitExpr(E);
12180b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
12190b57cec5SDimitry Andric   Record.AddStmt(E->getUpdater());
12200b57cec5SDimitry Andric   Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
12210b57cec5SDimitry Andric }
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
12240b57cec5SDimitry Andric   VisitExpr(E);
12250b57cec5SDimitry Andric   Code = serialization::EXPR_NO_INIT;
12260b57cec5SDimitry Andric }
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
12290b57cec5SDimitry Andric   VisitExpr(E);
12300b57cec5SDimitry Andric   Record.AddStmt(E->SubExprs[0]);
12310b57cec5SDimitry Andric   Record.AddStmt(E->SubExprs[1]);
12320b57cec5SDimitry Andric   Code = serialization::EXPR_ARRAY_INIT_LOOP;
12330b57cec5SDimitry Andric }
12340b57cec5SDimitry Andric 
12350b57cec5SDimitry Andric void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
12360b57cec5SDimitry Andric   VisitExpr(E);
12370b57cec5SDimitry Andric   Code = serialization::EXPR_ARRAY_INIT_INDEX;
12380b57cec5SDimitry Andric }
12390b57cec5SDimitry Andric 
12400b57cec5SDimitry Andric void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
12410b57cec5SDimitry Andric   VisitExpr(E);
12420b57cec5SDimitry Andric   Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
12430b57cec5SDimitry Andric }
12440b57cec5SDimitry Andric 
12450b57cec5SDimitry Andric void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
12460b57cec5SDimitry Andric   VisitExpr(E);
12470b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
12480b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
12490b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBuiltinLoc());
12500b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
12510b57cec5SDimitry Andric   Record.push_back(E->isMicrosoftABI());
12520b57cec5SDimitry Andric   Code = serialization::EXPR_VA_ARG;
12530b57cec5SDimitry Andric }
12540b57cec5SDimitry Andric 
12550b57cec5SDimitry Andric void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
12560b57cec5SDimitry Andric   VisitExpr(E);
12570b57cec5SDimitry Andric   Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
12580b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
12590b57cec5SDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
12605f757f3fSDimitry Andric   Record.push_back(llvm::to_underlying(E->getIdentKind()));
12610b57cec5SDimitry Andric   Code = serialization::EXPR_SOURCE_LOC;
12620b57cec5SDimitry Andric }
12630b57cec5SDimitry Andric 
1264*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitEmbedExpr(EmbedExpr *E) {
1265*0fca6ea1SDimitry Andric   VisitExpr(E);
1266*0fca6ea1SDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
1267*0fca6ea1SDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
1268*0fca6ea1SDimitry Andric   Record.AddStmt(E->getDataStringLiteral());
1269*0fca6ea1SDimitry Andric   Record.writeUInt32(E->getStartingElementPos());
1270*0fca6ea1SDimitry Andric   Record.writeUInt32(E->getDataElementCount());
1271*0fca6ea1SDimitry Andric   Code = serialization::EXPR_BUILTIN_PP_EMBED;
1272*0fca6ea1SDimitry Andric }
1273*0fca6ea1SDimitry Andric 
12740b57cec5SDimitry Andric void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
12750b57cec5SDimitry Andric   VisitExpr(E);
12760b57cec5SDimitry Andric   Record.AddSourceLocation(E->getAmpAmpLoc());
12770b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLabelLoc());
12780b57cec5SDimitry Andric   Record.AddDeclRef(E->getLabel());
12790b57cec5SDimitry Andric   Code = serialization::EXPR_ADDR_LABEL;
12800b57cec5SDimitry Andric }
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
12830b57cec5SDimitry Andric   VisitExpr(E);
12840b57cec5SDimitry Andric   Record.AddStmt(E->getSubStmt());
12850b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
12860b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
1287cd675bb6SDimitry Andric   Record.push_back(E->getTemplateDepth());
12880b57cec5SDimitry Andric   Code = serialization::EXPR_STMT;
12890b57cec5SDimitry Andric }
12900b57cec5SDimitry Andric 
12910b57cec5SDimitry Andric void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
12920b57cec5SDimitry Andric   VisitExpr(E);
12930b57cec5SDimitry Andric   Record.AddStmt(E->getCond());
12940b57cec5SDimitry Andric   Record.AddStmt(E->getLHS());
12950b57cec5SDimitry Andric   Record.AddStmt(E->getRHS());
12960b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBuiltinLoc());
12970b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
12980b57cec5SDimitry Andric   Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
12990b57cec5SDimitry Andric   Code = serialization::EXPR_CHOOSE;
13000b57cec5SDimitry Andric }
13010b57cec5SDimitry Andric 
13020b57cec5SDimitry Andric void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
13030b57cec5SDimitry Andric   VisitExpr(E);
13040b57cec5SDimitry Andric   Record.AddSourceLocation(E->getTokenLocation());
13050b57cec5SDimitry Andric   Code = serialization::EXPR_GNU_NULL;
13060b57cec5SDimitry Andric }
13070b57cec5SDimitry Andric 
13080b57cec5SDimitry Andric void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
13090b57cec5SDimitry Andric   VisitExpr(E);
13100b57cec5SDimitry Andric   Record.push_back(E->getNumSubExprs());
13110b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
13120b57cec5SDimitry Andric     Record.AddStmt(E->getExpr(I));
13130b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBuiltinLoc());
13140b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
13150b57cec5SDimitry Andric   Code = serialization::EXPR_SHUFFLE_VECTOR;
13160b57cec5SDimitry Andric }
13170b57cec5SDimitry Andric 
13180b57cec5SDimitry Andric void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
13190b57cec5SDimitry Andric   VisitExpr(E);
13200b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBuiltinLoc());
13210b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
13220b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
13230b57cec5SDimitry Andric   Record.AddStmt(E->getSrcExpr());
13240b57cec5SDimitry Andric   Code = serialization::EXPR_CONVERT_VECTOR;
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric 
13270b57cec5SDimitry Andric void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
13280b57cec5SDimitry Andric   VisitExpr(E);
13290b57cec5SDimitry Andric   Record.AddDeclRef(E->getBlockDecl());
13300b57cec5SDimitry Andric   Code = serialization::EXPR_BLOCK;
13310b57cec5SDimitry Andric }
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
13340b57cec5SDimitry Andric   VisitExpr(E);
13350b57cec5SDimitry Andric 
13360b57cec5SDimitry Andric   Record.push_back(E->getNumAssocs());
133706c3fb27SDimitry Andric   Record.push_back(E->isExprPredicate());
13380b57cec5SDimitry Andric   Record.push_back(E->ResultIndex);
13390b57cec5SDimitry Andric   Record.AddSourceLocation(E->getGenericLoc());
13400b57cec5SDimitry Andric   Record.AddSourceLocation(E->getDefaultLoc());
13410b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
13420b57cec5SDimitry Andric 
13430b57cec5SDimitry Andric   Stmt **Stmts = E->getTrailingObjects<Stmt *>();
13440b57cec5SDimitry Andric   // Add 1 to account for the controlling expression which is the first
13450b57cec5SDimitry Andric   // expression in the trailing array of Stmt *. This is not needed for
13460b57cec5SDimitry Andric   // the trailing array of TypeSourceInfo *.
13470b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
13480b57cec5SDimitry Andric     Record.AddStmt(Stmts[I]);
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric   TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
13510b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
13520b57cec5SDimitry Andric     Record.AddTypeSourceInfo(TSIs[I]);
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric   Code = serialization::EXPR_GENERIC_SELECTION;
13550b57cec5SDimitry Andric }
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
13580b57cec5SDimitry Andric   VisitExpr(E);
13590b57cec5SDimitry Andric   Record.push_back(E->getNumSemanticExprs());
13600b57cec5SDimitry Andric 
13610b57cec5SDimitry Andric   // Push the result index.  Currently, this needs to exactly match
13620b57cec5SDimitry Andric   // the encoding used internally for ResultIndex.
13630b57cec5SDimitry Andric   unsigned result = E->getResultExprIndex();
13640b57cec5SDimitry Andric   result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
13650b57cec5SDimitry Andric   Record.push_back(result);
13660b57cec5SDimitry Andric 
13670b57cec5SDimitry Andric   Record.AddStmt(E->getSyntacticForm());
13680b57cec5SDimitry Andric   for (PseudoObjectExpr::semantics_iterator
13690b57cec5SDimitry Andric          i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
13700b57cec5SDimitry Andric     Record.AddStmt(*i);
13710b57cec5SDimitry Andric   }
13720b57cec5SDimitry Andric   Code = serialization::EXPR_PSEUDO_OBJECT;
13730b57cec5SDimitry Andric }
13740b57cec5SDimitry Andric 
13750b57cec5SDimitry Andric void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
13760b57cec5SDimitry Andric   VisitExpr(E);
13770b57cec5SDimitry Andric   Record.push_back(E->getOp());
13780b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
13790b57cec5SDimitry Andric     Record.AddStmt(E->getSubExprs()[I]);
13800b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBuiltinLoc());
13810b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
13820b57cec5SDimitry Andric   Code = serialization::EXPR_ATOMIC;
13830b57cec5SDimitry Andric }
13840b57cec5SDimitry Andric 
13850b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13860b57cec5SDimitry Andric // Objective-C Expressions and Statements.
13870b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13880b57cec5SDimitry Andric 
13890b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
13900b57cec5SDimitry Andric   VisitExpr(E);
13910b57cec5SDimitry Andric   Record.AddStmt(E->getString());
13920b57cec5SDimitry Andric   Record.AddSourceLocation(E->getAtLoc());
13930b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_STRING_LITERAL;
13940b57cec5SDimitry Andric }
13950b57cec5SDimitry Andric 
13960b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
13970b57cec5SDimitry Andric   VisitExpr(E);
13980b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
13990b57cec5SDimitry Andric   Record.AddDeclRef(E->getBoxingMethod());
14000b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
14010b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
14020b57cec5SDimitry Andric }
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
14050b57cec5SDimitry Andric   VisitExpr(E);
14060b57cec5SDimitry Andric   Record.push_back(E->getNumElements());
14070b57cec5SDimitry Andric   for (unsigned i = 0; i < E->getNumElements(); i++)
14080b57cec5SDimitry Andric     Record.AddStmt(E->getElement(i));
14090b57cec5SDimitry Andric   Record.AddDeclRef(E->getArrayWithObjectsMethod());
14100b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
14110b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
14120b57cec5SDimitry Andric }
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
14150b57cec5SDimitry Andric   VisitExpr(E);
14160b57cec5SDimitry Andric   Record.push_back(E->getNumElements());
14170b57cec5SDimitry Andric   Record.push_back(E->HasPackExpansions);
14180b57cec5SDimitry Andric   for (unsigned i = 0; i < E->getNumElements(); i++) {
14190b57cec5SDimitry Andric     ObjCDictionaryElement Element = E->getKeyValueElement(i);
14200b57cec5SDimitry Andric     Record.AddStmt(Element.Key);
14210b57cec5SDimitry Andric     Record.AddStmt(Element.Value);
14220b57cec5SDimitry Andric     if (E->HasPackExpansions) {
14230b57cec5SDimitry Andric       Record.AddSourceLocation(Element.EllipsisLoc);
14240b57cec5SDimitry Andric       unsigned NumExpansions = 0;
14250b57cec5SDimitry Andric       if (Element.NumExpansions)
14260b57cec5SDimitry Andric         NumExpansions = *Element.NumExpansions + 1;
14270b57cec5SDimitry Andric       Record.push_back(NumExpansions);
14280b57cec5SDimitry Andric     }
14290b57cec5SDimitry Andric   }
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric   Record.AddDeclRef(E->getDictWithObjectsMethod());
14320b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
14330b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
14340b57cec5SDimitry Andric }
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
14370b57cec5SDimitry Andric   VisitExpr(E);
14380b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
14390b57cec5SDimitry Andric   Record.AddSourceLocation(E->getAtLoc());
14400b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
14410b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_ENCODE;
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
14450b57cec5SDimitry Andric   VisitExpr(E);
14460b57cec5SDimitry Andric   Record.AddSelectorRef(E->getSelector());
14470b57cec5SDimitry Andric   Record.AddSourceLocation(E->getAtLoc());
14480b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
14490b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric 
14520b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
14530b57cec5SDimitry Andric   VisitExpr(E);
14540b57cec5SDimitry Andric   Record.AddDeclRef(E->getProtocol());
14550b57cec5SDimitry Andric   Record.AddSourceLocation(E->getAtLoc());
14560b57cec5SDimitry Andric   Record.AddSourceLocation(E->ProtoLoc);
14570b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
14580b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
14590b57cec5SDimitry Andric }
14600b57cec5SDimitry Andric 
14610b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
14620b57cec5SDimitry Andric   VisitExpr(E);
14630b57cec5SDimitry Andric   Record.AddDeclRef(E->getDecl());
14640b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
14650b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOpLoc());
14660b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
14670b57cec5SDimitry Andric   Record.push_back(E->isArrow());
14680b57cec5SDimitry Andric   Record.push_back(E->isFreeIvar());
14690b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
14700b57cec5SDimitry Andric }
14710b57cec5SDimitry Andric 
14720b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
14730b57cec5SDimitry Andric   VisitExpr(E);
14740b57cec5SDimitry Andric   Record.push_back(E->SetterAndMethodRefFlags.getInt());
14750b57cec5SDimitry Andric   Record.push_back(E->isImplicitProperty());
14760b57cec5SDimitry Andric   if (E->isImplicitProperty()) {
14770b57cec5SDimitry Andric     Record.AddDeclRef(E->getImplicitPropertyGetter());
14780b57cec5SDimitry Andric     Record.AddDeclRef(E->getImplicitPropertySetter());
14790b57cec5SDimitry Andric   } else {
14800b57cec5SDimitry Andric     Record.AddDeclRef(E->getExplicitProperty());
14810b57cec5SDimitry Andric   }
14820b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
14830b57cec5SDimitry Andric   Record.AddSourceLocation(E->getReceiverLocation());
14840b57cec5SDimitry Andric   if (E->isObjectReceiver()) {
14850b57cec5SDimitry Andric     Record.push_back(0);
14860b57cec5SDimitry Andric     Record.AddStmt(E->getBase());
14870b57cec5SDimitry Andric   } else if (E->isSuperReceiver()) {
14880b57cec5SDimitry Andric     Record.push_back(1);
14890b57cec5SDimitry Andric     Record.AddTypeRef(E->getSuperReceiverType());
14900b57cec5SDimitry Andric   } else {
14910b57cec5SDimitry Andric     Record.push_back(2);
14920b57cec5SDimitry Andric     Record.AddDeclRef(E->getClassReceiver());
14930b57cec5SDimitry Andric   }
14940b57cec5SDimitry Andric 
14950b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
14960b57cec5SDimitry Andric }
14970b57cec5SDimitry Andric 
14980b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
14990b57cec5SDimitry Andric   VisitExpr(E);
15000b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRBracket());
15010b57cec5SDimitry Andric   Record.AddStmt(E->getBaseExpr());
15020b57cec5SDimitry Andric   Record.AddStmt(E->getKeyExpr());
15030b57cec5SDimitry Andric   Record.AddDeclRef(E->getAtIndexMethodDecl());
15040b57cec5SDimitry Andric   Record.AddDeclRef(E->setAtIndexMethodDecl());
15050b57cec5SDimitry Andric 
15060b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
15070b57cec5SDimitry Andric }
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
15100b57cec5SDimitry Andric   VisitExpr(E);
15110b57cec5SDimitry Andric   Record.push_back(E->getNumArgs());
15120b57cec5SDimitry Andric   Record.push_back(E->getNumStoredSelLocs());
15130b57cec5SDimitry Andric   Record.push_back(E->SelLocsKind);
15140b57cec5SDimitry Andric   Record.push_back(E->isDelegateInitCall());
15150b57cec5SDimitry Andric   Record.push_back(E->IsImplicit);
15160b57cec5SDimitry Andric   Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
15170b57cec5SDimitry Andric   switch (E->getReceiverKind()) {
15180b57cec5SDimitry Andric   case ObjCMessageExpr::Instance:
15190b57cec5SDimitry Andric     Record.AddStmt(E->getInstanceReceiver());
15200b57cec5SDimitry Andric     break;
15210b57cec5SDimitry Andric 
15220b57cec5SDimitry Andric   case ObjCMessageExpr::Class:
15230b57cec5SDimitry Andric     Record.AddTypeSourceInfo(E->getClassReceiverTypeInfo());
15240b57cec5SDimitry Andric     break;
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   case ObjCMessageExpr::SuperClass:
15270b57cec5SDimitry Andric   case ObjCMessageExpr::SuperInstance:
15280b57cec5SDimitry Andric     Record.AddTypeRef(E->getSuperType());
15290b57cec5SDimitry Andric     Record.AddSourceLocation(E->getSuperLoc());
15300b57cec5SDimitry Andric     break;
15310b57cec5SDimitry Andric   }
15320b57cec5SDimitry Andric 
15330b57cec5SDimitry Andric   if (E->getMethodDecl()) {
15340b57cec5SDimitry Andric     Record.push_back(1);
15350b57cec5SDimitry Andric     Record.AddDeclRef(E->getMethodDecl());
15360b57cec5SDimitry Andric   } else {
15370b57cec5SDimitry Andric     Record.push_back(0);
15380b57cec5SDimitry Andric     Record.AddSelectorRef(E->getSelector());
15390b57cec5SDimitry Andric   }
15400b57cec5SDimitry Andric 
15410b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLeftLoc());
15420b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRightLoc());
15430b57cec5SDimitry Andric 
15440b57cec5SDimitry Andric   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
15450b57cec5SDimitry Andric        Arg != ArgEnd; ++Arg)
15460b57cec5SDimitry Andric     Record.AddStmt(*Arg);
15470b57cec5SDimitry Andric 
15480b57cec5SDimitry Andric   SourceLocation *Locs = E->getStoredSelLocs();
15490b57cec5SDimitry Andric   for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
15500b57cec5SDimitry Andric     Record.AddSourceLocation(Locs[i]);
15510b57cec5SDimitry Andric 
15520b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
15530b57cec5SDimitry Andric }
15540b57cec5SDimitry Andric 
15550b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
15560b57cec5SDimitry Andric   VisitStmt(S);
15570b57cec5SDimitry Andric   Record.AddStmt(S->getElement());
15580b57cec5SDimitry Andric   Record.AddStmt(S->getCollection());
15590b57cec5SDimitry Andric   Record.AddStmt(S->getBody());
15600b57cec5SDimitry Andric   Record.AddSourceLocation(S->getForLoc());
15610b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
15620b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_FOR_COLLECTION;
15630b57cec5SDimitry Andric }
15640b57cec5SDimitry Andric 
15650b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
15660b57cec5SDimitry Andric   VisitStmt(S);
15670b57cec5SDimitry Andric   Record.AddStmt(S->getCatchBody());
15680b57cec5SDimitry Andric   Record.AddDeclRef(S->getCatchParamDecl());
15690b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAtCatchLoc());
15700b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
15710b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_CATCH;
15720b57cec5SDimitry Andric }
15730b57cec5SDimitry Andric 
15740b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
15750b57cec5SDimitry Andric   VisitStmt(S);
15760b57cec5SDimitry Andric   Record.AddStmt(S->getFinallyBody());
15770b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAtFinallyLoc());
15780b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_FINALLY;
15790b57cec5SDimitry Andric }
15800b57cec5SDimitry Andric 
15810b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
15820b57cec5SDimitry Andric   VisitStmt(S); // FIXME: no test coverage.
15830b57cec5SDimitry Andric   Record.AddStmt(S->getSubStmt());
15840b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAtLoc());
15850b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
15860b57cec5SDimitry Andric }
15870b57cec5SDimitry Andric 
15880b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
15890b57cec5SDimitry Andric   VisitStmt(S);
15900b57cec5SDimitry Andric   Record.push_back(S->getNumCatchStmts());
15910b57cec5SDimitry Andric   Record.push_back(S->getFinallyStmt() != nullptr);
15920b57cec5SDimitry Andric   Record.AddStmt(S->getTryBody());
1593349cc55cSDimitry Andric   for (ObjCAtCatchStmt *C : S->catch_stmts())
1594349cc55cSDimitry Andric     Record.AddStmt(C);
15950b57cec5SDimitry Andric   if (S->getFinallyStmt())
15960b57cec5SDimitry Andric     Record.AddStmt(S->getFinallyStmt());
15970b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAtTryLoc());
15980b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_AT_TRY;
15990b57cec5SDimitry Andric }
16000b57cec5SDimitry Andric 
16010b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
16020b57cec5SDimitry Andric   VisitStmt(S); // FIXME: no test coverage.
16030b57cec5SDimitry Andric   Record.AddStmt(S->getSynchExpr());
16040b57cec5SDimitry Andric   Record.AddStmt(S->getSynchBody());
16050b57cec5SDimitry Andric   Record.AddSourceLocation(S->getAtSynchronizedLoc());
16060b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
16070b57cec5SDimitry Andric }
16080b57cec5SDimitry Andric 
16090b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
16100b57cec5SDimitry Andric   VisitStmt(S); // FIXME: no test coverage.
16110b57cec5SDimitry Andric   Record.AddStmt(S->getThrowExpr());
16120b57cec5SDimitry Andric   Record.AddSourceLocation(S->getThrowLoc());
16130b57cec5SDimitry Andric   Code = serialization::STMT_OBJC_AT_THROW;
16140b57cec5SDimitry Andric }
16150b57cec5SDimitry Andric 
16160b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16170b57cec5SDimitry Andric   VisitExpr(E);
16180b57cec5SDimitry Andric   Record.push_back(E->getValue());
16190b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
16200b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_BOOL_LITERAL;
16210b57cec5SDimitry Andric }
16220b57cec5SDimitry Andric 
16230b57cec5SDimitry Andric void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
16240b57cec5SDimitry Andric   VisitExpr(E);
16250b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
16260b57cec5SDimitry Andric   Record.AddVersionTuple(E->getVersion());
16270b57cec5SDimitry Andric   Code = serialization::EXPR_OBJC_AVAILABILITY_CHECK;
16280b57cec5SDimitry Andric }
16290b57cec5SDimitry Andric 
16300b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16310b57cec5SDimitry Andric // C++ Expressions and Statements.
16320b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
16330b57cec5SDimitry Andric 
16340b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
16350b57cec5SDimitry Andric   VisitStmt(S);
16360b57cec5SDimitry Andric   Record.AddSourceLocation(S->getCatchLoc());
16370b57cec5SDimitry Andric   Record.AddDeclRef(S->getExceptionDecl());
16380b57cec5SDimitry Andric   Record.AddStmt(S->getHandlerBlock());
16390b57cec5SDimitry Andric   Code = serialization::STMT_CXX_CATCH;
16400b57cec5SDimitry Andric }
16410b57cec5SDimitry Andric 
16420b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
16430b57cec5SDimitry Andric   VisitStmt(S);
16440b57cec5SDimitry Andric   Record.push_back(S->getNumHandlers());
16450b57cec5SDimitry Andric   Record.AddSourceLocation(S->getTryLoc());
16460b57cec5SDimitry Andric   Record.AddStmt(S->getTryBlock());
16470b57cec5SDimitry Andric   for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
16480b57cec5SDimitry Andric     Record.AddStmt(S->getHandler(i));
16490b57cec5SDimitry Andric   Code = serialization::STMT_CXX_TRY;
16500b57cec5SDimitry Andric }
16510b57cec5SDimitry Andric 
16520b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
16530b57cec5SDimitry Andric   VisitStmt(S);
16540b57cec5SDimitry Andric   Record.AddSourceLocation(S->getForLoc());
16550b57cec5SDimitry Andric   Record.AddSourceLocation(S->getCoawaitLoc());
16560b57cec5SDimitry Andric   Record.AddSourceLocation(S->getColonLoc());
16570b57cec5SDimitry Andric   Record.AddSourceLocation(S->getRParenLoc());
16580b57cec5SDimitry Andric   Record.AddStmt(S->getInit());
16590b57cec5SDimitry Andric   Record.AddStmt(S->getRangeStmt());
16600b57cec5SDimitry Andric   Record.AddStmt(S->getBeginStmt());
16610b57cec5SDimitry Andric   Record.AddStmt(S->getEndStmt());
16620b57cec5SDimitry Andric   Record.AddStmt(S->getCond());
16630b57cec5SDimitry Andric   Record.AddStmt(S->getInc());
16640b57cec5SDimitry Andric   Record.AddStmt(S->getLoopVarStmt());
16650b57cec5SDimitry Andric   Record.AddStmt(S->getBody());
16660b57cec5SDimitry Andric   Code = serialization::STMT_CXX_FOR_RANGE;
16670b57cec5SDimitry Andric }
16680b57cec5SDimitry Andric 
16690b57cec5SDimitry Andric void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
16700b57cec5SDimitry Andric   VisitStmt(S);
16710b57cec5SDimitry Andric   Record.AddSourceLocation(S->getKeywordLoc());
16720b57cec5SDimitry Andric   Record.push_back(S->isIfExists());
16730b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
16740b57cec5SDimitry Andric   Record.AddDeclarationNameInfo(S->getNameInfo());
16750b57cec5SDimitry Andric   Record.AddStmt(S->getSubStmt());
16760b57cec5SDimitry Andric   Code = serialization::STMT_MS_DEPENDENT_EXISTS;
16770b57cec5SDimitry Andric }
16780b57cec5SDimitry Andric 
16790b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
16800b57cec5SDimitry Andric   VisitCallExpr(E);
16810b57cec5SDimitry Andric   Record.push_back(E->getOperator());
16820b57cec5SDimitry Andric   Record.AddSourceRange(E->Range);
1683cb14a3feSDimitry Andric 
1684cb14a3feSDimitry Andric   if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
1685cb14a3feSDimitry Andric     AbbrevToUse = Writer.getCXXOperatorCallExprAbbrev();
1686cb14a3feSDimitry Andric 
16870b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_OPERATOR_CALL;
16880b57cec5SDimitry Andric }
16890b57cec5SDimitry Andric 
16900b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
16910b57cec5SDimitry Andric   VisitCallExpr(E);
1692cb14a3feSDimitry Andric 
1693cb14a3feSDimitry Andric   if (!E->hasStoredFPFeatures() && !static_cast<bool>(E->getADLCallKind()))
1694cb14a3feSDimitry Andric     AbbrevToUse = Writer.getCXXMemberCallExprAbbrev();
1695cb14a3feSDimitry Andric 
16960b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_MEMBER_CALL;
16970b57cec5SDimitry Andric }
16980b57cec5SDimitry Andric 
1699a7dea167SDimitry Andric void ASTStmtWriter::VisitCXXRewrittenBinaryOperator(
1700a7dea167SDimitry Andric     CXXRewrittenBinaryOperator *E) {
1701a7dea167SDimitry Andric   VisitExpr(E);
1702a7dea167SDimitry Andric   Record.push_back(E->isReversed());
1703a7dea167SDimitry Andric   Record.AddStmt(E->getSemanticForm());
1704a7dea167SDimitry Andric   Code = serialization::EXPR_CXX_REWRITTEN_BINARY_OPERATOR;
1705a7dea167SDimitry Andric }
1706a7dea167SDimitry Andric 
17070b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
17080b57cec5SDimitry Andric   VisitExpr(E);
17090b57cec5SDimitry Andric 
17100b57cec5SDimitry Andric   Record.push_back(E->getNumArgs());
17110b57cec5SDimitry Andric   Record.push_back(E->isElidable());
17120b57cec5SDimitry Andric   Record.push_back(E->hadMultipleCandidates());
17130b57cec5SDimitry Andric   Record.push_back(E->isListInitialization());
17140b57cec5SDimitry Andric   Record.push_back(E->isStdInitListInitialization());
17150b57cec5SDimitry Andric   Record.push_back(E->requiresZeroInitialization());
17165f757f3fSDimitry Andric   Record.push_back(
17175f757f3fSDimitry Andric       llvm::to_underlying(E->getConstructionKind())); // FIXME: stable encoding
171806c3fb27SDimitry Andric   Record.push_back(E->isImmediateEscalating());
17190b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
17200b57cec5SDimitry Andric   Record.AddDeclRef(E->getConstructor());
17210b57cec5SDimitry Andric   Record.AddSourceRange(E->getParenOrBraceRange());
17220b57cec5SDimitry Andric 
17230b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
17240b57cec5SDimitry Andric     Record.AddStmt(E->getArg(I));
17250b57cec5SDimitry Andric 
17260b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_CONSTRUCT;
17270b57cec5SDimitry Andric }
17280b57cec5SDimitry Andric 
17290b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
17300b57cec5SDimitry Andric   VisitExpr(E);
17310b57cec5SDimitry Andric   Record.AddDeclRef(E->getConstructor());
17320b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
17330b57cec5SDimitry Andric   Record.push_back(E->constructsVBase());
17340b57cec5SDimitry Andric   Record.push_back(E->inheritedFromVBase());
17350b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
17360b57cec5SDimitry Andric }
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
17390b57cec5SDimitry Andric   VisitCXXConstructExpr(E);
17400b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
17410b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
17420b57cec5SDimitry Andric }
17430b57cec5SDimitry Andric 
17440b57cec5SDimitry Andric void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
17450b57cec5SDimitry Andric   VisitExpr(E);
17465ffd83dbSDimitry Andric   Record.push_back(E->LambdaExprBits.NumCaptures);
17470b57cec5SDimitry Andric   Record.AddSourceRange(E->IntroducerRange);
17485ffd83dbSDimitry Andric   Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
17490b57cec5SDimitry Andric   Record.AddSourceLocation(E->CaptureDefaultLoc);
17505ffd83dbSDimitry Andric   Record.push_back(E->LambdaExprBits.ExplicitParams);
17515ffd83dbSDimitry Andric   Record.push_back(E->LambdaExprBits.ExplicitResultType);
17520b57cec5SDimitry Andric   Record.AddSourceLocation(E->ClosingBrace);
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric   // Add capture initializers.
17550b57cec5SDimitry Andric   for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
17560b57cec5SDimitry Andric                                       CEnd = E->capture_init_end();
17570b57cec5SDimitry Andric        C != CEnd; ++C) {
17580b57cec5SDimitry Andric     Record.AddStmt(*C);
17590b57cec5SDimitry Andric   }
17600b57cec5SDimitry Andric 
17615ffd83dbSDimitry Andric   // Don't serialize the body. It belongs to the call operator declaration.
17625ffd83dbSDimitry Andric   // LambdaExpr only stores a copy of the Stmt *.
17635ffd83dbSDimitry Andric 
17640b57cec5SDimitry Andric   Code = serialization::EXPR_LAMBDA;
17650b57cec5SDimitry Andric }
17660b57cec5SDimitry Andric 
17670b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
17680b57cec5SDimitry Andric   VisitExpr(E);
17690b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
17700b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
17710b57cec5SDimitry Andric }
17720b57cec5SDimitry Andric 
17730b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
17740b57cec5SDimitry Andric   VisitExplicitCastExpr(E);
17750b57cec5SDimitry Andric   Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
1776cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->getAngleBrackets().isValid());
1777cb14a3feSDimitry Andric   if (E->getAngleBrackets().isValid())
17780b57cec5SDimitry Andric     Record.AddSourceRange(E->getAngleBrackets());
17790b57cec5SDimitry Andric }
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
17820b57cec5SDimitry Andric   VisitCXXNamedCastExpr(E);
17830b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_STATIC_CAST;
17840b57cec5SDimitry Andric }
17850b57cec5SDimitry Andric 
17860b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
17870b57cec5SDimitry Andric   VisitCXXNamedCastExpr(E);
17880b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_DYNAMIC_CAST;
17890b57cec5SDimitry Andric }
17900b57cec5SDimitry Andric 
17910b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
17920b57cec5SDimitry Andric   VisitCXXNamedCastExpr(E);
17930b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_REINTERPRET_CAST;
17940b57cec5SDimitry Andric }
17950b57cec5SDimitry Andric 
17960b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
17970b57cec5SDimitry Andric   VisitCXXNamedCastExpr(E);
17980b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_CONST_CAST;
17990b57cec5SDimitry Andric }
18000b57cec5SDimitry Andric 
18015ffd83dbSDimitry Andric void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
18025ffd83dbSDimitry Andric   VisitCXXNamedCastExpr(E);
18035ffd83dbSDimitry Andric   Code = serialization::EXPR_CXX_ADDRSPACE_CAST;
18045ffd83dbSDimitry Andric }
18055ffd83dbSDimitry Andric 
18060b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
18070b57cec5SDimitry Andric   VisitExplicitCastExpr(E);
18080b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
18090b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
18100b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
18110b57cec5SDimitry Andric }
18120b57cec5SDimitry Andric 
18130b57cec5SDimitry Andric void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) {
18140b57cec5SDimitry Andric   VisitExplicitCastExpr(E);
18150b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
18160b57cec5SDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
18175ffd83dbSDimitry Andric   Code = serialization::EXPR_BUILTIN_BIT_CAST;
18180b57cec5SDimitry Andric }
18190b57cec5SDimitry Andric 
18200b57cec5SDimitry Andric void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
18210b57cec5SDimitry Andric   VisitCallExpr(E);
18220b57cec5SDimitry Andric   Record.AddSourceLocation(E->UDSuffixLoc);
18230b57cec5SDimitry Andric   Code = serialization::EXPR_USER_DEFINED_LITERAL;
18240b57cec5SDimitry Andric }
18250b57cec5SDimitry Andric 
18260b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
18270b57cec5SDimitry Andric   VisitExpr(E);
18280b57cec5SDimitry Andric   Record.push_back(E->getValue());
18290b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
18300b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_BOOL_LITERAL;
18310b57cec5SDimitry Andric }
18320b57cec5SDimitry Andric 
18330b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
18340b57cec5SDimitry Andric   VisitExpr(E);
18350b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
18360b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
18370b57cec5SDimitry Andric }
18380b57cec5SDimitry Andric 
18390b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
18400b57cec5SDimitry Andric   VisitExpr(E);
18410b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
18420b57cec5SDimitry Andric   if (E->isTypeOperand()) {
18430b57cec5SDimitry Andric     Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
18440b57cec5SDimitry Andric     Code = serialization::EXPR_CXX_TYPEID_TYPE;
18450b57cec5SDimitry Andric   } else {
18460b57cec5SDimitry Andric     Record.AddStmt(E->getExprOperand());
18470b57cec5SDimitry Andric     Code = serialization::EXPR_CXX_TYPEID_EXPR;
18480b57cec5SDimitry Andric   }
18490b57cec5SDimitry Andric }
18500b57cec5SDimitry Andric 
18510b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
18520b57cec5SDimitry Andric   VisitExpr(E);
18530b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
18540b57cec5SDimitry Andric   Record.push_back(E->isImplicit());
1855*0fca6ea1SDimitry Andric   Record.push_back(E->isCapturedByCopyInLambdaWithExplicitObjectParameter());
1856cb14a3feSDimitry Andric 
18570b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_THIS;
18580b57cec5SDimitry Andric }
18590b57cec5SDimitry Andric 
18600b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
18610b57cec5SDimitry Andric   VisitExpr(E);
18620b57cec5SDimitry Andric   Record.AddSourceLocation(E->getThrowLoc());
18630b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
18640b57cec5SDimitry Andric   Record.push_back(E->isThrownVariableInScope());
18650b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_THROW;
18660b57cec5SDimitry Andric }
18670b57cec5SDimitry Andric 
18680b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
18690b57cec5SDimitry Andric   VisitExpr(E);
18700b57cec5SDimitry Andric   Record.AddDeclRef(E->getParam());
18710b57cec5SDimitry Andric   Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
18720b57cec5SDimitry Andric   Record.AddSourceLocation(E->getUsedLocation());
1873bdd1243dSDimitry Andric   Record.push_back(E->hasRewrittenInit());
1874bdd1243dSDimitry Andric   if (E->hasRewrittenInit())
1875bdd1243dSDimitry Andric     Record.AddStmt(E->getRewrittenExpr());
18760b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_DEFAULT_ARG;
18770b57cec5SDimitry Andric }
18780b57cec5SDimitry Andric 
18790b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
18800b57cec5SDimitry Andric   VisitExpr(E);
1881bdd1243dSDimitry Andric   Record.push_back(E->hasRewrittenInit());
18820b57cec5SDimitry Andric   Record.AddDeclRef(E->getField());
18830b57cec5SDimitry Andric   Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
18840b57cec5SDimitry Andric   Record.AddSourceLocation(E->getExprLoc());
1885bdd1243dSDimitry Andric   if (E->hasRewrittenInit())
1886bdd1243dSDimitry Andric     Record.AddStmt(E->getRewrittenExpr());
18870b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_DEFAULT_INIT;
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
18910b57cec5SDimitry Andric   VisitExpr(E);
18920b57cec5SDimitry Andric   Record.AddCXXTemporary(E->getTemporary());
18930b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
18940b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_BIND_TEMPORARY;
18950b57cec5SDimitry Andric }
18960b57cec5SDimitry Andric 
18970b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
18980b57cec5SDimitry Andric   VisitExpr(E);
18990b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
19000b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
19010b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
19020b57cec5SDimitry Andric }
19030b57cec5SDimitry Andric 
19040b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
19050b57cec5SDimitry Andric   VisitExpr(E);
19060b57cec5SDimitry Andric 
19070b57cec5SDimitry Andric   Record.push_back(E->isArray());
19080b57cec5SDimitry Andric   Record.push_back(E->hasInitializer());
19090b57cec5SDimitry Andric   Record.push_back(E->getNumPlacementArgs());
19100b57cec5SDimitry Andric   Record.push_back(E->isParenTypeId());
19110b57cec5SDimitry Andric 
19120b57cec5SDimitry Andric   Record.push_back(E->isGlobalNew());
19130b57cec5SDimitry Andric   Record.push_back(E->passAlignment());
19140b57cec5SDimitry Andric   Record.push_back(E->doesUsualArrayDeleteWantSize());
19157a6dacacSDimitry Andric   Record.push_back(E->CXXNewExprBits.HasInitializer);
19160b57cec5SDimitry Andric   Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
19170b57cec5SDimitry Andric 
19180b57cec5SDimitry Andric   Record.AddDeclRef(E->getOperatorNew());
19190b57cec5SDimitry Andric   Record.AddDeclRef(E->getOperatorDelete());
19200b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
19210b57cec5SDimitry Andric   if (E->isParenTypeId())
19220b57cec5SDimitry Andric     Record.AddSourceRange(E->getTypeIdParens());
19230b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
19240b57cec5SDimitry Andric   Record.AddSourceRange(E->getDirectInitRange());
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric   for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
19270b57cec5SDimitry Andric        I != N; ++I)
19280b57cec5SDimitry Andric     Record.AddStmt(*I);
19290b57cec5SDimitry Andric 
19300b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_NEW;
19310b57cec5SDimitry Andric }
19320b57cec5SDimitry Andric 
19330b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
19340b57cec5SDimitry Andric   VisitExpr(E);
19350b57cec5SDimitry Andric   Record.push_back(E->isGlobalDelete());
19360b57cec5SDimitry Andric   Record.push_back(E->isArrayForm());
19370b57cec5SDimitry Andric   Record.push_back(E->isArrayFormAsWritten());
19380b57cec5SDimitry Andric   Record.push_back(E->doesUsualArrayDeleteWantSize());
19390b57cec5SDimitry Andric   Record.AddDeclRef(E->getOperatorDelete());
19400b57cec5SDimitry Andric   Record.AddStmt(E->getArgument());
19410b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_DELETE;
19440b57cec5SDimitry Andric }
19450b57cec5SDimitry Andric 
19460b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
19470b57cec5SDimitry Andric   VisitExpr(E);
19480b57cec5SDimitry Andric 
19490b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
19500b57cec5SDimitry Andric   Record.push_back(E->isArrow());
19510b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
19520b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
19530b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getScopeTypeInfo());
19540b57cec5SDimitry Andric   Record.AddSourceLocation(E->getColonColonLoc());
19550b57cec5SDimitry Andric   Record.AddSourceLocation(E->getTildeLoc());
19560b57cec5SDimitry Andric 
19570b57cec5SDimitry Andric   // PseudoDestructorTypeStorage.
19580b57cec5SDimitry Andric   Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
19590b57cec5SDimitry Andric   if (E->getDestroyedTypeIdentifier())
19600b57cec5SDimitry Andric     Record.AddSourceLocation(E->getDestroyedTypeLoc());
19610b57cec5SDimitry Andric   else
19620b57cec5SDimitry Andric     Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());
19630b57cec5SDimitry Andric 
19640b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
19650b57cec5SDimitry Andric }
19660b57cec5SDimitry Andric 
19670b57cec5SDimitry Andric void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
19680b57cec5SDimitry Andric   VisitExpr(E);
19690b57cec5SDimitry Andric   Record.push_back(E->getNumObjects());
19705ffd83dbSDimitry Andric   for (auto &Obj : E->getObjects()) {
19715ffd83dbSDimitry Andric     if (auto *BD = Obj.dyn_cast<BlockDecl *>()) {
19725ffd83dbSDimitry Andric       Record.push_back(serialization::COK_Block);
19735ffd83dbSDimitry Andric       Record.AddDeclRef(BD);
19745ffd83dbSDimitry Andric     } else if (auto *CLE = Obj.dyn_cast<CompoundLiteralExpr *>()) {
19755ffd83dbSDimitry Andric       Record.push_back(serialization::COK_CompoundLiteral);
19765ffd83dbSDimitry Andric       Record.AddStmt(CLE);
19775ffd83dbSDimitry Andric     }
19785ffd83dbSDimitry Andric   }
19790b57cec5SDimitry Andric 
19800b57cec5SDimitry Andric   Record.push_back(E->cleanupsHaveSideEffects());
19810b57cec5SDimitry Andric   Record.AddStmt(E->getSubExpr());
19820b57cec5SDimitry Andric   Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
19830b57cec5SDimitry Andric }
19840b57cec5SDimitry Andric 
19850b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
19860b57cec5SDimitry Andric     CXXDependentScopeMemberExpr *E) {
19870b57cec5SDimitry Andric   VisitExpr(E);
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric   // Don't emit anything here (or if you do you will have to update
19900b57cec5SDimitry Andric   // the corresponding deserialization function).
19910b57cec5SDimitry Andric   Record.push_back(E->getNumTemplateArgs());
1992cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
1993cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
1994cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasFirstQualifierFoundInScope());
19950b57cec5SDimitry Andric 
19960b57cec5SDimitry Andric   if (E->hasTemplateKWAndArgsInfo()) {
19970b57cec5SDimitry Andric     const ASTTemplateKWAndArgsInfo &ArgInfo =
19980b57cec5SDimitry Andric         *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
19990b57cec5SDimitry Andric     AddTemplateKWAndArgsInfo(ArgInfo,
20000b57cec5SDimitry Andric                              E->getTrailingObjects<TemplateArgumentLoc>());
20010b57cec5SDimitry Andric   }
20020b57cec5SDimitry Andric 
2003cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->isArrow());
2004cb14a3feSDimitry Andric 
20050b57cec5SDimitry Andric   Record.AddTypeRef(E->getBaseType());
20060b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
2007cb14a3feSDimitry Andric   CurrentPackingBits.addBit(!E->isImplicitAccess());
20080b57cec5SDimitry Andric   if (!E->isImplicitAccess())
20090b57cec5SDimitry Andric     Record.AddStmt(E->getBase());
2010cb14a3feSDimitry Andric 
2011cb14a3feSDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
20120b57cec5SDimitry Andric 
20130b57cec5SDimitry Andric   if (E->hasFirstQualifierFoundInScope())
20140b57cec5SDimitry Andric     Record.AddDeclRef(E->getFirstQualifierFoundInScope());
20150b57cec5SDimitry Andric 
20160b57cec5SDimitry Andric   Record.AddDeclarationNameInfo(E->MemberNameInfo);
20170b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
20180b57cec5SDimitry Andric }
20190b57cec5SDimitry Andric 
20200b57cec5SDimitry Andric void
20210b57cec5SDimitry Andric ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
20220b57cec5SDimitry Andric   VisitExpr(E);
20230b57cec5SDimitry Andric 
20240b57cec5SDimitry Andric   // Don't emit anything here, HasTemplateKWAndArgsInfo must be
20250b57cec5SDimitry Andric   // emitted first.
2026cb14a3feSDimitry Andric   CurrentPackingBits.addBit(
2027cb14a3feSDimitry Andric       E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
20280b57cec5SDimitry Andric 
20290b57cec5SDimitry Andric   if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
20300b57cec5SDimitry Andric     const ASTTemplateKWAndArgsInfo &ArgInfo =
20310b57cec5SDimitry Andric         *E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
2032cb14a3feSDimitry Andric     // 16 bits should be enought to store the number of args
2033cb14a3feSDimitry Andric     CurrentPackingBits.addBits(ArgInfo.NumTemplateArgs, /*Width=*/16);
20340b57cec5SDimitry Andric     AddTemplateKWAndArgsInfo(ArgInfo,
20350b57cec5SDimitry Andric                              E->getTrailingObjects<TemplateArgumentLoc>());
20360b57cec5SDimitry Andric   }
20370b57cec5SDimitry Andric 
20380b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
20390b57cec5SDimitry Andric   Record.AddDeclarationNameInfo(E->NameInfo);
20400b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric 
20430b57cec5SDimitry Andric void
20440b57cec5SDimitry Andric ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
20450b57cec5SDimitry Andric   VisitExpr(E);
2046e8d8bef9SDimitry Andric   Record.push_back(E->getNumArgs());
20470b57cec5SDimitry Andric   for (CXXUnresolvedConstructExpr::arg_iterator
20480b57cec5SDimitry Andric          ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
20490b57cec5SDimitry Andric     Record.AddStmt(*ArgI);
20500b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getTypeSourceInfo());
20510b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLParenLoc());
20520b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
205306c3fb27SDimitry Andric   Record.push_back(E->isListInitialization());
20540b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
20550b57cec5SDimitry Andric }
20560b57cec5SDimitry Andric 
20570b57cec5SDimitry Andric void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
20580b57cec5SDimitry Andric   VisitExpr(E);
20590b57cec5SDimitry Andric 
2060cb14a3feSDimitry Andric   Record.push_back(E->getNumDecls());
2061cb14a3feSDimitry Andric 
2062cb14a3feSDimitry Andric   CurrentPackingBits.updateBits();
2063cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasTemplateKWAndArgsInfo());
20640b57cec5SDimitry Andric   if (E->hasTemplateKWAndArgsInfo()) {
20650b57cec5SDimitry Andric     const ASTTemplateKWAndArgsInfo &ArgInfo =
20660b57cec5SDimitry Andric         *E->getTrailingASTTemplateKWAndArgsInfo();
2067cb14a3feSDimitry Andric     Record.push_back(ArgInfo.NumTemplateArgs);
20680b57cec5SDimitry Andric     AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
2069cb14a3feSDimitry Andric   }
20700b57cec5SDimitry Andric 
20710b57cec5SDimitry Andric   for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
20720b57cec5SDimitry Andric                                     OvE = E->decls_end();
20730b57cec5SDimitry Andric        OvI != OvE; ++OvI) {
20740b57cec5SDimitry Andric     Record.AddDeclRef(OvI.getDecl());
20750b57cec5SDimitry Andric     Record.push_back(OvI.getAccess());
20760b57cec5SDimitry Andric   }
20770b57cec5SDimitry Andric 
20780b57cec5SDimitry Andric   Record.AddDeclarationNameInfo(E->getNameInfo());
20790b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
20800b57cec5SDimitry Andric }
20810b57cec5SDimitry Andric 
20820b57cec5SDimitry Andric void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
20830b57cec5SDimitry Andric   VisitOverloadExpr(E);
2084cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->isArrow());
2085cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->hasUnresolvedUsing());
2086cb14a3feSDimitry Andric   CurrentPackingBits.addBit(!E->isImplicitAccess());
2087cb14a3feSDimitry Andric   if (!E->isImplicitAccess())
2088cb14a3feSDimitry Andric     Record.AddStmt(E->getBase());
2089cb14a3feSDimitry Andric 
20900b57cec5SDimitry Andric   Record.AddSourceLocation(E->getOperatorLoc());
2091cb14a3feSDimitry Andric 
2092cb14a3feSDimitry Andric   Record.AddTypeRef(E->getBaseType());
20930b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
20940b57cec5SDimitry Andric }
20950b57cec5SDimitry Andric 
20960b57cec5SDimitry Andric void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
20970b57cec5SDimitry Andric   VisitOverloadExpr(E);
2098cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->requiresADL());
20990b57cec5SDimitry Andric   Record.AddDeclRef(E->getNamingClass());
21000b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
2101*0fca6ea1SDimitry Andric 
2102*0fca6ea1SDimitry Andric   if (Writer.isWritingStdCXXNamedModules() && Writer.getChain()) {
2103*0fca6ea1SDimitry Andric     // Referencing all the possible declarations to make sure the change get
2104*0fca6ea1SDimitry Andric     // propagted.
2105*0fca6ea1SDimitry Andric     DeclarationName Name = E->getName();
2106*0fca6ea1SDimitry Andric     for (auto *Found :
2107*0fca6ea1SDimitry Andric          Writer.getASTContext().getTranslationUnitDecl()->lookup(Name))
2108*0fca6ea1SDimitry Andric       if (Found->isFromASTFile())
2109*0fca6ea1SDimitry Andric         Writer.GetDeclRef(Found);
2110*0fca6ea1SDimitry Andric 
2111*0fca6ea1SDimitry Andric     llvm::SmallVector<NamespaceDecl *> ExternalNSs;
2112*0fca6ea1SDimitry Andric     Writer.getChain()->ReadKnownNamespaces(ExternalNSs);
2113*0fca6ea1SDimitry Andric     for (auto *NS : ExternalNSs)
2114*0fca6ea1SDimitry Andric       for (auto *Found : NS->lookup(Name))
2115*0fca6ea1SDimitry Andric         Writer.GetDeclRef(Found);
2116*0fca6ea1SDimitry Andric   }
21170b57cec5SDimitry Andric }
21180b57cec5SDimitry Andric 
21190b57cec5SDimitry Andric void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
21200b57cec5SDimitry Andric   VisitExpr(E);
21210b57cec5SDimitry Andric   Record.push_back(E->TypeTraitExprBits.NumArgs);
21220b57cec5SDimitry Andric   Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
21230b57cec5SDimitry Andric   Record.push_back(E->TypeTraitExprBits.Value);
21240b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
21250b57cec5SDimitry Andric   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
21260b57cec5SDimitry Andric     Record.AddTypeSourceInfo(E->getArg(I));
21270b57cec5SDimitry Andric   Code = serialization::EXPR_TYPE_TRAIT;
21280b57cec5SDimitry Andric }
21290b57cec5SDimitry Andric 
21300b57cec5SDimitry Andric void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
21310b57cec5SDimitry Andric   VisitExpr(E);
21320b57cec5SDimitry Andric   Record.push_back(E->getTrait());
21330b57cec5SDimitry Andric   Record.push_back(E->getValue());
21340b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
21350b57cec5SDimitry Andric   Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
21360b57cec5SDimitry Andric   Record.AddStmt(E->getDimensionExpression());
21370b57cec5SDimitry Andric   Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
21380b57cec5SDimitry Andric }
21390b57cec5SDimitry Andric 
21400b57cec5SDimitry Andric void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
21410b57cec5SDimitry Andric   VisitExpr(E);
21420b57cec5SDimitry Andric   Record.push_back(E->getTrait());
21430b57cec5SDimitry Andric   Record.push_back(E->getValue());
21440b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
21450b57cec5SDimitry Andric   Record.AddStmt(E->getQueriedExpression());
21460b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
21470b57cec5SDimitry Andric }
21480b57cec5SDimitry Andric 
21490b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
21500b57cec5SDimitry Andric   VisitExpr(E);
21510b57cec5SDimitry Andric   Record.push_back(E->getValue());
21520b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
21530b57cec5SDimitry Andric   Record.AddStmt(E->getOperand());
21540b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_NOEXCEPT;
21550b57cec5SDimitry Andric }
21560b57cec5SDimitry Andric 
21570b57cec5SDimitry Andric void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
21580b57cec5SDimitry Andric   VisitExpr(E);
21590b57cec5SDimitry Andric   Record.AddSourceLocation(E->getEllipsisLoc());
21600b57cec5SDimitry Andric   Record.push_back(E->NumExpansions);
21610b57cec5SDimitry Andric   Record.AddStmt(E->getPattern());
21620b57cec5SDimitry Andric   Code = serialization::EXPR_PACK_EXPANSION;
21630b57cec5SDimitry Andric }
21640b57cec5SDimitry Andric 
21650b57cec5SDimitry Andric void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
21660b57cec5SDimitry Andric   VisitExpr(E);
21670b57cec5SDimitry Andric   Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
21680b57cec5SDimitry Andric                                                : 0);
21690b57cec5SDimitry Andric   Record.AddSourceLocation(E->OperatorLoc);
21700b57cec5SDimitry Andric   Record.AddSourceLocation(E->PackLoc);
21710b57cec5SDimitry Andric   Record.AddSourceLocation(E->RParenLoc);
21720b57cec5SDimitry Andric   Record.AddDeclRef(E->Pack);
21730b57cec5SDimitry Andric   if (E->isPartiallySubstituted()) {
21740b57cec5SDimitry Andric     for (const auto &TA : E->getPartialArguments())
21750b57cec5SDimitry Andric       Record.AddTemplateArgument(TA);
21760b57cec5SDimitry Andric   } else if (!E->isValueDependent()) {
21770b57cec5SDimitry Andric     Record.push_back(E->getPackLength());
21780b57cec5SDimitry Andric   }
21790b57cec5SDimitry Andric   Code = serialization::EXPR_SIZEOF_PACK;
21800b57cec5SDimitry Andric }
21810b57cec5SDimitry Andric 
2182*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitPackIndexingExpr(PackIndexingExpr *E) {
2183*0fca6ea1SDimitry Andric   VisitExpr(E);
2184*0fca6ea1SDimitry Andric   Record.push_back(E->TransformedExpressions);
2185*0fca6ea1SDimitry Andric   Record.push_back(E->ExpandedToEmptyPack);
2186*0fca6ea1SDimitry Andric   Record.AddSourceLocation(E->getEllipsisLoc());
2187*0fca6ea1SDimitry Andric   Record.AddSourceLocation(E->getRSquareLoc());
2188*0fca6ea1SDimitry Andric   Record.AddStmt(E->getPackIdExpression());
2189*0fca6ea1SDimitry Andric   Record.AddStmt(E->getIndexExpr());
2190*0fca6ea1SDimitry Andric   for (Expr *Sub : E->getExpressions())
2191*0fca6ea1SDimitry Andric     Record.AddStmt(Sub);
2192*0fca6ea1SDimitry Andric   Code = serialization::EXPR_PACK_INDEXING;
2193*0fca6ea1SDimitry Andric }
2194*0fca6ea1SDimitry Andric 
21950b57cec5SDimitry Andric void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
21960b57cec5SDimitry Andric                                               SubstNonTypeTemplateParmExpr *E) {
21970b57cec5SDimitry Andric   VisitExpr(E);
2198bdd1243dSDimitry Andric   Record.AddDeclRef(E->getAssociatedDecl());
2199cb14a3feSDimitry Andric   CurrentPackingBits.addBit(E->isReferenceParameter());
2200cb14a3feSDimitry Andric   CurrentPackingBits.addBits(E->getIndex(), /*Width=*/12);
2201cb14a3feSDimitry Andric   CurrentPackingBits.addBit((bool)E->getPackIndex());
2202bdd1243dSDimitry Andric   if (auto PackIndex = E->getPackIndex())
2203bdd1243dSDimitry Andric     Record.push_back(*PackIndex + 1);
2204cb14a3feSDimitry Andric 
22050b57cec5SDimitry Andric   Record.AddSourceLocation(E->getNameLoc());
22060b57cec5SDimitry Andric   Record.AddStmt(E->getReplacement());
22070b57cec5SDimitry Andric   Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
22080b57cec5SDimitry Andric }
22090b57cec5SDimitry Andric 
22100b57cec5SDimitry Andric void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
22110b57cec5SDimitry Andric                                           SubstNonTypeTemplateParmPackExpr *E) {
22120b57cec5SDimitry Andric   VisitExpr(E);
2213bdd1243dSDimitry Andric   Record.AddDeclRef(E->getAssociatedDecl());
2214bdd1243dSDimitry Andric   Record.push_back(E->getIndex());
22150b57cec5SDimitry Andric   Record.AddTemplateArgument(E->getArgumentPack());
22160b57cec5SDimitry Andric   Record.AddSourceLocation(E->getParameterPackLocation());
22170b57cec5SDimitry Andric   Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
22180b57cec5SDimitry Andric }
22190b57cec5SDimitry Andric 
22200b57cec5SDimitry Andric void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
22210b57cec5SDimitry Andric   VisitExpr(E);
22220b57cec5SDimitry Andric   Record.push_back(E->getNumExpansions());
22230b57cec5SDimitry Andric   Record.AddDeclRef(E->getParameterPack());
22240b57cec5SDimitry Andric   Record.AddSourceLocation(E->getParameterPackLocation());
22250b57cec5SDimitry Andric   for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
22260b57cec5SDimitry Andric        I != End; ++I)
22270b57cec5SDimitry Andric     Record.AddDeclRef(*I);
22280b57cec5SDimitry Andric   Code = serialization::EXPR_FUNCTION_PARM_PACK;
22290b57cec5SDimitry Andric }
22300b57cec5SDimitry Andric 
22310b57cec5SDimitry Andric void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
22320b57cec5SDimitry Andric   VisitExpr(E);
2233480093f4SDimitry Andric   Record.push_back(static_cast<bool>(E->getLifetimeExtendedTemporaryDecl()));
2234480093f4SDimitry Andric   if (E->getLifetimeExtendedTemporaryDecl())
2235480093f4SDimitry Andric     Record.AddDeclRef(E->getLifetimeExtendedTemporaryDecl());
2236480093f4SDimitry Andric   else
2237480093f4SDimitry Andric     Record.AddStmt(E->getSubExpr());
22380b57cec5SDimitry Andric   Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
22390b57cec5SDimitry Andric }
22400b57cec5SDimitry Andric 
22410b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
22420b57cec5SDimitry Andric   VisitExpr(E);
22430b57cec5SDimitry Andric   Record.AddSourceLocation(E->LParenLoc);
22440b57cec5SDimitry Andric   Record.AddSourceLocation(E->EllipsisLoc);
22450b57cec5SDimitry Andric   Record.AddSourceLocation(E->RParenLoc);
22460b57cec5SDimitry Andric   Record.push_back(E->NumExpansions);
22470b57cec5SDimitry Andric   Record.AddStmt(E->SubExprs[0]);
22480b57cec5SDimitry Andric   Record.AddStmt(E->SubExprs[1]);
2249e8d8bef9SDimitry Andric   Record.AddStmt(E->SubExprs[2]);
22500b57cec5SDimitry Andric   Record.push_back(E->Opcode);
22510b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_FOLD;
22520b57cec5SDimitry Andric }
22530b57cec5SDimitry Andric 
2254bdd1243dSDimitry Andric void ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
2255bdd1243dSDimitry Andric   VisitExpr(E);
2256bdd1243dSDimitry Andric   ArrayRef<Expr *> InitExprs = E->getInitExprs();
2257bdd1243dSDimitry Andric   Record.push_back(InitExprs.size());
2258bdd1243dSDimitry Andric   Record.push_back(E->getUserSpecifiedInitExprs().size());
2259bdd1243dSDimitry Andric   Record.AddSourceLocation(E->getInitLoc());
2260bdd1243dSDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
2261bdd1243dSDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
2262bdd1243dSDimitry Andric   for (Expr *InitExpr : E->getInitExprs())
2263bdd1243dSDimitry Andric     Record.AddStmt(InitExpr);
2264bdd1243dSDimitry Andric   Expr *ArrayFiller = E->getArrayFiller();
2265bdd1243dSDimitry Andric   FieldDecl *UnionField = E->getInitializedFieldInUnion();
2266bdd1243dSDimitry Andric   bool HasArrayFillerOrUnionDecl = ArrayFiller || UnionField;
2267bdd1243dSDimitry Andric   Record.push_back(HasArrayFillerOrUnionDecl);
2268bdd1243dSDimitry Andric   if (HasArrayFillerOrUnionDecl) {
2269bdd1243dSDimitry Andric     Record.push_back(static_cast<bool>(ArrayFiller));
2270bdd1243dSDimitry Andric     if (ArrayFiller)
2271bdd1243dSDimitry Andric       Record.AddStmt(ArrayFiller);
2272bdd1243dSDimitry Andric     else
2273bdd1243dSDimitry Andric       Record.AddDeclRef(UnionField);
2274bdd1243dSDimitry Andric   }
2275bdd1243dSDimitry Andric   Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
2276bdd1243dSDimitry Andric }
2277bdd1243dSDimitry Andric 
22780b57cec5SDimitry Andric void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
22790b57cec5SDimitry Andric   VisitExpr(E);
22800b57cec5SDimitry Andric   Record.AddStmt(E->getSourceExpr());
22810b57cec5SDimitry Andric   Record.AddSourceLocation(E->getLocation());
22820b57cec5SDimitry Andric   Record.push_back(E->isUnique());
22830b57cec5SDimitry Andric   Code = serialization::EXPR_OPAQUE_VALUE;
22840b57cec5SDimitry Andric }
22850b57cec5SDimitry Andric 
22860b57cec5SDimitry Andric void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
22870b57cec5SDimitry Andric   VisitExpr(E);
22880b57cec5SDimitry Andric   // TODO: Figure out sane writer behavior for a TypoExpr, if necessary
22890b57cec5SDimitry Andric   llvm_unreachable("Cannot write TypoExpr nodes");
22900b57cec5SDimitry Andric }
22910b57cec5SDimitry Andric 
22920b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22930b57cec5SDimitry Andric // CUDA Expressions and Statements.
22940b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
22950b57cec5SDimitry Andric 
22960b57cec5SDimitry Andric void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
22970b57cec5SDimitry Andric   VisitCallExpr(E);
22980b57cec5SDimitry Andric   Record.AddStmt(E->getConfig());
22990b57cec5SDimitry Andric   Code = serialization::EXPR_CUDA_KERNEL_CALL;
23000b57cec5SDimitry Andric }
23010b57cec5SDimitry Andric 
23020b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23030b57cec5SDimitry Andric // OpenCL Expressions and Statements.
23040b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23050b57cec5SDimitry Andric void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
23060b57cec5SDimitry Andric   VisitExpr(E);
23070b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBuiltinLoc());
23080b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRParenLoc());
23090b57cec5SDimitry Andric   Record.AddStmt(E->getSrcExpr());
23100b57cec5SDimitry Andric   Code = serialization::EXPR_ASTYPE;
23110b57cec5SDimitry Andric }
23120b57cec5SDimitry Andric 
23130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23140b57cec5SDimitry Andric // Microsoft Expressions and Statements.
23150b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23160b57cec5SDimitry Andric void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
23170b57cec5SDimitry Andric   VisitExpr(E);
23180b57cec5SDimitry Andric   Record.push_back(E->isArrow());
23190b57cec5SDimitry Andric   Record.AddStmt(E->getBaseExpr());
23200b57cec5SDimitry Andric   Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
23210b57cec5SDimitry Andric   Record.AddSourceLocation(E->getMemberLoc());
23220b57cec5SDimitry Andric   Record.AddDeclRef(E->getPropertyDecl());
23230b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
23240b57cec5SDimitry Andric }
23250b57cec5SDimitry Andric 
23260b57cec5SDimitry Andric void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
23270b57cec5SDimitry Andric   VisitExpr(E);
23280b57cec5SDimitry Andric   Record.AddStmt(E->getBase());
23290b57cec5SDimitry Andric   Record.AddStmt(E->getIdx());
23300b57cec5SDimitry Andric   Record.AddSourceLocation(E->getRBracketLoc());
23310b57cec5SDimitry Andric   Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
23320b57cec5SDimitry Andric }
23330b57cec5SDimitry Andric 
23340b57cec5SDimitry Andric void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
23350b57cec5SDimitry Andric   VisitExpr(E);
23360b57cec5SDimitry Andric   Record.AddSourceRange(E->getSourceRange());
23375ffd83dbSDimitry Andric   Record.AddDeclRef(E->getGuidDecl());
23380b57cec5SDimitry Andric   if (E->isTypeOperand()) {
23390b57cec5SDimitry Andric     Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
23400b57cec5SDimitry Andric     Code = serialization::EXPR_CXX_UUIDOF_TYPE;
23410b57cec5SDimitry Andric   } else {
23420b57cec5SDimitry Andric     Record.AddStmt(E->getExprOperand());
23430b57cec5SDimitry Andric     Code = serialization::EXPR_CXX_UUIDOF_EXPR;
23440b57cec5SDimitry Andric   }
23450b57cec5SDimitry Andric }
23460b57cec5SDimitry Andric 
23470b57cec5SDimitry Andric void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
23480b57cec5SDimitry Andric   VisitStmt(S);
23490b57cec5SDimitry Andric   Record.AddSourceLocation(S->getExceptLoc());
23500b57cec5SDimitry Andric   Record.AddStmt(S->getFilterExpr());
23510b57cec5SDimitry Andric   Record.AddStmt(S->getBlock());
23520b57cec5SDimitry Andric   Code = serialization::STMT_SEH_EXCEPT;
23530b57cec5SDimitry Andric }
23540b57cec5SDimitry Andric 
23550b57cec5SDimitry Andric void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
23560b57cec5SDimitry Andric   VisitStmt(S);
23570b57cec5SDimitry Andric   Record.AddSourceLocation(S->getFinallyLoc());
23580b57cec5SDimitry Andric   Record.AddStmt(S->getBlock());
23590b57cec5SDimitry Andric   Code = serialization::STMT_SEH_FINALLY;
23600b57cec5SDimitry Andric }
23610b57cec5SDimitry Andric 
23620b57cec5SDimitry Andric void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
23630b57cec5SDimitry Andric   VisitStmt(S);
23640b57cec5SDimitry Andric   Record.push_back(S->getIsCXXTry());
23650b57cec5SDimitry Andric   Record.AddSourceLocation(S->getTryLoc());
23660b57cec5SDimitry Andric   Record.AddStmt(S->getTryBlock());
23670b57cec5SDimitry Andric   Record.AddStmt(S->getHandler());
23680b57cec5SDimitry Andric   Code = serialization::STMT_SEH_TRY;
23690b57cec5SDimitry Andric }
23700b57cec5SDimitry Andric 
23710b57cec5SDimitry Andric void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
23720b57cec5SDimitry Andric   VisitStmt(S);
23730b57cec5SDimitry Andric   Record.AddSourceLocation(S->getLeaveLoc());
23740b57cec5SDimitry Andric   Code = serialization::STMT_SEH_LEAVE;
23750b57cec5SDimitry Andric }
23760b57cec5SDimitry Andric 
23770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
23780b57cec5SDimitry Andric // OpenMP Directives.
23790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2380e8d8bef9SDimitry Andric 
2381fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPCanonicalLoop(OMPCanonicalLoop *S) {
2382fe6060f1SDimitry Andric   VisitStmt(S);
2383fe6060f1SDimitry Andric   for (Stmt *SubStmt : S->SubStmts)
2384fe6060f1SDimitry Andric     Record.AddStmt(SubStmt);
2385fe6060f1SDimitry Andric   Code = serialization::STMT_OMP_CANONICAL_LOOP;
2386fe6060f1SDimitry Andric }
2387fe6060f1SDimitry Andric 
23880b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
2389e8d8bef9SDimitry Andric   Record.writeOMPChildren(E->Data);
23900b57cec5SDimitry Andric   Record.AddSourceLocation(E->getBeginLoc());
23910b57cec5SDimitry Andric   Record.AddSourceLocation(E->getEndLoc());
23925f757f3fSDimitry Andric   Record.writeEnum(E->getMappedDirective());
23930b57cec5SDimitry Andric }
23940b57cec5SDimitry Andric 
2395fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) {
23960b57cec5SDimitry Andric   VisitStmt(D);
2397fe6060f1SDimitry Andric   Record.writeUInt32(D->getLoopsNumber());
23980b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
23990b57cec5SDimitry Andric }
24000b57cec5SDimitry Andric 
2401fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
2402fe6060f1SDimitry Andric   VisitOMPLoopBasedDirective(D);
2403fe6060f1SDimitry Andric }
2404fe6060f1SDimitry Andric 
2405349cc55cSDimitry Andric void ASTStmtWriter::VisitOMPMetaDirective(OMPMetaDirective *D) {
2406349cc55cSDimitry Andric   VisitStmt(D);
2407349cc55cSDimitry Andric   Record.push_back(D->getNumClauses());
2408349cc55cSDimitry Andric   VisitOMPExecutableDirective(D);
2409349cc55cSDimitry Andric   Code = serialization::STMT_OMP_META_DIRECTIVE;
2410349cc55cSDimitry Andric }
2411349cc55cSDimitry Andric 
24120b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
24130b57cec5SDimitry Andric   VisitStmt(D);
24140b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2415e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
24160b57cec5SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
24170b57cec5SDimitry Andric }
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
24200b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
24210b57cec5SDimitry Andric   Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
24220b57cec5SDimitry Andric }
24230b57cec5SDimitry Andric 
2424349cc55cSDimitry Andric void ASTStmtWriter::VisitOMPLoopTransformationDirective(
2425349cc55cSDimitry Andric     OMPLoopTransformationDirective *D) {
2426fe6060f1SDimitry Andric   VisitOMPLoopBasedDirective(D);
2427349cc55cSDimitry Andric   Record.writeUInt32(D->getNumGeneratedLoops());
2428349cc55cSDimitry Andric }
2429349cc55cSDimitry Andric 
2430349cc55cSDimitry Andric void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) {
2431349cc55cSDimitry Andric   VisitOMPLoopTransformationDirective(D);
2432fe6060f1SDimitry Andric   Code = serialization::STMT_OMP_TILE_DIRECTIVE;
2433fe6060f1SDimitry Andric }
2434fe6060f1SDimitry Andric 
2435fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
2436349cc55cSDimitry Andric   VisitOMPLoopTransformationDirective(D);
2437fe6060f1SDimitry Andric   Code = serialization::STMT_OMP_UNROLL_DIRECTIVE;
2438fe6060f1SDimitry Andric }
2439fe6060f1SDimitry Andric 
2440*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitOMPReverseDirective(OMPReverseDirective *D) {
2441*0fca6ea1SDimitry Andric   VisitOMPLoopTransformationDirective(D);
2442*0fca6ea1SDimitry Andric   Code = serialization::STMT_OMP_REVERSE_DIRECTIVE;
2443*0fca6ea1SDimitry Andric }
2444*0fca6ea1SDimitry Andric 
2445*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitOMPInterchangeDirective(OMPInterchangeDirective *D) {
2446*0fca6ea1SDimitry Andric   VisitOMPLoopTransformationDirective(D);
2447*0fca6ea1SDimitry Andric   Code = serialization::STMT_OMP_INTERCHANGE_DIRECTIVE;
2448*0fca6ea1SDimitry Andric }
2449*0fca6ea1SDimitry Andric 
24500b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
24510b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2452e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
24530b57cec5SDimitry Andric   Code = serialization::STMT_OMP_FOR_DIRECTIVE;
24540b57cec5SDimitry Andric }
24550b57cec5SDimitry Andric 
24560b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
24570b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
24580b57cec5SDimitry Andric   Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
24590b57cec5SDimitry Andric }
24600b57cec5SDimitry Andric 
24610b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
24620b57cec5SDimitry Andric   VisitStmt(D);
24630b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2464e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
24650b57cec5SDimitry Andric   Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
24660b57cec5SDimitry Andric }
24670b57cec5SDimitry Andric 
24680b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
24690b57cec5SDimitry Andric   VisitStmt(D);
24700b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2471e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
24720b57cec5SDimitry Andric   Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
24730b57cec5SDimitry Andric }
24740b57cec5SDimitry Andric 
24755f757f3fSDimitry Andric void ASTStmtWriter::VisitOMPScopeDirective(OMPScopeDirective *D) {
24765f757f3fSDimitry Andric   VisitStmt(D);
24775f757f3fSDimitry Andric   VisitOMPExecutableDirective(D);
24785f757f3fSDimitry Andric   Code = serialization::STMT_OMP_SCOPE_DIRECTIVE;
24795f757f3fSDimitry Andric }
24805f757f3fSDimitry Andric 
24810b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
24820b57cec5SDimitry Andric   VisitStmt(D);
24830b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
24840b57cec5SDimitry Andric   Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
24850b57cec5SDimitry Andric }
24860b57cec5SDimitry Andric 
24870b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
24880b57cec5SDimitry Andric   VisitStmt(D);
24890b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
24900b57cec5SDimitry Andric   Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
24910b57cec5SDimitry Andric }
24920b57cec5SDimitry Andric 
24930b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
24940b57cec5SDimitry Andric   VisitStmt(D);
24950b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
24960b57cec5SDimitry Andric   Record.AddDeclarationNameInfo(D->getDirectiveName());
24970b57cec5SDimitry Andric   Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
24980b57cec5SDimitry Andric }
24990b57cec5SDimitry Andric 
25000b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
25010b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2502e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
25030b57cec5SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
25040b57cec5SDimitry Andric }
25050b57cec5SDimitry Andric 
25060b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPParallelForSimdDirective(
25070b57cec5SDimitry Andric     OMPParallelForSimdDirective *D) {
25080b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
25090b57cec5SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
25100b57cec5SDimitry Andric }
25110b57cec5SDimitry Andric 
2512480093f4SDimitry Andric void ASTStmtWriter::VisitOMPParallelMasterDirective(
2513480093f4SDimitry Andric     OMPParallelMasterDirective *D) {
2514480093f4SDimitry Andric   VisitStmt(D);
2515480093f4SDimitry Andric   VisitOMPExecutableDirective(D);
2516480093f4SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE;
2517480093f4SDimitry Andric }
2518480093f4SDimitry Andric 
251981ad6265SDimitry Andric void ASTStmtWriter::VisitOMPParallelMaskedDirective(
252081ad6265SDimitry Andric     OMPParallelMaskedDirective *D) {
252181ad6265SDimitry Andric   VisitStmt(D);
252281ad6265SDimitry Andric   VisitOMPExecutableDirective(D);
252381ad6265SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_MASKED_DIRECTIVE;
252481ad6265SDimitry Andric }
252581ad6265SDimitry Andric 
25260b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPParallelSectionsDirective(
25270b57cec5SDimitry Andric     OMPParallelSectionsDirective *D) {
25280b57cec5SDimitry Andric   VisitStmt(D);
25290b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2530e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
25310b57cec5SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
25320b57cec5SDimitry Andric }
25330b57cec5SDimitry Andric 
25340b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
25350b57cec5SDimitry Andric   VisitStmt(D);
25360b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2537e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
25380b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TASK_DIRECTIVE;
25390b57cec5SDimitry Andric }
25400b57cec5SDimitry Andric 
25410b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
25420b57cec5SDimitry Andric   VisitStmt(D);
25430b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2544e8d8bef9SDimitry Andric   Record.writeBool(D->isXLHSInRHSPart());
2545e8d8bef9SDimitry Andric   Record.writeBool(D->isPostfixUpdate());
254681ad6265SDimitry Andric   Record.writeBool(D->isFailOnly());
25470b57cec5SDimitry Andric   Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
25480b57cec5SDimitry Andric }
25490b57cec5SDimitry Andric 
25500b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
25510b57cec5SDimitry Andric   VisitStmt(D);
25520b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
25530b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
25540b57cec5SDimitry Andric }
25550b57cec5SDimitry Andric 
25560b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
25570b57cec5SDimitry Andric   VisitStmt(D);
25580b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
25590b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
25600b57cec5SDimitry Andric }
25610b57cec5SDimitry Andric 
25620b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
25630b57cec5SDimitry Andric     OMPTargetEnterDataDirective *D) {
25640b57cec5SDimitry Andric   VisitStmt(D);
25650b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
25660b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
25670b57cec5SDimitry Andric }
25680b57cec5SDimitry Andric 
25690b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetExitDataDirective(
25700b57cec5SDimitry Andric     OMPTargetExitDataDirective *D) {
25710b57cec5SDimitry Andric   VisitStmt(D);
25720b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
25730b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
25740b57cec5SDimitry Andric }
25750b57cec5SDimitry Andric 
25760b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetParallelDirective(
25770b57cec5SDimitry Andric     OMPTargetParallelDirective *D) {
25780b57cec5SDimitry Andric   VisitStmt(D);
25790b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
25805ffd83dbSDimitry Andric   Record.writeBool(D->hasCancel());
25810b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
25820b57cec5SDimitry Andric }
25830b57cec5SDimitry Andric 
25840b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetParallelForDirective(
25850b57cec5SDimitry Andric     OMPTargetParallelForDirective *D) {
25860b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2587e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
25880b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
25890b57cec5SDimitry Andric }
25900b57cec5SDimitry Andric 
25910b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
25920b57cec5SDimitry Andric   VisitStmt(D);
25930b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
25940b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
25950b57cec5SDimitry Andric }
25960b57cec5SDimitry Andric 
25970b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
25980b57cec5SDimitry Andric   VisitStmt(D);
25990b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
26000b57cec5SDimitry Andric   Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
26010b57cec5SDimitry Andric }
26020b57cec5SDimitry Andric 
26030b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
26040b57cec5SDimitry Andric   VisitStmt(D);
2605349cc55cSDimitry Andric   Record.push_back(D->getNumClauses());
26060b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
26070b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
26080b57cec5SDimitry Andric }
26090b57cec5SDimitry Andric 
2610bdd1243dSDimitry Andric void ASTStmtWriter::VisitOMPErrorDirective(OMPErrorDirective *D) {
2611bdd1243dSDimitry Andric   VisitStmt(D);
2612bdd1243dSDimitry Andric   Record.push_back(D->getNumClauses());
2613bdd1243dSDimitry Andric   VisitOMPExecutableDirective(D);
2614bdd1243dSDimitry Andric   Code = serialization::STMT_OMP_ERROR_DIRECTIVE;
2615bdd1243dSDimitry Andric }
2616bdd1243dSDimitry Andric 
26170b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
26180b57cec5SDimitry Andric   VisitStmt(D);
26190b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
26200b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
26210b57cec5SDimitry Andric }
26220b57cec5SDimitry Andric 
26230b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
26240b57cec5SDimitry Andric   VisitStmt(D);
26250b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
26260b57cec5SDimitry Andric   Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
26270b57cec5SDimitry Andric }
26280b57cec5SDimitry Andric 
26295ffd83dbSDimitry Andric void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
26305ffd83dbSDimitry Andric   VisitStmt(D);
26315ffd83dbSDimitry Andric   VisitOMPExecutableDirective(D);
26325ffd83dbSDimitry Andric   Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
26335ffd83dbSDimitry Andric }
26345ffd83dbSDimitry Andric 
26355ffd83dbSDimitry Andric void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) {
26365ffd83dbSDimitry Andric   VisitStmt(D);
26375ffd83dbSDimitry Andric   VisitOMPExecutableDirective(D);
26385ffd83dbSDimitry Andric   Code = serialization::STMT_OMP_SCAN_DIRECTIVE;
26395ffd83dbSDimitry Andric }
26405ffd83dbSDimitry Andric 
26410b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
26420b57cec5SDimitry Andric   VisitStmt(D);
26430b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
26440b57cec5SDimitry Andric   Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
26450b57cec5SDimitry Andric }
26460b57cec5SDimitry Andric 
26470b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
26480b57cec5SDimitry Andric   VisitStmt(D);
26490b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
26500b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
26510b57cec5SDimitry Andric }
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPCancellationPointDirective(
26540b57cec5SDimitry Andric     OMPCancellationPointDirective *D) {
26550b57cec5SDimitry Andric   VisitStmt(D);
26560b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2657e8d8bef9SDimitry Andric   Record.writeEnum(D->getCancelRegion());
26580b57cec5SDimitry Andric   Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
26590b57cec5SDimitry Andric }
26600b57cec5SDimitry Andric 
26610b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
26620b57cec5SDimitry Andric   VisitStmt(D);
26630b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
2664e8d8bef9SDimitry Andric   Record.writeEnum(D->getCancelRegion());
26650b57cec5SDimitry Andric   Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
26660b57cec5SDimitry Andric }
26670b57cec5SDimitry Andric 
26680b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
26690b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2670e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
26710b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
26720b57cec5SDimitry Andric }
26730b57cec5SDimitry Andric 
26740b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
26750b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
26760b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
26770b57cec5SDimitry Andric }
26780b57cec5SDimitry Andric 
2679a7dea167SDimitry Andric void ASTStmtWriter::VisitOMPMasterTaskLoopDirective(
2680a7dea167SDimitry Andric     OMPMasterTaskLoopDirective *D) {
2681a7dea167SDimitry Andric   VisitOMPLoopDirective(D);
2682e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
2683a7dea167SDimitry Andric   Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE;
2684a7dea167SDimitry Andric }
2685a7dea167SDimitry Andric 
268681ad6265SDimitry Andric void ASTStmtWriter::VisitOMPMaskedTaskLoopDirective(
268781ad6265SDimitry Andric     OMPMaskedTaskLoopDirective *D) {
268881ad6265SDimitry Andric   VisitOMPLoopDirective(D);
268981ad6265SDimitry Andric   Record.writeBool(D->hasCancel());
269081ad6265SDimitry Andric   Code = serialization::STMT_OMP_MASKED_TASKLOOP_DIRECTIVE;
269181ad6265SDimitry Andric }
269281ad6265SDimitry Andric 
2693a7dea167SDimitry Andric void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective(
2694a7dea167SDimitry Andric     OMPMasterTaskLoopSimdDirective *D) {
2695a7dea167SDimitry Andric   VisitOMPLoopDirective(D);
2696a7dea167SDimitry Andric   Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE;
2697a7dea167SDimitry Andric }
2698a7dea167SDimitry Andric 
269981ad6265SDimitry Andric void ASTStmtWriter::VisitOMPMaskedTaskLoopSimdDirective(
270081ad6265SDimitry Andric     OMPMaskedTaskLoopSimdDirective *D) {
270181ad6265SDimitry Andric   VisitOMPLoopDirective(D);
270281ad6265SDimitry Andric   Code = serialization::STMT_OMP_MASKED_TASKLOOP_SIMD_DIRECTIVE;
270381ad6265SDimitry Andric }
270481ad6265SDimitry Andric 
2705a7dea167SDimitry Andric void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective(
2706a7dea167SDimitry Andric     OMPParallelMasterTaskLoopDirective *D) {
2707a7dea167SDimitry Andric   VisitOMPLoopDirective(D);
2708e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
2709a7dea167SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE;
2710a7dea167SDimitry Andric }
2711a7dea167SDimitry Andric 
271281ad6265SDimitry Andric void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopDirective(
271381ad6265SDimitry Andric     OMPParallelMaskedTaskLoopDirective *D) {
271481ad6265SDimitry Andric   VisitOMPLoopDirective(D);
271581ad6265SDimitry Andric   Record.writeBool(D->hasCancel());
271681ad6265SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_DIRECTIVE;
271781ad6265SDimitry Andric }
271881ad6265SDimitry Andric 
2719480093f4SDimitry Andric void ASTStmtWriter::VisitOMPParallelMasterTaskLoopSimdDirective(
2720480093f4SDimitry Andric     OMPParallelMasterTaskLoopSimdDirective *D) {
2721480093f4SDimitry Andric   VisitOMPLoopDirective(D);
2722480093f4SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE;
2723480093f4SDimitry Andric }
2724480093f4SDimitry Andric 
272581ad6265SDimitry Andric void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopSimdDirective(
272681ad6265SDimitry Andric     OMPParallelMaskedTaskLoopSimdDirective *D) {
272781ad6265SDimitry Andric   VisitOMPLoopDirective(D);
272881ad6265SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_SIMD_DIRECTIVE;
272981ad6265SDimitry Andric }
273081ad6265SDimitry Andric 
27310b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
27320b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27330b57cec5SDimitry Andric   Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
27340b57cec5SDimitry Andric }
27350b57cec5SDimitry Andric 
27360b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
27370b57cec5SDimitry Andric   VisitStmt(D);
27380b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
27390b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
27400b57cec5SDimitry Andric }
27410b57cec5SDimitry Andric 
27420b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
27430b57cec5SDimitry Andric     OMPDistributeParallelForDirective *D) {
27440b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2745e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
27460b57cec5SDimitry Andric   Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
27470b57cec5SDimitry Andric }
27480b57cec5SDimitry Andric 
27490b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
27500b57cec5SDimitry Andric     OMPDistributeParallelForSimdDirective *D) {
27510b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27520b57cec5SDimitry Andric   Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
27530b57cec5SDimitry Andric }
27540b57cec5SDimitry Andric 
27550b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPDistributeSimdDirective(
27560b57cec5SDimitry Andric     OMPDistributeSimdDirective *D) {
27570b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27580b57cec5SDimitry Andric   Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
27590b57cec5SDimitry Andric }
27600b57cec5SDimitry Andric 
27610b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
27620b57cec5SDimitry Andric     OMPTargetParallelForSimdDirective *D) {
27630b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27640b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
27650b57cec5SDimitry Andric }
27660b57cec5SDimitry Andric 
27670b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
27680b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27690b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
27700b57cec5SDimitry Andric }
27710b57cec5SDimitry Andric 
27720b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
27730b57cec5SDimitry Andric     OMPTeamsDistributeDirective *D) {
27740b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27750b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
27760b57cec5SDimitry Andric }
27770b57cec5SDimitry Andric 
27780b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
27790b57cec5SDimitry Andric     OMPTeamsDistributeSimdDirective *D) {
27800b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27810b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
27820b57cec5SDimitry Andric }
27830b57cec5SDimitry Andric 
27840b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
27850b57cec5SDimitry Andric     OMPTeamsDistributeParallelForSimdDirective *D) {
27860b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
27870b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
27880b57cec5SDimitry Andric }
27890b57cec5SDimitry Andric 
27900b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
27910b57cec5SDimitry Andric     OMPTeamsDistributeParallelForDirective *D) {
27920b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2793e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
27940b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
27950b57cec5SDimitry Andric }
27960b57cec5SDimitry Andric 
27970b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
27980b57cec5SDimitry Andric   VisitStmt(D);
27990b57cec5SDimitry Andric   VisitOMPExecutableDirective(D);
28000b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
28010b57cec5SDimitry Andric }
28020b57cec5SDimitry Andric 
28030b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
28040b57cec5SDimitry Andric     OMPTargetTeamsDistributeDirective *D) {
28050b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
28060b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
28070b57cec5SDimitry Andric }
28080b57cec5SDimitry Andric 
28090b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
28100b57cec5SDimitry Andric     OMPTargetTeamsDistributeParallelForDirective *D) {
28110b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
2812e8d8bef9SDimitry Andric   Record.writeBool(D->hasCancel());
28130b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
28140b57cec5SDimitry Andric }
28150b57cec5SDimitry Andric 
28160b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
28170b57cec5SDimitry Andric     OMPTargetTeamsDistributeParallelForSimdDirective *D) {
28180b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
28190b57cec5SDimitry Andric   Code = serialization::
28200b57cec5SDimitry Andric       STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
28210b57cec5SDimitry Andric }
28220b57cec5SDimitry Andric 
28230b57cec5SDimitry Andric void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
28240b57cec5SDimitry Andric     OMPTargetTeamsDistributeSimdDirective *D) {
28250b57cec5SDimitry Andric   VisitOMPLoopDirective(D);
28260b57cec5SDimitry Andric   Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
28270b57cec5SDimitry Andric }
28280b57cec5SDimitry Andric 
2829fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPInteropDirective(OMPInteropDirective *D) {
2830fe6060f1SDimitry Andric   VisitStmt(D);
2831fe6060f1SDimitry Andric   VisitOMPExecutableDirective(D);
2832fe6060f1SDimitry Andric   Code = serialization::STMT_OMP_INTEROP_DIRECTIVE;
2833fe6060f1SDimitry Andric }
2834fe6060f1SDimitry Andric 
2835fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPDispatchDirective(OMPDispatchDirective *D) {
2836fe6060f1SDimitry Andric   VisitStmt(D);
2837fe6060f1SDimitry Andric   VisitOMPExecutableDirective(D);
2838fe6060f1SDimitry Andric   Record.AddSourceLocation(D->getTargetCallLoc());
2839fe6060f1SDimitry Andric   Code = serialization::STMT_OMP_DISPATCH_DIRECTIVE;
2840fe6060f1SDimitry Andric }
2841fe6060f1SDimitry Andric 
2842fe6060f1SDimitry Andric void ASTStmtWriter::VisitOMPMaskedDirective(OMPMaskedDirective *D) {
2843fe6060f1SDimitry Andric   VisitStmt(D);
2844fe6060f1SDimitry Andric   VisitOMPExecutableDirective(D);
2845fe6060f1SDimitry Andric   Code = serialization::STMT_OMP_MASKED_DIRECTIVE;
2846fe6060f1SDimitry Andric }
2847fe6060f1SDimitry Andric 
2848349cc55cSDimitry Andric void ASTStmtWriter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *D) {
2849349cc55cSDimitry Andric   VisitOMPLoopDirective(D);
2850349cc55cSDimitry Andric   Code = serialization::STMT_OMP_GENERIC_LOOP_DIRECTIVE;
2851349cc55cSDimitry Andric }
2852349cc55cSDimitry Andric 
285381ad6265SDimitry Andric void ASTStmtWriter::VisitOMPTeamsGenericLoopDirective(
285481ad6265SDimitry Andric     OMPTeamsGenericLoopDirective *D) {
285581ad6265SDimitry Andric   VisitOMPLoopDirective(D);
285681ad6265SDimitry Andric   Code = serialization::STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE;
285781ad6265SDimitry Andric }
285881ad6265SDimitry Andric 
285981ad6265SDimitry Andric void ASTStmtWriter::VisitOMPTargetTeamsGenericLoopDirective(
286081ad6265SDimitry Andric     OMPTargetTeamsGenericLoopDirective *D) {
286181ad6265SDimitry Andric   VisitOMPLoopDirective(D);
2862*0fca6ea1SDimitry Andric   Record.writeBool(D->canBeParallelFor());
286381ad6265SDimitry Andric   Code = serialization::STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE;
286481ad6265SDimitry Andric }
286581ad6265SDimitry Andric 
286681ad6265SDimitry Andric void ASTStmtWriter::VisitOMPParallelGenericLoopDirective(
286781ad6265SDimitry Andric     OMPParallelGenericLoopDirective *D) {
286881ad6265SDimitry Andric   VisitOMPLoopDirective(D);
286981ad6265SDimitry Andric   Code = serialization::STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE;
287081ad6265SDimitry Andric }
287181ad6265SDimitry Andric 
287281ad6265SDimitry Andric void ASTStmtWriter::VisitOMPTargetParallelGenericLoopDirective(
287381ad6265SDimitry Andric     OMPTargetParallelGenericLoopDirective *D) {
287481ad6265SDimitry Andric   VisitOMPLoopDirective(D);
287581ad6265SDimitry Andric   Code = serialization::STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE;
287681ad6265SDimitry Andric }
287781ad6265SDimitry Andric 
28780b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2879*0fca6ea1SDimitry Andric // OpenACC Constructs/Directives.
2880*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
2881*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitOpenACCConstructStmt(OpenACCConstructStmt *S) {
2882*0fca6ea1SDimitry Andric   Record.push_back(S->clauses().size());
2883*0fca6ea1SDimitry Andric   Record.writeEnum(S->Kind);
2884*0fca6ea1SDimitry Andric   Record.AddSourceRange(S->Range);
2885*0fca6ea1SDimitry Andric   Record.AddSourceLocation(S->DirectiveLoc);
2886*0fca6ea1SDimitry Andric   Record.writeOpenACCClauseList(S->clauses());
2887*0fca6ea1SDimitry Andric }
2888*0fca6ea1SDimitry Andric 
2889*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitOpenACCAssociatedStmtConstruct(
2890*0fca6ea1SDimitry Andric     OpenACCAssociatedStmtConstruct *S) {
2891*0fca6ea1SDimitry Andric   VisitOpenACCConstructStmt(S);
2892*0fca6ea1SDimitry Andric   Record.AddStmt(S->getAssociatedStmt());
2893*0fca6ea1SDimitry Andric }
2894*0fca6ea1SDimitry Andric 
2895*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitOpenACCComputeConstruct(OpenACCComputeConstruct *S) {
2896*0fca6ea1SDimitry Andric   VisitStmt(S);
2897*0fca6ea1SDimitry Andric   VisitOpenACCAssociatedStmtConstruct(S);
2898*0fca6ea1SDimitry Andric   Code = serialization::STMT_OPENACC_COMPUTE_CONSTRUCT;
2899*0fca6ea1SDimitry Andric }
2900*0fca6ea1SDimitry Andric 
2901*0fca6ea1SDimitry Andric void ASTStmtWriter::VisitOpenACCLoopConstruct(OpenACCLoopConstruct *S) {
2902*0fca6ea1SDimitry Andric   VisitStmt(S);
2903*0fca6ea1SDimitry Andric   VisitOpenACCAssociatedStmtConstruct(S);
2904*0fca6ea1SDimitry Andric   Code = serialization::STMT_OPENACC_LOOP_CONSTRUCT;
2905*0fca6ea1SDimitry Andric }
2906*0fca6ea1SDimitry Andric 
2907*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
29080b57cec5SDimitry Andric // ASTWriter Implementation
29090b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
29100b57cec5SDimitry Andric 
29110b57cec5SDimitry Andric unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
291206c3fb27SDimitry Andric   assert(!SwitchCaseIDs.contains(S) && "SwitchCase recorded twice");
29130b57cec5SDimitry Andric   unsigned NextID = SwitchCaseIDs.size();
29140b57cec5SDimitry Andric   SwitchCaseIDs[S] = NextID;
29150b57cec5SDimitry Andric   return NextID;
29160b57cec5SDimitry Andric }
29170b57cec5SDimitry Andric 
29180b57cec5SDimitry Andric unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
291906c3fb27SDimitry Andric   assert(SwitchCaseIDs.contains(S) && "SwitchCase hasn't been seen yet");
29200b57cec5SDimitry Andric   return SwitchCaseIDs[S];
29210b57cec5SDimitry Andric }
29220b57cec5SDimitry Andric 
29230b57cec5SDimitry Andric void ASTWriter::ClearSwitchCaseIDs() {
29240b57cec5SDimitry Andric   SwitchCaseIDs.clear();
29250b57cec5SDimitry Andric }
29260b57cec5SDimitry Andric 
29270b57cec5SDimitry Andric /// Write the given substatement or subexpression to the
29280b57cec5SDimitry Andric /// bitstream.
29290b57cec5SDimitry Andric void ASTWriter::WriteSubStmt(Stmt *S) {
29300b57cec5SDimitry Andric   RecordData Record;
29310b57cec5SDimitry Andric   ASTStmtWriter Writer(*this, Record);
29320b57cec5SDimitry Andric   ++NumStatements;
29330b57cec5SDimitry Andric 
29340b57cec5SDimitry Andric   if (!S) {
29350b57cec5SDimitry Andric     Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
29360b57cec5SDimitry Andric     return;
29370b57cec5SDimitry Andric   }
29380b57cec5SDimitry Andric 
29390b57cec5SDimitry Andric   llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
29400b57cec5SDimitry Andric   if (I != SubStmtEntries.end()) {
29410b57cec5SDimitry Andric     Record.push_back(I->second);
29420b57cec5SDimitry Andric     Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
29430b57cec5SDimitry Andric     return;
29440b57cec5SDimitry Andric   }
29450b57cec5SDimitry Andric 
29460b57cec5SDimitry Andric #ifndef NDEBUG
29470b57cec5SDimitry Andric   assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
29480b57cec5SDimitry Andric 
29490b57cec5SDimitry Andric   struct ParentStmtInserterRAII {
29500b57cec5SDimitry Andric     Stmt *S;
29510b57cec5SDimitry Andric     llvm::DenseSet<Stmt *> &ParentStmts;
29520b57cec5SDimitry Andric 
29530b57cec5SDimitry Andric     ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
29540b57cec5SDimitry Andric       : S(S), ParentStmts(ParentStmts) {
29550b57cec5SDimitry Andric       ParentStmts.insert(S);
29560b57cec5SDimitry Andric     }
29570b57cec5SDimitry Andric     ~ParentStmtInserterRAII() {
29580b57cec5SDimitry Andric       ParentStmts.erase(S);
29590b57cec5SDimitry Andric     }
29600b57cec5SDimitry Andric   };
29610b57cec5SDimitry Andric 
29620b57cec5SDimitry Andric   ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
29630b57cec5SDimitry Andric #endif
29640b57cec5SDimitry Andric 
29650b57cec5SDimitry Andric   Writer.Visit(S);
29660b57cec5SDimitry Andric 
29670b57cec5SDimitry Andric   uint64_t Offset = Writer.Emit();
29680b57cec5SDimitry Andric   SubStmtEntries[S] = Offset;
29690b57cec5SDimitry Andric }
29700b57cec5SDimitry Andric 
29710b57cec5SDimitry Andric /// Flush all of the statements that have been added to the
29720b57cec5SDimitry Andric /// queue via AddStmt().
29730b57cec5SDimitry Andric void ASTRecordWriter::FlushStmts() {
29740b57cec5SDimitry Andric   // We expect to be the only consumer of the two temporary statement maps,
29750b57cec5SDimitry Andric   // assert that they are empty.
29760b57cec5SDimitry Andric   assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
29770b57cec5SDimitry Andric   assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
29780b57cec5SDimitry Andric 
29790b57cec5SDimitry Andric   for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
29800b57cec5SDimitry Andric     Writer->WriteSubStmt(StmtsToEmit[I]);
29810b57cec5SDimitry Andric 
29820b57cec5SDimitry Andric     assert(N == StmtsToEmit.size() && "record modified while being written!");
29830b57cec5SDimitry Andric 
29840b57cec5SDimitry Andric     // Note that we are at the end of a full expression. Any
29850b57cec5SDimitry Andric     // expression records that follow this one are part of a different
29860b57cec5SDimitry Andric     // expression.
29870b57cec5SDimitry Andric     Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());
29880b57cec5SDimitry Andric 
29890b57cec5SDimitry Andric     Writer->SubStmtEntries.clear();
29900b57cec5SDimitry Andric     Writer->ParentStmts.clear();
29910b57cec5SDimitry Andric   }
29920b57cec5SDimitry Andric 
29930b57cec5SDimitry Andric   StmtsToEmit.clear();
29940b57cec5SDimitry Andric }
29950b57cec5SDimitry Andric 
29960b57cec5SDimitry Andric void ASTRecordWriter::FlushSubStmts() {
29970b57cec5SDimitry Andric   // For a nested statement, write out the substatements in reverse order (so
29980b57cec5SDimitry Andric   // that a simple stack machine can be used when loading), and don't emit a
29990b57cec5SDimitry Andric   // STMT_STOP after each one.
30000b57cec5SDimitry Andric   for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
30010b57cec5SDimitry Andric     Writer->WriteSubStmt(StmtsToEmit[N - I - 1]);
30020b57cec5SDimitry Andric     assert(N == StmtsToEmit.size() && "record modified while being written!");
30030b57cec5SDimitry Andric   }
30040b57cec5SDimitry Andric 
30050b57cec5SDimitry Andric   StmtsToEmit.clear();
30060b57cec5SDimitry Andric }
3007