aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-10-09 21:13:30 +0000
committerJohn McCall <rjmccall@apple.com>2009-10-09 21:13:30 +0000
commitf36e02d4aff98bf2e52e342e0038d4172fbb5e64 (patch)
treede0e84cc5c69c3749a01794221565dcbe5d22614
parentd7e5bdb23c6ba2786cf94788c9af555e2c1276ce (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83674 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/Decl.cpp3
-rw-r--r--lib/Sema/Sema.h283
-rw-r--r--lib/Sema/SemaAttr.cpp9
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp43
-rw-r--r--lib/Sema/SemaDecl.cpp152
-rw-r--r--lib/Sema/SemaDeclAttr.cpp5
-rw-r--r--lib/Sema/SemaDeclCXX.cpp43
-rw-r--r--lib/Sema/SemaDeclObjC.cpp18
-rw-r--r--lib/Sema/SemaExpr.cpp28
-rw-r--r--lib/Sema/SemaExprCXX.cpp16
-rw-r--r--lib/Sema/SemaExprObjC.cpp8
-rw-r--r--lib/Sema/SemaLookup.cpp771
-rw-r--r--lib/Sema/SemaOverload.cpp9
-rw-r--r--lib/Sema/SemaTemplate.cpp41
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--test/SemaCXX/class-names.cpp4
16 files changed, 527 insertions, 911 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5584e4c3da..86c5719bb2 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -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.
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 9f6db69740..d319969cce 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -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,
- static LookupResult CreateLookupResult(ASTContext &Context, NamedDecl *D);
+ FirstAmbiguous = AmbiguousBaseSubobjectTypes
+ };
- static LookupResult CreateLookupResult(ASTContext &Context,
- IdentifierResolver::iterator F,
- IdentifierResolver::iterator L);
+ typedef llvm::SmallVector<NamedDecl*, 4> DeclsTy;
+ typedef DeclsTy::const_iterator iterator;
- static LookupResult CreateLookupResult(ASTContext &Context,
- DeclContext::lookup_iterator F,
- DeclContext::lookup_iterator L);
+ LookupResult()
+ : Kind(NotFound),
+ Paths(0)
+ {}
+ ~LookupResult() {
+ if (Paths) deletePaths(Paths);
+ }
- 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;
+ bool isAmbiguous() const {
+ return getKind() >= FirstAmbiguous;
}
- 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 {
+ sanity();
+ return Kind;
}
- LookupKind getKind() const;
+ iterator begin() const { return Decls.begin(); }
+ iterator end() const { return Decls.end(); }
- /// @brief Determine whether name look found something.
- operator bool() const { return getKind() != NotFound; }
+ /// \brief Return true if no decls were found
+ bool empty() const { return Decls.empty(); }
- /// @brief Determines whether the lookup resulted in an ambiguity.
- bool isAmbiguous() const {
- return StoredKind == AmbiguousLookupStoresBasePaths ||
- StoredKind == AmbiguousLookupStoresDecls;
+ /// \brief Return the base paths structure that's associated with
+ /// these results, or null if none is.
+ CXXBasePaths *getBasePaths() const {
+ return Paths;
}
- /// @brief Allows conversion of a lookup result into a
- /// declaration, with the same behavior as getAsDecl.
- operator NamedDecl*() const { return getAsDecl(); }
-
- NamedDecl* getAsDecl() const;
-
- CXXBasePaths *getBasePaths() const;
+ /// \brief Add a declaration to these results.
+ void addDecl(NamedDecl *D) {
+ Decls.push_back(D->getUnderlyingDecl());
+ Kind = Found;
+ }
- /// \brief Iterate over the results of name lookup.
+ /// \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;
-
- /// 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;
-
- public:
- typedef NamedDecl * value_type;
- typedef NamedDecl * reference;
- typedef NamedDecl * pointer;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- iterator() : Result(0), Current(0) { }
-
- iterator(LookupResult *Res, uintptr_t Cur) : Result(Res), Current(Cur) { }
+ /// This should be called in any environment where lookup might
+ /// generate multiple lookup results.
+ void resolveKind();
- reference operator*() const;
+ /// \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;
- pointer operator->() const { return **this; }
+ /// \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 &operator++();
+ /// \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 operator++(int) {
- iterator tmp(*this);
- ++(*this);
- return tmp;
- }
+ /// \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);
+
+ /// \brief Clears out any current state.
+ void clear() {
+ Kind = NotFound;
+ Decls.clear();
+ if (Paths) deletePaths(Paths);
+ Paths = NULL;
+ }
- friend inline bool operator==(iterator const& x, iterator const& y) {
- return x.Current == y.Current;
- }
+ void print(llvm::raw_ostream &);
- friend inline bool operator!=(iterator const& x, iterator const& y) {
- return x.Current != y.Current;
- }
- };
- friend class iterator;
+ private:
+ void addDeclsFromBasePaths(const CXXBasePaths &P);
+
+ // 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));
+ }
- iterator begin();
- iterator end();
+ static void deletePaths(CXXBasePaths *);
- /// \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);
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 702e120f9c..0a5335a2be 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -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)
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 8f536da777..911cf67770 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -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)
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c2a83cdc6f..7982387281 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index a23da41086..23c83175eb 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1104,8 +1104,9 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// Look up the function
- NamedDecl *CleanupDec