aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-11-17 02:14:36 +0000
committerJohn McCall <rjmccall@apple.com>2009-11-17 02:14:36 +0000
commita24dc2e38c7fb0f7f138b3d14b5f0f241fd0eccf (patch)
treed040e3cf363229c97136c3663a267a040760acd8
parent936d2a8a3968231199dddbc78378e8fddbab6e25 (diff)
Carry lookup configuration throughout lookup on the LookupResult. Give
LookupResult RAII powers to diagnose ambiguity in the results. Other diagnostics (e.g. access control and deprecation) will be moved to automatically trigger during lookup as part of this same mechanism. This abstraction makes it much easier to encapsulate aliasing declarations (e.g. using declarations) inside the lookup system: eventually, lookup will just produce the aliases in the LookupResult, and the standard access methods will naturally strip the aliases off. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89027 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/Sema.h179
-rw-r--r--lib/Sema/SemaAttr.cpp6
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp28
-rw-r--r--lib/Sema/SemaDecl.cpp80
-rw-r--r--lib/Sema/SemaDeclCXX.cpp37
-rw-r--r--lib/Sema/SemaExpr.cpp23
-rw-r--r--lib/Sema/SemaExprCXX.cpp16
-rw-r--r--lib/Sema/SemaLookup.cpp108
-rw-r--r--lib/Sema/SemaOverload.cpp18
-rw-r--r--lib/Sema/SemaTemplate.cpp40
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp13
11 files changed, 325 insertions, 223 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 011747a1dc..e6772dbe68 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1092,7 +1092,7 @@ public:
/// of multiple declarations.
class LookupResult {
public:
- enum LookupKind {
+ enum LookupResultKind {
/// @brief No entity found met the criteria.
NotFound = 0,
@@ -1173,24 +1173,86 @@ public:
AmbiguousTagHiding
};
+ enum RedeclarationKind {
+ NotForRedeclaration,
+ ForRedeclaration
+ };
+
+ /// A little identifier for flagging temporary lookup results.
+ enum TemporaryToken {
+ Temporary
+ };
+
typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
typedef DeclsTy::const_iterator iterator;
- LookupResult()
- : Kind(NotFound),
- Paths(0)
+ LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
+ LookupNameKind LookupKind,
+ RedeclarationKind Redecl = NotForRedeclaration)
+ : ResultKind(NotFound),
+ Paths(0),
+ SemaRef(SemaRef),
+ Name(Name),
+ NameLoc(NameLoc),
+ LookupKind(LookupKind),
+ IDNS(0),
+ Redecl(Redecl != NotForRedeclaration),
+ Diagnose(Redecl == NotForRedeclaration)
{}
+
+ /// Creates a temporary lookup result, initializing its core data
+ /// using the information from another result. Diagnostics are always
+ /// disabled.
+ LookupResult(TemporaryToken _, const LookupResult &Other)
+ : ResultKind(NotFound),
+ Paths(0),
+ SemaRef(Other.SemaRef),
+ Name(Other.Name),
+ NameLoc(Other.NameLoc),
+ LookupKind(Other.LookupKind),
+ IDNS(Other.IDNS),
+ Redecl(Other.Redecl),
+ Diagnose(false)
+ {}
+
~LookupResult() {
+ if (Diagnose) diagnose();
if (Paths) deletePaths(Paths);
}
+ /// Gets the name to look up.
+ DeclarationName getLookupName() const {
+ return Name;
+ }
+
+ /// Gets the kind of lookup to perform.
+ LookupNameKind getLookupKind() const {
+ return LookupKind;
+ }
+
+ /// True if this lookup is just looking for an existing declaration.
+ bool isForRedeclaration() const {
+ return Redecl;
+ }
+
+ /// The identifier namespace of this lookup. This information is
+ /// private to the lookup routines.
+ unsigned getIdentifierNamespace() const {
+ assert(IDNS);
+ return IDNS;
+ }
+
+ void setIdentifierNamespace(unsigned NS) {
+ IDNS = NS;
+ }
+
bool isAmbiguous() const {
- return getKind() == Ambiguous;
+ return getResultKind() == Ambiguous;
}
- LookupKind getKind() const {
+ LookupResultKind getResultKind() const {
sanity();
- return Kind;
+ return ResultKind;
}
AmbiguityKind getAmbiguityKind() const {
@@ -1226,14 +1288,14 @@ public:
}
} else
Decls.push_back(D->getUnderlyingDecl());
- Kind = Found;
+ ResultKind = Found;
}
/// \brief Add all the declarations from another set of lookup
/// results.
void addAllDecls(const LookupResult &Other) {
Decls.append(Other.begin(), Other.end());
- Kind = Found;
+ ResultKind = Found;
}
/// \brief Hides a set of declarations.
@@ -1267,13 +1329,14 @@ public:
/// This is intended for users who have examined the result kind
/// and are certain that there is only one result.
NamedDecl *getFoundDecl() const {
- assert(getKind() == Found && "getFoundDecl called on non-unique result");
+ assert(getResultKind() == Found
+ && "getFoundDecl called on non-unique result");
return *Decls.begin();
}
/// \brief Asks if the result is a single tag decl.
bool isSingleTagDecl() const {
- return getKind() == Found && isa<TagDecl>(getFoundDecl());
+ return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
}
/// \brief Make these results show that the name was found in
@@ -1297,17 +1360,53 @@ public:
/// \brief Clears out any current state.
void clear() {
- Kind = NotFound;
+ ResultKind = NotFound;
Decls.clear();
if (Paths) deletePaths(Paths);
Paths = NULL;
}
+ /// \brief Clears out any current state and re-initializes for a
+ /// different kind of lookup.
+ void clear(LookupNameKind Kind) {
+ clear();
+ LookupKind = Kind;
+ }
+
void print(llvm::raw_ostream &);
+ /// Suppress the diagnostics that would normally fire because of this
+ /// lookup. This happens during (e.g.) redeclaration lookups.
+ void suppressDiagnostics() {
+ Diagnose = false;
+ }
+
+ /// Sets a 'context' source range.
+ void setContextRange(SourceRange SR) {
+ NameContextRange = SR;
+ }
+
+ /// Gets the source range of the context of this name; for C++
+ /// qualified lookups, this is the source range of the scope
+ /// specifier.
+ SourceRange getContextRange() const {
+ return NameContextRange;
+ }
+
+ /// Gets the location of the identifier. This isn't always defined:
+ /// sometimes we're doing lookups on synthesized names.
+ SourceLocation getNameLoc() const {
+ return NameLoc;
+ }
+
private:
+ void diagnose() {
+ if (isAmbiguous())
+ SemaRef.DiagnoseAmbiguousLookup(*this);
+ }
+
void setAmbiguous(AmbiguityKind AK) {
- Kind = Ambiguous;
+ ResultKind = Ambiguous;
Ambiguity = AK;
}
@@ -1315,29 +1414,41 @@ public:
// Sanity checks.
void sanity() const {
- assert(Kind != NotFound || Decls.size() == 0);
- assert(Kind != Found || Decls.size() == 1);
- assert(Kind == NotFound || Kind == Found ||
- (Kind == Ambiguous && Ambiguity == AmbiguousBaseSubobjects)
+ assert(ResultKind != NotFound || Decls.size() == 0);
+ assert(ResultKind != Found || Decls.size() == 1);
+ assert(ResultKind == NotFound || ResultKind == Found ||
+ (ResultKind == Ambiguous && Ambiguity == AmbiguousBaseSubobjects)
|| Decls.size() > 1);
- assert((Paths != NULL) == (Kind == Ambiguous &&
+ assert((Paths != NULL) == (ResultKind == Ambiguous &&
(Ambiguity == AmbiguousBaseSubobjectTypes ||
Ambiguity == AmbiguousBaseSubobjects)));
}
static void deletePaths(CXXBasePaths *);
- LookupKind Kind;
+ // Results.
+ LookupResultKind ResultKind;
AmbiguityKind Ambiguity; // ill-defined unless ambiguous
DeclsTy Decls;
CXXBasePaths *Paths;
+
+ // Parameters.
+ Sema &SemaRef;
+ DeclarationName Name;
+ SourceLocation NameLoc;
+ SourceRange NameContextRange;
+ LookupNameKind LookupKind;
+ unsigned IDNS; // ill-defined until set by lookup
+ bool Redecl;
+
+ bool Diagnose;
};
private:
typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
- bool CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
- LookupNameKind NameKind, bool RedeclarationOnly);
+ bool CppLookupName(LookupResult &R, Scope *S);
+
public:
/// Determines whether D is a suitable lookup result according to the
/// lookup criteria.
@@ -1376,27 +1487,17 @@ public:
/// ambiguity and overloaded.
NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
LookupNameKind NameKind,
- bool RedeclarationOnly = false) {
- LookupResult R;
- LookupName(R, S, Name, NameKind, RedeclarationOnly);
+ LookupResult::RedeclarationKind Redecl
+ = LookupResult::NotForRedeclaration) {
+ LookupResult R(*this, Name, SourceLocation(), NameKind, Redecl);
+ LookupName(R, S);
return R.getAsSingleDecl(Context);
}
bool LookupName(LookupResult &R, Scope *S,
- DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly = false,
- bool AllowBuiltinCreation = false,
- SourceLocation Loc = SourceLocation());
- bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
- DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly = false);
+ bool AllowBuiltinCreation = false);
+ bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx);
bool LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
- DeclarationName Name,
- LookupNameKind NameKind,
- bool RedeclarationOnly = false,
bool AllowBuiltinCreation = false,
- SourceLocation Loc = SourceLocation(),
bool EnteringContext = false);
ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II);
@@ -1414,9 +1515,7 @@ public:
AssociatedNamespaceSet &AssociatedNamespaces,
AssociatedClassSet &AssociatedClasses);
- bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
- SourceLocation NameLoc,
- SourceRange LookupRange = SourceRange());
+ bool DiagnoseAmbiguousLookup(LookupResult &Result);
//@}
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 0a5335a2be..e2eb87f25e 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -179,10 +179,8 @@ void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
for (unsigned i = 0; i < NumIdentifiers; ++i) {
const Token &Tok = Identifiers[i];
IdentifierInfo *Name = Tok.getIdentifierInfo();
- LookupResult Lookup;
- LookupParsedName(Lookup, curScope, NULL, Name,LookupOrdinaryName,
- false, true, Tok.getLocation());
- // FIXME: Handle Lookup.isAmbiguous?
+ LookupResult Lookup(*this, Name, Tok.getLocation(), LookupOrdinaryName);
+ LookupParsedName(Lookup, curScope, NULL, true);
NamedDecl *ND = Lookup.getAsSingleDecl(Context);
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index ce3fb5f83c..b196dcec6f 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -307,8 +307,9 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
if (NNS->getKind() != NestedNameSpecifier::Identifier)
return 0;
- LookupResult Found;
- LookupName(Found, S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName);
+ LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(),
+ LookupNestedNameSpecifierName);
+ LookupName(Found, S);
assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
NamedDecl *Result = Found.getAsSingleDecl(Context);
@@ -336,6 +337,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
NestedNameSpecifier *Prefix
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+ LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+
// Determine where to perform name lookup
DeclContext *LookupCtx = 0;
bool isDependent = false;
@@ -350,9 +353,10 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// so long into the context associated with the prior nested-name-specifier.
LookupCtx = computeDeclContext(SS, EnteringContext);
isDependent = isDependentScopeSpecifier(SS);
+ Found.setContextRange(SS.getRange());
}
- LookupResult Found;
+
bool ObjectTypeSearchedInScope = false;
if (LookupCtx) {
// Perform "qualified" name lookup into the declaration context we
@@ -364,10 +368,9 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
return 0;
- LookupQualifiedName(Found, LookupCtx, &II, LookupNestedNameSpecifierName,
- false);
+ LookupQualifiedName(Found, LookupCtx);
- if (!ObjectType.isNull() && Found.getKind() == LookupResult::NotFound) {
+ if (!ObjectType.isNull() && Found.empty()) {
// C++ [basic.lookup.classref]p4:
// If the id-expression in a class member access is a qualified-id of
// the form
@@ -389,7 +392,7 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// reconstruct the result from when name lookup was performed at template
// definition time.
if (S)
- LookupName(Found, S, &II, LookupNestedNameSpecifierName);
+ LookupName(Found, S);
else if (ScopeLookupResult)
Found.addDecl(ScopeLookupResult);
@@ -406,7 +409,7 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
return NestedNameSpecifier::Create(Context, Prefix, &II);
} else {
// Perform unqualified name lookup in the current scope.
- LookupName(Found, S, &II, LookupNestedNameSpecifierName);
+ LookupName(Found, S);
}
// FIXME: Deal with ambiguities cleanly.
@@ -423,9 +426,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// scope, reconstruct the result from the template instantiation itself.
NamedDecl *OuterDecl;
if (S) {
- LookupResult FoundOuter;
- LookupName(FoundOuter, S, &II, LookupNestedNameSpecifierName);
- // FIXME: Handle ambiguities!
+ LookupResult FoundOuter(*this, &II, IdLoc, LookupNestedNameSpecifierName);
+ LookupName(FoundOuter, S);
OuterDecl = FoundOuter.getAsSingleDecl(Context);
} else
OuterDecl = ScopeLookupResult;
@@ -467,8 +469,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// ordinary name lookup, which can help us produce better error
// messages.
if (!SD) {
- Found.clear();
- LookupName(Found, S, &II, LookupOrdinaryName);
+ Found.clear(LookupOrdinaryName);
+ LookupName(Found, S);
SD = Found.getAsSingleDecl(Context);
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 502a0f1ab2..ecea71d7ed 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -87,11 +87,11 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
II, SS->getRange()).getAsOpaquePtr();
}
- LookupResult Result;
- LookupParsedName(Result, S, SS, &II, LookupOrdinaryName, false, false);
+ LookupResult Result(*this, &II, NameLoc, LookupOrdinaryName);
+ LookupParsedName(Result, S, SS, false);
NamedDecl *IIDecl = 0;
- switch (Result.getKind()) {
+ switch (Result.getResultKind()) {
case LookupResult::NotFound:
case LookupResult::FoundOverloaded:
return 0;
@@ -102,8 +102,10 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// diagnose the error then. If we don't do this, then the error
// about hiding the type will be immediately followed by an error
// that only makes sense if the identifier was treated like a type.
- if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding)
+ if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) {
+ Result.suppressDiagnostics();
return 0;
+ }
// Look to see if we have a type anywhere in the list of results.
for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end();
@@ -123,6 +125,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// perform this lookup again (e.g., as an object name), which
// will produce the ambiguity, or will complain that it expected
// a type name.
+ Result.suppressDiagnostics();
return 0;
}
@@ -130,7 +133,6 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
// ambiguity and then return that type. This might be the right
// answer, or it might not be, but it suppresses any attempt to
// perform the name lookup again.
- DiagnoseAmbiguousLookup(Result, DeclarationName(&II), NameLoc);
break;
case LookupResult::Found:
@@ -143,7 +145,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
QualType T;
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
DiagnoseUseOfDecl(IIDecl, NameLoc);
-
+
// C++ [temp.local]p2:
// Within the scope of a class template specialization or
// partial specialization, when the injected-class-name is
@@ -163,10 +165,12 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
T = getQualifiedNameType(*SS, T);
} else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
- DiagnoseUseOfDecl(IIDecl, NameLoc);
T = Context.getObjCInterfaceType(IDecl);
- } else
+ } else {
+ // If it's not plausibly a type, suppress diagnostics.
+ Result.suppressDiagnostics();
return 0;
+ }
return T.getAsOpaquePtr();
}
@@ -178,9 +182,10 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
/// where the user forgot to specify the tag.
DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
// Do a tag name lookup in this scope.
- LookupResult R;
- LookupName(R, S, &II, LookupTagName, false, false);
- if (R.getKind() == LookupResult::Found)
+ LookupResult R(*this, &II, SourceLocation(), LookupTagName);
+ LookupName(R, S, false);
+ R.suppressDiagnostics();
+ if (R.getResultKind() == LookupResult::Found)
if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsSingleDecl(Context))) {
switch (TD->getTagKind()) {
case TagDecl::TK_struct: return DeclSpec::TST_struct;
@@ -1415,9 +1420,9 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
FEnd = AnonRecord->field_end();
F != FEnd; ++F) {
if ((*F)->getDeclName()) {
- LookupResult R;
- LookupQualifiedName(R, Owner, (*F)->getDeclName(),
- LookupOrdinaryName, true);
+ LookupResult R(*this, (*F)->getDeclName(), SourceLocation(),
+ LookupOrdinaryName, LookupResult::ForRedeclaration);
+ LookupQualifiedName(R, Owner);
NamedDecl *PrevDecl = R.getAsSingleDecl(Context);
if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
// C++ [class.union]p2:
@@ -1784,10 +1789,10 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
NameKind = LookupRedeclarationWithLinkage;
DC = CurContext;
- LookupResult R;
- LookupName(R, S, Name, NameKind, true,
- NameKind == LookupRedeclarationWithLinkage,
- D.getIdentifierLoc());
+ LookupResult R(*this, Name, D.getIdentifierLoc(), NameKind,
+ LookupResult::ForRedeclaration);
+
+ LookupName(R, S, NameKind == LookupRedeclarationWithLinkage);
PrevDecl = R.getAsSingleDecl(Context);
} else { // Something like "int foo::x;"
DC = computeDeclContext(D.getCXXScopeSpec(), true);
@@ -1808,8 +1813,9 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
RequireCompleteDeclContext(D.getCXXScopeSpec()))
return DeclPtrTy();
- LookupResult Res;
- LookupQualifiedName(Res, DC, Name, LookupOrdinaryName, true);
+ LookupResult Res(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ LookupResult::ForRedeclaration);
+ LookupQualifiedName(Res, DC);
PrevDecl = Res.getAsSingleDecl(Context);
// C++ 7.3.1.2p2:
@@ -2923,8 +2929,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
<< Name << DC << D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl();
- LookupResult Prev;
- LookupQualifiedName(Prev, DC, Name, LookupOrdinaryName, true);
+ LookupResult Prev(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+ LookupResult::ForRedeclaration);
+ LookupQualifiedName(Prev, DC);
assert(!Prev.isAmbiguous() &&
"Cannot have an ambiguity in previous-declaration lookup");
for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
@@ -4302,7 +4309,8 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
bool isStdBadAlloc = false;
bool Invalid = false;
- bool RedeclarationOnly = (TUK != TUK_Reference);
+ LookupResult::RedeclarationKind Redecl =
+ (LookupResult::RedeclarationKind) (TUK != TUK_Reference);
if (Name && SS.isNotEmpty()) {
// We have a nested-name tag ('struct foo::bar').
@@ -4329,15 +4337,13 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DC = computeDeclContext(SS, true);
SearchDC = DC;
// Look-up name inside 'foo::'.
- LookupResult R;
- LookupQualifiedName(R, DC, Name, LookupTagName, RedeclarationOnly);
+ LookupResult R(*this, Name, NameLoc, LookupTagName, Redecl);
+ LookupQualifiedName(R, DC);
- if (R.isAmbiguous()) {
- DiagnoseAmbiguousLookup(R, Name, NameLoc, SS.getRange());
+ if (R.isAmbiguous())
return DeclPtrTy();
- }
- if (R.getKind() == LookupResult::Found)
+ if (R.getResultKind() == LookupResult::Found)
PrevDecl = dyn_cast<TagDecl>(R.getFoundDecl());
// A tag 'foo::bar' must already exist.
@@ -4353,10 +4359,9 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// FIXME: We're looking into outer scopes here, even when we
// shouldn't be. Doing so can result in ambiguities that we
// shouldn't be diagnosing.
- LookupResult R;
- LookupName(R, S, Name, LookupTagName, RedeclarationOnly);
+ LookupResult R(*this, Name, NameLoc, LookupTagName, Redecl);
+ LookupName(R, S);
if (R.isAmbiguous()) {
- DiagnoseAmbiguousLookup(R, Name, NameLoc);
// FIXME: This is not best way to recover from case like:
//
// struct S s;
@@ -4618,8 +4623,9 @@ CreateNewDecl:
// shall not be declared with the same name as a typedef-name
// that is declared in that scope and refers to a type other
// than the class or enumeration itself.
- LookupResult Lookup;
- LookupName(Lookup, S, Name, LookupOrdinaryName, true);
+ LookupResult Lookup(*this, Name, NameLoc, LookupOrdinaryName,
+ LookupResult::ForRedeclaration);
+ LookupName(Lookup, S);
TypedefDecl *PrevTypedef = 0;
if (NamedDecl *Prev = Lookup.getAsSingleDecl(Context))
PrevTypedef = dyn_cast<TypedefDecl>(Prev);
@@ -4838,7 +4844,8 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
if (D.getDeclSpec().isThreadSpecified())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
- NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
+ NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName,
+ LookupResult::ForRedeclaration);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
@@ -5223,7 +5230,8 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
DInfo, ac, (Expr *)BitfieldWidth);
if (II) {
- NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
+ NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName,
+ LookupResult::ForRedeclaration);
if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)
&& !isa<TagDecl>(PrevDecl)) {
Diag(Loc, diag::err_duplicate_member) << II;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e956ffec49..18e62291e5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2652,7 +2652,8 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
// in that declarative region, it is treated as an original-namespace-name.
NamedDecl *PrevDecl
- = LookupSingleName(DeclRegionScope, II, LookupOrdinaryName, true);
+ = LookupSingleName(DeclRegionScope, II, LookupOrdinaryName,
+ LookupResult::ForRedeclaration);
if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
// This is an extended namespace definition.
@@ -2760,12 +2761,11 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
UsingDirectiveDecl *UDir = 0;
// Lookup namespace name.
- LookupResult R;
- LookupParsedName(R, S, &SS, NamespcName, LookupNamespaceName, false);
- if (R.isAmbiguous()) {
- DiagnoseAmbiguousLookup(R, NamespcName, IdentLoc);
+ LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
+ LookupParsedName(R, S, &SS);
+ if (R.isAmbiguous())
return DeclPtrTy();
- }
+
if (!R.empty()) {
NamedDecl *NS = R.getFoundDecl();
// FIXME: Namespace aliases!
@@ -2913,8 +2913,8 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
}
// Lookup target name.
- LookupResult R;
- LookupQualifiedName(R, LookupContext, Name, LookupOrdinaryName);
+ LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName);
+ LookupQualifiedName(R, LookupContext);
if (R.empty()) {
Diag(IdentLoc, diag::err_no_member)
@@ -2959,12 +2959,13 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
IdentifierInfo *Ident) {
// Lookup the namespace name.
- LookupResult R;
- LookupParsedName(R, S, &SS, Ident, LookupNamespaceName, false);
+ LookupResult R(*this, Ident, IdentLoc, LookupNamespaceName);
+ LookupParsedName(R, S, &SS);
// Check if we have a previous declaration with the same name.
if (NamedDecl *PrevDecl
- = LookupSingleName(S, Alias, LookupOrdinaryName, true)) {
+ = LookupSingleName(S, Alias, LookupOrdinaryName,
+ LookupResult::ForRedeclaration)) {
if (NamespaceAliasDecl *AD = dyn_cast<NamespaceAliasDecl>(PrevDecl)) {
// We already have an alias with the same name that points to the same
// namespace, so don't create a new one.
@@ -2980,10 +2981,8 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
return DeclPtrTy();
}
- if (R.isAmbiguous()) {
- DiagnoseAmbiguousLookup(R, Ident, IdentLoc);
+ if (R.isAmbiguous())
return DeclPtrTy();
- }
if (R.empty()) {
Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
@@ -4613,8 +4612,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// FIXME: handle dependent contexts
if (!DC) return DeclPtrTy();
- LookupResult R;
- LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true);
+ LookupResult R(*this, Name, Loc, LookupOrdinaryName,
+ LookupResult::ForRedeclaration);
+ LookupQualifiedName(R, DC);
PrevDecl = R.getAsSingleDecl(Context);
// If searching in that context implicitly found a declaration in
@@ -4648,8 +4648,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
while (DC->isRecord())
DC = DC->getParent();
- LookupResult R;
- LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true);
+ LookupResult R(*this, Name, Loc, LookupOrdinaryName,
+ LookupResult::ForRedeclaration);
+ LookupQualifiedName(R, DC);
PrevDecl = R.getAsSingleDecl(Context);
// TODO: decide what we think about using declarations.
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a74d50365e..535632e6db 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -681,15 +681,11 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
isAddressOfOperand));
}
- LookupResult Lookup;
- LookupParsedName(Lookup, S, SS, Name, LookupOrdinaryName, false, true, Loc);
+ LookupResult Lookup(*this, Name, Loc, LookupOrdinaryName);
+ LookupParsedName(Lookup, S, SS, true);
- if (Lookup.isAmbiguous()) {
- DiagnoseAmbiguousLookup(Lookup, Name, Loc,
- SS && SS->isSet() ? SS->getRange()
- : SourceRange());
+ if (Lookup.isAmbiguous())
return ExprError();
- }
NamedDecl *D = Lookup.getAsSingleDecl(Context);
@@ -2075,17 +2071,14 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
}
// The record definition is complete, now make sure the member is valid.
- LookupResult Result;
- LookupQualifiedName(Result, DC, MemberName, LookupMemberName, false);
+ LookupResult Result(*this, MemberName, MemberLoc, LookupMemberName);
+ LookupQualifiedName(Result, DC);
if (Result.empty())
return ExprError(Diag(MemberLoc, diag::err_no_member)
<< MemberName << DC << BaseExpr->getSourceRange());
- if (Result.isAmbiguous()) {
- DiagnoseAmbiguousLookup(Result, MemberName, MemberLoc,
- BaseExpr->getSourceRange());
+ if (Result.isAmbiguous())
return ExprError();
- }
NamedDecl *MemberDecl = Result.getAsSingleDecl(Context);
@@ -5887,8 +5880,8 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
}
}
- LookupResult R;
- LookupQualifiedName(R, RD, OC.U.IdentInfo, LookupMemberName);
+ LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
+ LookupQualifiedName(R, RD);
FieldDecl *MemberDecl
= dyn_cast_or_null<FieldDecl>(R.getAsSingleDecl(Context));
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 3fcacfc9f3..fdce0e6c2d 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -34,8 +34,8 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr();
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
- LookupResult R;
- LookupQualifiedName(R, StdNamespace, TypeInfoII, LookupTagName);
+ LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
+ LookupQualifiedName(R, StdNamespace);
Decl *TypeInfoDecl = R.getAsSingleDecl(Context);
RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
if (!TypeInfoRecordDecl)
@@ -567,8 +567,8 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
DeclarationName Name, Expr** Args,
unsigned NumArgs, DeclContext *Ctx,
bool AllowMissing, FunctionDecl *&Operator) {
- LookupResult R;
- LookupQualifiedName(R, Ctx, Name, LookupOrdinaryName);
+ LookupResult R(*this, Name, StartLoc, LookupOrdinaryName);
+ LookupQualifiedName(R, Ctx);
if (R.empty()) {
if (AllowMissing)
return false;
@@ -756,14 +756,12 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
DeclarationName Name,
FunctionDecl* &Operator) {
- LookupResult Found;
+ LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
// Try to find operator delete/operator delete[] in class scope.
- LookupQualifiedName(Found, RD, Name, LookupOrdinaryName);
+ LookupQualifiedName(Found, RD);
- if (Found.isAmbiguous()) {
- DiagnoseAmbiguousLookup(Found, Name, StartLoc);
+ if (Found.isAmbiguous())
return true;
- }
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
F != FEnd; ++F) {
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index d45a1a8b92..1c7dce0def 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -248,7 +248,7 @@ void Sema::LookupResult::resolveKind() {
if (N <= 1) return;
// Don't do any extra resolution if we've already resolved as ambiguous.
- if (Kind == Ambiguous) return;
+ if (ResultKind == Ambiguous) return;
llvm::SmallPtrSet<NamedDecl*, 16> Unique;
@@ -308,9 +308,9 @@ void Sema::LookupResult::resolveKind() {
if (Ambiguous)
setAmbiguous(LookupResult::AmbiguousReference);
else if (N > 1)
- Kind = LookupResult::FoundOverloaded;
+ ResultKind = LookupResult::FoundOverloaded;
else
- Kind = LookupResult::Found;
+ ResultKind = LookupResult::Found;
}
/// @brief Converts the result of name lookup into a single (possible
@@ -391,15 +391,13 @@ void Sema::LookupResult::print(llvm::raw_ostream &Out) {
// Adds all qualifying matches for a name within a decl context to the
// given lookup result. Returns true if any matches were found.
static bool LookupDirect(Sema::LookupResult &R,
- const DeclContext *DC,
- DeclarationName Name,
- Sema::LookupNameKind NameKind,
- unsigned IDNS) {
+ const DeclContext *DC) {
bool Found = false;
DeclContext::lookup_const_iterator I, E;
- for (llvm::tie(I, E) = DC->lookup(Name); I != E; ++I)
- if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS))
+ for (llvm::tie(I, E) = DC->lookup(R.getLookupName()); I != E; ++I)
+ if (Sema::isAcceptableLookupResult(*I, R.getLookupKind(),
+ R.getIdentifierNamespace()))
R.addDecl(*I), Found = true;
return Found;
@@ -408,13 +406,12 @@ static bool LookupDirect