[AST] Add OriginalDC argument to ExternalASTSource::FindExternalVisibleDeclsByName (#123152)

Part for relanding https://github.com/llvm/llvm-project/pull/122887.

I split this to test where the performance regession comes from if
modules are not used.
This commit is contained in:
Chuanqi Xu 2025-01-17 12:46:00 +08:00 committed by GitHub
parent a4e87da963
commit 263fed7ce9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 82 additions and 43 deletions

View File

@ -2722,6 +2722,9 @@ public:
bool Deserialize = false) const;
private:
lookup_result lookupImpl(DeclarationName Name,
const DeclContext *OriginalLookupDC) const;
/// Whether this declaration context has had externally visible
/// storage added since the last lookup. In this case, \c LookupPtr's
/// invariant may not hold and needs to be fixed before we perform

View File

@ -141,7 +141,8 @@ public:
/// Implementation of the ExternalASTSource API.
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
DeclarationName Name,
const DeclContext *OriginalDC) override;
/// Implementation of the ExternalASTSource API.
void

View File

@ -145,12 +145,20 @@ public:
/// Find all declarations with the given name in the given context,
/// and add them to the context by calling SetExternalVisibleDeclsForName
/// or SetNoExternalVisibleDeclsForName.
/// \param DC The context for lookup in. \c DC should be a primary context.
/// \param Name The name to look for.
/// \param OriginalDC The original context for lookup. \c OriginalDC can
/// provide more information than \c DC. e.g., The same namespace can appear
/// in multiple module units. So we need the \c OriginalDC to tell us what
/// the module the lookup come from.
///
/// \return \c true if any declarations might have been found, \c false if
/// we definitely have no declarations with tbis name.
///
/// The default implementation of this method is a no-op returning \c false.
virtual bool
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name);
virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name,
const DeclContext *OriginalDC);
/// Load all the external specializations for the Decl \param D if \param
/// OnlyPartial is false. Otherwise, load all the external **partial**

View File

@ -95,7 +95,8 @@ public:
/// Find all declarations with the given name in the
/// given context.
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
DeclarationName Name,
const DeclContext *OriginalDC) override;
bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override;

View File

@ -2119,7 +2119,8 @@ public:
/// The current implementation of this method just loads the entire
/// lookup table as unmaterialized references.
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
DeclarationName Name,
const DeclContext *OriginalDC) override;
/// Read all of the declarations lexically stored in a
/// declaration context.

View File

