mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-01 10:26:06 +00:00

This commit relands the patches for implementing P0960R3 and P1975R0, which describe initializing aggregates via a parenthesized list. The relanded commits are: * 40c52159d3ee - P0960R3 and P1975R0: Allow initializing aggregates from a parenthesized list of values * c77a91bb7ba7 - Remove overly restrictive aggregate paren init logic * 32d7aae04fdb - Fix a clang crash on invalid code in C++20 mode This patch also fixes a crash in the original implementation. Previously, if the input tried to call an implicitly deleted copy or move constructor of a union, we would then try to initialize the union by initializing it's first element with a reference to a union. This behavior is incorrect (we should fail to initialize) and if the type of the first element has a constructor with a single template typename parameter, then Clang will explode. This patch fixes that issue by checking that constructor overload resolution did not result in a deleted function before attempting parenthesized aggregate initialization. Additionally, this patch also includes D140159, which contains some minor fixes made in response to code review comments in the original implementation that were made after that patch was submitted. Co-authored-by: Sheng <ox59616e@gmail.com> Fixes #54040, Fixes #59675 Reviewed By: ilya-biryukov Differential Revision: https://reviews.llvm.org/D141546
2798 lines
90 KiB
C++
2798 lines
90 KiB
C++
//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// Implements serialization for Statements and Expressions.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/AST/ExprOpenMP.h"
|
|
#include "clang/Serialization/ASTRecordWriter.h"
|
|
#include "clang/Sema/DeclSpec.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/AST/DeclCXX.h"
|
|
#include "clang/AST/DeclObjC.h"
|
|
#include "clang/AST/DeclTemplate.h"
|
|
#include "clang/AST/StmtVisitor.h"
|
|
#include "clang/Lex/Token.h"
|
|
#include "llvm/Bitstream/BitstreamWriter.h"
|
|
using namespace clang;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Statement/expression serialization
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace clang {
|
|
|
|
class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
|
|
ASTWriter &Writer;
|
|
ASTRecordWriter Record;
|
|
|
|
serialization::StmtCode Code;
|
|
unsigned AbbrevToUse;
|
|
|
|
public:
|
|
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
|
|
: Writer(Writer), Record(Writer, Record),
|
|
Code(serialization::STMT_NULL_PTR), AbbrevToUse(0) {}
|
|
|
|
ASTStmtWriter(const ASTStmtWriter&) = delete;
|
|
|
|
uint64_t Emit() {
|
|
assert(Code != serialization::STMT_NULL_PTR &&
|
|
"unhandled sub-statement writing AST file");
|
|
return Record.EmitStmt(Code, AbbrevToUse);
|
|
}
|
|
|
|
void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &ArgInfo,
|
|
const TemplateArgumentLoc *Args);
|
|
|
|
void VisitStmt(Stmt *S);
|
|
#define STMT(Type, Base) \
|
|
void Visit##Type(Type *);
|
|
#include "clang/AST/StmtNodes.inc"
|
|
};
|
|
}
|
|
|
|
void ASTStmtWriter::AddTemplateKWAndArgsInfo(
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo, const TemplateArgumentLoc *Args) {
|
|
Record.AddSourceLocation(ArgInfo.TemplateKWLoc);
|
|
Record.AddSourceLocation(ArgInfo.LAngleLoc);
|
|
Record.AddSourceLocation(ArgInfo.RAngleLoc);
|
|
for (unsigned i = 0; i != ArgInfo.NumTemplateArgs; ++i)
|
|
Record.AddTemplateArgumentLoc(Args[i]);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitStmt(Stmt *S) {
|
|
}
|
|
|
|
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getSemiLoc());
|
|
Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
|
|
Code = serialization::STMT_NULL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->size());
|
|
Record.push_back(S->hasStoredFPFeatures());
|
|
for (auto *CS : S->body())
|
|
Record.AddStmt(CS);
|
|
if (S->hasStoredFPFeatures())
|
|
Record.push_back(S->getStoredFPFeatures().getAsOpaqueInt());
|
|
Record.AddSourceLocation(S->getLBracLoc());
|
|
Record.AddSourceLocation(S->getRBracLoc());
|
|
Code = serialization::STMT_COMPOUND;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(Writer.getSwitchCaseID(S));
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
|
Record.AddSourceLocation(S->getColonLoc());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
|
|
VisitSwitchCase(S);
|
|
Record.push_back(S->caseStmtIsGNURange());
|
|
Record.AddStmt(S->getLHS());
|
|
Record.AddStmt(S->getSubStmt());
|
|
if (S->caseStmtIsGNURange()) {
|
|
Record.AddStmt(S->getRHS());
|
|
Record.AddSourceLocation(S->getEllipsisLoc());
|
|
}
|
|
Code = serialization::STMT_CASE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
|
|
VisitSwitchCase(S);
|
|
Record.AddStmt(S->getSubStmt());
|
|
Code = serialization::STMT_DEFAULT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->isSideEntry());
|
|
Record.AddDeclRef(S->getDecl());
|
|
Record.AddStmt(S->getSubStmt());
|
|
Record.AddSourceLocation(S->getIdentLoc());
|
|
Code = serialization::STMT_LABEL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getAttrs().size());
|
|
Record.AddAttributes(S->getAttrs());
|
|
Record.AddStmt(S->getSubStmt());
|
|
Record.AddSourceLocation(S->getAttrLoc());
|
|
Code = serialization::STMT_ATTRIBUTED;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
|
|
VisitStmt(S);
|
|
|
|
bool HasElse = S->getElse() != nullptr;
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
bool HasInit = S->getInit() != nullptr;
|
|
|
|
Record.push_back(HasElse);
|
|
Record.push_back(HasVar);
|
|
Record.push_back(HasInit);
|
|
Record.push_back(static_cast<uint64_t>(S->getStatementKind()));
|
|
Record.AddStmt(S->getCond());
|
|
Record.AddStmt(S->getThen());
|
|
if (HasElse)
|
|
Record.AddStmt(S->getElse());
|
|
if (HasVar)
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
if (HasInit)
|
|
Record.AddStmt(S->getInit());
|
|
|
|
Record.AddSourceLocation(S->getIfLoc());
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
if (HasElse)
|
|
Record.AddSourceLocation(S->getElseLoc());
|
|
|
|
Code = serialization::STMT_IF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
|
|
VisitStmt(S);
|
|
|
|
bool HasInit = S->getInit() != nullptr;
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
Record.push_back(HasInit);
|
|
Record.push_back(HasVar);
|
|
Record.push_back(S->isAllEnumCasesCovered());
|
|
|
|
Record.AddStmt(S->getCond());
|
|
Record.AddStmt(S->getBody());
|
|
if (HasInit)
|
|
Record.AddStmt(S->getInit());
|
|
if (HasVar)
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
|
|
Record.AddSourceLocation(S->getSwitchLoc());
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
|
|
for (SwitchCase *SC = S->getSwitchCaseList(); SC;
|
|
SC = SC->getNextSwitchCase())
|
|
Record.push_back(Writer.RecordSwitchCaseID(SC));
|
|
Code = serialization::STMT_SWITCH;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
|
|
VisitStmt(S);
|
|
|
|
bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
|
|
Record.push_back(HasVar);
|
|
|
|
Record.AddStmt(S->getCond());
|
|
Record.AddStmt(S->getBody());
|
|
if (HasVar)
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
|
|
Record.AddSourceLocation(S->getWhileLoc());
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Code = serialization::STMT_WHILE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddStmt(S->getCond());
|
|
Record.AddStmt(S->getBody());
|
|
Record.AddSourceLocation(S->getDoLoc());
|
|
Record.AddSourceLocation(S->getWhileLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Code = serialization::STMT_DO;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitForStmt(ForStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddStmt(S->getInit());
|
|
Record.AddStmt(S->getCond());
|
|
Record.AddDeclRef(S->getConditionVariable());
|
|
Record.AddStmt(S->getInc());
|
|
Record.AddStmt(S->getBody());
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
Record.AddSourceLocation(S->getLParenLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Code = serialization::STMT_FOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddDeclRef(S->getLabel());
|
|
Record.AddSourceLocation(S->getGotoLoc());
|
|
Record.AddSourceLocation(S->getLabelLoc());
|
|
Code = serialization::STMT_GOTO;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getGotoLoc());
|
|
Record.AddSourceLocation(S->getStarLoc());
|
|
Record.AddStmt(S->getTarget());
|
|
Code = serialization::STMT_INDIRECT_GOTO;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getContinueLoc());
|
|
Code = serialization::STMT_CONTINUE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getBreakLoc());
|
|
Code = serialization::STMT_BREAK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
|
|
VisitStmt(S);
|
|
|
|
bool HasNRVOCandidate = S->getNRVOCandidate() != nullptr;
|
|
Record.push_back(HasNRVOCandidate);
|
|
|
|
Record.AddStmt(S->getRetValue());
|
|
if (HasNRVOCandidate)
|
|
Record.AddDeclRef(S->getNRVOCandidate());
|
|
|
|
Record.AddSourceLocation(S->getReturnLoc());
|
|
Code = serialization::STMT_RETURN;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getBeginLoc());
|
|
Record.AddSourceLocation(S->getEndLoc());
|
|
DeclGroupRef DG = S->getDeclGroup();
|
|
for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
|
|
Record.AddDeclRef(*D);
|
|
Code = serialization::STMT_DECL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getNumOutputs());
|
|
Record.push_back(S->getNumInputs());
|
|
Record.push_back(S->getNumClobbers());
|
|
Record.AddSourceLocation(S->getAsmLoc());
|
|
Record.push_back(S->isVolatile());
|
|
Record.push_back(S->isSimple());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
|
|
VisitAsmStmt(S);
|
|
Record.push_back(S->getNumLabels());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Record.AddStmt(S->getAsmString());
|
|
|
|
// Outputs
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
Record.AddIdentifierRef(S->getOutputIdentifier(I));
|
|
Record.AddStmt(S->getOutputConstraintLiteral(I));
|
|
Record.AddStmt(S->getOutputExpr(I));
|
|
}
|
|
|
|
// Inputs
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
|
Record.AddIdentifierRef(S->getInputIdentifier(I));
|
|
Record.AddStmt(S->getInputConstraintLiteral(I));
|
|
Record.AddStmt(S->getInputExpr(I));
|
|
}
|
|
|
|
// Clobbers
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
|
Record.AddStmt(S->getClobberStringLiteral(I));
|
|
|
|
// Labels
|
|
for (auto *E : S->labels()) Record.AddStmt(E);
|
|
|
|
Code = serialization::STMT_GCCASM;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
|
|
VisitAsmStmt(S);
|
|
Record.AddSourceLocation(S->getLBraceLoc());
|
|
Record.AddSourceLocation(S->getEndLoc());
|
|
Record.push_back(S->getNumAsmToks());
|
|
Record.AddString(S->getAsmString());
|
|
|
|
// Tokens
|
|
for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
|
|
// FIXME: Move this to ASTRecordWriter?
|
|
Writer.AddToken(S->getAsmToks()[I], Record.getRecordData());
|
|
}
|
|
|
|
// Clobbers
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
|
|
Record.AddString(S->getClobber(I));
|
|
}
|
|
|
|
// Outputs
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
Record.AddStmt(S->getOutputExpr(I));
|
|
Record.AddString(S->getOutputConstraint(I));
|
|
}
|
|
|
|
// Inputs
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
|
Record.AddStmt(S->getInputExpr(I));
|
|
Record.AddString(S->getInputConstraint(I));
|
|
}
|
|
|
|
Code = serialization::STMT_MSASM;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCoroutineBodyStmt(CoroutineBodyStmt *CoroStmt) {
|
|
VisitStmt(CoroStmt);
|
|
Record.push_back(CoroStmt->getParamMoves().size());
|
|
for (Stmt *S : CoroStmt->children())
|
|
Record.AddStmt(S);
|
|
Code = serialization::STMT_COROUTINE_BODY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCoreturnStmt(CoreturnStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
|
Record.AddStmt(S->getOperand());
|
|
Record.AddStmt(S->getPromiseCall());
|
|
Record.push_back(S->isImplicit());
|
|
Code = serialization::STMT_CORETURN;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCoroutineSuspendExpr(CoroutineSuspendExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getKeywordLoc());
|
|
for (Stmt *S : E->children())
|
|
Record.AddStmt(S);
|
|
Record.AddStmt(E->getOpaqueValue());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCoawaitExpr(CoawaitExpr *E) {
|
|
VisitCoroutineSuspendExpr(E);
|
|
Record.push_back(E->isImplicit());
|
|
Code = serialization::EXPR_COAWAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCoyieldExpr(CoyieldExpr *E) {
|
|
VisitCoroutineSuspendExpr(E);
|
|
Code = serialization::EXPR_COYIELD;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDependentCoawaitExpr(DependentCoawaitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getKeywordLoc());
|
|
for (Stmt *S : E->children())
|
|
Record.AddStmt(S);
|
|
Code = serialization::EXPR_DEPENDENT_COAWAIT;
|
|
}
|
|
|
|
static void
|
|
addConstraintSatisfaction(ASTRecordWriter &Record,
|
|
const ASTConstraintSatisfaction &Satisfaction) {
|
|
Record.push_back(Satisfaction.IsSatisfied);
|
|
Record.push_back(Satisfaction.ContainsErrors);
|
|
if (!Satisfaction.IsSatisfied) {
|
|
Record.push_back(Satisfaction.NumRecords);
|
|
for (const auto &DetailRecord : Satisfaction) {
|
|
Record.AddStmt(const_cast<Expr *>(DetailRecord.first));
|
|
auto *E = DetailRecord.second.dyn_cast<Expr *>();
|
|
Record.push_back(E == nullptr);
|
|
if (E)
|
|
Record.AddStmt(E);
|
|
else {
|
|
auto *Diag = DetailRecord.second.get<std::pair<SourceLocation,
|
|
StringRef> *>();
|
|
Record.AddSourceLocation(Diag->first);
|
|
Record.AddString(Diag->second);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
addSubstitutionDiagnostic(
|
|
ASTRecordWriter &Record,
|
|
const concepts::Requirement::SubstitutionDiagnostic *D) {
|
|
Record.AddString(D->SubstitutedEntity);
|
|
Record.AddSourceLocation(D->DiagLoc);
|
|
Record.AddString(D->DiagMessage);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitConceptSpecializationExpr(
|
|
ConceptSpecializationExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc());
|
|
Record.AddSourceLocation(E->getTemplateKWLoc());
|
|
Record.AddDeclarationNameInfo(E->getConceptNameInfo());
|
|
Record.AddDeclRef(E->getNamedConcept());
|
|
Record.AddDeclRef(E->getFoundDecl());
|
|
Record.AddDeclRef(E->getSpecializationDecl());
|
|
Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
|
|
if (!E->isValueDependent())
|
|
addConstraintSatisfaction(Record, E->getSatisfaction());
|
|
|
|
Code = serialization::EXPR_CONCEPT_SPECIALIZATION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getLocalParameters().size());
|
|
Record.push_back(E->getRequirements().size());
|
|
Record.AddSourceLocation(E->RequiresExprBits.RequiresKWLoc);
|
|
Record.push_back(E->RequiresExprBits.IsSatisfied);
|
|
Record.AddDeclRef(E->getBody());
|
|
for (ParmVarDecl *P : E->getLocalParameters())
|
|
Record.AddDeclRef(P);
|
|
for (concepts::Requirement *R : E->getRequirements()) {
|
|
if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(R)) {
|
|
Record.push_back(concepts::Requirement::RK_Type);
|
|
Record.push_back(TypeReq->Status);
|
|
if (TypeReq->Status == concepts::TypeRequirement::SS_SubstitutionFailure)
|
|
addSubstitutionDiagnostic(Record, TypeReq->getSubstitutionDiagnostic());
|
|
else
|
|
Record.AddTypeSourceInfo(TypeReq->getType());
|
|
} else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(R)) {
|
|
Record.push_back(ExprReq->getKind());
|
|
Record.push_back(ExprReq->Status);
|
|
if (ExprReq->isExprSubstitutionFailure()) {
|
|
addSubstitutionDiagnostic(Record,
|
|
ExprReq->Value.get<concepts::Requirement::SubstitutionDiagnostic *>());
|
|
} else
|
|
Record.AddStmt(ExprReq->Value.get<Expr *>());
|
|
if (ExprReq->getKind() == concepts::Requirement::RK_Compound) {
|
|
Record.AddSourceLocation(ExprReq->NoexceptLoc);
|
|
const auto &RetReq = ExprReq->getReturnTypeRequirement();
|
|
if (RetReq.isSubstitutionFailure()) {
|
|
Record.push_back(2);
|
|
addSubstitutionDiagnostic(Record, RetReq.getSubstitutionDiagnostic());
|
|
} else if (RetReq.isTypeConstraint()) {
|
|
Record.push_back(1);
|
|
Record.AddTemplateParameterList(
|
|
RetReq.getTypeConstraintTemplateParameterList());
|
|
if (ExprReq->Status >=
|
|
concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
|
|
Record.AddStmt(
|
|
ExprReq->getReturnTypeRequirementSubstitutedConstraintExpr());
|
|
} else {
|
|
assert(RetReq.isEmpty());
|
|
Record.push_back(0);
|
|
}
|
|
}
|
|
} else {
|
|
auto *NestedReq = cast<concepts::NestedRequirement>(R);
|
|
Record.push_back(concepts::Requirement::RK_Nested);
|
|
Record.push_back(NestedReq->hasInvalidConstraint());
|
|
if (NestedReq->hasInvalidConstraint()) {
|
|
Record.AddString(NestedReq->getInvalidConstraintEntity());
|
|
addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
|
|
} else {
|
|
Record.AddStmt(NestedReq->getConstraintExpr());
|
|
if (!NestedReq->isDependent())
|
|
addConstraintSatisfaction(Record, *NestedReq->Satisfaction);
|
|
}
|
|
}
|
|
}
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
|
|
Code = serialization::EXPR_REQUIRES;
|
|
}
|
|
|
|
|
|
void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
|
|
VisitStmt(S);
|
|
// NumCaptures
|
|
Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
|
|
|
|
// CapturedDecl and captured region kind
|
|
Record.AddDeclRef(S->getCapturedDecl());
|
|
Record.push_back(S->getCapturedRegionKind());
|
|
|
|
Record.AddDeclRef(S->getCapturedRecordDecl());
|
|
|
|
// Capture inits
|
|
for (auto *I : S->capture_inits())
|
|
Record.AddStmt(I);
|
|
|
|
// Body
|
|
Record.AddStmt(S->getCapturedStmt());
|
|
|
|
// Captures
|
|
for (const auto &I : S->captures()) {
|
|
if (I.capturesThis() || I.capturesVariableArrayType())
|
|
Record.AddDeclRef(nullptr);
|
|
else
|
|
Record.AddDeclRef(I.getCapturedVar());
|
|
Record.push_back(I.getCaptureKind());
|
|
Record.AddSourceLocation(I.getLocation());
|
|
}
|
|
|
|
Code = serialization::STMT_CAPTURED;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExpr(Expr *E) {
|
|
VisitStmt(E);
|
|
Record.AddTypeRef(E->getType());
|
|
Record.push_back(E->getDependence());
|
|
Record.push_back(E->getValueKind());
|
|
Record.push_back(E->getObjectKind());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitConstantExpr(ConstantExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->ConstantExprBits.ResultKind);
|
|
|
|
Record.push_back(E->ConstantExprBits.APValueKind);
|
|
Record.push_back(E->ConstantExprBits.IsUnsigned);
|
|
Record.push_back(E->ConstantExprBits.BitWidth);
|
|
// HasCleanup not serialized since we can just query the APValue.
|
|
Record.push_back(E->ConstantExprBits.IsImmediateInvocation);
|
|
|
|
switch (E->ConstantExprBits.ResultKind) {
|
|
case ConstantExpr::RSK_None:
|
|
break;
|
|
case ConstantExpr::RSK_Int64:
|
|
Record.push_back(E->Int64Result());
|
|
break;
|
|
case ConstantExpr::RSK_APValue:
|
|
Record.AddAPValue(E->APValueResult());
|
|
break;
|
|
default:
|
|
llvm_unreachable("unexpected ResultKind!");
|
|
}
|
|
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_CONSTANT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.AddSourceLocation(E->getLParenLocation());
|
|
Record.AddSourceLocation(E->getRParenLocation());
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
|
|
Code = serialization::EXPR_SYCL_UNIQUE_STABLE_NAME;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
bool HasFunctionName = E->getFunctionName() != nullptr;
|
|
Record.push_back(HasFunctionName);
|
|
Record.push_back(E->getIdentKind()); // FIXME: stable encoding
|
|
Record.AddSourceLocation(E->getLocation());
|
|
if (HasFunctionName)
|
|
Record.AddStmt(E->getFunctionName());
|
|
Code = serialization::EXPR_PREDEFINED;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->hasQualifier());
|
|
Record.push_back(E->getDecl() != E->getFoundDecl());
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
|
Record.push_back(E->hadMultipleCandidates());
|
|
Record.push_back(E->refersToEnclosingVariableOrCapture());
|
|
Record.push_back(E->isNonOdrUse());
|
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
Record.push_back(NumTemplateArgs);
|
|
}
|
|
|
|
DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
|
|
|
|
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
|
|
(E->getDecl() == E->getFoundDecl()) &&
|
|
nk == DeclarationName::Identifier &&
|
|
!E->refersToEnclosingVariableOrCapture() && !E->isNonOdrUse()) {
|
|
AbbrevToUse = Writer.getDeclRefExprAbbrev();
|
|
}
|
|
|
|
if (E->hasQualifier())
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
if (E->getDecl() != E->getFoundDecl())
|
|
Record.AddDeclRef(E->getFoundDecl());
|
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
|
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
|
|
|
Record.AddDeclRef(E->getDecl());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName());
|
|
Code = serialization::EXPR_DECL_REF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.AddAPInt(E->getValue());
|
|
|
|
if (E->getValue().getBitWidth() == 32) {
|
|
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
|
|
}
|
|
|
|
Code = serialization::EXPR_INTEGER_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.push_back(E->getScale());
|
|
Record.AddAPInt(E->getValue());
|
|
Code = serialization::EXPR_FIXEDPOINT_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getRawSemantics());
|
|
Record.push_back(E->isExact());
|
|
Record.AddAPFloat(E->getValue());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Code = serialization::EXPR_FLOATING_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_IMAGINARY_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
|
|
VisitExpr(E);
|
|
|
|
// Store the various bits of data of StringLiteral.
|
|
Record.push_back(E->getNumConcatenated());
|
|
Record.push_back(E->getLength());
|
|
Record.push_back(E->getCharByteWidth());
|
|
Record.push_back(E->getKind());
|
|
Record.push_back(E->isPascal());
|
|
|
|
// Store the trailing array of SourceLocation.
|
|
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
|
Record.AddSourceLocation(E->getStrTokenLoc(I));
|
|
|
|
// Store the trailing array of char holding the string data.
|
|
StringRef StrData = E->getBytes();
|
|
for (unsigned I = 0, N = E->getByteLength(); I != N; ++I)
|
|
Record.push_back(StrData[I]);
|
|
|
|
Code = serialization::EXPR_STRING_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.push_back(E->getKind());
|
|
|
|
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
|
|
|
|
Code = serialization::EXPR_CHARACTER_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getLParen());
|
|
Record.AddSourceLocation(E->getRParen());
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_PAREN;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumExprs());
|
|
for (auto *SubStmt : E->exprs())
|
|
Record.AddStmt(SubStmt);
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_PAREN_LIST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
|
|
VisitExpr(E);
|
|
bool HasFPFeatures = E->hasStoredFPFeatures();
|
|
// Write this first for easy access when deserializing, as they affect the
|
|
// size of the UnaryOperator.
|
|
Record.push_back(HasFPFeatures);
|
|
Record.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
Record.push_back(E->canOverflow());
|
|
if (HasFPFeatures)
|
|
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
|
|
Code = serialization::EXPR_UNARY_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumComponents());
|
|
Record.push_back(E->getNumExpressions());
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
|
const OffsetOfNode &ON = E->getComponent(I);
|
|
Record.push_back(ON.getKind()); // FIXME: Stable encoding
|
|
Record.AddSourceLocation(ON.getSourceRange().getBegin());
|
|
Record.AddSourceLocation(ON.getSourceRange().getEnd());
|
|
switch (ON.getKind()) {
|
|
case OffsetOfNode::Array:
|
|
Record.push_back(ON.getArrayExprIndex());
|
|
break;
|
|
|
|
case OffsetOfNode::Field:
|
|
Record.AddDeclRef(ON.getField());
|
|
break;
|
|
|
|
case OffsetOfNode::Identifier:
|
|
Record.AddIdentifierRef(ON.getFieldName());
|
|
break;
|
|
|
|
case OffsetOfNode::Base:
|
|
Record.AddCXXBaseSpecifier(*ON.getBase());
|
|
break;
|
|
}
|
|
}
|
|
for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
|
|
Record.AddStmt(E->getIndexExpr(I));
|
|
Code = serialization::EXPR_OFFSETOF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getKind());
|
|
if (E->isArgumentType())
|
|
Record.AddTypeSourceInfo(E->getArgumentTypeInfo());
|
|
else {
|
|
Record.push_back(0);
|
|
Record.AddStmt(E->getArgumentExpr());
|
|
}
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_SIZEOF_ALIGN_OF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getLHS());
|
|
Record.AddStmt(E->getRHS());
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddStmt(E->getRowIdx());
|
|
Record.AddStmt(E->getColumnIdx());
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddStmt(E->getLowerBound());
|
|
Record.AddStmt(E->getLength());
|
|
Record.AddStmt(E->getStride());
|
|
Record.AddSourceLocation(E->getColonLocFirst());
|
|
Record.AddSourceLocation(E->getColonLocSecond());
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
|
Code = serialization::EXPR_OMP_ARRAY_SECTION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getDimensions().size());
|
|
Record.AddStmt(E->getBase());
|
|
for (Expr *Dim : E->getDimensions())
|
|
Record.AddStmt(Dim);
|
|
for (SourceRange SR : E->getBracketsRanges())
|
|
Record.AddSourceRange(SR);
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_OMP_ARRAY_SHAPING;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPIteratorExpr(OMPIteratorExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->numOfIterators());
|
|
Record.AddSourceLocation(E->getIteratorKwLoc());
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
|
|
Record.AddDeclRef(E->getIteratorDecl(I));
|
|
Record.AddSourceLocation(E->getAssignLoc(I));
|
|
OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
|
|
Record.AddStmt(Range.Begin);
|
|
Record.AddStmt(Range.End);
|
|
Record.AddStmt(Range.Step);
|
|
Record.AddSourceLocation(E->getColonLoc(I));
|
|
if (Range.Step)
|
|
Record.AddSourceLocation(E->getSecondColonLoc(I));
|
|
// Serialize helpers
|
|
OMPIteratorHelperData &HD = E->getHelper(I);
|
|
Record.AddDeclRef(HD.CounterVD);
|
|
Record.AddStmt(HD.Upper);
|
|
Record.AddStmt(HD.Update);
|
|
Record.AddStmt(HD.CounterUpdate);
|
|
}
|
|
Code = serialization::EXPR_OMP_ITERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumArgs());
|
|
Record.push_back(E->hasStoredFPFeatures());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.AddStmt(E->getCallee());
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
Arg != ArgEnd; ++Arg)
|
|
Record.AddStmt(*Arg);
|
|
Record.push_back(static_cast<unsigned>(E->getADLCallKind()));
|
|
if (E->hasStoredFPFeatures())
|
|
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
|
Code = serialization::EXPR_CALL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitRecoveryExpr(RecoveryExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(std::distance(E->children().begin(), E->children().end()));
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
for (Stmt *Child : E->children())
|
|
Record.AddStmt(Child);
|
|
Code = serialization::EXPR_RECOVERY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
bool HasQualifier = E->hasQualifier();
|
|
bool HasFoundDecl =
|
|
E->hasQualifierOrFoundDecl() &&
|
|
(E->getFoundDecl().getDecl() != E->getMemberDecl() ||
|
|
E->getFoundDecl().getAccess() != E->getMemberDecl()->getAccess());
|
|
bool HasTemplateInfo = E->hasTemplateKWAndArgsInfo();
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
|
|
// Write these first for easy access when deserializing, as they affect the
|
|
// size of the MemberExpr.
|
|
Record.push_back(HasQualifier);
|
|
Record.push_back(HasFoundDecl);
|
|
Record.push_back(HasTemplateInfo);
|
|
Record.push_back(NumTemplateArgs);
|
|
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddDeclRef(E->getMemberDecl());
|
|
Record.AddDeclarationNameLoc(E->MemberDNLoc,
|
|
E->getMemberDecl()->getDeclName());
|
|
Record.AddSourceLocation(E->getMemberLoc());
|
|
Record.push_back(E->isArrow());
|
|
Record.push_back(E->hadMultipleCandidates());
|
|
Record.push_back(E->isNonOdrUse());
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
|
|
if (HasFoundDecl) {
|
|
DeclAccessPair FoundDecl = E->getFoundDecl();
|
|
Record.AddDeclRef(FoundDecl.getDecl());
|
|
Record.push_back(FoundDecl.getAccess());
|
|
}
|
|
|
|
if (HasQualifier)
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
|
|
if (HasTemplateInfo)
|
|
AddTemplateKWAndArgsInfo(*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>(),
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
|
|
|
Code = serialization::EXPR_MEMBER;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddSourceLocation(E->getIsaMemberLoc());
|
|
Record.AddSourceLocation(E->getOpLoc());
|
|
Record.push_back(E->isArrow());
|
|
Code = serialization::EXPR_OBJC_ISA;
|
|
}
|
|
|
|
void ASTStmtWriter::
|
|
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->shouldCopy());
|
|
Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getBridgeKeywordLoc());
|
|
Record.push_back(E->getBridgeKind()); // FIXME: Stable encoding
|
|
Code = serialization::EXPR_OBJC_BRIDGED_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->path_size());
|
|
Record.push_back(E->hasStoredFPFeatures());
|
|
Record.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->getCastKind()); // FIXME: stable encoding
|
|
|
|
for (CastExpr::path_iterator
|
|
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
|
|
Record.AddCXXBaseSpecifier(**PI);
|
|
|
|
if (E->hasStoredFPFeatures())
|
|
Record.push_back(E->getFPFeatures().getAsOpaqueInt());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
|
|
VisitExpr(E);
|
|
bool HasFPFeatures = E->hasStoredFPFeatures();
|
|
// Write this first for easy access when deserializing, as they affect the
|
|
// size of the UnaryOperator.
|
|
Record.push_back(HasFPFeatures);
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
Record.AddStmt(E->getLHS());
|
|
Record.AddStmt(E->getRHS());
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
if (HasFPFeatures)
|
|
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
|
|
Code = serialization::EXPR_BINARY_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
|
|
VisitBinaryOperator(E);
|
|
Record.AddTypeRef(E->getComputationLHSType());
|
|
Record.AddTypeRef(E->getComputationResultType());
|
|
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getCond());
|
|
Record.AddStmt(E->getLHS());
|
|
Record.AddStmt(E->getRHS());
|
|
Record.AddSourceLocation(E->getQuestionLoc());
|
|
Record.AddSourceLocation(E->getColonLoc());
|
|
Code = serialization::EXPR_CONDITIONAL_OPERATOR;
|
|
}
|
|
|
|
void
|
|
ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getOpaqueValue());
|
|
Record.AddStmt(E->getCommon());
|
|
Record.AddStmt(E->getCond());
|
|
Record.AddStmt(E->getTrueExpr());
|
|
Record.AddStmt(E->getFalseExpr());
|
|
Record.AddSourceLocation(E->getQuestionLoc());
|
|
Record.AddSourceLocation(E->getColonLoc());
|
|
Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
|
VisitCastExpr(E);
|
|
Record.push_back(E->isPartOfExplicitCast());
|
|
|
|
if (E->path_size() == 0 && !E->hasStoredFPFeatures())
|
|
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
|
|
|
|
Code = serialization::EXPR_IMPLICIT_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
|
VisitCastExpr(E);
|
|
Record.AddTypeSourceInfo(E->getTypeInfoAsWritten());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_CSTYLE_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
Record.AddStmt(E->getInitializer());
|
|
Record.push_back(E->isFileScope());
|
|
Code = serialization::EXPR_COMPOUND_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddIdentifierRef(&E->getAccessor());
|
|
Record.AddSourceLocation(E->getAccessorLoc());
|
|
Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
|
|
VisitExpr(E);
|
|
// NOTE: only add the (possibly null) syntactic form.
|
|
// No need to serialize the isSemanticForm flag and the semantic form.
|
|
Record.AddStmt(E->getSyntacticForm());
|
|
Record.AddSourceLocation(E->getLBraceLoc());
|
|
Record.AddSourceLocation(E->getRBraceLoc());
|
|
bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
|
|
Record.push_back(isArrayFiller);
|
|
if (isArrayFiller)
|
|
Record.AddStmt(E->getArrayFiller());
|
|
else
|
|
Record.AddDeclRef(E->getInitializedFieldInUnion());
|
|
Record.push_back(E->hadArrayRangeDesignator());
|
|
Record.push_back(E->getNumInits());
|
|
if (isArrayFiller) {
|
|
// ArrayFiller may have filled "holes" due to designated initializer.
|
|
// Replace them by 0 to indicate that the filler goes in that place.
|
|
Expr *filler = E->getArrayFiller();
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
|
Record.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
|
|
} else {
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
|
Record.AddStmt(E->getInit(I));
|
|
}
|
|
Code = serialization::EXPR_INIT_LIST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumSubExprs());
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
|
Record.AddStmt(E->getSubExpr(I));
|
|
Record.AddSourceLocation(E->getEqualOrColonLoc());
|
|
Record.push_back(E->usesGNUSyntax());
|
|
for (const DesignatedInitExpr::Designator &D : E->designators()) {
|
|
if (D.isFieldDesignator()) {
|
|
if (FieldDecl *Field = D.getField()) {
|
|
Record.push_back(serialization::DESIG_FIELD_DECL);
|
|
Record.AddDeclRef(Field);
|
|
} else {
|
|
Record.push_back(serialization::DESIG_FIELD_NAME);
|
|
Record.AddIdentifierRef(D.getFieldName());
|
|
}
|
|
Record.AddSourceLocation(D.getDotLoc());
|
|
Record.AddSourceLocation(D.getFieldLoc());
|
|
} else if (D.isArrayDesignator()) {
|
|
Record.push_back(serialization::DESIG_ARRAY);
|
|
Record.push_back(D.getFirstExprIndex());
|
|
Record.AddSourceLocation(D.getLBracketLoc());
|
|
Record.AddSourceLocation(D.getRBracketLoc());
|
|
} else {
|
|
assert(D.isArrayRangeDesignator() && "Unknown designator");
|
|
Record.push_back(serialization::DESIG_ARRAY_RANGE);
|
|
Record.push_back(D.getFirstExprIndex());
|
|
Record.AddSourceLocation(D.getLBracketLoc());
|
|
Record.AddSourceLocation(D.getEllipsisLoc());
|
|
Record.AddSourceLocation(D.getRBracketLoc());
|
|
}
|
|
}
|
|
Code = serialization::EXPR_DESIGNATED_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddStmt(E->getUpdater());
|
|
Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
|
|
VisitExpr(E);
|
|
Code = serialization::EXPR_NO_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->SubExprs[0]);
|
|
Record.AddStmt(E->SubExprs[1]);
|
|
Code = serialization::EXPR_ARRAY_INIT_LOOP;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
|
|
VisitExpr(E);
|
|
Code = serialization::EXPR_ARRAY_INIT_INDEX;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
|
VisitExpr(E);
|
|
Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSubExpr());
|
|
Record.AddTypeSourceInfo(E->getWrittenTypeInfo());
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.push_back(E->isMicrosoftABI());
|
|
Code = serialization::EXPR_VA_ARG;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSourceLocExpr(SourceLocExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getParentContext()));
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
Record.push_back(E->getIdentKind());
|
|
Code = serialization::EXPR_SOURCE_LOC;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getAmpAmpLoc());
|
|
Record.AddSourceLocation(E->getLabelLoc());
|
|
Record.AddDeclRef(E->getLabel());
|
|
Code = serialization::EXPR_ADDR_LABEL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSubStmt());
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.push_back(E->getTemplateDepth());
|
|
Code = serialization::EXPR_STMT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getCond());
|
|
Record.AddStmt(E->getLHS());
|
|
Record.AddStmt(E->getRHS());
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
|
|
Code = serialization::EXPR_CHOOSE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getTokenLocation());
|
|
Code = serialization::EXPR_GNU_NULL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumSubExprs());
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
|
Record.AddStmt(E->getExpr(I));
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_SHUFFLE_VECTOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
Record.AddStmt(E->getSrcExpr());
|
|
Code = serialization::EXPR_CONVERT_VECTOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getBlockDecl());
|
|
Code = serialization::EXPR_BLOCK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumAssocs());
|
|
Record.push_back(E->ResultIndex);
|
|
Record.AddSourceLocation(E->getGenericLoc());
|
|
Record.AddSourceLocation(E->getDefaultLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
|
|
Stmt **Stmts = E->getTrailingObjects<Stmt *>();
|
|
// Add 1 to account for the controlling expression which is the first
|
|
// expression in the trailing array of Stmt *. This is not needed for
|
|
// the trailing array of TypeSourceInfo *.
|
|
for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
|
|
Record.AddStmt(Stmts[I]);
|
|
|
|
TypeSourceInfo **TSIs = E->getTrailingObjects<TypeSourceInfo *>();
|
|
for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
|
|
Record.AddTypeSourceInfo(TSIs[I]);
|
|
|
|
Code = serialization::EXPR_GENERIC_SELECTION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumSemanticExprs());
|
|
|
|
// Push the result index. Currently, this needs to exactly match
|
|
// the encoding used internally for ResultIndex.
|
|
unsigned result = E->getResultExprIndex();
|
|
result = (result == PseudoObjectExpr::NoResult ? 0 : result + 1);
|
|
Record.push_back(result);
|
|
|
|
Record.AddStmt(E->getSyntacticForm());
|
|
for (PseudoObjectExpr::semantics_iterator
|
|
i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
|
|
Record.AddStmt(*i);
|
|
}
|
|
Code = serialization::EXPR_PSEUDO_OBJECT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getOp());
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
|
Record.AddStmt(E->getSubExprs()[I]);
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_ATOMIC;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Objective-C Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getString());
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
Code = serialization::EXPR_OBJC_STRING_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSubExpr());
|
|
Record.AddDeclRef(E->getBoxingMethod());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumElements());
|
|
for (unsigned i = 0; i < E->getNumElements(); i++)
|
|
Record.AddStmt(E->getElement(i));
|
|
Record.AddDeclRef(E->getArrayWithObjectsMethod());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Code = serialization::EXPR_OBJC_ARRAY_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumElements());
|
|
Record.push_back(E->HasPackExpansions);
|
|
for (unsigned i = 0; i < E->getNumElements(); i++) {
|
|
ObjCDictionaryElement Element = E->getKeyValueElement(i);
|
|
Record.AddStmt(Element.Key);
|
|
Record.AddStmt(Element.Value);
|
|
if (E->HasPackExpansions) {
|
|
Record.AddSourceLocation(Element.EllipsisLoc);
|
|
unsigned NumExpansions = 0;
|
|
if (Element.NumExpansions)
|
|
NumExpansions = *Element.NumExpansions + 1;
|
|
Record.push_back(NumExpansions);
|
|
}
|
|
}
|
|
|
|
Record.AddDeclRef(E->getDictWithObjectsMethod());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddTypeSourceInfo(E->getEncodedTypeSourceInfo());
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_OBJC_ENCODE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSelectorRef(E->getSelector());
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getProtocol());
|
|
Record.AddSourceLocation(E->getAtLoc());
|
|
Record.AddSourceLocation(E->ProtoLoc);
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getDecl());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.AddSourceLocation(E->getOpLoc());
|
|
Record.AddStmt(E->getBase());
|
|
Record.push_back(E->isArrow());
|
|
Record.push_back(E->isFreeIvar());
|
|
Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->SetterAndMethodRefFlags.getInt());
|
|
Record.push_back(E->isImplicitProperty());
|
|
if (E->isImplicitProperty()) {
|
|
Record.AddDeclRef(E->getImplicitPropertyGetter());
|
|
Record.AddDeclRef(E->getImplicitPropertySetter());
|
|
} else {
|
|
Record.AddDeclRef(E->getExplicitProperty());
|
|
}
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.AddSourceLocation(E->getReceiverLocation());
|
|
if (E->isObjectReceiver()) {
|
|
Record.push_back(0);
|
|
Record.AddStmt(E->getBase());
|
|
} else if (E->isSuperReceiver()) {
|
|
Record.push_back(1);
|
|
Record.AddTypeRef(E->getSuperReceiverType());
|
|
} else {
|
|
Record.push_back(2);
|
|
Record.AddDeclRef(E->getClassReceiver());
|
|
}
|
|
|
|
Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getRBracket());
|
|
Record.AddStmt(E->getBaseExpr());
|
|
Record.AddStmt(E->getKeyExpr());
|
|
Record.AddDeclRef(E->getAtIndexMethodDecl());
|
|
Record.AddDeclRef(E->setAtIndexMethodDecl());
|
|
|
|
Code = serialization::EXPR_OBJC_SUBSCRIPT_REF_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumArgs());
|
|
Record.push_back(E->getNumStoredSelLocs());
|
|
Record.push_back(E->SelLocsKind);
|
|
Record.push_back(E->isDelegateInitCall());
|
|
Record.push_back(E->IsImplicit);
|
|
Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
|
|
switch (E->getReceiverKind()) {
|
|
case ObjCMessageExpr::Instance:
|
|
Record.AddStmt(E->getInstanceReceiver());
|
|
break;
|
|
|
|
case ObjCMessageExpr::Class:
|
|
Record.AddTypeSourceInfo(E->getClassReceiverTypeInfo());
|
|
break;
|
|
|
|
case ObjCMessageExpr::SuperClass:
|
|
case ObjCMessageExpr::SuperInstance:
|
|
Record.AddTypeRef(E->getSuperType());
|
|
Record.AddSourceLocation(E->getSuperLoc());
|
|
break;
|
|
}
|
|
|
|
if (E->getMethodDecl()) {
|
|
Record.push_back(1);
|
|
Record.AddDeclRef(E->getMethodDecl());
|
|
} else {
|
|
Record.push_back(0);
|
|
Record.AddSelectorRef(E->getSelector());
|
|
}
|
|
|
|
Record.AddSourceLocation(E->getLeftLoc());
|
|
Record.AddSourceLocation(E->getRightLoc());
|
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
Arg != ArgEnd; ++Arg)
|
|
Record.AddStmt(*Arg);
|
|
|
|
SourceLocation *Locs = E->getStoredSelLocs();
|
|
for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
|
|
Record.AddSourceLocation(Locs[i]);
|
|
|
|
Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddStmt(S->getElement());
|
|
Record.AddStmt(S->getCollection());
|
|
Record.AddStmt(S->getBody());
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Code = serialization::STMT_OBJC_FOR_COLLECTION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddStmt(S->getCatchBody());
|
|
Record.AddDeclRef(S->getCatchParamDecl());
|
|
Record.AddSourceLocation(S->getAtCatchLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Code = serialization::STMT_OBJC_CATCH;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddStmt(S->getFinallyBody());
|
|
Record.AddSourceLocation(S->getAtFinallyLoc());
|
|
Code = serialization::STMT_OBJC_FINALLY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
|
|
VisitStmt(S); // FIXME: no test coverage.
|
|
Record.AddStmt(S->getSubStmt());
|
|
Record.AddSourceLocation(S->getAtLoc());
|
|
Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getNumCatchStmts());
|
|
Record.push_back(S->getFinallyStmt() != nullptr);
|
|
Record.AddStmt(S->getTryBody());
|
|
for (ObjCAtCatchStmt *C : S->catch_stmts())
|
|
Record.AddStmt(C);
|
|
if (S->getFinallyStmt())
|
|
Record.AddStmt(S->getFinallyStmt());
|
|
Record.AddSourceLocation(S->getAtTryLoc());
|
|
Code = serialization::STMT_OBJC_AT_TRY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
|
|
VisitStmt(S); // FIXME: no test coverage.
|
|
Record.AddStmt(S->getSynchExpr());
|
|
Record.AddStmt(S->getSynchBody());
|
|
Record.AddSourceLocation(S->getAtSynchronizedLoc());
|
|
Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
|
|
VisitStmt(S); // FIXME: no test coverage.
|
|
Record.AddStmt(S->getThrowExpr());
|
|
Record.AddSourceLocation(S->getThrowLoc());
|
|
Code = serialization::STMT_OBJC_AT_THROW;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Code = serialization::EXPR_OBJC_BOOL_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Record.AddVersionTuple(E->getVersion());
|
|
Code = serialization::EXPR_OBJC_AVAILABILITY_CHECK;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// C++ Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getCatchLoc());
|
|
Record.AddDeclRef(S->getExceptionDecl());
|
|
Record.AddStmt(S->getHandlerBlock());
|
|
Code = serialization::STMT_CXX_CATCH;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getNumHandlers());
|
|
Record.AddSourceLocation(S->getTryLoc());
|
|
Record.AddStmt(S->getTryBlock());
|
|
for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
|
|
Record.AddStmt(S->getHandler(i));
|
|
Code = serialization::STMT_CXX_TRY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getForLoc());
|
|
Record.AddSourceLocation(S->getCoawaitLoc());
|
|
Record.AddSourceLocation(S->getColonLoc());
|
|
Record.AddSourceLocation(S->getRParenLoc());
|
|
Record.AddStmt(S->getInit());
|
|
Record.AddStmt(S->getRangeStmt());
|
|
Record.AddStmt(S->getBeginStmt());
|
|
Record.AddStmt(S->getEndStmt());
|
|
Record.AddStmt(S->getCond());
|
|
Record.AddStmt(S->getInc());
|
|
Record.AddStmt(S->getLoopVarStmt());
|
|
Record.AddStmt(S->getBody());
|
|
Code = serialization::STMT_CXX_FOR_RANGE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getKeywordLoc());
|
|
Record.push_back(S->isIfExists());
|
|
Record.AddNestedNameSpecifierLoc(S->getQualifierLoc());
|
|
Record.AddDeclarationNameInfo(S->getNameInfo());
|
|
Record.AddStmt(S->getSubStmt());
|
|
Code = serialization::STMT_MS_DEPENDENT_EXISTS;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
|
|
VisitCallExpr(E);
|
|
Record.push_back(E->getOperator());
|
|
Record.AddSourceRange(E->Range);
|
|
Code = serialization::EXPR_CXX_OPERATOR_CALL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
|
VisitCallExpr(E);
|
|
Code = serialization::EXPR_CXX_MEMBER_CALL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXRewrittenBinaryOperator(
|
|
CXXRewrittenBinaryOperator *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->isReversed());
|
|
Record.AddStmt(E->getSemanticForm());
|
|
Code = serialization::EXPR_CXX_REWRITTEN_BINARY_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumArgs());
|
|
Record.push_back(E->isElidable());
|
|
Record.push_back(E->hadMultipleCandidates());
|
|
Record.push_back(E->isListInitialization());
|
|
Record.push_back(E->isStdInitListInitialization());
|
|
Record.push_back(E->requiresZeroInitialization());
|
|
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.AddDeclRef(E->getConstructor());
|
|
Record.AddSourceRange(E->getParenOrBraceRange());
|
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
Record.AddStmt(E->getArg(I));
|
|
|
|
Code = serialization::EXPR_CXX_CONSTRUCT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getConstructor());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.push_back(E->constructsVBase());
|
|
Record.push_back(E->inheritedFromVBase());
|
|
Code = serialization::EXPR_CXX_INHERITED_CTOR_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
|
|
VisitCXXConstructExpr(E);
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->LambdaExprBits.NumCaptures);
|
|
Record.AddSourceRange(E->IntroducerRange);
|
|
Record.push_back(E->LambdaExprBits.CaptureDefault); // FIXME: stable encoding
|
|
Record.AddSourceLocation(E->CaptureDefaultLoc);
|
|
Record.push_back(E->LambdaExprBits.ExplicitParams);
|
|
Record.push_back(E->LambdaExprBits.ExplicitResultType);
|
|
Record.AddSourceLocation(E->ClosingBrace);
|
|
|
|
// Add capture initializers.
|
|
for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
|
|
CEnd = E->capture_init_end();
|
|
C != CEnd; ++C) {
|
|
Record.AddStmt(*C);
|
|
}
|
|
|
|
// Don't serialize the body. It belongs to the call operator declaration.
|
|
// LambdaExpr only stores a copy of the Stmt *.
|
|
|
|
Code = serialization::EXPR_LAMBDA;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Record.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()));
|
|
Record.AddSourceRange(E->getAngleBrackets());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
|
|
VisitCXXNamedCastExpr(E);
|
|
Code = serialization::EXPR_CXX_STATIC_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
|
|
VisitCXXNamedCastExpr(E);
|
|
Code = serialization::EXPR_CXX_DYNAMIC_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
|
|
VisitCXXNamedCastExpr(E);
|
|
Code = serialization::EXPR_CXX_REINTERPRET_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
|
VisitCXXNamedCastExpr(E);
|
|
Code = serialization::EXPR_CXX_CONST_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
|
|
VisitCXXNamedCastExpr(E);
|
|
Code = serialization::EXPR_CXX_ADDRSPACE_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBuiltinBitCastExpr(BuiltinBitCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
Code = serialization::EXPR_BUILTIN_BIT_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
|
|
VisitCallExpr(E);
|
|
Record.AddSourceLocation(E->UDSuffixLoc);
|
|
Code = serialization::EXPR_USER_DEFINED_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Code = serialization::EXPR_CXX_BOOL_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
if (E->isTypeOperand()) {
|
|
Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
|
|
Code = serialization::EXPR_CXX_TYPEID_TYPE;
|
|
} else {
|
|
Record.AddStmt(E->getExprOperand());
|
|
Code = serialization::EXPR_CXX_TYPEID_EXPR;
|
|
}
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.push_back(E->isImplicit());
|
|
Code = serialization::EXPR_CXX_THIS;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getThrowLoc());
|
|
Record.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->isThrownVariableInScope());
|
|
Code = serialization::EXPR_CXX_THROW;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getParam());
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
|
|
Record.AddSourceLocation(E->getUsedLocation());
|
|
Record.push_back(E->hasRewrittenInit());
|
|
if (E->hasRewrittenInit())
|
|
Record.AddStmt(E->getRewrittenExpr());
|
|
Code = serialization::EXPR_CXX_DEFAULT_ARG;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->hasRewrittenInit());
|
|
Record.AddDeclRef(E->getField());
|
|
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
|
|
Record.AddSourceLocation(E->getExprLoc());
|
|
if (E->hasRewrittenInit())
|
|
Record.AddStmt(E->getRewrittenExpr());
|
|
Code = serialization::EXPR_CXX_DEFAULT_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddCXXTemporary(E->getTemporary());
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_CXX_BIND_TEMPORARY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isArray());
|
|
Record.push_back(E->hasInitializer());
|
|
Record.push_back(E->getNumPlacementArgs());
|
|
Record.push_back(E->isParenTypeId());
|
|
|
|
Record.push_back(E->isGlobalNew());
|
|
Record.push_back(E->passAlignment());
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
|
Record.push_back(E->CXXNewExprBits.StoredInitializationStyle);
|
|
|
|
Record.AddDeclRef(E->getOperatorNew());
|
|
Record.AddDeclRef(E->getOperatorDelete());
|
|
Record.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo());
|
|
if (E->isParenTypeId())
|
|
Record.AddSourceRange(E->getTypeIdParens());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Record.AddSourceRange(E->getDirectInitRange());
|
|
|
|
for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), N = E->raw_arg_end();
|
|
I != N; ++I)
|
|
Record.AddStmt(*I);
|
|
|
|
Code = serialization::EXPR_CXX_NEW;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->isGlobalDelete());
|
|
Record.push_back(E->isArrayForm());
|
|
Record.push_back(E->isArrayFormAsWritten());
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
|
Record.AddDeclRef(E->getOperatorDelete());
|
|
Record.AddStmt(E->getArgument());
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
|
|
Code = serialization::EXPR_CXX_DELETE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.AddStmt(E->getBase());
|
|
Record.push_back(E->isArrow());
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
Record.AddTypeSourceInfo(E->getScopeTypeInfo());
|
|
Record.AddSourceLocation(E->getColonColonLoc());
|
|
Record.AddSourceLocation(E->getTildeLoc());
|
|
|
|
// PseudoDestructorTypeStorage.
|
|
Record.AddIdentifierRef(E->getDestroyedTypeIdentifier());
|
|
if (E->getDestroyedTypeIdentifier())
|
|
Record.AddSourceLocation(E->getDestroyedTypeLoc());
|
|
else
|
|
Record.AddTypeSourceInfo(E->getDestroyedTypeInfo());
|
|
|
|
Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumObjects());
|
|
for (auto &Obj : E->getObjects()) {
|
|
if (auto *BD = Obj.dyn_cast<BlockDecl *>()) {
|
|
Record.push_back(serialization::COK_Block);
|
|
Record.AddDeclRef(BD);
|
|
} else if (auto *CLE = Obj.dyn_cast<CompoundLiteralExpr *>()) {
|
|
Record.push_back(serialization::COK_CompoundLiteral);
|
|
Record.AddStmt(CLE);
|
|
}
|
|
}
|
|
|
|
Record.push_back(E->cleanupsHaveSideEffects());
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXDependentScopeMemberExpr(
|
|
CXXDependentScopeMemberExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
// Don't emit anything here (or if you do you will have to update
|
|
// the corresponding deserialization function).
|
|
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
|
Record.push_back(E->getNumTemplateArgs());
|
|
Record.push_back(E->hasFirstQualifierFoundInScope());
|
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
|
AddTemplateKWAndArgsInfo(ArgInfo,
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
|
}
|
|
|
|
Record.push_back(E->isArrow());
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
Record.AddTypeRef(E->getBaseType());
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
if (!E->isImplicitAccess())
|
|
Record.AddStmt(E->getBase());
|
|
else
|
|
Record.AddStmt(nullptr);
|
|
|
|
if (E->hasFirstQualifierFoundInScope())
|
|
Record.AddDeclRef(E->getFirstQualifierFoundInScope());
|
|
|
|
Record.AddDeclarationNameInfo(E->MemberNameInfo);
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
|
|
}
|
|
|
|
void
|
|
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
|
// emitted first.
|
|
|
|
Record.push_back(E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo);
|
|
if (E->DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo) {
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
*E->getTrailingObjects<ASTTemplateKWAndArgsInfo>();
|
|
Record.push_back(ArgInfo.NumTemplateArgs);
|
|
AddTemplateKWAndArgsInfo(ArgInfo,
|
|
E->getTrailingObjects<TemplateArgumentLoc>());
|
|
}
|
|
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
Record.AddDeclarationNameInfo(E->NameInfo);
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
|
|
}
|
|
|
|
void
|
|
ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumArgs());
|
|
for (CXXUnresolvedConstructExpr::arg_iterator
|
|
ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
|
|
Record.AddStmt(*ArgI);
|
|
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
|
|
Record.AddSourceLocation(E->getLParenLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumDecls());
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
|
const ASTTemplateKWAndArgsInfo &ArgInfo =
|
|
*E->getTrailingASTTemplateKWAndArgsInfo();
|
|
Record.push_back(ArgInfo.NumTemplateArgs);
|
|
AddTemplateKWAndArgsInfo(ArgInfo, E->getTrailingTemplateArgumentLoc());
|
|
}
|
|
|
|
for (OverloadExpr::decls_iterator OvI = E->decls_begin(),
|
|
OvE = E->decls_end();
|
|
OvI != OvE; ++OvI) {
|
|
Record.AddDeclRef(OvI.getDecl());
|
|
Record.push_back(OvI.getAccess());
|
|
}
|
|
|
|
Record.AddDeclarationNameInfo(E->getNameInfo());
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
|
|
VisitOverloadExpr(E);
|
|
Record.push_back(E->isArrow());
|
|
Record.push_back(E->hasUnresolvedUsing());
|
|
Record.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
|
|
Record.AddTypeRef(E->getBaseType());
|
|
Record.AddSourceLocation(E->getOperatorLoc());
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
|
|
VisitOverloadExpr(E);
|
|
Record.push_back(E->requiresADL());
|
|
Record.push_back(E->isOverloaded());
|
|
Record.AddDeclRef(E->getNamingClass());
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->TypeTraitExprBits.NumArgs);
|
|
Record.push_back(E->TypeTraitExprBits.Kind); // FIXME: Stable encoding
|
|
Record.push_back(E->TypeTraitExprBits.Value);
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
Record.AddTypeSourceInfo(E->getArg(I));
|
|
Code = serialization::EXPR_TYPE_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getTrait());
|
|
Record.push_back(E->getValue());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Record.AddTypeSourceInfo(E->getQueriedTypeSourceInfo());
|
|
Record.AddStmt(E->getDimensionExpression());
|
|
Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getTrait());
|
|
Record.push_back(E->getValue());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Record.AddStmt(E->getQueriedExpression());
|
|
Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Record.AddStmt(E->getOperand());
|
|
Code = serialization::EXPR_CXX_NOEXCEPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getEllipsisLoc());
|
|
Record.push_back(E->NumExpansions);
|
|
Record.AddStmt(E->getPattern());
|
|
Code = serialization::EXPR_PACK_EXPANSION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->isPartiallySubstituted() ? E->getPartialArguments().size()
|
|
: 0);
|
|
Record.AddSourceLocation(E->OperatorLoc);
|
|
Record.AddSourceLocation(E->PackLoc);
|
|
Record.AddSourceLocation(E->RParenLoc);
|
|
Record.AddDeclRef(E->Pack);
|
|
if (E->isPartiallySubstituted()) {
|
|
for (const auto &TA : E->getPartialArguments())
|
|
Record.AddTemplateArgument(TA);
|
|
} else if (!E->isValueDependent()) {
|
|
Record.push_back(E->getPackLength());
|
|
}
|
|
Code = serialization::EXPR_SIZEOF_PACK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
|
|
SubstNonTypeTemplateParmExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getAssociatedDecl());
|
|
Record.push_back(E->isReferenceParameter());
|
|
Record.push_back(E->getIndex());
|
|
if (auto PackIndex = E->getPackIndex())
|
|
Record.push_back(*PackIndex + 1);
|
|
else
|
|
Record.push_back(0);
|
|
Record.AddSourceLocation(E->getNameLoc());
|
|
Record.AddStmt(E->getReplacement());
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddDeclRef(E->getAssociatedDecl());
|
|
Record.push_back(E->getIndex());
|
|
Record.AddTemplateArgument(E->getArgumentPack());
|
|
Record.AddSourceLocation(E->getParameterPackLocation());
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumExpansions());
|
|
Record.AddDeclRef(E->getParameterPack());
|
|
Record.AddSourceLocation(E->getParameterPackLocation());
|
|
for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
|
|
I != End; ++I)
|
|
Record.AddDeclRef(*I);
|
|
Code = serialization::EXPR_FUNCTION_PARM_PACK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(static_cast<bool>(E->getLifetimeExtendedTemporaryDecl()));
|
|
if (E->getLifetimeExtendedTemporaryDecl())
|
|
Record.AddDeclRef(E->getLifetimeExtendedTemporaryDecl());
|
|
else
|
|
Record.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->LParenLoc);
|
|
Record.AddSourceLocation(E->EllipsisLoc);
|
|
Record.AddSourceLocation(E->RParenLoc);
|
|
Record.push_back(E->NumExpansions);
|
|
Record.AddStmt(E->SubExprs[0]);
|
|
Record.AddStmt(E->SubExprs[1]);
|
|
Record.AddStmt(E->SubExprs[2]);
|
|
Record.push_back(E->Opcode);
|
|
Code = serialization::EXPR_CXX_FOLD;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXParenListInitExpr(CXXParenListInitExpr *E) {
|
|
VisitExpr(E);
|
|
ArrayRef<Expr *> InitExprs = E->getInitExprs();
|
|
Record.push_back(InitExprs.size());
|
|
Record.push_back(E->getUserSpecifiedInitExprs().size());
|
|
Record.AddSourceLocation(E->getInitLoc());
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
for (Expr *InitExpr : E->getInitExprs())
|
|
Record.AddStmt(InitExpr);
|
|
Expr *ArrayFiller = E->getArrayFiller();
|
|
FieldDecl *UnionField = E->getInitializedFieldInUnion();
|
|
bool HasArrayFillerOrUnionDecl = ArrayFiller || UnionField;
|
|
Record.push_back(HasArrayFillerOrUnionDecl);
|
|
if (HasArrayFillerOrUnionDecl) {
|
|
Record.push_back(static_cast<bool>(ArrayFiller));
|
|
if (ArrayFiller)
|
|
Record.AddStmt(ArrayFiller);
|
|
else
|
|
Record.AddDeclRef(UnionField);
|
|
}
|
|
Code = serialization::EXPR_CXX_PAREN_LIST_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getSourceExpr());
|
|
Record.AddSourceLocation(E->getLocation());
|
|
Record.push_back(E->isUnique());
|
|
Code = serialization::EXPR_OPAQUE_VALUE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
|
|
VisitExpr(E);
|
|
// TODO: Figure out sane writer behavior for a TypoExpr, if necessary
|
|
llvm_unreachable("Cannot write TypoExpr nodes");
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CUDA Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
|
VisitCallExpr(E);
|
|
Record.AddStmt(E->getConfig());
|
|
Code = serialization::EXPR_CUDA_KERNEL_CALL;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OpenCL Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceLocation(E->getBuiltinLoc());
|
|
Record.AddSourceLocation(E->getRParenLoc());
|
|
Record.AddStmt(E->getSrcExpr());
|
|
Code = serialization::EXPR_ASTYPE;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Microsoft Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->isArrow());
|
|
Record.AddStmt(E->getBaseExpr());
|
|
Record.AddNestedNameSpecifierLoc(E->getQualifierLoc());
|
|
Record.AddSourceLocation(E->getMemberLoc());
|
|
Record.AddDeclRef(E->getPropertyDecl());
|
|
Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMSPropertySubscriptExpr(MSPropertySubscriptExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddStmt(E->getBase());
|
|
Record.AddStmt(E->getIdx());
|
|
Record.AddSourceLocation(E->getRBracketLoc());
|
|
Code = serialization::EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
|
VisitExpr(E);
|
|
Record.AddSourceRange(E->getSourceRange());
|
|
Record.AddDeclRef(E->getGuidDecl());
|
|
if (E->isTypeOperand()) {
|
|
Record.AddTypeSourceInfo(E->getTypeOperandSourceInfo());
|
|
Code = serialization::EXPR_CXX_UUIDOF_TYPE;
|
|
} else {
|
|
Record.AddStmt(E->getExprOperand());
|
|
Code = serialization::EXPR_CXX_UUIDOF_EXPR;
|
|
}
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getExceptLoc());
|
|
Record.AddStmt(S->getFilterExpr());
|
|
Record.AddStmt(S->getBlock());
|
|
Code = serialization::STMT_SEH_EXCEPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getFinallyLoc());
|
|
Record.AddStmt(S->getBlock());
|
|
Code = serialization::STMT_SEH_FINALLY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getIsCXXTry());
|
|
Record.AddSourceLocation(S->getTryLoc());
|
|
Record.AddStmt(S->getTryBlock());
|
|
Record.AddStmt(S->getHandler());
|
|
Code = serialization::STMT_SEH_TRY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
|
|
VisitStmt(S);
|
|
Record.AddSourceLocation(S->getLeaveLoc());
|
|
Code = serialization::STMT_SEH_LEAVE;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OpenMP Directives.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitOMPCanonicalLoop(OMPCanonicalLoop *S) {
|
|
VisitStmt(S);
|
|
for (Stmt *SubStmt : S->SubStmts)
|
|
Record.AddStmt(SubStmt);
|
|
Code = serialization::STMT_OMP_CANONICAL_LOOP;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
|
|
Record.writeOMPChildren(E->Data);
|
|
Record.AddSourceLocation(E->getBeginLoc());
|
|
Record.AddSourceLocation(E->getEndLoc());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPLoopBasedDirective(OMPLoopBasedDirective *D) {
|
|
VisitStmt(D);
|
|
Record.writeUInt32(D->getLoopsNumber());
|
|
VisitOMPExecutableDirective(D);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
|
|
VisitOMPLoopBasedDirective(D);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMetaDirective(OMPMetaDirective *D) {
|
|
VisitStmt(D);
|
|
Record.push_back(D->getNumClauses());
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_META_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPLoopTransformationDirective(
|
|
OMPLoopTransformationDirective *D) {
|
|
VisitOMPLoopBasedDirective(D);
|
|
Record.writeUInt32(D->getNumGeneratedLoops());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTileDirective(OMPTileDirective *D) {
|
|
VisitOMPLoopTransformationDirective(D);
|
|
Code = serialization::STMT_OMP_TILE_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPUnrollDirective(OMPUnrollDirective *D) {
|
|
VisitOMPLoopTransformationDirective(D);
|
|
Code = serialization::STMT_OMP_UNROLL_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_FOR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.AddDeclarationNameInfo(D->getDirectiveName());
|
|
Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelForSimdDirective(
|
|
OMPParallelForSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterDirective(
|
|
OMPParallelMasterDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMaskedDirective(
|
|
OMPParallelMaskedDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_PARALLEL_MASKED_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelSectionsDirective(
|
|
OMPParallelSectionsDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_TASK_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->isXLHSInRHSPart());
|
|
Record.writeBool(D->isPostfixUpdate());
|
|
Record.writeBool(D->isFailOnly());
|
|
Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetDataDirective(OMPTargetDataDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_DATA_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetEnterDataDirective(
|
|
OMPTargetEnterDataDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetExitDataDirective(
|
|
OMPTargetExitDataDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelDirective(
|
|
OMPTargetParallelDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelForDirective(
|
|
OMPTargetParallelForDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|
VisitStmt(D);
|
|
Record.push_back(D->getNumClauses());
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPErrorDirective(OMPErrorDirective *D) {
|
|
VisitStmt(D);
|
|
Record.push_back(D->getNumClauses());
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_ERROR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPDepobjDirective(OMPDepobjDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_DEPOBJ_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPScanDirective(OMPScanDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_SCAN_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPCancellationPointDirective(
|
|
OMPCancellationPointDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeEnum(D->getCancelRegion());
|
|
Code = serialization::STMT_OMP_CANCELLATION_POINT_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.writeEnum(D->getCancelRegion());
|
|
Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_TASKLOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTaskLoopSimdDirective(OMPTaskLoopSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TASKLOOP_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMasterTaskLoopDirective(
|
|
OMPMasterTaskLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_MASTER_TASKLOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMaskedTaskLoopDirective(
|
|
OMPMaskedTaskLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_MASKED_TASKLOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMasterTaskLoopSimdDirective(
|
|
OMPMasterTaskLoopSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_MASTER_TASKLOOP_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMaskedTaskLoopSimdDirective(
|
|
OMPMaskedTaskLoopSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_MASKED_TASKLOOP_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterTaskLoopDirective(
|
|
OMPParallelMasterTaskLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopDirective(
|
|
OMPParallelMaskedTaskLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMasterTaskLoopSimdDirective(
|
|
OMPParallelMasterTaskLoopSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_PARALLEL_MASTER_TASKLOOP_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelMaskedTaskLoopSimdDirective(
|
|
OMPParallelMaskedTaskLoopSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_PARALLEL_MASKED_TASKLOOP_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPDistributeDirective(OMPDistributeDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetUpdateDirective(OMPTargetUpdateDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_UPDATE_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPDistributeParallelForDirective(
|
|
OMPDistributeParallelForDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPDistributeParallelForSimdDirective(
|
|
OMPDistributeParallelForSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPDistributeSimdDirective(
|
|
OMPDistributeSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelForSimdDirective(
|
|
OMPTargetParallelForSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetSimdDirective(OMPTargetSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeDirective(
|
|
OMPTeamsDistributeDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeSimdDirective(
|
|
OMPTeamsDistributeSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeParallelForSimdDirective(
|
|
OMPTeamsDistributeParallelForSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTeamsDistributeParallelForDirective(
|
|
OMPTeamsDistributeParallelForDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDirective(OMPTargetTeamsDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeDirective(
|
|
OMPTargetTeamsDistributeDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForDirective(
|
|
OMPTargetTeamsDistributeParallelForDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Record.writeBool(D->hasCancel());
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
|
|
OMPTargetTeamsDistributeParallelForSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::
|
|
STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsDistributeSimdDirective(
|
|
OMPTargetTeamsDistributeSimdDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPInteropDirective(OMPInteropDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_INTEROP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPDispatchDirective(OMPDispatchDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Record.AddSourceLocation(D->getTargetCallLoc());
|
|
Code = serialization::STMT_OMP_DISPATCH_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPMaskedDirective(OMPMaskedDirective *D) {
|
|
VisitStmt(D);
|
|
VisitOMPExecutableDirective(D);
|
|
Code = serialization::STMT_OMP_MASKED_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPGenericLoopDirective(OMPGenericLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_GENERIC_LOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTeamsGenericLoopDirective(
|
|
OMPTeamsGenericLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TEAMS_GENERIC_LOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetTeamsGenericLoopDirective(
|
|
OMPTargetTeamsGenericLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPParallelGenericLoopDirective(
|
|
OMPParallelGenericLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOMPTargetParallelGenericLoopDirective(
|
|
OMPTargetParallelGenericLoopDirective *D) {
|
|
VisitOMPLoopDirective(D);
|
|
Code = serialization::STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ASTWriter Implementation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
|
|
assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
|
|
"SwitchCase recorded twice");
|
|
unsigned NextID = SwitchCaseIDs.size();
|
|
SwitchCaseIDs[S] = NextID;
|
|
return NextID;
|
|
}
|
|
|
|
unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
|
|
assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
|
|
"SwitchCase hasn't been seen yet");
|
|
return SwitchCaseIDs[S];
|
|
}
|
|
|
|
void ASTWriter::ClearSwitchCaseIDs() {
|
|
SwitchCaseIDs.clear();
|
|
}
|
|
|
|
/// Write the given substatement or subexpression to the
|
|
/// bitstream.
|
|
void ASTWriter::WriteSubStmt(Stmt *S) {
|
|
RecordData Record;
|
|
ASTStmtWriter Writer(*this, Record);
|
|
++NumStatements;
|
|
|
|
if (!S) {
|
|
Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
|
|
return;
|
|
}
|
|
|
|
llvm::DenseMap<Stmt *, uint64_t>::iterator I = SubStmtEntries.find(S);
|
|
if (I != SubStmtEntries.end()) {
|
|
Record.push_back(I->second);
|
|
Stream.EmitRecord(serialization::STMT_REF_PTR, Record);
|
|
return;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
assert(!ParentStmts.count(S) && "There is a Stmt cycle!");
|
|
|
|
struct ParentStmtInserterRAII {
|
|
Stmt *S;
|
|
llvm::DenseSet<Stmt *> &ParentStmts;
|
|
|
|
ParentStmtInserterRAII(Stmt *S, llvm::DenseSet<Stmt *> &ParentStmts)
|
|
: S(S), ParentStmts(ParentStmts) {
|
|
ParentStmts.insert(S);
|
|
}
|
|
~ParentStmtInserterRAII() {
|
|
ParentStmts.erase(S);
|
|
}
|
|
};
|
|
|
|
ParentStmtInserterRAII ParentStmtInserter(S, ParentStmts);
|
|
#endif
|
|
|
|
Writer.Visit(S);
|
|
|
|
uint64_t Offset = Writer.Emit();
|
|
SubStmtEntries[S] = Offset;
|
|
}
|
|
|
|
/// Flush all of the statements that have been added to the
|
|
/// queue via AddStmt().
|
|
void ASTRecordWriter::FlushStmts() {
|
|
// We expect to be the only consumer of the two temporary statement maps,
|
|
// assert that they are empty.
|
|
assert(Writer->SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
|
|
assert(Writer->ParentStmts.empty() && "unexpected entries in parent stmt map");
|
|
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
|
Writer->WriteSubStmt(StmtsToEmit[I]);
|
|
|
|
assert(N == StmtsToEmit.size() && "record modified while being written!");
|
|
|
|
// Note that we are at the end of a full expression. Any
|
|
// expression records that follow this one are part of a different
|
|
// expression.
|
|
Writer->Stream.EmitRecord(serialization::STMT_STOP, ArrayRef<uint32_t>());
|
|
|
|
Writer->SubStmtEntries.clear();
|
|
Writer->ParentStmts.clear();
|
|
}
|
|
|
|
StmtsToEmit.clear();
|
|
}
|
|
|
|
void ASTRecordWriter::FlushSubStmts() {
|
|
// For a nested statement, write out the substatements in reverse order (so
|
|
// that a simple stack machine can be used when loading), and don't emit a
|
|
// STMT_STOP after each one.
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
|
Writer->WriteSubStmt(StmtsToEmit[N - I - 1]);
|
|
assert(N == StmtsToEmit.size() && "record modified while being written!");
|
|
}
|
|
|
|
StmtsToEmit.clear();
|
|
}
|