aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-02-28 20:01:57 +0000
committerDouglas Gregor <dgregor@apple.com>2011-02-28 20:01:57 +0000
commit4c9be89bb615ec07eb3ed507c8fa9d0baa8a5ad7 (patch)
treea1b918295232ef44468ada01cab55c79ded0b028
parent3d04a0e534b43504f6879657d47891625bd63352 (diff)
Push nested-name-specifier source location information into
UnresolvedLookupExpr and UnresolvedMemberExpr. Also, improve the computation that checks whether the base of a member expression (either unresolved or dependent-scoped) is implicit. The previous check didn't cover all of the cases we use in our representation, which threw off source-location information for these expressions (which, in turn, caused some breakage in libclang's token annotation). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126681 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ExprCXX.h75
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h4
-rw-r--r--lib/AST/ExprCXX.cpp75
-rw-r--r--lib/Sema/SemaCXXCast.cpp5
-rw-r--r--lib/Sema/SemaExpr.cpp13
-rw-r--r--lib/Sema/SemaOverload.cpp26
-rw-r--r--lib/Sema/SemaTemplate.cpp13
-rw-r--r--lib/Sema/TreeTransform.h30
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp19
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp3
-rw-r--r--test/Index/annotate-nested-name-specifier.cpp56
-rw-r--r--tools/libclang/CIndex.cpp4
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/