2010-08-19 07:57:11 +08:00
|
|
|
//===--- ASTReaderStmt.cpp - Stmt/Expr Deserialization ----------*- C++ -*-===//
|
2009-04-27 13:14:47 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// Statement/expression deserialization. This implements the
|
2010-08-19 07:56:43 +08:00
|
|
|
// ASTReader::ReadStmt method.
|
2009-04-27 13:14:47 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:57:17 +08:00
|
|
|
#include "clang/Serialization/ASTReader.h"
|
2009-09-10 07:08:42 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2011-01-15 09:15:58 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2009-04-27 13:14:47 +08:00
|
|
|
#include "clang/AST/StmtVisitor.h"
|
2012-02-04 21:45:25 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2009-04-27 13:14:47 +08:00
|
|
|
using namespace clang;
|
2010-08-19 07:57:32 +08:00
|
|
|
using namespace clang::serialization;
|
2009-04-27 13:14:47 +08:00
|
|
|
|
2010-06-30 16:49:18 +08:00
|
|
|
namespace clang {
|
2010-06-28 17:31:42 +08:00
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
class ASTStmtReader : public StmtVisitor<ASTStmtReader> {
|
2011-07-22 06:35:25 +08:00
|
|
|
typedef ASTReader::RecordData RecordData;
|
|
|
|
|
2010-08-19 07:56:43 +08:00
|
|
|
ASTReader &Reader;
|
2011-12-01 07:21:26 +08:00
|
|
|
ModuleFile &F;
|
2010-07-23 06:43:28 +08:00
|
|
|
llvm::BitstreamCursor &DeclsCursor;
|
2010-08-19 07:56:43 +08:00
|
|
|
const ASTReader::RecordData &Record;
|
2009-04-27 13:14:47 +08:00
|
|
|
unsigned &Idx;
|
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return Reader.ReadSourceLocation(F, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
|
|
|
SourceRange ReadSourceRange(const RecordData &R, unsigned &I) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return Reader.ReadSourceRange(F, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
|
|
|
TypeSourceInfo *GetTypeSourceInfo(const RecordData &R, unsigned &I) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return Reader.GetTypeSourceInfo(F, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
|
|
|
serialization::DeclID ReadDeclID(const RecordData &R, unsigned &I) {
|
|
|
|
return Reader.ReadDeclID(F, R, I);
|
|
|
|
}
|
|
|
|
|
|
|
|
Decl *ReadDecl(const RecordData &R, unsigned &I) {
|
|
|
|
return Reader.ReadDecl(F, R, I);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
T *ReadDeclAs(const RecordData &R, unsigned &I) {
|
|
|
|
return Reader.ReadDeclAs<T>(F, R, I);
|
|
|
|
}
|
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
void ReadDeclarationNameLoc(DeclarationNameLoc &DNLoc, DeclarationName Name,
|
|
|
|
const ASTReader::RecordData &R, unsigned &I) {
|
|
|
|
Reader.ReadDeclarationNameLoc(F, DNLoc, Name, R, I);
|
|
|
|
}
|
2011-07-22 06:35:25 +08:00
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
void ReadDeclarationNameInfo(DeclarationNameInfo &NameInfo,
|
|
|
|
const ASTReader::RecordData &R, unsigned &I) {
|
|
|
|
Reader.ReadDeclarationNameInfo(F, NameInfo, R, I);
|
|
|
|
}
|
2010-10-05 23:59:54 +08:00
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
public:
|
2011-12-01 07:21:26 +08:00
|
|
|
ASTStmtReader(ASTReader &Reader, ModuleFile &F,
|
2010-10-05 23:59:54 +08:00
|
|
|
llvm::BitstreamCursor &Cursor,
|
2010-08-19 07:56:43 +08:00
|
|
|
const ASTReader::RecordData &Record, unsigned &Idx)
|
2010-10-05 23:59:54 +08:00
|
|
|
: Reader(Reader), F(F), DeclsCursor(Cursor), Record(Record), Idx(Idx) { }
|
2009-04-27 13:14:47 +08:00
|
|
|
|
|
|
|
/// \brief The number of record fields required for the Stmt class
|
|
|
|
/// itself.
|
|
|
|
static const unsigned NumStmtFields = 0;
|
|
|
|
|
|
|
|
/// \brief The number of record fields required for the Expr class
|
|
|
|
/// itself.
|
2011-07-01 09:22:09 +08:00
|
|
|
static const unsigned NumExprFields = NumStmtFields + 7;
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
/// \brief Read and initialize a ExplicitTemplateArgumentList structure.
|
|
|
|
void ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
|
|
|
|
unsigned NumTemplateArgs);
|
2010-06-28 17:31:48 +08:00
|
|
|
/// \brief Read and initialize a ExplicitTemplateArgumentList structure.
|
2011-09-23 04:07:03 +08:00
|
|
|
void ReadExplicitTemplateArgumentList(ASTTemplateArgumentListInfo &ArgList,
|
2010-06-29 06:28:35 +08:00
|
|
|
unsigned NumTemplateArgs);
|
|
|
|
|
|
|
|
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 13:14:47 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::
|
2012-01-27 17:46:47 +08:00
|
|
|
ReadTemplateKWAndArgsInfo(ASTTemplateKWAndArgsInfo &Args,
|
|
|
|
unsigned NumTemplateArgs) {
|
|
|
|
SourceLocation TemplateKWLoc = ReadSourceLocation(Record, Idx);
|
2010-06-28 17:31:48 +08:00
|
|
|
TemplateArgumentListInfo ArgInfo;
|
2010-10-05 23:59:54 +08:00
|
|
|
ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx));
|
2010-06-28 17:31:48 +08:00
|
|
|
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
2010-07-23 06:43:28 +08:00
|
|
|
ArgInfo.addArgument(
|
2010-10-05 23:59:54 +08:00
|
|
|
Reader.ReadTemplateArgumentLoc(F, Record, Idx));
|
2012-01-27 17:46:47 +08:00
|
|
|
Args.initializeFrom(TemplateKWLoc, ArgInfo);
|
2010-06-28 17:31:48 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitStmt(Stmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
assert(Idx == NumStmtFields && "Incorrect statement field count");
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitNullStmt(NullStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setSemiLoc(ReadSourceLocation(Record, Idx));
|
2011-09-02 05:53:45 +08:00
|
|
|
S->HasLeadingEmptyMacro = Record[Idx++];
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Stmt *, 16> Stmts;
|
2009-04-27 13:14:47 +08:00
|
|
|
unsigned NumStmts = Record[Idx++];
|
2010-06-29 06:28:35 +08:00
|
|
|
while (NumStmts--)
|
2010-06-30 06:46:25 +08:00
|
|
|
Stmts.push_back(Reader.ReadSubStmt());
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setStmts(Reader.getContext(), Stmts.data(), Stmts.size());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setLBracLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRBracLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitSwitchCase(SwitchCase *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
Reader.RecordSwitchCaseID(S, Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitSwitchCase(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setLHS(Reader.ReadSubExpr());
|
|
|
|
S->setRHS(Reader.ReadSubExpr());
|
|
|
|
S->setSubStmt(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setCaseLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setEllipsisLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setColonLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitSwitchCase(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setSubStmt(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setDefaultLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setColonLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitLabelStmt(LabelStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2011-07-22 06:35:25 +08:00
|
|
|
LabelDecl *LD = ReadDeclAs<LabelDecl>(Record, Idx);
|
2011-02-17 15:39:24 +08:00
|
|
|
LD->setStmt(S);
|
|
|
|
S->setDecl(LD);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setSubStmt(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setIdentLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitIfStmt(IfStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setConditionVariable(Reader.getContext(),
|
2011-07-22 06:35:25 +08:00
|
|
|
ReadDeclAs<VarDecl>(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setCond(Reader.ReadSubExpr());
|
|
|
|
S->setThen(Reader.ReadSubStmt());
|
|
|
|
S->setElse(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setIfLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setElseLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setConditionVariable(Reader.getContext(),
|
2011-07-22 06:35:25 +08:00
|
|
|
ReadDeclAs<VarDecl>(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setCond(Reader.ReadSubExpr());
|
|
|
|
S->setBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setSwitchLoc(ReadSourceLocation(Record, Idx));
|
2010-09-09 08:05:53 +08:00
|
|
|
if (Record[Idx++])
|
|
|
|
S->setAllEnumCasesCovered();
|
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
SwitchCase *PrevSC = 0;
|
|
|
|
for (unsigned N = Record.size(); Idx != N; ++Idx) {
|
|
|
|
SwitchCase *SC = Reader.getSwitchCaseWithID(Record[Idx]);
|
|
|
|
if (PrevSC)
|
|
|
|
PrevSC->setNextSwitchCase(SC);
|
|
|
|
else
|
|
|
|
S->setSwitchCaseList(SC);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
PrevSC = SC;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setConditionVariable(Reader.getContext(),
|
2011-07-22 06:35:25 +08:00
|
|
|
ReadDeclAs<VarDecl>(Record, Idx));
|
|
|
|
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setCond(Reader.ReadSubExpr());
|
|
|
|
S->setBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setWhileLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitDoStmt(DoStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setCond(Reader.ReadSubExpr());
|
|
|
|
S->setBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setDoLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setWhileLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitForStmt(ForStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setInit(Reader.ReadSubStmt());
|
|
|
|
S->setCond(Reader.ReadSubExpr());
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setConditionVariable(Reader.getContext(),
|
2011-07-22 06:35:25 +08:00
|
|
|
ReadDeclAs<VarDecl>(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setInc(Reader.ReadSubExpr());
|
|
|
|
S->setBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setForLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setLParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitGotoStmt(GotoStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2011-07-22 06:35:25 +08:00
|
|
|
S->setLabel(ReadDeclAs<LabelDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setGotoLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setLabelLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setGotoLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setStarLoc(ReadSourceLocation(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setTarget(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitContinueStmt(ContinueStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setContinueLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitBreakStmt(BreakStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setBreakLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setRetValue(Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setReturnLoc(ReadSourceLocation(Record, Idx));
|
2011-07-22 06:35:25 +08:00
|
|
|
S->setNRVOCandidate(ReadDeclAs<VarDecl>(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setStartLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setEndLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
|
|
|
|
if (Idx + 1 == Record.size()) {
|
|
|
|
// Single declaration
|
2011-07-22 06:35:25 +08:00
|
|
|
S->setDeclGroup(DeclGroupRef(ReadDecl(Record, Idx)));
|
2009-04-27 13:14:47 +08:00
|
|
|
} else {
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Decl *, 16> Decls;
|
2011-07-22 06:35:25 +08:00
|
|
|
Decls.reserve(Record.size() - Idx);
|
|
|
|
for (unsigned N = Record.size(); Idx != N; )
|
|
|
|
Decls.push_back(ReadDecl(Record, Idx));
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setDeclGroup(DeclGroupRef(DeclGroup::Create(Reader.getContext(),
|
2009-05-23 06:45:36 +08:00
|
|
|
Decls.data(),
|
|
|
|
Decls.size())));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitAsmStmt(AsmStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
unsigned NumOutputs = Record[Idx++];
|
|
|
|
unsigned NumInputs = Record[Idx++];
|
|
|
|
unsigned NumClobbers = Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setAsmLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
S->setVolatile(Record[Idx++]);
|
|
|
|
S->setSimple(Record[Idx++]);
|
2010-01-05 06:37:17 +08:00
|
|
|
S->setMSAsm(Record[Idx++]);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
|
2009-04-27 13:14:47 +08:00
|
|
|
|
|
|
|
// Outputs and inputs
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<IdentifierInfo *, 16> Names;
|
|
|
|
SmallVector<StringLiteral*, 16> Constraints;
|
|
|
|
SmallVector<Stmt*, 16> Exprs;
|
2009-04-27 13:14:47 +08:00
|
|
|
for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
|
2011-07-29 04:55:49 +08:00
|
|
|
Names.push_back(Reader.GetIdentifierInfo(F, Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
Constraints.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
|
|
|
|
Exprs.push_back(Reader.ReadSubStmt());
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Constraints
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<StringLiteral*, 16> Clobbers;
|
2009-04-27 13:14:47 +08:00
|
|
|
for (unsigned I = 0; I != NumClobbers; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
Clobbers.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
|
2010-01-31 03:34:25 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
S->setOutputsAndInputsAndClobbers(Reader.getContext(),
|
2010-01-31 04:38:10 +08:00
|
|
|
Names.data(), Constraints.data(),
|
2010-01-31 03:34:25 +08:00
|
|
|
Exprs.data(), NumOutputs, NumInputs,
|
|
|
|
Clobbers.data(), NumClobbers);
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitExpr(Expr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(E);
|
2011-07-22 08:38:23 +08:00
|
|
|
E->setType(Reader.readType(F, Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setTypeDependent(Record[Idx++]);
|
|
|
|
E->setValueDependent(Record[Idx++]);
|
2011-07-01 09:22:09 +08:00
|
|
|
E->setInstantiationDependent(Record[Idx++]);
|
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
|
|
|
E->ExprBits.ContainsUnexpandedParameterPack = Record[Idx++];
|
2010-11-18 14:31:45 +08:00
|
|
|
E->setValueKind(static_cast<ExprValueKind>(Record[Idx++]));
|
|
|
|
E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++]));
|
2009-04-27 13:14:47 +08:00
|
|
|
assert(Idx == NumExprFields && "Incorrect expression field count");
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setIdentType((PredefinedExpr::IdentType)Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2011-05-02 05:29:53 +08:00
|
|
|
E->DeclRefExprBits.HasQualifier = Record[Idx++];
|
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
|
|
|
E->DeclRefExprBits.HasFoundDecl = Record[Idx++];
|
2012-01-27 17:46:47 +08:00
|
|
|
E->DeclRefExprBits.HasTemplateKWAndArgsInfo = Record[Idx++];
|
2011-10-05 15:56:41 +08:00
|
|
|
E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++];
|
2012-03-10 17:33:50 +08:00
|
|
|
E->DeclRefExprBits.RefersToEnclosingLocal = Record[Idx++];
|
2011-03-07 02:19:42 +08:00
|
|
|
unsigned NumTemplateArgs = 0;
|
2012-01-27 17:46:47 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
2011-03-07 02:19:42 +08:00
|
|
|
NumTemplateArgs = Record[Idx++];
|
|
|
|
|
2011-05-02 05:29:53 +08:00
|
|
|
if (E->hasQualifier())
|
2011-05-02 06:14:37 +08:00
|
|
|
E->getInternalQualifierLoc()
|
2011-03-01 05:54:11 +08:00
|
|
|
= Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-07-08 21:09:47 +08:00
|
|
|
|
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->hasFoundDecl())
|
2011-07-22 06:35:25 +08:00
|
|
|
E->getInternalFoundDecl() = ReadDeclAs<NamedDecl>(Record, Idx);
|
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
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
if (E->hasTemplateKWAndArgsInfo())
|
|
|
|
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(),
|
|
|
|
NumTemplateArgs);
|
2010-07-08 21:09:47 +08:00
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setDecl(ReadDeclAs<ValueDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameLoc(E->DNLoc, E->getDecl()->getDeclName(), Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2011-09-10 05:34:22 +08:00
|
|
|
E->setValue(Reader.getContext(), Reader.ReadAPInt(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-09-10 05:34:22 +08:00
|
|
|
E->setValue(Reader.getContext(), Reader.ReadAPFloat(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setExact(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitImaginaryLiteral(ImaginaryLiteral *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitStringLiteral(StringLiteral *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
unsigned Len = Record[Idx++];
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(Record[Idx] == E->getNumConcatenated() &&
|
2009-04-27 13:14:47 +08:00
|
|
|
"Wrong number of concatenated tokens!");
|
|
|
|
++Idx;
|
2011-11-01 10:23:42 +08:00
|
|
|
StringLiteral::StringKind kind =
|
|
|
|
static_cast<StringLiteral::StringKind>(Record[Idx++]);
|
|
|
|
bool isPascal = Record[Idx++];
|
2009-04-27 13:14:47 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
// Read string data
|
2012-02-05 10:13:05 +08:00
|
|
|
SmallString<16> Str(&Record[Idx], &Record[Idx] + Len);
|
2011-11-01 10:23:42 +08:00
|
|
|
E->setString(Reader.getContext(), Str.str(), kind, isPascal);
|
2009-04-27 13:14:47 +08:00
|
|
|
Idx += Len;
|
|
|
|
|
|
|
|
// Read source locations
|
|
|
|
for (unsigned I = 0, N = E->getNumConcatenated(); I != N; ++I)
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setStrTokenLoc(I, ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCharacterLiteral(CharacterLiteral *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
E->setValue(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2011-07-27 13:40:30 +08:00
|
|
|
E->setKind(static_cast<CharacterLiteral::CharacterKind>(Record[Idx++]));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitParenExpr(ParenExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLParen(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParen(ReadSourceLocation(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitParenListExpr(ParenListExpr *E) {
|
2010-06-30 16:49:18 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
unsigned NumExprs = Record[Idx++];
|
2011-09-10 05:34:22 +08:00
|
|
|
E->Exprs = new (Reader.getContext()) Stmt*[NumExprs];
|
2010-06-30 16:49:18 +08:00
|
|
|
for (unsigned i = 0; i != NumExprs; ++i)
|
|
|
|
E->Exprs[i] = Reader.ReadSubStmt();
|
|
|
|
E->NumExprs = NumExprs;
|
2010-10-05 23:59:54 +08:00
|
|
|
E->LParenLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->RParenLoc = ReadSourceLocation(Record, Idx);
|
2010-06-30 16:49:18 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitUnaryOperator(UnaryOperator *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setOpcode((UnaryOperator::Opcode)Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setOperatorLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::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
|
|
|
typedef OffsetOfExpr::OffsetOfNode Node;
|
|
|
|
VisitExpr(E);
|
|
|
|
assert(E->getNumComponents() == Record[Idx]);
|
|
|
|
++Idx;
|
|
|
|
assert(E->getNumExpressions() == Record[Idx]);
|
|
|
|
++Idx;
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setOperatorLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
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->getNumComponents(); I != N; ++I) {
|
|
|
|
Node::Kind Kind = static_cast<Node::Kind>(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation Start = ReadSourceLocation(Record, Idx);
|
|
|
|
SourceLocation End = ReadSourceLocation(Record, Idx);
|
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 (Kind) {
|
|
|
|
case Node::Array:
|
|
|
|
E->setComponent(I, Node(Start, Record[Idx++], End));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Node::Field:
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setComponent(I, Node(Start, ReadDeclAs<FieldDecl>(Record, Idx), End));
|
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
|
|
|
break;
|
|
|
|
|
|
|
|
case Node::Identifier:
|
2011-07-29 04:55:49 +08:00
|
|
|
E->setComponent(I,
|
|
|
|
Node(Start,
|
|
|
|
Reader.GetIdentifierInfo(F, Record, Idx),
|
|
|
|
End));
|
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
|
|
|
break;
|
2010-04-29 08:18:15 +08:00
|
|
|
|
2010-07-30 02:16:10 +08:00
|
|
|
case Node::Base: {
|
2011-09-10 05:34:22 +08:00
|
|
|
CXXBaseSpecifier *Base = new (Reader.getContext()) CXXBaseSpecifier();
|
2010-10-05 23:59:54 +08:00
|
|
|
*Base = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
|
2010-07-30 02:16:10 +08:00
|
|
|
E->setComponent(I, Node(Base));
|
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
|
|
|
}
|
2010-07-30 02:16:10 +08:00
|
|
|
}
|
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-30 06:46:25 +08:00
|
|
|
E->setIndexExpr(I, Reader.ReadSubExpr());
|
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 ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-03-12 03:24:49 +08:00
|
|
|
E->setKind(static_cast<UnaryExprOrTypeTrait>(Record[Idx++]));
|
2009-04-27 13:14:47 +08:00
|
|
|
if (Record[Idx] == 0) {
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setArgument(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
++Idx;
|
|
|
|
} else {
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setArgument(GetTypeSourceInfo(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setOperatorLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setLHS(Reader.ReadSubExpr());
|
|
|
|
E->setRHS(Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setRBracketLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCallExpr(CallExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-09-10 05:34:22 +08:00
|
|
|
E->setNumArgs(Reader.getContext(), Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setCallee(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setArg(I, Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
void ASTStmtReader::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
|
|
|
|
VisitCallExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitMemberExpr(MemberExpr *E) {
|
2010-07-08 21:09:47 +08:00
|
|
|
// Don't call VisitExpr, this is fully initialized at creation.
|
|
|
|
assert(E->getStmtClass() == Stmt::MemberExprClass &&
|
|
|
|
"It's a subclass, we must advance Idx!");
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
|
2009-07-25 01:54:45 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setBase(Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setIsaMemberLoc(ReadSourceLocation(Record, Idx));
|
2009-07-25 01:54:45 +08:00
|
|
|
E->setArrow(Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
void ASTStmtReader::
|
|
|
|
VisitObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->Operand = Reader.ReadSubExpr();
|
|
|
|
E->setShouldCopy(Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
|
|
|
|
VisitExplicitCastExpr(E);
|
|
|
|
E->LParenLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->BridgeKeywordLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->Kind = Record[Idx++];
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCastExpr(CastExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-08-07 14:22:56 +08:00
|
|
|
unsigned NumBaseSpecs = Record[Idx++];
|
|
|
|
assert(NumBaseSpecs == E->path_size());
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(Reader.ReadSubExpr());
|
2009-07-31 08:48:10 +08:00
|
|
|
E->setCastKind((CastExpr::CastKind)Record[Idx++]);
|
2010-08-07 14:22:56 +08:00
|
|
|
CastExpr::path_iterator BaseI = E->path_begin();
|
2010-07-03 07:30:27 +08:00
|
|
|
while (NumBaseSpecs--) {
|
2011-09-10 05:34:22 +08:00
|
|
|
CXXBaseSpecifier *BaseSpec = new (Reader.getContext()) CXXBaseSpecifier;
|
2010-10-05 23:59:54 +08:00
|
|
|
*BaseSpec = Reader.ReadCXXBaseSpecifier(F, Record, Idx);
|
2010-08-07 14:22:56 +08:00
|
|
|
*BaseI++ = BaseSpec;
|
2010-07-03 07:30:27 +08:00
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitBinaryOperator(BinaryOperator *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setLHS(Reader.ReadSubExpr());
|
|
|
|
E->setRHS(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setOpcode((BinaryOperator::Opcode)Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setOperatorLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitBinaryOperator(E);
|
2011-07-22 08:38:23 +08:00
|
|
|
E->setComputationLHSType(Reader.readType(F, Record, Idx));
|
|
|
|
E->setComputationResultType(Reader.readType(F, Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-02-17 18:25:35 +08:00
|
|
|
E->SubExprs[ConditionalOperator::COND] = Reader.ReadSubExpr();
|
|
|
|
E->SubExprs[ConditionalOperator::LHS] = Reader.ReadSubExpr();
|
|
|
|
E->SubExprs[ConditionalOperator::RHS] = Reader.ReadSubExpr();
|
|
|
|
E->QuestionLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->ColonLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ASTStmtReader::VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->OpaqueValue = cast<OpaqueValueExpr>(Reader.ReadSubExpr());
|
|
|
|
E->SubExprs[BinaryConditionalOperator::COMMON] = Reader.ReadSubExpr();
|
|
|
|
E->SubExprs[BinaryConditionalOperator::COND] = Reader.ReadSubExpr();
|
|
|
|
E->SubExprs[BinaryConditionalOperator::LHS] = Reader.ReadSubExpr();
|
|
|
|
E->SubExprs[BinaryConditionalOperator::RHS] = Reader.ReadSubExpr();
|
|
|
|
E->QuestionLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->ColonLoc = ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitCastExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitCastExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setTypeInfoAsWritten(GetTypeSourceInfo(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCStyleCastExpr(CStyleCastExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setInitializer(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setFileScope(Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setBase(Reader.ReadSubExpr());
|
2011-07-29 04:55:49 +08:00
|
|
|
E->setAccessor(Reader.GetIdentifierInfo(F, Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setAccessorLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSyntacticForm(cast_or_null<InitListExpr>(Reader.ReadSubStmt()));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLBraceLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRBraceLoc(ReadSourceLocation(Record, Idx));
|
2011-04-22 13:29:30 +08:00
|
|
|
bool isArrayFiller = Record[Idx++];
|
|
|
|
Expr *filler = 0;
|
|
|
|
if (isArrayFiller) {
|
|
|
|
filler = Reader.ReadSubExpr();
|
|
|
|
E->ArrayFillerOrUnionFieldInit = filler;
|
|
|
|
} else
|
2011-07-22 06:35:25 +08:00
|
|
|
E->ArrayFillerOrUnionFieldInit = ReadDeclAs<FieldDecl>(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
E->sawArrayRangeDesignator(Record[Idx++]);
|
2012-02-27 21:20:39 +08:00
|
|
|
E->setInitializesStdInitializerList(Record[Idx++]);
|
2011-04-22 13:29:30 +08:00
|
|
|
unsigned NumInits = Record[Idx++];
|
2011-09-10 05:34:22 +08:00
|
|
|
E->reserveInits(Reader.getContext(), NumInits);
|
2011-04-22 13:29:30 +08:00
|
|
|
if (isArrayFiller) {
|
|
|
|
for (unsigned I = 0; I != NumInits; ++I) {
|
|
|
|
Expr *init = Reader.ReadSubExpr();
|
2011-09-10 05:34:22 +08:00
|
|
|
E->updateInit(Reader.getContext(), I, init ? init : filler);
|
2011-04-22 13:29:30 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (unsigned I = 0; I != NumInits; ++I)
|
2011-09-10 05:34:22 +08:00
|
|
|
E->updateInit(Reader.getContext(), I, Reader.ReadSubExpr());
|
2011-04-22 13:29:30 +08:00
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
typedef DesignatedInitExpr::Designator Designator;
|
|
|
|
|
|
|
|
VisitExpr(E);
|
|
|
|
unsigned NumSubExprs = Record[Idx++];
|
|
|
|
assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
|
|
|
|
for (unsigned I = 0; I != NumSubExprs; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(I, Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setEqualOrColonLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setGNUSyntax(Record[Idx++]);
|
|
|
|
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Designator, 4> Designators;
|
2009-04-27 13:14:47 +08:00
|
|
|
while (Idx < Record.size()) {
|
2010-08-19 07:57:32 +08:00
|
|
|
switch ((DesignatorTypes)Record[Idx++]) {
|
|
|
|
case DESIG_FIELD_DECL: {
|
2011-07-22 06:35:25 +08:00
|
|
|
FieldDecl *Field = ReadDeclAs<FieldDecl>(Record, Idx);
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation DotLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation FieldLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-09-09 23:08:12 +08:00
|
|
|
Designators.push_back(Designator(Field->getIdentifier(), DotLoc,
|
2009-04-27 13:14:47 +08:00
|
|
|
FieldLoc));
|
|
|
|
Designators.back().setField(Field);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case DESIG_FIELD_NAME: {
|
2011-07-29 04:55:49 +08:00
|
|
|
const IdentifierInfo *Name = Reader.GetIdentifierInfo(F, Record, Idx);
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation DotLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation FieldLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
Designators.push_back(Designator(Name, DotLoc, FieldLoc));
|
|
|
|
break;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case DESIG_ARRAY: {
|
2009-04-27 13:14:47 +08:00
|
|
|
unsigned Index = Record[Idx++];
|
|
|
|
SourceLocation LBracketLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
SourceLocation RBracketLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case DESIG_ARRAY_RANGE: {
|
2009-04-27 13:14:47 +08:00
|
|
|
unsigned Index = Record[Idx++];
|
|
|
|
SourceLocation LBracketLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
SourceLocation EllipsisLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
SourceLocation RBracketLoc
|
2010-10-05 23:59:54 +08:00
|
|
|
= ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
|
|
|
|
RBracketLoc));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-09-10 05:34:22 +08:00
|
|
|
E->setDesignators(Reader.getContext(),
|
2010-01-07 07:17:19 +08:00
|
|
|
Designators.data(), Designators.size());
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitVAArgExpr(VAArgExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setWrittenTypeInfo(GetTypeSourceInfo(Record, Idx));
|
|
|
|
E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitAddrLabelExpr(AddrLabelExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setAmpAmpLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setLabelLoc(ReadSourceLocation(Record, Idx));
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setLabel(ReadDeclAs<LabelDecl>(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitStmtExpr(StmtExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubStmt(cast_or_null<CompoundStmt>(Reader.ReadSubStmt()));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setCond(Reader.ReadSubExpr());
|
|
|
|
E->setLHS(Reader.ReadSubExpr());
|
|
|
|
E->setRHS(Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitGNUNullExpr(GNUNullExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setTokenLocation(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<Expr *, 16> Exprs;
|
2009-04-27 13:14:47 +08:00
|
|
|
unsigned NumExprs = Record[Idx++];
|
2010-06-29 06:28:35 +08:00
|
|
|
while (NumExprs--)
|
2010-06-30 06:46:25 +08:00
|
|
|
Exprs.push_back(Reader.ReadSubExpr());
|
2011-09-10 05:34:22 +08:00
|
|
|
E->setExprs(Reader.getContext(), Exprs.data(), Exprs.size());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitBlockExpr(BlockExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setBlockDecl(ReadDeclAs<BlockDecl>(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->NumAssocs = Record[Idx++];
|
2011-09-10 05:34:22 +08:00
|
|
|
E->AssocTypes = new (Reader.getContext()) TypeSourceInfo*[E->NumAssocs];
|
2011-04-15 08:35:48 +08:00
|
|
|
E->SubExprs =
|
2011-09-10 05:34:22 +08:00
|
|
|
new(Reader.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
|
2011-04-15 08:35:48 +08:00
|
|
|
|
|
|
|
E->SubExprs[GenericSelectionExpr::CONTROLLING] = Reader.ReadSubExpr();
|
|
|
|
for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
|
|
|
|
E->AssocTypes[I] = GetTypeSourceInfo(Record, Idx);
|
|
|
|
E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Reader.ReadSubExpr();
|
|
|
|
}
|
|
|
|
E->ResultIndex = Record[Idx++];
|
|
|
|
|
|
|
|
E->GenericLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->DefaultLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->RParenLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
unsigned numSemanticExprs = Record[Idx++];
|
|
|
|
assert(numSemanticExprs + 1 == E->PseudoObjectExprBits.NumSubExprs);
|
|
|
|
E->PseudoObjectExprBits.ResultIndex = Record[Idx++];
|
|
|
|
|
|
|
|
// Read the syntactic expression.
|
|
|
|
E->getSubExprsBuffer()[0] = Reader.ReadSubExpr();
|
|
|
|
|
|
|
|
// Read all the semantic expressions.
|
|
|
|
for (unsigned i = 0; i != numSemanticExprs; ++i) {
|
|
|
|
Expr *subExpr = Reader.ReadSubExpr();
|
|
|
|
E->getSubExprsBuffer()[i+1] = subExpr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-11 10:20:01 +08:00
|
|
|
void ASTStmtReader::VisitAtomicExpr(AtomicExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->setOp(AtomicExpr::AtomicOp(Record[Idx++]));
|
|
|
|
E->setPtr(Reader.ReadSubExpr());
|
|
|
|
E->setOrder(Reader.ReadSubExpr());
|
|
|
|
E->setNumSubExprs(2);
|
|
|
|
if (E->getOp() != AtomicExpr::Load) {
|
|
|
|
E->setVal1(Reader.ReadSubExpr());
|
|
|
|
E->setNumSubExprs(3);
|
|
|
|
}
|
|
|
|
if (E->isCmpXChg()) {
|
|
|
|
E->setOrderFail(Reader.ReadSubExpr());
|
|
|
|
E->setVal2(Reader.ReadSubExpr());
|
|
|
|
E->setNumSubExprs(5);
|
|
|
|
}
|
|
|
|
E->setBuiltinLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Objective-C Expressions and Statements
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setString(cast<StringLiteral>(Reader.ReadSubStmt()));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setAtLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void ASTStmtReader::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
// could be one of several IntegerLiteral, FloatLiteral, etc.
|
|
|
|
E->Number = Reader.ReadSubStmt();
|
|
|
|
E->ObjCNumericLiteralMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
|
|
E->AtLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
unsigned NumElements = Record[Idx++];
|
|
|
|
assert(NumElements == E->getNumElements() && "Wrong number of elements");
|
|
|
|
Expr **Elements = E->getElements();
|
|
|
|
for (unsigned I = 0, N = NumElements; I != N; ++I)
|
|
|
|
Elements[I] = Reader.ReadSubExpr();
|
|
|
|
E->ArrayWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
|
|
E->Range = ReadSourceRange(Record, Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
unsigned NumElements = Record[Idx++];
|
|
|
|
assert(NumElements == E->getNumElements() && "Wrong number of elements");
|
|
|
|
bool HasPackExpansions = Record[Idx++];
|
|
|
|
assert(HasPackExpansions == E->HasPackExpansions &&"Pack expansion mismatch");
|
|
|
|
ObjCDictionaryLiteral::KeyValuePair *KeyValues = E->getKeyValues();
|
|
|
|
ObjCDictionaryLiteral::ExpansionData *Expansions = E->getExpansionData();
|
|
|
|
for (unsigned I = 0; I != NumElements; ++I) {
|
|
|
|
KeyValues[I].Key = Reader.ReadSubExpr();
|
|
|
|
KeyValues[I].Value = Reader.ReadSubExpr();
|
|
|
|
if (HasPackExpansions) {
|
|
|
|
Expansions[I].EllipsisLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
Expansions[I].NumExpansionsPlusOne = Record[Idx++];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
E->DictWithObjectsMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
|
|
E->Range = ReadSourceRange(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setEncodedTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
|
|
|
|
E->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-07-29 05:16:51 +08:00
|
|
|
E->setSelector(Reader.ReadSelector(F, Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setProtocol(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setDecl(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setBase(Reader.ReadSubExpr());
|
2009-04-27 13:14:47 +08:00
|
|
|
E->setIsArrow(Record[Idx++]);
|
|
|
|
E->setIsFreeIvar(Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
2010-12-02 09:19:52 +08:00
|
|
|
bool Implicit = Record[Idx++] != 0;
|
|
|
|
if (Implicit) {
|
2011-07-22 06:35:25 +08:00
|
|
|
ObjCMethodDecl *Getter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
|
|
ObjCMethodDecl *Setter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
2010-12-02 09:19:52 +08:00
|
|
|
E->setImplicitProperty(Getter, Setter);
|
|
|
|
} else {
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
|
2010-10-15 00:04:05 +08:00
|
|
|
}
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2010-12-02 09:19:52 +08:00
|
|
|
E->setReceiverLocation(ReadSourceLocation(Record, Idx));
|
|
|
|
switch (Record[Idx++]) {
|
|
|
|
case 0:
|
|
|
|
E->setBase(Reader.ReadSubExpr());
|
|
|
|
break;
|
|
|
|
case 1:
|
2011-07-22 08:38:23 +08:00
|
|
|
E->setSuperReceiver(Reader.readType(F, Record, Idx));
|
2010-12-02 09:19:52 +08:00
|
|
|
break;
|
|
|
|
case 2:
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setClassReceiver(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
|
2010-12-02 09:19:52 +08:00
|
|
|
break;
|
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void ASTStmtReader::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->setRBracket(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setBaseExpr(Reader.ReadSubExpr());
|
|
|
|
E->setKeyExpr(Reader.ReadSubExpr());
|
|
|
|
E->GetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
|
|
E->SetAtIndexMethodDecl = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitExpr(E);
|
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
|
|
|
assert(Record[Idx] == E->getNumArgs());
|
|
|
|
++Idx;
|
2011-10-03 14:36:51 +08:00
|
|
|
unsigned NumStoredSelLocs = Record[Idx++];
|
|
|
|
E->SelLocsKind = Record[Idx++];
|
2011-06-16 07:02:42 +08:00
|
|
|
E->setDelegateInitCall(Record[Idx++]);
|
2012-01-12 10:34:39 +08:00
|
|
|
E->IsImplicit = Record[Idx++];
|
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
|
|
|
ObjCMessageExpr::ReceiverKind Kind
|
|
|
|
= static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
|
|
|
|
switch (Kind) {
|
|
|
|
case ObjCMessageExpr::Instance:
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setInstanceReceiver(Reader.ReadSubExpr());
|
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:
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setClassReceiver(GetTypeSourceInfo(Record, Idx));
|
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::SuperClass:
|
|
|
|
case ObjCMessageExpr::SuperInstance: {
|
2011-07-22 08:38:23 +08:00
|
|
|
QualType T = Reader.readType(F, Record, Idx);
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation SuperLoc = ReadSourceLocation(Record, Idx);
|
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
|
|
|
E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
|
|
|
|
break;
|
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
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
|
|
|
assert(Kind == E->getReceiverKind());
|
|
|
|
|
|
|
|
if (Record[Idx++])
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setMethodDecl(ReadDeclAs<ObjCMethodDecl>(Record, Idx));
|
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
|
|
|
else
|
2011-07-29 05:16:51 +08:00
|
|
|
E->setSelector(Reader.ReadSelector(F, Record, Idx));
|
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
|
|
|
|
2010-12-11 04:08:27 +08:00
|
|
|
E->LBracLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->RBracLoc = ReadSourceLocation(Record, Idx);
|
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
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setArg(I, Reader.ReadSubExpr());
|
2011-10-03 14:36:51 +08:00
|
|
|
|
|
|
|
SourceLocation *Locs = E->getStoredSelLocs();
|
|
|
|
for (unsigned I = 0; I != NumStoredSelLocs; ++I)
|
|
|
|
Locs[I] = ReadSourceLocation(Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setElement(Reader.ReadSubStmt());
|
|
|
|
S->setCollection(Reader.ReadSubExpr());
|
|
|
|
S->setBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setForLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setCatchBody(Reader.ReadSubStmt());
|
2011-07-22 06:35:25 +08:00
|
|
|
S->setCatchParamDecl(ReadDeclAs<VarDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setAtCatchLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setFinallyBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setAtFinallyLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
void ASTStmtReader::VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
S->setSubStmt(Reader.ReadSubStmt());
|
|
|
|
S->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-04-24 06:50:49 +08:00
|
|
|
assert(Record[Idx] == S->getNumCatchStmts());
|
|
|
|
++Idx;
|
|
|
|
bool HasFinally = Record[Idx++];
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setTryBody(Reader.ReadSubStmt());
|
2010-06-29 06:28:35 +08:00
|
|
|
for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(Reader.ReadSubStmt()));
|
2010-04-24 06:50:49 +08:00
|
|
|
|
|
|
|
if (HasFinally)
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setFinallyStmt(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setAtTryLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setSynchExpr(Reader.ReadSubStmt());
|
|
|
|
S->setSynchBody(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setAtSynchronizedLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
|
2009-04-27 13:14:47 +08:00
|
|
|
VisitStmt(S);
|
2010-06-30 06:46:25 +08:00
|
|
|
S->setThrowExpr(Reader.ReadSubStmt());
|
2010-10-05 23:59:54 +08:00
|
|
|
S->setThrowLoc(ReadSourceLocation(Record, Idx));
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 04:05:56 +08:00
|
|
|
void ASTStmtReader::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->setValue(Record[Idx++]);
|
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
|
|
|
}
|
|
|
|
|
2009-07-14 11:19:21 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// C++ Expressions and Statements
|
2010-07-23 00:03:56 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXCatchStmt(CXXCatchStmt *S) {
|
2010-07-23 00:03:56 +08:00
|
|
|
VisitStmt(S);
|
2010-10-05 23:59:54 +08:00
|
|
|
S->CatchLoc = ReadSourceLocation(Record, Idx);
|
2011-07-22 06:35:25 +08:00
|
|
|
S->ExceptionDecl = ReadDeclAs<VarDecl>(Record, Idx);
|
2010-07-23 00:03:56 +08:00
|
|
|
S->HandlerBlock = Reader.ReadSubStmt();
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXTryStmt(CXXTryStmt *S) {
|
2010-07-23 00:03:56 +08:00
|
|
|
VisitStmt(S);
|
|
|
|
assert(Record[Idx] == S->getNumHandlers() && "NumStmtFields is wrong ?");
|
|
|
|
++Idx;
|
2010-10-05 23:59:54 +08:00
|
|
|
S->TryLoc = ReadSourceLocation(Record, Idx);
|
2010-07-23 00:03:56 +08:00
|
|
|
S->getStmts()[0] = Reader.ReadSubStmt();
|
|
|
|
for (unsigned i = 0, e = S->getNumHandlers(); i != e; ++i)
|
|
|
|
S->getStmts()[i + 1] = Reader.ReadSubStmt();
|
|
|
|
}
|
2009-07-14 11:19:21 +08:00
|
|
|
|
2011-04-15 06:09:26 +08:00
|
|
|
void ASTStmtReader::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
S->setForLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setColonLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
S->setRangeStmt(Reader.ReadSubStmt());
|
|
|
|
S->setBeginEndStmt(Reader.ReadSubStmt());
|
|
|
|
S->setCond(Reader.ReadSubExpr());
|
|
|
|
S->setInc(Reader.ReadSubExpr());
|
|
|
|
S->setLoopVarStmt(Reader.ReadSubStmt());
|
|
|
|
S->setBody(Reader.ReadSubStmt());
|
|
|
|
}
|
|
|
|
|
2011-10-25 09:33:02 +08:00
|
|
|
void ASTStmtReader::VisitMSDependentExistsStmt(MSDependentExistsStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
S->KeywordLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
S->IsIfExists = Record[Idx++];
|
|
|
|
S->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
|
|
|
ReadDeclarationNameInfo(S->NameInfo, Record, Idx);
|
|
|
|
S->SubStmt = Reader.ReadSubStmt();
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
|
2010-06-29 06:28:35 +08:00
|
|
|
VisitCallExpr(E);
|
2009-07-14 11:19:21 +08:00
|
|
|
E->setOperator((OverloadedOperatorKind)Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
2009-09-10 07:08:42 +08:00
|
|
|
VisitExpr(E);
|
2010-07-10 19:46:15 +08:00
|
|
|
E->NumArgs = Record[Idx++];
|
|
|
|
if (E->NumArgs)
|
2011-09-10 05:34:22 +08:00
|
|
|
E->Args = new (Reader.getContext()) Stmt*[E->NumArgs];
|
2010-06-24 16:57:09 +08:00
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setArg(I, Reader.ReadSubExpr());
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2011-10-05 15:56:41 +08:00
|
|
|
E->setElidable(Record[Idx++]);
|
|
|
|
E->setHadMultipleCandidates(Record[Idx++]);
|
2009-12-17 02:50:27 +08:00
|
|
|
E->setRequiresZeroInitialization(Record[Idx++]);
|
2010-05-15 08:13:29 +08:00
|
|
|
E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
|
2010-10-25 16:47:36 +08:00
|
|
|
E->ParenRange = ReadSourceRange(Record, Idx);
|
2009-09-10 07:08:42 +08:00
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
|
2010-07-10 19:46:15 +08:00
|
|
|
VisitCXXConstructExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->Type = GetTypeSourceInfo(Record, Idx);
|
2010-07-10 19:46:15 +08:00
|
|
|
}
|
|
|
|
|
2012-02-07 18:09:13 +08:00
|
|
|
void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) {
|
|
|
|
VisitExpr(E);
|
2012-02-15 01:54:36 +08:00
|
|
|
unsigned NumCaptures = Record[Idx++];
|
|
|
|
assert(NumCaptures == E->NumCaptures);(void)NumCaptures;
|
|
|
|
unsigned NumArrayIndexVars = Record[Idx++];
|
|
|
|
E->IntroducerRange = ReadSourceRange(Record, Idx);
|
|
|
|
E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record[Idx++]);
|
|
|
|
E->ExplicitParams = Record[Idx++];
|
|
|
|
E->ExplicitResultType = Record[Idx++];
|
|
|
|
E->ClosingBrace = ReadSourceLocation(Record, Idx);
|
|
|
|
|
|
|
|
// Read capture initializers.
|
|
|
|
for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(),
|
|
|
|
CEnd = E->capture_init_end();
|
|
|
|
C != CEnd; ++C)
|
|
|
|
*C = Reader.ReadSubExpr();
|
|
|
|
|
|
|
|
// Read array capture index variables.
|
|
|
|
if (NumArrayIndexVars > 0) {
|
|
|
|
unsigned *ArrayIndexStarts = E->getArrayIndexStarts();
|
|
|
|
for (unsigned I = 0; I != NumCaptures + 1; ++I)
|
|
|
|
ArrayIndexStarts[I] = Record[Idx++];
|
|
|
|
|
|
|
|
VarDecl **ArrayIndexVars = E->getArrayIndexVars();
|
|
|
|
for (unsigned I = 0; I != NumArrayIndexVars; ++I)
|
|
|
|
ArrayIndexVars[I] = ReadDeclAs<VarDecl>(Record, Idx);
|
|
|
|
}
|
2012-02-07 18:09:13 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
|
2010-06-29 06:28:35 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2011-01-13 06:41:29 +08:00
|
|
|
SourceRange R = ReadSourceRange(Record, Idx);
|
|
|
|
E->Loc = R.getBegin();
|
|
|
|
E->RParenLoc = R.getEnd();
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXStaticCastExpr(CXXStaticCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
return VisitCXXNamedCastExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
return VisitCXXNamedCastExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
return VisitCXXNamedCastExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXConstCastExpr(CXXConstCastExpr *E) {
|
2010-01-17 05:21:01 +08:00
|
|
|
return VisitCXXNamedCastExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
|
2010-06-29 06:28:35 +08:00
|
|
|
VisitExplicitCastExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setTypeBeginLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2010-01-17 05:21:01 +08:00
|
|
|
}
|
|
|
|
|
2012-03-07 16:35:16 +08:00
|
|
|
void ASTStmtReader::VisitUserDefinedLiteral(UserDefinedLiteral *E) {
|
|
|
|
VisitCallExpr(E);
|
|
|
|
E->UDSuffixLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
|
2010-02-07 14:32:43 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
E->setValue(Record[Idx++]);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2010-02-07 14:32:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
|
2010-02-07 14:32:43 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2010-02-07 14:32:43 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
|
2010-05-09 14:03:39 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setSourceRange(ReadSourceRange(Record, Idx));
|
2010-05-09 14:03:39 +08:00
|
|
|
if (E->isTypeOperand()) { // typeid(int)
|
2010-07-23 06:43:28 +08:00
|
|
|
E->setTypeOperandSourceInfo(
|
2010-10-05 23:59:54 +08:00
|
|
|
GetTypeSourceInfo(Record, Idx));
|
2010-06-29 06:28:35 +08:00
|
|
|
return;
|
2010-05-09 14:03:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// typeid(42+2)
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setExprOperand(Reader.ReadSubExpr());
|
2010-05-09 14:03:39 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXThisExpr(CXXThisExpr *E) {
|
2010-05-09 14:15:05 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setLocation(ReadSourceLocation(Record, Idx));
|
2010-05-09 14:15:05 +08:00
|
|
|
E->setImplicit(Record[Idx++]);
|
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXThrowExpr(CXXThrowExpr *E) {
|
2010-05-09 14:15:05 +08:00
|
|
|
VisitExpr(E);
|
2011-07-07 06:04:06 +08:00
|
|
|
E->ThrowLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->Op = Reader.ReadSubExpr();
|
|
|
|
E->IsThrownVariableInScope = Record[Idx++];
|
2010-05-09 14:15:05 +08:00
|
|
|
}
|
2010-05-09 14:03:39 +08:00
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
|
2010-05-09 14:40:08 +08:00
|
|
|
VisitExpr(E);
|
2010-07-03 07:30:15 +08:00
|
|
|
|
2011-09-24 06:07:41 +08:00
|
|
|
assert((bool)Record[Idx] == E->Param.getInt() && "We messed up at creation ?");
|
2010-07-03 07:30:15 +08:00
|
|
|
++Idx; // HasOtherExprStored and SubExpr was handled during creation.
|
2011-07-22 06:35:25 +08:00
|
|
|
E->Param.setPointer(ReadDeclAs<ParmVarDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->Loc = ReadSourceLocation(Record, Idx);
|
2010-05-10 08:25:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
|
2010-05-10 08:25:06 +08:00
|
|
|
VisitExpr(E);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setTemporary(Reader.ReadCXXTemporary(F, Record, Idx));
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setSubExpr(Reader.ReadSubExpr());
|
2010-05-10 08:25:06 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
|
2010-05-10 09:22:27 +08:00
|
|
|
VisitExpr(E);
|
2010-10-05 23:59:54 +08:00
|
|
|
E->TypeInfo = GetTypeSourceInfo(Record, Idx);
|
|
|
|
E->RParenLoc = ReadSourceLocation(Record, Idx);
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
|
2010-05-10 09:22:27 +08:00
|
|
|
VisitExpr(E);
|
2011-01-27 17:37:56 +08:00
|
|
|
E->GlobalNew = Record[Idx++];
|
2012-02-16 19:35:52 +08:00
|
|
|
bool isArray = Record[Idx++];
|
2012-02-16 20:22:20 +08:00
|
|
|
E->UsualArrayDeleteWantsSize = Record[Idx++];
|
2010-05-10 09:22:27 +08:00
|
|
|
unsigned NumPlacementArgs = Record[Idx++];
|
2012-02-16 20:22:20 +08:00
|
|
|
E->StoredInitializationStyle = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
|
|
|
|
E->setOperatorDelete(ReadDeclAs<FunctionDecl>(Record, Idx));
|
2010-10-05 23:59:54 +08:00
|
|
|
E->AllocatedTypeInfo = GetTypeSourceInfo(Record, Idx);
|
2012-02-21 00:12:14 +08:00
|
|
|
E->TypeIdParens = ReadSourceRange(Record, Idx);
|
2010-10-25 16:47:36 +08:00
|
|
|
E->StartLoc = ReadSourceLocation(Record, Idx);
|
2012-02-21 00:12:14 +08:00
|
|
|
E->DirectInitRange = ReadSourceRange(Record, Idx);
|
2010-10-25 16:47:36 +08:00
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
E->AllocateArgsArray(Reader.getContext(), isArray, NumPlacementArgs,
|
2012-02-16 20:22:20 +08:00
|
|
|
E->StoredInitializationStyle != 0);
|
2010-05-10 09:22:27 +08:00
|
|
|
|
|
|
|
// Install all the subexpressions.
|
|
|
|
for (CXXNewExpr::raw_arg_iterator I = E->raw_arg_begin(),e = E->raw_arg_end();
|
|
|
|
I != e; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
*I = Reader.ReadSubStmt();
|
2010-05-10 09:22:27 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
|
2010-06-23 01:07:59 +08:00
|
|
|
VisitExpr(E);
|
2010-09-14 04:15:40 +08:00
|
|
|
E->GlobalDelete = Record[Idx++];
|
|
|
|
E->ArrayForm = Record[Idx++];
|
2010-09-14 04:15:54 +08:00
|
|
|
E->ArrayFormAsWritten = Record[Idx++];
|
2011-01-27 17:37:56 +08:00
|
|
|
E->UsualArrayDeleteWantsSize = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
E->OperatorDelete = ReadDeclAs<FunctionDecl>(Record, Idx);
|
2010-09-14 04:15:40 +08:00
|
|
|
E->Argument = Reader.ReadSubExpr();
|
2010-10-05 23:59:54 +08:00
|
|
|
E->Loc = ReadSourceLocation(Record, Idx);
|
2010-06-23 01:07:59 +08:00
|
|
|
}
|
2010-05-10 08:25:06 +08:00
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
|
2010-06-28 17:32:03 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
|
2011-02-26 02:19:59 +08:00
|
|
|
E->Base = Reader.ReadSubExpr();
|
|
|
|
E->IsArrow = Record[Idx++];
|
|
|
|
E->OperatorLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
|
|
|
E->ScopeType = GetTypeSourceInfo(Record, Idx);
|
|
|
|
E->ColonColonLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->TildeLoc = ReadSourceLocation(Record, Idx);
|
2010-06-28 17:32:03 +08:00
|
|
|
|
2011-07-29 04:55:49 +08:00
|
|
|
IdentifierInfo *II = Reader.GetIdentifierInfo(F, Record, Idx);
|
2010-06-28 17:32:03 +08:00
|
|
|
if (II)
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setDestroyedType(II, ReadSourceLocation(Record, Idx));
|
2010-06-28 17:32:03 +08:00
|
|
|
else
|
2010-10-05 23:59:54 +08:00
|
|
|
E->setDestroyedType(GetTypeSourceInfo(Record, Idx));
|
2010-06-28 17:32:03 +08:00
|
|
|
}
|
|
|
|
|
2010-12-06 16:20:24 +08:00
|
|
|
void ASTStmtReader::VisitExprWithCleanups(ExprWithCleanups *E) {
|
2010-05-10 08:25:06 +08:00
|
|
|
VisitExpr(E);
|
2011-11-10 13:35:25 +08:00
|
|
|
|
|
|
|
unsigned NumObjects = Record[Idx++];
|
|
|
|
assert(NumObjects == E->getNumObjects());
|
|
|
|
for (unsigned i = 0; i != NumObjects; ++i)
|
|
|
|
E->getObjectsBuffer()[i] = ReadDeclAs<BlockDecl>(Record, Idx);
|
|
|
|
|
|
|
|
E->SubExpr = Reader.ReadSubExpr();
|
2010-05-09 14:40:08 +08:00
|
|
|
}
|
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
void
|
2010-08-19 07:56:52 +08:00
|
|
|
ASTStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){
|
2010-06-24 16:57:31 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
if (Record[Idx++]) // HasTemplateKWAndArgsInfo
|
|
|
|
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(),
|
|
|
|
/*NumTemplateArgs=*/Record[Idx++]);
|
2010-06-24 16:57:31 +08:00
|
|
|
|
2011-03-01 02:50:33 +08:00
|
|
|
E->Base = Reader.ReadSubExpr();
|
2011-07-22 08:38:23 +08:00
|
|
|
E->BaseType = Reader.readType(F, Record, Idx);
|
2011-03-01 02:50:33 +08:00
|
|
|
E->IsArrow = Record[Idx++];
|
|
|
|
E->OperatorLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->FirstQualifierFoundInScope = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameInfo(E->MemberNameInfo, Record, Idx);
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
void
|
2010-08-19 07:56:52 +08:00
|
|
|
ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
|
2010-06-28 17:31:56 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
if (Record[Idx++]) // HasTemplateKWAndArgsInfo
|
|
|
|
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(),
|
|
|
|
/*NumTemplateArgs=*/Record[Idx++]);
|
2011-02-26 04:49:16 +08:00
|
|
|
|
|
|
|
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
|
2010-06-28 17:31:56 +08:00
|
|
|
}
|
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
void
|
2010-08-19 07:56:52 +08:00
|
|
|
ASTStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) {
|
2010-06-24 16:57:31 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
assert(Record[Idx] == E->arg_size() && "Read wrong record during creation ?");
|
|
|
|
++Idx; // NumArgs;
|
|
|
|
for (unsigned I = 0, N = E->arg_size(); I != N; ++I)
|
2010-06-30 06:46:25 +08:00
|
|
|
E->setArg(I, Reader.ReadSubExpr());
|
2010-10-05 23:59:54 +08:00
|
|
|
E->Type = GetTypeSourceInfo(Record, Idx);
|
|
|
|
E->setLParenLoc(ReadSourceLocation(Record, Idx));
|
|
|
|
E->setRParenLoc(ReadSourceLocation(Record, Idx));
|
2010-06-24 16:57:31 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) {
|
2010-06-25 17:03:26 +08:00
|
|
|
VisitExpr(E);
|
2012-01-27 17:46:47 +08:00
|
|
|
|
|
|
|
if (Record[Idx++]) // HasTemplateKWAndArgsInfo
|
|
|
|
ReadTemplateKWAndArgsInfo(*E->getTemplateKWAndArgsInfo(),
|
|
|
|
/*NumTemplateArgs=*/Record[Idx++]);
|
2010-06-25 17:03:26 +08:00
|
|
|
|
|
|
|
unsigned NumDecls = Record[Idx++];
|
|
|
|
UnresolvedSet<8> Decls;
|
|
|
|
for (unsigned i = 0; i != NumDecls; ++i) {
|
2011-07-22 06:35:25 +08:00
|
|
|
NamedDecl *D = ReadDeclAs<NamedDecl>(Record, Idx);
|
2010-06-25 17:03:26 +08:00
|
|
|
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
|
|
|
|
Decls.addDecl(D, AS);
|
|
|
|
}
|
2011-09-10 05:34:22 +08:00
|
|
|
E->initializeResults(Reader.getContext(), Decls.begin(), Decls.end());
|
2010-06-25 17:03:26 +08:00
|
|
|
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameInfo(E->NameInfo, Record, Idx);
|
2011-03-01 04:01:57 +08:00
|
|
|
E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
|
2010-06-29 06:28:35 +08:00
|
|
|
VisitOverloadExpr(E);
|
2011-03-01 04:01:57 +08:00
|
|
|
E->IsArrow = Record[Idx++];
|
|
|
|
E->HasUnresolvedUsing = Record[Idx++];
|
|
|
|
E->Base = Reader.ReadSubExpr();
|
2011-07-22 08:38:23 +08:00
|
|
|
E->BaseType = Reader.readType(F, Record, Idx);
|
2011-03-01 04:01:57 +08:00
|
|
|
E->OperatorLoc = ReadSourceLocation(Record, Idx);
|
2010-06-25 17:03:26 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
|
2010-06-29 06:28:35 +08:00
|
|
|
VisitOverloadExpr(E);
|
2011-03-01 04:01:57 +08:00
|
|
|
E->RequiresADL = Record[Idx++];
|
2011-04-15 06:09:26 +08:00
|
|
|
if (E->RequiresADL)
|
|
|
|
E->StdIsAssociatedNamespace = Record[Idx++];
|
2011-03-01 04:01:57 +08:00
|
|
|
E->Overloaded = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
E->NamingClass = ReadDeclAs<CXXRecordDecl>(Record, Idx);
|
2010-06-25 17:03:34 +08:00
|
|
|
}
|
|
|
|
|
2010-08-19 07:56:52 +08:00
|
|
|
void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
|
2010-07-10 19:46:15 +08:00
|
|
|
VisitExpr(E);
|
|
|
|
E->UTT = (UnaryTypeTrait)Record[Idx++];
|
2010-09-14 04:56:31 +08:00
|
|
|
E->Value = (bool)Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceRange Range = ReadSourceRange(Record, Idx);
|
2010-07-10 19:46:15 +08:00
|
|
|
E->Loc = Range.getBegin();
|
|
|
|
E->RParen = Range.getEnd();
|
2010-10-05 23:59:54 +08:00
|
|
|
E->QueriedType = GetTypeSourceInfo(Record, Idx);
|
2010-07-10 19:46:15 +08:00
|
|
|
}
|
|
|
|
|
2010-12-07 08:08:36 +08:00
|
|
|
void ASTStmtReader::VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->BTT = (BinaryTypeTrait)Record[Idx++];
|
|
|
|
E->Value = (bool)Record[Idx++];
|
|
|
|
SourceRange Range = ReadSourceRange(Record, Idx);
|
|
|
|
E->Loc = Range.getBegin();
|
|
|
|
E->RParen = Range.getEnd();
|
|
|
|
E->LhsType = GetTypeSourceInfo(Record, Idx);
|
|
|
|
E->RhsType = GetTypeSourceInfo(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2012-02-24 15:38:34 +08:00
|
|
|
void ASTStmtReader::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->TypeTraitExprBits.NumArgs = Record[Idx++];
|
|
|
|
E->TypeTraitExprBits.Kind = Record[Idx++];
|
|
|
|
E->TypeTraitExprBits.Value = Record[Idx++];
|
|
|
|
|
|
|
|
TypeSourceInfo **Args = E->getTypeSourceInfos();
|
|
|
|
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
|
|
|
|
Args[I] = GetTypeSourceInfo(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2011-04-28 08:16:57 +08:00
|
|
|
void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->ATT = (ArrayTypeTrait)Record[Idx++];
|
|
|
|
E->Value = (unsigned int)Record[Idx++];
|
|
|
|
SourceRange Range = ReadSourceRange(Record, Idx);
|
|
|
|
E->Loc = Range.getBegin();
|
|
|
|
E->RParen = Range.getEnd();
|
|
|
|
E->QueriedType = GetTypeSourceInfo(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2011-04-25 14:54:41 +08:00
|
|
|
void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->ET = (ExpressionTrait)Record[Idx++];
|
|
|
|
E->Value = (bool)Record[Idx++];
|
|
|
|
SourceRange Range = ReadSourceRange(Record, Idx);
|
|
|
|
E->QueriedExpression = Reader.ReadSubExpr();
|
|
|
|
E->Loc = Range.getBegin();
|
|
|
|
E->RParen = Range.getEnd();
|
|
|
|
}
|
|
|
|
|
2010-09-11 04:55:54 +08:00
|
|
|
void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
|
|
|
|
VisitExpr(E);
|
2010-09-11 06:34:40 +08:00
|
|
|
E->Value = (bool)Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
E->Range = ReadSourceRange(Record, Idx);
|
2010-09-11 06:34:40 +08:00
|
|
|
E->Operand = Reader.ReadSubExpr();
|
2010-09-11 04:55:54 +08:00
|
|
|
}
|
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
void ASTStmtReader::VisitPackExpansionExpr(PackExpansionExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->EllipsisLoc = ReadSourceLocation(Record, Idx);
|
2011-01-15 05:20:45 +08:00
|
|
|
E->NumExpansions = Record[Idx++];
|
2011-01-04 01:17:50 +08:00
|
|
|
E->Pattern = Reader.ReadSubExpr();
|
|
|
|
}
|
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
void ASTStmtReader::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->OperatorLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->PackLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->RParenLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->Length = Record[Idx++];
|
2011-07-22 06:35:25 +08:00
|
|
|
E->Pack = ReadDeclAs<NamedDecl>(Record, Idx);
|
2011-01-05 01:33:58 +08:00
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
void ASTStmtReader::VisitSubstNonTypeTemplateParmExpr(
|
|
|
|
SubstNonTypeTemplateParmExpr *E) {
|
|
|
|
VisitExpr(E);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->Param = ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx);
|
2011-07-15 15:00:14 +08:00
|
|
|
E->NameLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->Replacement = Reader.ReadSubExpr();
|
|
|
|
}
|
|
|
|
|
2011-01-15 09:15:58 +08:00
|
|
|
void ASTStmtReader::VisitSubstNonTypeTemplateParmPackExpr(
|
|
|
|
SubstNonTypeTemplateParmPackExpr *E) {
|
|
|
|
VisitExpr(E);
|
2011-07-22 06:35:25 +08:00
|
|
|
E->Param = ReadDeclAs<NonTypeTemplateParmDecl>(Record, Idx);
|
2011-01-15 09:15:58 +08:00
|
|
|
TemplateArgument ArgPack = Reader.ReadTemplateArgument(F, Record, Idx);
|
|
|
|
if (ArgPack.getKind() != TemplateArgument::Pack)
|
|
|
|
return;
|
|
|
|
|
|
|
|
E->Arguments = ArgPack.pack_begin();
|
|
|
|
E->NumArguments = ArgPack.pack_size();
|
|
|
|
E->NameLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
}
|
|
|
|
|
2011-06-22 01:03:29 +08:00
|
|
|
void ASTStmtReader::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->Temporary = Reader.ReadSubExpr();
|
|
|
|
}
|
|
|
|
|
2010-11-16 07:31:06 +08:00
|
|
|
void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
|
|
|
|
VisitExpr(E);
|
2011-12-03 11:49:52 +08:00
|
|
|
E->SourceExpr = Reader.ReadSubExpr();
|
2011-01-28 10:26:04 +08:00
|
|
|
E->Loc = ReadSourceLocation(Record, Idx);
|
2010-11-16 07:31:06 +08:00
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Microsoft Expressions and Statements
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtReader::VisitCXXUuidofExpr(CXXUuidofExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->setSourceRange(ReadSourceRange(Record, Idx));
|
|
|
|
if (E->isTypeOperand()) { // __uuidof(ComType)
|
|
|
|
E->setTypeOperandSourceInfo(
|
|
|
|
GetTypeSourceInfo(Record, Idx));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// __uuidof(expr)
|
|
|
|
E->setExprOperand(Reader.ReadSubExpr());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitSEHExceptStmt(SEHExceptStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
S->Loc = ReadSourceLocation(Record, Idx);
|
|
|
|
S->Children[SEHExceptStmt::FILTER_EXPR] = Reader.ReadSubStmt();
|
|
|
|
S->Children[SEHExceptStmt::BLOCK] = Reader.ReadSubStmt();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitSEHFinallyStmt(SEHFinallyStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
S->Loc = ReadSourceLocation(Record, Idx);
|
|
|
|
S->Block = Reader.ReadSubStmt();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitSEHTryStmt(SEHTryStmt *S) {
|
|
|
|
VisitStmt(S);
|
|
|
|
S->IsCXXTry = Record[Idx++];
|
|
|
|
S->TryLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
S->Children[SEHTryStmt::TRY] = Reader.ReadSubStmt();
|
|
|
|
S->Children[SEHTryStmt::HANDLER] = Reader.ReadSubStmt();
|
|
|
|
}
|
|
|
|
|
2011-02-10 05:07:24 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// CUDA Expressions and Statements
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
void ASTStmtReader::VisitCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
|
|
|
|
VisitCallExpr(E);
|
|
|
|
E->setConfig(cast<CallExpr>(Reader.ReadSubExpr()));
|
|
|
|
}
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// OpenCL Expressions and Statements.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void ASTStmtReader::VisitAsTypeExpr(AsTypeExpr *E) {
|
|
|
|
VisitExpr(E);
|
|
|
|
E->BuiltinLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->RParenLoc = ReadSourceLocation(Record, Idx);
|
|
|
|
E->SrcExpr = Reader.ReadSubExpr();
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// ASTReader Implementation
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
Stmt *ASTReader::ReadStmt(ModuleFile &F) {
|
2010-06-29 06:28:35 +08:00
|
|
|
switch (ReadingKind) {
|
|
|
|
case Read_Decl:
|
|
|
|
case Read_Type:
|
2010-10-05 23:59:54 +08:00
|
|
|
return ReadStmtFromStream(F);
|
2010-06-29 06:28:35 +08:00
|
|
|
case Read_Stmt:
|
2010-06-30 06:46:25 +08:00
|
|
|
return ReadSubStmt();
|
2010-06-29 06:28:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("ReadingKind not set ?");
|
|
|
|
}
|
|
|
|
|
2011-12-01 07:21:26 +08:00
|
|
|
Expr *ASTReader::ReadExpr(ModuleFile &F) {
|
2010-10-05 23:59:54 +08:00
|
|
|
return cast_or_null<Expr>(ReadStmt(F));
|
2010-06-29 06:28:35 +08:00
|
|
|
}
|
2010-05-09 14:40:08 +08:00
|
|
|
|
2010-08-19 07:56:43 +08:00
|
|
|
Expr *ASTReader::ReadSubExpr() {
|
2010-06-30 06:46:25 +08:00
|
|
|
return cast_or_null<Expr>(ReadSubStmt());
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:41:06 +08:00
|
|
|
// Within the bitstream, expressions are stored in Reverse Polish
|
|
|
|
// Notation, with each of the subexpressions preceding the
|
2010-06-29 06:28:35 +08:00
|
|
|
// expression they are stored in. Subexpressions are stored from last to first.
|
|
|
|
// To evaluate expressions, we continue reading expressions and placing them on
|
|
|
|
// the stack, with expressions having operands removing those operands from the
|
2009-04-27 13:41:06 +08:00
|
|
|
// stack. Evaluation terminates when we see a STMT_STOP record, and
|
|
|
|
// the single remaining expression on the stack is our result.
|
2011-12-01 07:21:26 +08:00
|
|
|
Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
2010-06-29 06:28:35 +08:00
|
|
|
|
|
|
|
ReadingKindTracker ReadingKind(Read_Stmt, *this);
|
2010-10-05 23:59:54 +08:00
|
|
|
llvm::BitstreamCursor &Cursor = F.DeclsCursor;
|
2011-10-22 07:02:28 +08:00
|
|
|
|
|
|
|
// Map of offset to previously deserialized stmt. The offset points
|
|
|
|
/// just after the stmt record.
|
|
|
|
llvm::DenseMap<uint64_t, Stmt *> StmtEntries;
|
2010-10-05 23:59:54 +08:00
|
|
|
|
2010-06-29 06:28:35 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
unsigned PrevNumStmts = StmtStack.size();
|
|
|
|
#endif
|
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
RecordData Record;
|
|
|
|
unsigned Idx;
|
2010-10-05 23:59:54 +08:00
|
|
|
ASTStmtReader Reader(*this, F, Cursor, Record, Idx);
|
2009-04-27 13:14:47 +08:00
|
|
|
Stmt::EmptyShell Empty;
|
|
|
|
|
|
|
|
while (true) {
|
2009-04-27 13:41:06 +08:00
|
|
|
unsigned Code = Cursor.ReadCode();
|
2009-04-27 13:14:47 +08:00
|
|
|
if (Code == llvm::bitc::END_BLOCK) {
|
2009-04-27 13:41:06 +08:00
|
|
|
if (Cursor.ReadBlockEnd()) {
|
2010-08-19 07:57:06 +08:00
|
|
|
Error("error at end of block in AST file");
|
2009-04-27 13:14:47 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Code == llvm::bitc::ENTER_SUBBLOCK) {
|
|
|
|
// No known subblocks, always skip them.
|
2009-04-27 13:41:06 +08:00
|
|
|
Cursor.ReadSubBlockID();
|
|
|
|
if (Cursor.SkipBlock()) {
|
2010-08-19 07:57:06 +08:00
|
|
|
Error("malformed block record in AST file");
|
2009-04-27 13:14:47 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Code == llvm::bitc::DEFINE_ABBREV) {
|
2009-04-27 13:41:06 +08:00
|
|
|
Cursor.ReadAbbrevRecord();
|
2009-04-27 13:14:47 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Stmt *S = 0;
|
|
|
|
Idx = 0;
|
|
|
|
Record.clear();
|
|
|
|
bool Finished = false;
|
2011-10-22 07:02:28 +08:00
|
|
|
bool IsStmtReference = false;
|
2010-08-19 07:57:32 +08:00
|
|
|
switch ((StmtCode)Cursor.ReadRecord(Code, Record)) {
|
|
|
|
case STMT_STOP:
|
2009-04-27 13:14:47 +08:00
|
|
|
Finished = true;
|
|
|
|
break;
|
|
|
|
|
2011-10-22 07:02:28 +08:00
|
|
|
case STMT_REF_PTR:
|
|
|
|
IsStmtReference = true;
|
|
|
|
assert(StmtEntries.find(Record[0]) != StmtEntries.end() &&
|
|
|
|
"No stmt was recorded for this offset reference!");
|
|
|
|
S = StmtEntries[Record[Idx++]];
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_NULL_PTR:
|
2009-09-09 23:08:12 +08:00
|
|
|
S = 0;
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_NULL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) NullStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_COMPOUND:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) CompoundStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_CASE:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) CaseStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_DEFAULT:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) DefaultStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_LABEL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) LabelStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_IF:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) IfStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_SWITCH:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) SwitchStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_WHILE:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) WhileStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_DO:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) DoStmt(Empty);
|
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_FOR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ForStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_GOTO:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) GotoStmt(Empty);
|
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_INDIRECT_GOTO:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) IndirectGotoStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_CONTINUE:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ContinueStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_BREAK:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) BreakStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_RETURN:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ReturnStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_DECL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) DeclStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_ASM:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) AsmStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_PREDEFINED:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) PredefinedExpr(Empty);
|
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_DECL_REF:
|
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
|
|
|
S = DeclRefExpr::CreateEmpty(
|
2011-09-10 05:34:22 +08:00
|
|
|
Context,
|
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
|
|
|
/*HasQualifier=*/Record[ASTStmtReader::NumExprFields],
|
|
|
|
/*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1],
|
2012-01-27 17:46:47 +08:00
|
|
|
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields + 2],
|
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
|
|
|
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ?
|
2012-03-10 17:33:50 +08:00
|
|
|
Record[ASTStmtReader::NumExprFields + 5] : 0);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_INTEGER_LITERAL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = IntegerLiteral::Create(Context, Empty);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_FLOATING_LITERAL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = FloatingLiteral::Create(Context, Empty);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_IMAGINARY_LITERAL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ImaginaryLiteral(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_STRING_LITERAL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = StringLiteral::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
Record[ASTStmtReader::NumExprFields + 1]);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CHARACTER_LITERAL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) CharacterLiteral(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_PAREN:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ParenExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_PAREN_LIST:
|
2010-06-30 16:49:18 +08:00
|
|
|
S = new (Context) ParenListExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_UNARY_OPERATOR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) UnaryOperator(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OFFSETOF:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = OffsetOfExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
Record[ASTStmtReader::NumExprFields],
|
|
|
|
Record[ASTStmtReader::NumExprFields + 1]);
|
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
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_SIZEOF_ALIGN_OF:
|
2011-03-12 03:24:49 +08:00
|
|
|
S = new (Context) UnaryExprOrTypeTraitExpr(Empty);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_ARRAY_SUBSCRIPT:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ArraySubscriptExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CALL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = new (Context) CallExpr(Context, Stmt::CallExprClass, Empty);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_MEMBER: {
|
2010-07-08 21:09:47 +08:00
|
|
|
// We load everything here and fully initialize it at creation.
|
|
|
|
// That way we can use MemberExpr::Create and don't have to duplicate its
|
|
|
|
// logic with a MemberExpr::CreateEmpty.
|
|
|
|
|
|
|
|
assert(Idx == 0);
|
2011-03-01 05:54:11 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc;
|
2010-07-08 21:09:47 +08:00
|
|
|
if (Record[Idx++]) { // HasQualifier.
|
2011-03-01 05:54:11 +08:00
|
|
|
QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx);
|
2010-07-08 21:09:47 +08:00
|
|
|
}
|
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
SourceLocation TemplateKWLoc;
|
2010-07-08 21:09:47 +08:00
|
|
|
TemplateArgumentListInfo ArgInfo;
|
2012-01-27 17:46:47 +08:00
|
|
|
bool HasTemplateKWAndArgsInfo = Record[Idx++];
|
|
|
|
if (HasTemplateKWAndArgsInfo) {
|
|
|
|
TemplateKWLoc = ReadSourceLocation(F, Record, Idx);
|
2011-02-04 20:01:24 +08:00
|
|
|
unsigned NumTemplateArgs = Record[Idx++];
|
2010-10-05 23:59:54 +08:00
|
|
|
ArgInfo.setLAngleLoc(ReadSourceLocation(F, Record, Idx));
|
|
|
|
ArgInfo.setRAngleLoc(ReadSourceLocation(F, Record, Idx));
|
2010-07-08 21:09:47 +08:00
|
|
|
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
2010-10-05 23:59:54 +08:00
|
|
|
ArgInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Idx));
|
2010-07-08 21:09:47 +08:00
|
|
|
}
|
2011-10-05 15:56:41 +08:00
|
|
|
|
|
|
|
bool HadMultipleCandidates = Record[Idx++];
|
|
|
|
|
2011-07-22 06:35:25 +08:00
|
|
|
NamedDecl *FoundD = ReadDeclAs<NamedDecl>(F, Record, Idx);
|
2010-07-08 21:09:47 +08:00
|
|
|
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
|
|
|
|
DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
|
|
|
|
|
2011-07-22 08:38:23 +08:00
|
|
|
QualType T = readType(F, Record, Idx);
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK = static_cast<ExprValueKind>(Record[Idx++]);
|
|
|
|
ExprObjectKind OK = static_cast<ExprObjectKind>(Record[Idx++]);
|
2010-07-08 21:09:47 +08:00
|
|
|
Expr *Base = ReadSubExpr();
|
2011-07-22 06:35:25 +08:00
|
|
|
ValueDecl *MemberD = ReadDeclAs<ValueDecl>(F, Record, Idx);
|
2010-10-05 23:59:54 +08:00
|
|
|
SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx);
|
2010-08-12 06:01:17 +08:00
|
|
|
DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc);
|
2010-07-08 21:09:47 +08:00
|
|
|
bool IsArrow = Record[Idx++];
|
|
|
|
|
2011-09-10 05:34:22 +08:00
|
|
|
S = MemberExpr::Create(Context, Base, IsArrow, QualifierLoc,
|
2012-01-27 17:46:47 +08:00
|
|
|
TemplateKWLoc, MemberD, FoundDecl, MemberNameInfo,
|
|
|
|
HasTemplateKWAndArgsInfo ? &ArgInfo : 0,
|
|
|
|
T, VK, OK);
|
2010-10-16 02:21:24 +08:00
|
|
|
ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
|
|
|
|
MemberD->getDeclName(), Record, Idx);
|
2011-10-05 15:56:41 +08:00
|
|
|
if (HadMultipleCandidates)
|
|
|
|
cast<MemberExpr>(S)->setHadMultipleCandidates(true);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
2010-07-08 21:09:47 +08:00
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_BINARY_OPERATOR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) BinaryOperator(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_COMPOUND_ASSIGN_OPERATOR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) CompoundAssignOperator(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CONDITIONAL_OPERATOR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ConditionalOperator(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-02-17 18:25:35 +08:00
|
|
|
case EXPR_BINARY_CONDITIONAL_OPERATOR:
|
|
|
|
S = new (Context) BinaryConditionalOperator(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_IMPLICIT_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = ImplicitCastExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CSTYLE_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CStyleCastExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_COMPOUND_LITERAL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) CompoundLiteralExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_EXT_VECTOR_ELEMENT:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ExtVectorElementExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_INIT_LIST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = new (Context) InitListExpr(getContext(), Empty);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_DESIGNATED_INIT:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = DesignatedInitExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
Record[ASTStmtReader::NumExprFields] - 1);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_IMPLICIT_VALUE_INIT:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ImplicitValueInitExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_VA_ARG:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) VAArgExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_ADDR_LABEL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) AddrLabelExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_STMT:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) StmtExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CHOOSE:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ChooseExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_GNU_NULL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) GNUNullExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_SHUFFLE_VECTOR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ShuffleVectorExpr(Empty);
|
|
|
|
break;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_BLOCK:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) BlockExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-04-15 08:35:48 +08:00
|
|
|
case EXPR_GENERIC_SELECTION:
|
|
|
|
S = new (Context) GenericSelectionExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_STRING_LITERAL:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCStringLiteral(Empty);
|
|
|
|
break;
|
2012-03-07 04:05:56 +08:00
|
|
|
case EXPR_OBJC_NUMERIC_LITERAL:
|
|
|
|
S = new (Context) ObjCNumericLiteral(Empty);
|
|
|
|
break;
|
|
|
|
case EXPR_OBJC_ARRAY_LITERAL:
|
|
|
|
S = ObjCArrayLiteral::CreateEmpty(Context,
|
|
|
|
Record[ASTStmtReader::NumExprFields]);
|
|
|
|
break;
|
|
|
|
case EXPR_OBJC_DICTIONARY_LITERAL:
|
|
|
|
S = ObjCDictionaryLiteral::CreateEmpty(Context,
|
|
|
|
Record[ASTStmtReader::NumExprFields],
|
|
|
|
Record[ASTStmtReader::NumExprFields + 1]);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_ENCODE:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCEncodeExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_SELECTOR_EXPR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCSelectorExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_PROTOCOL_EXPR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCProtocolExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_IVAR_REF_EXPR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCIvarRefExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_PROPERTY_REF_EXPR:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCPropertyRefExpr(Empty);
|
|
|
|
break;
|
2012-03-07 04:05:56 +08:00
|
|
|
case EXPR_OBJC_SUBSCRIPT_REF_EXPR:
|
|
|
|
S = new (Context) ObjCSubscriptRefExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_KVC_REF_EXPR:
|
2010-12-02 09:19:52 +08:00
|
|
|
llvm_unreachable("mismatching AST file");
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_MESSAGE_EXPR:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = ObjCMessageExpr::CreateEmpty(Context,
|
2011-10-03 14:36:51 +08:00
|
|
|
Record[ASTStmtReader::NumExprFields],
|
|
|
|
Record[ASTStmtReader::NumExprFields + 1]);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_OBJC_ISA:
|
2009-07-25 01:54:45 +08:00
|
|
|
S = new (Context) ObjCIsaExpr(Empty);
|
|
|
|
break;
|
2011-06-16 07:02:42 +08:00
|
|
|
case EXPR_OBJC_INDIRECT_COPY_RESTORE:
|
|
|
|
S = new (Context) ObjCIndirectCopyRestoreExpr(Empty);
|
|
|
|
break;
|
|
|
|
case EXPR_OBJC_BRIDGED_CAST:
|
|
|
|
S = new (Context) ObjCBridgedCastExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_OBJC_FOR_COLLECTION:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCForCollectionStmt(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_OBJC_CATCH:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCAtCatchStmt(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_OBJC_FINALLY:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCAtFinallyStmt(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_OBJC_AT_TRY:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = ObjCAtTryStmt::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
Record[ASTStmtReader::NumStmtFields],
|
|
|
|
Record[ASTStmtReader::NumStmtFields + 1]);
|
2009-04-27 13:14:47 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_OBJC_AT_SYNCHRONIZED:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCAtSynchronizedStmt(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_OBJC_AT_THROW:
|
2009-04-27 13:14:47 +08:00
|
|
|
S = new (Context) ObjCAtThrowStmt(Empty);
|
|
|
|
break;
|
2011-06-16 07:02:42 +08:00
|
|
|
case STMT_OBJC_AUTORELEASE_POOL:
|
|
|
|
S = new (Context) ObjCAutoreleasePoolStmt(Empty);
|
|
|
|
break;
|
2012-03-07 04:05:56 +08:00
|
|
|
case EXPR_OBJC_BOOL_LITERAL:
|
|
|
|
S = new (Context) ObjCBoolLiteralExpr(Empty);
|
|
|
|
break;
|
2011-07-15 15:00:14 +08:00
|
|
|
case STMT_SEH_EXCEPT:
|
|
|
|
S = new (Context) SEHExceptStmt(Empty);
|
|
|
|
break;
|
|
|
|
case STMT_SEH_FINALLY:
|
|
|
|
S = new (Context) SEHFinallyStmt(Empty);
|
|
|
|
break;
|
|
|
|
case STMT_SEH_TRY:
|
|
|
|
S = new (Context) SEHTryStmt(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_CXX_CATCH:
|
2010-07-23 00:03:56 +08:00
|
|
|
S = new (Context) CXXCatchStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case STMT_CXX_TRY:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXTryStmt::Create(Context, Empty,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*NumHandlers=*/Record[ASTStmtReader::NumStmtFields]);
|
2010-07-23 00:03:56 +08:00
|
|
|
break;
|
|
|
|
|
2011-04-15 06:09:26 +08:00
|
|
|
case STMT_CXX_FOR_RANGE:
|
|
|
|
S = new (Context) CXXForRangeStmt(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-10-25 09:33:02 +08:00
|
|
|
case STMT_MS_DEPENDENT_EXISTS:
|
|
|
|
S = new (Context) MSDependentExistsStmt(SourceLocation(), true,
|
|
|
|
NestedNameSpecifierLoc(),
|
|
|
|
DeclarationNameInfo(),
|
|
|
|
0);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_OPERATOR_CALL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = new (Context) CXXOperatorCallExpr(Context, Empty);
|
2009-07-14 11:19:21 +08:00
|
|
|
break;
|
2010-05-09 13:36:05 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_MEMBER_CALL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = new (Context) CXXMemberCallExpr(Context, Empty);
|
2010-05-09 13:36:05 +08:00
|
|
|
break;
|
2009-09-10 07:08:42 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_CONSTRUCT:
|
2010-07-10 19:46:15 +08:00
|
|
|
S = new (Context) CXXConstructExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_TEMPORARY_OBJECT:
|
2010-07-10 19:46:15 +08:00
|
|
|
S = new (Context) CXXTemporaryObjectExpr(Empty);
|
2009-09-10 07:08:42 +08:00
|
|
|
break;
|
2010-01-17 05:21:01 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_STATIC_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXStaticCastExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
2010-01-17 05:21:01 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_DYNAMIC_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXDynamicCastExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
2010-01-17 05:21:01 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_REINTERPRET_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXReinterpretCastExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
2010-01-17 05:21:01 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_CONST_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXConstCastExpr::CreateEmpty(Context);
|
2010-01-17 05:21:01 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_FUNCTIONAL_CAST:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXFunctionalCastExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*PathSize*/ Record[ASTStmtReader::NumExprFields]);
|
2010-01-17 05:21:01 +08:00
|
|
|
break;
|
|
|
|
|
2012-03-07 16:35:16 +08:00
|
|
|
case EXPR_USER_DEFINED_LITERAL:
|
|
|
|
S = new (Context) UserDefinedLiteral(Context, Empty);
|
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_BOOL_LITERAL:
|
2010-02-07 14:32:43 +08:00
|
|
|
S = new (Context) CXXBoolLiteralExpr(Empty);
|
|
|
|
break;
|
2010-01-17 05:21:01 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_NULL_PTR_LITERAL:
|
2010-02-07 14:32:43 +08:00
|
|
|
S = new (Context) CXXNullPtrLiteralExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_TYPEID_EXPR:
|
2010-05-09 14:03:39 +08:00
|
|
|
S = new (Context) CXXTypeidExpr(Empty, true);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_TYPEID_TYPE:
|
2010-05-09 14:03:39 +08:00
|
|
|
S = new (Context) CXXTypeidExpr(Empty, false);
|
|
|
|
break;
|
2010-09-08 20:20:18 +08:00
|
|
|
case EXPR_CXX_UUIDOF_EXPR:
|
|
|
|
S = new (Context) CXXUuidofExpr(Empty, true);
|
|
|
|
break;
|
|
|
|
case EXPR_CXX_UUIDOF_TYPE:
|
|
|
|
S = new (Context) CXXUuidofExpr(Empty, false);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_THIS:
|
2010-05-09 14:15:05 +08:00
|
|
|
S = new (Context) CXXThisExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_THROW:
|
2010-05-09 14:15:05 +08:00
|
|
|
S = new (Context) CXXThrowExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_DEFAULT_ARG: {
|
2010-08-19 07:56:52 +08:00
|
|
|
bool HasOtherExprStored = Record[ASTStmtReader::NumExprFields];
|
2010-07-03 07:30:15 +08:00
|
|
|
if (HasOtherExprStored) {
|
|
|
|
Expr *SubExpr = ReadSubExpr();
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXDefaultArgExpr::Create(Context, SourceLocation(), 0, SubExpr);
|
2010-07-03 07:30:15 +08:00
|
|
|
} else
|
|
|
|
S = new (Context) CXXDefaultArgExpr(Empty);
|
2010-05-09 14:40:08 +08:00
|
|
|
break;
|
2010-07-03 07:30:15 +08:00
|
|
|
}
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_BIND_TEMPORARY:
|
2010-05-10 08:25:06 +08:00
|
|
|
S = new (Context) CXXBindTemporaryExpr(Empty);
|
|
|
|
break;
|
2010-09-03 05:50:02 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_SCALAR_VALUE_INIT:
|
2010-07-08 14:14:04 +08:00
|
|
|
S = new (Context) CXXScalarValueInitExpr(Empty);
|
2010-05-10 09:22:27 +08:00
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_NEW:
|
2010-05-10 09:22:27 +08:00
|
|
|
S = new (Context) CXXNewExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_DELETE:
|
2010-06-23 01:07:59 +08:00
|
|
|
S = new (Context) CXXDeleteExpr(Empty);
|
|
|
|
break;
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_PSEUDO_DESTRUCTOR:
|
2010-06-28 17:32:03 +08:00
|
|
|
S = new (Context) CXXPseudoDestructorExpr(Empty);
|
|
|
|
break;
|
2010-05-10 09:22:27 +08:00
|
|
|
|
2010-12-06 16:20:24 +08:00
|
|
|
case EXPR_EXPR_WITH_CLEANUPS:
|
2011-11-10 13:35:25 +08:00
|
|
|
S = ExprWithCleanups::Create(Context, Empty,
|
|
|
|
Record[ASTStmtReader::NumExprFields]);
|
2010-05-10 08:25:06 +08:00
|
|
|
break;
|
2010-06-24 16:57:31 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_DEPENDENT_SCOPE_MEMBER:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXDependentScopeMemberExpr::CreateEmpty(Context,
|
2012-01-27 17:46:47 +08:00
|
|
|
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
|
2011-02-04 20:01:24 +08:00
|
|
|
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
|
|
|
|
? Record[ASTStmtReader::NumExprFields + 1]
|
|
|
|
: 0);
|
2010-06-24 16:57:31 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_DEPENDENT_SCOPE_DECL_REF:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = DependentScopeDeclRefExpr::CreateEmpty(Context,
|
2012-01-27 17:46:47 +08:00
|
|
|
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
|
2011-02-04 20:01:24 +08:00
|
|
|
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
|
|
|
|
? Record[ASTStmtReader::NumExprFields + 1]
|
|
|
|
: 0);
|
2010-06-28 17:31:56 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_UNRESOLVED_CONSTRUCT:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = CXXUnresolvedConstructExpr::CreateEmpty(Context,
|
2010-08-19 07:56:52 +08:00
|
|
|
/*NumArgs=*/Record[ASTStmtReader::NumExprFields]);
|
2010-06-25 17:03:26 +08:00
|
|
|
break;
|
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_UNRESOLVED_MEMBER:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = UnresolvedMemberExpr::CreateEmpty(Context,
|
2012-01-27 17:46:47 +08:00
|
|
|
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
|
2011-02-04 20:01:24 +08:00
|
|
|
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
|
|
|
|
? Record[ASTStmtReader::NumExprFields + 1]
|
|
|
|
: 0);
|
2010-06-24 16:57:31 +08:00
|
|
|
break;
|
2010-06-25 17:03:34 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_UNRESOLVED_LOOKUP:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = UnresolvedLookupExpr::CreateEmpty(Context,
|
2012-01-27 17:46:47 +08:00
|
|
|
/*HasTemplateKWAndArgsInfo=*/Record[ASTStmtReader::NumExprFields],
|
2011-02-04 20:01:24 +08:00
|
|
|
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields]
|
|
|
|
? Record[ASTStmtReader::NumExprFields + 1]
|
|
|
|
: 0);
|
2010-06-25 17:03:34 +08:00
|
|
|
break;
|
2010-07-10 19:46:15 +08:00
|
|
|
|
2010-08-19 07:57:32 +08:00
|
|
|
case EXPR_CXX_UNARY_TYPE_TRAIT:
|
2010-07-10 19:46:15 +08:00
|
|
|
S = new (Context) UnaryTypeTraitExpr(Empty);
|
|
|
|
break;
|
2010-09-11 04:55:54 +08:00
|
|
|
|
2010-12-09 06:35:30 +08:00
|
|
|
case EXPR_BINARY_TYPE_TRAIT:
|
2010-12-07 08:08:36 +08:00
|
|
|
S = new (Context) BinaryTypeTraitExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2012-02-24 15:38:34 +08:00
|
|
|
case EXPR_TYPE_TRAIT:
|
|
|
|
S = TypeTraitExpr::CreateDeserialized(Context,
|
|
|
|
Record[ASTStmtReader::NumExprFields]);
|
|
|
|
break;
|
|
|
|
|
2011-04-28 08:16:57 +08:00
|
|
|
case EXPR_ARRAY_TYPE_TRAIT:
|
|
|
|
S = new (Context) ArrayTypeTraitExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-04-25 14:54:41 +08:00
|
|
|
case EXPR_CXX_EXPRESSION_TRAIT:
|
|
|
|
S = new (Context) ExpressionTraitExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2010-09-11 04:55:54 +08:00
|
|
|
case EXPR_CXX_NOEXCEPT:
|
|
|
|
S = new (Context) CXXNoexceptExpr(Empty);
|
|
|
|
break;
|
2010-11-16 07:31:06 +08:00
|
|
|
|
2011-01-04 01:17:50 +08:00
|
|
|
case EXPR_PACK_EXPANSION:
|
|
|
|
S = new (Context) PackExpansionExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-01-05 01:33:58 +08:00
|
|
|
case EXPR_SIZEOF_PACK:
|
|
|
|
S = new (Context) SizeOfPackExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-07-15 15:00:14 +08:00
|
|
|
case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM:
|
|
|
|
S = new (Context) SubstNonTypeTemplateParmExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-01-15 09:15:58 +08:00
|
|
|
case EXPR_SUBST_NON_TYPE_TEMPLATE_PARM_PACK:
|
|
|
|
S = new (Context) SubstNonTypeTemplateParmPackExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-06-22 01:03:29 +08:00
|
|
|
case EXPR_MATERIALIZE_TEMPORARY:
|
|
|
|
S = new (Context) MaterializeTemporaryExpr(Empty);
|
|
|
|
break;
|
|
|
|
|
2011-12-03 11:49:52 +08:00
|
|
|
case EXPR_OPAQUE_VALUE:
|
|
|
|
S = new (Context) OpaqueValueExpr(Empty);
|
2010-11-16 07:31:06 +08:00
|
|
|
break;
|
2011-02-10 05:07:24 +08:00
|
|
|
|
|
|
|
case EXPR_CUDA_KERNEL_CALL:
|
2011-09-10 05:34:22 +08:00
|
|
|
S = new (Context) CUDAKernelCallExpr(Context, Empty);
|
2011-02-10 05:07:24 +08:00
|
|
|
break;
|
2011-06-04 08:47:47 +08:00
|
|
|
|
|
|
|
case EXPR_ASTYPE:
|
|
|
|
S = new (Context) AsTypeExpr(Empty);
|
|
|
|
break;
|
2011-10-11 10:20:01 +08:00
|
|
|
|
2011-11-06 17:01:30 +08:00
|
|
|
case EXPR_PSEUDO_OBJECT: {
|
|
|
|
unsigned numSemanticExprs = Record[ASTStmtReader::NumExprFields];
|
|
|
|
S = PseudoObjectExpr::Create(Context, Empty, numSemanticExprs);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-10-11 10:20:01 +08:00
|
|
|
case EXPR_ATOMIC:
|
|
|
|
S = new (Context) AtomicExpr(Empty);
|
|
|
|
break;
|
2012-02-15 01:54:36 +08:00
|
|
|
|
|
|
|
case EXPR_LAMBDA: {
|
|
|
|
unsigned NumCaptures = Record[ASTStmtReader::NumExprFields];
|
|
|
|
unsigned NumArrayIndexVars = Record[ASTStmtReader::NumExprFields + 1];
|
|
|
|
S = LambdaExpr::CreateDeserialized(Context, NumCaptures,
|
|
|
|
NumArrayIndexVars);
|
|
|
|
break;
|
|
|
|
}
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|
2010-07-10 19:46:15 +08:00
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
// We hit a STMT_STOP, so we're done with this expression.
|
|
|
|
if (Finished)
|
|
|
|
break;
|
|
|
|
|
|
|
|
++NumStatementsRead;
|
|
|
|
|
2011-10-22 07:02:28 +08:00
|
|
|
if (S && !IsStmtReference) {
|
2010-06-29 06:28:35 +08:00
|
|
|
Reader.Visit(S);
|
2011-10-22 07:02:28 +08:00
|
|
|
StmtEntries[Cursor.GetCurrentBitNo()] = S;
|
|
|
|
}
|
|
|
|
|
2009-04-27 13:14:47 +08:00
|
|
|
|
|
|
|
assert(Idx == Record.size() && "Invalid deserialization of statement");
|
|
|
|
StmtStack.push_back(S);
|
|
|
|
}
|
2010-06-29 06:28:35 +08:00
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
assert(StmtStack.size() > PrevNumStmts && "Read too many sub stmts!");
|
|
|
|
assert(StmtStack.size() == PrevNumStmts + 1 && "Extra expressions on stack!");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return StmtStack.pop_back_val();
|
2009-04-27 13:14:47 +08:00
|
|
|
}
|