Refactor the LookupResult API to simplify most common operations. Require users to

pass a LookupResult reference to lookup routines.  Call out uses which assume a single
result.

llvm-svn: 83674
This commit is contained in:
John McCall 2009-10-09 21:13:30 +00:00
parent a2b99107c4
commit 9f3059a192
16 changed files with 532 additions and 916 deletions

View File

@ -299,6 +299,9 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
if (isa<ObjCMethodDecl>(this))
return false;
if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
return true;
// For non-function declarations, if the declarations are of the
// same kind then this must be a redeclaration, or semantic analysis
// would not have given us the new declaration.

View File

@ -1045,63 +1045,13 @@ public:
/// results occurred for a given lookup.
///
/// Any non-ambiguous lookup can be converted into a single
/// (possibly NULL) @c NamedDecl* via a conversion function or the
/// getAsDecl() method. This conversion permits the common-case
/// usage in C and Objective-C where name lookup will always return
/// a single declaration.
struct LookupResult {
/// The kind of entity that is actually stored within the
/// LookupResult object.
enum {
/// First is a single declaration (a NamedDecl*), which may be NULL.
SingleDecl,
/// First is a single declaration (an OverloadedFunctionDecl*).
OverloadedDeclSingleDecl,
/// [First, Last) is an iterator range represented as opaque
/// pointers used to reconstruct IdentifierResolver::iterators.
OverloadedDeclFromIdResolver,
/// [First, Last) is an iterator range represented as opaque
/// pointers used to reconstruct DeclContext::lookup_iterators.
OverloadedDeclFromDeclContext,
/// First is a pointer to a CXXBasePaths structure, which is owned
/// by the LookupResult. Last is non-zero to indicate that the
/// ambiguity is caused by two names found in base class
/// subobjects of different types.
AmbiguousLookupStoresBasePaths,
/// [First, Last) is an iterator range represented as opaque
/// pointers used to reconstruct new'ed Decl*[] array containing
/// found ambiguous decls. LookupResult is owner of this array.
AmbiguousLookupStoresDecls
} StoredKind;
/// The first lookup result, whose contents depend on the kind of
/// lookup result. This may be a NamedDecl* (if StoredKind ==
/// SingleDecl), OverloadedFunctionDecl* (if StoredKind ==
/// OverloadedDeclSingleDecl), the opaque pointer from an
/// IdentifierResolver::iterator (if StoredKind ==
/// OverloadedDeclFromIdResolver), a DeclContext::lookup_iterator
/// (if StoredKind == OverloadedDeclFromDeclContext), or a
/// CXXBasePaths pointer (if StoredKind == AmbiguousLookupStoresBasePaths).
mutable uintptr_t First;
/// The last lookup result, whose contents depend on the kind of
/// lookup result. This may be unused (if StoredKind ==
/// SingleDecl), it may have the same type as First (for
/// overloaded function declarations), or is may be used as a
/// Boolean value (if StoredKind == AmbiguousLookupStoresBasePaths).
mutable uintptr_t Last;
/// Context - The context in which we will build any
/// OverloadedFunctionDecl nodes needed by the conversion to
/// Decl*.
ASTContext *Context;
/// @brief The kind of entity found by name lookup.
/// (possibly NULL) @c NamedDecl* via the getAsSingleDecl() method.
/// This permits the common-case usage in C and Objective-C where
/// name lookup will always return a single declaration. Use of
/// this is largely deprecated; callers should handle the possibility
/// of multiple declarations.
class LookupResult {
public:
enum LookupKind {
/// @brief No entity found met the criteria.
NotFound = 0,
@ -1156,122 +1106,119 @@ public:
/// }
/// }
/// @endcode
AmbiguousReference
AmbiguousReference,
FirstAmbiguous = AmbiguousBaseSubobjectTypes
};
static LookupResult CreateLookupResult(ASTContext &Context, NamedDecl *D);
typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
typedef DeclsTy::const_iterator iterator;
static LookupResult CreateLookupResult(ASTContext &Context,
IdentifierResolver::iterator F,
IdentifierResolver::iterator L);
static LookupResult CreateLookupResult(ASTContext &Context,
DeclContext::lookup_iterator F,
DeclContext::lookup_iterator L);
static LookupResult CreateLookupResult(ASTContext &Context,
CXXBasePaths *Paths,
bool DifferentSubobjectTypes) {
LookupResult Result;
Result.StoredKind = AmbiguousLookupStoresBasePaths;
Result.First = reinterpret_cast<uintptr_t>(Paths);
Result.Last = DifferentSubobjectTypes? 1 : 0;
Result.Context = &Context;
return Result;
LookupResult()
: Kind(NotFound),
Paths(0)
{}
~LookupResult() {
if (Paths) deletePaths(Paths);
}
template <typename Iterator>
static LookupResult CreateLookupResult(ASTContext &Context,
Iterator B, std::size_t Len) {
NamedDecl ** Array = new NamedDecl*[Len];
for (std::size_t Idx = 0; Idx < Len; ++Idx, ++B)
Array[Idx] = *B;
LookupResult Result;
Result.StoredKind = AmbiguousLookupStoresDecls;
Result.First = reinterpret_cast<uintptr_t>(Array);
Result.Last = reinterpret_cast<uintptr_t>(Array + Len);
Result.Context = &Context;
return Result;
}
LookupKind getKind() const;
/// @brief Determine whether name look found something.
operator bool() const { return getKind() != NotFound; }
/// @brief Determines whether the lookup resulted in an ambiguity.
bool isAmbiguous() const {
return StoredKind == AmbiguousLookupStoresBasePaths ||
StoredKind == AmbiguousLookupStoresDecls;
return getKind() >= FirstAmbiguous;
}
/// @brief Allows conversion of a lookup result into a
/// declaration, with the same behavior as getAsDecl.
operator NamedDecl*() const { return getAsDecl(); }
LookupKind getKind() const {
sanity();
return Kind;
}
NamedDecl* getAsDecl() const;
iterator begin() const { return Decls.begin(); }
iterator end() const { return Decls.end(); }
CXXBasePaths *getBasePaths() const;
/// \brief Return true if no decls were found
bool empty() const { return Decls.empty(); }
/// \brief Iterate over the results of name lookup.
/// \brief Return the base paths structure that's associated with
/// these results, or null if none is.
CXXBasePaths *getBasePaths() const {
return Paths;
}
/// \brief Add a declaration to these results.
void addDecl(NamedDecl *D) {
Decls.push_back(D->getUnderlyingDecl());
Kind = Found;
}
/// \brief Resolves the kind of the lookup, possibly hiding decls.
///
/// The @c iterator class provides iteration over the results of a
/// non-ambiguous name lookup.
class iterator {
/// The LookupResult structure we're iterating through.
LookupResult *Result;
/// This should be called in any environment where lookup might
/// generate multiple lookup results.
void resolveKind();
/// The current position of this iterator within the sequence of
/// results. This value will have the same representation as the
/// @c First field in the LookupResult structure.
mutable uintptr_t Current;
/// \brief Fetch this as an unambiguous single declaration
/// (possibly an overloaded one).
///
/// This is deprecated; users should be written to handle
/// ambiguous and overloaded lookups.
NamedDecl *getAsSingleDecl(ASTContext &Context) const;
public:
typedef NamedDecl * value_type;
typedef NamedDecl * reference;
typedef NamedDecl * pointer;
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
/// \brief Fetch the unique decl found by this lookup. Asserts
/// that one was found.
///
/// 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");
return *Decls.begin();
}
iterator() : Result(0), Current(0) { }
/// \brief Make these results show that the name was found in
/// base classes of different types.
///
/// The given paths object is copied and invalidated.
void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
iterator(LookupResult *Res, uintptr_t Cur) : Result(Res), Current(Cur) { }
/// \brief Make these results show that the name was found in
/// distinct base classes of the same type.
///
/// The given paths object is copied and invalidated.
void setAmbiguousBaseSubobjects(CXXBasePaths &P);
reference operator*() const;
/// \brief Clears out any current state.
void clear() {
Kind = NotFound;
Decls.clear();
if (Paths) deletePaths(Paths);
Paths = NULL;
}
pointer operator->() const { return **this; }
void print(llvm::raw_ostream &);
iterator &operator++();
private:
void addDeclsFromBasePaths(const CXXBasePaths &P);
iterator operator++(int) {
iterator tmp(*this);
++(*this);
return tmp;
}
// Sanity checks.
void sanity() const {
assert(Kind != NotFound || Decls.size() == 0);
assert(Kind != Found || Decls.size() == 1);
assert(Kind == NotFound || Kind == Found ||
Kind == AmbiguousBaseSubobjects || Decls.size() > 1);
assert((Paths != NULL) == (Kind == AmbiguousBaseSubobjectTypes ||
Kind == AmbiguousBaseSubobjects));
}
friend inline bool operator==(iterator const& x, iterator const& y) {
return x.Current == y.Current;
}
static void deletePaths(CXXBasePaths *);
friend inline bool operator!=(iterator const& x, iterator const& y) {
return x.Current != y.Current;
}
};
friend class iterator;
iterator begin();
iterator end();
/// \brief Free the memory associated with this lookup.
void Destroy();
LookupKind Kind;
DeclsTy Decls;
CXXBasePaths *Paths;
};
private:
typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name,
LookupNameKind NameKind,
bool RedeclarationOnly);
bool CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
LookupNameKind NameKind, bool RedeclarationOnly);
public:
/// Determines whether D is a suitable lookup result according to the
/// lookup criteria.
@ -1303,24 +1250,38 @@ public:
return false;
}
LookupResult LookupName(Scope *S, DeclarationName Name,
LookupNameKind NameKind,
bool RedeclarationOnly = false,
bool AllowBuiltinCreation = false,
SourceLocation Loc = SourceLocation());
LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
LookupNameKind NameKind,
bool RedeclarationOnly = false);
/// \brief Look up a name, looking for a single declaration. Return
/// null if no unambiguous results were found.
///
/// It is preferable to use the elaborated form and explicitly handle
/// ambiguity and overloaded.
NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
LookupNameKind NameKind,
bool RedeclarationOnly = false) {
LookupResult R;
LookupName(R, S, Name, NameKind, RedeclarationOnly);
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);
Decl *LookupQualifiedNameWithType(DeclContext *LookupCtx,
DeclarationName Name,
QualType T);
LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS,
DeclarationName Name,
LookupNameKind NameKind,
bool RedeclarationOnly = false,
bool AllowBuiltinCreation = false,
SourceLocation Loc = SourceLocation(),
bool EnteringContext = false);
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);
ObjCCategoryImplDecl *LookupObjCCategoryImpl(IdentifierInfo *II);

