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.

llvm-svn: 89027
This commit is contained in:
John McCall 2009-11-17 02:14:36 +00:00
parent 4359796e52
commit 27b18f8144
11 changed files with 326 additions and 224 deletions

View File

@ -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);
}
bool isAmbiguous() const {
return getKind() == Ambiguous;
/// Gets the name to look up.
DeclarationName getLookupName() const {
return Name;
}
LookupKind getKind() const {
/// 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 getResultKind() == Ambiguous;
}
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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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.

View File

@ -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));

View File

@ -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) {

View File

@ -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(Sema::LookupResult &R,
// Performs C++ unqualified lookup into the given file context.
static bool
CppNamespaceLookup(Sema::LookupResult &R, ASTContext &Context, DeclContext *NS,
DeclarationName Name, Sema::LookupNameKind NameKind,
unsigned IDNS, UnqualUsingDirectiveSet &UDirs) {
UnqualUsingDirectiveSet &UDirs) {
assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!");
// Perform direct name lookup into the LookupCtx.
bool Found = LookupDirect(R, NS, Name, NameKind, IDNS);
bool Found = LookupDirect(R, NS);
// Perform direct name lookup into the namespaces nominated by the
// using directives whose common ancestor is this namespace.
@ -422,7 +419,7 @@ CppNamespaceLookup(Sema::LookupResult &R, ASTContext &Context, DeclContext *NS,
llvm::tie(UI, UEnd) = UDirs.getNamespacesFor(NS);
for (; UI != UEnd; ++UI)
if (LookupDirect(R, UI->getNominatedNamespace(), Name, NameKind, IDNS))
if (LookupDirect(R, UI->getNominatedNamespace()))
Found = true;
R.resolveKind();
@ -445,20 +442,23 @@ static DeclContext *findOuterContext(Scope *S) {
return 0;
}
bool
Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
LookupNameKind NameKind, bool RedeclarationOnly) {
bool Sema::CppLookupName(LookupResult &R, Scope *S) {
assert(getLangOptions().CPlusPlus &&
"Can perform only C++ lookup");
LookupNameKind NameKind = R.getLookupKind();
unsigned IDNS
= getIdentifierNamespacesFromLookupNameKind(NameKind, /*CPlusPlus*/ true);
// If we're testing for redeclarations, also look in the friend namespaces.
if (RedeclarationOnly) {
if (R.isForRedeclaration()) {
if (IDNS & Decl::IDNS_Tag) IDNS |= Decl::IDNS_TagFriend;
if (IDNS & Decl::IDNS_Ordinary) IDNS |= Decl::IDNS_OrdinaryFriend;
}
R.setIdentifierNamespace(IDNS);
DeclarationName Name = R.getLookupName();
Scope *Initial = S;
IdentifierResolver::iterator
I = IdResolver.begin(Name),
@ -509,7 +509,7 @@ Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
// example, inside a class without any base classes, we never need to
// perform qualified lookup because all of the members are on top of the
// identifier chain.
if (LookupQualifiedName(R, Ctx, Name, NameKind, RedeclarationOnly))
if (LookupQualifiedName(R, Ctx))
return true;
}
}
@ -556,7 +556,7 @@ Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
}
// Look into context considering using-directives.
if (CppNamespaceLookup(R, Context, Ctx, Name, NameKind, IDNS, UDirs))
if (CppNamespaceLookup(R, Context, Ctx, UDirs))
Found = true;
if (Found) {
@ -564,7 +564,7 @@ Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
return true;
}
if (RedeclarationOnly && !Ctx->isTransparentContext())
if (R.isForRedeclaration() && !Ctx->isTransparentContext())
return false;
}
@ -602,11 +602,12 @@ Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
/// @returns The result of name lookup, which includes zero or more
/// declarations and possibly additional information used to diagnose
/// ambiguities.
bool Sema::LookupName(LookupResult &R, Scope *S, DeclarationName Name,
LookupNameKind NameKind, bool RedeclarationOnly,
bool AllowBuiltinCreation, SourceLocation Loc) {
bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
DeclarationName Name = R.getLookupName();
if (!Name) return false;
LookupNameKind NameKind = R.getLookupKind();
if (!getLangOptions().CPlusPlus) {
// Unqualified name lookup in C/Objective-C is purely lexical, so
// search in the declarations attached to the name.
@ -702,7 +703,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, DeclarationName Name,
}
} else {
// Perform C++ unqualified name lookup.
if (CppLookupName(R, S, Name, NameKind, RedeclarationOnly))
if (CppLookupName(R, S))
return true;
}
@ -722,7 +723,8 @@ bool Sema::LookupName(LookupResult &R, Scope *S, DeclarationName Name,
return false;
NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
S, RedeclarationOnly, Loc);
S, R.isForRedeclaration(),
R.getNameLoc());
if (D) R.addDecl(D);
return (D != NULL);
}
@ -758,10 +760,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, DeclarationName Name,
/// from the same namespace; otherwise (the declarations are from
/// different namespaces), the program is ill-formed.
static bool LookupQualifiedNameInUsingDirectives(Sema::LookupResult &R,
DeclContext *StartDC,
DeclarationName Name,
Sema::LookupNameKind NameKind,
unsigned IDNS) {
DeclContext *StartDC) {
assert(StartDC->isFileContext() && "start context is not a file context");
DeclContext::udir_iterator I = StartDC->using_directives_begin();
@ -792,7 +791,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema::LookupResult &R,
bool FoundTag = false;
bool FoundNonTag = false;
Sema::LookupResult LocalR;
Sema::LookupResult LocalR(Sema::LookupResult::Temporary, R);
bool Found = false;
while (!Queue.empty()) {
@ -803,7 +802,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema::LookupResult &R,
// between LookupResults.
bool UseLocal = !R.empty();
Sema::LookupResult &DirectR = UseLocal ? LocalR : R;
bool FoundDirect = LookupDirect(DirectR, ND, Name, NameKind, IDNS);
bool FoundDirect = LookupDirect(DirectR, ND);
if (FoundDirect) {
// First do any local hiding.
@ -875,22 +874,23 @@ static bool LookupQualifiedNameInUsingDirectives(Sema::LookupResult &R,
/// @returns The result of name lookup, which includes zero or more
/// declarations and possibly additional information used to diagnose
/// ambiguities.
bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
DeclarationName Name, LookupNameKind NameKind,
bool RedeclarationOnly) {
bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx) {
assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context");
if (!Name)
if (!R.getLookupName())
return false;
// If we're performing qualified name lookup (e.g., lookup into a
// struct), find fields as part of ordinary name lookup.
LookupNameKind NameKind = R.getLookupKind();
unsigned IDNS
= getIdentifierNamespacesFromLookupNameKind(NameKind,
getLangOptions().CPlusPlus);
if (NameKind == LookupOrdinaryName)
IDNS |= Decl::IDNS_Member;
R.setIdentifierNamespace(IDNS);
// Make sure that the declaration context is complete.
assert((!isa<TagDecl>(LookupCtx) ||
LookupCtx->isDependentContext() ||
@ -900,7 +900,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
"Declaration context must already be complete!");
// Perform qualified name lookup into the LookupCtx.
if (LookupDirect(R, LookupCtx, Name, NameKind, IDNS)) {
if (LookupDirect(R, LookupCtx)) {
R.resolveKind();
return true;
}
@ -914,13 +914,12 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
// the unqualified-id shall name a member of the namespace
// designated by the nested-name-specifier.
// See also [class.mfct]p5 and [class.static.data]p2.
if (RedeclarationOnly)
if (R.isForRedeclaration())
return false;
// If this is a namespace, look it up in
// If this is a namespace, look it up in the implied namespaces.
if (LookupCtx->isFileContext())
return LookupQualifiedNameInUsingDirectives(R, LookupCtx, Name, NameKind,
IDNS);
return LookupQualifiedNameInUsingDirectives(R, LookupCtx);
// If this isn't a C++ class, we aren't allowed to look into base
// classes, we're done.
@ -934,7 +933,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
// Look for this member in our base classes
CXXRecordDecl::BaseMatchesCallback *BaseCallback = 0;
switch (NameKind) {
switch (R.getLookupKind()) {
case LookupOrdinaryName:
case LookupMemberName:
case LookupRedeclarationWithLinkage:
@ -958,7 +957,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
break;
}
if (!LookupRec->lookupInBases(BaseCallback, Name.getAsOpaquePtr(), Paths))
if (!LookupRec->lookupInBases(BaseCallback,
R.getLookupName().getAsOpaquePtr(), Paths))
return false;
// C++ [class.member.lookup]p2:
@ -1060,10 +1060,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
///
/// @returns True if any decls were found (but possibly ambiguous)
bool Sema::LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
DeclarationName Name, LookupNameKind NameKind,
bool RedeclarationOnly, bool AllowBuiltinCreation,
SourceLocation Loc,
bool EnteringContext) {
bool AllowBuiltinCreation, bool EnteringContext) {
if (SS && SS->isInvalid()) {
// When the scope specifier is invalid, don't even look for
// anything.
@ -1077,7 +1074,9 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS))
return false;
return LookupQualifiedName(R, DC, Name, NameKind, RedeclarationOnly);
R.setContextRange(SS->getRange());
return LookupQualifiedName(R, DC);
}
// We could not resolve the scope specified to a specific declaration
@ -1087,8 +1086,7 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
}
// Perform unqualified name lookup starting in the given scope.
return LookupName(R, S, Name, NameKind, RedeclarationOnly,
AllowBuiltinCreation, Loc);
return LookupName(R, S, AllowBuiltinCreation);
}
@ -1108,11 +1106,13 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
/// precedes the name.
///
/// @returns true
bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
SourceLocation NameLoc,
SourceRange LookupRange) {
bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result) {
assert(Result.isAmbiguous() && "Lookup result must be ambiguous");
DeclarationName Name = Result.getLookupName();
SourceLocation NameLoc = Result.getNameLoc();
SourceRange LookupRange = Result.getContextRange();
switch (Result.getAmbiguityKind()) {
case LookupResult::AmbiguousBaseSubobjects: {
CXXBasePaths *Paths = Result.getBasePaths();
@ -1621,8 +1621,8 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
// of type T2 or "reference to (possibly cv-qualified) T2",
// when T2 is an enumeration type, are candidate functions.
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
LookupResult Operators;
LookupName(Operators, S, OpName, LookupOperatorName);
LookupResult Operators(*this, OpName, SourceLocation(), LookupOperatorName);
LookupName(Operators, S);
assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");

View File

@ -2833,9 +2833,10 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
if (RequireCompleteType(OpLoc, T1, PDiag()))
return;
LookupResult Operators;
LookupQualifiedName(Operators, T1Rec->getDecl(), OpName,
LookupOrdinaryName, false);
LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName);
LookupQualifiedName(Operators, T1Rec->getDecl());
Operators.suppressDiagnostics();
for (LookupResult::iterator Oper = Operators.begin(),
OperEnd = Operators.end();
Oper != OperEnd;
@ -5260,8 +5261,10 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
<< Object->getSourceRange()))
return true;
LookupResult R;
LookupQualifiedName(R, Record->getDecl(), OpName, LookupOrdinaryName, false);
LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
LookupQualifiedName(R, Record->getDecl());
R.suppressDiagnostics();
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*Oper)) {
@ -5492,8 +5495,9 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
OverloadCandidateSet CandidateSet;
const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
LookupResult R;
LookupQualifiedName(R, BaseRecord->getDecl(), OpName, LookupOrdinaryName);
LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName);
LookupQualifiedName(R, BaseRecord->getDecl());
R.suppressDiagnostics();
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper)

