reference is going to message the setter, the getter, or both. Having this info on the ObjCPropertyRefExpr node makes it easier for AST clients (like libclang) to reason about the meaning of the property reference. [AST/Sema] -Use 2 bits (with a PointerIntPair) in ObjCPropertyRefExpr to record the above info -Have ObjCPropertyOpBuilder set the info appropriately. [libclang] -When there is an implicit property reference (property syntax using methods) have clang_getCursorReferenced return a cursor for the method. If the property reference is going to result in messaging both the getter and the setter choose to return a cursor for the setter because it is less obvious from source inspection that the setter is getting called. The general idea has the seal of approval by John. rdar://11151621 llvm-svn: 153709
1666 lines
56 KiB
C++
1666 lines
56 KiB
C++
//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements serialization for Statements and Expressions.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Serialization/ASTWriter.h"
|
|
#include "clang/AST/DeclCXX.h"
|
|
#include "clang/AST/DeclObjC.h"
|
|
#include "clang/AST/DeclTemplate.h"
|
|
#include "clang/AST/StmtVisitor.h"
|
|
#include "llvm/Bitcode/BitstreamWriter.h"
|
|
using namespace clang;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Statement/expression serialization
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace clang {
|
|
class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
|
|
ASTWriter &Writer;
|
|
ASTWriter::RecordData &Record;
|
|
|
|
public:
|
|
serialization::StmtCode Code;
|
|
unsigned AbbrevToUse;
|
|
|
|
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
|
|
: Writer(Writer), Record(Record) { }
|
|
|
|
void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args);
|
|
|
|
void VisitStmt(Stmt *S);
|
|
#define STMT(Type, Base) \
|
|
void Visit##Type(Type *);
|
|
#include "clang/AST/StmtNodes.inc"
|
|
};
|
|
}
|
|
|
|
void ASTStmtWriter::
|
|
AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) {
|
|
Writer.AddSourceLocation(Args.getTemplateKeywordLoc(), Record);
|
|
Writer.AddSourceLocation(Args.LAngleLoc, Record);
|
|
Writer.AddSourceLocation(Args.RAngleLoc, Record);
|
|
for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
|
|
Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitStmt(Stmt *S) {
|
|
}
|
|
|
|
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getSemiLoc(), Record);
|
|
Record.push_back(S->HasLeadingEmptyMacro);
|
|
Code = serialization::STMT_NULL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->size());
|
|
for (CompoundStmt::body_iterator CS = S->body_begin(), CSEnd = S->body_end();
|
|
CS != CSEnd; ++CS)
|
|
Writer.AddStmt(*CS);
|
|
Writer.AddSourceLocation(S->getLBracLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRBracLoc(), Record);
|
|
Code = serialization::STMT_COMPOUND;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(Writer.getSwitchCaseID(S));
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
|
|
VisitSwitchCase(S);
|
|
Writer.AddStmt(S->getLHS());
|
|
Writer.AddStmt(S->getRHS());
|
|
Writer.AddStmt(S->getSubStmt());
|
|
Writer.AddSourceLocation(S->getCaseLoc(), Record);
|
|
Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
|
|
Writer.AddSourceLocation(S->getColonLoc(), Record);
|
|
Code = serialization::STMT_CASE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
|
|
VisitSwitchCase(S);
|
|
Writer.AddStmt(S->getSubStmt());
|
|
Writer.AddSourceLocation(S->getDefaultLoc(), Record);
|
|
Writer.AddSourceLocation(S->getColonLoc(), Record);
|
|
Code = serialization::STMT_DEFAULT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddDeclRef(S->getDecl(), Record);
|
|
Writer.AddStmt(S->getSubStmt());
|
|
Writer.AddSourceLocation(S->getIdentLoc(), Record);
|
|
Code = serialization::STMT_LABEL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
|
Writer.AddStmt(S->getCond());
|
|
Writer.AddStmt(S->getThen());
|
|
Writer.AddStmt(S->getElse());
|
|
Writer.AddSourceLocation(S->getIfLoc(), Record);
|
|
Writer.AddSourceLocation(S->getElseLoc(), Record);
|
|
Code = serialization::STMT_IF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
|
Writer.AddStmt(S->getCond());
|
|
Writer.AddStmt(S->getBody());
|
|
Writer.AddSourceLocation(S->getSwitchLoc(), Record);
|
|
Record.push_back(S->isAllEnumCasesCovered());
|
|
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);
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
|
Writer.AddStmt(S->getCond());
|
|
Writer.AddStmt(S->getBody());
|
|
Writer.AddSourceLocation(S->getWhileLoc(), Record);
|
|
Code = serialization::STMT_WHILE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddStmt(S->getCond());
|
|
Writer.AddStmt(S->getBody());
|
|
Writer.AddSourceLocation(S->getDoLoc(), Record);
|
|
Writer.AddSourceLocation(S->getWhileLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
|
Code = serialization::STMT_DO;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitForStmt(ForStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddStmt(S->getInit());
|
|
Writer.AddStmt(S->getCond());
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
|
Writer.AddStmt(S->getInc());
|
|
Writer.AddStmt(S->getBody());
|
|
Writer.AddSourceLocation(S->getForLoc(), Record);
|
|
Writer.AddSourceLocation(S->getLParenLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
|
Code = serialization::STMT_FOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddDeclRef(S->getLabel(), Record);
|
|
Writer.AddSourceLocation(S->getGotoLoc(), Record);
|
|
Writer.AddSourceLocation(S->getLabelLoc(), Record);
|
|
Code = serialization::STMT_GOTO;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getGotoLoc(), Record);
|
|
Writer.AddSourceLocation(S->getStarLoc(), Record);
|
|
Writer.AddStmt(S->getTarget());
|
|
Code = serialization::STMT_INDIRECT_GOTO;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getContinueLoc(), Record);
|
|
Code = serialization::STMT_CONTINUE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getBreakLoc(), Record);
|
|
Code = serialization::STMT_BREAK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddStmt(S->getRetValue());
|
|
Writer.AddSourceLocation(S->getReturnLoc(), Record);
|
|
Writer.AddDeclRef(S->getNRVOCandidate(), Record);
|
|
Code = serialization::STMT_RETURN;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getStartLoc(), Record);
|
|
Writer.AddSourceLocation(S->getEndLoc(), Record);
|
|
DeclGroupRef DG = S->getDeclGroup();
|
|
for (DeclGroupRef::iterator D = DG.begin(), DEnd = DG.end(); D != DEnd; ++D)
|
|
Writer.AddDeclRef(*D, Record);
|
|
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());
|
|
Writer.AddSourceLocation(S->getAsmLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
|
Record.push_back(S->isVolatile());
|
|
Record.push_back(S->isSimple());
|
|
Record.push_back(S->isMSAsm());
|
|
Writer.AddStmt(S->getAsmString());
|
|
|
|
// Outputs
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
|
|
Writer.AddStmt(S->getOutputConstraintLiteral(I));
|
|
Writer.AddStmt(S->getOutputExpr(I));
|
|
}
|
|
|
|
// Inputs
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
|
Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
|
|
Writer.AddStmt(S->getInputConstraintLiteral(I));
|
|
Writer.AddStmt(S->getInputExpr(I));
|
|
}
|
|
|
|
// Clobbers
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
|
Writer.AddStmt(S->getClobber(I));
|
|
|
|
Code = serialization::STMT_ASM;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExpr(Expr *E) {
|
|
VisitStmt(E);
|
|
Writer.AddTypeRef(E->getType(), Record);
|
|
Record.push_back(E->isTypeDependent());
|
|
Record.push_back(E->isValueDependent());
|
|
Record.push_back(E->isInstantiationDependent());
|
|
Record.push_back(E->containsUnexpandedParameterPack());
|
|
Record.push_back(E->getValueKind());
|
|
Record.push_back(E->getObjectKind());
|
|
}
|
|
|
|
void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Record.push_back(E->getIdentType()); // FIXME: stable encoding
|
|
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->refersToEnclosingLocal());
|
|
|
|
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) {
|
|
AbbrevToUse = Writer.getDeclRefExprAbbrev();
|
|
}
|
|
|
|
if (E->hasQualifier())
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
|
|
if (E->getDecl() != E->getFoundDecl())
|
|
Writer.AddDeclRef(E->getFoundDecl(), Record);
|
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
|
AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo());
|
|
|
|
Writer.AddDeclRef(E->getDecl(), Record);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
|
|
Code = serialization::EXPR_DECL_REF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Writer.AddAPInt(E->getValue(), Record);
|
|
|
|
if (E->getValue().getBitWidth() == 32) {
|
|
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
|
|
}
|
|
|
|
Code = serialization::EXPR_INTEGER_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
|
|
VisitExpr(E);
|
|
Writer.AddAPFloat(E->getValue(), Record);
|
|
Record.push_back(E->isExact());
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Code = serialization::EXPR_FLOATING_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_IMAGINARY_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getByteLength());
|
|
Record.push_back(E->getNumConcatenated());
|
|
Record.push_back(E->getKind());
|
|
Record.push_back(E->isPascal());
|
|
// FIXME: String data should be stored as a blob at the end of the
|
|
// StringLiteral. However, we can't do so now because we have no
|
|
// provision for coping with abbreviations when we're jumping around
|
|
// the AST file during deserialization.
|
|
Record.append(E->getBytes().begin(), E->getBytes().end());
|
|
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
|
Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
|
|
Code = serialization::EXPR_STRING_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Record.push_back(E->getKind());
|
|
|
|
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
|
|
|
|
Code = serialization::EXPR_CHARACTER_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getLParen(), Record);
|
|
Writer.AddSourceLocation(E->getRParen(), Record);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_PAREN;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->NumExprs);
|
|
for (unsigned i=0; i != E->NumExprs; ++i)
|
|
Writer.AddStmt(E->Exprs[i]);
|
|
Writer.AddSourceLocation(E->LParenLoc, Record);
|
|
Writer.AddSourceLocation(E->RParenLoc, Record);
|
|
Code = serialization::EXPR_PAREN_LIST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Code = serialization::EXPR_UNARY_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumComponents());
|
|
Record.push_back(E->getNumExpressions());
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
|
for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
|
|
const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
|
|
Record.push_back(ON.getKind()); // FIXME: Stable encoding
|
|
Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
|
|
Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
|
|
switch (ON.getKind()) {
|
|
case OffsetOfExpr::OffsetOfNode::Array:
|
|
Record.push_back(ON.getArrayExprIndex());
|
|
break;
|
|
|
|
case OffsetOfExpr::OffsetOfNode::Field:
|
|
Writer.AddDeclRef(ON.getField(), Record);
|
|
break;
|
|
|
|
case OffsetOfExpr::OffsetOfNode::Identifier:
|
|
Writer.AddIdentifierRef(ON.getFieldName(), Record);
|
|
break;
|
|
|
|
case OffsetOfExpr::OffsetOfNode::Base:
|
|
Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
|
|
break;
|
|
}
|
|
}
|
|
for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
|
|
Writer.AddStmt(E->getIndexExpr(I));
|
|
Code = serialization::EXPR_OFFSETOF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getKind());
|
|
if (E->isArgumentType())
|
|
Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
|
|
else {
|
|
Record.push_back(0);
|
|
Writer.AddStmt(E->getArgumentExpr());
|
|
}
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_SIZEOF_ALIGN_OF;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getLHS());
|
|
Writer.AddStmt(E->getRHS());
|
|
Writer.AddSourceLocation(E->getRBracketLoc(), Record);
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumArgs());
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Writer.AddStmt(E->getCallee());
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
Arg != ArgEnd; ++Arg)
|
|
Writer.AddStmt(*Arg);
|
|
Code = serialization::EXPR_CALL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
|
// Don't call VisitExpr, we'll write everything here.
|
|
|
|
Record.push_back(E->hasQualifier());
|
|
if (E->hasQualifier())
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
Writer.AddSourceLocation(E->getTemplateKeywordLoc(), Record);
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
Record.push_back(NumTemplateArgs);
|
|
Writer.AddSourceLocation(E->getLAngleLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRAngleLoc(), Record);
|
|
for (unsigned i=0; i != NumTemplateArgs; ++i)
|
|
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
|
|
}
|
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
|
|
|
DeclAccessPair FoundDecl = E->getFoundDecl();
|
|
Writer.AddDeclRef(FoundDecl.getDecl(), Record);
|
|
Record.push_back(FoundDecl.getAccess());
|
|
|
|
Writer.AddTypeRef(E->getType(), Record);
|
|
Record.push_back(E->getValueKind());
|
|
Record.push_back(E->getObjectKind());
|
|
Writer.AddStmt(E->getBase());
|
|
Writer.AddDeclRef(E->getMemberDecl(), Record);
|
|
Writer.AddSourceLocation(E->getMemberLoc(), Record);
|
|
Record.push_back(E->isArrow());
|
|
Writer.AddDeclarationNameLoc(E->MemberDNLoc,
|
|
E->getMemberDecl()->getDeclName(), Record);
|
|
Code = serialization::EXPR_MEMBER;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getBase());
|
|
Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
|
|
Record.push_back(E->isArrow());
|
|
Code = serialization::EXPR_OBJC_ISA;
|
|
}
|
|
|
|
void ASTStmtWriter::
|
|
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->shouldCopy());
|
|
Code = serialization::EXPR_OBJC_INDIRECT_COPY_RESTORE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
Writer.AddSourceLocation(E->getBridgeKeywordLoc(), Record);
|
|
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());
|
|
Writer.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)
|
|
Writer.AddCXXBaseSpecifier(**PI, Record);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getLHS());
|
|
Writer.AddStmt(E->getRHS());
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Code = serialization::EXPR_BINARY_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
|
|
VisitBinaryOperator(E);
|
|
Writer.AddTypeRef(E->getComputationLHSType(), Record);
|
|
Writer.AddTypeRef(E->getComputationResultType(), Record);
|
|
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getCond());
|
|
Writer.AddStmt(E->getLHS());
|
|
Writer.AddStmt(E->getRHS());
|
|
Writer.AddSourceLocation(E->getQuestionLoc(), Record);
|
|
Writer.AddSourceLocation(E->getColonLoc(), Record);
|
|
Code = serialization::EXPR_CONDITIONAL_OPERATOR;
|
|
}
|
|
|
|
void
|
|
ASTStmtWriter::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getOpaqueValue());
|
|
Writer.AddStmt(E->getCommon());
|
|
Writer.AddStmt(E->getCond());
|
|
Writer.AddStmt(E->getTrueExpr());
|
|
Writer.AddStmt(E->getFalseExpr());
|
|
Writer.AddSourceLocation(E->getQuestionLoc(), Record);
|
|
Writer.AddSourceLocation(E->getColonLoc(), Record);
|
|
Code = serialization::EXPR_BINARY_CONDITIONAL_OPERATOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
|
VisitCastExpr(E);
|
|
Code = serialization::EXPR_IMPLICIT_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
|
VisitCastExpr(E);
|
|
Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_CSTYLE_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
|
Writer.AddStmt(E->getInitializer());
|
|
Record.push_back(E->isFileScope());
|
|
Code = serialization::EXPR_COMPOUND_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getBase());
|
|
Writer.AddIdentifierRef(&E->getAccessor(), Record);
|
|
Writer.AddSourceLocation(E->getAccessorLoc(), Record);
|
|
Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSyntacticForm());
|
|
Writer.AddSourceLocation(E->getLBraceLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRBraceLoc(), Record);
|
|
bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
|
|
Record.push_back(isArrayFiller);
|
|
if (isArrayFiller)
|
|
Writer.AddStmt(E->getArrayFiller());
|
|
else
|
|
Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
|
|
Record.push_back(E->hadArrayRangeDesignator());
|
|
Record.push_back(E->initializesStdInitializerList());
|
|
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)
|
|
Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : 0);
|
|
} else {
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
|
Writer.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)
|
|
Writer.AddStmt(E->getSubExpr(I));
|
|
Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
|
|
Record.push_back(E->usesGNUSyntax());
|
|
for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
|
|
DEnd = E->designators_end();
|
|
D != DEnd; ++D) {
|
|
if (D->isFieldDesignator()) {
|
|
if (FieldDecl *Field = D->getField()) {
|
|
Record.push_back(serialization::DESIG_FIELD_DECL);
|
|
Writer.AddDeclRef(Field, Record);
|
|
} else {
|
|
Record.push_back(serialization::DESIG_FIELD_NAME);
|
|
Writer.AddIdentifierRef(D->getFieldName(), Record);
|
|
}
|
|
Writer.AddSourceLocation(D->getDotLoc(), Record);
|
|
Writer.AddSourceLocation(D->getFieldLoc(), Record);
|
|
} else if (D->isArrayDesignator()) {
|
|
Record.push_back(serialization::DESIG_ARRAY);
|
|
Record.push_back(D->getFirstExprIndex());
|
|
Writer.AddSourceLocation(D->getLBracketLoc(), Record);
|
|
Writer.AddSourceLocation(D->getRBracketLoc(), Record);
|
|
} else {
|
|
assert(D->isArrayRangeDesignator() && "Unknown designator");
|
|
Record.push_back(serialization::DESIG_ARRAY_RANGE);
|
|
Record.push_back(D->getFirstExprIndex());
|
|
Writer.AddSourceLocation(D->getLBracketLoc(), Record);
|
|
Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
|
|
Writer.AddSourceLocation(D->getRBracketLoc(), Record);
|
|
}
|
|
}
|
|
Code = serialization::EXPR_DESIGNATED_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
|
VisitExpr(E);
|
|
Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_VA_ARG;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
|
|
Writer.AddSourceLocation(E->getLabelLoc(), Record);
|
|
Writer.AddDeclRef(E->getLabel(), Record);
|
|
Code = serialization::EXPR_ADDR_LABEL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSubStmt());
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_STMT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getCond());
|
|
Writer.AddStmt(E->getLHS());
|
|
Writer.AddStmt(E->getRHS());
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_CHOOSE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getTokenLocation(), Record);
|
|
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)
|
|
Writer.AddStmt(E->getExpr(I));
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_SHUFFLE_VECTOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddDeclRef(E->getBlockDecl(), Record);
|
|
Code = serialization::EXPR_BLOCK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumAssocs());
|
|
|
|
Writer.AddStmt(E->getControllingExpr());
|
|
for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
|
|
Writer.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I), Record);
|
|
Writer.AddStmt(E->getAssocExpr(I));
|
|
}
|
|
Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
|
|
|
|
Writer.AddSourceLocation(E->getGenericLoc(), Record);
|
|
Writer.AddSourceLocation(E->getDefaultLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
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);
|
|
|
|
Writer.AddStmt(E->getSyntacticForm());
|
|
for (PseudoObjectExpr::semantics_iterator
|
|
i = E->semantics_begin(), e = E->semantics_end(); i != e; ++i) {
|
|
Writer.AddStmt(*i);
|
|
}
|
|
Code = serialization::EXPR_PSEUDO_OBJECT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getOp());
|
|
Writer.AddStmt(E->getPtr());
|
|
Writer.AddStmt(E->getOrder());
|
|
if (E->getOp() != AtomicExpr::Load)
|
|
Writer.AddStmt(E->getVal1());
|
|
if (E->isCmpXChg()) {
|
|
Writer.AddStmt(E->getOrderFail());
|
|
Writer.AddStmt(E->getVal2());
|
|
}
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_ATOMIC;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Objective-C Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getString());
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
Code = serialization::EXPR_OBJC_STRING_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getNumber());
|
|
Writer.AddDeclRef(E->getObjCNumericLiteralMethod(), Record);
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
Code = serialization::EXPR_OBJC_NUMERIC_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumElements());
|
|
for (unsigned i = 0; i < E->getNumElements(); i++)
|
|
Writer.AddStmt(E->getElement(i));
|
|
Writer.AddDeclRef(E->getArrayWithObjectsMethod(), Record);
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
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);
|
|
Writer.AddStmt(Element.Key);
|
|
Writer.AddStmt(Element.Value);
|
|
if (E->HasPackExpansions) {
|
|
Writer.AddSourceLocation(Element.EllipsisLoc, Record);
|
|
unsigned NumExpansions = 0;
|
|
if (Element.NumExpansions)
|
|
NumExpansions = *Element.NumExpansions + 1;
|
|
Record.push_back(NumExpansions);
|
|
}
|
|
}
|
|
|
|
Writer.AddDeclRef(E->getDictWithObjectsMethod(), Record);
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
Code = serialization::EXPR_OBJC_DICTIONARY_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_OBJC_ENCODE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSelectorRef(E->getSelector(), Record);
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddDeclRef(E->getProtocol(), Record);
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddDeclRef(E->getDecl(), Record);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Writer.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()) {
|
|
Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
|
|
Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
|
|
} else {
|
|
Writer.AddDeclRef(E->getExplicitProperty(), Record);
|
|
}
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Writer.AddSourceLocation(E->getReceiverLocation(), Record);
|
|
if (E->isObjectReceiver()) {
|
|
Record.push_back(0);
|
|
Writer.AddStmt(E->getBase());
|
|
} else if (E->isSuperReceiver()) {
|
|
Record.push_back(1);
|
|
Writer.AddTypeRef(E->getSuperReceiverType(), Record);
|
|
} else {
|
|
Record.push_back(2);
|
|
Writer.AddDeclRef(E->getClassReceiver(), Record);
|
|
}
|
|
|
|
Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getRBracket(), Record);
|
|
Writer.AddStmt(E->getBaseExpr());
|
|
Writer.AddStmt(E->getKeyExpr());
|
|
Writer.AddDeclRef(E->getAtIndexMethodDecl(), Record);
|
|
Writer.AddDeclRef(E->setAtIndexMethodDecl(), Record);
|
|
|
|
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:
|
|
Writer.AddStmt(E->getInstanceReceiver());
|
|
break;
|
|
|
|
case ObjCMessageExpr::Class:
|
|
Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
|
|
break;
|
|
|
|
case ObjCMessageExpr::SuperClass:
|
|
case ObjCMessageExpr::SuperInstance:
|
|
Writer.AddTypeRef(E->getSuperType(), Record);
|
|
Writer.AddSourceLocation(E->getSuperLoc(), Record);
|
|
break;
|
|
}
|
|
|
|
if (E->getMethodDecl()) {
|
|
Record.push_back(1);
|
|
Writer.AddDeclRef(E->getMethodDecl(), Record);
|
|
} else {
|
|
Record.push_back(0);
|
|
Writer.AddSelectorRef(E->getSelector(), Record);
|
|
}
|
|
|
|
Writer.AddSourceLocation(E->getLeftLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRightLoc(), Record);
|
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
Arg != ArgEnd; ++Arg)
|
|
Writer.AddStmt(*Arg);
|
|
|
|
SourceLocation *Locs = E->getStoredSelLocs();
|
|
for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
|
|
Writer.AddSourceLocation(Locs[i], Record);
|
|
|
|
Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddStmt(S->getElement());
|
|
Writer.AddStmt(S->getCollection());
|
|
Writer.AddStmt(S->getBody());
|
|
Writer.AddSourceLocation(S->getForLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
|
Code = serialization::STMT_OBJC_FOR_COLLECTION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
|
Writer.AddStmt(S->getCatchBody());
|
|
Writer.AddDeclRef(S->getCatchParamDecl(), Record);
|
|
Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
|
Code = serialization::STMT_OBJC_CATCH;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
|
Writer.AddStmt(S->getFinallyBody());
|
|
Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
|
|
Code = serialization::STMT_OBJC_FINALLY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
|
|
Writer.AddStmt(S->getSubStmt());
|
|
Writer.AddSourceLocation(S->getAtLoc(), Record);
|
|
Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
|
|
Record.push_back(S->getNumCatchStmts());
|
|
Record.push_back(S->getFinallyStmt() != 0);
|
|
Writer.AddStmt(S->getTryBody());
|
|
for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
|
|
Writer.AddStmt(S->getCatchStmt(I));
|
|
if (S->getFinallyStmt())
|
|
Writer.AddStmt(S->getFinallyStmt());
|
|
Writer.AddSourceLocation(S->getAtTryLoc(), Record);
|
|
Code = serialization::STMT_OBJC_AT_TRY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
|
|
Writer.AddStmt(S->getSynchExpr());
|
|
Writer.AddStmt(S->getSynchBody());
|
|
Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
|
|
Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
|
|
Writer.AddStmt(S->getThrowExpr());
|
|
Writer.AddSourceLocation(S->getThrowLoc(), Record);
|
|
Code = serialization::STMT_OBJC_AT_THROW;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Code = serialization::EXPR_OBJC_BOOL_LITERAL;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// C++ Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getCatchLoc(), Record);
|
|
Writer.AddDeclRef(S->getExceptionDecl(), Record);
|
|
Writer.AddStmt(S->getHandlerBlock());
|
|
Code = serialization::STMT_CXX_CATCH;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getNumHandlers());
|
|
Writer.AddSourceLocation(S->getTryLoc(), Record);
|
|
Writer.AddStmt(S->getTryBlock());
|
|
for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
|
|
Writer.AddStmt(S->getHandler(i));
|
|
Code = serialization::STMT_CXX_TRY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getForLoc(), Record);
|
|
Writer.AddSourceLocation(S->getColonLoc(), Record);
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
|
Writer.AddStmt(S->getRangeStmt());
|
|
Writer.AddStmt(S->getBeginEndStmt());
|
|
Writer.AddStmt(S->getCond());
|
|
Writer.AddStmt(S->getInc());
|
|
Writer.AddStmt(S->getLoopVarStmt());
|
|
Writer.AddStmt(S->getBody());
|
|
Code = serialization::STMT_CXX_FOR_RANGE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getKeywordLoc(), Record);
|
|
Record.push_back(S->isIfExists());
|
|
Writer.AddNestedNameSpecifierLoc(S->getQualifierLoc(), Record);
|
|
Writer.AddDeclarationNameInfo(S->getNameInfo(), Record);
|
|
Writer.AddStmt(S->getSubStmt());
|
|
Code = serialization::STMT_MS_DEPENDENT_EXISTS;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
|
|
VisitCallExpr(E);
|
|
Record.push_back(E->getOperator());
|
|
Code = serialization::EXPR_CXX_OPERATOR_CALL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
|
VisitCallExpr(E);
|
|
Code = serialization::EXPR_CXX_MEMBER_CALL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumArgs());
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
Writer.AddStmt(E->getArg(I));
|
|
Writer.AddDeclRef(E->getConstructor(), Record);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Record.push_back(E->isElidable());
|
|
Record.push_back(E->hadMultipleCandidates());
|
|
Record.push_back(E->requiresZeroInitialization());
|
|
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
|
|
Writer.AddSourceRange(E->getParenRange(), Record);
|
|
Code = serialization::EXPR_CXX_CONSTRUCT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
|
|
VisitCXXConstructExpr(E);
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
|
Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->NumCaptures);
|
|
unsigned NumArrayIndexVars = 0;
|
|
if (E->HasArrayIndexVars)
|
|
NumArrayIndexVars = E->getArrayIndexStarts()[E->NumCaptures];
|
|
Record.push_back(NumArrayIndexVars);
|
|
Writer.AddSourceRange(E->IntroducerRange, Record);
|
|
Record.push_back(E->CaptureDefault); // FIXME: stable encoding
|
|
Record.push_back(E->ExplicitParams);
|
|
Record.push_back(E->ExplicitResultType);
|
|
Writer.AddSourceLocation(E->ClosingBrace, Record);
|
|
|
|
// Add capture initializers.
|
|
for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
|
|
CEnd = E->capture_init_end();
|
|
C != CEnd; ++C) {
|
|
Writer.AddStmt(*C);
|
|
}
|
|
|
|
// Add array index variables, if any.
|
|
if (NumArrayIndexVars) {
|
|
Record.append(E->getArrayIndexStarts(),
|
|
E->getArrayIndexStarts() + E->NumCaptures + 1);
|
|
VarDecl **ArrayIndexVars = E->getArrayIndexVars();
|
|
for (unsigned I = 0; I != NumArrayIndexVars; ++I)
|
|
Writer.AddDeclRef(ArrayIndexVars[I], Record);
|
|
}
|
|
|
|
Code = serialization::EXPR_LAMBDA;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
|
|
Record);
|
|
}
|
|
|
|
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::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
|
VisitExplicitCastExpr(E);
|
|
Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
|
|
VisitCallExpr(E);
|
|
Writer.AddSourceLocation(E->UDSuffixLoc, Record);
|
|
Code = serialization::EXPR_USER_DEFINED_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Code = serialization::EXPR_CXX_BOOL_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
if (E->isTypeOperand()) {
|
|
Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
|
|
Code = serialization::EXPR_CXX_TYPEID_TYPE;
|
|
} else {
|
|
Writer.AddStmt(E->getExprOperand());
|
|
Code = serialization::EXPR_CXX_TYPEID_EXPR;
|
|
}
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Record.push_back(E->isImplicit());
|
|
Code = serialization::EXPR_CXX_THIS;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getThrowLoc(), Record);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Record.push_back(E->isThrownVariableInScope());
|
|
Code = serialization::EXPR_CXX_THROW;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
bool HasOtherExprStored = E->Param.getInt();
|
|
// Store these first, the reader reads them before creation.
|
|
Record.push_back(HasOtherExprStored);
|
|
if (HasOtherExprStored)
|
|
Writer.AddStmt(E->getExpr());
|
|
Writer.AddDeclRef(E->getParam(), Record);
|
|
Writer.AddSourceLocation(E->getUsedLocation(), Record);
|
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_ARG;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddCXXTemporary(E->getTemporary(), Record);
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_CXX_BIND_TEMPORARY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->isGlobalNew());
|
|
Record.push_back(E->isArray());
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
|
Record.push_back(E->getNumPlacementArgs());
|
|
Record.push_back(E->StoredInitializationStyle);
|
|
Writer.AddDeclRef(E->getOperatorNew(), Record);
|
|
Writer.AddDeclRef(E->getOperatorDelete(), Record);
|
|
Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
|
|
Writer.AddSourceRange(E->getTypeIdParens(), Record);
|
|
Writer.AddSourceLocation(E->getStartLoc(), Record);
|
|
Writer.AddSourceRange(E->getDirectInitRange(), Record);
|
|
for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
|
|
I != e; ++I)
|
|
Writer.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());
|
|
Writer.AddDeclRef(E->getOperatorDelete(), Record);
|
|
Writer.AddStmt(E->getArgument());
|
|
Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
|
|
|
|
Code = serialization::EXPR_CXX_DELETE;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
Writer.AddStmt(E->getBase());
|
|
Record.push_back(E->isArrow());
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
Writer.AddTypeSourceInfo(E->getScopeTypeInfo(), Record);
|
|
Writer.AddSourceLocation(E->getColonColonLoc(), Record);
|
|
Writer.AddSourceLocation(E->getTildeLoc(), Record);
|
|
|
|
// PseudoDestructorTypeStorage.
|
|
Writer.AddIdentifierRef(E->getDestroyedTypeIdentifier(), Record);
|
|
if (E->getDestroyedTypeIdentifier())
|
|
Writer.AddSourceLocation(E->getDestroyedTypeLoc(), Record);
|
|
else
|
|
Writer.AddTypeSourceInfo(E->getDestroyedTypeInfo(), Record);
|
|
|
|
Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getNumObjects());
|
|
for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
|
|
Writer.AddDeclRef(E->getObject(i), Record);
|
|
|
|
Writer.AddStmt(E->getSubExpr());
|
|
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
|
}
|
|
|
|
void
|
|
ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
|
|
VisitExpr(E);
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
|
// emitted first.
|
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
|
|
Record.push_back(Args.NumTemplateArgs);
|
|
AddTemplateKWAndArgsInfo(Args);
|
|
}
|
|
|
|
if (!E->isImplicitAccess())
|
|
Writer.AddStmt(E->getBase());
|
|
else
|
|
Writer.AddStmt(0);
|
|
Writer.AddTypeRef(E->getBaseType(), Record);
|
|
Record.push_back(E->isArrow());
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
|
|
Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
|
|
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->HasTemplateKWAndArgsInfo);
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
|
|
Record.push_back(Args.NumTemplateArgs);
|
|
AddTemplateKWAndArgsInfo(Args);
|
|
}
|
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
Writer.AddDeclarationNameInfo(E->NameInfo, Record);
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
|
|
}
|
|
|
|
void
|
|
ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->arg_size());
|
|
for (CXXUnresolvedConstructExpr::arg_iterator
|
|
ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
|
|
Writer.AddStmt(*ArgI);
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
|
|
VisitExpr(E);
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
|
// emitted first.
|
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
|
|
Record.push_back(Args.NumTemplateArgs);
|
|
AddTemplateKWAndArgsInfo(Args);
|
|
}
|
|
|
|
Record.push_back(E->getNumDecls());
|
|
for (OverloadExpr::decls_iterator
|
|
OvI = E->decls_begin(), OvE = E->decls_end(); OvI != OvE; ++OvI) {
|
|
Writer.AddDeclRef(OvI.getDecl(), Record);
|
|
Record.push_back(OvI.getAccess());
|
|
}
|
|
|
|
Writer.AddDeclarationNameInfo(E->NameInfo, Record);
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
|
|
VisitOverloadExpr(E);
|
|
Record.push_back(E->isArrow());
|
|
Record.push_back(E->hasUnresolvedUsing());
|
|
Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : 0);
|
|
Writer.AddTypeRef(E->getBaseType(), Record);
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
|
|
VisitOverloadExpr(E);
|
|
Record.push_back(E->requiresADL());
|
|
if (E->requiresADL())
|
|
Record.push_back(E->isStdAssociatedNamespace());
|
|
Record.push_back(E->isOverloaded());
|
|
Writer.AddDeclRef(E->getNamingClass(), Record);
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getTrait());
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
|
|
Code = serialization::EXPR_CXX_UNARY_TYPE_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getTrait());
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
Writer.AddTypeSourceInfo(E->getLhsTypeSourceInfo(), Record);
|
|
Writer.AddTypeSourceInfo(E->getRhsTypeSourceInfo(), Record);
|
|
Code = serialization::EXPR_BINARY_TYPE_TRAIT;
|
|
}
|
|
|
|
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);
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
Writer.AddTypeSourceInfo(E->getArg(I), Record);
|
|
Code = serialization::EXPR_TYPE_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getTrait());
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
|
|
Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getTrait());
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
Writer.AddStmt(E->getQueriedExpression());
|
|
Code = serialization::EXPR_CXX_EXPRESSION_TRAIT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
|
|
VisitExpr(E);
|
|
Record.push_back(E->getValue());
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
Writer.AddStmt(E->getOperand());
|
|
Code = serialization::EXPR_CXX_NOEXCEPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getEllipsisLoc(), Record);
|
|
Record.push_back(E->NumExpansions);
|
|
Writer.AddStmt(E->getPattern());
|
|
Code = serialization::EXPR_PACK_EXPANSION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->OperatorLoc, Record);
|
|
Writer.AddSourceLocation(E->PackLoc, Record);
|
|
Writer.AddSourceLocation(E->RParenLoc, Record);
|
|
Record.push_back(E->Length);
|
|
Writer.AddDeclRef(E->Pack, Record);
|
|
Code = serialization::EXPR_SIZEOF_PACK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmExpr(
|
|
SubstNonTypeTemplateParmExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddDeclRef(E->getParameter(), Record);
|
|
Writer.AddSourceLocation(E->getNameLoc(), Record);
|
|
Writer.AddStmt(E->getReplacement());
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddDeclRef(E->getParameterPack(), Record);
|
|
Writer.AddTemplateArgument(E->getArgumentPack(), Record);
|
|
Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->Temporary);
|
|
Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddStmt(E->getSourceExpr());
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
Code = serialization::EXPR_OPAQUE_VALUE;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// CUDA Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
|
VisitCallExpr(E);
|
|
Writer.AddStmt(E->getConfig());
|
|
Code = serialization::EXPR_CUDA_KERNEL_CALL;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// OpenCL Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
Writer.AddStmt(E->getSrcExpr());
|
|
Code = serialization::EXPR_ASTYPE;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Microsoft Expressions and Statements.
|
|
//===----------------------------------------------------------------------===//
|
|
void ASTStmtWriter::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
|
VisitExpr(E);
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
if (E->isTypeOperand()) {
|
|
Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
|
|
Code = serialization::EXPR_CXX_UUIDOF_TYPE;
|
|
} else {
|
|
Writer.AddStmt(E->getExprOperand());
|
|
Code = serialization::EXPR_CXX_UUIDOF_EXPR;
|
|
}
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHExceptStmt(SEHExceptStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getExceptLoc(), Record);
|
|
Writer.AddStmt(S->getFilterExpr());
|
|
Writer.AddStmt(S->getBlock());
|
|
Code = serialization::STMT_SEH_EXCEPT;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
|
|
VisitStmt(S);
|
|
Writer.AddSourceLocation(S->getFinallyLoc(), Record);
|
|
Writer.AddStmt(S->getBlock());
|
|
Code = serialization::STMT_SEH_FINALLY;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitSEHTryStmt(SEHTryStmt *S) {
|
|
VisitStmt(S);
|
|
Record.push_back(S->getIsCXXTry());
|
|
Writer.AddSourceLocation(S->getTryLoc(), Record);
|
|
Writer.AddStmt(S->getTryBlock());
|
|
Writer.AddStmt(S->getHandler());
|
|
Code = serialization::STMT_SEH_TRY;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// 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();
|
|
}
|
|
|
|
/// \brief Write the given substatement or subexpression to the
|
|
/// bitstream.
|
|
void ASTWriter::WriteSubStmt(Stmt *S,
|
|
llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
|
|
llvm::DenseSet<Stmt *> &ParentStmts) {
|
|
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
|
|
|
|
// Redirect ASTWriter::AddStmt to collect sub stmts.
|
|
SmallVector<Stmt *, 16> SubStmts;
|
|
CollectedStmts = &SubStmts;
|
|
|
|
Writer.Code = serialization::STMT_NULL_PTR;
|
|
Writer.AbbrevToUse = 0;
|
|
Writer.Visit(S);
|
|
|
|
#ifndef NDEBUG
|
|
if (Writer.Code == serialization::STMT_NULL_PTR) {
|
|
SourceManager &SrcMgr
|
|
= DeclIDs.begin()->first->getASTContext().getSourceManager();
|
|
S->dump(SrcMgr);
|
|
llvm_unreachable("Unhandled sub statement writing AST file");
|
|
}
|
|
#endif
|
|
|
|
// Revert ASTWriter::AddStmt.
|
|
CollectedStmts = &StmtsToEmit;
|
|
|
|
// Write the sub stmts in reverse order, last to first. When reading them back
|
|
// we will read them in correct order by "pop"ing them from the Stmts stack.
|
|
// This simplifies reading and allows to store a variable number of sub stmts
|
|
// without knowing it in advance.
|
|
while (!SubStmts.empty())
|
|
WriteSubStmt(SubStmts.pop_back_val(), SubStmtEntries, ParentStmts);
|
|
|
|
Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
|
|
|
|
SubStmtEntries[S] = Stream.GetCurrentBitNo();
|
|
}
|
|
|
|
/// \brief Flush all of the statements that have been added to the
|
|
/// queue via AddStmt().
|
|
void ASTWriter::FlushStmts() {
|
|
RecordData Record;
|
|
|
|
// We expect to be the only consumer of the two temporary statement maps,
|
|
// assert that they are empty.
|
|
assert(SubStmtEntries.empty() && "unexpected entries in sub stmt map");
|
|
assert(ParentStmts.empty() && "unexpected entries in parent stmt map");
|
|
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
|
WriteSubStmt(StmtsToEmit[I], SubStmtEntries, ParentStmts);
|
|
|
|
assert(N == StmtsToEmit.size() &&
|
|
"Substatement written via AddStmt rather than WriteSubStmt!");
|
|
|
|
// Note that we are at the end of a full expression. Any
|
|
// expression records that follow this one are part of a different
|
|
// expression.
|
|
Stream.EmitRecord(serialization::STMT_STOP, Record);
|
|
|
|
SubStmtEntries.clear();
|
|
ParentStmts.clear();
|
|
}
|
|
|
|
StmtsToEmit.clear();
|
|
}
|