View File

@ -179,13 +179,12 @@ void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
for (unsigned i = 0; i < NumIdentifiers; ++i) {
const Token &Tok = Identifiers[i];
IdentifierInfo *Name = Tok.getIdentifierInfo();
const LookupResult &Lookup = LookupParsedName(curScope, NULL, Name,
LookupOrdinaryName,
false, true,
Tok.getLocation());
LookupResult Lookup;
LookupParsedName(Lookup, curScope, NULL, Name,LookupOrdinaryName,
false, true, Tok.getLocation());
// FIXME: Handle Lookup.isAmbiguous?
NamedDecl *ND = Lookup.getAsDecl();
NamedDecl *ND = Lookup.getAsSingleDecl(Context);
if (!ND) {
Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)

View File

@ -302,11 +302,11 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
if (NNS->getKind() != NestedNameSpecifier::Identifier)
return 0;
LookupResult Found
= LookupName(S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName);
LookupResult Found;
LookupName(Found, S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName);
assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
NamedDecl *Result = Found;
NamedDecl *Result = Found.getAsSingleDecl(Context);
if (isAcceptableNestedNameSpecifier(Result))
return Result;
@ -359,8 +359,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
return 0;
Found = LookupQualifiedName(LookupCtx, &II, LookupNestedNameSpecifierName,
false);
LookupQualifiedName(Found, LookupCtx, &II, LookupNestedNameSpecifierName,
false);
if (!ObjectType.isNull() && Found.getKind() == LookupResult::NotFound) {
// C++ [basic.lookup.classref]p4:
@ -384,9 +384,9 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// reconstruct the result from when name lookup was performed at template
// definition time.
if (S)
Found = LookupName(S, &II, LookupNestedNameSpecifierName);
else
Found = LookupResult::CreateLookupResult(Context, ScopeLookupResult);
LookupName(Found, S, &II, LookupNestedNameSpecifierName);
else if (ScopeLookupResult)
Found.addDecl(ScopeLookupResult);
ObjectTypeSearchedInScope = true;
}
@ -401,11 +401,11 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
return NestedNameSpecifier::Create(Context, Prefix, &II);
} else {
// Perform unqualified name lookup in the current scope.
Found = LookupName(S, &II, LookupNestedNameSpecifierName);
LookupName(Found, S, &II, LookupNestedNameSpecifierName);
}
// FIXME: Deal with ambiguities cleanly.
NamedDecl *SD = Found;
NamedDecl *SD = Found.getAsSingleDecl(Context);
if (isAcceptableNestedNameSpecifier(SD)) {
if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
// C++ [basic.lookup.classref]p4:
@ -416,15 +416,15 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// into the current scope (the scope of the postfix-expression) to
// see if we can find the same name there. As above, if there is no
// scope, reconstruct the result from the template instantiation itself.
LookupResult FoundOuter;
if (S)
FoundOuter = LookupName(S, &II, LookupNestedNameSpecifierName);
else
FoundOuter = LookupResult::CreateLookupResult(Context,
ScopeLookupResult);
NamedDecl *OuterDecl;
if (S) {
LookupResult FoundOuter;
LookupName(FoundOuter, S, &II, LookupNestedNameSpecifierName);
// FIXME: Handle ambiguities!
OuterDecl = FoundOuter.getAsSingleDecl(Context);
} else
OuterDecl = ScopeLookupResult;
// FIXME: Handle ambiguities in FoundOuter!
NamedDecl *OuterDecl = FoundOuter;
if (isAcceptableNestedNameSpecifier(OuterDecl) &&
OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
(!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
@ -461,8 +461,11 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
// If we didn't find anything during our lookup, try again with
// ordinary name lookup, which can help us produce better error
// messages.
if (!SD)
SD = LookupName(S, &II, LookupOrdinaryName);
if (!SD) {
Found.clear();
LookupName(Found, S, &II, LookupOrdinaryName);
SD = Found.getAsSingleDecl(Context);
}
unsigned DiagID;
if (SD)

View File

@ -85,8 +85,8 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
II, SS->getRange()).getAsOpaquePtr();
}
LookupResult Result
= LookupParsedName(S, SS, &II, LookupOrdinaryName, false, false);
LookupResult Result;
LookupParsedName(Result, S, SS, &II, LookupOrdinaryName, false, false);
NamedDecl *IIDecl = 0;
switch (Result.getKind()) {
@ -115,7 +115,6 @@ 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.Destroy();
return 0;
}
@ -128,7 +127,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
}
case LookupResult::Found:
IIDecl = Result.getAsDecl();
IIDecl = Result.getFoundDecl();
break;
}
@ -179,9 +178,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(S, &II, LookupTagName, false, false);
LookupResult R;
LookupName(R, S, &II, LookupTagName, false, false);
if (R.getKind() == LookupResult::Found)
if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsDecl())) {
if (const TagDecl *TD = dyn_cast<TagDecl>(R.getAsSingleDecl(Context))) {
switch (TD->getTagKind()) {
case TagDecl::TK_struct: return DeclSpec::TST_struct;
case TagDecl::TK_union: return DeclSpec::TST_union;
@ -303,84 +303,20 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
(isa<VarDecl>(D) && cast<VarDecl>(D)->isOutOfLine()))
return;
S->AddDecl(DeclPtrTy::make(D));
// C++ [basic.scope]p4:
// -- exactly one declaration shall declare a class name or
// enumeration name that is not a typedef name and the other
// declarations shall all refer to the same object or
// enumerator, or all refer to functions and function templates;
// in this case the class name or enumeration name is hidden.
if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
// We are pushing the name of a tag (enum or class).
if (CurContext->getLookupContext()
== TD->getDeclContext()->getLookupContext()) {
// We're pushing the tag into the current context, which might
// require some reshuffling in the identifier resolver.
IdentifierResolver::iterator
I = IdResolver.begin(TD->getDeclName()),
IEnd = IdResolver.end();
NamedDecl *ID = *I;
if (I != IEnd && isDeclInScope(ID, CurContext, S)) {
NamedDecl *PrevDecl = *I;
for (; I != IEnd && isDeclInScope(ID, CurContext, S);
PrevDecl = *I, ++I) {
if (TD->declarationReplaces(*I)) {
// This is a redeclaration. Remove it from the chain and
// break out, so that we'll add in the shadowed
// declaration.
S->RemoveDecl(DeclPtrTy::make(*I));
if (PrevDecl == *I) {
IdResolver.RemoveDecl(*I);
IdResolver.AddDecl(TD);
return;
} else {
IdResolver.RemoveDecl(*I);
break;
}
}
}
// If this replaces anything in the current scope,
IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()),
IEnd = IdResolver.end();
for (; I != IEnd; ++I) {
if (S->isDeclScope(DeclPtrTy::make(*I)) && D->declarationReplaces(*I)) {
S->RemoveDecl(DeclPtrTy::make(*I));
IdResolver.RemoveDecl(*I);
// There is already a declaration with the same name in the same
// scope, which is not a tag declaration. It must be found
// before we find the new declaration, so insert the new
// declaration at the end of the chain.
IdResolver.AddShadowedDecl(TD, PrevDecl);
return;
}
}
} else if ((isa<FunctionDecl>(D) &&
AllowOverloadingOfFunction(D, Context)) ||
isa<FunctionTemplateDecl>(D)) {
// We are pushing the name of a function or function template,
// which might be an overloaded name.
IdentifierResolver::iterator Redecl
= std::find_if(IdResolver.begin(D->getDeclName()),
IdResolver.end(),
std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
D));
if (Redecl != IdResolver.end() &&
S->isDeclScope(DeclPtrTy::make(*Redecl))) {
// There is already a declaration of a function on our
// IdResolver chain. Replace it with this declaration.
S->RemoveDecl(DeclPtrTy::make(*Redecl));
IdResolver.RemoveDecl(*Redecl);
}
} else if (isa<ObjCInterfaceDecl>(D)) {
// We're pushing an Objective-C interface into the current
// context. If there is already an alias declaration, remove it first.
for (IdentifierResolver::iterator
I = IdResolver.begin(D->getDeclName()), IEnd = IdResolver.end();
I != IEnd; ++I) {
if (isa<ObjCCompatibleAliasDecl>(*I)) {
S->RemoveDecl(DeclPtrTy::make(*I));
IdResolver.RemoveDecl(*I);
break;
}
// Should only need to replace one decl.
break;
}
}
S->AddDecl(DeclPtrTy::make(D));
IdResolver.AddDecl(D);
}
@ -450,7 +386,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
// The third "scope" argument is 0 since we aren't enabling lazy built-in
// creation from this context.
NamedDecl *IDecl = LookupName(TUScope, Id, LookupOrdinaryName);
NamedDecl *IDecl = LookupSingleName(TUScope, Id, LookupOrdinaryName);
return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
}
@ -492,7 +428,7 @@ void Sema::InitBuiltinVaListType() {
return;
IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
NamedDecl *VaDecl = LookupName(TUScope, VaIdent, LookupOrdinaryName);
NamedDecl *VaDecl = LookupSingleName(TUScope, VaIdent, LookupOrdinaryName);
TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
}
@ -1414,8 +1350,10 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
FEnd = AnonRecord->field_end();
F != FEnd; ++F) {
if ((*F)->getDeclName()) {
NamedDecl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(),
LookupOrdinaryName, true);
LookupResult R;
LookupQualifiedName(R, Owner, (*F)->getDeclName(),
LookupOrdinaryName, true);
NamedDecl *PrevDecl = R.getAsSingleDecl(Context);
if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
// C++ [class.union]p2:
// The names of the members of an anonymous union shall be
@ -1771,9 +1709,11 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
NameKind = LookupRedeclarationWithLinkage;
DC = CurContext;
PrevDecl = LookupName(S, Name, NameKind, true,
NameKind == LookupRedeclarationWithLinkage,
D.getIdentifierLoc());
LookupResult R;
LookupName(R, S, Name, NameKind, true,
NameKind == LookupRedeclarationWithLinkage,
D.getIdentifierLoc());
PrevDecl = R.getAsSingleDecl(Context);
} else { // Something like "int foo::x;"
DC = computeDeclContext(D.getCXXScopeSpec(), true);
@ -1789,7 +1729,9 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
return DeclPtrTy();
}
PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
LookupResult Res;
LookupQualifiedName(Res, DC, Name, LookupOrdinaryName, true);
PrevDecl = Res.getAsSingleDecl(Context);
// C++ 7.3.1.2p2:
// Members (including explicit specializations of templates) of a named
@ -2885,8 +2827,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
<< cast<NamedDecl>(DC) << D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl();
LookupResult Prev = LookupQualifiedName(DC, Name, LookupOrdinaryName,
true);
LookupResult Prev;
LookupQualifiedName(Prev, DC, Name, LookupOrdinaryName, true);
assert(!Prev.isAmbiguous() &&
"Cannot have an ambiguity in previous-declaration lookup");
for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
@ -3603,7 +3545,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
// among each other. Here they can only shadow globals, which is ok.
IdentifierInfo *II = D.getIdentifier();
if (II) {
if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) {
if (PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@ -4212,9 +4154,9 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DC = computeDeclContext(SS, true);
SearchDC = DC;
// Look-up name inside 'foo::'.
PrevDecl
= dyn_cast_or_null<TagDecl>(
LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl());
LookupResult R;
LookupQualifiedName(R, DC, Name, LookupTagName, true);
PrevDecl = dyn_cast_or_null<TagDecl>(R.getAsSingleDecl(Context));
// A tag 'foo::bar' must already exist.
if (PrevDecl == 0) {
@ -4229,7 +4171,8 @@ 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(S, Name, LookupTagName,
LookupResult R;
LookupName(R, S, Name, LookupTagName,
/*RedeclarationOnly=*/(TUK != TUK_Reference));
if (R.isAmbiguous()) {
DiagnoseAmbiguousLookup(R, Name, NameLoc);
@ -4242,7 +4185,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
PrevDecl = 0;
Invalid = true;
} else
PrevDecl = R;
PrevDecl = R.getAsSingleDecl(Context);
if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
@ -4489,10 +4432,11 @@ 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(S, Name, LookupOrdinaryName, true);
LookupResult Lookup;
LookupName(Lookup, S, Name, LookupOrdinaryName, true);
TypedefDecl *PrevTypedef = 0;
if (Lookup.getKind() == LookupResult::Found)
PrevTypedef = dyn_cast<TypedefDecl>(Lookup.getAsDecl());
if (NamedDecl *Prev = Lookup.getAsSingleDecl(Context))
PrevTypedef = dyn_cast<TypedefDecl>(Prev);
NamedDecl *PrevTypedefNamed = PrevTypedef;
if (PrevTypedef && isDeclInScope(PrevTypedefNamed, SearchDC, S) &&
@ -4708,7 +4652,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
if (D.getDeclSpec().isThreadSpecified())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true);
NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
@ -5089,7 +5033,7 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
DInfo, ac, (Expr *)BitfieldWidth);
if (II) {
NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true);
NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)
&& !isa<TagDecl>(PrevDecl)) {
Diag(Loc, diag::err_duplicate_member) << II;
@ -5342,7 +5286,7 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
// Verify that there isn't already something declared with this name in this
// scope.
NamedDecl *PrevDecl = LookupName(S, Id, LookupOrdinaryName);
NamedDecl *PrevDecl = LookupSingleName(S, Id, LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
@ -5585,7 +5529,7 @@ Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
SourceLocation PragmaLoc,
SourceLocation NameLoc) {
Decl *PrevDecl = LookupName(TUScope, Name, LookupOrdinaryName);
Decl *PrevDecl = LookupSingleName(TUScope, Name, LookupOrdinaryName);
if (PrevDecl) {
PrevDecl->addAttr(::new (Context) WeakAttr());
@ -5601,7 +5545,7 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
SourceLocation PragmaLoc,
SourceLocation NameLoc,
SourceLocation AliasNameLoc) {
Decl *PrevDecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
Decl *PrevDecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName);
WeakInfo W = WeakInfo(Name, NameLoc);
if (PrevDecl) {

View File

@ -1104,8 +1104,9 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// Look up the function
NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(),
Sema::LookupOrdinaryName);
NamedDecl *CleanupDecl
= S.LookupSingleName(S.TUScope, Attr.getParameterName(),
Sema::LookupOrdinaryName);
if (!CleanupDecl) {
S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) <<
Attr.getParameterName();

View File

@ -2490,8 +2490,8 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
// original-namespace-definition is the name of the namespace. Subsequently
// in that declarative region, it is treated as an original-namespace-name.
NamedDecl *PrevDecl = LookupName(DeclRegionScope, II, LookupOrdinaryName,
true);
NamedDecl *PrevDecl
= LookupSingleName(DeclRegionScope, II, LookupOrdinaryName, true);
if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
// This is an extended namespace definition.
@ -2599,13 +2599,14 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
UsingDirectiveDecl *UDir = 0;
// Lookup namespace name.
LookupResult R = LookupParsedName(S, &SS, NamespcName,
LookupNamespaceName, false);
LookupResult R;
LookupParsedName(R, S, &SS, NamespcName, LookupNamespaceName, false);
if (R.isAmbiguous()) {
DiagnoseAmbiguousLookup(R, NamespcName, IdentLoc);
return DeclPtrTy();
}
if (NamedDecl *NS = R) {
if (!R.empty()) {
NamedDecl *NS = R.getFoundDecl();
assert(isa<NamespaceDecl>(NS) && "expected namespace decl");
// C++ [namespace.udir]p1:
// A using-directive specifies that the names in the nominated
@ -2746,15 +2747,16 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
// Lookup target name.
LookupResult R = LookupQualifiedName(LookupContext,
Name, LookupOrdinaryName);
LookupResult R;
LookupQualifiedName(R, LookupContext, Name, LookupOrdinaryName);
if (!R) {
if (R.empty()) {
DiagnoseMissingMember(IdentLoc, Name, NNS, SS.getRange());
return 0;
}
NamedDecl *ND = R.getAsDecl();
// FIXME: handle ambiguity?
NamedDecl *ND = R.getAsSingleDecl(Context);
if (IsTypeName && !isa<TypeDecl>(ND)) {
Diag(IdentLoc, diag::err_using_typename_non_type);
@ -2790,14 +2792,17 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
IdentifierInfo *Ident) {
// Lookup the namespace name.
LookupResult R = LookupParsedName(S, &SS, Ident, LookupNamespaceName, false);
LookupResult R;
LookupParsedName(R, S, &SS, Ident, LookupNamespaceName, false);
// Check if we have a previous declaration with the same name.
if (NamedDecl *PrevDecl = LookupName(S, Alias, LookupOrdinaryName, true)) {
if (NamedDecl *PrevDecl
= LookupSingleName(S, Alias, LookupOrdinaryName, true)) {
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.
if (!R.isAmbiguous() && AD->getNamespace() == getNamespaceDecl(R))
if (!R.isAmbiguous() && !R.empty() &&
AD->getNamespace() == getNamespaceDecl(R.getFoundDecl()))
return DeclPtrTy();
}
@ -2813,7 +2818,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
return DeclPtrTy();
}
if (!R) {
if (R.empty()) {
Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
return DeclPtrTy();
}
@ -2822,7 +2827,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc,
Alias, SS.getRange(),
(NestedNameSpecifier *)SS.getScopeRep(),
IdentLoc, R);
IdentLoc, R.getFoundDecl());
CurContext->addDecl(AliasDecl);
return DeclPtrTy::make(AliasDecl);
@ -4151,7 +4156,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
bool Invalid = D.isInvalidType();
IdentifierInfo *II = D.getIdentifier();
if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) {
// The scope should be freshly made just for us. There is just no way
// it contains any previous declaration.
assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));
@ -4398,7 +4403,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
// FIXME: handle dependent contexts
if (!DC) return DeclPtrTy();
PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
LookupResult R;
LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true);
PrevDecl = R.getAsSingleDecl(Context);
// If searching in that context implicitly found a declaration in
// a different context, treat it like it wasn't found at all.
@ -4431,7 +4438,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
while (DC->isRecord())
DC = DC->getParent();
PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true);
LookupResult R;
LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true);
PrevDecl = R.getAsSingleDecl(Context);
// TODO: decide what we think about using declarations.
if (PrevDecl)

View File

@ -84,7 +84,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
assert(ClassName && "Missing class identifier");
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
@ -124,7 +124,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
if (SuperName) {
// Check if a different kind of symbol declared in this scope.
PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
PrevDecl = LookupSingleName(TUScope, SuperName, LookupOrdinaryName);
if (PrevDecl == IDecl) {
Diag(SuperLoc, diag::err_recursive_superclass)
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
@ -195,7 +195,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
IdentifierInfo *ClassName,
SourceLocation ClassLocation) {
// Look for previous declaration of alias name
NamedDecl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName);
if (ADecl) {
if (isa<ObjCCompatibleAliasDecl>(ADecl))
Diag(AliasLocation, diag::warn_previous_alias_decl);
@ -205,13 +205,13 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
return DeclPtrTy();
}
// Check for class declaration
NamedDecl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(CDeclU)) {
QualType T = TDecl->getUnderlyingType();
if (T->isObjCInterfaceType()) {
if (NamedDecl *IDecl = T->getAs<ObjCInterfaceType>()->getDecl()) {
ClassName = IDecl->getIdentifier();
CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
}
}
}
@ -654,7 +654,8 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
SourceLocation SuperClassLoc) {
ObjCInterfaceDecl* IDecl = 0;
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
NamedDecl *PrevDecl
= LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
@ -671,7 +672,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
ObjCInterfaceDecl* SDecl = 0;
if (SuperClassname) {
// Check if a different kind of symbol declared in this scope.
PrevDecl = LookupName(TUScope, SuperClassname, LookupOrdinaryName);
PrevDecl = LookupSingleName(TUScope, SuperClassname, LookupOrdinaryName);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(SuperClassLoc, diag::err_redefinition_different_kind)
<< SuperClassname;
@ -1121,7 +1122,8 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
for (unsigned i = 0; i != NumElts; ++i) {
// Check for another declaration kind with the same name.
NamedDecl *PrevDecl = LookupName(TUScope, IdentList[i], LookupOrdinaryName);
NamedDecl *PrevDecl
= LookupSingleName(TUScope, IdentList[i], LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);

View File

@ -695,8 +695,8 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
isAddressOfOperand));
}
LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName,
false, true, Loc);
LookupResult Lookup;
LookupParsedName(Lookup, S, SS, Name, LookupOrdinaryName, false, true, Loc);
if (Lookup.isAmbiguous()) {
DiagnoseAmbiguousLookup(Lookup, Name, Loc,
@ -705,7 +705,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
return ExprError();
}
NamedDecl *D = Lookup.getAsDecl();
NamedDecl *D = Lookup.getAsSingleDecl(Context);
// If this reference is in an Objective-C method, then ivar lookup happens as
// well.
@ -2181,10 +2181,10 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
}
// The record definition is complete, now make sure the member is valid.
LookupResult Result
= LookupQualifiedName(DC, MemberName, LookupMemberName, false);
LookupResult Result;
LookupQualifiedName(Result, DC, MemberName, LookupMemberName, false);
if (!Result)
if (Result.empty())
return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated)
<< MemberName << BaseExpr->getSourceRange());
if (Result.isAmbiguous()) {
@ -2193,13 +2193,14 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
return ExprError();
}
NamedDecl *MemberDecl = Result.getAsSingleDecl(Context);
if (SS && SS->isSet()) {
TypeDecl* TyD = cast<TypeDecl>(MemberDecl->getDeclContext());
QualType BaseTypeCanon
= Context.getCanonicalType(BaseType).getUnqualifiedType();
QualType MemberTypeCanon
= Context.getCanonicalType(
Context.getTypeDeclType(
dyn_cast<TypeDecl>(Result.getAsDecl()->getDeclContext())));
= Context.getCanonicalType(Context.getTypeDeclType(TyD));
if (BaseTypeCanon != MemberTypeCanon &&
!IsDerivedFrom(BaseTypeCanon, MemberTypeCanon))
@ -2208,8 +2209,6 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
<< MemberTypeCanon << BaseTypeCanon);
}
NamedDecl *MemberDecl = Result;
// If the decl being referenced had an error, return an error for this
// sub-expr without emitting another error, in order to avoid cascading
// error cases.
@ -5685,10 +5684,11 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
}
}
LookupResult R;
LookupQualifiedName(R, RD, OC.U.IdentInfo, LookupMemberName);
FieldDecl *MemberDecl
= dyn_cast_or_null<FieldDecl>(LookupQualifiedName(RD, OC.U.IdentInfo,
LookupMemberName)
.getAsDecl());
= dyn_cast_or_null<FieldDecl>(R.getAsSingleDecl(Context));
// FIXME: Leaks Res
if (!MemberDecl)
return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member_deprecated)