View File

@ -138,7 +138,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
isDependent = isDependentScopeSpecifier(SS);
}
LookupResult Found;
LookupResult Found(*this, TName, SourceLocation(), LookupOrdinaryName);
bool ObjectTypeSearchedInScope = false;
if (LookupCtx) {
// Perform "qualified" name lookup into the declaration context we
@ -150,9 +150,9 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
return TNK_Non_template;
LookupQualifiedName(Found, LookupCtx, TName, LookupOrdinaryName);
LookupQualifiedName(Found, LookupCtx);
if (ObjectTypePtr && Found.getKind() == LookupResult::NotFound) {
if (ObjectTypePtr && Found.empty()) {
// C++ [basic.lookup.classref]p1:
// In a class member access expression (5.2.5), if the . or -> token is
// immediately followed by an identifier followed by a <, the
@ -165,7 +165,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
//
// FIXME: When we're instantiating a template, do we actually have to
// look in the scope of the template? Seems fishy...
LookupName(Found, S, TName, LookupOrdinaryName);
LookupName(Found, S);
ObjectTypeSearchedInScope = true;
}
} else if (isDependent) {
@ -173,7 +173,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
return TNK_Non_template;
} else {
// Perform unqualified name lookup in the current scope.
LookupName(Found, S, TName, LookupOrdinaryName);
LookupName(Found, S);
}
// FIXME: Cope with ambiguous name-lookup results.
@ -191,8 +191,8 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
// template, the name is also looked up in the context of the entire
// postfix-expression and [...]
//
LookupResult FoundOuter;
LookupName(FoundOuter, S, TName, LookupOrdinaryName);
LookupResult FoundOuter(*this, TName, SourceLocation(), LookupOrdinaryName);
LookupName(FoundOuter, S);
// FIXME: Handle ambiguities in this lookup better
NamedDecl *OuterTemplate
= isAcceptableTemplateName(Context, FoundOuter.getAsSingleDecl(Context));
@ -628,7 +628,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
// Find any previous declaration with this name.
DeclContext *SemanticContext;
LookupResult Previous;
LookupResult Previous(*this, Name, NameLoc, LookupOrdinaryName,
LookupResult::ForRedeclaration);
if (SS.isNotEmpty() && !SS.isInvalid()) {
if (RequireCompleteDeclContext(SS))
return true;
@ -639,11 +640,10 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
return true;
}
LookupQualifiedName(Previous, SemanticContext, Name, LookupOrdinaryName,
true);
LookupQualifiedName(Previous, SemanticContext);
} else {
SemanticContext = CurContext;
LookupName(Previous, S, Name, LookupOrdinaryName, true);
LookupName(Previous, S);
}
assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?");
@ -4192,19 +4192,16 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
LookupResult Previous;
LookupParsedName(Previous, S, &D.getCXXScopeSpec(),
Name, LookupOrdinaryName);
LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName);
LookupParsedName(Previous, S, &D.getCXXScopeSpec());
if (!R->isFunctionType()) {
// C++ [temp.explicit]p1:
// A [...] static data member of a class template can be explicitly
// instantiated from the member definition associated with its class
// template.
if (Previous.isAmbiguous()) {
return DiagnoseAmbiguousLookup(Previous, Name, D.getIdentifierLoc(),
D.getSourceRange());
}
if (Previous.isAmbiguous())
return true;
VarDecl *Prev = dyn_cast_or_null<VarDecl>(
Previous.getAsSingleDecl(Context));
@ -4483,11 +4480,11 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
assert(Ctx && "No declaration context?");
DeclarationName Name(&II);
LookupResult Result;
LookupQualifiedName(Result, Ctx, Name, LookupOrdinaryName, false);
LookupResult Result(*this, Name, Range.getEnd(), LookupOrdinaryName);
LookupQualifiedName(Result, Ctx);
unsigned DiagID = 0;
Decl *Referenced = 0;
switch (Result.getKind()) {
switch (Result.getResultKind()) {
case LookupResult::NotFound:
DiagID = diag::err_typename_nested_not_found;
break;
@ -4510,7 +4507,6 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
break;
case LookupResult::Ambiguous:
DiagnoseAmbiguousLookup(Result, Name, Range.getEnd(), Range);
return QualType();
}

View File

@ -677,9 +677,10 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// Look only into the namespace where the friend would be declared to
// find a previous declaration. This is the innermost enclosing namespace,
// as described in ActOnFriendFunctionDecl.
Sema::LookupResult R;
SemaRef.LookupQualifiedName(R, DC, Function->getDeclName(),
Sema::LookupOrdinaryName, true);
Sema::LookupResult R(SemaRef, Function->getDeclName(), SourceLocation(),
Sema::LookupOrdinaryName,
Sema::LookupResult::ForRedeclaration);
SemaRef.LookupQualifiedName(R, DC);
PrevDecl = R.getAsSingleDecl(SemaRef.Context);
@ -837,8 +838,10 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
NamedDecl *PrevDecl = 0;
if (!FunctionTemplate || TemplateParams) {
Sema::LookupResult R;
SemaRef.LookupQualifiedName(R, Owner, Name, Sema::LookupOrdinaryName, true);
Sema::LookupResult R(SemaRef, Name, SourceLocation(),
Sema::LookupOrdinaryName,
Sema::LookupResult::ForRedeclaration);
SemaRef.LookupQualifiedName(R, Owner);
PrevDecl = R.getAsSingleDecl(SemaRef.Context);
// In C++, the previous declaration we find might be a tag type