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)) if (isa<ObjCMethodDecl>(this))
return false; return false;
if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
return true;
// For non-function declarations, if the declarations are of the // For non-function declarations, if the declarations are of the
// same kind then this must be a redeclaration, or semantic analysis // same kind then this must be a redeclaration, or semantic analysis
// would not have given us the new declaration. // would not have given us the new declaration.

View File

@ -1045,63 +1045,13 @@ public:
/// results occurred for a given lookup. /// results occurred for a given lookup.
/// ///
/// Any non-ambiguous lookup can be converted into a single /// Any non-ambiguous lookup can be converted into a single
/// (possibly NULL) @c NamedDecl* via a conversion function or the /// (possibly NULL) @c NamedDecl* via the getAsSingleDecl() method.
/// getAsDecl() method. This conversion permits the common-case /// This permits the common-case usage in C and Objective-C where
/// usage in C and Objective-C where name lookup will always return /// name lookup will always return a single declaration. Use of
/// a single declaration. /// this is largely deprecated; callers should handle the possibility
struct LookupResult { /// of multiple declarations.
/// The kind of entity that is actually stored within the class LookupResult {
/// LookupResult object. public:
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.
enum LookupKind { enum LookupKind {
/// @brief No entity found met the criteria. /// @brief No entity found met the criteria.
NotFound = 0, NotFound = 0,
@ -1156,122 +1106,119 @@ public:
/// } /// }
/// } /// }
/// @endcode /// @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, LookupResult()
IdentifierResolver::iterator F, : Kind(NotFound),
IdentifierResolver::iterator L); Paths(0)
{}
static LookupResult CreateLookupResult(ASTContext &Context, ~LookupResult() {
DeclContext::lookup_iterator F, if (Paths) deletePaths(Paths);
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;
} }
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 { bool isAmbiguous() const {
return StoredKind == AmbiguousLookupStoresBasePaths || return getKind() >= FirstAmbiguous;
StoredKind == AmbiguousLookupStoresDecls;
} }
/// @brief Allows conversion of a lookup result into a LookupKind getKind() const {
/// declaration, with the same behavior as getAsDecl. sanity();
operator NamedDecl*() const { return getAsDecl(); } 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 /// This should be called in any environment where lookup might
/// non-ambiguous name lookup. /// generate multiple lookup results.
class iterator { void resolveKind();
/// The LookupResult structure we're iterating through.
LookupResult *Result;
/// The current position of this iterator within the sequence of /// \brief Fetch this as an unambiguous single declaration
/// results. This value will have the same representation as the /// (possibly an overloaded one).
/// @c First field in the LookupResult structure. ///
mutable uintptr_t Current; /// This is deprecated; users should be written to handle
/// ambiguous and overloaded lookups.
NamedDecl *getAsSingleDecl(ASTContext &Context) const;
public: /// \brief Fetch the unique decl found by this lookup. Asserts
typedef NamedDecl * value_type; /// that one was found.
typedef NamedDecl * reference; ///
typedef NamedDecl * pointer; /// This is intended for users who have examined the result kind
typedef std::ptrdiff_t difference_type; /// and are certain that there is only one result.
typedef std::forward_iterator_tag iterator_category; 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) { // Sanity checks.
iterator tmp(*this); void sanity() const {
++(*this); assert(Kind != NotFound || Decls.size() == 0);
return tmp; 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) { static void deletePaths(CXXBasePaths *);
return x.Current == y.Current;
}
friend inline bool operator!=(iterator const& x, iterator const& y) { LookupKind Kind;
return x.Current != y.Current; DeclsTy Decls;
} CXXBasePaths *Paths;
};
friend class iterator;
iterator begin();
iterator end();
/// \brief Free the memory associated with this lookup.
void Destroy();
}; };
private: private:
typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy; typedef llvm::SmallVector<LookupResult, 3> LookupResultsVecTy;
std::pair<bool, LookupResult> CppLookupName(Scope *S, DeclarationName Name, bool CppLookupName(LookupResult &R, Scope *S, DeclarationName Name,
LookupNameKind NameKind, LookupNameKind NameKind, bool RedeclarationOnly);
bool RedeclarationOnly);
public: public:
/// Determines whether D is a suitable lookup result according to the /// Determines whether D is a suitable lookup result according to the
/// lookup criteria. /// lookup criteria.
@ -1303,24 +1250,38 @@ public:
return false; return false;
} }
LookupResult LookupName(Scope *S, DeclarationName Name, /// \brief Look up a name, looking for a single declaration. Return
LookupNameKind NameKind, /// null if no unambiguous results were found.
bool RedeclarationOnly = false, ///
bool AllowBuiltinCreation = false, /// It is preferable to use the elaborated form and explicitly handle
SourceLocation Loc = SourceLocation()); /// ambiguity and overloaded.
LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
LookupNameKind NameKind, LookupNameKind NameKind,
bool RedeclarationOnly = false); 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, Decl *LookupQualifiedNameWithType(DeclContext *LookupCtx,
DeclarationName Name, DeclarationName Name,
QualType T); QualType T);
LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS, bool LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
DeclarationName Name, DeclarationName Name,
LookupNameKind NameKind, LookupNameKind NameKind,
bool RedeclarationOnly = false, bool RedeclarationOnly = false,
bool AllowBuiltinCreation = false, bool AllowBuiltinCreation = false,
SourceLocation Loc = SourceLocation(), SourceLocation Loc = SourceLocation(),
bool EnteringContext = false); bool EnteringContext = false);
ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II); ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II);
ObjCCategoryImplDecl *LookupObjCCategoryImpl(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) { for (unsigned i = 0; i < NumIdentifiers; ++i) {
const Token &Tok = Identifiers[i]; const Token &Tok = Identifiers[i];
IdentifierInfo *Name = Tok.getIdentifierInfo(); IdentifierInfo *Name = Tok.getIdentifierInfo();
const LookupResult &Lookup = LookupParsedName(curScope, NULL, Name, LookupResult Lookup;
LookupOrdinaryName, LookupParsedName(Lookup, curScope, NULL, Name,LookupOrdinaryName,
false, true, false, true, Tok.getLocation());
Tok.getLocation());
// FIXME: Handle Lookup.isAmbiguous? // FIXME: Handle Lookup.isAmbiguous?
NamedDecl *ND = Lookup.getAsDecl(); NamedDecl *ND = Lookup.getAsSingleDecl(Context);
if (!ND) { if (!ND) {
Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 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) if (NNS->getKind() != NestedNameSpecifier::Identifier)
return 0; return 0;
LookupResult Found LookupResult Found;
= LookupName(S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName); LookupName(Found, S, NNS->getAsIdentifier(), LookupNestedNameSpecifierName);
assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet"); assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
NamedDecl *Result = Found; NamedDecl *Result = Found.getAsSingleDecl(Context);
if (isAcceptableNestedNameSpecifier(Result)) if (isAcceptableNestedNameSpecifier(Result))
return Result; return Result;
@ -359,8 +359,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS)) if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(SS))
return 0; return 0;
Found = LookupQualifiedName(LookupCtx, &II, LookupNestedNameSpecifierName, LookupQualifiedName(Found, LookupCtx, &II, LookupNestedNameSpecifierName,
false); false);
if (!ObjectType.isNull() && Found.getKind() == LookupResult::NotFound) { if (!ObjectType.isNull() && Found.getKind() == LookupResult::NotFound) {
// C++ [basic.lookup.classref]p4: // 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 // reconstruct the result from when name lookup was performed at template
// definition time. // definition time.
if (S) if (S)
Found = LookupName(S, &II, LookupNestedNameSpecifierName); LookupName(Found, S, &II, LookupNestedNameSpecifierName);
else else if (ScopeLookupResult)
Found = LookupResult::CreateLookupResult(Context, ScopeLookupResult); Found.addDecl(ScopeLookupResult);
ObjectTypeSearchedInScope = true; ObjectTypeSearchedInScope = true;
} }
@ -401,11 +401,11 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
return NestedNameSpecifier::Create(Context, Prefix, &II); return NestedNameSpecifier::Create(Context, Prefix, &II);
} else { } else {
// Perform unqualified name lookup in the current scope. // Perform unqualified name lookup in the current scope.
Found = LookupName(S, &II, LookupNestedNameSpecifierName); LookupName(Found, S, &II, LookupNestedNameSpecifierName);
} }
// FIXME: Deal with ambiguities cleanly. // FIXME: Deal with ambiguities cleanly.
NamedDecl *SD = Found; NamedDecl *SD = Found.getAsSingleDecl(Context);
if (isAcceptableNestedNameSpecifier(SD)) { if (isAcceptableNestedNameSpecifier(SD)) {
if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) { if (!ObjectType.isNull() && !ObjectTypeSearchedInScope) {
// C++ [basic.lookup.classref]p4: // 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 // 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 // see if we can find the same name there. As above, if there is no
// scope, reconstruct the result from the template instantiation itself. // scope, reconstruct the result from the template instantiation itself.
LookupResult FoundOuter; NamedDecl *OuterDecl;
if (S) if (S) {
FoundOuter = LookupName(S, &II, LookupNestedNameSpecifierName); LookupResult FoundOuter;
else LookupName(FoundOuter, S, &II, LookupNestedNameSpecifierName);
FoundOuter = LookupResult::CreateLookupResult(Context, // FIXME: Handle ambiguities!
ScopeLookupResult); OuterDecl = FoundOuter.getAsSingleDecl(Context);
} else
OuterDecl = ScopeLookupResult;
// FIXME: Handle ambiguities in FoundOuter!
NamedDecl *OuterDecl = FoundOuter;
if (isAcceptableNestedNameSpecifier(OuterDecl) && if (isAcceptableNestedNameSpecifier(OuterDecl) &&
OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() && OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
(!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) || (!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 // If we didn't find anything during our lookup, try again with
// ordinary name lookup, which can help us produce better error // ordinary name lookup, which can help us produce better error
// messages. // messages.
if (!SD) if (!SD) {
SD = LookupName(S, &II, LookupOrdinaryName); Found.clear();
LookupName(Found, S, &II, LookupOrdinaryName);
SD = Found.getAsSingleDecl(Context);
}
unsigned DiagID; unsigned DiagID;
if (SD) if (SD)

View File

@ -85,8 +85,8 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
II, SS->getRange()).getAsOpaquePtr(); II, SS->getRange()).getAsOpaquePtr();
} }
LookupResult Result LookupResult Result;
= LookupParsedName(S, SS, &II, LookupOrdinaryName, false, false); LookupParsedName(Result, S, SS, &II, LookupOrdinaryName, false, false);
NamedDecl *IIDecl = 0; NamedDecl *IIDecl = 0;
switch (Result.getKind()) { 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 // perform this lookup again (e.g., as an object name), which
// will produce the ambiguity, or will complain that it expected // will produce the ambiguity, or will complain that it expected
// a type name. // a type name.
Result.Destroy();
return 0; return 0;
} }
@ -128,7 +127,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
} }
case LookupResult::Found: case LookupResult::Found:
IIDecl = Result.getAsDecl(); IIDecl = Result.getFoundDecl();
break; break;
} }
@ -179,9 +178,10 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
/// where the user forgot to specify the tag. /// where the user forgot to specify the tag.
DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) { DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
// Do a tag name lookup in this scope. // 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 (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()) { switch (TD->getTagKind()) {
case TagDecl::TK_struct: return DeclSpec::TST_struct; case TagDecl::TK_struct: return DeclSpec::TST_struct;
case TagDecl::TK_union: return DeclSpec::TST_union; 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())) (isa<VarDecl>(D) && cast<VarDecl>(D)->isOutOfLine()))
return; return;
S->AddDecl(DeclPtrTy::make(D)); // If this replaces anything in the current scope,
IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()),
// C++ [basic.scope]p4: IEnd = IdResolver.end();
// -- exactly one declaration shall declare a class name or for (; I != IEnd; ++I) {
// enumeration name that is not a typedef name and the other if (S->isDeclScope(DeclPtrTy::make(*I)) && D->declarationReplaces(*I)) {
// declarations shall all refer to the same object or S->RemoveDecl(DeclPtrTy::make(*I));
// enumerator, or all refer to functions and function templates; IdResolver.RemoveDecl(*I);
// 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;
}
}
}
// There is already a declaration with the same name in the same // Should only need to replace one decl.
// scope, which is not a tag declaration. It must be found break;
// 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;
}
} }
} }
S->AddDecl(DeclPtrTy::make(D));
IdResolver.AddDecl(D); IdResolver.AddDecl(D);
} }
@ -450,7 +386,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) { ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
// The third "scope" argument is 0 since we aren't enabling lazy built-in // The third "scope" argument is 0 since we aren't enabling lazy built-in
// creation from this context. // creation from this context.
NamedDecl *IDecl = LookupName(TUScope, Id, LookupOrdinaryName); NamedDecl *IDecl = LookupSingleName(TUScope, Id, LookupOrdinaryName);
return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl); return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
} }
@ -492,7 +428,7 @@ void Sema::InitBuiltinVaListType() {
return; return;
IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list"); 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); TypedefDecl *VaTypedef = cast<TypedefDecl>(VaDecl);
Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef)); Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
} }
@ -1414,8 +1350,10 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
FEnd = AnonRecord->field_end(); FEnd = AnonRecord->field_end();
F != FEnd; ++F) { F != FEnd; ++F) {
if ((*F)->getDeclName()) { if ((*F)->getDeclName()) {
NamedDecl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(), LookupResult R;
LookupOrdinaryName, true); LookupQualifiedName(R, Owner, (*F)->getDeclName(),
LookupOrdinaryName, true);
NamedDecl *PrevDecl = R.getAsSingleDecl(Context);
if (PrevDecl && !isa<TagDecl>(PrevDecl)) { if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
// C++ [class.union]p2: // C++ [class.union]p2:
// The names of the members of an anonymous union shall be // The names of the members of an anonymous union shall be
@ -1771,9 +1709,11 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
NameKind = LookupRedeclarationWithLinkage; NameKind = LookupRedeclarationWithLinkage;
DC = CurContext; DC = CurContext;
PrevDecl = LookupName(S, Name, NameKind, true, LookupResult R;
NameKind == LookupRedeclarationWithLinkage, LookupName(R, S, Name, NameKind, true,
D.getIdentifierLoc()); NameKind == LookupRedeclarationWithLinkage,
D.getIdentifierLoc());
PrevDecl = R.getAsSingleDecl(Context);
} else { // Something like "int foo::x;" } else { // Something like "int foo::x;"
DC = computeDeclContext(D.getCXXScopeSpec(), true); DC = computeDeclContext(D.getCXXScopeSpec(), true);
@ -1789,7 +1729,9 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
return DeclPtrTy(); 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: // C++ 7.3.1.2p2:
// Members (including explicit specializations of templates) of a named // 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(); << cast<NamedDecl>(DC) << D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl(); NewFD->setInvalidDecl();
LookupResult Prev = LookupQualifiedName(DC, Name, LookupOrdinaryName, LookupResult Prev;
true); LookupQualifiedName(Prev, DC, Name, LookupOrdinaryName, true);
assert(!Prev.isAmbiguous() && assert(!Prev.isAmbiguous() &&
"Cannot have an ambiguity in previous-declaration lookup"); "Cannot have an ambiguity in previous-declaration lookup");
for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); 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. // among each other. Here they can only shadow globals, which is ok.
IdentifierInfo *II = D.getIdentifier(); IdentifierInfo *II = D.getIdentifier();
if (II) { if (II) {
if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) { if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) {
if (PrevDecl->isTemplateParameter()) { if (PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter. // Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@ -4212,9 +4154,9 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DC = computeDeclContext(SS, true); DC = computeDeclContext(SS, true);
SearchDC = DC; SearchDC = DC;
// Look-up name inside 'foo::'. // Look-up name inside 'foo::'.
PrevDecl LookupResult R;
= dyn_cast_or_null<TagDecl>( LookupQualifiedName(R, DC, Name, LookupTagName, true);
LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl()); PrevDecl = dyn_cast_or_null<TagDecl>(R.getAsSingleDecl(Context));
// A tag 'foo::bar' must already exist. // A tag 'foo::bar' must already exist.
if (PrevDecl == 0) { 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 // 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. Doing so can result in ambiguities that we
// shouldn't be diagnosing. // shouldn't be diagnosing.
LookupResult R = LookupName(S, Name, LookupTagName, LookupResult R;
LookupName(R, S, Name, LookupTagName,
/*RedeclarationOnly=*/(TUK != TUK_Reference)); /*RedeclarationOnly=*/(TUK != TUK_Reference));
if (R.isAmbiguous()) { if (R.isAmbiguous()) {
DiagnoseAmbiguousLookup(R, Name, NameLoc); DiagnoseAmbiguousLookup(R, Name, NameLoc);
@ -4242,7 +4185,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
PrevDecl = 0; PrevDecl = 0;
Invalid = true; Invalid = true;
} else } else
PrevDecl = R; PrevDecl = R.getAsSingleDecl(Context);
if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) { if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated // 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 // shall not be declared with the same name as a typedef-name
// that is declared in that scope and refers to a type other // that is declared in that scope and refers to a type other
// than the class or enumeration itself. // than the class or enumeration itself.
LookupResult Lookup = LookupName(S, Name, LookupOrdinaryName, true); LookupResult Lookup;
LookupName(Lookup, S, Name, LookupOrdinaryName, true);
TypedefDecl *PrevTypedef = 0; TypedefDecl *PrevTypedef = 0;
if (Lookup.getKind() == LookupResult::Found) if (NamedDecl *Prev = Lookup.getAsSingleDecl(Context))
PrevTypedef = dyn_cast<TypedefDecl>(Lookup.getAsDecl()); PrevTypedef = dyn_cast<TypedefDecl>(Prev);
NamedDecl *PrevTypedefNamed = PrevTypedef; NamedDecl *PrevTypedefNamed = PrevTypedef;
if (PrevTypedef && isDeclInScope(PrevTypedefNamed, SearchDC, S) && if (PrevTypedef && isDeclInScope(PrevTypedefNamed, SearchDC, S) &&
@ -4708,7 +4652,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
if (D.getDeclSpec().isThreadSpecified()) if (D.getDeclSpec().isThreadSpecified())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread); 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()) { if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter. // Maybe we will complain about the shadowed template parameter.
@ -5089,7 +5033,7 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
DInfo, ac, (Expr *)BitfieldWidth); DInfo, ac, (Expr *)BitfieldWidth);
if (II) { if (II) {
NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true); NamedDecl *PrevDecl = LookupSingleName(S, II, LookupMemberName, true);
if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S) if (PrevDecl && isDeclInScope(PrevDecl, EnclosingContext, S)
&& !isa<TagDecl>(PrevDecl)) { && !isa<TagDecl>(PrevDecl)) {
Diag(Loc, diag::err_duplicate_member) << II; 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 // Verify that there isn't already something declared with this name in this
// scope. // scope.
NamedDecl *PrevDecl = LookupName(S, Id, LookupOrdinaryName); NamedDecl *PrevDecl = LookupSingleName(S, Id, LookupOrdinaryName);
if (PrevDecl && PrevDecl->isTemplateParameter()) { if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter. // Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(IdLoc, PrevDecl); DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
@ -5585,7 +5529,7 @@ Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
void Sema::ActOnPragmaWeakID(IdentifierInfo* Name, void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
SourceLocation PragmaLoc, SourceLocation PragmaLoc,
SourceLocation NameLoc) { SourceLocation NameLoc) {
Decl *PrevDecl = LookupName(TUScope, Name, LookupOrdinaryName); Decl *PrevDecl = LookupSingleName(TUScope, Name, LookupOrdinaryName);
if (PrevDecl) { if (PrevDecl) {
PrevDecl->addAttr(::new (Context) WeakAttr()); PrevDecl->addAttr(::new (Context) WeakAttr());
@ -5601,7 +5545,7 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
SourceLocation PragmaLoc, SourceLocation PragmaLoc,
SourceLocation NameLoc, SourceLocation NameLoc,
SourceLocation AliasNameLoc) { SourceLocation AliasNameLoc) {
Decl *PrevDecl = LookupName(TUScope, AliasName, LookupOrdinaryName); Decl *PrevDecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName);
WeakInfo W = WeakInfo(Name, NameLoc); WeakInfo W = WeakInfo(Name, NameLoc);
if (PrevDecl) { if (PrevDecl) {

View File

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

View File

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

View File

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

View File

@ -695,8 +695,8 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
isAddressOfOperand)); isAddressOfOperand));
} }
LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName, LookupResult Lookup;
false, true, Loc); LookupParsedName(Lookup, S, SS, Name, LookupOrdinaryName, false, true, Loc);
if (Lookup.isAmbiguous()) { if (Lookup.isAmbiguous()) {
DiagnoseAmbiguousLookup(Lookup, Name, Loc, DiagnoseAmbiguousLookup(Lookup, Name, Loc,
@ -705,7 +705,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
return ExprError(); 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 // If this reference is in an Objective-C method, then ivar lookup happens as
// well. // 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. // The record definition is complete, now make sure the member is valid.
LookupResult Result LookupResult Result;
= LookupQualifiedName(DC, MemberName, LookupMemberName, false); LookupQualifiedName(Result, DC, MemberName, LookupMemberName, false);
if (!Result) if (Result.empty())
return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated) return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated)
<< MemberName << BaseExpr->getSourceRange()); << MemberName << BaseExpr->getSourceRange());
if (Result.isAmbiguous()) { if (Result.isAmbiguous()) {
@ -2193,13 +2193,14 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
return ExprError(); return ExprError();
} }
NamedDecl *MemberDecl = Result.getAsSingleDecl(Context);
if (SS && SS->isSet()) { if (SS && SS->isSet()) {
TypeDecl* TyD = cast<TypeDecl>(MemberDecl->getDeclContext());
QualType BaseTypeCanon QualType BaseTypeCanon
= Context.getCanonicalType(BaseType).getUnqualifiedType(); = Context.getCanonicalType(BaseType).getUnqualifiedType();
QualType MemberTypeCanon QualType MemberTypeCanon
= Context.getCanonicalType( = Context.getCanonicalType(Context.getTypeDeclType(TyD));
Context.getTypeDeclType(
dyn_cast<TypeDecl>(Result.getAsDecl()->getDeclContext())));
if (BaseTypeCanon != MemberTypeCanon && if (BaseTypeCanon != MemberTypeCanon &&
!IsDerivedFrom(BaseTypeCanon, MemberTypeCanon)) !IsDerivedFrom(BaseTypeCanon, MemberTypeCanon))
@ -2208,8 +2209,6 @@ Sema::BuildMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
<< MemberTypeCanon << BaseTypeCanon); << MemberTypeCanon << BaseTypeCanon);
} }
NamedDecl *MemberDecl = Result;
// If the decl being referenced had an error, return an error for this // If the decl being referenced had an error, return an error for this
// sub-expr without emitting another error, in order to avoid cascading // sub-expr without emitting another error, in order to avoid cascading
// error cases. // error cases.
@ -5685,10 +5684,11 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
} }
} }
LookupResult R;
LookupQualifiedName(R, RD, OC.U.IdentInfo, LookupMemberName);
FieldDecl *MemberDecl FieldDecl *MemberDecl
= dyn_cast_or_null<FieldDecl>(LookupQualifiedName(RD, OC.U.IdentInfo, = dyn_cast_or_null<FieldDecl>(R.getAsSingleDecl(Context));
LookupMemberName)
.getAsDecl());
// FIXME: Leaks Res // FIXME: Leaks Res
if (!MemberDecl) if (!MemberDecl)
return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member_deprecated) 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(); TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr();
IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
Decl *TypeInfoDecl = LookupQualifiedName(StdNamespace, TypeInfoII, LookupResult R;
LookupTagName); LookupQualifiedName(R, StdNamespace, TypeInfoII, LookupTagName);
Decl *TypeInfoDecl = R.getAsSingleDecl(Context);
RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl); RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
if (!TypeInfoRecordDecl) if (!TypeInfoRecordDecl)
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); 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, DeclarationName Name, Expr** Args,
unsigned NumArgs, DeclContext *Ctx, unsigned NumArgs, DeclContext *Ctx,
bool AllowMissing, FunctionDecl *&Operator) { bool AllowMissing, FunctionDecl *&Operator) {
LookupResult R = LookupQualifiedName(Ctx, Name, LookupOrdinaryName); LookupResult R;
if (!R) { LookupQualifiedName(R, Ctx, Name, LookupOrdinaryName);
if (R.empty()) {
if (AllowMissing) if (AllowMissing)
return false; return false;
return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
<< Name << Range; << Name << Range;
} }
// FIXME: handle ambiguity
OverloadCandidateSet Candidates; OverloadCandidateSet Candidates;
for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end();
Alloc != AllocEnd; ++Alloc) { Alloc != AllocEnd; ++Alloc) {
@ -868,8 +872,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
= cast<CXXRecordDecl>(Pointee->getAs<RecordType>()->getDecl()); = cast<CXXRecordDecl>(Pointee->getAs<RecordType>()->getDecl());
// Try to find operator delete/operator delete[] in class scope. // Try to find operator delete/operator delete[] in class scope.
LookupResult Found = LookupQualifiedName(Record, DeleteName, LookupResult Found;
LookupOrdinaryName); LookupQualifiedName(Found, Record, DeleteName, LookupOrdinaryName);
// FIXME: Diagnose ambiguity properly // FIXME: Diagnose ambiguity properly
assert(!Found.isAmbiguous() && "Ambiguous delete/delete[] not handled"); assert(!Found.isAmbiguous() && "Ambiguous delete/delete[] not handled");
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end(); 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); Ty = Context.getObjCObjectPointerType(Ty);
} else { } else {
IdentifierInfo *NSIdent = &Context.Idents.get("NSString"); 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)) { if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
Context.setObjCConstantStringInterface(StrIF); Context.setObjCConstantStringInterface(StrIF);
Ty = Context.getObjCConstantStringInterface(); Ty = Context.getObjCConstantStringInterface();
@ -387,7 +387,8 @@ Sema::ExprResult Sema::ActOnClassMessage(
} else { } else {
// 'super' has been used outside a method context. If a variable named // 'super' has been used outside a method context. If a variable named
// 'super' has been declared, redirect. If not, produce a diagnostic. // '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); ValueDecl *VD = dyn_cast_or_null<ValueDecl>(SuperDecl);
if (VD) { if (VD) {
ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(), 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 necessary, the following lookup could move to getObjCInterfaceDecl().
if (!ClassDecl) { if (!ClassDecl) {
NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName); NamedDecl *IDecl
= LookupSingleName(TUScope, receiverName, LookupOrdinaryName);
if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) { if (TypedefDecl *OCTD = dyn_cast_or_null<TypedefDecl>(IDecl)) {
const ObjCInterfaceType *OCIT; const ObjCInterfaceType *OCIT;
OCIT = OCTD->getUnderlyingType()->getAs<ObjCInterfaceType>(); 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))) if (RequireCompleteType(OpLoc, T1, PartialDiagnostic(0)))
return; return;
LookupResult Operators = LookupQualifiedName(T1Rec->getDecl(), OpName, LookupResult Operators;
LookupOrdinaryName, false); LookupQualifiedName(Operators, T1Rec->getDecl(), OpName,
LookupOrdinaryName, false);
for (LookupResult::iterator Oper = Operators.begin(), for (LookupResult::iterator Oper = Operators.begin(),
OperEnd = Operators.end(); OperEnd = Operators.end();
Oper != OperEnd; Oper != OperEnd;
@ -5070,8 +5071,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
OverloadCandidateSet CandidateSet; OverloadCandidateSet CandidateSet;
const RecordType *BaseRecord = Base->getType()->getAs<RecordType>(); const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
LookupResult R = LookupQualifiedName(BaseRecord->getDecl(), OpName, LookupResult R;
LookupOrdinaryName); LookupQualifiedName(R, BaseRecord->getDecl(), OpName, LookupOrdinaryName);
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) Oper != OperEnd; ++Oper)

View File

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

View File

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

View File

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