View File

@ -69,8 +69,9 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr();
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
Decl *TypeInfoDecl = LookupQualifiedName(StdNamespace, TypeInfoII,
LookupTagName);
LookupResult R;
LookupQualifiedName(R, StdNamespace, TypeInfoII, LookupTagName);
Decl *TypeInfoDecl = R.getAsSingleDecl(Context);
RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
if (!TypeInfoRecordDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
@ -589,14 +590,17 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
DeclarationName Name, Expr** Args,
unsigned NumArgs, DeclContext *Ctx,
bool AllowMissing, FunctionDecl *&Operator) {
LookupResult R = LookupQualifiedName(Ctx, Name, LookupOrdinaryName);
if (!R) {
LookupResult R;
LookupQualifiedName(R, Ctx, Name, LookupOrdinaryName);
if (R.empty()) {
if (AllowMissing)
return false;
return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range;
}
// FIXME: handle ambiguity
OverloadCandidateSet Candidates;
for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
Alloc != AllocEnd; ++Alloc) {
@ -868,8 +872,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
= cast<CXXRecordDecl>(Pointee->getAs<RecordType>()->getDecl());
// Try to find operator delete/operator delete[] in class scope.
LookupResult Found = LookupQualifiedName(Record, DeleteName,
LookupOrdinaryName);
LookupResult Found;
LookupQualifiedName(Found, Record, DeleteName, LookupOrdinaryName);
// FIXME: Diagnose ambiguity properly
assert(!Found.isAmbiguous() && "Ambiguous delete/delete[] not handled");
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();

View File

@ -77,7 +77,7 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
Ty = Context.getObjCObjectPointerType(Ty);
} else {
IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
NamedDecl *IF = LookupName(TUScope, NSIdent, LookupOrdinaryName);
NamedDecl *IF = LookupSingleName(TUScope, NSIdent, LookupOrdinaryName);
if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
Context.setObjCConstantStringInterface(StrIF);
Ty = Context.getObjCConstantStringInterface();
@ -387,7 +387,8 @@ Sema::ExprResult Sema::ActOnClassMessage(
} else {
// 'super' has been used outside a method context. If a variable named
// 'super' has been declared, redirect. If not, produce a diagnostic.
NamedDecl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName);
NamedDecl *SuperDecl
= LookupSingleName(S, receiverName, LookupOrdinaryName);
ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
if (VD) {
ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(),
@ -412,7 +413,8 @@ Sema::ExprResult Sema::ActOnClassMessage(
//
// If necessary, the following lookup could move to getObjCInterfaceDecl().
if (!ClassDecl) {
NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName);
NamedDecl *IDecl
= LookupSingleName(TUScope, receiverName, LookupOrdinaryName);
if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
const ObjCInterfaceType *OCIT;
OCIT = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>();

File diff suppressed because it is too large Load Diff

View File

@ -2762,8 +2762,9 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
if (RequireCompleteType(OpLoc, T1, PartialDiagnostic(0)))
return;
LookupResult Operators = LookupQualifiedName(T1Rec->getDecl(), OpName,
LookupOrdinaryName, false);
LookupResult Operators;
LookupQualifiedName(Operators, T1Rec->getDecl(), OpName,
LookupOrdinaryName, false);
for (LookupResult::iterator Oper = Operators.begin(),
OperEnd = Operators.end();
Oper != OperEnd;
@ -5070,8 +5071,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
OverloadCandidateSet CandidateSet;
const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
LookupResult R = LookupQualifiedName(BaseRecord->getDecl(), OpName,
LookupOrdinaryName);
LookupResult R;
LookupQualifiedName(R, BaseRecord->getDecl(), OpName, LookupOrdinaryName);
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper)

View File

@ -135,7 +135,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS))
return TNK_Non_template;
Found = LookupQualifiedName(LookupCtx, &II, LookupOrdinaryName);
LookupQualifiedName(Found, LookupCtx, &II, LookupOrdinaryName);
if (ObjectTypePtr && Found.getKind() == LookupResult::NotFound) {
// C++ [basic.lookup.classref]p1:
@ -150,7 +150,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...
Found = LookupName(S, &II, LookupOrdinaryName);
LookupName(Found, S, &II, LookupOrdinaryName);
ObjectTypeSearchedInScope = true;
}
} else if (isDependent) {
@ -158,14 +158,15 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
return TNK_Non_template;
} else {
// Perform unqualified name lookup in the current scope.
Found = LookupName(S, &II, LookupOrdinaryName);
LookupName(Found, S, &II, LookupOrdinaryName);
}
// FIXME: Cope with ambiguous name-lookup results.
assert(!Found.isAmbiguous() &&
"Cannot handle template name-lookup ambiguities");
NamedDecl *Template = isAcceptableTemplateName(Context, Found);
NamedDecl *Template
= isAcceptableTemplateName(Context, Found.getAsSingleDecl(Context));
if (!Template)
return TNK_Non_template;
@ -175,9 +176,11 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
// template, the name is also looked up in the context of the entire
// postfix-expression and [...]
//
LookupResult FoundOuter = LookupName(S, &II, LookupOrdinaryName);
LookupResult FoundOuter;
LookupName(FoundOuter, S, &II, LookupOrdinaryName);
// FIXME: Handle ambiguities in this lookup better
NamedDecl *OuterTemplate = isAcceptableTemplateName(Context, FoundOuter);
NamedDecl *OuterTemplate
= isAcceptableTemplateName(Context, FoundOuter.getAsSingleDecl(Context));
if (!OuterTemplate) {
// - if the name is not found, the name found in the class of the
@ -284,7 +287,7 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
bool Invalid = false;
if (ParamName) {
NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, LookupTagName);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
PrevDecl);
@ -402,7 +405,7 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
IdentifierInfo *ParamName = D.getIdentifier();
if (ParamName) {
NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName);
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, LookupTagName);
if (PrevDecl && PrevDecl->isTemplateParameter())
Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
PrevDecl);
@ -577,11 +580,11 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
return true;
}
Previous = LookupQualifiedName(SemanticContext, Name, LookupOrdinaryName,
LookupQualifiedName(Previous, SemanticContext, Name, LookupOrdinaryName,
true);
} else {
SemanticContext = CurContext;
Previous = LookupName(S, Name, LookupOrdinaryName, true);
LookupName(Previous, S, Name, LookupOrdinaryName, true);
}
assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?");
@ -3581,8 +3584,9 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
: TSK_ExplicitInstantiationDeclaration;
LookupResult Previous = LookupParsedName(S, &D.getCXXScopeSpec(),
Name, LookupOrdinaryName);
LookupResult Previous;
LookupParsedName(Previous, S, &D.getCXXScopeSpec(),
Name, LookupOrdinaryName);
if (!R->isFunctionType()) {
// C++ [temp.explicit]p1:
@ -3594,14 +3598,15 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
D.getSourceRange());
}
VarDecl *Prev = dyn_cast_or_null<VarDecl>(Previous.getAsDecl());
VarDecl *Prev = dyn_cast_or_null<VarDecl>(
Previous.getAsSingleDecl(Context));
if (!Prev || !Prev->isStaticDataMember()) {
// We expect to see a data data member here.
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known)
<< Name;
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
P != PEnd; ++P)
Diag(P->getLocation(), diag::note_explicit_instantiation_here);
Diag((*P)->getLocation(), diag::note_explicit_instantiation_here);
return true;
}
@ -3824,8 +3829,8 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
assert(Ctx && "No declaration context?");
DeclarationName Name(&II);
LookupResult Result = LookupQualifiedName(Ctx, Name, LookupOrdinaryName,
false);
LookupResult Result;
LookupQualifiedName(Result, Ctx, Name, LookupOrdinaryName, false);
unsigned DiagID = 0;
Decl *Referenced = 0;
switch (Result.getKind()) {
@ -3837,7 +3842,7 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
break;
case LookupResult::Found:
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getAsDecl())) {
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
// We found a type. Build a QualifiedNameType, since the
// typename-specifier was just sugar. FIXME: Tell
// QualifiedNameType that it has a "typename" prefix.
@ -3845,7 +3850,7 @@ Sema::CheckTypenameType(NestedNameSpecifier *NNS, const IdentifierInfo &II,
}
DiagID = diag::err_typename_nested_not_type;
Referenced = Result.getAsDecl();
Referenced = Result.getFoundDecl();
break;
case LookupResult::FoundOverloaded:

View File

@ -657,8 +657,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
NamedDecl *PrevDecl = 0;
if (!FunctionTemplate || TemplateParams) {
PrevDecl = SemaRef.LookupQualifiedName(Owner, Name,
Sema::LookupOrdinaryName, true);
Sema::LookupResult R;
SemaRef.LookupQualifiedName(R, Owner, Name, Sema::LookupOrdinaryName, true);
PrevDecl = R.getAsSingleDecl(SemaRef.Context);
// In C++, the previous declaration we find might be a tag type
// (class or enum). In this case, the new declaration will hide the

View File

@ -5,7 +5,7 @@ C c;
void D(int);
class D {}; // expected-note {{previous use is here}}
class D {};
void foo()
{
@ -13,7 +13,7 @@ void foo()
class D d;
}
class D;
class D; // expected-note {{previous use is here}}
enum D; // expected-error {{use of 'D' with tag type that does not match previous declaration}}