From: Argyrios Kyrtzidis Date: Mon, 28 Jun 2010 09:31:56 +0000 (+0000) Subject: Support DependentScopeDeclRefExpr for PCH. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=12dffcddb60380c5bed4f085a1f51534afda3b87;p=clang Support DependentScopeDeclRefExpr for PCH. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106998 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 534ffa4e55..4305adbddc 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1656,18 +1656,25 @@ public: SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs = 0); + static DependentScopeDeclRefExpr *CreateEmpty(ASTContext &C, + unsigned NumTemplateArgs); + /// \brief Retrieve the name that this expression refers to. DeclarationName getDeclName() const { return Name; } + void setDeclName(DeclarationName N) { Name = N; } /// \brief Retrieve the location of the name within the expression. SourceLocation getLocation() const { return Loc; } + void setLocation(SourceLocation L) { Loc = L; } /// \brief Retrieve the source range of the nested-name-specifier. SourceRange getQualifierRange() const { return QualifierRange; } + void setQualifierRange(SourceRange R) { QualifierRange = R; } /// \brief Retrieve the nested-name-specifier that qualifies this /// declaration. NestedNameSpecifier *getQualifier() const { return Qualifier; } + void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; } /// Determines whether this lookup had explicit template arguments. bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } @@ -1676,6 +1683,11 @@ public: // nodes, users are *forbidden* from calling these methods on objects // without explicit template arguments. + ExplicitTemplateArgumentList &getExplicitTemplateArgs() { + assert(hasExplicitTemplateArgs()); + return *reinterpret_cast(this + 1); + } + /// Gets a reference to the explicit template argument list. const ExplicitTemplateArgumentList &getExplicitTemplateArgs() const { assert(hasExplicitTemplateArgs()); diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 0abe657475..31864183d3 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -772,6 +772,7 @@ namespace clang { EXPR_CXX_EXPR_WITH_TEMPORARIES, // CXXExprWithTemporaries EXPR_CXX_DEPENDENT_SCOPE_MEMBER, // CXXDependentScopeMemberExpr + EXPR_CXX_DEPENDENT_SCOPE_DECL_REF, // DependentScopeDeclRefExpr EXPR_CXX_UNRESOLVED_CONSTRUCT, // CXXUnresolvedConstructExpr EXPR_CXX_UNRESOLVED_MEMBER, // UnresolvedMemberExpr EXPR_CXX_UNRESOLVED_LOOKUP // UnresolvedLookupExpr diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index b31c448ff0..08d8ae46b4 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -290,6 +290,19 @@ DependentScopeDeclRefExpr::Create(ASTContext &C, return DRE; } +DependentScopeDeclRefExpr * +DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C, + unsigned NumTemplateArgs) { + std::size_t size = sizeof(DependentScopeDeclRefExpr); + if (NumTemplateArgs) + size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); + void *Mem = C.Allocate(size); + + return new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(), + DeclarationName(),SourceLocation(), + NumTemplateArgs != 0); +} + StmtIterator DependentScopeDeclRefExpr::child_begin() { return child_iterator(); } diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index a2334d7330..5f9ee3b25f 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -147,6 +147,7 @@ namespace { unsigned VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); unsigned VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); + unsigned VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); unsigned VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); unsigned VisitOverloadExpr(OverloadExpr *E); @@ -1184,6 +1185,26 @@ PCHStmtReader::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ return NumExprs + 1; } +unsigned +PCHStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { + VisitExpr(E); + unsigned NumExprs = 0; + + unsigned NumTemplateArgs = Record[Idx++]; + assert((NumTemplateArgs != 0) == E->hasExplicitTemplateArgs() && + "Read wrong record during creation ?"); + if (E->hasExplicitTemplateArgs()) + NumExprs + = ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), + NumTemplateArgs, StmtStack.end()); + + E->setDeclName(Reader.ReadDeclarationName(Record, Idx)); + E->setLocation(Reader.ReadSourceLocation(Record, Idx)); + E->setQualifierRange(Reader.ReadSourceRange(Record, Idx)); + E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); + return NumExprs; +} + unsigned PCHStmtReader::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { VisitExpr(E); @@ -1635,6 +1656,11 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) { /*NumTemplateArgs=*/Record[PCHStmtReader::NumExprFields]); break; + case pch::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF: + S = DependentScopeDeclRefExpr::CreateEmpty(*Context, + /*NumTemplateArgs=*/Record[PCHStmtReader::NumExprFields]); + break; + case pch::EXPR_CXX_UNRESOLVED_CONSTRUCT: S = CXXUnresolvedConstructExpr::CreateEmpty(*Context, /*NumArgs=*/Record[PCHStmtReader::NumExprFields]); diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index a3f18dea39..d3e1e1aab7 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -137,6 +137,7 @@ namespace { void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); void VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E); + void VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E); void VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E); void VisitOverloadExpr(OverloadExpr *E); @@ -1103,6 +1104,29 @@ PCHStmtWriter::VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E){ Code = pch::EXPR_CXX_DEPENDENT_SCOPE_MEMBER; } +void +PCHStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { + VisitExpr(E); + + // Don't emit anything here, NumTemplateArgs must be emitted first. + + if (E->hasExplicitTemplateArgs()) { + const ExplicitTemplateArgumentList &Args = E->getExplicitTemplateArgs(); + assert(Args.NumTemplateArgs && + "Num of template args was zero! PCH reading will mess up!"); + Record.push_back(Args.NumTemplateArgs); + AddExplicitTemplateArgumentList(Args); + } else { + Record.push_back(0); + } + + Writer.AddDeclarationName(E->getDeclName(), Record); + Writer.AddSourceLocation(E->getLocation(), Record); + Writer.AddSourceRange(E->getQualifierRange(), Record); + Writer.AddNestedNameSpecifier(E->getQualifier(), Record); + Code = pch::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF; +} + void PCHStmtWriter::VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E) { VisitExpr(E); diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h index ca4a29fde7..bfc0def146 100644 --- a/test/PCH/cxx-templates.h +++ b/test/PCH/cxx-templates.h @@ -51,5 +51,6 @@ struct Dep { template inline T make_a(const A1& a1) { + T::depend_declref(); return T(a1); }