llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-modules Author: Raphael Isemann (Teemperor) <details> <summary>Changes</summary> LLDB's expression parser needs to know whether Sema is performing a qualified name lookup (e.g. '::A') so that it only considers root namespaces in that case. This was done by checking the UseQualifiedLookup bit in DeclContext, which Sema::LookupQualifiedName sets for the duration of the lookup. This patch gets removes bit by moving the tracking into LLDB. Sema now reports whether we a qualified lookup started/stopped via a callback to the ExternalSemaSource, and LLDB tracks this state in a small set. --- Full diff: https://github.com/llvm/llvm-project/pull/229005.diff 10 Files Affected: - (modified) clang/include/clang/AST/DeclBase.h (+1-15) - (modified) clang/include/clang/Sema/ExternalSemaSource.h (+9) - (modified) clang/include/clang/Sema/MultiplexExternalSemaSource.h (+4) - (modified) clang/lib/AST/DeclBase.cpp (-1) - (modified) clang/lib/Sema/MultiplexExternalSemaSource.cpp (+12) - (modified) clang/lib/Sema/SemaLookup.cpp (+10-8) - (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+9-9) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h (+22) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp (+1-2) - (modified) lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h (+33-1) ``````````diff diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 8ea2533825dd9..3ca8603b73d21 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -1520,16 +1520,10 @@ class DeclContext { /// that are missing from the lookup table. LLVM_PREFERRED_TYPE(bool) mutable uint64_t HasLazyExternalLexicalLookups : 1; - - /// If \c true, lookups should only return identifier from - /// DeclContext scope (for example TranslationUnit). Used in - /// LookupQualifiedName() - LLVM_PREFERRED_TYPE(bool) - mutable uint64_t UseQualifiedLookup : 1; }; /// Number of bits in DeclContextBitfields. - enum { NumDeclContextBits = 13 }; + enum { NumDeclContextBits = 12 }; /// Stores the bits used by NamespaceDecl. /// If modified NumNamespaceDeclBits and the accessor @@ -2766,14 +2760,6 @@ class DeclContext { D == LastDecl); } - void setUseQualifiedLookup(bool use = true) const { - DeclContextBits.UseQualifiedLookup = use; - } - - bool shouldUseQualifiedLookup() const { - return DeclContextBits.UseQualifiedLookup; - } - static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } diff --git a/clang/include/clang/Sema/ExternalSemaSource.h b/clang/include/clang/Sema/ExternalSemaSource.h index 0122beff53df9..022294e9dbee3 100644 --- a/clang/include/clang/Sema/ExternalSemaSource.h +++ b/clang/include/clang/Sema/ExternalSemaSource.h @@ -240,6 +240,15 @@ class ExternalSemaSource : public ExternalASTSource { return false; } + /// Notify the external source that Sema started a qualified name lookup + /// into \p DC (e.g. the lookup of \c B in \c A::B or of \c A in \c ::A). + virtual void StartedQualifiedLookup(const DeclContext *DC) {} + + /// Notify the external source that Sema finished the qualified name lookup + /// into \p DC that was started by the last call to + /// \c StartedQualifiedLookup. + virtual void FinishedQualifiedLookup(const DeclContext *DC) {} + /// LLVM-style RTTI. /// \{ bool isA(const void *ClassID) const override { diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 8e25b6266d9ad..ad75a1d97d418 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -392,6 +392,10 @@ class MultiplexExternalSemaSource : public ExternalSemaSource { bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc, QualType T) override; + void StartedQualifiedLookup(const DeclContext *DC) override; + + void FinishedQualifiedLookup(const DeclContext *DC) override; + /// LLVM-style RTTI. /// \{ bool isA(const void *ClassID) const override { diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 548643cea2cce..226229bcb622f 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1315,7 +1315,6 @@ DeclContext::DeclContext(Decl::Kind K) { setNeedToReconcileExternalVisibleStorage(false); setHasLazyLocalLexicalLookups(false); setHasLazyExternalLexicalLookups(false); - setUseQualifiedLookup(false); } bool DeclContext::classof(const Decl *D) { diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 6f6ea9f0df261..bf2b19e143a4d 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -370,3 +370,15 @@ bool MultiplexExternalSemaSource::MaybeDiagnoseMissingCompleteType( } return false; } + +void MultiplexExternalSemaSource::StartedQualifiedLookup( + const DeclContext *DC) { + for (size_t I = 0, E = Sources.size(); I < E; ++I) + Sources[I]->StartedQualifiedLookup(DC); +} + +void MultiplexExternalSemaSource::FinishedQualifiedLookup( + const DeclContext *DC) { + for (size_t I = 0, E = Sources.size(); I < E; ++I) + Sources[I]->FinishedQualifiedLookup(DC); +} diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index bc8a30d4e9dad..75cad0bb433f8 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -2445,18 +2445,20 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, llvm_unreachable("Declaration context must already be complete!"); #endif + // Inform the external source that we're looking for a qualified name. struct QualifiedLookupInScope { - bool oldVal; - DeclContext *Context; - // Set flag in DeclContext informing debugger that we're looking for qualified name - QualifiedLookupInScope(DeclContext *ctx) - : oldVal(ctx->shouldUseQualifiedLookup()), Context(ctx) { - ctx->setUseQualifiedLookup(); + ExternalSemaSource *Source; + const DeclContext *Context; + QualifiedLookupInScope(ExternalSemaSource *Source, const DeclContext *Ctx) + : Source(Source), Context(Ctx) { + if (Source) + Source->StartedQualifiedLookup(Context); } ~QualifiedLookupInScope() { - Context->setUseQualifiedLookup(oldVal); + if (Source) + Source->FinishedQualifiedLookup(Context); } - } QL(LookupCtx); + } QL(ExternalSource.get(), LookupCtx); CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx); // FIXME: Per [temp.dep.general]p2, an unqualified name is also dependent diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 2f5b9ed925097..75be3ea7ee390 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -626,7 +626,7 @@ void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) { } void ASTDeclWriter::VisitTagDecl(TagDecl *D) { - static_assert(DeclContext::NumTagDeclBits == 23, + static_assert(DeclContext::NumTagDeclBits == 22, "You need to update the serializer after you change the " "TagDeclBits"); @@ -656,7 +656,7 @@ void ASTDeclWriter::VisitTagDecl(TagDecl *D) { } void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { - static_assert(DeclContext::NumEnumDeclBits == 43, + static_assert(DeclContext::NumEnumDeclBits == 42, "You need to update the serializer after you change the " "EnumDeclBits"); @@ -699,7 +699,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { } void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { - static_assert(DeclContext::NumRecordDeclBits == 64, + static_assert(DeclContext::NumRecordDeclBits == 63, "You need to update the serializer after you change the " "RecordDeclBits"); @@ -771,7 +771,7 @@ void ASTDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) { } void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { - static_assert(DeclContext::NumFunctionDeclBits == 45, + static_assert(DeclContext::NumFunctionDeclBits == 44, "You need to update the serializer after you change the " "FunctionDeclBits"); @@ -954,7 +954,7 @@ void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { } void ASTDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) { - static_assert(DeclContext::NumObjCMethodDeclBits == 37, + static_assert(DeclContext::NumObjCMethodDeclBits == 36, "You need to update the serializer after you change the " "ObjCMethodDeclBits"); @@ -1509,7 +1509,7 @@ void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *CD) { } void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { - static_assert(DeclContext::NumLinkageSpecDeclBits == 17, + static_assert(DeclContext::NumLinkageSpecDeclBits == 16, "You need to update the serializer after you change the" "LinkageSpecDeclBits"); @@ -1767,7 +1767,7 @@ void ASTDeclWriter::VisitCXXMethodDecl(CXXMethodDecl *D) { } void ASTDeclWriter::VisitCXXConstructorDecl(CXXConstructorDecl *D) { - static_assert(DeclContext::NumCXXConstructorDeclBits == 64, + static_assert(DeclContext::NumCXXConstructorDeclBits == 63, "You need to update the serializer after you change the " "CXXConstructorDeclBits"); @@ -2252,7 +2252,7 @@ void ASTDeclWriter::VisitCXXExpansionStmtDecl(CXXExpansionStmtDecl *D) { /// Emit the DeclContext part of a declaration context decl. void ASTDeclWriter::VisitDeclContext(DeclContext *DC) { - static_assert(DeclContext::NumDeclContextBits == 13, + static_assert(DeclContext::NumDeclContextBits == 12, "You need to update the serializer after you change the " "DeclContextBits"); LookupBlockOffsets Offsets; @@ -2378,7 +2378,7 @@ void ASTDeclWriter::VisitOMPRequiresDecl(OMPRequiresDecl *D) { } void ASTDeclWriter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { - static_assert(DeclContext::NumOMPDeclareReductionDeclBits == 15, + static_assert(DeclContext::NumOMPDeclareReductionDeclBits == 14, "You need to update the serializer after you change the " "NumOMPDeclareReductionDeclBits"); diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h index fb4e2331a5cb9..3529bb03b5d89 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ASTUtils.h @@ -153,6 +153,18 @@ class ExternalASTSourceWrapper : public clang::ExternalSemaSource { BaseOffsets, VirtualBaseOffsets); } + void StartedQualifiedLookup(const clang::DeclContext *DC) override { + if (auto *sema_source = + llvm::dyn_cast<clang::ExternalSemaSource>(m_Source.get())) + sema_source->StartedQualifiedLookup(DC); + } + + void FinishedQualifiedLookup(const clang::DeclContext *DC) override { + if (auto *sema_source = + llvm::dyn_cast<clang::ExternalSemaSource>(m_Source.get())) + sema_source->FinishedQualifiedLookup(DC); + } + /// This gets called when Sema is reconciling undefined but used decls. /// For LLDB's use-case, we never provide Clang with function definitions, /// instead we rely on linkage names and symbol resolution to call the @@ -634,6 +646,16 @@ class SemaSourceWithPriorities : public clang::ExternalSemaSource { } return false; } + + void StartedQualifiedLookup(const clang::DeclContext *DC) override { + for (auto &Source : Sources) + Source->StartedQualifiedLookup(DC); + } + + void FinishedQualifiedLookup(const clang::DeclContext *DC) override { + for (auto &Source : Sources) + Source->FinishedQualifiedLookup(DC); + } }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 2361e4923943e..a96f22bff93d1 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -686,8 +686,7 @@ void ClangASTSource::FillNamespaceMap( // disambiguation for function calls are handled separately in // SearchFunctionsInSymbolContexts. const bool find_root_namespaces = - context.m_decl_context && - context.m_decl_context->shouldUseQualifiedLookup(); + context.m_decl_context && IsInQualifiedLookup(context.m_decl_context); found_namespace_decl = symbol_file->FindNamespace( name, namespace_decl, /* only root namespaces */ find_root_namespaces); diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h index 33edc2d1eecc7..cdae1cc524e6d 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h @@ -17,8 +17,11 @@ #include "lldb/Target/Target.h" #include "clang/AST/ExternalASTSource.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Sema/ExternalSemaSource.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" namespace lldb_private { @@ -202,12 +205,31 @@ class ClangASTSource : public clang::ExternalASTSource, } bool GetLookupsEnabled() { return m_lookups_enabled; } + /// Called by Sema when it starts a qualified name lookup into \p DC. + void StartedQualifiedLookup(const clang::DeclContext *DC) { + m_qualified_lookup_contexts.push_back(DC); + } + + /// Called by Sema when it finishes a qualified name lookup into \p DC. + void FinishedQualifiedLookup(const clang::DeclContext *DC) { + assert(!m_qualified_lookup_contexts.empty() && + m_qualified_lookup_contexts.back() == DC && + "Unbalanced qualified lookup notifications"); + m_qualified_lookup_contexts.pop_back(); + } + + /// Returns true if Sema is currently performing a qualified name lookup + /// into \p DC. + bool IsInQualifiedLookup(const clang::DeclContext *DC) const { + return llvm::is_contained(m_qualified_lookup_contexts, DC); + } + /// \class ClangASTSourceProxy ClangASTSource.h /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource /// /// Clang AST contexts like to own their AST sources, so this is a state- /// free proxy object. - class ClangASTSourceProxy : public clang::ExternalASTSource { + class ClangASTSourceProxy : public clang::ExternalSemaSource { public: ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {} @@ -247,6 +269,14 @@ class ClangASTSource : public clang::ExternalASTSource, return m_original.StartTranslationUnit(Consumer); } + void StartedQualifiedLookup(const clang::DeclContext *DC) override { + m_original.StartedQualifiedLookup(DC); + } + + void FinishedQualifiedLookup(const clang::DeclContext *DC) override { + m_original.FinishedQualifiedLookup(DC); + } + private: ClangASTSource &m_original; }; @@ -393,6 +423,8 @@ class ClangASTSource : public clang::ExternalASTSource, std::shared_ptr<ClangASTImporter> m_ast_importer_sp; std::set<const clang::Decl *> m_active_lexical_decls; std::set<const char *> m_active_lookups; + /// The DeclContexts Sema is currently performing a qualified lookup into. + llvm::SmallVector<const clang::DeclContext *, 2> m_qualified_lookup_contexts; }; } // namespace lldb_private `````````` </details> https://github.com/llvm/llvm-project/pull/229005 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
