[Lldb-commits] [lldb] r355897 - Correctly look up declarations in inline namespaces

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 12 00:45:04 PDT 2019


Author: teemperor
Date: Tue Mar 12 00:45:04 2019
New Revision: 355897

URL: http://llvm.org/viewvc/llvm-project?rev=355897&view=rev
Log:
Correctly look up declarations in inline namespaces

Summary:
This patch marks the inline namespaces from DWARF as inline and also ensures that looking
up declarations now follows the lookup rules for inline namespaces.

Reviewers: aprantl, shafik, serge-sans-paille

Reviewed By: aprantl

Subscribers: eraman, jdoerfert, lldb-commits

Tags: #c_modules_in_lldb, #lldb

Differential Revision: https://reviews.llvm.org/D59198

Added:
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/TestInlineNamespace.py
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/main.cpp
Modified:
    lldb/trunk/include/lldb/Symbol/ClangASTContext.h
    lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h
    lldb/trunk/include/lldb/Symbol/TypeSystem.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/trunk/source/Symbol/ClangASTContext.cpp
    lldb/trunk/source/Symbol/CompilerDeclContext.cpp

Modified: lldb/trunk/include/lldb/Symbol/ClangASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ClangASTContext.h?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ClangASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h Tue Mar 12 00:45:04 2019
@@ -354,11 +354,13 @@ public:
   //------------------------------------------------------------------
 
   clang::NamespaceDecl *
-  GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx);
+  GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
+                                bool is_inline = false);
 
   static clang::NamespaceDecl *
   GetUniqueNamespaceDeclaration(clang::ASTContext *ast, const char *name,
-                                clang::DeclContext *decl_ctx);
+                                clang::DeclContext *decl_ctx,
+                                bool is_inline = false);
 
   //------------------------------------------------------------------
   // Function Types
@@ -506,6 +508,9 @@ public:
                                 bool *is_instance_method_ptr,
                                 ConstString *language_object_name_ptr) override;
 
+  bool DeclContextIsContainedInLookup(void *opaque_decl_ctx,
+                                      void *other_opaque_decl_ctx) override;
+
   //----------------------------------------------------------------------
   // Clang specific clang::DeclContext functions
   //----------------------------------------------------------------------

Modified: lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/CompilerDeclContext.h Tue Mar 12 00:45:04 2019
@@ -76,6 +76,21 @@ public:
                      ConstString *language_object_name_ptr);
 
   //----------------------------------------------------------------------
+  /// Check if the given other decl context is contained in the lookup
+  /// of this decl context (for example because the other context is a nested
+  /// inline namespace).
+  ///
+  /// @param[in] other
+  ///     The other decl context for which we should check if it is contained
+  ///     in the lookoup of this context.
+  ///
+  /// @return
+  ///     Returns true iff the other decl context is contained in the lookup
+  ///     of this decl context.
+  //----------------------------------------------------------------------
+  bool IsContainedInLookup(CompilerDeclContext other) const;
+
+  //----------------------------------------------------------------------
   // Accessors
   //----------------------------------------------------------------------
 

Modified: lldb/trunk/include/lldb/Symbol/TypeSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TypeSystem.h?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/TypeSystem.h (original)
+++ lldb/trunk/include/lldb/Symbol/TypeSystem.h Tue Mar 12 00:45:04 2019
@@ -132,6 +132,9 @@ public:
       void *opaque_decl_ctx, lldb::LanguageType *language_ptr,
       bool *is_instance_method_ptr, ConstString *language_object_name_ptr) = 0;
 
+  virtual bool DeclContextIsContainedInLookup(void *opaque_decl_ctx,
+                                              void *other_opaque_decl_ctx) = 0;
+
   //----------------------------------------------------------------------
   // Tests
   //----------------------------------------------------------------------

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/Makefile?rev=355897&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/Makefile Tue Mar 12 00:45:04 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/TestInlineNamespace.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/TestInlineNamespace.py?rev=355897&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/TestInlineNamespace.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/TestInlineNamespace.py Tue Mar 12 00:45:04 2019
@@ -0,0 +1,26 @@
+"""
+Test that we correctly handle inline namespaces.
+"""
+
+import lldb
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestInlineNamespace(TestBase):
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test(self):
+        self.build()
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        # The 'A::B::f' function must be found via 'A::f' as 'B' is an inline
+        # namespace.
+        self.expect("expr A::f()", substrs=['$0 = 3'])
+        # But we should still find the function when we pretend the inline
+        # namespace is not inline.
+        self.expect("expr A::B::f()", substrs=['$1 = 3'])

Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/main.cpp?rev=355897&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/inline-namespace/main.cpp Tue Mar 12 00:45:04 2019
@@ -0,0 +1,10 @@
+namespace A {
+  inline namespace B {
+    int f() { return 3; }
+  };
+}
+
+int main(int argc, char **argv) {
+  // Set break point at this line.
+  return A::f();
+}

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Tue Mar 12 00:45:04 2019
@@ -3798,8 +3798,11 @@ DWARFASTParserClang::ResolveNamespaceDIE
       const char *namespace_name = die.GetName();
       clang::DeclContext *containing_decl_ctx =
           GetClangDeclContextContainingDIE(die, nullptr);
