From ea972d3faaad383c0401c7041a406b1ecaea378d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 28 Feb 2011 21:54:11 +0000 Subject: [PATCH] Push nested-name-specifier location information into DeclRefExpr and MemberExpr, the last of the expressions with qualifiers! llvm-svn: 126688 --- clang/include/clang/AST/Expr.h | 66 +++++++++---------- clang/include/clang/AST/RecursiveASTVisitor.h | 5 +- clang/lib/AST/ASTImporter.cpp | 4 +- clang/lib/AST/Expr.cpp | 46 ++++++------- clang/lib/Sema/SemaDeclCXX.cpp | 4 +- clang/lib/Sema/SemaExpr.cpp | 13 +--- clang/lib/Sema/SemaExprCXX.cpp | 3 +- clang/lib/Sema/SemaOverload.cpp | 12 +--- clang/lib/Sema/TreeTransform.h | 52 +++++++-------- clang/lib/Serialization/ASTReaderStmt.cpp | 12 ++-- clang/lib/Serialization/ASTWriterStmt.cpp | 12 ++-- .../Index/annotate-nested-name-specifier.cpp | 54 ++++++++++++++- clang/tools/libclang/CIndex.cpp | 8 +-- 13 files changed, 152 insertions(+), 139 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 95bfad5a16c2..a1157c09c01b 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -621,11 +621,9 @@ public: /// \brief Represents the qualifier that may precede a C++ name, e.g., the /// "std::" in "std::sort". struct NameQualifier { - /// \brief The nested name specifier. - NestedNameSpecifier *NNS; - - /// \brief The source range covered by the nested name specifier. - SourceRange Range; + /// \brief The nested-name-specifier that qualifies the name, including + /// source-location information. + NestedNameSpecifierLoc QualifierLoc; }; /// \brief Represents an explicit template argument list in C++, e.g., @@ -698,12 +696,12 @@ class DeclRefExpr : public Expr { return const_cast(this)->getNameQualifier(); } - DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, + DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK); - DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, + DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK); @@ -724,16 +722,14 @@ public: } static DeclRefExpr *Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, SourceLocation NameLoc, QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs = 0); static DeclRefExpr *Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, @@ -761,25 +757,24 @@ public: /// C++ nested-name-specifier, e.g., \c N::foo. bool hasQualifier() const { return DecoratedD.getInt() & HasQualifierFlag; } - /// \brief If the name was qualified, retrieves the source range of - /// the nested-name-specifier that precedes the name. Otherwise, - /// returns an empty source range. - SourceRange getQualifierRange() const { - if (!hasQualifier()) - return SourceRange(); - - return getNameQualifier()->Range; - } - /// \brief If the name was qualified, retrieves the nested-name-specifier /// that precedes the name. Otherwise, returns NULL. NestedNameSpecifier *getQualifier() const { if (!hasQualifier()) return 0; - return getNameQualifier()->NNS; + return getNameQualifier()->QualifierLoc.getNestedNameSpecifier(); } - + + /// \brief If the name was qualified, retrieves the nested-name-specifier + /// that precedes the name, with source-location information. + NestedNameSpecifierLoc getQualifierLoc() const { + if (!hasQualifier()) + return NestedNameSpecifierLoc(); + + return getNameQualifier()->QualifierLoc; + } + bool hasExplicitTemplateArgs() const { return (DecoratedD.getInt() & HasExplicitTemplateArgumentListFlag); } @@ -1936,7 +1931,7 @@ public: HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {} static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, - NestedNameSpecifier *qual, SourceRange qualrange, + NestedNameSpecifierLoc QualifierLoc, ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *targs, @@ -1965,16 +1960,6 @@ public: /// x->Base::foo. bool hasQualifier() const { return getQualifier() != 0; } - /// \brief If the member name was qualified, retrieves the source range of - /// the nested-name-specifier that precedes the member name. Otherwise, - /// returns an empty source range. - SourceRange getQualifierRange() const { - if (!HasQualifierOrFoundDecl) - return SourceRange(); - - return getMemberQualifier()->Range; - } - /// \brief If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name. Otherwise, returns /// NULL. @@ -1982,7 +1967,17 @@ public: if (!HasQualifierOrFoundDecl) return 0; - return getMemberQualifier()->NNS; + return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier(); + } + + /// \brief If the member name was qualified, retrieves the + /// nested-name-specifier that precedes the member name, with source-location + /// information. + NestedNameSpecifierLoc getQualifierLoc() const { + if (!hasQualifier()) + return NestedNameSpecifierLoc(); + + return getMemberQualifier()->QualifierLoc; } /// \brief Determines whether this member expression actually had a C++ @@ -2078,6 +2073,7 @@ public: SourceRange getSourceRange() const { // If we have an implicit base (like a C++ implicit this), // make sure not to return its location + // FIXME: This isn't the way to do the above. SourceLocation EndLoc = (HasExplicitTemplateArgumentList) ? getRAngleLoc() : getMemberNameInfo().getEndLoc(); diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index b0b6a71fd337..ebd16f8cc42e 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1692,7 +1692,7 @@ DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { }) DEF_TRAVERSE_STMT(DeclRefExpr, { - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); TRY_TO(TraverseTemplateArgumentLocsHelper( S->getTemplateArgs(), S->getNumTemplateArgs())); }) @@ -1707,10 +1707,9 @@ DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, { }) DEF_TRAVERSE_STMT(MemberExpr, { + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); TRY_TO(TraverseTemplateArgumentLocsHelper( S->getTemplateArgs(), S->getNumTemplateArgs())); - // FIXME: Should we be recursing on the qualifier? - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); }) DEF_TRAVERSE_STMT(ImplicitCastExpr, { diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 21f10fb7ad99..f4b0ff6aab7b 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3728,8 +3728,8 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { if (T.isNull()) return 0; - return DeclRefExpr::Create(Importer.getToContext(), Qualifier, - Importer.Import(E->getQualifierRange()), + return DeclRefExpr::Create(Importer.getToContext(), + Importer.Import(E->getQualifierLoc()), ToD, Importer.Import(E->getLocation()), T, E->getValueKind(), diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 1c1061b5a229..8e44c073682b 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -276,20 +276,18 @@ void DeclRefExpr::computeDependence() { ExprBits.ContainsUnexpandedParameterPack = true; } -DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, +DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), DecoratedD(D, - (Qualifier? HasQualifierFlag : 0) | + (QualifierLoc? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), Loc(NameLoc) { - if (Qualifier) { + if (QualifierLoc) { NameQualifier *NQ = getNameQualifier(); - NQ->NNS = Qualifier; - NQ->Range = QualifierRange; + NQ->QualifierLoc = QualifierLoc; } if (TemplateArgs) @@ -298,20 +296,18 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, computeDependence(); } -DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, +DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), DecoratedD(D, - (Qualifier? HasQualifierFlag : 0) | + (QualifierLoc? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { - if (Qualifier) { + if (QualifierLoc) { NameQualifier *NQ = getNameQualifier(); - NQ->NNS = Qualifier; - NQ->Range = QualifierRange; + NQ->QualifierLoc = QualifierLoc; } if (TemplateArgs) @@ -321,36 +317,33 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, SourceLocation NameLoc, QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs) { - return Create(Context, Qualifier, QualifierRange, D, + return Create(Context, QualifierLoc, D, DeclarationNameInfo(D->getDeclName(), NameLoc), T, VK, TemplateArgs); } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, ValueDecl *D, const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs) { std::size_t Size = sizeof(DeclRefExpr); - if (Qualifier != 0) + if (QualifierLoc != 0) Size += sizeof(NameQualifier); if (TemplateArgs) Size += ExplicitTemplateArgumentList::sizeFor(*TemplateArgs); void *Mem = Context.Allocate(Size, llvm::alignOf()); - return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo, - TemplateArgs, T, VK); + return new (Mem) DeclRefExpr(QualifierLoc, D, NameInfo, TemplateArgs, T, VK); } DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, @@ -371,7 +364,7 @@ DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, SourceRange DeclRefExpr::getSourceRange() const { SourceRange R = getNameInfo().getSourceRange(); if (hasQualifier()) - R.setBegin(getQualifierRange().getBegin()); + R.setBegin(getQualifierLoc().getBeginLoc()); if (hasExplicitTemplateArgs()) R.setEnd(getRAngleLoc()); return R; @@ -906,8 +899,7 @@ IdentifierInfo *OffsetOfExpr::OffsetOfNode::getFieldName() const { } MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, - NestedNameSpecifier *qual, - SourceRange qualrange, + NestedNameSpecifierLoc QualifierLoc, ValueDecl *memberdecl, DeclAccessPair founddecl, DeclarationNameInfo nameinfo, @@ -917,7 +909,7 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, ExprObjectKind ok) { std::size_t Size = sizeof(MemberExpr); - bool hasQualOrFound = (qual != 0 || + bool hasQualOrFound = (QualifierLoc || founddecl.getDecl() != memberdecl || founddecl.getAccess() != memberdecl->getAccess()); if (hasQualOrFound) @@ -931,15 +923,15 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, ty, vk, ok); if (hasQualOrFound) { - if (qual && qual->isDependent()) { + // FIXME: Wrong. We should be looking at the member declaration we found. + if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) { E->setValueDependent(true); E->setTypeDependent(true); } E->HasQualifierOrFoundDecl = true; MemberNameQualifier *NQ = E->getMemberQualifier(); - NQ->NNS = qual; - NQ->Range = qualrange; + NQ->QualifierLoc = QualifierLoc; NQ->FoundDecl = founddecl; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 457ae8594131..1205974f30e5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1728,7 +1728,7 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, QualType ParamType = Param->getType().getNonReferenceType(); Expr *CopyCtorArg = - DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, + DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), Param, Constructor->getLocation(), ParamType, VK_LValue, 0); @@ -1789,7 +1789,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, QualType ParamType = Param->getType().getNonReferenceType(); Expr *MemberExprBase = - DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, + DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), Param, Loc, ParamType, VK_LValue, 0); // Build a reference to this field within the parameter. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6c8398ea64d9..ae0ed3e4f168 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -974,8 +974,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, MarkDeclarationReferenced(NameInfo.getLoc(), D); Expr *E = DeclRefExpr::Create(Context, - SS? (NestedNameSpecifier *)SS->getScopeRep() : 0, - SS? SS->getRange() : SourceRange(), + SS? SS->getWithLocInContext(Context) + : NestedNameSpecifierLoc(), D, NameInfo, Ty, VK); // Just in case we're building an illegal pointer-to-member. @@ -2064,14 +2064,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = 0) { - NestedNameSpecifier *Qualifier = 0; - SourceRange QualifierRange; - if (SS.isSet()) { - Qualifier = (NestedNameSpecifier *) SS.getScopeRep(); - QualifierRange = SS.getRange(); - } - - return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange, + return MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C), Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index bdbb90839af5..5266d7d18532 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1783,7 +1783,8 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, diag::err_invalid_use_of_array_type) << ConditionVar->getSourceRange()); - Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, + Expr *Condition = DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), + ConditionVar, ConditionVar->getLocation(), ConditionVar->getType().getNonReferenceType(), VK_LValue); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8893ab48586a..f5316b564e2e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -8928,10 +8928,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, TemplateArgs = &TemplateArgsBuffer; } - // FIXME: Nested-name-specifier source location information for DeclRefExpr. return DeclRefExpr::Create(Context, - ULE->getQualifier(), - ULE->getQualifierLoc().getSourceRange(), + ULE->getQualifierLoc(), Fn, ULE->getNameLoc(), Fn->getType(), @@ -8952,11 +8950,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, // If we're filling in a static method where we used to have an // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { - // FIXME: Source location information for DeclRefExpr if (cast(Fn)->isStatic()) { return DeclRefExpr::Create(Context, - MemExpr->getQualifier(), - MemExpr->getQualifierLoc().getSourceRange(), + MemExpr->getQualifierLoc(), Fn, MemExpr->getMemberLoc(), Fn->getType(), @@ -8973,11 +8969,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, } else Base = MemExpr->getBase(); - // FIXME: Source location information for MemberExpr return MemberExpr::Create(Context, Base, MemExpr->isArrow(), - MemExpr->getQualifier(), - MemExpr->getQualifierLoc().getSourceRange(), + MemExpr->getQualifierLoc(), Fn, Found, MemExpr->getMemberNameInfo(), diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 6514b2e65e29..d0de1df65072 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1264,13 +1264,12 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *VD, const DeclarationNameInfo &NameInfo, TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange); + SS.Adopt(QualifierLoc); // FIXME: loses template args. @@ -1378,8 +1377,7 @@ public: /// Subclasses may override this routine to provide different behavior. ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, bool isArrow, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &MemberNameInfo, ValueDecl *Member, NamedDecl *FoundDecl, @@ -1389,11 +1387,12 @@ public: // We have a reference to an unnamed field. This is always the // base of an anonymous struct/union member access, i.e. the // field is always of record type. - assert(!Qualifier && "Can't have an unnamed field with a qualifier!"); + assert(!QualifierLoc && "Can't have an unnamed field with a qualifier!"); assert(Member->getType()->isRecordType() && "unnamed member not of record type?"); - if (getSema().PerformObjectMemberConversion(Base, Qualifier, + if (getSema().PerformObjectMemberConversion(Base, + QualifierLoc.getNestedNameSpecifier(), FoundDecl, Member)) return ExprError(); @@ -1407,9 +1406,7 @@ public: } CXXScopeSpec SS; - if (Qualifier) { - SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange); - } + SS.Adopt(QualifierLoc); getSema().DefaultFunctionArrayConversion(Base); QualType BaseType = Base->getType(); @@ -5438,11 +5435,11 @@ TreeTransform::TransformPredefinedExpr(PredefinedExpr *E) { template ExprResult TreeTransform::TransformDeclRefExpr(DeclRefExpr *E) { - NestedNameSpecifier *Qualifier = 0; - if (E->getQualifier()) { - Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(), - E->getQualifierRange()); - if (!Qualifier) + NestedNameSpecifierLoc QualifierLoc; + if (E->getQualifierLoc()) { + QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); + if (!QualifierLoc) return ExprError(); } @@ -5460,7 +5457,7 @@ TreeTransform::TransformDeclRefExpr(DeclRefExpr *E) { } if (!getDerived().AlwaysRebuild() && - Qualifier == E->getQualifier() && + QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() && NameInfo.getName() == E->getDecl()->getDeclName() && !E->hasExplicitTemplateArgs()) { @@ -5483,8 +5480,8 @@ TreeTransform::TransformDeclRefExpr(DeclRefExpr *E) { return ExprError(); } - return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(), - ND, NameInfo, TemplateArgs); + return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo, + TemplateArgs); } template @@ -5716,12 +5713,12 @@ TreeTransform::TransformMemberExpr(MemberExpr *E) { if (Base.isInvalid()) return ExprError(); - NestedNameSpecifier *Qualifier = 0; + NestedNameSpecifierLoc QualifierLoc; if (E->hasQualifier()) { - Qualifier - = getDerived().TransformNestedNameSpecifier(E->getQualifier(), - E->getQualifierRange()); - if (Qualifier == 0) + QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); + + if (!QualifierLoc) return ExprError(); } @@ -5743,7 +5740,7 @@ TreeTransform::TransformMemberExpr(MemberExpr *E) { if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && - Qualifier == E->getQualifier() && + QualifierLoc == E->getQualifierLoc() && Member == E->getMemberDecl() && FoundDecl == E->getFoundDecl() && !E->hasExplicitTemplateArgs()) { @@ -5776,8 +5773,7 @@ TreeTransform::TransformMemberExpr(MemberExpr *E) { return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, E->isArrow(), - Qualifier, - E->getQualifierRange(), + QualifierLoc, E->getMemberNameInfo(), Member, FoundDecl, @@ -7555,8 +7551,6 @@ TreeTransform::TransformBlockExpr(BlockExpr *E) { template ExprResult TreeTransform::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) { - NestedNameSpecifier *Qualifier = 0; - ValueDecl *ND = cast_or_null(getDerived().TransformDecl(E->getLocation(), E->getDecl())); @@ -7573,7 +7567,7 @@ TreeTransform::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) { } DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation()); - return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(), + return getDerived().RebuildDeclRefExpr(NestedNameSpecifierLoc(), ND, NameInfo, 0); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 86e9cdc3cb18..9bf417c7b133 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -429,8 +429,8 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) { ? DeclRefExpr::HasExplicitTemplateArgumentListFlag : 0)); if (HasQualifier) { - E->getNameQualifier()->NNS = Reader.ReadNestedNameSpecifier(Record, Idx); - E->getNameQualifier()->Range = ReadSourceRange(Record, Idx); + E->getNameQualifier()->QualifierLoc + = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); } if (HasExplicitTemplateArgs) { @@ -1563,11 +1563,9 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { // logic with a MemberExpr::CreateEmpty. assert(Idx == 0); - NestedNameSpecifier *NNS = 0; - SourceRange QualifierRange; + NestedNameSpecifierLoc QualifierLoc; if (Record[Idx++]) { // HasQualifier. - NNS = ReadNestedNameSpecifier(Record, Idx); - QualifierRange = ReadSourceRange(F, Record, Idx); + QualifierLoc = ReadNestedNameSpecifierLoc(F, Record, Idx); } TemplateArgumentListInfo ArgInfo; @@ -1593,7 +1591,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { DeclarationNameInfo MemberNameInfo(MemberD->getDeclName(), MemberLoc); bool IsArrow = Record[Idx++]; - S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange, + S = MemberExpr::Create(*Context, Base, IsArrow, QualifierLoc, MemberD, FoundDecl, MemberNameInfo, HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK); ReadDeclarationNameLoc(F, cast(S)->MemberDNLoc, diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index da194d3aa099..21f1d512532f 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -382,10 +382,8 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) { Record.push_back(E->hasQualifier()); Record.push_back(E->hasExplicitTemplateArgs()); - if (E->hasQualifier()) { - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); - } + if (E->hasQualifier()) + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); if (E->hasExplicitTemplateArgs()) { unsigned NumTemplateArgs = E->getNumTemplateArgs(); @@ -541,10 +539,8 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *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); - } + if (E->hasQualifier()) + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); Record.push_back(E->hasExplicitTemplateArgs()); if (E->hasExplicitTemplateArgs()) { diff --git a/clang/test/Index/annotate-nested-name-specifier.cpp b/clang/test/Index/annotate-nested-name-specifier.cpp index e29d5da9128a..766f21a5b6f6 100644 --- a/clang/test/Index/annotate-nested-name-specifier.cpp +++ b/clang/test/Index/annotate-nested-name-specifier.cpp @@ -61,7 +61,7 @@ struct X3 { namespace outer { namespace inner { void f(int); - void f(float); + void f(double); } } @@ -78,7 +78,22 @@ struct X4 { } }; -// RUN: c-index-test -test-annotate-tokens=%s:13:1:78:1 %s | FileCheck %s +typedef int Integer; +template<> +struct X4 { + typedef Integer type; + + void g(int); + void g(float); + + void h(type t) { + ::outer_alias::inner::f(t); + ::X4::g(t); + this->::X4::g(t); + } +}; + +// RUN: c-index-test -test-annotate-tokens=%s:13:1:93:1 %s | FileCheck %s // CHECK: Keyword: "using" [14:1 - 14:6] UsingDeclaration=vector[4:12] // CHECK: Identifier: "outer_alias" [14:7 - 14:18] NamespaceRef=outer_alias:10:11 @@ -202,3 +217,38 @@ struct X4 { // CHECK: Punctuation: "(" [77:24 - 77:25] CallExpr= // CHECK: Identifier: "t" [77:25 - 77:26] DeclRefExpr=t:74:12 // CHECK: Punctuation: ")" [77:26 - 77:27] CallExpr= + +// Resolved member and non-member references +// CHECK: Punctuation: "::" [90:5 - 90:7] DeclRefExpr=f:63:10 +// CHECK: Identifier: "outer_alias" [90:7 - 90:18] NamespaceRef=outer_alias:10:11 +// CHECK: Punctuation: "::" [90:18 - 90:20] DeclRefExpr=f:63:10 +// CHECK: Identifier: "inner" [90:20 - 90:25] NamespaceRef=inner:62:13 +// CHECK: Punctuation: "::" [90:25 - 90:27] DeclRefExpr=f:63:10 +// CHECK: Identifier: "f" [90:27 - 90:28] DeclRefExpr=f:63:10 +// CHECK: Punctuation: "(" [90:28 - 90:29] CallExpr=f:63:10 +// CHECK: Identifier: "t" [90:29 - 90:30] DeclRefExpr=t:89:15 +// CHECK: Punctuation: ")" [90:30 - 90:31] CallExpr=f:63:10 +// CHECK: Punctuation: ";" [90:31 - 90:32] UnexposedStmt= +// CHECK: Punctuation: "::" [91:5 - 91:7] MemberRefExpr=g:86:8 +// CHECK: Identifier: "X4" [91:7 - 91:9] TemplateRef=X4:69:8 +// CHECK: Punctuation: "<" [91:9 - 91:10] MemberRefExpr=g:86:8 +// CHECK: Identifier: "type" [91:10 - 91:14] TypeRef=type:84:19 +// CHECK: Punctuation: ">" [91:14 - 91:15] MemberRefExpr=g:86:8 +// CHECK: Punctuation: "::" [91:15 - 91:17] MemberRefExpr=g:86:8 +// CHECK: Identifier: "g" [91:17 - 91:18] MemberRefExpr=g:86:8 +// CHECK: Punctuation: "(" [91:18 - 91:19] CallExpr=g:86:8 +// CHECK: Identifier: "t" [91:19 - 91:20] DeclRefExpr=t:89:15 +// CHECK: Punctuation: ")" [91:20 - 91:21] CallExpr=g:86:8 +// CHECK: Punctuation: ";" [91:21 - 91:22] UnexposedStmt= +// CHECK: Keyword: "this" [92:5 - 92:9] UnexposedExpr= +// CHECK: Punctuation: "->" [92:9 - 92:11] MemberRefExpr=g:86:8 +// CHECK: Punctuation: "::" [92:11 - 92:13] MemberRefExpr=g:86:8 +// CHECK: Identifier: "X4" [92:13 - 92:15] TemplateRef=X4:69:8 +// CHECK: Punctuation: "<" [92:15 - 92:16] MemberRefExpr=g:86:8 +// CHECK: Identifier: "type" [92:16 - 92:20] TypeRef=type:84:19 +// CHECK: Punctuation: ">" [92:20 - 92:21] MemberRefExpr=g:86:8 +// CHECK: Punctuation: "::" [92:21 - 92:23] MemberRefExpr=g:86:8 +// CHECK: Identifier: "g" [92:23 - 92:24] MemberRefExpr=g:86:8 +// CHECK: Punctuation: "(" [92:24 - 92:25] CallExpr=g:86:8 +// CHECK: Identifier: "t" [92:25 - 92:26] DeclRefExpr=t:89:15 +// CHECK: Punctuation: ")" [92:26 - 92:27] CallExpr=g:86:8 diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 09f7cf6b7160..c244bff50f02 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2124,8 +2124,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { MemberExpr *M = cast(&LI)->get(); // Visit the nested-name-specifier - if (NestedNameSpecifier *Qualifier = M->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, M->getQualifierRange())) + if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc()) + if (VisitNestedNameSpecifierLoc(QualifierLoc)) return true; // Visit the declaration name. @@ -2146,8 +2146,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { case VisitorJob::DeclRefExprPartsKind: { DeclRefExpr *DR = cast(&LI)->get(); // Visit nested-name-specifier, if present. - if (NestedNameSpecifier *Qualifier = DR->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, DR->getQualifierRange())) + if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc()) + if (VisitNestedNameSpecifierLoc(QualifierLoc)) return true; // Visit declaration name. if (VisitDeclarationNameInfo(DR->getNameInfo()))