From 00cf3cc2718671aa48e8da264a523b0058a8591e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 25 Feb 2011 20:49:16 +0000 Subject: [PATCH] Push nested-name-specifier source location information into DependentScopeDeclRefExpr. Plus, give NestedNameSpecifierLoc == and != operators, since we're going to need 'em elsewhere. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126508 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 39 +++++++++------------ include/clang/AST/NestedNameSpecifier.h | 10 ++++++ include/clang/AST/RecursiveASTVisitor.h | 6 ++-- lib/AST/ExprCXX.cpp | 17 +++++---- lib/Sema/SemaTemplate.cpp | 11 +++--- lib/Sema/TreeTransform.h | 21 +++++------ lib/Serialization/ASTReaderStmt.cpp | 5 ++- lib/Serialization/ASTWriterStmt.cpp | 3 +- test/SemaCXX/nested-name-spec-locations.cpp | 7 ++++ tools/libclang/CIndex.cpp | 3 +- 10 files changed, 64 insertions(+), 58 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 5f4ab333a3..a599cfbbe8 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1873,30 +1873,26 @@ public: /// ("value"). Such expressions will instantiate to a DeclRefExpr once the /// declaration can be found. class DependentScopeDeclRefExpr : public Expr { - /// The name of the entity we will be referencing. - DeclarationNameInfo NameInfo; - - /// QualifierRange - The source range that covers the - /// nested-name-specifier. - SourceRange QualifierRange; - /// \brief The nested-name-specifier that qualifies this unresolved /// declaration name. - NestedNameSpecifier *Qualifier; + NestedNameSpecifierLoc QualifierLoc; + + /// The name of the entity we will be referencing. + DeclarationNameInfo NameInfo; /// \brief Whether the name includes explicit template arguments. bool HasExplicitTemplateArgs; DependentScopeDeclRefExpr(QualType T, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args); + friend class ASTStmtReader; + public: static DependentScopeDeclRefExpr *Create(ASTContext &C, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs = 0); @@ -1906,24 +1902,23 @@ public: /// \brief Retrieve the name that this expression refers to. const DeclarationNameInfo &getNameInfo() const { return NameInfo; } - void setNameInfo(const DeclarationNameInfo &N) { NameInfo = N; } /// \brief Retrieve the name that this expression refers to. DeclarationName getDeclName() const { return NameInfo.getName(); } - void setDeclName(DeclarationName N) { NameInfo.setName(N); } /// \brief Retrieve the location of the name within the expression. SourceLocation getLocation() const { return NameInfo.getLoc(); } - void setLocation(SourceLocation L) { NameInfo.setLoc(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 the + /// name, with source location information. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + /// \brief Retrieve the nested-name-specifier that qualifies this /// declaration. - NestedNameSpecifier *getQualifier() const { return Qualifier; } - void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; } + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } /// Determines whether this lookup had explicit template arguments. bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } @@ -1974,7 +1969,7 @@ public: } SourceRange getSourceRange() const { - SourceRange Range(QualifierRange.getBegin(), getLocation()); + SourceRange Range(QualifierLoc.getBeginLoc(), getLocation()); if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); return Range; diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index 5e9adfccc4..024bf40289 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -300,6 +300,16 @@ public: /// \brief Determines the data length for the entire /// nested-name-specifier. unsigned getDataLength() const { return getDataLength(Qualifier); } + + friend bool operator==(NestedNameSpecifierLoc X, + NestedNameSpecifierLoc Y) { + return X.Qualifier == Y.Qualifier && X.Data == Y.Data; + } + + friend bool operator!=(NestedNameSpecifierLoc X, + NestedNameSpecifierLoc Y) { + return !(X == Y); + } }; /// Insertion operator for diagnostics. This allows sending NestedNameSpecifiers diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 8f9b3a0349..e85b6dcd27 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1692,20 +1692,18 @@ DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { }) DEF_TRAVERSE_STMT(DeclRefExpr, { + TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); TRY_TO(TraverseTemplateArgumentLocsHelper( S->getTemplateArgs(), S->getNumTemplateArgs())); - // FIXME: Should we be recursing on the qualifier? - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); }) DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, { - // FIXME: Should we be recursing on these two things? + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (S->hasExplicitTemplateArgs()) { TRY_TO(TraverseTemplateArgumentLocsHelper( S->getExplicitTemplateArgs().getTemplateArgs(), S->getNumTemplateArgs())); } - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); }) DEF_TRAVERSE_STMT(MemberExpr, { diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index fec7c249a7..4f4a6b4944 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -283,15 +283,16 @@ CXXRecordDecl *OverloadExpr::getNamingClass() const { // DependentScopeDeclRefExpr DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, true, true, (NameInfo.containsUnexpandedParameterPack() || - (Qualifier && Qualifier->containsUnexpandedParameterPack()))), - NameInfo(NameInfo), QualifierRange(QualifierRange), Qualifier(Qualifier), + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier() + ->containsUnexpandedParameterPack()))), + QualifierLoc(QualifierLoc), NameInfo(NameInfo), HasExplicitTemplateArgs(Args != 0) { if (Args) { @@ -307,16 +308,14 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, DependentScopeDeclRefExpr * DependentScopeDeclRefExpr::Create(ASTContext &C, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args) { std::size_t size = sizeof(DependentScopeDeclRefExpr); if (Args) size += ExplicitTemplateArgumentList::sizeFor(*Args); void *Mem = C.Allocate(size); - return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, - Qualifier, QualifierRange, + return new (Mem) DependentScopeDeclRefExpr(C.DependentTy, QualifierLoc, NameInfo, Args); } @@ -329,7 +328,7 @@ DependentScopeDeclRefExpr::CreateEmpty(ASTContext &C, size += ExplicitTemplateArgumentList::sizeFor(NumTemplateArgs); void *Mem = C.Allocate(size); DependentScopeDeclRefExpr *E - = new (Mem) DependentScopeDeclRefExpr(QualType(), 0, SourceRange(), + = new (Mem) DependentScopeDeclRefExpr(QualType(), NestedNameSpecifierLoc(), DeclarationNameInfo(), 0); E->HasExplicitTemplateArgs = HasExplicitTemplateArgs; return E; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 446eb9ed6d..f02dd25824 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -400,8 +400,7 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { return Owned(DependentScopeDeclRefExpr::Create(Context, - static_cast(SS.getScopeRep()), - SS.getRange(), + SS.getWithLocInContext(Context), NameInfo, TemplateArgs)); } @@ -2332,9 +2331,13 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, DeclarationNameInfo NameInfo(DTN->getIdentifier(), Arg.getTemplateNameLoc()); + // FIXME: TemplateArgumentLoc should store a NestedNameSpecifierLoc + // for the template name. + CXXScopeSpec SS; + SS.MakeTrivial(Context, DTN->getQualifier(), + Arg.getTemplateQualifierRange()); Expr *E = DependentScopeDeclRefExpr::Create(Context, - DTN->getQualifier(), - Arg.getTemplateQualifierRange(), + SS.getWithLocInContext(Context), NameInfo); // If we parsed the template argument as a pack expansion, create a diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 4869ce6db6..57a44ad9d9 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1887,12 +1887,12 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS, - SourceRange QualifierRange, + ExprResult RebuildDependentScopeDeclRefExpr( + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, NNS, QualifierRange); + SS.Adopt(QualifierLoc); if (TemplateArgs) return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo, @@ -6787,10 +6787,9 @@ template ExprResult TreeTransform::TransformDependentScopeDeclRefExpr( DependentScopeDeclRefExpr *E) { - NestedNameSpecifier *NNS - = getDerived().TransformNestedNameSpecifier(E->getQualifier(), - E->getQualifierRange()); - if (!NNS) + NestedNameSpecifierLoc QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); + if (!QualifierLoc) return ExprError(); // TODO: If this is a conversion-function-id, verify that the @@ -6804,14 +6803,13 @@ TreeTransform::TransformDependentScopeDeclRefExpr( if (!E->hasExplicitTemplateArgs()) { if (!getDerived().AlwaysRebuild() && - NNS == E->getQualifier() && + QualifierLoc == E->getQualifierLoc() && // Note: it is sufficient to compare the Name component of NameInfo: // if name has not changed, DNLoc has not changed either. NameInfo.getName() == E->getDeclName()) return SemaRef.Owned(E); - return getDerived().RebuildDependentScopeDeclRefExpr(NNS, - E->getQualifierRange(), + return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, NameInfo, /*TemplateArgs*/ 0); } @@ -6822,8 +6820,7 @@ TreeTransform::TransformDependentScopeDeclRefExpr( TransArgs)) return ExprError(); - return getDerived().RebuildDependentScopeDeclRefExpr(NNS, - E->getQualifierRange(), + return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, NameInfo, &TransArgs); } diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 34c37298d4..42f0b1aace 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1219,10 +1219,9 @@ ASTStmtReader::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { if (Record[Idx++]) ReadExplicitTemplateArgumentList(E->getExplicitTemplateArgs(), Record[Idx++]); - + + E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); ReadDeclarationNameInfo(E->NameInfo, Record, Idx); - E->setQualifierRange(ReadSourceRange(Record, Idx)); - E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); } void diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 587b687cfb..af846a9280 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1216,9 +1216,8 @@ ASTStmtWriter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { AddExplicitTemplateArgumentList(Args); } + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); Writer.AddDeclarationNameInfo(E->NameInfo, Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); Code = serialization::EXPR_CXX_DEPENDENT_SCOPE_DECL_REF; } diff --git a/test/SemaCXX/nested-name-spec-locations.cpp b/test/SemaCXX/nested-name-spec-locations.cpp index 85ebd90288..25914df627 100644 --- a/test/SemaCXX/nested-name-spec-locations.cpp +++ b/test/SemaCXX/nested-name-spec-locations.cpp @@ -61,3 +61,10 @@ void PseudoDestructorExprCheck( PseudoDestructorExprTester tester) { tester.f(0); // expected-note{{in instantiation of member function}} } + +template +struct DependentScopedDeclRefExpr { + void f() { + outer_alias::inner::X0::value = 17; + } +}; diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index bddf3d82ff..cd1b8d6667 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1864,8 +1864,7 @@ void EnqueueVisitor::VisitDeclRefExpr(DeclRefExpr *DR) { void EnqueueVisitor::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) { AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs()); AddDeclarationNameInfo(E); - if (NestedNameSpecifier *Qualifier = E->getQualifier()) - AddNestedNameSpecifier(Qualifier, E->getQualifierRange()); + AddNestedNameSpecifierLoc(E->getQualifierLoc()); } void EnqueueVisitor::VisitDeclStmt(DeclStmt *S) { unsigned size = WL.size(); -- 2.40.0