diff options
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 240 |
1 files changed, 133 insertions, 107 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index a9db973851df..2732112c00b6 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -187,7 +187,7 @@ namespace { } void done() { - std::sort(list.begin(), list.end(), UnqualUsingEntry::Comparator()); + llvm::sort(list.begin(), list.end(), UnqualUsingEntry::Comparator()); } typedef ListTy::const_iterator const_iterator; @@ -356,7 +356,7 @@ static DeclContext *getContextForScopeMatching(Decl *D) { return D->getDeclContext()->getRedeclContext(); } -/// \brief Determine whether \p D is a better lookup result than \p Existing, +/// Determine whether \p D is a better lookup result than \p Existing, /// given that they declare the same entity. static bool isPreferredLookupResult(Sema &S, Sema::LookupNameKind Kind, NamedDecl *D, NamedDecl *Existing) { @@ -669,7 +669,7 @@ LLVM_DUMP_METHOD void LookupResult::dump() { D->dump(); } -/// \brief Lookup a builtin function, when name lookup would otherwise +/// Lookup a builtin function, when name lookup would otherwise /// fail. static bool LookupBuiltin(Sema &S, LookupResult &R) { Sema::LookupNameKind NameKind = R.getLookupKind(); @@ -713,7 +713,7 @@ static bool LookupBuiltin(Sema &S, LookupResult &R) { return false; } -/// \brief Determine whether we can declare a special member function within +/// Determine whether we can declare a special member function within /// the class at this point. static bool CanDeclareSpecialMemberFunction(const CXXRecordDecl *Class) { // We need to have a definition for the class. @@ -755,7 +755,7 @@ void Sema::ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class) { DeclareImplicitDestructor(Class); } -/// \brief Determine whether this is the name of an implicitly-declared +/// Determine whether this is the name of an implicitly-declared /// special member function. static bool isImplicitlyDeclaredMemberFunctionName(DeclarationName Name) { switch (Name.getNameKind()) { @@ -773,7 +773,7 @@ static bool isImplicitlyDeclaredMemberFunctionName(DeclarationName Name) { return false; } -/// \brief If there are any implicit member functions with the given name +/// If there are any implicit member functions with the given name /// that need to be declared in the given declaration context, do so. static void DeclareImplicitMemberFunctionsWithName(Sema &S, DeclarationName Name, @@ -1354,7 +1354,7 @@ void Sema::makeMergedDefinitionVisible(NamedDecl *ND) { makeMergedDefinitionVisible(Param); } -/// \brief Find the module in which the given declaration was defined. +/// Find the module in which the given declaration was defined. static Module *getDefiningModule(Sema &S, Decl *Entity) { if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Entity)) { // If this function was instantiated from a template, the defining module is @@ -1452,6 +1452,8 @@ template<typename Filter> static bool hasVisibleDeclarationImpl(Sema &S, const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules, Filter F) { + bool HasFilteredRedecls = false; + for (auto *Redecl : D->redecls()) { auto *R = cast<NamedDecl>(Redecl); if (!F(R)) @@ -1460,6 +1462,8 @@ static bool hasVisibleDeclarationImpl(Sema &S, const NamedDecl *D, if (S.isVisible(R)) return true; + HasFilteredRedecls = true; + if (Modules) { Modules->push_back(R->getOwningModule()); const auto &Merged = S.Context.getModulesWithMergedDefinition(R); @@ -1467,7 +1471,11 @@ static bool hasVisibleDeclarationImpl(Sema &S, const NamedDecl *D, } } - return false; + // Only return false if there is at least one redecl that is not filtered out. + if (HasFilteredRedecls) + return false; + + return true; } bool Sema::hasVisibleExplicitSpecialization( @@ -1497,11 +1505,9 @@ bool Sema::hasVisibleMemberSpecialization( // class definition? return D->getLexicalDeclContext()->isFileContext(); }); - - return false; } -/// \brief Determine whether a declaration is visible to name lookup. +/// Determine whether a declaration is visible to name lookup. /// /// This routine determines whether the declaration D is visible in the current /// lookup context, taking into account the current template instantiation @@ -1648,7 +1654,7 @@ bool Sema::shouldLinkPossiblyHiddenDecl(LookupResult &R, const NamedDecl *New) { return New->isExternallyDeclarable(); } -/// \brief Retrieve the visible declaration corresponding to D, if any. +/// Retrieve the visible declaration corresponding to D, if any. /// /// This routine determines whether the declaration D is visible in the current /// module, with the current imports. If not, it checks whether any @@ -1656,7 +1662,8 @@ bool Sema::shouldLinkPossiblyHiddenDecl(LookupResult &R, const NamedDecl *New) { /// /// \returns D, or a visible previous declaration of D, whichever is more recent /// and visible. If no declaration of D is visible, returns null. -static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { +static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D, + unsigned IDNS) { assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); for (auto RD : D->redecls()) { @@ -1668,7 +1675,8 @@ static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { // FIXME: This is wrong in the case where the previous declaration is not // visible in the same scope as D. This needs to be done much more // carefully. - if (LookupResult::isVisible(SemaRef, ND)) + if (ND->isInIdentifierNamespace(IDNS) && + LookupResult::isVisible(SemaRef, ND)) return ND; } @@ -1693,17 +1701,18 @@ NamedDecl *LookupResult::getAcceptableDeclSlow(NamedDecl *D) const { auto *Key = ND->getCanonicalDecl(); if (auto *Acceptable = getSema().VisibleNamespaceCache.lookup(Key)) return Acceptable; - auto *Acceptable = - isVisible(getSema(), Key) ? Key : findAcceptableDecl(getSema(), Key); + auto *Acceptable = isVisible(getSema(), Key) + ? Key + : findAcceptableDecl(getSema(), Key, IDNS); if (Acceptable) getSema().VisibleNamespaceCache.insert(std::make_pair(Key, Acceptable)); return Acceptable; } - return findAcceptableDecl(getSema(), D); + return findAcceptableDecl(getSema(), D, IDNS); } -/// @brief Perform unqualified name lookup starting from a given +/// Perform unqualified name lookup starting from a given /// scope. /// /// Unqualified name lookup (C++ [basic.lookup.unqual], C99 6.2.1) is @@ -1841,7 +1850,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) { return (ExternalSource && ExternalSource->LookupUnqualified(R, S)); } -/// @brief Perform qualified name lookup in the namespaces nominated by +/// Perform qualified name lookup in the namespaces nominated by /// using directives by the given context. /// /// C++98 [namespace.qual]p2: @@ -1947,7 +1956,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R, return Found; } -/// \brief Callback that looks for any member of a class with the given name. +/// Callback that looks for any member of a class with the given name. static bool LookupAnyMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, DeclarationName Name) { RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl(); @@ -1956,7 +1965,7 @@ static bool LookupAnyMember(const CXXBaseSpecifier *Specifier, return !Path.Decls.empty(); } -/// \brief Determine whether the given set of member declarations contains only +/// Determine whether the given set of member declarations contains only /// static members, nested types, and enumerators. template<typename InputIterator> static bool HasOnlyStaticMembers(InputIterator First, InputIterator Last) { @@ -1988,7 +1997,7 @@ static bool HasOnlyStaticMembers(InputIterator First, InputIterator Last) { return false; } -/// \brief Perform qualified name lookup into a given context. +/// Perform qualified name lookup into a given context. /// /// Qualified name lookup (C++ [basic.lookup.qual]) is used to find /// names when the context of those names is explicit specified, e.g., @@ -2212,7 +2221,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, return true; } -/// \brief Performs qualified name lookup or special type of lookup for +/// Performs qualified name lookup or special type of lookup for /// "__super::" scope specifier. /// /// This routine is a convenience overload meant to be called from contexts @@ -2237,7 +2246,7 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, return LookupQualifiedName(R, LookupCtx); } -/// @brief Performs name lookup for a name that was parsed in the +/// Performs name lookup for a name that was parsed in the /// source code, and may contain a C++ scope specifier. /// /// This routine is a convenience routine meant to be called from @@ -2291,7 +2300,7 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, return LookupName(R, S, AllowBuiltinCreation); } -/// \brief Perform qualified name lookup into all base classes of the given +/// Perform qualified name lookup into all base classes of the given /// class. /// /// \param R captures both the lookup criteria and any lookup results found. @@ -2309,7 +2318,7 @@ bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { CXXRecordDecl *RD = cast<CXXRecordDecl>( BaseSpec.getType()->castAs<RecordType>()->getDecl()); LookupResult Result(*this, R.getLookupNameInfo(), R.getLookupKind()); - Result.setBaseObjectType(Context.getRecordType(Class)); + Result.setBaseObjectType(Context.getRecordType(Class)); LookupQualifiedName(Result, RD); // Copy the lookup results into the target, merging the base's access into @@ -2329,7 +2338,7 @@ bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { return !R.empty(); } -/// \brief Produce a diagnostic describing the ambiguity that resulted +/// Produce a diagnostic describing the ambiguity that resulted /// from name lookup. /// /// \param Result The result of the ambiguous lookup to be diagnosed. @@ -2445,7 +2454,7 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces, Namespaces.insert(Ctx->getPrimaryContext()); } -// \brief Add the associated classes and namespaces for argument-dependent +// Add the associated classes and namespaces for argument-dependent // lookup that involves a template argument (C++ [basic.lookup.koenig]p2). static void addAssociatedClassesAndNamespaces(AssociatedLookup &Result, @@ -2495,7 +2504,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, } } -// \brief Add the associated classes and namespaces for +// Add the associated classes and namespaces for // argument-dependent lookup with an argument of class type // (C++ [basic.lookup.koenig]p2). static void @@ -2590,7 +2599,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, } } -// \brief Add the associated classes and namespaces for +// Add the associated classes and namespaces for // argument-dependent lookup with an argument of type T // (C++ [basic.lookup.koenig]p2). static void @@ -2754,7 +2763,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { } } -/// \brief Find the associated classes and namespaces for +/// Find the associated classes and namespaces for /// argument-dependent lookup for a call with the given set of /// arguments. /// @@ -2821,7 +2830,7 @@ NamedDecl *Sema::LookupSingleName(Scope *S, DeclarationName Name, return R.getAsSingle<NamedDecl>(); } -/// \brief Find the protocol with the given name, if any. +/// Find the protocol with the given name, if any. ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc, RedeclarationKind Redecl) { @@ -3048,7 +3057,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, return *Result; } -/// \brief Look up the default constructor for the given class. +/// Look up the default constructor for the given class. CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) { SpecialMemberOverloadResult Result = LookupSpecialMember(Class, CXXDefaultConstructor, false, false, false, @@ -3057,7 +3066,7 @@ CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) { return cast_or_null<CXXConstructorDecl>(Result.getMethod()); } -/// \brief Look up the copying constructor for the given class. +/// Look up the copying constructor for the given class. CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class, unsigned Quals) { assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) && @@ -3069,7 +3078,7 @@ CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class, return cast_or_null<CXXConstructorDecl>(Result.getMethod()); } -/// \brief Look up the moving constructor for the given class. +/// Look up the moving constructor for the given class. CXXConstructorDecl *Sema::LookupMovingConstructor(CXXRecordDecl *Class, unsigned Quals) { SpecialMemberOverloadResult Result = @@ -3079,7 +3088,7 @@ CXXConstructorDecl *Sema::LookupMovingConstructor(CXXRecordDecl *Class, return cast_or_null<CXXConstructorDecl>(Result.getMethod()); } -/// \brief Look up the constructors for the given class. +/// Look up the constructors for the given class. DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { // If the implicit constructors have not yet been declared, do so now. if (CanDeclareSpecialMemberFunction(Class)) { @@ -3096,7 +3105,7 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { return Class->lookup(Name); } -/// \brief Look up the copying assignment operator for the given class. +/// Look up the copying assignment operator for the given class. CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, bool RValueThis, unsigned ThisQuals) { @@ -3113,7 +3122,7 @@ CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class, return Result.getMethod(); } -/// \brief Look up the moving assignment operator for the given class. +/// Look up the moving assignment operator for the given class. CXXMethodDecl *Sema::LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, bool RValueThis, @@ -3129,7 +3138,7 @@ CXXMethodDecl *Sema::LookupMovingAssignment(CXXRecordDecl *Class, return Result.getMethod(); } -/// \brief Look for the destructor of the given class. +/// Look for the destructor of the given class. /// /// During semantic analysis, this routine should be used in lieu of /// CXXRecordDecl::getDestructor(). @@ -3329,6 +3338,23 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, // lookup (11.4). DeclContext::lookup_result R = NS->lookup(Name); for (auto *D : R) { + auto *Underlying = D; + if (auto *USD = dyn_cast<UsingShadowDecl>(D)) + Underlying = USD->getTargetDecl(); + + if (!isa<FunctionDecl>(Underlying) && + !isa<FunctionTemplateDecl>(Underlying)) + continue; + + if (!isVisible(D)) { + D = findAcceptableDecl( + *this, D, (Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend)); + if (!D) + continue; + if (auto *USD = dyn_cast<UsingShadowDecl>(D)) + Underlying = USD->getTargetDecl(); + } + // If the only declaration here is an ordinary friend, consider // it only if it was declared in an associated classes. if ((D->getIdentifierNamespace() & Decl::IDNS_Ordinary) == 0) { @@ -3350,22 +3376,6 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc, continue; } - auto *Underlying = D; - if (auto *USD = dyn_cast<UsingShadowDecl>(D)) - Underlying = USD->getTargetDecl(); - - if (!isa<FunctionDecl>(Underlying) && - !isa<FunctionTemplateDecl>(Underlying)) - continue; - - if (!isVisible(D)) { - D = findAcceptableDecl(*this, D); - if (!D) - continue; - if (auto *USD = dyn_cast<UsingShadowDecl>(D)) - Underlying = USD->getTargetDecl(); - } - // FIXME: Preserve D as the FoundDecl. Result.insert(Underlying); } @@ -3385,26 +3395,26 @@ class ShadowContextRAII; class VisibleDeclsRecord { public: - /// \brief An entry in the shadow map, which is optimized to store a + /// An entry in the shadow map, which is optimized to store a /// single declaration (the common case) but can also store a list /// of declarations. typedef llvm::TinyPtrVector<NamedDecl*> ShadowMapEntry; private: - /// \brief A mapping from declaration names to the declarations that have + /// A mapping from declaration names to the declarations that have /// this name within a particular scope. typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap; - /// \brief A list of shadow maps, which is used to model name hiding. + /// A list of shadow maps, which is used to model name hiding. std::list<ShadowMap> ShadowMaps; - /// \brief The declaration contexts we have already visited. + /// The declaration contexts we have already visited. llvm::SmallPtrSet<DeclContext *, 8> VisitedContexts; friend class ShadowContextRAII; public: - /// \brief Determine whether we have already visited this context + /// Determine whether we have already visited this context /// (and, if not, note that we are going to visit that context now). bool visitedContext(DeclContext *Ctx) { return !VisitedContexts.insert(Ctx).second; @@ -3414,20 +3424,20 @@ public: return VisitedContexts.count(Ctx); } - /// \brief Determine whether the given declaration is hidden in the + /// Determine whether the given declaration is hidden in the /// current scope. /// /// \returns the declaration that hides the given declaration, or /// NULL if no such declaration exists. NamedDecl *checkHidden(NamedDecl *ND); - /// \brief Add a declaration to the current shadow map. + /// Add a declaration to the current shadow map. void add(NamedDecl *ND) { ShadowMaps.back()[ND->getDeclName()].push_back(ND); } }; -/// \brief RAII object that records when we've entered a shadow context. +/// RAII object that records when we've entered a shadow context. class ShadowContextRAII { VisibleDeclsRecord &Visible; @@ -3494,7 +3504,8 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, bool InBaseClass, VisibleDeclConsumer &Consumer, VisibleDeclsRecord &Visited, - bool IncludeDependentBases = false) { + bool IncludeDependentBases, + bool LoadExternal) { if (!Ctx) return; @@ -3502,6 +3513,8 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, if (Visited.visitedContext(Ctx->getPrimaryContext())) return; + Consumer.EnteredContext(Ctx); + // Outside C++, lookup results for the TU live on identifiers. if (isa<TranslationUnitDecl>(Ctx) && !Result.getSema().getLangOpts().CPlusPlus) { @@ -3509,11 +3522,12 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, auto &Idents = S.Context.Idents; // Ensure all external identifiers are in the identifier table. - if (IdentifierInfoLookup *External = Idents.getExternalIdentifierLookup()) { - std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers()); - for (StringRef Name = Iter->Next(); !Name.empty(); Name = Iter->Next()) - Idents.get(Name); - } + if (LoadExternal) + if (IdentifierInfoLookup *External = Idents.getExternalIdentifierLookup()) { + std::unique_ptr<IdentifierIterator> Iter(External->getIdentifiers()); + for (StringRef Name = Iter->Next(); !Name.empty(); Name = Iter->Next()) + Idents.get(Name); + } // Walk all lookup results in the TU for each identifier. for (const auto &Ident : Idents) { @@ -3535,8 +3549,13 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, if (CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(Ctx)) Result.getSema().ForceDeclarationOfImplicitMembers(Class); + // We sometimes skip loading namespace-level results (they tend to be huge). + bool Load = LoadExternal || + !(isa<TranslationUnitDecl>(Ctx) || isa<NamespaceDecl>(Ctx)); // Enumerate all of the results in this context. - for (DeclContextLookupResult R : Ctx->lookups()) { + for (DeclContextLookupResult R : + Load ? Ctx->lookups() + : Ctx->noload_lookups(/*PreserveInternalState=*/false)) { for (auto *D : R) { if (auto *ND = Result.getAcceptableDecl(D)) { Consumer.FoundDecl(ND, Visited.checkHidden(ND), Ctx, InBaseClass); @@ -3553,7 +3572,7 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, continue; LookupVisibleDecls(I->getNominatedNamespace(), Result, QualifiedNameLookup, InBaseClass, Consumer, Visited, - IncludeDependentBases); + IncludeDependentBases, LoadExternal); } } @@ -3610,7 +3629,7 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, // Find results in this base class (and its bases). ShadowContextRAII Shadow(Visited); LookupVisibleDecls(RD, Result, QualifiedNameLookup, true, Consumer, - Visited, IncludeDependentBases); + Visited, IncludeDependentBases, LoadExternal); } } @@ -3619,22 +3638,23 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, // Traverse categories. for (auto *Cat : IFace->visible_categories()) { ShadowContextRAII Shadow(Visited); - LookupVisibleDecls(Cat, Result, QualifiedNameLookup, false, - Consumer, Visited); + LookupVisibleDecls(Cat, Result, QualifiedNameLookup, false, Consumer, + Visited, IncludeDependentBases, LoadExternal); } // Traverse protocols. for (auto *I : IFace->all_referenced_protocols()) { ShadowContextRAII Shadow(Visited); LookupVisibleDecls(I, Result, QualifiedNameLookup, false, Consumer, - Visited); + Visited, IncludeDependentBases, LoadExternal); } // Traverse the superclass. if (IFace->getSuperClass()) { ShadowContextRAII Shadow(Visited); LookupVisibleDecls(IFace->getSuperClass(), Result, QualifiedNameLookup, - true, Consumer, Visited); + true, Consumer, Visited, IncludeDependentBases, + LoadExternal); } // If there is an implementation, traverse it. We do this to find @@ -3642,26 +3662,28 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, if (IFace->getImplementation()) { ShadowContextRAII Shadow(Visited); LookupVisibleDecls(IFace->getImplementation(), Result, - QualifiedNameLookup, InBaseClass, Consumer, Visited); + QualifiedNameLookup, InBaseClass, Consumer, Visited, + IncludeDependentBases, LoadExternal); } } else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) { for (auto *I : Protocol->protocols()) { ShadowContextRAII Shadow(Visited); LookupVisibleDecls(I, Result, QualifiedNameLookup, false, Consumer, - Visited); + Visited, IncludeDependentBases, LoadExternal); } } else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) { for (auto *I : Category->protocols()) { ShadowContextRAII Shadow(Visited); LookupVisibleDecls(I, Result, QualifiedNameLookup, false, Consumer, - Visited); + Visited, IncludeDependentBases, LoadExternal); } // If there is an implementation, traverse it. if (Category->getImplementation()) { ShadowContextRAII Shadow(Visited); LookupVisibleDecls(Category->getImplementation(), Result, - QualifiedNameLookup, true, Consumer, Visited); + QualifiedNameLookup, true, Consumer, Visited, + IncludeDependentBases, LoadExternal); } } } @@ -3669,7 +3691,8 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result, static void LookupVisibleDecls(Scope *S, LookupResult &Result, UnqualUsingDirectiveSet &UDirs, VisibleDeclConsumer &Consumer, - VisibleDeclsRecord &Visited) { + VisibleDeclsRecord &Visited, + bool LoadExternal) { if (!S) return; @@ -3708,7 +3731,8 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result, Result.getNameLoc(), Sema::LookupMemberName); if (ObjCInterfaceDecl *IFace = Method->getClassInterface()) { LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false, - /*InBaseClass=*/false, Consumer, Visited); + /*InBaseClass=*/false, Consumer, Visited, + /*IncludeDependentBases=*/false, LoadExternal); } } @@ -3722,7 +3746,8 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result, continue; LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/false, - /*InBaseClass=*/false, Consumer, Visited); + /*InBaseClass=*/false, Consumer, Visited, + /*IncludeDependentBases=*/false, LoadExternal); } } else if (!S->getParent()) { // Look into the translation unit scope. We walk through the translation @@ -3736,7 +3761,8 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result, // in DeclContexts unless we have to" optimization), we can eliminate this. Entity = Result.getSema().Context.getTranslationUnitDecl(); LookupVisibleDecls(Entity, Result, /*QualifiedNameLookup=*/false, - /*InBaseClass=*/false, Consumer, Visited); + /*InBaseClass=*/false, Consumer, Visited, + /*IncludeDependentBases=*/false, LoadExternal); } if (Entity) { @@ -3745,17 +3771,19 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result, for (const UnqualUsingEntry &UUE : UDirs.getNamespacesFor(Entity)) LookupVisibleDecls(const_cast<DeclContext *>(UUE.getNominatedNamespace()), Result, /*QualifiedNameLookup=*/false, - /*InBaseClass=*/false, Consumer, Visited); + /*InBaseClass=*/false, Consumer, Visited, + /*IncludeDependentBases=*/false, LoadExternal); } // Lookup names in the parent scope. ShadowContextRAII Shadow(Visited); - LookupVisibleDecls(S->getParent(), Result, UDirs, Consumer, Visited); + LookupVisibleDecls(S->getParent(), Result, UDirs, Consumer, Visited, + LoadExternal); } void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind, VisibleDeclConsumer &Consumer, - bool IncludeGlobalScope) { + bool IncludeGlobalScope, bool LoadExternal) { // Determine the set of using directives available during // unqualified name lookup. Scope *Initial = S; @@ -3776,13 +3804,13 @@ void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind, if (!IncludeGlobalScope) Visited.visitedContext(Context.getTranslationUnitDecl()); ShadowContextRAII Shadow(Visited); - ::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited); + ::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited, LoadExternal); } void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, VisibleDeclConsumer &Consumer, bool IncludeGlobalScope, - bool IncludeDependentBases) { + bool IncludeDependentBases, bool LoadExternal) { LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind); Result.setAllowHidden(Consumer.includeHiddenDecls()); VisibleDeclsRecord Visited; @@ -3791,7 +3819,7 @@ void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, ShadowContextRAII Shadow(Visited); ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, /*InBaseClass=*/false, Consumer, Visited, - IncludeDependentBases); + IncludeDependentBases, LoadExternal); } /// LookupOrCreateLabel - Do a name lookup of a label with the specified name. @@ -3846,7 +3874,7 @@ static void LookupPotentialTypoResult(Sema &SemaRef, bool isObjCIvarLookup, bool FindHidden); -/// \brief Check whether the declarations found for a typo correction are +/// Check whether the declarations found for a typo correction are /// visible. Set the correction's RequiresImport flag to true if none of the /// declarations are visible, false otherwise. static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { @@ -3865,17 +3893,13 @@ static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) { bool AnyVisibleDecls = !NewDecls.empty(); for (/**/; DI != DE; ++DI) { - NamedDecl *VisibleDecl = *DI; - if (!LookupResult::isVisible(SemaRef, *DI)) - VisibleDecl = findAcceptableDecl(SemaRef, *DI); - - if (VisibleDecl) { + if (LookupResult::isVisible(SemaRef, *DI)) { if (!AnyVisibleDecls) { // Found a visible decl, discard all hidden ones. AnyVisibleDecls = true; NewDecls.clear(); } - NewDecls.push_back(VisibleDecl); + NewDecls.push_back(*DI); } else if (!AnyVisibleDecls && !(*DI)->isModulePrivate()) NewDecls.push_back(*DI); } @@ -3945,8 +3969,7 @@ void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding, // Only consider visible declarations and declarations from modules with // names that exactly match. - if (!LookupResult::isVisible(SemaRef, ND) && Name != Typo && - !findAcceptableDecl(SemaRef, ND)) + if (!LookupResult::isVisible(SemaRef, ND) && Name != Typo) return; FoundName(Name->getName()); @@ -4337,7 +4360,7 @@ void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier( DistanceMap[NumSpecifiers].push_back(SI); } -/// \brief Perform name lookup for a possible result for typo correction. +/// Perform name lookup for a possible result for typo correction. static void LookupPotentialTypoResult(Sema &SemaRef, LookupResult &Res, IdentifierInfo *Name, @@ -4391,7 +4414,7 @@ static void LookupPotentialTypoResult(Sema &SemaRef, } } -/// \brief Add keywords to the consumer as possible typo corrections. +/// Add keywords to the consumer as possible typo corrections. static void AddKeywordsToConsumer(Sema &SemaRef, TypoCorrectionConsumer &Consumer, Scope *S, CorrectionCandidateCallback &CCC, @@ -4442,7 +4465,7 @@ static void AddKeywordsToConsumer(Sema &SemaRef, } } - if (SemaRef.getLangOpts().GNUMode) + if (SemaRef.getLangOpts().GNUKeywords) Consumer.addKeywordResult("typeof"); } else if (CCC.WantFunctionLikeCasts) { static const char *const CastableTypeSpecs[] = { @@ -4512,7 +4535,8 @@ static void AddKeywordsToConsumer(Sema &SemaRef, if (S && S->getContinueParent()) Consumer.addKeywordResult("continue"); - if (!SemaRef.getCurFunction()->SwitchStack.empty()) { + if (SemaRef.getCurFunction() && + !SemaRef.getCurFunction()->SwitchStack.empty()) { Consumer.addKeywordResult("case"); Consumer.addKeywordResult("default"); } @@ -4681,7 +4705,7 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( return Consumer; } -/// \brief Try to "correct" a typo in the source code by finding +/// Try to "correct" a typo in the source code by finding /// visible declarations whose names are similar to the name that was /// present in the source code. /// @@ -4810,7 +4834,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure && !SecondBestTC); } -/// \brief Try to "correct" a typo in the source code by finding +/// Try to "correct" a typo in the source code by finding /// visible declarations whose names are similar to the name that was /// present in the source code. /// @@ -4966,6 +4990,8 @@ bool FunctionCallFilterCCC::ValidateCandidate(const TypoCorrection &candidate) { // determine if it is a pointer or reference to a function. If so, // check against the number of arguments expected for the pointee. QualType ValType = cast<ValueDecl>(ND)->getType(); + if (ValType.isNull()) + continue; if (ValType->isAnyPointerType() || ValType->isReferenceType()) ValType = ValType->getPointeeType(); if (const FunctionProtoType *FPT = ValType->getAs<FunctionProtoType>()) @@ -5047,7 +5073,7 @@ void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, Recover); } -/// \brief Get a "quoted.h" or <angled.h> include path to use in a diagnostic +/// Get a "quoted.h" or <angled.h> include path to use in a diagnostic /// suggesting the addition of a #include of the specified file. static std::string getIncludeStringForHeader(Preprocessor &PP, const FileEntry *E) { @@ -5126,7 +5152,7 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, NamedDecl *Decl, createImplicitModuleImportForErrorRecovery(UseLoc, Modules[0]); } -/// \brief Diagnose a successfully-corrected typo. Separated from the correction +/// Diagnose a successfully-corrected typo. Separated from the correction /// itself to allow external validation of the result, etc. /// /// \param Correction The result of performing typo correction. |