Index: test/SemaCXX/class-names.cpp =================================================================== --- test/SemaCXX/class-names.cpp (revision 83513) +++ test/SemaCXX/class-names.cpp (working copy) @@ -5,7 +5,7 @@ C c; void D(int); -class D {}; // expected-note {{previous use is here}} +class D {}; void foo() { @@ -13,7 +13,7 @@ void foo() class D d; } -class D; +class D; // expected-note {{previous use is here}} enum D; // expected-error {{use of 'D' with tag type that does not match previous declaration}} Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp (revision 83513) +++ lib/Sema/SemaDeclCXX.cpp (working copy) @@ -2490,8 +2490,8 @@ Sema::DeclPtrTy Sema::ActOnStartNamespac // original-namespace-definition is the name of the namespace. Subsequently // in that declarative region, it is treated as an original-namespace-name. - NamedDecl *PrevDecl = LookupName(DeclRegionScope, II, LookupOrdinaryName, - true); + NamedDecl *PrevDecl + = LookupSingleName(DeclRegionScope, II, LookupOrdinaryName, true); if (NamespaceDecl *OrigNS = dyn_cast_or_null(PrevDecl)) { // This is an extended namespace definition. @@ -2599,13 +2599,14 @@ Sema::DeclPtrTy Sema::ActOnUsingDirectiv UsingDirectiveDecl *UDir = 0; // Lookup namespace name. - LookupResult R = LookupParsedName(S, &SS, NamespcName, - LookupNamespaceName, false); + LookupResult R; + LookupParsedName(R, S, &SS, NamespcName, LookupNamespaceName, false); if (R.isAmbiguous()) { DiagnoseAmbiguousLookup(R, NamespcName, IdentLoc); return DeclPtrTy(); } - if (NamedDecl *NS = R) { + if (!R.empty()) { + NamedDecl *NS = R.getFoundDecl(); assert(isa(NS) && "expected namespace decl"); // C++ [namespace.udir]p1: // A using-directive specifies that the names in the nominated @@ -2746,15 +2747,16 @@ NamedDecl *Sema::BuildUsingDeclaration(S // Lookup target name. - LookupResult R = LookupQualifiedName(LookupContext, - Name, LookupOrdinaryName); + LookupResult R; + LookupQualifiedName(R, LookupContext, Name, LookupOrdinaryName); - if (!R) { + if (R.empty()) { DiagnoseMissingMember(IdentLoc, Name, NNS, SS.getRange()); return 0; } - NamedDecl *ND = R.getAsDecl(); + // FIXME: handle ambiguity? + NamedDecl *ND = R.getAsSingleDecl(Context); if (IsTypeName && !isa(ND)) { Diag(IdentLoc, diag::err_using_typename_non_type); @@ -2790,14 +2792,17 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAlia IdentifierInfo *Ident) { // Lookup the namespace name. - LookupResult R = LookupParsedName(S, &SS, Ident, LookupNamespaceName, false); + LookupResult R; + LookupParsedName(R, S, &SS, Ident, LookupNamespaceName, false); // Check if we have a previous declaration with the same name. - if (NamedDecl *PrevDecl = LookupName(S, Alias, LookupOrdinaryName, true)) { + if (NamedDecl *PrevDecl + = LookupSingleName(S, Alias, LookupOrdinaryName, true)) { if (NamespaceAliasDecl *AD = dyn_cast(PrevDecl)) { // We already have an alias with the same name that points to the same // namespace, so don't create a new one. - if (!R.isAmbiguous() && AD->getNamespace() == getNamespaceDecl(R)) + if (!R.isAmbiguous() && !R.empty() && + AD->getNamespace() == getNamespaceDecl(R.getFoundDecl())) return DeclPtrTy(); } @@ -2813,7 +2818,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAlia return DeclPtrTy(); } - if (!R) { + if (R.empty()) { Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange(); return DeclPtrTy(); } @@ -2822,7 +2827,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAlia NamespaceAliasDecl::Create(Context, CurContext, NamespaceLoc, AliasLoc, Alias, SS.getRange(), (NestedNameSpecifier *)SS.getScopeRep(), - IdentLoc, R); + IdentLoc, R.getFoundDecl()); CurContext->addDecl(AliasDecl); return DeclPtrTy::make(AliasDecl); @@ -4150,7 +4155,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDecl bool Invalid = D.isInvalidType(); IdentifierInfo *II = D.getIdentifier(); - if (NamedDecl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) { + if (NamedDecl *PrevDecl = LookupSingleName(S, II, LookupOrdinaryName)) { // The scope should be freshly made just for us. There is just no way // it contains any previous declaration. assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl))); @@ -4397,7 +4402,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S, // FIXME: handle dependent contexts if (!DC) return DeclPtrTy(); - PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true); + LookupResult R; + LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true); + PrevDecl = R.getAsSingleDecl(Context); // If searching in that context implicitly found a declaration in // a different context, treat it like it wasn't found at all. @@ -4430,7 +4437,9 @@ Sema::ActOnFriendFunctionDecl(Scope *S, while (DC->isRecord()) DC = DC->getParent(); - PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName, true); + LookupResult R; + LookupQualifiedName(R, DC, Name, LookupOrdinaryName, true); + PrevDecl = R.getAsSingleDecl(Context); // TODO: decide what we think about using declarations. if (PrevDecl) Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp (revision 83513) +++ lib/Sema/SemaExprCXX.cpp (working copy) @@ -69,8 +69,9 @@ Sema::ActOnCXXTypeid(SourceLocation OpLo TyOrExpr = GetTypeFromParser(TyOrExpr).getAsOpaquePtr(); IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info"); - Decl *TypeInfoDecl = LookupQualifiedName(StdNamespace, TypeInfoII, - LookupTagName); + LookupResult R; + LookupQualifiedName(R, StdNamespace, TypeInfoII, LookupTagName); + Decl *TypeInfoDecl = R.getAsSingleDecl(Context); RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null(TypeInfoDecl); if (!TypeInfoRecordDecl) return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid)); @@ -589,14 +590,17 @@ bool Sema::FindAllocationOverload(Source DeclarationName Name, Expr** Args, unsigned NumArgs, DeclContext *Ctx, bool AllowMissing, FunctionDecl *&Operator) { - LookupResult R = LookupQualifiedName(Ctx, Name, LookupOrdinaryName); - if (!R) { + LookupResult R; + LookupQualifiedName(R, Ctx, Name, LookupOrdinaryName); + if (R.empty()) { if (AllowMissing) return false; return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) << Name << Range; } + // FIXME: handle ambiguity + OverloadCandidateSet Candidates; for (LookupResult::iterator Alloc = R.begin(), AllocEnd = R.end(); Alloc != AllocEnd; ++Alloc) { @@ -868,8 +872,8 @@ Sema::ActOnCXXDelete(SourceLocation Star = cast(Pointee->getAs()->getDecl()); // Try to find operator delete/operator delete[] in class scope. - LookupResult Found = LookupQualifiedName(Record, DeleteName, - LookupOrdinaryName); + LookupResult Found; + LookupQualifiedName(Found, Record, DeleteName, LookupOrdinaryName); // FIXME: Diagnose ambiguity properly assert(!Found.isAmbiguous() && "Ambiguous delete/delete[] not handled"); for (LookupResult::iterator F = Found.begin(), FEnd = Found.end(); Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp (revision 83513) +++ lib/Sema/SemaDeclAttr.cpp (working copy) @@ -1104,8 +1104,9 @@ static void HandleCleanupAttr(Decl *d, c } // Look up the function - NamedDecl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), - Sema::LookupOrdinaryName); + NamedDecl *CleanupDecl + = S.LookupSingleName(S.TUScope, Attr.getParameterName(), + Sema::LookupOrdinaryName); if (!CleanupDecl) { S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << Attr.getParameterName(); Index: lib/Sema/SemaDeclObjC.cpp =================================================================== --- lib/Sema/SemaDeclObjC.cpp (revision 83513) +++ lib/Sema/SemaDeclObjC.cpp (working copy) @@ -84,7 +84,7 @@ ActOnStartClassInterface(SourceLocation assert(ClassName && "Missing class identifier"); // Check for another declaration kind with the same name. - NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName); + NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl); @@ -124,7 +124,7 @@ ActOnStartClassInterface(SourceLocation if (SuperName) { // Check if a different kind of symbol declared in this scope. - PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName); + PrevDecl = LookupSingleName(TUScope, SuperName, LookupOrdinaryName); if (PrevDecl == IDecl) { Diag(SuperLoc, diag::err_recursive_superclass) << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); @@ -195,7 +195,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityA IdentifierInfo *ClassName, SourceLocation ClassLocation) { // Look for previous declaration of alias name - NamedDecl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName); + NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, LookupOrdinaryName); if (ADecl) { if (isa(ADecl)) Diag(AliasLocation, diag::warn_previous_alias_decl); @@ -205,13 +205,13 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityA return DeclPtrTy(); } // Check for class declaration - NamedDecl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName); + NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); if (const TypedefDecl *TDecl = dyn_cast_or_null(CDeclU)) { QualType T = TDecl->getUnderlyingType(); if (T->isObjCInterfaceType()) { if (NamedDecl *IDecl = T->getAs()->getDecl()) { ClassName = IDecl->getIdentifier(); - CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName); + CDeclU = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); } } } @@ -654,7 +654,8 @@ Sema::DeclPtrTy Sema::ActOnStartClassImp SourceLocation SuperClassLoc) { ObjCInterfaceDecl* IDecl = 0; // Check for another declaration kind with the same name. - NamedDecl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName); + NamedDecl *PrevDecl + = LookupSingleName(TUScope, ClassName, LookupOrdinaryName); if (PrevDecl && !isa(PrevDecl)) { Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName; Diag(PrevDecl->getLocation(), diag::note_previous_definition); @@ -671,7 +672,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImp ObjCInterfaceDecl* SDecl = 0; if (SuperClassname) { // Check if a different kind of symbol declared in this scope. - PrevDecl = LookupName(TUScope, SuperClassname, LookupOrdinaryName); + PrevDecl = LookupSingleName(TUScope, SuperClassname, LookupOrdinaryName); if (PrevDecl && !isa(PrevDecl)) { Diag(SuperClassLoc, diag::err_redefinition_different_kind) << SuperClassname; @@ -1121,7 +1122,8 @@ Sema::ActOnForwardClassDeclaration(Sourc for (unsigned i = 0; i != NumElts; ++i) { // Check for another declaration kind with the same name. - NamedDecl *PrevDecl = LookupName(TUScope, IdentList[i], LookupOrdinaryName); + NamedDecl *PrevDecl + = LookupSingleName(TUScope, IdentList[i], LookupOrdinaryName); if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl); Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp (revision 83513) +++ lib/Sema/SemaTemplateInstantiateDecl.cpp (working copy) @@ -656,8 +656,9 @@ TemplateDeclInstantiator::VisitCXXMethod NamedDecl *PrevDecl = 0; if (!FunctionTemplate || TemplateParams) { - PrevDecl = SemaRef.LookupQualifiedName(Owner, Name, - Sema::LookupOrdinaryName, true); + Sema::LookupResult R; + SemaRef.LookupQualifiedName(R, Owner, Name, Sema::LookupOrdinaryName, true); + PrevDecl = R.getAsSingleDecl(SemaRef.Context); // In C++, the previous declaration we find might be a tag type // (class or enum). In this case, the new declaration will hide the Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp (revision 83513) +++ lib/Sema/SemaDecl.cpp (working copy) @@ -85,8 +85,8 @@ Sema::TypeTy *Sema::getTypeName(Identifi 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(Identifi // 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(Identifi } case LookupResult::Found: - IIDecl = Result.getAsDecl(); + IIDecl = Result.getFoundDecl(); break; } @@ -179,9 +178,10 @@ Sema::TypeTy *Sema::getTypeName(Identifi /// 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(R.getAsDecl())) { + if (const TagDecl *TD = dyn_cast(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 * (isa(D) && cast(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(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 - // 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); + // 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); - return; - } - } - } else if ((isa(D) && - AllowOverloadingOfFunction(D, Context)) || - isa(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(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(*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); } @@ -444,7 +380,7 @@ void Sema::ActOnPopScope(SourceLocation 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(IDecl); } @@ -486,7 +422,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(VaDecl); Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef)); } @@ -1408,8 +1344,10 @@ bool Sema::InjectAnonymousStructOrUnionM 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(PrevDecl)) { // C++ [class.union]p2: // The names of the members of an anonymous union shall be @@ -1765,9 +1703,11 @@ Sema::HandleDeclarator(Scope *S, Declara 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); @@ -1783,7 +1723,9 @@ Sema::HandleDeclarator(Scope *S, Declara 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 @@ -2874,8 +2816,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, << cast(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(); @@ -3581,7 +3523,7 @@ Sema::ActOnParamDeclarator(Scope *S, Dec // 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); @@ -4187,9 +4129,9 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, DC = computeDeclContext(SS, true); SearchDC = DC; // Look-up name inside 'foo::'. - PrevDecl - = dyn_cast_or_null( - LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl()); + LookupResult R; + LookupQualifiedName(R, DC, Name, LookupTagName, true); + PrevDecl = dyn_cast_or_null(R.getAsSingleDecl(Context)); // A tag 'foo::bar' must already exist. if (PrevDecl == 0) { @@ -4204,7 +4146,8 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, // 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); @@ -4217,7 +4160,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, 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 @@ -4464,10 +4407,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(Lookup.getAsDecl()); + if (NamedDecl *Prev = Lookup.getAsSingleDecl(Context)) + PrevTypedef = dyn_cast(Prev); NamedDecl *PrevTypedefNamed = PrevTypedef; if (PrevTypedef && isDeclInScope(PrevTypedefNamed, SearchDC, S) && @@ -4678,7 +4622,7 @@ FieldDecl *Sema::HandleField(Scope *S, R 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. @@ -5059,7 +5003,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(PrevDecl)) { Diag(Loc, diag::err_duplicate_member) << II; @@ -5312,7 +5256,7 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant( // 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); @@ -5555,7 +5499,7 @@ Sema::DeclPtrTy Sema::ActOnFileScopeAsmD 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()); @@ -5571,7 +5515,7 @@ void Sema::ActOnPragmaWeakAlias(Identifi 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) { Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp (revision 83513) +++ lib/Sema/SemaTemplate.cpp (working copy) @@ -135,7 +135,7 @@ TemplateNameKind Sema::isTemplateName(Sc if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS)) return TNK_Non_template; - Found = LookupQualifiedName(LookupCtx, &II, LookupOrdinaryName); + LookupQualifiedName(Found, LookupCtx, &II, LookupOrdinaryName); if (ObjectTypePtr && Found.getKind() == LookupResult::NotFound) { // C++ [basic.lookup.classref]p1: @@ -150,7 +150,7 @@ TemplateNameKind Sema::isTemplateName(Sc // // FIXME: When we're instantiating a template, do we actually have to // look in the scope of the template? Seems fishy... - Found = LookupName(S, &II, LookupOrdinaryName); + LookupName(Found, S, &II, LookupOrdinaryName); ObjectTypeSearchedInScope = true; } } else if (isDependent) { @@ -158,14 +158,15 @@ TemplateNameKind Sema::isTemplateName(Sc return TNK_Non_template; } else { // Perform unqualified name lookup in the current scope. - Found = LookupName(S, &II, LookupOrdinaryName); + LookupName(Found, S, &II, LookupOrdinaryName); } // FIXME: Cope with ambiguous name-lookup results. assert(!Found.isAmbiguous() && "Cannot handle template name-lookup ambiguities"); - NamedDecl *Template = isAcceptableTemplateName(Context, Found); + NamedDecl *Template + = isAcceptableTemplateName(Context, Found.getAsSingleDecl(Context)); if (!Template) return TNK_Non_template; @@ -175,9 +176,11 @@ TemplateNameKind Sema::isTemplateName(Sc // template, the name is also looked up in the context of the entire // postfix-expression and [...] // - LookupResult FoundOuter = LookupName(S, &II, LookupOrdinaryName); + LookupResult FoundOuter; + LookupName(FoundOuter, S, &II, LookupOrdinaryName); // FIXME: Handle ambiguities in this lookup better - NamedDecl *OuterTemplate = isAcceptableTemplateName(Context, FoundOuter); + NamedDecl *OuterTemplate + = isAcceptableTemplateName(Context, FoundOuter.getAsSingleDecl(Context)); if (!OuterTemplate) { // - if the name is not found, the name found in the class of the @@ -284,7 +287,7 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter bool Invalid = false; if (ParamName) { - NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName); + NamedDecl *PrevDecl = LookupSingleName(S, ParamName, LookupTagName); if (PrevDecl && PrevDecl->isTemplateParameter()) Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc, PrevDecl); @@ -402,7 +405,7 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTempla IdentifierInfo *ParamName = D.getIdentifier(); if (ParamName) { - NamedDecl *PrevDecl = LookupName(S, ParamName, LookupTagName); + NamedDecl *PrevDecl = LookupSingleName(S, ParamName, LookupTagName); if (PrevDecl && PrevDecl->isTemplateParameter()) Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); @@ -577,11 +580,11 @@ Sema::CheckClassTemplate(Scope *S, unsig return true; } - Previous = LookupQualifiedName(SemanticContext, Name, LookupOrdinaryName, + LookupQualifiedName(Previous, SemanticContext, Name, LookupOrdinaryName, true); } else { SemanticContext = CurContext; - Previous = LookupName(S, Name, LookupOrdinaryName, true); + LookupName(Previous, S, Name, LookupOrdinaryName, true); } assert(!Previous.isAmbiguous() && "Ambiguity in class template redecl?"); @@ -3512,8 +3515,9 @@ Sema::DeclResult Sema::ActOnExplicitInst = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition : TSK_ExplicitInstantiationDeclaration; - LookupResult Previous = LookupParsedName(S, &D.getCXXScopeSpec(), - Name, LookupOrdinaryName); + LookupResult Previous; + LookupParsedName(Previous, S, &D.getCXXScopeSpec(), + Name, LookupOrdinaryName); if (!R->isFunctionType()) { // C++ [temp.explicit]p1: @@ -3525,14 +3529,15 @@ Sema::DeclResult Sema::ActOnExplicitInst D.getSourceRange()); } - VarDecl *Prev = dyn_cast_or_null(Previous.getAsDecl()); + VarDecl *Prev = dyn_cast_or_null( + Previous.getAsSingleDecl(Context)); if (!Prev || !Prev->isStaticDataMember()) { // We expect to see a data data member here. Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known) << Name; for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end(); P != PEnd; ++P) - Diag(P->getLocation(), diag::note_explicit_instantiation_here); + Diag((*P)->getLocation(), diag::note_explicit_instantiation_here); return true; } @@ -3759,8 +3764,8 @@ Sema::CheckTypenameType(NestedNameSpecif assert(Ctx && "No declaration context?"); DeclarationName Name(&II); - LookupResult Result = LookupQualifiedName(Ctx, Name, LookupOrdinaryName, - false); + LookupResult Result; + LookupQualifiedName(Result, Ctx, Name, LookupOrdinaryName, false); unsigned DiagID = 0; Decl *Referenced = 0; switch (Result.getKind()) { @@ -3772,7 +3777,7 @@ Sema::CheckTypenameType(NestedNameSpecif break; case LookupResult::Found: - if (TypeDecl *Type = dyn_cast(Result.getAsDecl())) { + if (TypeDecl *Type = dyn_cast(Result.getFoundDecl())) { // We found a type. Build a QualifiedNameType, since the // typename-specifier was just sugar. FIXME: Tell // QualifiedNameType that it has a "typename" prefix. @@ -3780,7 +3785,7 @@ Sema::CheckTypenameType(NestedNameSpecif } DiagID = diag::err_typename_nested_not_type; - Referenced = Result.getAsDecl(); + Referenced = Result.getFoundDecl(); break; case LookupResult::FoundOverloaded: Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp (revision 83513) +++ lib/Sema/SemaOverload.cpp (working copy) @@ -2762,8 +2762,9 @@ void Sema::AddMemberOperatorCandidates(O if (RequireCompleteType(OpLoc, T1, PartialDiagnostic(0))) return; - LookupResult Operators = LookupQualifiedName(T1Rec->getDecl(), OpName, - LookupOrdinaryName, false); + LookupResult Operators; + LookupQualifiedName(Operators, T1Rec->getDecl(), OpName, + LookupOrdinaryName, false); for (LookupResult::iterator Oper = Operators.begin(), OperEnd = Operators.end(); Oper != OperEnd; @@ -5075,8 +5076,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, OverloadCandidateSet CandidateSet; const RecordType *BaseRecord = Base->getType()->getAs(); - LookupResult R = LookupQualifiedName(BaseRecord->getDecl(), OpName, - LookupOrdinaryName); + LookupResult R; + LookupQualifiedName(R, BaseRecord->getDecl(), OpName, LookupOrdinaryName); for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) Index: lib/Sema/Sema.h =================================================================== --- lib/Sema/Sema.h (revision 83513) +++ lib/Sema/Sema.h (working copy) @@ -1043,63 +1043,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, @@ -1154,122 +1104,119 @@ public: /// } /// } /// @endcode - AmbiguousReference + AmbiguousReference, + + FirstAmbiguous = AmbiguousBaseSubobjectTypes }; - static LookupResult CreateLookupResult(ASTContext &Context, NamedDecl *D); + typedef llvm::SmallVector DeclsTy; + typedef DeclsTy::const_iterator iterator; - static LookupResult CreateLookupResult(ASTContext &Context, - IdentifierResolver::iterator F, - IdentifierResolver::iterator L); - - static LookupResult CreateLookupResult(ASTContext &Context, - DeclContext::lookup_iterator F, - DeclContext::lookup_iterator L); - - static LookupResult CreateLookupResult(ASTContext &Context, - CXXBasePaths *Paths, - bool DifferentSubobjectTypes) { - LookupResult Result; - Result.StoredKind = AmbiguousLookupStoresBasePaths; - Result.First = reinterpret_cast(Paths); - Result.Last = DifferentSubobjectTypes? 1 : 0; - Result.Context = &Context; - return Result; + LookupResult() + : Kind(NotFound), + Paths(0) + {} + ~LookupResult() { + if (Paths) deletePaths(Paths); } - template - 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(Array); - Result.Last = reinterpret_cast(Array + Len); - Result.Context = &Context; - return Result; + bool isAmbiguous() const { + return getKind() >= FirstAmbiguous; + } + + 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(); } + /// \brief Add a declaration to these results. + void addDecl(NamedDecl *D) { + Decls.push_back(D->getUnderlyingDecl()); + Kind = Found; + } - NamedDecl* getAsDecl() const; + /// \brief Resolves the kind of the lookup, possibly hiding decls. + /// + /// This should be called in any environment where lookup might + /// generate multiple lookup results. + void resolveKind(); - CXXBasePaths *getBasePaths() 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; - /// \brief Iterate over the results of name lookup. + /// \brief Fetch the unique decl found by this lookup. Asserts + /// that one was found. /// - /// 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) { } - - reference operator*() const; - - pointer operator->() const { return **this; } - - iterator &operator++(); - - iterator operator++(int) { - iterator tmp(*this); - ++(*this); - return tmp; - } + /// 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(); + } - friend inline bool operator==(iterator const& x, iterator const& y) { - return x.Current == y.Current; - } + /// \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); - friend inline bool operator!=(iterator const& x, iterator const& y) { - return x.Current != y.Current; - } - }; - friend class iterator; + /// \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; + } - iterator begin(); - iterator end(); + void print(llvm::raw_ostream &); - /// \brief Free the memory associated with this lookup. - void Destroy(); + 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)); + } + + static void deletePaths(CXXBasePaths *); + + LookupKind Kind; + DeclsTy Decls; + CXXBasePaths *Paths; }; private: typedef llvm::SmallVector LookupResultsVecTy; - std::pair 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. @@ -1301,24 +1248,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); Index: lib/Sema/SemaCXXScopeSpec.cpp =================================================================== --- lib/Sema/SemaCXXScopeSpec.cpp (revision 83513) +++ lib/Sema/SemaCXXScopeSpec.cpp (working copy) @@ -302,11 +302,11 @@ NamedDecl *Sema::FindFirstQualifierInSco 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::BuildCXXNestedNa 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::BuildCXXNestedNa // 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::BuildCXXNestedNa 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::BuildCXXNestedNa // 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(OuterDecl) || !isa(SD) || @@ -461,8 +461,11 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNa // 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) Index: lib/Sema/SemaLookup.cpp =================================================================== --- lib/Sema/SemaLookup.cpp (revision 83513) +++ lib/Sema/SemaLookup.cpp (working copy) @@ -35,7 +35,6 @@ using namespace clang; typedef llvm::SmallVector UsingDirectivesTy; typedef llvm::DenseSet NamespaceSet; -typedef llvm::SmallVector LookupResultsTy; /// UsingDirAncestorCompare - Implements strict weak ordering of /// UsingDirectives. It orders them by address of its common ancestor. @@ -107,178 +106,6 @@ static void AddScopeUsingDirectives(ASTC } } -/// MaybeConstructOverloadSet - Name lookup has determined that the -/// elements in [I, IEnd) have the name that we are looking for, and -/// *I is a match for the namespace. This routine returns an -/// appropriate Decl for name lookup, which may either be *I or an -/// OverloadedFunctionDecl that represents the overloaded functions in -/// [I, IEnd). -/// -/// The existance of this routine is temporary; users of LookupResult -/// should be able to handle multiple results, to deal with cases of -/// ambiguity and overloaded functions without needing to create a -/// Decl node. -template -static NamedDecl * -MaybeConstructOverloadSet(ASTContext &Context, - DeclIterator I, DeclIterator IEnd) { - assert(I != IEnd && "Iterator range cannot be empty"); - assert(!isa(*I) && - "Cannot have an overloaded function"); - - if ((*I)->isFunctionOrFunctionTemplate()) { - // If we found a function, there might be more functions. If - // so, collect them into an overload set. - DeclIterator Last = I; - OverloadedFunctionDecl *Ovl = 0; - for (++Last; - Last != IEnd && (*Last)->isFunctionOrFunctionTemplate(); - ++Last) { - if (!Ovl) { - // FIXME: We leak this overload set. Eventually, we want to stop - // building the declarations for these overload sets, so there will be - // nothing to leak. - Ovl = OverloadedFunctionDecl::Create(Context, (*I)->getDeclContext(), - (*I)->getDeclName()); - NamedDecl *ND = (*I)->getUnderlyingDecl(); - if (isa(ND)) - Ovl->addOverload(cast(ND)); - else - Ovl->addOverload(cast(ND)); - } - - NamedDecl *ND = (*Last)->getUnderlyingDecl(); - if (isa(ND)) - Ovl->addOverload(cast(ND)); - else - Ovl->addOverload(cast(ND)); - } - - // If we had more than one function, we built an overload - // set. Return it. - if (Ovl) - return Ovl; - } - - return *I; -} - -/// Merges together multiple LookupResults dealing with duplicated Decl's. -static Sema::LookupResult -MergeLookupResults(ASTContext &Context, LookupResultsTy &Results) { - typedef Sema::LookupResult LResult; - typedef llvm::SmallPtrSet DeclsSetTy; - - // Remove duplicated Decl pointing at same Decl, by storing them in - // associative collection. This might be case for code like: - // - // namespace A { int i; } - // namespace B { using namespace A; } - // namespace C { using namespace A; } - // - // void foo() { - // using namespace B; - // using namespace C; - // ++i; // finds A::i, from both namespace B and C at global scope - // } - // - // C++ [namespace.qual].p3: - // The same declaration found more than once is not an ambiguity - // (because it is still a unique declaration). - DeclsSetTy FoundDecls; - - // Counter of tag names, and functions for resolving ambiguity - // and name hiding. - std::size_t TagNames = 0, Functions = 0, OrdinaryNonFunc = 0; - - LookupResultsTy::iterator I = Results.begin(), End = Results.end(); - - // No name lookup results, return early. - if (I == End) return LResult::CreateLookupResult(Context, 0); - - // Keep track of the tag declaration we found. We only use this if - // we find a single tag declaration. - TagDecl *TagFound = 0; - - for (; I != End; ++I) { - switch (I->getKind()) { - case LResult::NotFound: - assert(false && - "Should be always successful name lookup result here."); - break; - - case LResult::AmbiguousReference: - case LResult::AmbiguousBaseSubobjectTypes: - case LResult::AmbiguousBaseSubobjects: - assert(false && "Shouldn't get ambiguous lookup here."); - break; - - case LResult::Found: { - NamedDecl *ND = I->getAsDecl()->getUnderlyingDecl(); - - if (TagDecl *TD = dyn_cast(ND)) { - TagFound = TD->getCanonicalDecl(); - TagNames += FoundDecls.insert(TagFound)? 1 : 0; - } else if (ND->isFunctionOrFunctionTemplate()) - Functions += FoundDecls.insert(ND)? 1 : 0; - else - FoundDecls.insert(ND); - break; - } - - case LResult::FoundOverloaded: - for (LResult::iterator FI = I->begin(), FEnd = I->end(); FI != FEnd; ++FI) - Functions += FoundDecls.insert(*FI)? 1 : 0; - break; - } - } - OrdinaryNonFunc = FoundDecls.size() - TagNames - Functions; - bool Ambiguous = false, NameHidesTags = false; - - if (FoundDecls.size() == 1) { - // 1) Exactly one result. - } else if (TagNames > 1) { - // 2) Multiple tag names (even though they may be hidden by an - // object name). - Ambiguous = true; - } else if (FoundDecls.size() - TagNames == 1) { - // 3) Ordinary name hides (optional) tag. - NameHidesTags = TagFound; - } else if (Functions) { - // C++ [basic.lookup].p1: - // ... Name lookup may associate more than one declaration with - // a name if it finds the name to be a function name; the declarations - // are said to form a set of overloaded functions (13.1). - // Overload resolution (13.3) takes place after name lookup has succeeded. - // - if (!OrdinaryNonFunc) { - // 4) Functions hide tag names. - NameHidesTags = TagFound; - } else { - // 5) Functions + ordinary names. - Ambiguous = true; - } - } else { - // 6) Multiple non-tag names - Ambiguous = true; - } - - if (Ambiguous) - return LResult::CreateLookupResult(Context, - FoundDecls.begin(), FoundDecls.size()); - if (NameHidesTags) { - // There's only one tag, TagFound. Remove it. - assert(TagFound && FoundDecls.count(TagFound) && "No tag name found?"); - FoundDecls.erase(TagFound); - } - - // Return successful name lookup result. - return LResult::CreateLookupResult(Context, - MaybeConstructOverloadSet(Context, - FoundDecls.begin(), - FoundDecls.end())); -} - // Retrieve the set of identifier namespaces that correspond to a // specific kind of name lookup. inline unsigned @@ -324,97 +151,78 @@ getIdentifierNamespacesFromLookupNameKin return IDNS; } -Sema::LookupResult -Sema::LookupResult::CreateLookupResult(ASTContext &Context, NamedDecl *D) { - if (D) - D = D->getUnderlyingDecl(); - - LookupResult Result; - Result.StoredKind = (D && isa(D))? - OverloadedDeclSingleDecl : SingleDecl; - Result.First = reinterpret_cast(D); - Result.Last = 0; - Result.Context = &Context; - return Result; -} - -/// @brief Moves the name-lookup results from Other to this LookupResult. -Sema::LookupResult -Sema::LookupResult::CreateLookupResult(ASTContext &Context, - IdentifierResolver::iterator F, - IdentifierResolver::iterator L) { - LookupResult Result; - Result.Context = &Context; - - if (F != L && (*F)->isFunctionOrFunctionTemplate()) { - IdentifierResolver::iterator Next = F; - ++Next; - if (Next != L && (*Next)->isFunctionOrFunctionTemplate()) { - Result.StoredKind = OverloadedDeclFromIdResolver; - Result.First = F.getAsOpaqueValue(); - Result.Last = L.getAsOpaqueValue(); - return Result; - } - } +// Necessary because CXXBasePaths is not complete in Sema.h +void Sema::LookupResult::deletePaths(CXXBasePaths *Paths) { + delete Paths; +} - NamedDecl *D = *F; - if (D) - D = D->getUnderlyingDecl(); - - Result.StoredKind = SingleDecl; - Result.First = reinterpret_cast(D); - Result.Last = 0; - return Result; -} - -Sema::LookupResult -Sema::LookupResult::CreateLookupResult(ASTContext &Context, - DeclContext::lookup_iterator F, - DeclContext::lookup_iterator L) { - LookupResult Result; - Result.Context = &Context; - - if (F != L && (*F)->isFunctionOrFunctionTemplate()) { - DeclContext::lookup_iterator Next = F; - ++Next; - if (Next != L && (*Next)->isFunctionOrFunctionTemplate()) { - Result.StoredKind = OverloadedDeclFromDeclContext; - Result.First = reinterpret_cast(F); - Result.Last = reinterpret_cast(L); - return Result; - } - } +void Sema::LookupResult::resolveKind() { + unsigned N = Decls.size(); - NamedDecl *D = *F; - if (D) - D = D->getUnderlyingDecl(); + // Fast case: no possible ambiguity. + if (N <= 1) return; - Result.StoredKind = SingleDecl; - Result.First = reinterpret_cast(D); - Result.Last = 0; - return Result; -} + llvm::SmallPtrSet Unique; + + bool Ambiguous = false; + bool HasTag = false, HasFunction = false, HasNonFunction = false; -/// @brief Determine the result of name lookup. -Sema::LookupResult::LookupKind Sema::LookupResult::getKind() const { - switch (StoredKind) { - case SingleDecl: - return (reinterpret_cast(First) != 0)? Found : NotFound; + unsigned UniqueTagIndex; + + unsigned I = 0; + while (I < N) { + NamedDecl *D = Decls[I]; + assert(D == D->getUnderlyingDecl()); + + NamedDecl *CanonD = cast(D->getCanonicalDecl()); + if (!Unique.insert(CanonD)) { + // If it's not unique, pull something off the back (and + // continue at this index). + Decls[I] = Decls[--N]; + } else if (isa(D)) { + // FIXME: proper support for UnresolvedUsingDecls. + Decls[I] = Decls[--N]; + } else { + // Otherwise, do some decl type analysis and then continue. + if (isa(D)) { + if (HasTag) + Ambiguous = true; + UniqueTagIndex = I; + HasTag = true; + } else if (D->isFunctionOrFunctionTemplate()) { + HasFunction = true; + } else { + if (HasNonFunction) + Ambiguous = true; + HasNonFunction = true; + } + I++; + } + } - case OverloadedDeclSingleDecl: - case OverloadedDeclFromIdResolver: - case OverloadedDeclFromDeclContext: - return FoundOverloaded; + // C++ [basic.scope.hiding]p2: + // A class name or enumeration name can be hidden by the name of + // an object, function, or enumerator declared in the same + // scope. If a class or enumeration name and an object, function, + // or enumerator are declared in the same scope (in any order) + // with the same name, the class or enumeration name is hidden + // wherever the object, function, or enumerator name is visible. + // But it's still an error if there are distinct tag types found, + // even if they're not visible. (ref?) + if (HasTag && !Ambiguous && (HasFunction || HasNonFunction)) + Decls[UniqueTagIndex] = Decls[--N]; - case AmbiguousLookupStoresBasePaths: - return Last? AmbiguousBaseSubobjectTypes : AmbiguousBaseSubobjects; + Decls.set_size(N); - case AmbiguousLookupStoresDecls: - return AmbiguousReference; - } + if (HasFunction && HasNonFunction) + Ambiguous = true; - // We can't ever get here. - return NotFound; + if (Ambiguous) + Kind = AmbiguousReference; + else if (N > 1) + Kind = FoundOverloaded; + else + Kind = Found; } /// @brief Converts the result of name lookup into a single (possible @@ -430,191 +238,93 @@ Sema::LookupResult::LookupKind Sema::Loo /// solution, since it causes the OverloadedFunctionDecl to be /// leaked. FIXME: Eventually, there will be a better way to iterate /// over the set of overloaded functions returned by name lookup. -NamedDecl *Sema::LookupResult::getAsDecl() const { - switch (StoredKind) { - case SingleDecl: - return reinterpret_cast(First); - - case OverloadedDeclFromIdResolver: - return MaybeConstructOverloadSet(*Context, - IdentifierResolver::iterator::getFromOpaqueValue(First), - IdentifierResolver::iterator::getFromOpaqueValue(Last)); - - case OverloadedDeclFromDeclContext: - return MaybeConstructOverloadSet(*Context, - reinterpret_cast(First), - reinterpret_cast(Last)); - - case OverloadedDeclSingleDecl: - return reinterpret_cast(First); - - case AmbiguousLookupStoresDecls: - case AmbiguousLookupStoresBasePaths: - assert(false && - "Name lookup returned an ambiguity that could not be handled"); - break; +NamedDecl *Sema::LookupResult::getAsSingleDecl(ASTContext &C) const { + size_t size = Decls.size(); + if (size == 0) return 0; + if (size == 1) return *begin(); + + if (isAmbiguous()) return 0; + + iterator I = begin(), E = end(); + + OverloadedFunctionDecl *Ovl + = OverloadedFunctionDecl::Create(C, (*I)->getDeclContext(), + (*I)->getDeclName()); + for (; I != E; ++I) { + NamedDecl *ND = *I; + assert(ND->getUnderlyingDecl() == ND + && "decls in lookup result should have redirections stripped"); + assert(ND->isFunctionOrFunctionTemplate()); + if (isa(ND)) + Ovl->addOverload(cast(ND)); + else + Ovl->addOverload(cast(ND)); + // FIXME: UnresolvedUsingDecls. } - - return 0; + + return Ovl; } -/// @brief Retrieves the BasePaths structure describing an ambiguous -/// name lookup, or null. -CXXBasePaths *Sema::LookupResult::getBasePaths() const { - if (StoredKind == AmbiguousLookupStoresBasePaths) - return reinterpret_cast(First); - return 0; +void Sema::LookupResult::addDeclsFromBasePaths(const CXXBasePaths &P) { + CXXBasePaths::paths_iterator I, E; + DeclContext::lookup_iterator DI, DE; + for (I = P.begin(), E = P.end(); I != E; ++I) + for (llvm::tie(DI,DE) = I->Decls; DI != DE; ++DI) + addDecl(*DI); } -Sema::LookupResult::iterator::reference -Sema::LookupResult::iterator::operator*() const { - switch (Result->StoredKind) { - case SingleDecl: - return reinterpret_cast(Current); - - case OverloadedDeclSingleDecl: - return *reinterpret_cast(Current); - - case OverloadedDeclFromIdResolver: - return *IdentifierResolver::iterator::getFromOpaqueValue(Current); - - case AmbiguousLookupStoresBasePaths: - if (Result->Last) - return *reinterpret_cast(Current); - - // Fall through to handle the DeclContext::lookup_iterator we're - // storing. - - case OverloadedDeclFromDeclContext: - case AmbiguousLookupStoresDecls: - return *reinterpret_cast(Current); - } - - return 0; +void Sema::LookupResult::setAmbiguousBaseSubobjects(CXXBasePaths &P) { + Paths = new CXXBasePaths; + Paths->swap(P); + addDeclsFromBasePaths(*Paths); + resolveKind(); + Kind = AmbiguousBaseSubobjects; } -Sema::LookupResult::iterator& Sema::LookupResult::iterator::operator++() { - switch (Result->StoredKind) { - case SingleDecl: - Current = reinterpret_cast((NamedDecl*)0); - break; - - case OverloadedDeclSingleDecl: { - NamedDecl ** I = reinterpret_cast(Current); - ++I; - Current = reinterpret_cast(I); - break; - } - - case OverloadedDeclFromIdResolver: { - IdentifierResolver::iterator I - = IdentifierResolver::iterator::getFromOpaqueValue(Current); - ++I; - Current = I.getAsOpaqueValue(); - break; - } - - case AmbiguousLookupStoresBasePaths: - if (Result->Last) { - NamedDecl ** I = reinterpret_cast(Current); - ++I; - Current = reinterpret_cast(I); - break; - } - // Fall through to handle the DeclContext::lookup_iterator we're - // storing. - - case OverloadedDeclFromDeclContext: - case AmbiguousLookupStoresDecls: { - DeclContext::lookup_iterator I - = reinterpret_cast(Current); - ++I; - Current = reinterpret_cast(I); - break; - } - } - - return *this; +void Sema::LookupResult::setAmbiguousBaseSubobjectTypes(CXXBasePaths &P) { + Paths = new CXXBasePaths; + Paths->swap(P); + addDeclsFromBasePaths(*Paths); + resolveKind(); + Kind = AmbiguousBaseSubobjectTypes; } -Sema::LookupResult::iterator Sema::LookupResult::begin() { - switch (StoredKind) { - case SingleDecl: - case OverloadedDeclFromIdResolver: - case OverloadedDeclFromDeclContext: - case AmbiguousLookupStoresDecls: - return iterator(this, First); - - case OverloadedDeclSingleDecl: { - OverloadedFunctionDecl * Ovl = - reinterpret_cast(First); - return iterator(this, - reinterpret_cast(&(*Ovl->function_begin()))); - } - - case AmbiguousLookupStoresBasePaths: - if (Last) - return iterator(this, - reinterpret_cast(getBasePaths()->found_decls_begin())); - else - return iterator(this, - reinterpret_cast(getBasePaths()->front().Decls.first)); +void Sema::LookupResult::print(llvm::raw_ostream &Out) { + Out << Decls.size() << " result(s)"; + if (isAmbiguous()) Out << ", ambiguous"; + if (Paths) Out << ", base paths present"; + + for (iterator I = begin(), E = end(); I != E; ++I) { + Out << "\n"; + (*I)->print(Out, 2); } - - // Required to suppress GCC warning. - return iterator(); } -Sema::LookupResult::iterator Sema::LookupResult::end() { - switch (StoredKind) { - case SingleDecl: - case OverloadedDeclFromIdResolver: - case OverloadedDeclFromDeclContext: - case AmbiguousLookupStoresDecls: - return iterator(this, Last); - - case OverloadedDeclSingleDecl: { - OverloadedFunctionDecl * Ovl = - reinterpret_cast(First); - return iterator(this, - reinterpret_cast(&(*Ovl->function_end()))); - } - - case AmbiguousLookupStoresBasePaths: - if (Last) - return iterator(this, - reinterpret_cast(getBasePaths()->found_decls_end())); - else - return iterator(this, reinterpret_cast( - getBasePaths()->front().Decls.second)); - } +// Adds all qualifying matches for a name within a decl context to the +// given lookup result. Returns true if any matches were found. +static bool LookupDirect(Sema::LookupResult &R, DeclContext *DC, + DeclarationName Name, + Sema::LookupNameKind NameKind, + unsigned IDNS) { + bool Found = false; - // Required to suppress GCC warning. - return iterator(); -} + DeclContext::lookup_iterator I, E; + for (llvm::tie(I, E) = DC->lookup(Name); I != E; ++I) + if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS)) + R.addDecl(*I), Found = true; -void Sema::LookupResult::Destroy() { - if (CXXBasePaths *Paths = getBasePaths()) - delete Paths; - else if (getKind() == AmbiguousReference) - delete[] reinterpret_cast(First); + return Found; } -static void -CppNamespaceLookup(ASTContext &Context, DeclContext *NS, +static bool +CppNamespaceLookup(Sema::LookupResult &R, ASTContext &Context, DeclContext *NS, DeclarationName Name, Sema::LookupNameKind NameKind, - unsigned IDNS, LookupResultsTy &Results, - UsingDirectivesTy *UDirs = 0) { + unsigned IDNS, UsingDirectivesTy *UDirs = 0) { assert(NS && NS->isFileContext() && "CppNamespaceLookup() requires namespace!"); // Perform qualified name lookup into the LookupCtx. - DeclContext::lookup_iterator I, E; - for (llvm::tie(I, E) = NS->lookup(Name); I != E; ++I) - if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS)) { - Results.push_back(Sema::LookupResult::CreateLookupResult(Context, I, E)); - break; - } + bool Found = LookupDirect(R, NS, Name, NameKind, IDNS); if (UDirs) { // For each UsingDirectiveDecl, which common ancestor is equal @@ -625,9 +335,13 @@ CppNamespaceLookup(ASTContext &Context, UsingDirAncestorCompare()); for (; UI != UEnd; ++UI) - CppNamespaceLookup(Context, (*UI)->getNominatedNamespace(), - Name, NameKind, IDNS, Results); + if (LookupDirect(R, (*UI)->getNominatedNamespace(), Name, NameKind, IDNS)) + Found = true; } + + R.resolveKind(); + + return Found; } static bool isNamespaceOrTranslationUnitScope(Scope *S) { @@ -645,8 +359,8 @@ static DeclContext *findOuterContext(Sco return 0; } -std::pair -Sema::CppLookupName(Scope *S, DeclarationName Name, +bool +Sema::CppLookupName(LookupResult &R, Scope *S, DeclarationName Name, LookupNameKind NameKind, bool RedeclarationOnly) { assert(getLangOptions().CPlusPlus && "Can perform only C++ lookup"); @@ -684,25 +398,19 @@ Sema::CppLookupName(Scope *S, Declaratio // for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) { // Check whether the IdResolver has anything in this scope. + bool Found = false; for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) { if (isAcceptableLookupResult(*I, NameKind, IDNS)) { - // We found something. Look for anything else in our scope - // with this same name and in an acceptable identifier - // namespace, so that we can construct an overload set if we - // need to. - IdentifierResolver::iterator LastI = I; - for (++LastI; LastI != IEnd; ++LastI) { - if (!S->isDeclScope(DeclPtrTy::make(*LastI))) - break; - } - LookupResult Result = - LookupResult::CreateLookupResult(Context, I, LastI); - return std::make_pair(true, Result); + Found = true; + R.addDecl(*I); } } + if (Found) { + R.resolveKind(); + return true; + } + if (DeclContext *Ctx = static_cast(S->getEntity())) { - LookupResult R; - DeclContext *OuterCtx = findOuterContext(S); for (; Ctx && Ctx->getPrimaryContext() != OuterCtx; Ctx = Ctx->getLookupParent()) { @@ -715,9 +423,8 @@ Sema::CppLookupName(Scope *S, Declaratio // example, inside a class without any base classes, we never need to // perform qualified lookup because all of the members are on top of the // identifier chain. - R = LookupQualifiedName(Ctx, Name, NameKind, RedeclarationOnly); - if (R) - return std::make_pair(true, R); + if (LookupQualifiedName(R, Ctx, Name, NameKind, RedeclarationOnly)) + return true; } } } @@ -740,8 +447,6 @@ Sema::CppLookupName(Scope *S, Declaratio // that aren't strictly lexical, and therefore we walk through the // context as well as walking through the scopes. - LookupResultsTy LookupResults; - bool LookedInCtx = false; for (; S; S = S->getParent()) { DeclContext *Ctx = static_cast(S->getEntity()); if (Ctx->isTransparentContext()) @@ -751,45 +456,32 @@ Sema::CppLookupName(Scope *S, Declaratio "We should have been looking only at file context here already."); // Check whether the IdResolver has anything in this scope. + bool Found = false; for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) { if (isAcceptableLookupResult(*I, NameKind, IDNS)) { // We found something. Look for anything else in our scope // with this same name and in an acceptable identifier // namespace, so that we can construct an overload set if we // need to. - IdentifierResolver::iterator LastI = I; - for (++LastI; LastI != IEnd; ++LastI) { - if (!S->isDeclScope(DeclPtrTy::make(*LastI))) - break; - } - - // We store name lookup result, and continue trying to look into - // associated context, and maybe namespaces nominated by - // using-directives. - LookupResults.push_back( - LookupResult::CreateLookupResult(Context, I, LastI)); - break; + Found = true; + R.addDecl(*I); } } - LookedInCtx = true; // Look into context considering using-directives. - CppNamespaceLookup(Context, Ctx, Name, NameKind, IDNS, - LookupResults, &UDirs); + if (CppNamespaceLookup(R, Context, Ctx, Name, NameKind, IDNS, &UDirs)) + Found = true; - LookupResult Result; - if ((Result = MergeLookupResults(Context, LookupResults)) || - (RedeclarationOnly && !Ctx->isTransparentContext())) - return std::make_pair(true, Result); - } - - if (!(LookedInCtx || LookupResults.empty())) { - // We didn't Performed lookup in Scope entity, so we return - // result form IdentifierResolver. - assert((LookupResults.size() == 1) && "Wrong size!"); - return std::make_pair(true, LookupResults.front()); + if (Found) { + R.resolveKind(); + return true; + } + + if (RedeclarationOnly && !Ctx->isTransparentContext()) + return false; } - return std::make_pair(false, LookupResult()); + + return !R.empty(); } /// @brief Perform unqualified name lookup starting from a given @@ -823,11 +515,10 @@ Sema::CppLookupName(Scope *S, Declaratio /// @returns The result of name lookup, which includes zero or more /// declarations and possibly additional information used to diagnose /// ambiguities. -Sema::LookupResult -Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind, - bool RedeclarationOnly, bool AllowBuiltinCreation, - SourceLocation Loc) { - if (!Name) return LookupResult::CreateLookupResult(Context, 0); +bool Sema::LookupName(LookupResult &R, Scope *S, DeclarationName Name, + LookupNameKind NameKind, bool RedeclarationOnly, + bool AllowBuiltinCreation, SourceLocation Loc) { + if (!Name) return false; if (!getLangOptions().CPlusPlus) { // Unqualified name lookup in C/Objective-C is purely lexical, so @@ -897,6 +588,8 @@ Sema::LookupName(Scope *S, DeclarationNa continue; } + R.addDecl(*I); + if ((*I)->getAttr()) { // If this declaration has the "overloadable" attribute, we // might have a set of overloaded functions. @@ -912,20 +605,18 @@ Sema::LookupName(Scope *S, DeclarationNa for (++LastI; LastI != IEnd; ++LastI) { if (!S->isDeclScope(DeclPtrTy::make(*LastI))) break; + R.addDecl(*LastI); } - - return LookupResult::CreateLookupResult(Context, I, LastI); } - // We have a single lookup result. - return LookupResult::CreateLookupResult(Context, *I); + R.resolveKind(); + + return true; } } else { // Perform C++ unqualified name lookup. - std::pair MaybeResult = - CppLookupName(S, Name, NameKind, RedeclarationOnly); - if (MaybeResult.first) - return MaybeResult.second; + if (CppLookupName(R, S, Name, NameKind, RedeclarationOnly)) + return true; } // If we didn't find a use of this identifier, and if the identifier @@ -941,15 +632,16 @@ Sema::LookupName(Scope *S, DeclarationNa // 'malloc'. Instead, we'll just error. if (getLangOptions().CPlusPlus && Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - return LookupResult::CreateLookupResult(Context, 0); + return false; - return LookupResult::CreateLookupResult(Context, - LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, - S, RedeclarationOnly, Loc)); + NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, + S, RedeclarationOnly, Loc); + if (D) R.addDecl(D); + return (D != NULL); } } } - return LookupResult::CreateLookupResult(Context, 0); + return false; } /// @brief Perform qualified name lookup into a given context. @@ -982,13 +674,13 @@ Sema::LookupName(Scope *S, DeclarationNa /// @returns The result of name lookup, which includes zero or more /// declarations and possibly additional information used to diagnose /// ambiguities. -Sema::LookupResult -Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name, - LookupNameKind NameKind, bool RedeclarationOnly) { +bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, + DeclarationName Name, LookupNameKind NameKind, + bool RedeclarationOnly) { assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context"); if (!Name) - return LookupResult::CreateLookupResult(Context, 0); + return false; // If we're performing qualified name lookup (e.g., lookup into a // struct), find fields as part of ordinary name lookup. @@ -1007,15 +699,15 @@ Sema::LookupQualifiedName(DeclContext *L "Declaration context must already be complete!"); // Perform qualified name lookup into the LookupCtx. - DeclContext::lookup_iterator I, E; - for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I) - if (isAcceptableLookupResult(*I, NameKind, IDNS)) - return LookupResult::CreateLookupResult(Context, I, E); + if (LookupDirect(R, LookupCtx, Name, NameKind, IDNS)) { + R.resolveKind(); + return true; + } // If this isn't a C++ class, we aren't allowed to look into base // classes, we're done. if (RedeclarationOnly || !isa(LookupCtx)) - return LookupResult::CreateLookupResult(Context, 0); + return false; // Perform lookup into our base classes. CXXRecordDecl *LookupRec = cast(LookupCtx); @@ -1041,7 +733,7 @@ Sema::LookupQualifiedName(DeclContext *L case LookupObjCImplementationName: case LookupObjCCategoryImplName: // These lookups will never find a member in a C++ class (or base class). - return LookupResult::CreateLookupResult(Context, 0); + return false; case LookupNestedNameSpecifierName: BaseCallback = &CXXRecordDecl::FindNestedNameSpecifierMember; @@ -1049,7 +741,7 @@ Sema::LookupQualifiedName(DeclContext *L } if (!LookupRec->lookupInBases(BaseCallback, Name.getAsOpaquePtr(), Paths)) - return LookupResult::CreateLookupResult(Context, 0); + return false; // C++ [class.member.lookup]p2: // [...] If the resulting set of declarations are not all from @@ -1066,16 +758,15 @@ Sema::LookupQualifiedName(DeclContext *L // Determine whether we're looking at a distinct sub-object or not. if (SubobjectType.isNull()) { - // This is the first subobject we've looked at. Record it's type. + // This is the first subobject we've looked at. Record its type. SubobjectType = Context.getCanonicalType(PathElement.Base->getType()); SubobjectNumber = PathElement.SubobjectNumber; } else if (SubobjectType != Context.getCanonicalType(PathElement.Base->getType())) { // We found members of the given name in two subobjects of // different types. This lookup is ambiguous. - CXXBasePaths *PathsOnHeap = new CXXBasePaths; - PathsOnHeap->swap(Paths); - return LookupResult::CreateLookupResult(Context, PathsOnHeap, true); + R.setAmbiguousBaseSubobjectTypes(Paths); + return true; } else if (SubobjectNumber != PathElement.SubobjectNumber) { // We have a different subobject of the same type. @@ -1111,21 +802,18 @@ Sema::LookupQualifiedName(DeclContext *L // We have found a nonstatic member name in multiple, distinct // subobjects. Name lookup is ambiguous. - CXXBasePaths *PathsOnHeap = new CXXBasePaths; - PathsOnHeap->swap(Paths); - return LookupResult::CreateLookupResult(Context, PathsOnHeap, false); + R.setAmbiguousBaseSubobjects(Paths); + return true; } } // Lookup in a base class succeeded; return these results. - // If we found a function declaration, return an overload set. - if ((*Paths.front().Decls.first)->isFunctionOrFunctionTemplate()) - return LookupResult::CreateLookupResult(Context, - Paths.front().Decls.first, Paths.front().Decls.second); - - // We found a non-function declaration; return a single declaration. - return LookupResult::CreateLookupResult(Context, *Paths.front().Decls.first); + DeclContext::lookup_iterator I, E; + for (llvm::tie(I,E) = Paths.front().Decls; I != E; ++I) + R.addDecl(*I); + R.resolveKind(); + return true; } /// @brief Performs name lookup for a name that was parsed in the @@ -1152,17 +840,16 @@ Sema::LookupQualifiedName(DeclContext *L /// @param EnteringContext Indicates whether we are going to enter the /// context of the scope-specifier SS (if present). /// -/// @returns The result of qualified or unqualified name lookup. -Sema::LookupResult -Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS, - DeclarationName Name, LookupNameKind NameKind, - bool RedeclarationOnly, bool AllowBuiltinCreation, - SourceLocation Loc, - bool EnteringContext) { +/// @returns True if any decls were found (but possibly ambiguous) +bool Sema::LookupParsedName(LookupResult &R, Scope *S, const CXXScopeSpec *SS, + DeclarationName Name, LookupNameKind NameKind, + bool RedeclarationOnly, bool AllowBuiltinCreation, + SourceLocation Loc, + bool EnteringContext) { if (SS && SS->isInvalid()) { // When the scope specifier is invalid, don't even look for // anything. - return LookupResult::CreateLookupResult(Context, 0); + return false; } if (SS && SS->isSet()) { @@ -1170,20 +857,20 @@ Sema::LookupParsedName(Scope *S, const C // We have resolved the scope specifier to a particular declaration // contex, and will perform name lookup in that context. if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS)) - return LookupResult::CreateLookupResult(Context, 0); + return false; - return LookupQualifiedName(DC, Name, NameKind, RedeclarationOnly); + return LookupQualifiedName(R, DC, Name, NameKind, RedeclarationOnly); } // We could not resolve the scope specified to a specific declaration // context, which means that SS refers to an unknown specialization. // Name lookup can't find anything in this case. - return LookupResult::CreateLookupResult(Context, 0); + return false; } // Perform unqualified name lookup starting in the given scope. - return LookupName(S, Name, NameKind, RedeclarationOnly, AllowBuiltinCreation, - Loc); + return LookupName(R, S, Name, NameKind, RedeclarationOnly, + AllowBuiltinCreation, Loc); } @@ -1222,7 +909,6 @@ bool Sema::DiagnoseAmbiguousLookup(Looku Diag((*Found)->getLocation(), diag::note_ambiguous_member_found); - Result.Destroy(); return true; } @@ -1240,24 +926,18 @@ bool Sema::DiagnoseAmbiguousLookup(Looku Diag(D->getLocation(), diag::note_ambiguous_member_found); } - Result.Destroy(); - return true; - } else if (Result.getKind() == LookupResult::AmbiguousReference) { - Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange; - - NamedDecl **DI = reinterpret_cast(Result.First), - **DEnd = reinterpret_cast(Result.Last); - - for (; DI != DEnd; ++DI) - Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI; - - Result.Destroy(); return true; } - assert(false && "Unhandled form of name lookup ambiguity"); + assert(Result.getKind() == LookupResult::AmbiguousReference && + "unhandled form of name lookup ambiguity"); + Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange; + + + LookupResult::iterator DI = Result.begin(), DE = Result.end(); + for (; DI != DE; ++DI) + Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI; - // We can't reach here. return true; } @@ -1661,14 +1341,14 @@ IsAcceptableNonMemberOperatorCandidate(F /// \brief Find the protocol with the given name, if any. ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II) { - Decl *D = LookupName(TUScope, II, LookupObjCProtocolName).getAsDecl(); + Decl *D = LookupSingleName(TUScope, II, LookupObjCProtocolName); return cast_or_null(D); } /// \brief Find the Objective-C category implementation with the given /// name, if any. ObjCCategoryImplDecl *Sema::LookupObjCCategoryImpl(IdentifierInfo *II) { - Decl *D = LookupName(TUScope, II, LookupObjCCategoryImplName).getAsDecl(); + Decl *D = LookupSingleName(TUScope, II, LookupObjCCategoryImplName); return cast_or_null(D); } @@ -1678,8 +1358,8 @@ ObjCCategoryImplDecl *Sema::LookupObjCCa Decl *Sema::LookupQualifiedNameWithType(DeclContext *DC, DeclarationName Name, QualType T) { - LookupResult result = - LookupQualifiedName(DC, Name, LookupOrdinaryName, true); + LookupResult result; + LookupQualifiedName(result, DC, Name, LookupOrdinaryName, true); CanQualType CQT = Context.getCanonicalType(T); @@ -1708,11 +1388,12 @@ void Sema::LookupOverloadedOperatorName( // of type T2 or "reference to (possibly cv-qualified) T2", // when T2 is an enumeration type, are candidate functions. DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); - LookupResult Operators = LookupName(S, OpName, LookupOperatorName); + LookupResult Operators; + LookupName(Operators, S, OpName, LookupOperatorName); assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous"); - if (!Operators) + if (Operators.empty()) return; for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end(); Index: lib/Sema/SemaAttr.cpp =================================================================== --- lib/Sema/SemaAttr.cpp (revision 83513) +++ lib/Sema/SemaAttr.cpp (working copy) @@ -179,13 +179,12 @@ void Sema::ActOnPragmaUnused(const Token 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) Index: lib/Sema/SemaExprObjC.cpp =================================================================== --- lib/Sema/SemaExprObjC.cpp (revision 83513) +++ lib/Sema/SemaExprObjC.cpp (working copy) @@ -77,7 +77,7 @@ Sema::ExprResult Sema::ParseObjCStringLi Ty = Context.getObjCObjectPointerType(Ty); } else { IdentifierInfo *NSIdent = &Context.Idents.get("NSString"); - NamedDecl *IF = LookupName(TUScope, NSIdent, LookupOrdinaryName); + NamedDecl *IF = LookupSingleName(TUScope, NSIdent, LookupOrdinaryName); if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null(IF)) { Context.setObjCConstantStringInterface(StrIF); Ty = Context.getObjCConstantStringInterface(); @@ -387,7 +387,8 @@ Sema::ExprResult Sema::ActOnClassMessage } else { // 'super' has been used outside a method context. If a variable named // 'super' has been declared, redirect. If not, produce a diagnostic. - NamedDecl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName); + NamedDecl *SuperDecl + = LookupSingleName(S, receiverName, LookupOrdinaryName); ValueDecl *VD = dyn_cast_or_null(SuperDecl); if (VD) { ExprResult ReceiverExpr = new (Context) DeclRefExpr(VD, VD->getType(), @@ -412,7 +413,8 @@ Sema::ExprResult Sema::ActOnClassMessage // // If necessary, the following lookup could move to getObjCInterfaceDecl(). if (!ClassDecl) { - NamedDecl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName); + NamedDecl *IDecl + = LookupSingleName(TUScope, receiverName, LookupOrdinaryName); if (TypedefDecl *OCTD = dyn_cast_or_null(IDecl)) { const ObjCInterfaceType *OCIT; OCIT = OCTD->getUnderlyingType()->getAs(); Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp (revision 83513) +++ lib/Sema/SemaExpr.cpp (working copy) @@ -695,8 +695,8 @@ Sema::ActOnDeclarationNameExpr(Scope *S, isAddressOfOperand)); } - LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName, - false, true, Loc); + LookupResult Lookup; + LookupParsedName(Lookup, S, SS, Name, LookupOrdinaryName, false, true, Loc); if (Lookup.isAmbiguous()) { DiagnoseAmbiguousLookup(Lookup, Name, Loc, @@ -705,7 +705,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, return ExprError(); } - NamedDecl *D = Lookup.getAsDecl(); + NamedDecl *D = Lookup.getAsSingleDecl(Context); // If this reference is in an Objective-C method, then ivar lookup happens as // well. @@ -2181,10 +2181,10 @@ Sema::BuildMemberReferenceExpr(Scope *S, } // The record definition is complete, now make sure the member is valid. - LookupResult Result - = LookupQualifiedName(DC, MemberName, LookupMemberName, false); + LookupResult Result; + LookupQualifiedName(Result, DC, MemberName, LookupMemberName, false); - if (!Result) + if (Result.empty()) return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member_deprecated) << MemberName << BaseExpr->getSourceRange()); if (Result.isAmbiguous()) { @@ -2193,13 +2193,14 @@ Sema::BuildMemberReferenceExpr(Scope *S, return ExprError(); } + NamedDecl *MemberDecl = Result.getAsSingleDecl(Context); + if (SS && SS->isSet()) { + TypeDecl* TyD = cast(MemberDecl->getDeclContext()); QualType BaseTypeCanon = Context.getCanonicalType(BaseType).getUnqualifiedType(); QualType MemberTypeCanon - = Context.getCanonicalType( - Context.getTypeDeclType( - dyn_cast(Result.getAsDecl()->getDeclContext()))); + = Context.getCanonicalType(Context.getTypeDeclType(TyD)); if (BaseTypeCanon != MemberTypeCanon && !IsDerivedFrom(BaseTypeCanon, MemberTypeCanon)) @@ -2208,8 +2209,6 @@ Sema::BuildMemberReferenceExpr(Scope *S, << MemberTypeCanon << BaseTypeCanon); } - NamedDecl *MemberDecl = Result; - // If the decl being referenced had an error, return an error for this // sub-expr without emitting another error, in order to avoid cascading // error cases. @@ -5685,10 +5684,11 @@ Sema::OwningExprResult Sema::ActOnBuilti } } + LookupResult R; + LookupQualifiedName(R, RD, OC.U.IdentInfo, LookupMemberName); + FieldDecl *MemberDecl - = dyn_cast_or_null(LookupQualifiedName(RD, OC.U.IdentInfo, - LookupMemberName) - .getAsDecl()); + = dyn_cast_or_null(R.getAsSingleDecl(Context)); // FIXME: Leaks Res if (!MemberDecl) return ExprError(Diag(BuiltinLoc, diag::err_typecheck_no_member_deprecated) Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp (revision 83513) +++ lib/AST/Decl.cpp (working copy) @@ -299,6 +299,9 @@ bool NamedDecl::declarationReplaces(Name if (isa(this)) return false; + if (isa(this) && isa(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.