-      namespace_decl = m_ast.GetUniqueNamespaceDeclaration(namespace_name,
-                                                           containing_decl_ctx);
+      bool is_inline =
+          die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
+
+      namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
+          namespace_name, containing_decl_ctx, is_inline);
       Log *log =
           nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
       if (log) {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Tue Mar 12 00:45:04 2019
@@ -2239,7 +2239,7 @@ bool SymbolFileDWARF::DIEInDeclContext(c
       CompilerDeclContext actual_decl_ctx =
           dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
       if (actual_decl_ctx)
-        return actual_decl_ctx == *decl_ctx;
+        return decl_ctx->IsContainedInLookup(actual_decl_ctx);
     }
   }
   return false;

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Tue Mar 12 00:45:04 2019
@@ -1893,9 +1893,8 @@ ClangASTContext::GetNumBaseClasses(const
 
 #pragma mark Namespace Declarations
 
-NamespaceDecl *
-ClangASTContext::GetUniqueNamespaceDeclaration(const char *name,
-                                               DeclContext *decl_ctx) {
+NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
+    const char *name, DeclContext *decl_ctx, bool is_inline) {
   NamespaceDecl *namespace_decl = nullptr;
   ASTContext *ast = getASTContext();
   TranslationUnitDecl *translation_unit_decl = ast->getTranslationUnitDecl();
@@ -1913,7 +1912,7 @@ ClangASTContext::GetUniqueNamespaceDecla
     }
 
     namespace_decl =
-        NamespaceDecl::Create(*ast, decl_ctx, false, SourceLocation(),
+        NamespaceDecl::Create(*ast, decl_ctx, is_inline, SourceLocation(),
                               SourceLocation(), &identifier_info, nullptr);
 
     decl_ctx->addDecl(namespace_decl);
@@ -1954,12 +1953,13 @@ ClangASTContext::GetUniqueNamespaceDecla
 }
 
 NamespaceDecl *ClangASTContext::GetUniqueNamespaceDeclaration(
-    clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx) {
+    clang::ASTContext *ast, const char *name, clang::DeclContext *decl_ctx,
+    bool is_inline) {
   ClangASTContext *ast_ctx = ClangASTContext::GetASTContext(ast);
   if (ast_ctx == nullptr)
     return nullptr;
 
-  return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx);
+  return ast_ctx->GetUniqueNamespaceDeclaration(name, decl_ctx, is_inline);
 }
 
 clang::BlockDecl *
@@ -10264,6 +10264,23 @@ bool ClangASTContext::DeclContextIsClass
   return false;
 }
 
+bool ClangASTContext::DeclContextIsContainedInLookup(
+    void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
+  auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
+  auto *other = (clang::DeclContext *)other_opaque_decl_ctx;
+
+  do {
+    // A decl context always includes its own contents in its lookup.
+    if (decl_ctx == other)
+      return true;
+
+    // If we have an inline namespace, then the lookup of the parent context
+    // also includes the inline namespace contents.
+  } while (other->isInlineNamespace() && (other = other->getParent()));
+
+  return false;
+}
+
 clang::DeclContext *
 ClangASTContext::DeclContextGetAsDeclContext(const CompilerDeclContext &dc) {
   if (dc.IsClang())

Modified: lldb/trunk/source/Symbol/CompilerDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompilerDeclContext.cpp?rev=355897&r1=355896&r2=355897&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CompilerDeclContext.cpp (original)
+++ lldb/trunk/source/Symbol/CompilerDeclContext.cpp Tue Mar 12 00:45:04 2019
@@ -59,6 +59,19 @@ bool CompilerDeclContext::IsClassMethod(
     return false;
 }
 
+bool CompilerDeclContext::IsContainedInLookup(CompilerDeclContext other) const {
+  if (!IsValid())
+    return false;
+
+  // If the other context is just the current context, we don't need to go
+  // over the type system to know that the lookup is identical.
+  if (this == &other)
+    return true;
+
+  return m_type_system->DeclContextIsContainedInLookup(m_opaque_decl_ctx,
+                                                       other.m_opaque_decl_ctx);
+}
+
 bool lldb_private::operator==(const lldb_private::CompilerDeclContext &lhs,
                               const lldb_private::CompilerDeclContext &rhs) {
   return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&




More information about the lldb-commits mailing list