llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
Serge Pavlov f7819ce166 [FPEnv] Allow CompoundStmt to keep FP options
This is a recommit of b822efc7404bf09ccfdc1ab7657475026966c3b2,
reverted in dc34d8df4c48b3a8f474360970cae8a58e6c84f0. The commit caused
fails because the test ast-print-fp-pragmas.c did not specify particular
target, and it failed on targets which do not support constrained
intrinsics. The original commit message is below.

AST does not have special nodes for pragmas. Instead a pragma modifies
some state variables of Sema, which in turn results in modified
attributes of AST nodes. This technique applies to floating point
operations as well. Every AST node that can depend on FP options keeps
current set of them.

This technique works well for options like exception behavior or fast
math options. They represent instructions to the compiler how to modify
code generation for the affected nodes. However treatment of FP control
modes has problems with this technique. Modifying FP control mode
(like rounding direction) usually requires operations on hardware, like
writing to control registers. It must be done prior to the first
operation that depends on the control mode. In particular, such
operations are required for implementation of `pragma STDC FENV_ROUND`,
compiler should set up necessary rounding direction at the beginning of
compound statement where the pragma occurs. As there is no representation
for pragmas in AST, the code generation becomes a complicated task in
this case.

To solve this issue FP options are kept inside CompoundStmt. Unlike to FP
options in expressions, these does not affect any operation on FP values,
but only inform the codegen about the FP options that act in the body of
the statement. As all pragmas that modify FP environment may occurs only
at the start of compound statement or at global level, such solution
works for all relevant pragmas. The options are kept as a difference
from the options in the enclosing compound statement or default options,
it helps codegen to set only changed control modes.

Differential Revision: https://reviews.llvm.org/D123952
2022-07-03 17:06:26 +07:00

2757 lines
89 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);
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);
ArrayRef<TemplateArgument> TemplateArgs = E->getTemplateArguments();
Record.push_back(TemplateArgs.size());
Record.AddNestedNameSpecifierLoc(E->getNestedNameSpecifierLoc());
Record.AddSourceLocation(E->getTemplateKWLoc());
Record.AddDeclarationNameInfo(E->getConceptNameInfo());
Record.AddDeclRef(E->getNamedConcept());
Record.AddDeclRef(E->getFoundDecl());
Record.AddASTTemplateArgumentListInfo(E->getTemplateArgsAsWritten());
for (const TemplateArgument &Arg : TemplateArgs)
Record.AddTemplateArgument(Arg);
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->isSubstitutionFailure());
if (NestedReq->isSubstitutionFailure()){
addSubstitutionDiagnostic(Record,
NestedReq->getSubstitutionDiagnostic());
} else {
Record.AddStmt(NestedReq->Value.get<Expr *>());
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());
Code = serialization::EXPR_CXX_DEFAULT_ARG;
}
void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
VisitExpr(E);
Record.AddDeclRef(E->getField());
Record.AddDeclRef(cast_or_null<Decl>(E->getUsedContext()));
Record.AddSourceLocation(E->getExprLoc());
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->getParameter());
Record.push_back(E->isReferenceParameter());
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->getParameterPack());
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::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::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();
}