From 663e380d7b2de2bbf20e886e05371195bea9adc4 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 8 Jul 2010 13:09:47 +0000 Subject: [PATCH] Read/write the C++ parts of DeclRefExpr and MemberExpr for PCH. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107872 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 20 +++++----- lib/AST/Expr.cpp | 13 +++++++ lib/Frontend/PCHReaderStmt.cpp | 70 ++++++++++++++++++++++++++++------ lib/Frontend/PCHWriterStmt.cpp | 44 ++++++++++++++++++--- 4 files changed, 122 insertions(+), 25 deletions(-) diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index b04e74ac28..9d1ba48a35 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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, diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index e84f73a1aa..cc6ad5ab46 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -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()); + return new (Mem) DeclRefExpr(EmptyShell()); +} + SourceRange DeclRefExpr::getSourceRange() const { // FIXME: Does not handle multi-token names well, e.g., operator[]. SourceRange R(Loc); diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index d330eecb70..2f99d7c1a0 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -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(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(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(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(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); diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index 00cebf15eb..ea464742de 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -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; } -- 2.40.0