@ -1856,9 +1856,16 @@ DeclContext::lookup(DeclarationName Name) const {
if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export)
return getParent()->lookup(Name);
const DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this)
return PrimaryContext->lookup(Name);
return getPrimaryContext()->lookupImpl(Name, this);
}
DeclContext::lookup_result
DeclContext::lookupImpl(DeclarationName Name,
const DeclContext *OriginalLookupDC) const {
assert(this == getPrimaryContext() &&
"lookupImpl should only be called with primary DC!");
assert(getDeclKind() != Decl::LinkageSpec && getDeclKind() != Decl::Export &&
"We shouldn't lookup in transparent DC.");
// If we have an external source, ensure that any later redeclarations of this
// context have been loaded, since they may add names to the result of this
@ -1889,7 +1896,8 @@ DeclContext::lookup(DeclarationName Name) const {
if (!R.second && !R.first->second.hasExternalDecls())
return R.first->second.getLookupResult();
if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
if (Source->FindExternalVisibleDeclsByName(this, Name, OriginalLookupDC) ||
!R.second) {
if (StoredDeclsMap *Map = LookupPtr) {
StoredDeclsMap::iterator I = Map->find(Name);
if (I != Map->end())
@ -2115,7 +2123,8 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
if (hasExternalVisibleStorage() &&
Map->find(D->getDeclName()) == Map->end())
Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
Source->FindExternalVisibleDeclsByName(this, D->getDeclName(),
D->getDeclContext());
// Insert this declaration into the map.
StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];

View File

@ -471,8 +471,9 @@ static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer) {
return false;
}
bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
bool ExternalASTMerger::FindExternalVisibleDeclsByName(
const DeclContext *DC, DeclarationName Name,
const DeclContext *OriginalDC) {
llvm::SmallVector<NamedDecl *, 1> Decls;
llvm::SmallVector<Candidate, 4> Candidates;

View File

@ -90,9 +90,9 @@ ExternalASTSource::GetExternalCXXBaseSpecifiers(uint64_t Offset) {
return nullptr;
}
bool
ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
bool ExternalASTSource::FindExternalVisibleDeclsByName(
const DeclContext *DC, DeclarationName Name,
const DeclContext *OriginalDC) {
return false;
}

View File

@ -228,7 +228,8 @@ public:
ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM,
ASTContext &ParentASTCtxt, FileManager &ParentFM);
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
DeclarationName Name,
const DeclContext *OriginalDC) override;
void
completeVisibleDeclsMap(const clang::DeclContext *childDeclContext) override;
};
@ -270,8 +271,9 @@ ExternalSource::ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM,
Importer.reset(importer);
}
bool ExternalSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
bool ExternalSource::FindExternalVisibleDeclsByName(
const DeclContext *DC, DeclarationName Name,
const DeclContext *OriginalDC) {
IdentifierTable &ParentIdTable = ParentASTCtxt.Idents;

View File

@ -107,11 +107,13 @@ MultiplexExternalSemaSource::hasExternalDefinitions(const Decl *D) {
return EK_ReplyHazy;
}
bool MultiplexExternalSemaSource::
FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) {
bool MultiplexExternalSemaSource::FindExternalVisibleDeclsByName(
const DeclContext *DC, DeclarationName Name,
const DeclContext *OriginalDC) {
bool AnyDeclsFound = false;
for (size_t i = 0; i < Sources.size(); ++i)
AnyDeclsFound |= Sources[i]->FindExternalVisibleDeclsByName(DC, Name);
AnyDeclsFound |=
Sources[i]->FindExternalVisibleDeclsByName(DC, Name, OriginalDC);
return AnyDeclsFound;
}

View File

@ -8366,9 +8366,9 @@ void ASTReader::FindFileRegionDecls(FileID File,
*DInfo.Mod, LocalDeclID::get(*this, *DInfo.Mod, *DIt))));
}
bool
ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
bool ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name,
const DeclContext *OriginalDC) {
assert(DC->hasExternalVisibleStorage() && DC == DC->getPrimaryContext() &&
"DeclContext has no visible decls in storage");
if (!Name)

View File

@ -67,8 +67,9 @@ TEST(ExternalASTSourceTest, FailedLookupOccursOnce) {
struct TestSource : ExternalASTSource {
TestSource(unsigned &Calls) : Calls(Calls) {}
bool FindExternalVisibleDeclsByName(const DeclContext *,
DeclarationName Name) override {
bool
FindExternalVisibleDeclsByName(const DeclContext *, DeclarationName Name,
const DeclContext *OriginalDC) override {
if (Name.getAsString() == "j")
++Calls;
return false;

View File

@ -70,9 +70,10 @@ public:
m_Source->updateOutOfDateIdentifier(II);
}
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name) override {
return m_Source->FindExternalVisibleDeclsByName(DC, Name);
bool FindExternalVisibleDeclsByName(
const clang::DeclContext *DC, clang::DeclarationName Name,
const clang::DeclContext *OriginalDC) override {
return m_Source->FindExternalVisibleDeclsByName(DC, Name, OriginalDC);
}
bool LoadExternalSpecializations(const clang::Decl *D,
@ -387,10 +388,11 @@ public:
return EK_ReplyHazy;
}
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name) override {
bool FindExternalVisibleDeclsByName(
const clang::DeclContext *DC, clang::DeclarationName Name,
const clang::DeclContext *OriginalDC) override {
for (size_t i = 0; i < Sources.size(); ++i)
if (Sources[i]->FindExternalVisibleDeclsByName(DC, Name))
if (Sources[i]->FindExternalVisibleDeclsByName(DC, Name, OriginalDC))
return true;
return false;
}

View File

@ -99,7 +99,8 @@ void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
// The core lookup interface.
bool ClangASTSource::FindExternalVisibleDeclsByName(
const DeclContext *decl_ctx, DeclarationName clang_decl_name) {
const DeclContext *decl_ctx, DeclarationName clang_decl_name,
const clang::DeclContext *original_dc) {
if (!m_ast_context) {
SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
return false;

View File

@ -83,8 +83,10 @@ public:
///
/// \return
/// Whatever SetExternalVisibleDeclsForName returns.
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name) override;
bool
FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name,
const clang::DeclContext *OriginalDC) override;
/// Enumerate all Decls in a given lexical context.
///
@ -211,9 +213,10 @@ public:
public:
ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name) override {
return m_original.FindExternalVisibleDeclsByName(DC, Name);
bool FindExternalVisibleDeclsByName(
const clang::DeclContext *DC, clang::DeclarationName Name,
const clang::DeclContext *OriginalDC) override {
return m_original.FindExternalVisibleDeclsByName(DC, Name, OriginalDC);
}
void FindExternalLexicalDecls(

View File

@ -50,7 +50,8 @@ void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls(
}
bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(
const clang::DeclContext *DC, clang::DeclarationName Name) {
const clang::DeclContext *DC, clang::DeclarationName Name,
const clang::DeclContext *OriginalDC) {
llvm::SmallVector<clang::NamedDecl *, 4> decls;
// Objective-C methods are not added into the LookupPtr when they originate
// from an external source. SetExternalVisibleDeclsForName() adds them.

View File

@ -37,8 +37,10 @@ public:
llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
llvm::SmallVectorImpl<clang::Decl *> &Result) override;
bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name) override;
bool
FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
clang::DeclarationName Name,
const clang::DeclContext *OriginalDC) override;
void CompleteType(clang::TagDecl *tag_decl) override;

View File

@ -29,8 +29,9 @@ public:
AppleObjCExternalASTSource(AppleObjCDeclVendor &decl_vendor)
: m_decl_vendor(decl_vendor) {}
bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx,
clang::DeclarationName name) override {
bool FindExternalVisibleDeclsByName(
const clang::DeclContext *decl_ctx, clang::DeclarationName name,
const clang::DeclContext *original_dc) override {
Log *log(GetLog(
LLDBLog::Expressions)); // FIXME - a more appropriate log channel?