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

Reply via email to