diff options
author | John McCall <rjmccall@apple.com> | 2009-10-09 21:13:30 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-10-09 21:13:30 +0000 |
commit | f36e02d4aff98bf2e52e342e0038d4172fbb5e64 (patch) | |
tree | de0e84cc5c69c3749a01794221565dcbe5d22614 | |
parent | d7e5bdb23c6ba2786cf94788c9af555e2c1276ce (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.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 283 | ||||
-rw-r--r-- | lib/Sema/SemaAttr.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 43 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 152 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 43 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 28 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 771 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 41 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 | ||||
-rw-r--r-- | test/SemaCXX/class-names.cpp | 4 |
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 |