2010-08-19 07:56:31 +08:00
|
|
|
//===--- ASTWriterStmt.cpp - Statement and Expression Serialization -------===//
|
2009-04-27 14:20:01 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-08-10 07:08:25 +08:00
|
|
|
///
|
|
|
|
/// \file
|
|
|
|
/// \brief Implements serialization for Statements and Expressions.
|
|
|
|
///
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:37 +08:00
|
|
|
#include "clang/Serialization/ASTWriter.h"
|
2012-07-05 04:19:54 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2009-09-10 07:08:42 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2009-04-27 14:20:01 +08:00
|
|
|
#include "clang/AST/DeclObjC.h"
|
2011-01-15 09:15:58 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2009-04-27 14:20:01 +08:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2013-05-03 08:10:13 +08:00
|
|
|
#include "clang/Lex/Token.h"
|
2009-04-27 14:20:01 +08:00
|
|
|
#include "llvm/Bitcode/BitstreamWriter.h"
|
|
|
|
using namespace clang;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Statement/expression serialization
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-06-30 16:49:18 +08:00
|
|
|
namespace clang {
|
2013-07-19 11:13:43 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
class ASTStmtWriter : public StmtVisitor<ASTStmtWriter, void> {
|
2013-07-19 11:13:43 +08:00
|
|
|
friend class OMPClauseWriter;
|
2010-08-19 07:56:21 +08:00
|
|
|
ASTWriter &Writer;
|
|
|
|
ASTWriter::RecordData &Record;
|
2009-04-27 14:20:01 +08:00
|
|
|
|
|
|
|
public:
|
2010-08-19 07:57:32 +08:00
|
|
|
serialization::StmtCode Code;
|
2011-06-03 10:27:19 +08:00
|
|
|
unsigned AbbrevToUse;
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter(ASTWriter &Writer, ASTWriter::RecordData &Record)
|
2009-04-27 14:20:01 +08:00
|
|
|
: Writer(Writer), Record(Record) { }
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
void AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args);
|
2009-04-27 14:20:01 +08:00
|
|
|
|
|
|
|
void VisitStmt(Stmt *S);
|
2011-07-15 15:00:14 +08:00
|
|
|
#define STMT(Type, Base) \
|
|
|
|
void Visit##Type(Type *);
|
|
|
|
#include "clang/AST/StmtNodes.inc"
|
2009-04-27 14:20:01 +08:00
|
|
|
};
|
2015-06-22 17:47:44 +08:00
|
|
|
} // namespace clang
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::
|
2012-01-27 17:46:47 +08:00
|
|
|
AddTemplateKWAndArgsInfo(const ASTTemplateKWAndArgsInfo &Args) {
|
|
|
|
Writer.AddSourceLocation(Args.getTemplateKeywordLoc(), Record);
|
2010-06-28 17:31:48 +08:00
|
|
|
Writer.AddSourceLocation(Args.LAngleLoc, Record);
|
|
|
|
Writer.AddSourceLocation(Args.RAngleLoc, Record);
|
|
|
|
for (unsigned i=0; i != Args.NumTemplateArgs; ++i)
|
|
|
|
Writer.AddTemplateArgumentLoc(Args.getTemplateArgs()[i], Record);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitStmt(Stmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getSemiLoc(), Record);
|
2011-09-02 05:53:45 +08:00
|
|
|
Record.push_back(S->HasLeadingEmptyMacro);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_NULL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCompoundStmt(CompoundStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->size());
|
2014-03-17 22:19:37 +08:00
|
|
|
for (auto *CS : S->body())
|
|
|
|
Writer.AddStmt(CS);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getLBracLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getRBracLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_COMPOUND;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitSwitchCase(SwitchCase *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Record.push_back(Writer.getSwitchCaseID(S));
|
2013-01-05 02:30:04 +08:00
|
|
|
Writer.AddSourceLocation(S->getKeywordLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getColonLoc(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitSwitchCase(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getLHS());
|
|
|
|
Writer.AddStmt(S->getRHS());
|
|
|
|
Writer.AddStmt(S->getSubStmt());
|
2009-05-16 07:57:33 +08:00
|
|
|
Writer.AddSourceLocation(S->getEllipsisLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CASE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDefaultStmt(DefaultStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitSwitchCase(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getSubStmt());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_DEFAULT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitLabelStmt(LabelStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2011-02-17 15:39:24 +08:00
|
|
|
Writer.AddDeclRef(S->getDecl(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getSubStmt());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getIdentLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_LABEL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-04-14 08:33:13 +08:00
|
|
|
void ASTStmtWriter::VisitAttributedStmt(AttributedStmt *S) {
|
|
|
|
VisitStmt(S);
|
2012-07-09 18:04:07 +08:00
|
|
|
Record.push_back(S->getAttrs().size());
|
2012-04-14 08:33:13 +08:00
|
|
|
Writer.WriteAttributes(S->getAttrs(), Record);
|
|
|
|
Writer.AddStmt(S->getSubStmt());
|
|
|
|
Writer.AddSourceLocation(S->getAttrLoc(), Record);
|
|
|
|
Code = serialization::STMT_ATTRIBUTED;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2009-11-24 07:44:04 +08:00
|
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getCond());
|
|
|
|
Writer.AddStmt(S->getThen());
|
|
|
|
Writer.AddStmt(S->getElse());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getIfLoc(), Record);
|
2009-05-16 02:53:42 +08:00
|
|
|
Writer.AddSourceLocation(S->getElseLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_IF;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2009-11-25 01:07:59 +08:00
|
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getCond());
|
|
|
|
Writer.AddStmt(S->getBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getSwitchLoc(), Record);
|
2010-09-09 08:05:53 +08:00
|
|
|
Record.push_back(S->isAllEnumCasesCovered());
|
2009-09-09 23:08:12 +08:00
|
|
|
for (SwitchCase *SC = S->getSwitchCaseList(); SC;
|
2009-04-27 14:20:01 +08:00
|
|
|
SC = SC->getNextSwitchCase())
|
2010-06-29 06:28:35 +08:00
|
|
|
Record.push_back(Writer.RecordSwitchCaseID(SC));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_SWITCH;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2009-11-25 05:15:44 +08:00
|
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getCond());
|
|
|
|
Writer.AddStmt(S->getBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getWhileLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_WHILE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDoStmt(DoStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getCond());
|
|
|
|
Writer.AddStmt(S->getBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getDoLoc(), Record);
|
2009-05-16 05:56:04 +08:00
|
|
|
Writer.AddSourceLocation(S->getWhileLoc(), Record);
|
2009-06-13 07:04:47 +08:00
|
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_DO;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitForStmt(ForStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getInit());
|
|
|
|
Writer.AddStmt(S->getCond());
|
2009-11-25 08:27:52 +08:00
|
|
|
Writer.AddDeclRef(S->getConditionVariable(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getInc());
|
|
|
|
Writer.AddStmt(S->getBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getForLoc(), Record);
|
2009-05-16 06:12:32 +08:00
|
|
|
Writer.AddSourceLocation(S->getLParenLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_FOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitGotoStmt(GotoStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2011-02-17 15:39:24 +08:00
|
|
|
Writer.AddDeclRef(S->getLabel(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getGotoLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getLabelLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_GOTO;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getGotoLoc(), Record);
|
2009-05-16 08:20:29 +08:00
|
|
|
Writer.AddSourceLocation(S->getStarLoc(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getTarget());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_INDIRECT_GOTO;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitContinueStmt(ContinueStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getContinueLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CONTINUE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitBreakStmt(BreakStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getBreakLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_BREAK;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getRetValue());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getReturnLoc(), Record);
|
2010-05-15 14:01:05 +08:00
|
|
|
Writer.AddDeclRef(S->getNRVOCandidate(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_RETURN;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDeclStmt(DeclStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
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);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_DECL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2013-05-03 08:10:13 +08:00
|
|
|
void ASTStmtWriter::VisitAsmStmt(AsmStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Record.push_back(S->getNumOutputs());
|
|
|
|
Record.push_back(S->getNumInputs());
|
|
|
|
Record.push_back(S->getNumClobbers());
|
|
|
|
Writer.AddSourceLocation(S->getAsmLoc(), Record);
|
|
|
|
Record.push_back(S->isVolatile());
|
|
|
|
Record.push_back(S->isSimple());
|
2013-05-03 08:10:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitGCCAsmStmt(GCCAsmStmt *S) {
|
|
|
|
VisitAsmStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getAsmString());
|
2009-04-27 14:20:01 +08:00
|
|
|
|
|
|
|
// Outputs
|
2010-01-31 06:25:16 +08:00
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
|
|
Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getOutputConstraintLiteral(I));
|
|
|
|
Writer.AddStmt(S->getOutputExpr(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
2010-01-31 06:25:16 +08:00
|
|
|
Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getInputConstraintLiteral(I));
|
|
|
|
Writer.AddStmt(S->getInputExpr(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Clobbers
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I)
|
2012-08-28 07:28:41 +08:00
|
|
|
Writer.AddStmt(S->getClobberStringLiteral(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
|
2012-08-25 08:11:56 +08:00
|
|
|
Code = serialization::STMT_GCCASM;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-06-12 04:47:18 +08:00
|
|
|
void ASTStmtWriter::VisitMSAsmStmt(MSAsmStmt *S) {
|
2013-05-03 08:10:13 +08:00
|
|
|
VisitAsmStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getLBraceLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getEndLoc(), Record);
|
|
|
|
Record.push_back(S->getNumAsmToks());
|
|
|
|
Writer.AddString(S->getAsmString(), Record);
|
|
|
|
|
|
|
|
// Tokens
|
|
|
|
for (unsigned I = 0, N = S->getNumAsmToks(); I != N; ++I) {
|
|
|
|
Writer.AddToken(S->getAsmToks()[I], Record);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clobbers
|
|
|
|
for (unsigned I = 0, N = S->getNumClobbers(); I != N; ++I) {
|
|
|
|
Writer.AddString(S->getClobber(I), Record);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Outputs
|
|
|
|
for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
|
|
|
|
Writer.AddStmt(S->getOutputExpr(I));
|
|
|
|
Writer.AddString(S->getOutputConstraint(I), Record);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inputs
|
|
|
|
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
|
|
|
|
Writer.AddStmt(S->getInputExpr(I));
|
|
|
|
Writer.AddString(S->getInputConstraint(I), Record);
|
|
|
|
}
|
2012-08-25 07:51:02 +08:00
|
|
|
|
|
|
|
Code = serialization::STMT_MSASM;
|
2012-06-12 04:47:18 +08:00
|
|
|
}
|
|
|
|
|
2013-04-17 02:53:08 +08:00
|
|
|
void ASTStmtWriter::VisitCapturedStmt(CapturedStmt *S) {
|
|
|
|
VisitStmt(S);
|
2013-05-04 03:20:19 +08:00
|
|
|
// NumCaptures
|
|
|
|
Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
|
|
|
|
|
2013-05-04 11:59:06 +08:00
|
|
|
// CapturedDecl and captured region kind
|
2013-05-04 03:20:19 +08:00
|
|
|
Writer.AddDeclRef(S->getCapturedDecl(), Record);
|
2013-05-04 11:59:06 +08:00
|
|
|
Record.push_back(S->getCapturedRegionKind());
|
|
|
|
|
2013-05-04 03:20:19 +08:00
|
|
|
Writer.AddDeclRef(S->getCapturedRecordDecl(), Record);
|
|
|
|
|
|
|
|
// Capture inits
|
2014-03-15 03:41:04 +08:00
|
|
|
for (auto *I : S->capture_inits())
|
|
|
|
Writer.AddStmt(I);
|
2013-05-04 03:20:19 +08:00
|
|
|
|
|
|
|
// Body
|
|
|
|
Writer.AddStmt(S->getCapturedStmt());
|
|
|
|
|
|
|
|
// Captures
|
2014-03-15 02:08:33 +08:00
|
|
|
for (const auto &I : S->captures()) {
|
2014-10-29 20:21:55 +08:00
|
|
|
if (I.capturesThis() || I.capturesVariableArrayType())
|
2014-05-22 13:54:18 +08:00
|
|
|
Writer.AddDeclRef(nullptr, Record);
|
2013-05-04 03:20:19 +08:00
|
|
|
else
|
2014-03-15 02:08:33 +08:00
|
|
|
Writer.AddDeclRef(I.getCapturedVar(), Record);
|
|
|
|
Record.push_back(I.getCaptureKind());
|
|
|
|
Writer.AddSourceLocation(I.getLocation(), Record);
|
2013-05-04 03:20:19 +08:00
|
|
|
}
|
2013-04-17 02:53:08 +08:00
|
|
|
|
2013-05-04 03:20:19 +08:00
|
|
|
Code = serialization::STMT_CAPTURED;
|
2013-04-17 02:53:08 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitExpr(Expr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(E);
|
|
|
|
Writer.AddTypeRef(E->getType(), Record);
|
|
|
|
Record.push_back(E->isTypeDependent());
|
|
|
|
Record.push_back(E->isValueDependent());
|
2011-07-01 09:22:09 +08:00
|
|
|
Record.push_back(E->isInstantiationDependent());
|
Variadic templates: extend Type, NestedNameSpecifier, TemplateName,
and TemplateArgument with an operation that determines whether there
are any unexpanded parameter packs within that construct. Use this
information to diagnose the appearance of the names of parameter packs
that have not been expanded (C++ [temp.variadic]p5). Since this
property is checked often (every declaration, ever expression
statement, etc.), we extend Type and Expr with a bit storing the
result of this computation, rather than walking the AST each time to
determine whether any unexpanded parameter packs occur.
This commit is deficient in several ways, which will be remedied with
future commits:
- Expr has a bit to store the presence of an unexpanded parameter
pack, but it is never set.
- The error messages don't point out where the unexpanded parameter
packs were named in the type/expression, but they should.
- We don't check for unexpanded parameter packs in all of the places
where we should.
- Testing is sparse, pending the resolution of the above three
issues.
llvm-svn: 121724
2010-12-14 06:49:22 +08:00
|
|
|
Record.push_back(E->containsUnexpandedParameterPack());
|
2010-11-18 14:31:45 +08:00
|
|
|
Record.push_back(E->getValueKind());
|
|
|
|
Record.push_back(E->getObjectKind());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
|
|
Record.push_back(E->getIdentType()); // FIXME: stable encoding
|
2014-10-09 16:45:04 +08:00
|
|
|
Writer.AddStmt(E->getFunctionName());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_PREDEFINED;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-07-08 21:09:47 +08:00
|
|
|
|
|
|
|
Record.push_back(E->hasQualifier());
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
Record.push_back(E->getDecl() != E->getFoundDecl());
|
2012-01-27 17:46:47 +08:00
|
|
|
Record.push_back(E->hasTemplateKWAndArgsInfo());
|
2011-10-05 15:56:41 +08:00
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
2015-01-12 18:17:46 +08:00
|
|
|
Record.push_back(E->refersToEnclosingVariableOrCapture());
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo()) {
|
2011-02-04 20:01:24 +08:00
|
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
|
|
Record.push_back(NumTemplateArgs);
|
|
|
|
}
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2011-06-03 10:27:19 +08:00
|
|
|
DeclarationName::NameKind nk = (E->getDecl()->getDeclName().getNameKind());
|
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if ((!E->hasTemplateKWAndArgsInfo()) && (!E->hasQualifier()) &&
|
2011-06-03 10:27:19 +08:00
|
|
|
(E->getDecl() == E->getFoundDecl()) &&
|
|
|
|
nk == DeclarationName::Identifier) {
|
|
|
|
AbbrevToUse = Writer.getDeclRefExprAbbrev();
|
|
|
|
}
|
|
|
|
|
2011-03-07 02:19:42 +08:00
|
|
|
if (E->hasQualifier())
|
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
|
|
|
Add an optional field attached to a DeclRefExpr which points back to the
Decl actually found via name lookup & overload resolution when that Decl
is different from the ValueDecl which is actually referenced by the
expression.
This can be used by AST consumers to correctly attribute references to
the spelling location of a using declaration, and otherwise gain insight
into the name resolution performed by Clang.
The public interface to DRE is kept as narrow as possible: we provide
a getFoundDecl() which always returns a NamedDecl, either the ValueDecl
referenced or the new, more precise NamedDecl if present. This way AST
clients can code against getFoundDecl without know when exactly the AST
has a split representation.
For an example of the data this provides consider:
% cat x.cc
namespace N1 {
struct S {};
void f(const S&);
}
void test(N1::S s) {
f(s);
using N1::f;
f(s);
}
% ./bin/clang -fsyntax-only -Xclang -ast-dump x.cc
[...]
void test(N1::S s) (CompoundStmt 0x5b02010 <x.cc:5:20, line:9:1>
(CallExpr 0x5b01df0 <line:6:3, col:6> 'void'
(ImplicitCastExpr 0x5b01dd8 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01d80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)'))
(ImplicitCastExpr 0x5b01e20 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01d58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S')))
(DeclStmt 0x5b01ee0 <line:7:3, col:14>
0x5b01e40 "UsingN1::;")
(CallExpr 0x5b01fc8 <line:8:3, col:6> 'void'
(ImplicitCastExpr 0x5b01fb0 <col:3> 'void (*)(const struct N1::S &)' <FunctionToPointerDecay>
(DeclRefExpr 0x5b01f80 <col:3> 'void (const struct N1::S &)' lvalue Function 0x5b01a20 'f' 'void (const struct N1::S &)' (UsingShadow 0x5b01ea0 'f')))
(ImplicitCastExpr 0x5b01ff8 <col:5> 'const struct N1::S' lvalue <NoOp>
(DeclRefExpr 0x5b01f58 <col:5> 'N1::S':'struct N1::S' lvalue ParmVar 0x5b01b60 's' 'N1::S':'struct N1::S'))))
Now we can tell that the second call is 'using' (no pun intended) the using
declaration, and *which* using declaration it sees. Without this, we can
mistake calls that go through using declarations for ADL calls, and have no way
to attribute names looked up with using declarations to the appropriate
UsingDecl.
llvm-svn: 130670
2011-05-02 07:48:14 +08:00
|
|
|
if (E->getDecl() != E->getFoundDecl())
|
|
|
|
Writer.AddDeclRef(E->getFoundDecl(), Record);
|
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
|
|
|
AddTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo());
|
2011-03-07 02:19:42 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddDeclRef(E->getDecl(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2010-10-16 02:21:24 +08:00
|
|
|
Writer.AddDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_DECL_REF;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitIntegerLiteral(IntegerLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
|
|
Writer.AddAPInt(E->getValue(), Record);
|
2011-06-03 10:27:19 +08:00
|
|
|
|
|
|
|
if (E->getValue().getBitWidth() == 32) {
|
|
|
|
AbbrevToUse = Writer.getIntegerLiteralAbbrev();
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_INTEGER_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2013-01-22 17:46:51 +08:00
|
|
|
Record.push_back(E->getRawSemantics());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isExact());
|
2013-01-22 17:46:51 +08:00
|
|
|
Writer.AddAPFloat(E->getValue(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_FLOATING_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_IMAGINARY_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitStringLiteral(StringLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getByteLength());
|
|
|
|
Record.push_back(E->getNumConcatenated());
|
2011-07-27 13:40:30 +08:00
|
|
|
Record.push_back(E->getKind());
|
2011-04-14 08:40:03 +08:00
|
|
|
Record.push_back(E->isPascal());
|
2009-04-27 14:20:01 +08:00
|
|
|
// 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
|
2010-08-19 07:56:27 +08:00
|
|
|
// the AST file during deserialization.
|
2011-11-01 10:23:42 +08:00
|
|
|
Record.append(E->getBytes().begin(), E->getBytes().end());
|
2009-04-27 14:20:01 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
|
|
|
Writer.AddSourceLocation(E->getStrTokenLoc(I), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_STRING_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCharacterLiteral(CharacterLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
2009-08-25 01:39:36 +08:00
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2011-07-27 13:40:30 +08:00
|
|
|
Record.push_back(E->getKind());
|
2011-06-03 10:27:19 +08:00
|
|
|
|
|
|
|
AbbrevToUse = Writer.getCharacterLiteralAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CHARACTER_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitParenExpr(ParenExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLParen(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParen(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_PAREN;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitParenListExpr(ParenListExpr *E) {
|
2010-06-30 16:49:18 +08:00
|
|
|
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);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_PAREN_LIST;
|
2010-06-30 16:49:18 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_UNARY_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
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
|
2011-03-12 17:45:03 +08:00
|
|
|
Writer.AddSourceLocation(ON.getSourceRange().getBegin(), Record);
|
|
|
|
Writer.AddSourceLocation(ON.getSourceRange().getEnd(), Record);
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
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;
|
2010-04-29 08:18:15 +08:00
|
|
|
|
|
|
|
case OffsetOfExpr::OffsetOfNode::Base:
|
2010-07-30 02:16:10 +08:00
|
|
|
Writer.AddCXXBaseSpecifier(*ON.getBase(), Record);
|
2010-04-29 08:18:15 +08:00
|
|
|
break;
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getIndexExpr(I));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OFFSETOF;
|
Completely reimplement __builtin_offsetof, based on a patch by Roberto
Amadini.
This change introduces a new expression node type, OffsetOfExpr, that
describes __builtin_offsetof. Previously, __builtin_offsetof was
implemented using a unary operator whose subexpression involved
various synthesized array-subscript and member-reference expressions,
which was ugly and made it very hard to instantiate as a
template. OffsetOfExpr represents the AST more faithfully, with proper
type source information and a more compact representation.
OffsetOfExpr also has support for dependent __builtin_offsetof
expressions; it can be value-dependent, but will never be
type-dependent (like sizeof or alignof). This commit introduces
template instantiation for __builtin_offsetof as well.
There are two major caveats to this patch:
1) CodeGen cannot handle the case where __builtin_offsetof is not a
constant expression, so it produces an error. So, to avoid
regressing in C, we retain the old UnaryOperator-based
__builtin_offsetof implementation in C while using the shiny new
OffsetOfExpr implementation in C++. The old implementation can go
away once we have proper CodeGen support for this case, which we
expect won't cause much trouble in C++.
2) __builtin_offsetof doesn't work well with non-POD class types,
particularly when the designated field is found within a base
class. I will address this in a subsequent patch.
Fixes PR5880 and a bunch of assertions when building Boost.Python
tests.
llvm-svn: 102542
2010-04-29 06:16:22 +08:00
|
|
|
}
|
|
|
|
|
2011-03-12 03:24:49 +08:00
|
|
|
void ASTStmtWriter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2011-03-12 03:24:49 +08:00
|
|
|
Record.push_back(E->getKind());
|
2009-04-27 14:20:01 +08:00
|
|
|
if (E->isArgumentType())
|
2009-12-07 10:54:59 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getArgumentTypeInfo(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
else {
|
|
|
|
Record.push_back(0);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getArgumentExpr());
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_SIZEOF_ALIGN_OF;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getLHS());
|
|
|
|
Writer.AddStmt(E->getRHS());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getRBracketLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_ARRAY_SUBSCRIPT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCallExpr(CallExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumArgs());
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getCallee());
|
2009-04-27 14:20:01 +08:00
|
|
|
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
|
|
|
|
Arg != ArgEnd; ++Arg)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(*Arg);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CALL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
|
2010-07-08 21:09:47 +08:00
|
|
|
// Don't call VisitExpr, we'll write everything here.
|
|
|
|
|
|
|
|
Record.push_back(E->hasQualifier());
|
2011-03-01 05:54:11 +08:00
|
|
|
if (E->hasQualifier())
|
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
|
|
Writer.AddSourceLocation(E->getTemplateKeywordLoc(), Record);
|
2011-02-04 20:01:24 +08:00
|
|
|
unsigned NumTemplateArgs = E->getNumTemplateArgs();
|
|
|
|
Record.push_back(NumTemplateArgs);
|
2010-07-08 21:09:47 +08:00
|
|
|
Writer.AddSourceLocation(E->getLAngleLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRAngleLoc(), Record);
|
|
|
|
for (unsigned i=0; i != NumTemplateArgs; ++i)
|
|
|
|
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
|
|
|
|
}
|
2011-10-05 15:56:41 +08:00
|
|
|
|
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
|
|
|
|
2010-07-08 21:09:47 +08:00
|
|
|
DeclAccessPair FoundDecl = E->getFoundDecl();
|
|
|
|
Writer.AddDeclRef(FoundDecl.getDecl(), Record);
|
|
|
|
Record.push_back(FoundDecl.getAccess());
|
|
|
|
|
|
|
|
Writer.AddTypeRef(E->getType(), Record);
|
2010-11-18 14:31:45 +08:00
|
|
|
Record.push_back(E->getValueKind());
|
|
|
|
Record.push_back(E->getObjectKind());
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getBase());
|
2015-05-01 10:04:32 +08:00
|
|
|
Writer.AddDeclRef(E->getMemberDecl(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getMemberLoc(), Record);
|
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
|
|
|
Writer.AddDeclarationNameLoc(E->MemberDNLoc,
|
|
|
|
E->getMemberDecl()->getDeclName(), Record);
|
|
|
|
Code = serialization::EXPR_MEMBER;
|
2009-07-25 01:54:45 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCIsaExpr(ObjCIsaExpr *E) {
|
2009-07-25 01:54:45 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getBase());
|
2009-07-25 01:54:45 +08:00
|
|
|
Writer.AddSourceLocation(E->getIsaMemberLoc(), Record);
|
2013-03-29 03:50:55 +08:00
|
|
|
Writer.AddSourceLocation(E->getOpLoc(), Record);
|
2009-07-25 01:54:45 +08:00
|
|
|
Record.push_back(E->isArrow());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_ISA;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCastExpr(CastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-08-07 14:22:56 +08:00
|
|
|
Record.push_back(E->path_size());
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2009-07-31 08:48:10 +08:00
|
|
|
Record.push_back(E->getCastKind()); // FIXME: stable encoding
|
2010-08-07 14:22:56 +08:00
|
|
|
|
|
|
|
for (CastExpr::path_iterator
|
|
|
|
PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI)
|
|
|
|
Writer.AddCXXBaseSpecifier(**PI, Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitBinaryOperator(BinaryOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getLHS());
|
|
|
|
Writer.AddStmt(E->getRHS());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->getOpcode()); // FIXME: stable encoding
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
2012-10-02 12:45:10 +08:00
|
|
|
Record.push_back(E->isFPContractable());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_BINARY_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitBinaryOperator(E);
|
|
|
|
Writer.AddTypeRef(E->getComputationLHSType(), Record);
|
|
|
|
Writer.AddTypeRef(E->getComputationResultType(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_COMPOUND_ASSIGN_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getCond());
|
|
|
|
Writer.AddStmt(E->getLHS());
|
|
|
|
Writer.AddStmt(E->getRHS());
|
2009-08-26 22:37:04 +08:00
|
|
|
Writer.AddSourceLocation(E->getQuestionLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getColonLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CONDITIONAL_OPERATOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-02-17 18:25:35 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitCastExpr(E);
|
2014-07-27 12:19:32 +08:00
|
|
|
|
|
|
|
if (E->path_size() == 0)
|
|
|
|
AbbrevToUse = Writer.getExprImplicitCastAbbrev();
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_IMPLICIT_CAST;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitCastExpr(E);
|
2010-01-16 02:39:57 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getTypeInfoAsWritten(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCStyleCastExpr(CStyleCastExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CSTYLE_CAST;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
2010-01-19 03:35:47 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getInitializer());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isFileScope());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_COMPOUND_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getBase());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddIdentifierRef(&E->getAccessor(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getAccessorLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_EXT_VECTOR_ELEMENT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2012-11-09 02:41:43 +08:00
|
|
|
// NOTE: only add the (possibly null) syntactic form.
|
|
|
|
// No need to serialize the isSemanticForm flag and the semantic form.
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSyntacticForm());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getLBraceLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRBraceLoc(), Record);
|
2011-04-21 08:27:41 +08:00
|
|
|
bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is<Expr*>();
|
|
|
|
Record.push_back(isArrayFiller);
|
|
|
|
if (isArrayFiller)
|
|
|
|
Writer.AddStmt(E->getArrayFiller());
|
|
|
|
else
|
|
|
|
Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->hadArrayRangeDesignator());
|
2011-04-22 13:29:30 +08:00
|
|
|
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)
|
2014-05-22 13:54:18 +08:00
|
|
|
Writer.AddStmt(E->getInit(I) != filler ? E->getInit(I) : nullptr);
|
2011-04-22 13:29:30 +08:00
|
|
|
} else {
|
|
|
|
for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
|
|
|
|
Writer.AddStmt(E->getInit(I));
|
|
|
|
}
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_INIT_LIST;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSubExprs());
|
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
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()) {
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_FIELD_DECL);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddDeclRef(Field, Record);
|
|
|
|
} else {
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_FIELD_NAME);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddIdentifierRef(D->getFieldName(), Record);
|
|
|
|
}
|
|
|
|
Writer.AddSourceLocation(D->getDotLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(D->getFieldLoc(), Record);
|
|
|
|
} else if (D->isArrayDesignator()) {
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_ARRAY);
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(D->getFirstExprIndex());
|
|
|
|
Writer.AddSourceLocation(D->getLBracketLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(D->getRBracketLoc(), Record);
|
|
|
|
} else {
|
|
|
|
assert(D->isArrayRangeDesignator() && "Unknown designator");
|
2010-08-19 07:57:32 +08:00
|
|
|
Record.push_back(serialization::DESIG_ARRAY_RANGE);
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(D->getFirstExprIndex());
|
|
|
|
Writer.AddSourceLocation(D->getLBracketLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(D->getRBracketLoc(), Record);
|
|
|
|
}
|
|
|
|
}
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_DESIGNATED_INIT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2015-06-10 08:27:52 +08:00
|
|
|
void ASTStmtWriter::VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddStmt(E->getBase());
|
|
|
|
Writer.AddStmt(E->getUpdater());
|
|
|
|
Code = serialization::EXPR_DESIGNATED_INIT_UPDATE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitNoInitExpr(NoInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Code = serialization::EXPR_NO_INIT;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_IMPLICIT_VALUE_INIT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2010-08-10 18:06:15 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getWrittenTypeInfo(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_VA_ARG;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitAddrLabelExpr(AddrLabelExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getAmpAmpLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getLabelLoc(), Record);
|
2011-02-17 15:39:24 +08:00
|
|
|
Writer.AddDeclRef(E->getLabel(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_ADDR_LABEL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubStmt());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_STMT;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitChooseExpr(ChooseExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getCond());
|
|
|
|
Writer.AddStmt(E->getLHS());
|
|
|
|
Writer.AddStmt(E->getRHS());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2013-07-20 08:40:58 +08:00
|
|
|
Record.push_back(E->isConditionDependent() ? false : E->isConditionTrue());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CHOOSE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitGNUNullExpr(GNUNullExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getTokenLocation(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_GNU_NULL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumSubExprs());
|
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getExpr(I));
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_SHUFFLE_VECTOR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2013-09-18 11:29:45 +08:00
|
|
|
void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
|
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
|
|
|
Writer.AddStmt(E->getSrcExpr());
|
|
|
|
Code = serialization::EXPR_CONVERT_VECTOR;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddDeclRef(E->getBlockDecl(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_BLOCK;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
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);
|
|
|
|
}
|
2011-11-15 14:20:27 +08:00
|
|
|
Code = serialization::EXPR_PSEUDO_OBJECT;
|
2011-11-06 17:01:30 +08:00
|
|
|
}
|
|
|
|
|
2011-10-11 10:20:01 +08:00
|
|
|
void ASTStmtWriter::VisitAtomicExpr(AtomicExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getOp());
|
2012-04-11 06:49:28 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
|
|
|
|
Writer.AddStmt(E->getSubExprs()[I]);
|
2011-10-11 10:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2011-11-15 14:20:27 +08:00
|
|
|
Code = serialization::EXPR_ATOMIC;
|
2011-10-11 10:20:01 +08:00
|
|
|
}
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Objective-C Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getString());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_STRING_LITERAL;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-04-19 08:25:12 +08:00
|
|
|
void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
2012-03-07 04:05:56 +08:00
|
|
|
VisitExpr(E);
|
2012-04-19 08:25:12 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
|
|
|
Writer.AddDeclRef(E->getBoxingMethod(), Record);
|
|
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
|
|
Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
|
2012-03-07 04:05:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2010-04-20 23:39:42 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_ENCODE;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSelectorRef(E->getSelector(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_SELECTOR_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddDeclRef(E->getProtocol(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getAtLoc(), Record);
|
2012-05-16 08:50:02 +08:00
|
|
|
Writer.AddSourceLocation(E->ProtoLoc, Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_PROTOCOL_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddDeclRef(E->getDecl(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2013-04-03 02:57:54 +08:00
|
|
|
Writer.AddSourceLocation(E->getOpLoc(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getBase());
|
2009-04-27 14:20:01 +08:00
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Record.push_back(E->isFreeIvar());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_IVAR_REF_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
2012-03-30 08:19:18 +08:00
|
|
|
Record.push_back(E->SetterAndMethodRefFlags.getInt());
|
2010-12-02 09:19:52 +08:00
|
|
|
Record.push_back(E->isImplicitProperty());
|
|
|
|
if (E->isImplicitProperty()) {
|
|
|
|
Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);
|
|
|
|
Writer.AddDeclRef(E->getImplicitPropertySetter(), Record);
|
|
|
|
} else {
|
|
|
|
Writer.AddDeclRef(E->getExplicitProperty(), Record);
|
|
|
|
}
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2010-12-02 09:19:52 +08:00
|
|
|
Writer.AddSourceLocation(E->getReceiverLocation(), Record);
|
|
|
|
if (E->isObjectReceiver()) {
|
|
|
|
Record.push_back(0);
|
2010-10-15 00:04:05 +08:00
|
|
|
Writer.AddStmt(E->getBase());
|
2010-12-02 09:19:52 +08:00
|
|
|
} else if (E->isSuperReceiver()) {
|
|
|
|
Record.push_back(1);
|
|
|
|
Writer.AddTypeRef(E->getSuperReceiverType(), Record);
|
|
|
|
} else {
|
|
|
|
Record.push_back(2);
|
|
|
|
Writer.AddDeclRef(E->getClassReceiver(), Record);
|
|
|
|
}
|
2010-10-15 00:04:05 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_PROPERTY_REF_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumArgs());
|
2011-10-03 14:36:51 +08:00
|
|
|
Record.push_back(E->getNumStoredSelLocs());
|
|
|
|
Record.push_back(E->SelLocsKind);
|
2011-06-16 07:02:42 +08:00
|
|
|
Record.push_back(E->isDelegateInitCall());
|
2012-01-12 10:34:39 +08:00
|
|
|
Record.push_back(E->IsImplicit);
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
|
|
|
|
switch (E->getReceiverKind()) {
|
|
|
|
case ObjCMessageExpr::Instance:
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getInstanceReceiver());
|
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:
1) Send to a object instance described by an expression (e.g., [x method:5])
2) Send to a class described by the class name (e.g., [NSString method:5])
3) Send to a superclass class (e.g, [super method:5] in class method)
4) Send to a superclass instance (e.g., [super method:5] in instance method)
Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:
1) Unchanged; the object instance is represented by an Expr*.
2) Previously stored the ObjCInterfaceDecl* referring to the class
receiving the message. Now stores a TypeSourceInfo* so that we know
how the class was spelled. This both maintains typedef information
and opens the door for more complicated C++ types (e.g., dependent
types). There was an alternative, unused representation of these
sends by naming the class via an IdentifierInfo *. In practice, we
either had an ObjCInterfaceDecl *, from which we would get the
IdentifierInfo *, or we fell into the case below...
3) Previously represented by a class message whose IdentifierInfo *
referred to "super". Sema and CodeGen would use isStr("super") to
determine if they had a send to super. Now represented as a
"class super" send, where we have both the location of the "super"
keyword and the ObjCInterfaceDecl* of the superclass we're
targetting (statically).
4) Previously represented by an instance message whose receiver is a
an ObjCSuperExpr, which Sema and CodeGen would check for via
isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
where we have both the location of the "super" keyword and the
ObjCInterfaceDecl* of the superclass we're targetting
(statically). Note that ObjCSuperExpr only has one remaining use in
the AST, which is for "super.prop" references.
The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!
This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:
if (message has a receiver expression) {
// instance message
if (isa<ObjCSuperExpr>(...)) {
// send to super
} else {
// send to an object
}
} else {
// class message
if (name->isStr("super")) {
// class send to super
} else {
// send to class
}
}
with a switch
switch (E->getReceiverKind()) {
case ObjCMessageExpr::SuperInstance: ...
case ObjCMessageExpr::Instance: ...
case ObjCMessageExpr::SuperClass: ...
case ObjCMessageExpr::Class:...
}
There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.
llvm-svn: 101972
2010-04-21 08:45:42 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
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)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(*Arg);
|
2011-10-03 14:36:51 +08:00
|
|
|
|
|
|
|
SourceLocation *Locs = E->getStoredSelLocs();
|
|
|
|
for (unsigned i = 0, e = E->getNumStoredSelLocs(); i != e; ++i)
|
|
|
|
Writer.AddSourceLocation(Locs[i], Record);
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_OBJC_MESSAGE_EXPR;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
2009-04-27 14:20:01 +08:00
|
|
|
VisitStmt(S);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getElement());
|
|
|
|
Writer.AddStmt(S->getCollection());
|
|
|
|
Writer.AddStmt(S->getBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getForLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_FOR_COLLECTION;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getCatchBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddDeclRef(S->getCatchParamDecl(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(S->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_CATCH;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getFinallyBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getAtFinallyLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_FINALLY;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
|
|
|
|
Writer.AddStmt(S->getSubStmt());
|
|
|
|
Writer.AddSourceLocation(S->getAtLoc(), Record);
|
|
|
|
Code = serialization::STMT_OBJC_AUTORELEASE_POOL;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
|
2010-04-24 06:50:49 +08:00
|
|
|
Record.push_back(S->getNumCatchStmts());
|
2014-05-22 13:54:18 +08:00
|
|
|
Record.push_back(S->getFinallyStmt() != nullptr);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getTryBody());
|
2010-04-24 06:50:49 +08:00
|
|
|
for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getCatchStmt(I));
|
2010-04-24 06:50:49 +08:00
|
|
|
if (S->getFinallyStmt())
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getFinallyStmt());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getAtTryLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_AT_TRY;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getSynchExpr());
|
|
|
|
Writer.AddStmt(S->getSynchBody());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getAtSynchronizedLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_AT_SYNCHRONIZED;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(S->getThrowExpr());
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.AddSourceLocation(S->getThrowLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_OBJC_AT_THROW;
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void ASTStmtWriter::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
|
|
Code = serialization::EXPR_OBJC_BOOL_LITERAL;
|
|
|
|
}
|
|
|
|
|
2009-07-14 11:19:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXCatchStmt(CXXCatchStmt *S) {
|
2010-07-23 00:03:56 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getCatchLoc(), Record);
|
|
|
|
Writer.AddDeclRef(S->getExceptionDecl(), Record);
|
|
|
|
Writer.AddStmt(S->getHandlerBlock());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CXX_CATCH;
|
2010-07-23 00:03:56 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXTryStmt(CXXTryStmt *S) {
|
2010-07-23 00:03:56 +08:00
|
|
|
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));
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::STMT_CXX_TRY;
|
2010-07-23 00:03:56 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 06:09:26 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-10-25 09:33:02 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
|
2009-07-14 11:19:21 +08:00
|
|
|
VisitCallExpr(E);
|
|
|
|
Record.push_back(E->getOperator());
|
2012-05-01 06:12:22 +08:00
|
|
|
Writer.AddSourceRange(E->Range, Record);
|
2012-10-02 12:45:10 +08:00
|
|
|
Record.push_back(E->isFPContractable());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_OPERATOR_CALL;
|
2009-07-14 11:19:21 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
2010-05-09 13:36:05 +08:00
|
|
|
VisitCallExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_MEMBER_CALL;
|
2010-05-09 13:36:05 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
2009-09-10 07:08:42 +08:00
|
|
|
VisitExpr(E);
|
2010-06-24 16:57:09 +08:00
|
|
|
Record.push_back(E->getNumArgs());
|
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getArg(I));
|
2009-09-10 07:08:42 +08:00
|
|
|
Writer.AddDeclRef(E->getConstructor(), Record);
|
2009-12-16 09:38:02 +08:00
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2009-09-10 07:08:42 +08:00
|
|
|
Record.push_back(E->isElidable());
|
2011-10-05 15:56:41 +08:00
|
|
|
Record.push_back(E->hadMultipleCandidates());
|
2012-12-19 09:39:02 +08:00
|
|
|
Record.push_back(E->isListInitialization());
|
2014-07-17 13:12:35 +08:00
|
|
|
Record.push_back(E->isStdInitListInitialization());
|
2009-12-17 02:50:27 +08:00
|
|
|
Record.push_back(E->requiresZeroInitialization());
|
2010-05-15 08:13:29 +08:00
|
|
|
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
|
2013-09-07 13:49:53 +08:00
|
|
|
Writer.AddSourceRange(E->getParenOrBraceRange(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_CONSTRUCT;
|
2009-09-10 07:08:42 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
|
2010-07-10 19:46:15 +08:00
|
|
|
VisitCXXConstructExpr(E);
|
2010-09-08 08:15:04 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_TEMPORARY_OBJECT;
|
2010-07-10 19:46:15 +08:00
|
|
|
}
|
|
|
|
|
2012-02-07 18:09:13 +08:00
|
|
|
void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) {
|
|
|
|
VisitExpr(E);
|
2012-02-15 01:54:36 +08:00
|
|
|
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
|
2013-08-10 07:08:25 +08:00
|
|
|
Writer.AddSourceLocation(E->CaptureDefaultLoc, Record);
|
2012-02-15 01:54:36 +08:00
|
|
|
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;
|
2012-02-07 18:09:13 +08:00
|
|
|
}
|
|
|
|
|
2013-06-13 06:31:48 +08:00
|
|
|
void ASTStmtWriter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddStmt(E->getSubExpr());
|
|
|
|
Code = serialization::EXPR_CXX_STD_INITIALIZER_LIST;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2011-01-13 06:41:29 +08:00
|
|
|
Writer.AddSourceRange(SourceRange(E->getOperatorLoc(), E->getRParenLoc()),
|
|
|
|
Record);
|
2013-02-23 06:02:53 +08:00
|
|
|
Writer.AddSourceRange(E->getAngleBrackets(), Record);
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_STATIC_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DYNAMIC_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_REINTERPRET_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitCXXNamedCastExpr(E);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_CONST_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2013-08-16 06:02:56 +08:00
|
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
2010-01-17 05:21:01 +08:00
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_FUNCTIONAL_CAST;
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 16:35:16 +08:00
|
|
|
void ASTStmtWriter::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
|
|
|
|
VisitCallExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->UDSuffixLoc, Record);
|
|
|
|
Code = serialization::EXPR_USER_DEFINED_LITERAL;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
2010-02-07 14:32:43 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getValue());
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_BOOL_LITERAL;
|
2010-02-07 14:32:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
|
2010-02-07 14:32:43 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_NULL_PTR_LITERAL;
|
2010-02-07 14:32:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
2010-05-09 14:03:39 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
|
|
if (E->isTypeOperand()) {
|
|
|
|
Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_TYPEID_TYPE;
|
2010-05-09 14:03:39 +08:00
|
|
|
} else {
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getExprOperand());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_TYPEID_EXPR;
|
2010-05-09 14:03:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXThisExpr(CXXThisExpr *E) {
|
2010-05-09 14:15:05 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
|
|
|
Record.push_back(E->isImplicit());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_THIS;
|
2010-05-09 14:15:05 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXThrowExpr(CXXThrowExpr *E) {
|
2010-05-09 14:40:08 +08:00
|
|
|
VisitExpr(E);
|
2010-05-09 14:15:05 +08:00
|
|
|
Writer.AddSourceLocation(E->getThrowLoc(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2011-07-07 06:04:06 +08:00
|
|
|
Record.push_back(E->isThrownVariableInScope());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_THROW;
|
2010-05-09 14:15:05 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
2010-05-09 14:40:08 +08:00
|
|
|
VisitExpr(E);
|
2010-07-03 07:30:15 +08:00
|
|
|
|
|
|
|
bool HasOtherExprStored = E->Param.getInt();
|
|
|
|
// Store these first, the reader reads them before creation.
|
|
|
|
Record.push_back(HasOtherExprStored);
|
|
|
|
if (HasOtherExprStored)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getExpr());
|
2010-07-03 07:30:15 +08:00
|
|
|
Writer.AddDeclRef(E->getParam(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getUsedLocation(), Record);
|
2010-05-09 14:40:08 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_ARG;
|
2010-05-09 14:40:08 +08:00
|
|
|
}
|
|
|
|
|
2013-04-21 06:23:05 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddDeclRef(E->getField(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getExprLoc(), Record);
|
|
|
|
Code = serialization::EXPR_CXX_DEFAULT_INIT;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
2010-05-10 08:25:06 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddCXXTemporary(E->getTemporary(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_BIND_TEMPORARY;
|
2010-05-10 08:25:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
2010-05-10 09:22:27 +08:00
|
|
|
VisitExpr(E);
|
2010-09-08 08:15:04 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
2010-05-10 09:22:27 +08:00
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_SCALAR_VALUE_INIT;
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
|
2010-05-10 09:22:27 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isGlobalNew());
|
2012-02-16 19:35:52 +08:00
|
|
|
Record.push_back(E->isArray());
|
2012-02-16 20:22:20 +08:00
|
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
2010-05-10 09:22:27 +08:00
|
|
|
Record.push_back(E->getNumPlacementArgs());
|
2012-02-16 20:22:20 +08:00
|
|
|
Record.push_back(E->StoredInitializationStyle);
|
2010-05-10 09:22:27 +08:00
|
|
|
Writer.AddDeclRef(E->getOperatorNew(), Record);
|
|
|
|
Writer.AddDeclRef(E->getOperatorDelete(), Record);
|
2010-09-08 05:49:58 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getAllocatedTypeSourceInfo(), Record);
|
2010-07-13 23:54:32 +08:00
|
|
|
Writer.AddSourceRange(E->getTypeIdParens(), Record);
|
2012-11-07 08:12:38 +08:00
|
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
2012-02-16 20:22:20 +08:00
|
|
|
Writer.AddSourceRange(E->getDirectInitRange(), Record);
|
2010-05-10 09:22:27 +08:00
|
|
|
for (CXXNewExpr::arg_iterator I = E->raw_arg_begin(), e = E->raw_arg_end();
|
|
|
|
I != e; ++I)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(*I);
|
2012-02-16 20:22:20 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_NEW;
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
2010-06-23 01:07:59 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isGlobalDelete());
|
|
|
|
Record.push_back(E->isArrayForm());
|
2010-09-14 04:15:54 +08:00
|
|
|
Record.push_back(E->isArrayFormAsWritten());
|
2011-01-27 17:37:56 +08:00
|
|
|
Record.push_back(E->doesUsualArrayDeleteWantSize());
|
2010-06-23 01:07:59 +08:00
|
|
|
Writer.AddDeclRef(E->getOperatorDelete(), Record);
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getArgument());
|
2010-06-23 01:07:59 +08:00
|
|
|
Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DELETE;
|
2010-06-23 01:07:59 +08:00
|
|
|
}
|
2010-05-10 09:22:27 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
2010-06-28 17:32:03 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
|
|
|
|
Writer.AddStmt(E->getBase());
|
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
2011-02-26 02:19:59 +08:00
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
2010-06-28 17:32:03 +08:00
|
|
|
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);
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_PSEUDO_DESTRUCTOR;
|
2010-06-28 17:32:03 +08:00
|
|
|
}
|
|
|
|
|
2010-12-06 16:20:24 +08:00
|
|
|
void ASTStmtWriter::VisitExprWithCleanups(ExprWithCleanups *E) {
|
2010-05-10 08:25:06 +08:00
|
|
|
VisitExpr(E);
|
2011-11-10 13:35:25 +08:00
|
|
|
Record.push_back(E->getNumObjects());
|
|
|
|
for (unsigned i = 0, e = E->getNumObjects(); i != e; ++i)
|
|
|
|
Writer.AddDeclRef(E->getObject(i), Record);
|
2010-05-10 08:25:06 +08:00
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getSubExpr());
|
2010-12-06 16:20:24 +08:00
|
|
|
Code = serialization::EXPR_EXPR_WITH_CLEANUPS;
|
2010-05-10 08:25:06 +08:00
|
|
|
}
|
|
|
|
|
2010-06-24 16:57:31 +08:00
|
|
|
void
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
|
2010-06-24 16:57:31 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
2011-02-04 20:01:24 +08:00
|
|
|
// emitted first.
|
2010-06-24 16:57:31 +08:00
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
|
|
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
|
2010-06-28 17:31:48 +08:00
|
|
|
Record.push_back(Args.NumTemplateArgs);
|
2012-01-27 17:46:47 +08:00
|
|
|
AddTemplateKWAndArgsInfo(Args);
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
2012-01-27 17:46:47 +08:00
|
|
|
|
2010-06-24 16:57:31 +08:00
|
|
|
if (!E->isImplicitAccess())
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(E->getBase());
|
2010-06-24 16:57:31 +08:00
|
|
|
else
|
2014-05-22 13:54:18 +08:00
|
|
|
Writer.AddStmt(nullptr);
|
2010-06-24 16:57:31 +08:00
|
|
|
Writer.AddTypeRef(E->getBaseType(), Record);
|
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
2011-03-01 02:50:33 +08:00
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
2010-06-24 16:57:31 +08:00
|
|
|
Writer.AddDeclRef(E->getFirstQualifierFoundInScope(), Record);
|
2010-10-16 02:21:24 +08:00
|
|
|
Writer.AddDeclarationNameInfo(E->MemberNameInfo, Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_MEMBER;
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
|
|
|
|
2010-06-28 17:31:56 +08:00
|
|
|
void
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
|
2010-06-28 17:31:56 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
2011-02-04 20:01:24 +08:00
|
|
|
// emitted first.
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
|
|
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
|
2010-06-28 17:31:56 +08:00
|
|
|
Record.push_back(Args.NumTemplateArgs);
|
2012-01-27 17:46:47 +08:00
|
|
|
AddTemplateKWAndArgsInfo(Args);
|
2010-06-28 17:31:56 +08:00
|
|
|
}
|
|
|
|
|
2011-02-26 04:49:16 +08:00
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
2010-10-16 02:21:24 +08:00
|
|
|
Writer.AddDeclarationNameInfo(E->NameInfo, Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF;
|
2010-06-28 17:31:56 +08:00
|
|
|
}
|
|
|
|
|
2010-06-24 16:57:31 +08:00
|
|
|
void
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
|
2010-06-24 16:57:31 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->arg_size());
|
|
|
|
for (CXXUnresolvedConstructExpr::arg_iterator
|
|
|
|
ArgI = E->arg_begin(), ArgE = E->arg_end(); ArgI != ArgE; ++ArgI)
|
2010-06-29 06:28:35 +08:00
|
|
|
Writer.AddStmt(*ArgI);
|
2010-09-08 08:15:04 +08:00
|
|
|
Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
|
2010-06-24 16:57:31 +08:00
|
|
|
Writer.AddSourceLocation(E->getLParenLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_CONSTRUCT;
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
2010-05-09 14:15:05 +08:00
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) {
|
2010-06-25 17:03:26 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
// Don't emit anything here, HasTemplateKWAndArgsInfo must be
|
|
|
|
// emitted first.
|
|
|
|
|
|
|
|
Record.push_back(E->HasTemplateKWAndArgsInfo);
|
|
|
|
if (E->HasTemplateKWAndArgsInfo) {
|
|
|
|
const ASTTemplateKWAndArgsInfo &Args = *E->getTemplateKWAndArgsInfo();
|
2010-06-25 17:03:26 +08:00
|
|
|
Record.push_back(Args.NumTemplateArgs);
|
2012-01-27 17:46:47 +08:00
|
|
|
AddTemplateKWAndArgsInfo(Args);
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
Writer.AddDeclarationNameInfo(E->NameInfo, Record);
|
2011-03-01 04:01:57 +08:00
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
|
2010-06-25 17:03:26 +08:00
|
|
|
VisitOverloadExpr(E);
|
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Record.push_back(E->hasUnresolvedUsing());
|
2014-05-22 13:54:18 +08:00
|
|
|
Writer.AddStmt(!E->isImplicitAccess() ? E->getBase() : nullptr);
|
2010-06-25 17:03:26 +08:00
|
|
|
Writer.AddTypeRef(E->getBaseType(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getOperatorLoc(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_MEMBER;
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:27 +08:00
|
|
|
void ASTStmtWriter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
|
2010-06-25 17:03:34 +08:00
|
|
|
VisitOverloadExpr(E);
|
|
|
|
Record.push_back(E->requiresADL());
|
|
|
|
Record.push_back(E->isOverloaded());
|
|
|
|
Writer.AddDeclRef(E->getNamingClass(), Record);
|
2010-08-19 07:57:32 +08:00
|
|
|
Code = serialization::EXPR_CXX_UNRESOLVED_LOOKUP;
|
2010-06-25 17:03:34 +08:00
|
|
|
}
|
|
|
|
|
2012-02-24 15:38:34 +08:00
|
|
|
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);
|
2013-12-20 09:26:47 +08:00
|
|
|
Writer.AddSourceRange(E->getSourceRange(), Record);
|
2012-02-24 15:38:34 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
|
|
Writer.AddTypeSourceInfo(E->getArg(I), Record);
|
|
|
|
Code = serialization::EXPR_TYPE_TRAIT;
|
|
|
|
}
|
|
|
|
|
2011-04-28 08:16:57 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-04-25 14:54:41 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-09-11 04:55:54 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
void ASTStmtWriter::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->getEllipsisLoc(), Record);
|
2011-01-15 05:20:45 +08:00
|
|
|
Record.push_back(E->NumExpansions);
|
2011-01-04 01:17:50 +08:00
|
|
|
Writer.AddStmt(E->getPattern());
|
|
|
|
Code = serialization::EXPR_PACK_EXPANSION;
|
|
|
|
}
|
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2011-01-15 09:15:58 +08:00
|
|
|
void ASTStmtWriter::VisitSubstNonTypeTemplateParmPackExpr(
|
|
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
2011-07-15 15:00:14 +08:00
|
|
|
Writer.AddDeclRef(E->getParameterPack(), Record);
|
2011-01-15 09:15:58 +08:00
|
|
|
Writer.AddTemplateArgument(E->getArgumentPack(), Record);
|
2011-07-15 15:00:14 +08:00
|
|
|
Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
|
2011-01-15 09:15:58 +08:00
|
|
|
Code = serialization::EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK;
|
|
|
|
}
|
|
|
|
|
2012-09-12 08:56:43 +08:00
|
|
|
void ASTStmtWriter::VisitFunctionParmPackExpr(FunctionParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->getNumExpansions());
|
|
|
|
Writer.AddDeclRef(E->getParameterPack(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getParameterPackLocation(), Record);
|
|
|
|
for (FunctionParmPackExpr::iterator I = E->begin(), End = E->end();
|
|
|
|
I != End; ++I)
|
|
|
|
Writer.AddDeclRef(*I, Record);
|
|
|
|
Code = serialization::EXPR_FUNCTION_PARM_PACK;
|
|
|
|
}
|
|
|
|
|
2011-06-22 01:03:29 +08:00
|
|
|
void ASTStmtWriter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
|
|
|
VisitExpr(E);
|
2014-05-02 01:50:17 +08:00
|
|
|
Writer.AddStmt(E->getTemporary());
|
|
|
|
Writer.AddDeclRef(E->getExtendingDecl(), Record);
|
|
|
|
Record.push_back(E->getManglingNumber());
|
2011-06-22 01:03:29 +08:00
|
|
|
Code = serialization::EXPR_MATERIALIZE_TEMPORARY;
|
|
|
|
}
|
|
|
|
|
2014-11-08 13:07:16 +08:00
|
|
|
void ASTStmtWriter::VisitCXXFoldExpr(CXXFoldExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Writer.AddSourceLocation(E->LParenLoc, Record);
|
|
|
|
Writer.AddSourceLocation(E->EllipsisLoc, Record);
|
|
|
|
Writer.AddSourceLocation(E->RParenLoc, Record);
|
|
|
|
Writer.AddStmt(E->SubExprs[0]);
|
|
|
|
Writer.AddStmt(E->SubExprs[1]);
|
|
|
|
Record.push_back(E->Opcode);
|
|
|
|
Code = serialization::EXPR_CXX_FOLD;
|
|
|
|
}
|
|
|
|
|
2010-11-16 07:31:06 +08:00
|
|
|
void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|
|
|
VisitExpr(E);
|
2011-12-03 11:49:52 +08:00
|
|
|
Writer.AddStmt(E->getSourceExpr());
|
2011-01-28 10:26:04 +08:00
|
|
|
Writer.AddSourceLocation(E->getLocation(), Record);
|
2010-11-16 07:31:06 +08:00
|
|
|
Code = serialization::EXPR_OPAQUE_VALUE;
|
|
|
|
}
|
|
|
|
|
2014-10-28 02:07:20 +08:00
|
|
|
void ASTStmtWriter::VisitTypoExpr(TypoExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
// TODO: Figure out sane writer behavior for a TypoExpr, if necessary
|
|
|
|
assert(false && "Cannot write TypoExpr nodes");
|
|
|
|
}
|
|
|
|
|
2011-02-10 05:07:24 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CUDA Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
|
|
|
VisitCallExpr(E);
|
|
|
|
Writer.AddStmt(E->getConfig());
|
|
|
|
Code = serialization::EXPR_CUDA_KERNEL_CALL;
|
|
|
|
}
|
|
|
|
|
2011-06-04 08:47:47 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenCL Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitAsTypeExpr(AsTypeExpr *E) {
|
|
|
|
VisitExpr(E);
|
2011-07-15 15:00:14 +08:00
|
|
|
Writer.AddSourceLocation(E->getBuiltinLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getRParenLoc(), Record);
|
2011-06-04 08:47:47 +08:00
|
|
|
Writer.AddStmt(E->getSrcExpr());
|
|
|
|
Code = serialization::EXPR_ASTYPE;
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Microsoft Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2013-04-16 15:28:30 +08:00
|
|
|
void ASTStmtWriter::VisitMSPropertyRefExpr(MSPropertyRefExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
Record.push_back(E->isArrow());
|
|
|
|
Writer.AddStmt(E->getBaseExpr());
|
|
|
|
Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getMemberLoc(), Record);
|
|
|
|
Writer.AddDeclRef(E->getPropertyDecl(), Record);
|
|
|
|
Code = serialization::EXPR_CXX_PROPERTY_REF_EXPR;
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-07-07 08:12:30 +08:00
|
|
|
void ASTStmtWriter::VisitSEHLeaveStmt(SEHLeaveStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
Writer.AddSourceLocation(S->getLeaveLoc(), Record);
|
|
|
|
Code = serialization::STMT_SEH_LEAVE;
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenMP Clauses.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
class OMPClauseWriter : public OMPClauseVisitor<OMPClauseWriter> {
|
|
|
|
ASTStmtWriter *Writer;
|
|
|
|
ASTWriter::RecordData &Record;
|
|
|
|
public:
|
|
|
|
OMPClauseWriter(ASTStmtWriter *W, ASTWriter::RecordData &Record)
|
|
|
|
: Writer(W), Record(Record) { }
|
|
|
|
#define OPENMP_CLAUSE(Name, Class) \
|
|
|
|
void Visit##Class(Class *S);
|
|
|
|
#include "clang/Basic/OpenMPKinds.def"
|
|
|
|
void writeClause(OMPClause *C);
|
|
|
|
};
|
2015-06-22 17:47:44 +08:00
|
|
|
} // namespace clang
|
2013-07-19 11:13:43 +08:00
|
|
|
|
|
|
|
void OMPClauseWriter::writeClause(OMPClause *C) {
|
|
|
|
Record.push_back(C->getClauseKind());
|
|
|
|
Visit(C);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLocStart(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLocEnd(), Record);
|
|
|
|
}
|
|
|
|
|
2014-02-13 13:29:23 +08:00
|
|
|
void OMPClauseWriter::VisitOMPIfClause(OMPIfClause *C) {
|
|
|
|
Writer->Writer.AddStmt(C->getCondition());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-03-06 14:15:19 +08:00
|
|
|
}
|
|
|
|
|
2014-07-17 15:32:53 +08:00
|
|
|
void OMPClauseWriter::VisitOMPFinalClause(OMPFinalClause *C) {
|
|
|
|
Writer->Writer.AddStmt(C->getCondition());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
}
|
|
|
|
|
2014-03-06 14:15:19 +08:00
|
|
|
void OMPClauseWriter::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
|
|
|
|
Writer->Writer.AddStmt(C->getNumThreads());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-02-13 13:29:23 +08:00
|
|
|
}
|
|
|
|
|
2014-03-21 12:51:18 +08:00
|
|
|
void OMPClauseWriter::VisitOMPSafelenClause(OMPSafelenClause *C) {
|
|
|
|
Writer->Writer.AddStmt(C->getSafelen());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
}
|
|
|
|
|
2014-05-27 23:12:19 +08:00
|
|
|
void OMPClauseWriter::VisitOMPCollapseClause(OMPCollapseClause *C) {
|
|
|
|
Writer->Writer.AddStmt(C->getNumForLoops());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
void OMPClauseWriter::VisitOMPDefaultClause(OMPDefaultClause *C) {
|
|
|
|
Record.push_back(C->getDefaultKind());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getDefaultKindKwLoc(), Record);
|
|
|
|
}
|
|
|
|
|
2014-05-06 14:04:14 +08:00
|
|
|
void OMPClauseWriter::VisitOMPProcBindClause(OMPProcBindClause *C) {
|
|
|
|
Record.push_back(C->getProcBindKind());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getProcBindKindKwLoc(), Record);
|
|
|
|
}
|
|
|
|
|
2014-06-20 15:16:17 +08:00
|
|
|
void OMPClauseWriter::VisitOMPScheduleClause(OMPScheduleClause *C) {
|
|
|
|
Record.push_back(C->getScheduleKind());
|
|
|
|
Writer->Writer.AddStmt(C->getChunkSize());
|
2015-05-12 16:35:28 +08:00
|
|
|
Writer->Writer.AddStmt(C->getHelperChunkSize());
|
2014-06-20 15:16:17 +08:00
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getScheduleKindLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getCommaLoc(), Record);
|
|
|
|
}
|
|
|
|
|
2014-06-20 17:44:06 +08:00
|
|
|
void OMPClauseWriter::VisitOMPOrderedClause(OMPOrderedClause *) {}
|
|
|
|
|
2014-06-20 19:19:47 +08:00
|
|
|
void OMPClauseWriter::VisitOMPNowaitClause(OMPNowaitClause *) {}
|
|
|
|
|
2014-07-17 20:19:31 +08:00
|
|
|
void OMPClauseWriter::VisitOMPUntiedClause(OMPUntiedClause *) {}
|
|
|
|
|
2014-07-17 20:47:03 +08:00
|
|
|
void OMPClauseWriter::VisitOMPMergeableClause(OMPMergeableClause *) {}
|
|
|
|
|
2014-07-23 10:27:21 +08:00
|
|
|
void OMPClauseWriter::VisitOMPReadClause(OMPReadClause *) {}
|
|
|
|
|
2014-07-23 15:46:59 +08:00
|
|
|
void OMPClauseWriter::VisitOMPWriteClause(OMPWriteClause *) {}
|
|
|
|
|
2014-07-23 18:25:33 +08:00
|
|
|
void OMPClauseWriter::VisitOMPUpdateClause(OMPUpdateClause *) {}
|
|
|
|
|
2014-07-24 14:46:57 +08:00
|
|
|
void OMPClauseWriter::VisitOMPCaptureClause(OMPCaptureClause *) {}
|
|
|
|
|
2014-07-24 16:55:34 +08:00
|
|
|
void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-10-21 11:16:40 +08:00
|
|
|
for (auto *VE : C->varlists()) {
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
|
|
|
for (auto *VE : C->private_copies()) {
|
2014-04-04 18:02:14 +08:00
|
|
|
Writer->Writer.AddStmt(VE);
|
2014-10-21 11:16:40 +08:00
|
|
|
}
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
|
|
|
|
2013-10-01 13:32:34 +08:00
|
|
|
void OMPClauseWriter::VisitOMPFirstprivateClause(OMPFirstprivateClause *C) {
|
2014-06-04 21:06:39 +08:00
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-10-08 22:01:46 +08:00
|
|
|
for (auto *VE : C->varlists()) {
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
|
|
|
for (auto *VE : C->private_copies()) {
|
2014-10-08 19:35:04 +08:00
|
|
|
Writer->Writer.AddStmt(VE);
|
2014-10-08 22:01:46 +08:00
|
|
|
}
|
|
|
|
for (auto *VE : C->inits()) {
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
2014-06-04 21:06:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void OMPClauseWriter::VisitOMPLastprivateClause(OMPLastprivateClause *C) {
|
2013-10-01 13:32:34 +08:00
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-04-04 18:02:14 +08:00
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
2015-04-16 12:54:05 +08:00
|
|
|
for (auto *E : C->private_copies())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->source_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->destination_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->assignment_ops())
|
|
|
|
Writer->Writer.AddStmt(E);
|
2013-10-01 13:32:34 +08:00
|
|
|
}
|
|
|
|
|
2013-09-07 02:03:48 +08:00
|
|
|
void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-04-04 18:02:14 +08:00
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
2013-09-07 02:03:48 +08:00
|
|
|
}
|
|
|
|
|
2014-06-16 15:08:35 +08:00
|
|
|
void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
|
|
|
|
Writer->Writer.AddNestedNameSpecifierLoc(C->getQualifierLoc(), Record);
|
|
|
|
Writer->Writer.AddDeclarationNameInfo(C->getNameInfo(), Record);
|
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
[OPENMP] Codegen for 'reduction' clause in 'parallel' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:
static kmp_critical_name lock = { 0 };
void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
...
*(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
...
}
... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
...
<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
...
__kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
break;
case 2:
...
Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
...
break;
default:
;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D8915
llvm-svn: 234583
2015-04-10 18:43:45 +08:00
|
|
|
for (auto *E : C->lhs_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->rhs_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->reduction_ops())
|
|
|
|
Writer->Writer.AddStmt(E);
|
2014-06-16 15:08:35 +08:00
|
|
|
}
|
|
|
|
|
2014-04-22 21:09:42 +08:00
|
|
|
void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
|
2015-03-21 18:12:56 +08:00
|
|
|
for (auto *VE : C->varlists()) {
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
|
|
|
for (auto *VE : C->inits()) {
|
2014-04-22 21:09:42 +08:00
|
|
|
Writer->Writer.AddStmt(VE);
|
2015-03-21 18:12:56 +08:00
|
|
|
}
|
|
|
|
for (auto *VE : C->updates()) {
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
|
|
|
for (auto *VE : C->finals()) {
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
2014-04-22 21:09:42 +08:00
|
|
|
Writer->Writer.AddStmt(C->getStep());
|
2015-03-21 18:12:56 +08:00
|
|
|
Writer->Writer.AddStmt(C->getCalcStep());
|
2014-04-22 21:09:42 +08:00
|
|
|
}
|
|
|
|
|
2014-05-29 22:36:25 +08:00
|
|
|
void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
|
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
Writer->Writer.AddStmt(C->getAlignment());
|
|
|
|
}
|
|
|
|
|
2014-03-31 11:36:38 +08:00
|
|
|
void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
2014-04-04 18:02:14 +08:00
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
2015-04-16 13:39:01 +08:00
|
|
|
for (auto *E : C->source_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->destination_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->assignment_ops())
|
|
|
|
Writer->Writer.AddStmt(E);
|
2014-03-31 11:36:38 +08:00
|
|
|
}
|
|
|
|
|
2014-06-27 18:37:06 +08:00
|
|
|
void OMPClauseWriter::VisitOMPCopyprivateClause(OMPCopyprivateClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
2015-03-23 14:18:07 +08:00
|
|
|
for (auto *E : C->source_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->destination_exprs())
|
|
|
|
Writer->Writer.AddStmt(E);
|
|
|
|
for (auto *E : C->assignment_ops())
|
|
|
|
Writer->Writer.AddStmt(E);
|
2014-06-27 18:37:06 +08:00
|
|
|
}
|
|
|
|
|
2014-07-21 19:26:11 +08:00
|
|
|
void OMPClauseWriter::VisitOMPFlushClause(OMPFlushClause *C) {
|
|
|
|
Record.push_back(C->varlist_size());
|
|
|
|
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
|
|
|
for (auto *VE : C->varlists())
|
|
|
|
Writer->Writer.AddStmt(VE);
|
|
|
|
}
|
|
|
|
|
2013-07-19 11:13:43 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenMP Directives.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtWriter::VisitOMPExecutableDirective(OMPExecutableDirective *E) {
|
|
|
|
Writer.AddSourceLocation(E->getLocStart(), Record);
|
|
|
|
Writer.AddSourceLocation(E->getLocEnd(), Record);
|
|
|
|
OMPClauseWriter ClauseWriter(this, Record);
|
|
|
|
for (unsigned i = 0; i < E->getNumClauses(); ++i) {
|
|
|
|
ClauseWriter.writeClause(E->getClause(i));
|
|
|
|
}
|
2014-07-18 15:47:19 +08:00
|
|
|
if (E->hasAssociatedStmt())
|
|
|
|
Writer.AddStmt(E->getAssociatedStmt());
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:27:13 +08:00
|
|
|
void ASTStmtWriter::VisitOMPLoopDirective(OMPLoopDirective *D) {
|
2014-02-27 16:29:12 +08:00
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
2014-08-19 19:27:13 +08:00
|
|
|
Record.push_back(D->getCollapsedNumber());
|
2013-07-19 11:13:43 +08:00
|
|
|
VisitOMPExecutableDirective(D);
|
2014-10-01 14:03:56 +08:00
|
|
|
Writer.AddStmt(D->getIterationVariable());
|
|
|
|
Writer.AddStmt(D->getLastIteration());
|
|
|
|
Writer.AddStmt(D->getCalcLastIteration());
|
|
|
|
Writer.AddStmt(D->getPreCond());
|
2015-06-16 19:59:36 +08:00
|
|
|
Writer.AddStmt(D->getCond());
|
2014-10-01 14:03:56 +08:00
|
|
|
Writer.AddStmt(D->getInit());
|
|
|
|
Writer.AddStmt(D->getInc());
|
2014-12-15 15:07:06 +08:00
|
|
|
if (isOpenMPWorksharingDirective(D->getDirectiveKind())) {
|
|
|
|
Writer.AddStmt(D->getIsLastIterVariable());
|
|
|
|
Writer.AddStmt(D->getLowerBoundVariable());
|
|
|
|
Writer.AddStmt(D->getUpperBoundVariable());
|
|
|
|
Writer.AddStmt(D->getStrideVariable());
|
|
|
|
Writer.AddStmt(D->getEnsureUpperBound());
|
|
|
|
Writer.AddStmt(D->getNextLowerBound());
|
|
|
|
Writer.AddStmt(D->getNextUpperBound());
|
|
|
|
}
|
2014-10-01 14:03:56 +08:00
|
|
|
for (auto I : D->counters()) {
|
|
|
|
Writer.AddStmt(I);
|
|
|
|
}
|
|
|
|
for (auto I : D->updates()) {
|
|
|
|
Writer.AddStmt(I);
|
|
|
|
}
|
|
|
|
for (auto I : D->finals()) {
|
|
|
|
Writer.AddStmt(I);
|
|
|
|
}
|
2013-07-19 11:13:43 +08:00
|
|
|
}
|
|
|
|
|
2014-08-19 19:27:13 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelDirective(OMPParallelDirective *D) {
|
2014-02-27 16:29:12 +08:00
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2014-08-19 19:27:13 +08:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtWriter::VisitOMPSimdDirective(OMPSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
2014-02-27 16:29:12 +08:00
|
|
|
Code = serialization::STMT_OMP_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-18 12:14:57 +08:00
|
|
|
void ASTStmtWriter::VisitOMPForDirective(OMPForDirective *D) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(D);
|
2014-06-18 12:14:57 +08:00
|
|
|
Code = serialization::STMT_OMP_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-18 13:12:34 +08:00
|
|
|
void ASTStmtWriter::VisitOMPForSimdDirective(OMPForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-25 19:44:49 +08:00
|
|
|
void ASTStmtWriter::VisitOMPSectionsDirective(OMPSectionsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SECTIONS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-26 16:21:58 +08:00
|
|
|
void ASTStmtWriter::VisitOMPSectionDirective(OMPSectionDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SECTION_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-06-26 20:05:45 +08:00
|
|
|
void ASTStmtWriter::VisitOMPSingleDirective(OMPSingleDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_SINGLE_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-17 16:54:58 +08:00
|
|
|
void ASTStmtWriter::VisitOMPMasterDirective(OMPMasterDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_MASTER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 17:42:05 +08:00
|
|
|
void ASTStmtWriter::VisitOMPCriticalDirective(OMPCriticalDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Writer.AddDeclarationNameInfo(D->getDirectiveName(), Record);
|
|
|
|
Code = serialization::STMT_OMP_CRITICAL_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-07 21:01:15 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelForDirective(OMPParallelForDirective *D) {
|
2014-08-19 19:27:13 +08:00
|
|
|
VisitOMPLoopDirective(D);
|
2014-07-07 21:01:15 +08:00
|
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-23 17:33:00 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelForSimdDirective(
|
|
|
|
OMPParallelForSimdDirective *D) {
|
|
|
|
VisitOMPLoopDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_FOR_SIMD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-08 16:12:03 +08:00
|
|
|
void ASTStmtWriter::VisitOMPParallelSectionsDirective(
|
|
|
|
OMPParallelSectionsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_PARALLEL_SECTIONS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-11 19:25:16 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskDirective(OMPTaskDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASK_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 18:10:35 +08:00
|
|
|
void ASTStmtWriter::VisitOMPAtomicDirective(OMPAtomicDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
2014-11-18 18:14:22 +08:00
|
|
|
Writer.AddStmt(D->getX());
|
|
|
|
Writer.AddStmt(D->getV());
|
|
|
|
Writer.AddStmt(D->getExpr());
|
2015-03-30 13:20:59 +08:00
|
|
|
Writer.AddStmt(D->getUpdateExpr());
|
|
|
|
Record.push_back(D->isXLHSInRHSPart() ? 1 : 0);
|
2015-04-01 11:33:17 +08:00
|
|
|
Record.push_back(D->isPostfixUpdate() ? 1 : 0);
|
2014-07-22 18:10:35 +08:00
|
|
|
Code = serialization::STMT_OMP_ATOMIC_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-09-19 16:19:49 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTargetDirective(OMPTargetDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TARGET_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 15:47:19 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskyieldDirective(OMPTaskyieldDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKYIELD_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 17:11:51 +08:00
|
|
|
void ASTStmtWriter::VisitOMPBarrierDirective(OMPBarrierDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_BARRIER_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-18 18:17:07 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2015-06-18 20:14:09 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-21 19:26:11 +08:00
|
|
|
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_FLUSH_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-07-22 14:45:04 +08:00
|
|
|
void ASTStmtWriter::VisitOMPOrderedDirective(OMPOrderedDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_ORDERED_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2014-10-09 12:18:56 +08:00
|
|
|
void ASTStmtWriter::VisitOMPTeamsDirective(OMPTeamsDirective *D) {
|
|
|
|
VisitStmt(D);
|
|
|
|
Record.push_back(D->getNumClauses());
|
|
|
|
VisitOMPExecutableDirective(D);
|
|
|
|
Code = serialization::STMT_OMP_TEAMS_DIRECTIVE;
|
|
|
|
}
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2010-08-19 07:56:21 +08:00
|
|
|
// ASTWriter Implementation
|
2009-04-27 14:20:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:21 +08:00
|
|
|
unsigned ASTWriter::RecordSwitchCaseID(SwitchCase *S) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(SwitchCaseIDs.find(S) == SwitchCaseIDs.end() &&
|
2009-04-27 14:20:01 +08:00
|
|
|
"SwitchCase recorded twice");
|
|
|
|
unsigned NextID = SwitchCaseIDs.size();
|
|
|
|
SwitchCaseIDs[S] = NextID;
|
|
|
|
return NextID;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:21 +08:00
|
|
|
unsigned ASTWriter::getSwitchCaseID(SwitchCase *S) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(SwitchCaseIDs.find(S) != SwitchCaseIDs.end() &&
|
2009-04-27 14:20:01 +08:00
|
|
|
"SwitchCase hasn't been seen yet");
|
|
|
|
return SwitchCaseIDs[S];
|
|
|
|
}
|
|
|
|
|
2010-10-28 17:29:32 +08:00
|
|
|
void ASTWriter::ClearSwitchCaseIDs() {
|
|
|
|
SwitchCaseIDs.clear();
|
|
|
|
}
|
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
/// \brief Write the given substatement or subexpression to the
|
|
|
|
/// bitstream.
|
2011-10-22 07:02:28 +08:00
|
|
|
void ASTWriter::WriteSubStmt(Stmt *S,
|
|
|
|
llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries,
|
|
|
|
llvm::DenseSet<Stmt *> &ParentStmts) {
|
2009-04-27 14:20:01 +08:00
|
|
|
RecordData Record;
|
2010-08-19 07:56:27 +08:00
|
|
|
ASTStmtWriter Writer(*this, Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
++NumStatements;
|
2010-06-29 06:28:35 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
if (!S) {
|
2010-08-19 07:57:32 +08:00
|
|
|
Stream.EmitRecord(serialization::STMT_NULL_PTR, Record);
|
2009-04-27 14:20:01 +08:00
|
|
|
return;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-10-22 07:02:28 +08:00
|
|
|
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
|
|
|
|
|
2013-12-07 01:56:43 +08:00
|
|
|
// Redirect ASTWriter::AddStmt to collect sub-stmts.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Stmt *, 16> SubStmts;
|
2010-06-29 06:28:35 +08:00
|
|
|
CollectedStmts = &SubStmts;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
Writer.Code = serialization::STMT_NULL_PTR;
|
2011-06-03 10:27:19 +08:00
|
|
|
Writer.AbbrevToUse = 0;
|
2009-04-27 14:20:01 +08:00
|
|
|
Writer.Visit(S);
|
2010-05-10 09:22:27 +08:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
2010-08-19 07:57:32 +08:00
|
|
|
if (Writer.Code == serialization::STMT_NULL_PTR) {
|
2010-06-25 17:03:12 +08:00
|
|
|
SourceManager &SrcMgr
|
|
|
|
= DeclIDs.begin()->first->getASTContext().getSourceManager();
|
|
|
|
S->dump(SrcMgr);
|
2013-12-07 01:56:43 +08:00
|
|
|
llvm_unreachable("Unhandled sub-statement writing AST file");
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
#endif
|
2010-06-29 06:28:35 +08:00
|
|
|
|
2010-08-19 07:56:21 +08:00
|
|
|
// Revert ASTWriter::AddStmt.
|
2010-06-29 06:28:35 +08:00
|
|
|
CollectedStmts = &StmtsToEmit;
|
|
|
|
|
2013-12-07 01:56:43 +08:00
|
|
|
// Write the sub-stmts in reverse order, last to first. When reading them back
|
2010-06-29 06:28:35 +08:00
|
|
|
// we will read them in correct order by "pop"ing them from the Stmts stack.
|
2013-12-07 01:56:43 +08:00
|
|
|
// This simplifies reading and allows to store a variable number of sub-stmts
|
2010-06-29 06:28:35 +08:00
|
|
|
// without knowing it in advance.
|
|
|
|
while (!SubStmts.empty())
|
2011-10-22 07:02:28 +08:00
|
|
|
WriteSubStmt(SubStmts.pop_back_val(), SubStmtEntries, ParentStmts);
|
2010-06-29 06:28:35 +08:00
|
|
|
|
2011-06-03 10:27:19 +08:00
|
|
|
Stream.EmitRecord(Writer.Code, Record, Writer.AbbrevToUse);
|
2011-10-22 07:02:28 +08:00
|
|
|
|
|
|
|
SubStmtEntries[S] = Stream.GetCurrentBitNo();
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Flush all of the statements that have been added to the
|
|
|
|
/// queue via AddStmt().
|
2010-08-19 07:56:21 +08:00
|
|
|
void ASTWriter::FlushStmts() {
|
2009-04-27 14:20:01 +08:00
|
|
|
RecordData Record;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-02-29 10:39:13 +08:00
|
|
|
// We expect to be the only consumer of the two temporary statement maps,
|
|
|
|
// assert that they are empty.
|
2013-12-07 01:56:43 +08:00
|
|
|
assert(SubStmtEntries.empty() && "unexpected entries in sub-stmt map");
|
2012-02-29 10:39:13 +08:00
|
|
|
assert(ParentStmts.empty() && "unexpected entries in parent stmt map");
|
2011-10-22 07:02:28 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
for (unsigned I = 0, N = StmtsToEmit.size(); I != N; ++I) {
|
2011-10-22 07:02:28 +08:00
|
|
|
WriteSubStmt(StmtsToEmit[I], SubStmtEntries, ParentStmts);
|
2010-06-29 06:28:35 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(N == StmtsToEmit.size() &&
|
2011-04-15 13:22:18 +08:00
|
|
|
"Substatement written via AddStmt rather than WriteSubStmt!");
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
// Note that we are at the end of a full expression. Any
|
|
|
|
// expression records that follow this one are part of a different
|
|
|
|
// expression.
|
2010-08-19 07:57:32 +08:00
|
|
|
Stream.EmitRecord(serialization::STMT_STOP, Record);
|
2011-10-22 07:02:28 +08:00
|
|
|
|
|
|
|
SubStmtEntries.clear();
|
|
|
|
ParentStmts.clear();
|
2009-04-27 14:20:01 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-27 14:20:01 +08:00
|
|
|
StmtsToEmit.clear();
|
|
|
|
}
|