Read/write the C++ parts of DeclRefExpr and MemberExpr for PCH.

llvm-svn: 107872
This commit is contained in:
Argyrios Kyrtzidis 2010-07-08 13:09:47 +00:00
parent 00dda6accc
commit 1985bb3b10
4 changed files with 122 additions and 25 deletions

View File

@ -561,6 +561,10 @@ class DeclRefExpr : public Expr {
ValueDecl *D, SourceLocation NameLoc,
const TemplateArgumentListInfo *TemplateArgs,
QualType T);
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
@ -572,10 +576,6 @@ public:
computeDependence();
}
/// \brief Construct an empty declaration reference expression.
explicit DeclRefExpr(EmptyShell Empty)
: Expr(DeclRefExprClass, Empty) { }
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange QualifierRange,
@ -583,6 +583,10 @@ public:
SourceLocation NameLoc,
QualType T,
const TemplateArgumentListInfo *TemplateArgs = 0);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(ASTContext &Context,
bool HasQualifier, unsigned NumTemplateArgs);
ValueDecl *getDecl() { return DecoratedD.getPointer(); }
const ValueDecl *getDecl() const { return DecoratedD.getPointer(); }
@ -672,6 +676,9 @@ public:
// Iterators
virtual child_iterator child_begin();
virtual child_iterator child_end();
friend class PCHStmtReader;
friend class PCHStmtWriter;
};
/// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__.
@ -1641,11 +1648,6 @@ public:
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
/// \brief Build an empty member reference expression.
explicit MemberExpr(EmptyShell Empty)
: Expr(MemberExprClass, Empty), HasQualifierOrFoundDecl(false),
HasExplicitTemplateArgumentList(false) { }
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
ValueDecl *memberdecl, DeclAccessPair founddecl,

View File

