diff options
-rw-r--r-- | include/clang/AST/ExprCXX.h | 75 | ||||
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 4 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 75 | ||||
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 26 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 30 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 19 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 3 | ||||
-rw-r--r-- | test/Index/annotate-nested-name-specifier.cpp | 56 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 4 |
12 files changed, 196 insertions, 127 deletions
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 6e71f29387..c904d9785c 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1590,18 +1590,15 @@ class OverloadExpr : public Expr { /// The common name of these declarations. DeclarationNameInfo NameInfo; - /// The scope specifier, if any. - NestedNameSpecifier *Qualifier; - - /// The source range of the scope specifier. - SourceRange QualifierRange; + /// \brief The nested-name-specifier that qualifies the name, if any. + NestedNameSpecifierLoc QualifierLoc; protected: /// True if the name was a template-id. bool HasExplicitTemplateArgs; OverloadExpr(StmtClass K, ASTContext &C, - NestedNameSpecifier *Qualifier, SourceRange QRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End, @@ -1610,7 +1607,7 @@ protected: OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty), Results(0), NumResults(0), - Qualifier(0), HasExplicitTemplateArgs(false) { } + QualifierLoc(), HasExplicitTemplateArgs(false) { } void initializeResults(ASTContext &C, UnresolvedSetIterator Begin, @@ -1665,23 +1662,21 @@ public: /// Gets the full name info. const DeclarationNameInfo &getNameInfo() const { return NameInfo; } - void setNameInfo(const DeclarationNameInfo &N) { NameInfo = N; } /// Gets the name looked up. DeclarationName getName() const { return NameInfo.getName(); } - void setName(DeclarationName N) { NameInfo.setName(N); } /// Gets the location of the name. SourceLocation getNameLoc() const { return NameInfo.getLoc(); } - void setNameLoc(SourceLocation Loc) { NameInfo.setLoc(Loc); } /// Fetches the nested-name qualifier, if one was given. - NestedNameSpecifier *getQualifier() const { return Qualifier; } - void setQualifier(NestedNameSpecifier *NNS) { Qualifier = NNS; } + NestedNameSpecifier *getQualifier() const { + return QualifierLoc.getNestedNameSpecifier(); + } - /// Fetches the range of the nested-name qualifier. - SourceRange getQualifierRange() const { return QualifierRange; } - void setQualifierRange(SourceRange R) { QualifierRange = R; } + /// Fetches the nested-name qualifier with source-location information, if + /// one was given. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } /// \brief Determines whether this expression had an explicit /// template argument list, e.g. f<int>. @@ -1740,12 +1735,12 @@ class UnresolvedLookupExpr : public OverloadExpr { UnresolvedLookupExpr(ASTContext &C, CXXRecordDecl *NamingClass, - NestedNameSpecifier *Qualifier, SourceRange QRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedLookupExprClass, C, Qualifier, QRange, NameInfo, + : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, NameInfo, TemplateArgs, Begin, End), RequiresADL(RequiresADL), Overloaded(Overloaded), NamingClass(NamingClass) {} @@ -1755,24 +1750,23 @@ class UnresolvedLookupExpr : public OverloadExpr { RequiresADL(false), Overloaded(false), NamingClass(0) {} + friend class ASTStmtReader; + public: static UnresolvedLookupExpr *Create(ASTContext &C, CXXRecordDecl *NamingClass, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End) { - return new(C) UnresolvedLookupExpr(C, NamingClass, Qualifier, - QualifierRange, NameInfo, ADL, - Overloaded, 0, Begin, End); + return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo, + ADL, Overloaded, 0, Begin, End); } static UnresolvedLookupExpr *Create(ASTContext &C, CXXRecordDecl *NamingClass, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, const TemplateArgumentListInfo &Args, @@ -1786,17 +1780,14 @@ public: /// True if this declaration should be extended by /// argument-dependent lookup. bool requiresADL() const { return RequiresADL; } - void setRequiresADL(bool V) { RequiresADL = V; } /// True if this lookup is overloaded. bool isOverloaded() const { return Overloaded; } - void setOverloaded(bool V) { Overloaded = V; } /// Gets the 'naming class' (in the sense of C++0x /// [class.access.base]p5) of the lookup. This is the scope /// that was looked in to find these results. CXXRecordDecl *getNamingClass() const { return NamingClass; } - void setNamingClass(CXXRecordDecl *D) { NamingClass = D; } // Note that, inconsistently with the explicit-template-argument AST // nodes, users are *forbidden* from calling these methods on objects @@ -1845,8 +1836,10 @@ public: SourceRange getSourceRange() const { SourceRange Range(getNameInfo().getSourceRange()); - if (getQualifier()) Range.setBegin(getQualifierRange().getBegin()); - if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); + if (getQualifierLoc()) + Range.setBegin(getQualifierLoc().getBeginLoc()); + if (hasExplicitTemplateArgs()) + Range.setEnd(getRAngleLoc()); return Range; } @@ -2235,7 +2228,7 @@ public: /// \brief True if this is an implicit access, i.e. one in which the /// member being accessed was not written in the source. The source /// location of the operator is invalid in this case. - bool isImplicitAccess() const { return Base == 0; } + bool isImplicitAccess() const; /// \brief Retrieve the base object of this member expressions, /// e.g., the \c x in \c x.m. @@ -2423,8 +2416,7 @@ class UnresolvedMemberExpr : public OverloadExpr { UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End); @@ -2433,13 +2425,14 @@ class UnresolvedMemberExpr : public OverloadExpr { : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), HasUnresolvedUsing(false), Base(0) { } + friend class ASTStmtReader; + public: static UnresolvedMemberExpr * Create(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End); @@ -2451,7 +2444,7 @@ public: /// \brief True if this is an implicit access, i.e. one in which the /// member being accessed was not written in the source. The source /// location of the operator is invalid in this case. - bool isImplicitAccess() const { return Base == 0; } + bool isImplicitAccess() const; /// \brief Retrieve the base object of this member expressions, /// e.g., the \c x in \c x.m. @@ -2463,24 +2456,19 @@ public: assert(!isImplicitAccess()); return cast<Expr>(Base); } - void setBase(Expr *E) { Base = E; } QualType getBaseType() const { return BaseType; } - void setBaseType(QualType T) { BaseType = T; } /// \brief Determine whether the lookup results contain an unresolved using /// declaration. bool hasUnresolvedUsing() const { return HasUnresolvedUsing; } - void setHasUnresolvedUsing(bool V) { HasUnresolvedUsing = V; } /// \brief Determine whether this member expression used the '->' /// operator; otherwise, it used the '.' operator. bool isArrow() const { return IsArrow; } - void setArrow(bool A) { IsArrow = A; } /// \brief Retrieve the location of the '->' or '.' operator. SourceLocation getOperatorLoc() const { return OperatorLoc; } - void setOperatorLoc(SourceLocation L) { OperatorLoc = L; } /// \brief Retrieves the naming class of this lookup. CXXRecordDecl *getNamingClass() const; @@ -2488,17 +2476,14 @@ public: /// \brief Retrieve the full name info for the member that this expression /// refers to. const DeclarationNameInfo &getMemberNameInfo() const { return getNameInfo(); } - void setMemberNameInfo(const DeclarationNameInfo &N) { setNameInfo(N); } /// \brief Retrieve the name of the member that this expression /// refers to. DeclarationName getMemberName() const { return getName(); } - void setMemberName(DeclarationName N) { setName(N); } // \brief Retrieve the location of the name of the member that this // expression refers to. SourceLocation getMemberLoc() const { return getNameLoc(); } - void setMemberLoc(SourceLocation L) { setNameLoc(L); } /// \brief Retrieve the explicit template argument list that followed the /// member template name. @@ -2555,8 +2540,8 @@ public: SourceRange Range = getMemberNameInfo().getSourceRange(); if (!isImplicitAccess()) Range.setBegin(Base->getSourceRange().getBegin()); - else if (getQualifier()) - Range.setBegin(getQualifierRange().getBegin()); + else if (getQualifierLoc()) + Range.setBegin(getQualifierLoc().getBeginLoc()); if (hasExplicitTemplateArgs()) Range.setEnd(getRAngleLoc()); diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 3a07690f11..b0b6a71fd3 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1869,7 +1869,7 @@ DEF_TRAVERSE_STMT(PredefinedExpr, { }) DEF_TRAVERSE_STMT(ShuffleVectorExpr, { }) DEF_TRAVERSE_STMT(StmtExpr, { }) DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (S->hasExplicitTemplateArgs()) { TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), S->getNumTemplateArgs())); @@ -1877,7 +1877,7 @@ DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { }) DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { - TRY_TO(TraverseNestedNameSpecifier(S->getQualifier())); + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); if (S->hasExplicitTemplateArgs()) { TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), S->getNumTemplateArgs())); diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index b1e60102ed..fb99dc9c86 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -174,8 +174,7 @@ SourceRange CXXPseudoDestructorExpr::getSourceRange() const { UnresolvedLookupExpr * UnresolvedLookupExpr::Create(ASTContext &C, CXXRecordDecl *NamingClass, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, const TemplateArgumentListInfo &Args, @@ -184,8 +183,7 @@ UnresolvedLookupExpr::Create(ASTContext &C, { void *Mem = C.Allocate(sizeof(UnresolvedLookupExpr) + ExplicitTemplateArgumentList::sizeFor(Args)); - return new (Mem) UnresolvedLookupExpr(C, NamingClass, - Qualifier, QualifierRange, NameInfo, + return new (Mem) UnresolvedLookupExpr(C, NamingClass, QualifierLoc, NameInfo, ADL, /*Overload*/ true, &Args, Begin, End); } @@ -204,7 +202,7 @@ UnresolvedLookupExpr::CreateEmpty(ASTContext &C, bool HasExplicitTemplateArgs, } OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, - NestedNameSpecifier *Qualifier, SourceRange QRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, @@ -215,10 +213,11 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, KnownDependent, (KnownContainsUnexpandedParameterPack || NameInfo.containsUnexpandedParameterPack() || - (Qualifier && Qualifier->containsUnexpandedParameterPack()))), + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier() + ->containsUnexpandedParameterPack()))), Results(0), NumResults(End - Begin), NameInfo(NameInfo), - Qualifier(Qualifier), QualifierRange(QRange), - HasExplicitTemplateArgs(TemplateArgs != 0) + QualifierLoc(QualifierLoc), HasExplicitTemplateArgs(TemplateArgs != 0) { NumResults = End - Begin; if (NumResults) { @@ -784,19 +783,59 @@ CXXDependentScopeMemberExpr::CreateEmpty(ASTContext &C, return E; } +/// \brief Determine whether this expression is an implicit C++ 'this'. +static bool isImplicitThis(const Expr *E) { + // Strip away parentheses and casts we don't care about. + while (true) { + if (const ParenExpr *Paren = dyn_cast<ParenExpr>(E)) { + E = Paren->getSubExpr(); + continue; + } + + if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { + if (ICE->getCastKind() == CK_NoOp || + ICE->getCastKind() == CK_LValueToRValue || + ICE->getCastKind() == CK_DerivedToBase || + ICE->getCastKind() == CK_UncheckedDerivedToBase) { + E = ICE->getSubExpr(); + continue; + } + } + + if (const UnaryOperator* UnOp = dyn_cast<UnaryOperator>(E)) { + if (UnOp->getOpcode() == UO_Extension) { + E = UnOp->getSubExpr(); + continue; + } + } + + break; + } + + if (const CXXThisExpr *This = dyn_cast<CXXThisExpr>(E)) + return This->isImplicit(); + + return false; +} + +bool CXXDependentScopeMemberExpr::isImplicitAccess() const { + if (Base == 0) + return true; + + return isImplicitThis(cast<Expr>(Base)); +} + UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedMemberExprClass, C, - Qualifier, QualifierRange, MemberNameInfo, + : OverloadExpr(UnresolvedMemberExprClass, C, QualifierLoc, MemberNameInfo, TemplateArgs, Begin, End, // Dependent ((Base && Base->isTypeDependent()) || @@ -808,13 +847,19 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) { } +bool UnresolvedMemberExpr::isImplicitAccess() const { + if (Base == 0) + return true; + + return isImplicitThis(cast<Expr>(Base)); +} + UnresolvedMemberExpr * UnresolvedMemberExpr::Create(ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, @@ -826,7 +871,7 @@ UnresolvedMemberExpr::Create(ASTContext &C, void *Mem = C.Allocate(size, llvm::alignOf<UnresolvedMemberExpr>()); return new (Mem) UnresolvedMemberExpr(C, HasUnresolvedUsing, Base, BaseType, - IsArrow, OperatorLoc, Qualifier, QualifierRange, + IsArrow, OperatorLoc, QualifierLoc, MemberNameInfo, TemplateArgs, Begin, End); } diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 506d2612ff..5b28bc3d9f 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -642,7 +642,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, if (SrcExpr->getType() == Self.Context.OverloadTy) { OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression; Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload) - << oe->getName() << DestType << OpRange << oe->getQualifierRange(); + << oe->getName() << DestType << OpRange + << oe->getQualifierLoc().getSourceRange(); Self.NoteAllOverloadCandidates(SrcExpr); } else { diagnoseBadCast(Self, msg, CT_Static, OpRange, SrcExpr, DestType); @@ -1289,7 +1290,7 @@ static ExprResult ResolveAndFixSingleFunctionTemplateSpecialization( OverloadExpr* oe = OverloadExpr::find(SrcExpr).Expression; Self.Diag(OpRangeForComplaining.getBegin(), DiagIDForComplaining) << oe->getName() << DestTypeForComplaining << OpRangeForComplaining - << oe->getQualifierRange(); + << oe->getQualifierLoc().getSourceRange(); Self.NoteAllOverloadCandidates(SrcExpr); } return SingleFunctionExpression; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2abbcf0acd..6c8398ea64 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1351,12 +1351,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, if (ULE->hasExplicitTemplateArgs()) ULE->copyTemplateArgumentsInto(TList); - // FIXME: We should have nested-name-specifier location info in - // the ULE itself. CXXScopeSpec SS; - SS.MakeTrivial(Context, ULE->getQualifier(), - ULE->getQualifierRange()); - + SS.Adopt(ULE->getQualifierLoc()); CXXDependentScopeMemberExpr *DepExpr = CXXDependentScopeMemberExpr::Create( Context, DepThis, DepThisType, true, SourceLocation(), @@ -2283,8 +2279,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), - (NestedNameSpecifier*) SS.getScopeRep(), - SS.getRange(), R.getLookupNameInfo(), + SS.getWithLocInContext(Context), + R.getLookupNameInfo(), NeedsADL, R.isOverloadedResult(), R.begin(), R.end()); @@ -3483,7 +3479,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, } R.setBaseObjectType(BaseType); - NestedNameSpecifier *Qualifier = SS.getScopeRep(); const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo(); DeclarationName MemberName = MemberNameInfo.getName(); SourceLocation MemberLoc = MemberNameInfo.getLoc(); @@ -3528,7 +3523,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, = UnresolvedMemberExpr::Create(Context, R.isUnresolvableResult(), BaseExpr, BaseExprType, IsArrow, OpLoc, - Qualifier, SS.getRange(), + SS.getWithLocInContext(Context), MemberNameInfo, TemplateArgs, R.begin(), R.end()); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 8d03285ee4..8893ab4858 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7590,9 +7590,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, SourceLocation RParenLoc) { CXXScopeSpec SS; - if (ULE->getQualifier()) - SS.MakeTrivial(SemaRef.Context, - ULE->getQualifier(), ULE->getQualifierRange()); + SS.Adopt(ULE->getQualifierLoc()); TemplateArgumentListInfo TABuffer; const TemplateArgumentListInfo *ExplicitTemplateArgs = 0; @@ -7776,11 +7774,11 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, NamingClass, - 0, SourceRange(), OpNameInfo, + NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, - &Args[0], NumArgs, + &Args[0], NumArgs, Context.DependentTy, VK_RValue, OpLoc)); @@ -7956,8 +7954,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // TODO: provide better source location info in DNLoc component. DeclarationNameInfo OpNameInfo(OpName, OpLoc); UnresolvedLookupExpr *Fn - = UnresolvedLookupExpr::Create(Context, NamingClass, 0, SourceRange(), - OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), + = UnresolvedLookupExpr::Create(Context, NamingClass, + NestedNameSpecifierLoc(), OpNameInfo, + /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, 2, @@ -8187,7 +8186,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc)); UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, NamingClass, - 0, SourceRange(), OpNameInfo, + NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, /*Overloaded*/ false, UnresolvedSetIterator(), UnresolvedSetIterator()); @@ -8929,9 +8928,10 @@ 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->getQualifierRange(), + ULE->getQualifierLoc().getSourceRange(), Fn, ULE->getNameLoc(), Fn->getType(), @@ -8952,10 +8952,11 @@ 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<CXXMethodDecl>(Fn)->isStatic()) { return DeclRefExpr::Create(Context, MemExpr->getQualifier(), - MemExpr->getQualifierRange(), + MemExpr->getQualifierLoc().getSourceRange(), Fn, MemExpr->getMemberLoc(), Fn->getType(), @@ -8964,7 +8965,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, } else { SourceLocation Loc = MemExpr->getMemberLoc(); if (MemExpr->getQualifier()) - Loc = MemExpr->getQualifierRange().getBegin(); + Loc = MemExpr->getQualifierLoc().getBeginLoc(); Base = new (Context) CXXThisExpr(Loc, MemExpr->getBaseType(), /*isImplicit=*/true); @@ -8972,10 +8973,11 @@ 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->getQualifierRange(), + MemExpr->getQualifierLoc().getSourceRange(), Fn, Found, MemExpr->getMemberNameInfo(), diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 01850353fd..1c776fb765 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1832,8 +1832,8 @@ TypeResult Sema::ActOnTagTemplateIdType(CXXScopeSpec &SS, } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool RequiresADL, + LookupResult &R, + bool RequiresADL, const TemplateArgumentListInfo &TemplateArgs) { // FIXME: Can we do any checking at this point? I guess we could check the // template arguments that we have against the template name, if the template @@ -1849,19 +1849,12 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, assert(!R.empty() && "empty lookup results when building templateid"); assert(!R.isAmbiguous() && "ambiguous lookup when building templateid"); - NestedNameSpecifier *Qualifier = 0; - SourceRange QualifierRange; - if (SS.isSet()) { - Qualifier = static_cast<NestedNameSpecifier*>(SS.getScopeRep()); - QualifierRange = SS.getRange(); - } - // We don't want lookup warnings at this point. R.suppressDiagnostics(); UnresolvedLookupExpr *ULE = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), - Qualifier, QualifierRange, + SS.getWithLocInContext(Context), R.getLookupNameInfo(), RequiresADL, TemplateArgs, R.begin(), R.end()); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 4e2902690c..6514b2e65e 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2000,13 +2000,12 @@ public: QualType BaseType, SourceLocation OperatorLoc, bool IsArrow, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + NestedNameSpecifierLoc QualifierLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; - SS.MakeTrivial(SemaRef.Context, Qualifier, QualifierRange); + SS.Adopt(QualifierLoc); return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, OperatorLoc, IsArrow, @@ -6779,14 +6778,13 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( // Rebuild the nested-name qualifier, if present. CXXScopeSpec SS; - NestedNameSpecifier *Qualifier = 0; - if (Old->getQualifier()) { - Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(), - Old->getQualifierRange()); - if (!Qualifier) + if (Old->getQualifierLoc()) { + NestedNameSpecifierLoc QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); + if (!QualifierLoc) return ExprError(); - SS.MakeTrivial(SemaRef.Context, Qualifier, Old->getQualifierRange()); + SS.Adopt(QualifierLoc); } if (Old->getNamingClass()) { @@ -7139,12 +7137,11 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) BaseType = getDerived().TransformType(Old->getBaseType()); } - NestedNameSpecifier *Qualifier = 0; - if (Old->getQualifier()) { - Qualifier - = getDerived().TransformNestedNameSpecifier(Old->getQualifier(), - Old->getQualifierRange()); - if (Qualifier == 0) + NestedNameSpecifierLoc QualifierLoc; + if (Old->getQualifierLoc()) { + QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); + if (!QualifierLoc) return ExprError(); } @@ -7212,8 +7209,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) BaseType, Old->getOperatorLoc(), Old->isArrow(), - Qualifier, - Old->getQualifierRange(), + QualifierLoc, FirstQualifierInScope, R, (Old->hasExplicitTemplateArgs() diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index 24ff7e8bd9..86e9cdc3cb 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1253,24 +1253,23 @@ void ASTStmtReader::VisitOverloadExpr(OverloadExpr *E) { E->initializeResults(*Reader.getContext(), Decls.begin(), Decls.end()); ReadDeclarationNameInfo(E->NameInfo, Record, Idx); - E->setQualifier(Reader.ReadNestedNameSpecifier(Record, Idx)); - E->setQualifierRange(ReadSourceRange(Record, Idx)); + E->QualifierLoc = Reader.ReadNestedNameSpecifierLoc(F, Record, Idx); } void ASTStmtReader::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { VisitOverloadExpr(E); - E->setArrow(Record[Idx++]); - E->setHasUnresolvedUsing(Record[Idx++]); - E->setBase(Reader.ReadSubExpr()); - E->setBaseType(Reader.GetType(Record[Idx++])); - E->setOperatorLoc(ReadSourceLocation(Record, Idx)); + E->IsArrow = Record[Idx++]; + E->HasUnresolvedUsing = Record[Idx++]; + E->Base = Reader.ReadSubExpr(); + E->BaseType = Reader.GetType(Record[Idx++]); + E->OperatorLoc = ReadSourceLocation(Record, Idx); } void ASTStmtReader::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) { VisitOverloadExpr(E); - E->setRequiresADL(Record[Idx++]); - E->setOverloaded(Record[Idx++]); - E->setNamingClass(cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]))); + E->RequiresADL = Record[Idx++]; + E->Overloaded = Record[Idx++]; + E->NamingClass = cast_or_null<CXXRecordDecl>(Reader.GetDecl(Record[Idx++])); } void ASTStmtReader::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 6e81ebbd1b..da194d3aa0 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1252,8 +1252,7 @@ void ASTStmtWriter::VisitOverloadExpr(OverloadExpr *E) { } Writer.AddDeclarationNameInfo(E->NameInfo, Record); - Writer.AddNestedNameSpecifier(E->getQualifier(), Record); - Writer.AddSourceRange(E->getQualifierRange(), Record); + Writer.AddNestedNameSpecifierLoc(E->getQualifierLoc(), Record); } void ASTStmtWriter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) { diff --git a/test/Index/annotate-nested-name-specifier.cpp b/test/Index/annotate-nested-name-specifier.cpp index 70d84889e9..e29d5da912 100644 --- a/test/Index/annotate-nested-name-specifier.cpp +++ b/test/Index/annotate-nested-name-specifier.cpp @@ -58,7 +58,27 @@ struct X3 { } }; -// RUN: c-index-test -test-annotate-tokens=%s:13:1:60:1 %s | FileCheck %s +namespace outer { + namespace inner { + void f(int); + void f(float); + } +} + +template<typename T> +struct X4 { + typedef T type; + void g(int); + void g(float); + + void h(T t) { + ::outer_alias::inner::f(t); + ::X4<type>::g(t); + this->::X4<type>::g(t); + } +}; + +// RUN: c-index-test -test-annotate-tokens=%s:13:1:78: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 @@ -148,3 +168,37 @@ struct X3 { // CHECK: Punctuation: ">" [57:59 - 57:60] UnexposedExpr= // CHECK: Punctuation: "(" [57:60 - 57:61] CallExpr= // CHECK: Punctuation: ")" [57:61 - 57:62] CallExpr= + +// Unresolved member and non-member references +// CHECK: Punctuation: "::" [75:5 - 75:7] UnexposedExpr=[63:10, 64:10] +// CHECK: Identifier: "outer_alias" [75:7 - 75:18] NamespaceRef=outer_alias:10:11 +// CHECK: Punctuation: "::" [75:18 - 75:20] UnexposedExpr=[63:10, 64:10] +// CHECK: Identifier: "inner" [75:20 - 75:25] NamespaceRef=inner:62:13 +// CHECK: Punctuation: "::" [75:25 - 75:27] UnexposedExpr=[63:10, 64:10] +// CHECK: Identifier: "f" [75:27 - 75:28] OverloadedDeclRef=f[63:10, 64:10] +// CHECK: Punctuation: "(" [75:28 - 75:29] CallExpr= +// CHECK: Identifier: "t" [75:29 - 75:30] DeclRefExpr=t:74:12 +// CHECK: Punctuation: ")" [75:30 - 75:31] CallExpr= +// CHECK: Punctuation: "::" [76:5 - 76:7] UnexposedExpr=[71:8, 72:8] +// CHECK: Identifier: "X4" [76:7 - 76:9] TemplateRef=X4:69:8 +// CHECK: Punctuation: "<" [76:9 - 76:10] UnexposedExpr=[71:8, 72:8] +// CHECK: Identifier: "type" [76:10 - 76:14] TypeRef=type:70:13 +// CHECK: Punctuation: ">" [76:14 - 76:15] UnexposedExpr=[71:8, 72:8] +// CHECK: Punctuation: "::" [76:15 - 76:17] UnexposedExpr=[71:8, 72:8] +// CHECK: Identifier: "g" [76:17 - 76:18] OverloadedDeclRef=g[71:8, 72:8] +// CHECK: Punctuation: "(" [76:18 - 76:19] CallExpr= +// CHECK: Identifier: "t" [76:19 - 76:20] DeclRefExpr=t:74:12 +// CHECK: Punctuation: ")" [76:20 - 76:21] CallExpr= +// CHECK: Punctuation: ";" [76:21 - 76:22] UnexposedStmt= +// CHECK: Keyword: "this" [77:5 - 77:9] UnexposedExpr= +// CHECK: Punctuation: "->" [77:9 - 77:11] UnexposedExpr= +// CHECK: Punctuation: "::" [77:11 - 77:13] UnexposedExpr= +// CHECK: Identifier: "X4" [77:13 - 77:15] TemplateRef=X4:69:8 +// CHECK: Punctuation: "<" [77:15 - 77:16] UnexposedExpr= +// CHECK: Identifier: "type" [77:16 - 77:20] TypeRef=type:70:13 +// CHECK: Punctuation: ">" [77:20 - 77:21] UnexposedExpr= +// CHECK: Punctuation: "::" [77:21 - 77:23] UnexposedExpr= +// CHECK: Identifier: "g" [77:23 - 77:24] UnexposedExpr= +// 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= diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 5df33eb573..09f7cf6b71 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -2157,8 +2157,8 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { case VisitorJob::OverloadExprPartsKind: { OverloadExpr *O = cast<OverloadExprParts>(&LI)->get(); // Visit the nested-name-specifier. - if (NestedNameSpecifier *Qualifier = O->getQualifier()) - if (VisitNestedNameSpecifier(Qualifier, O->getQualifierRange())) + if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc()) + if (VisitNestedNameSpecifierLoc(QualifierLoc)) return true; // Visit the declaration name. if (VisitDeclarationNameInfo(O->getNameInfo())) |