@ -228,6 +228,19 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
TemplateArgs, T);
}
DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier,
unsigned NumTemplateArgs) {
std::size_t Size = sizeof(DeclRefExpr);
if (HasQualifier)
Size += sizeof(NameQualifier);
if (NumTemplateArgs)
Size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs);
void *Mem = Context.Allocate(Size, llvm::alignof<DeclRefExpr>());
return new (Mem) DeclRefExpr(EmptyShell());
}
SourceRange DeclRefExpr::getSourceRange() const {
// FIXME: Does not handle multi-token names well, e.g., operator[].
SourceRange R(Loc);

View File

@ -374,10 +374,24 @@ void PCHStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
void PCHStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
bool HasQualifier = Record[Idx++];
unsigned NumTemplateArgs = Record[Idx++];
E->DecoratedD.setInt((HasQualifier? DeclRefExpr::HasQualifierFlag : 0) |
(NumTemplateArgs ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0));
if (HasQualifier) {
E->getNameQualifier()->NNS = Reader.ReadNestedNameSpecifier(Record, Idx);
E->getNameQualifier()->Range = Reader.ReadSourceRange(Record, Idx);
}
if (NumTemplateArgs)
ReadExplicitTemplateArgumentList(*E->getExplicitTemplateArgumentList(),
NumTemplateArgs);
E->setDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
// FIXME: read qualifier
// FIXME: read explicit template arguments
E->setLocation(Reader.ReadSourceLocation(Record, Idx));
}
void PCHStmtReader::VisitIntegerLiteral(IntegerLiteral *E) {
@ -519,11 +533,9 @@ void PCHStmtReader::VisitCallExpr(CallExpr *E) {
}
void PCHStmtReader::VisitMemberExpr(MemberExpr *E) {
VisitExpr(E);
E->setBase(Reader.ReadSubExpr());
E->setMemberDecl(cast<ValueDecl>(Reader.GetDecl(Record[Idx++])));
E->setMemberLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
E->setArrow(Record[Idx++]);
// Don't call VisitExpr, this is fully initialized at creation.
assert(E->getStmtClass() == Stmt::MemberExprClass &&
"It's a subclass, we must advance Idx!");
}
void PCHStmtReader::VisitObjCIsaExpr(ObjCIsaExpr *E) {
@ -1321,7 +1333,9 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
break;
case pch::EXPR_DECL_REF:
S = new (Context) DeclRefExpr(Empty);
S = DeclRefExpr::CreateEmpty(*Context,
/*HasQualifier=*/Record[PCHStmtReader::NumExprFields],
/*NumTemplateArgs=*/Record[PCHStmtReader::NumExprFields + 1]);
break;
case pch::EXPR_INTEGER_LITERAL:
@ -1375,9 +1389,43 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) {
S = new (Context) CallExpr(*Context, Stmt::CallExprClass, Empty);
break;
case pch::EXPR_MEMBER:
S = new (Context) MemberExpr(Empty);
case pch::EXPR_MEMBER: {
// 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);
NestedNameSpecifier *NNS = 0;
SourceRange QualifierRange;
if (Record[Idx++]) { // HasQualifier.
NNS = ReadNestedNameSpecifier(Record, Idx);
QualifierRange = ReadSourceRange(Record, Idx);
}
TemplateArgumentListInfo ArgInfo;
unsigned NumTemplateArgs = Record[Idx++];
if (NumTemplateArgs) {
ArgInfo.setLAngleLoc(ReadSourceLocation(Record, Idx));
ArgInfo.setRAngleLoc(ReadSourceLocation(Record, Idx));
for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument(ReadTemplateArgumentLoc(Record, Idx));
}
NamedDecl *FoundD = cast_or_null<NamedDecl>(GetDecl(Record[Idx++]));
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
QualType T = GetType(Record[Idx++]);
Expr *Base = ReadSubExpr();
ValueDecl *MemberD = cast<ValueDecl>(GetDecl(Record[Idx++]));
SourceLocation MemberLoc = ReadSourceLocation(Record, Idx);
bool IsArrow = Record[Idx++];
S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange,
MemberD, FoundDecl, MemberLoc,
NumTemplateArgs ? &ArgInfo : 0, T);
break;
}
case pch::EXPR_BINARY_OPERATOR:
S = new (Context) BinaryOperator(Empty);

View File

@ -359,10 +359,23 @@ void PCHStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
void PCHStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
VisitExpr(E);
Record.push_back(E->hasQualifier());
unsigned NumTemplateArgs = E->getNumTemplateArgs();
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgumentList() &&
"Template args list with no args ?");
Record.push_back(NumTemplateArgs);
if (E->hasQualifier()) {
Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
Writer.AddSourceRange(E->getQualifierRange(), Record);
}
if (NumTemplateArgs)
AddExplicitTemplateArgumentList(*E->getExplicitTemplateArgumentList());
Writer.AddDeclRef(E->getDecl(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
// FIXME: write qualifier
// FIXME: write explicit template arguments
Code = pch::EXPR_DECL_REF;
}
@ -507,13 +520,34 @@ void PCHStmtWriter::VisitCallExpr(CallExpr *E) {
}
void PCHStmtWriter::VisitMemberExpr(MemberExpr *E) {
VisitExpr(E);
// Don't call VisitExpr, we'll write everything here.
Record.push_back(E->hasQualifier());
if (E->hasQualifier()) {
Writer.AddNestedNameSpecifier(E->getQualifier(), Record);
Writer.AddSourceRange(E->getQualifierRange(), Record);
}
unsigned NumTemplateArgs = E->getNumTemplateArgs();
assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgumentList() &&
"Template args list with no args ?");
Record.push_back(NumTemplateArgs);
if (NumTemplateArgs) {
Writer.AddSourceLocation(E->getLAngleLoc(), Record);
Writer.AddSourceLocation(E->getRAngleLoc(), Record);
for (unsigned i=0; i != NumTemplateArgs; ++i)
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
}
DeclAccessPair FoundDecl = E->getFoundDecl();
Writer.AddDeclRef(FoundDecl.getDecl(), Record);
Record.push_back(FoundDecl.getAccess());
Writer.AddTypeRef(E->getType(), Record);
Writer.AddStmt(E->getBase());
Writer.AddDeclRef(E->getMemberDecl(), Record);
Writer.AddSourceLocation(E->getMemberLoc(), Record);
Record.push_back(E->isArrow());
// FIXME: C++ nested-name-specifier
// FIXME: C++ template argument list
Code = pch::EXPR_MEMBER;
}