[Lldb-commits] [lldb] r301273 - [Expression parser] Return both types and variables

Sean Callanan via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 24 16:14:04 PDT 2017


Author: spyffe
Date: Mon Apr 24 18:14:04 2017
New Revision: 301273

URL: http://llvm.org/viewvc/llvm-project?rev=301273&view=rev
Log:
[Expression parser] Return both types and variables

Many times a user wants to access a type when there's a variable of
the same name, or a variable when there's a type of the same name.
Depending on the precise context, currently the expression parser
can fail to resolve one or the other.

This is because ClangExpressionDeclMap has logic to limit the
amount of information it searches, and that logic sometimes cuts
down the search prematurely. This patch removes some of those early
exits.

In that sense, this patch trades performance (early exit is faster)
for correctness.

I've also included two new test cases showing examples of this
behavior – as well as modifying an existing test case that gets it
wrong.

Added:
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cc
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cc
Modified:
    lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile?rev=301273&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile Mon Apr 24 18:14:04 2017
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+C_SOURCES := main.c
+include $(LEVEL)/Makefile.rules
\ No newline at end of file

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py?rev=301273&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py Mon Apr 24 18:14:04 2017
@@ -0,0 +1,7 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+    __file__, globals(), [
+        decorators.expectedFailureAll(
+            oslist=["windows"], bugnumber="llvm.org/pr24764")])
\ No newline at end of file

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cc
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cc?rev=301273&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cc (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cc Mon Apr 24 18:14:04 2017
@@ -0,0 +1,36 @@
+//===-- main.cc -------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LIDENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace n {
+    struct D {
+        int i;
+        static int anInt() { return 2; }
+        int dump() { return i; }
+    };
+
+    class C {
+    public:
+        int foo(D *D);
+    };
+}
+
+using namespace n;
+
+int C::foo(D* D) {
+    return D->dump(); //% self.expect("expression -- D->dump()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"])
+                      //% self.expect("expression -- D::anInt()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"])
+
+}
+
+int main (int argc, char const *argv[])
+{
+    D myD { D::anInt() };
+    C().foo(&myD);
+    return 0; 
+}

Modified: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py?rev=301273&r1=301272&r2=301273&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py Mon Apr 24 18:14:04 2017
@@ -111,8 +111,8 @@ class TestCppNsImport(TestBase):
 
         test_result = frame.EvaluateExpression("imported")
         self.assertTrue(
-            test_result.IsValid() and test_result.GetError().Fail(),
-            "imported is ambiguous")
+            test_result.IsValid() and test_result.GetValueAsSigned() == 99,
+            "imported = 99")
 
         test_result = frame.EvaluateExpression("single")
         self.assertTrue(

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile?rev=301273&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile Mon Apr 24 18:14:04 2017
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+C_SOURCES := main.c
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py?rev=301273&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py Mon Apr 24 18:14:04 2017
@@ -0,0 +1,7 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+    __file__, globals(), [
+        decorators.expectedFailureAll(
+            oslist=["windows"], bugnumber="llvm.org/pr24764")])

Added: lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cc
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cc?rev=301273&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cc (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cc Mon Apr 24 18:14:04 2017
@@ -0,0 +1,40 @@
+//===-- main.cc -------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LIDENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+void *D = 0;
+
+class D {
+    static int i;
+};
+
+int D::i = 3;
+
+namespace errno {
+    int j = 4;
+};
+
+int twice(int n)
+{
+    return n * 2; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"])
+                  //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["void"])
+                  //% self.expect("expression -- errno::j", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "4"])
+}
+
+const char getAChar()
+{
+    const char D[] = "Hello world";
+    return D[0];  //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"])
+                  //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["char", "Hello"])
+}
+
+int main (int argc, char const *argv[])
+{
+    int six = twice(3);
+    return 0; 
+}

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp?rev=301273&r1=301272&r2=301273&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp Mon Apr 24 18:14:04 2017
@@ -814,9 +814,8 @@ void ClangExpressionDeclMap::FindExterna
     FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
                              current_id);
   }
-
-  if (!context.m_found.variable && !context.m_found.local_vars_nsp)
-    ClangASTSource::FindExternalVisibleDecls(context);
+  
+  ClangASTSource::FindExternalVisibleDecls(context);
 }
 
 void ClangExpressionDeclMap::FindExternalVisibleDecls(
@@ -1217,7 +1216,7 @@ void ClangExpressionDeclMap::FindExterna
             }
           }
 
-          if (var) {
+          if (var && !variable_found) {
             variable_found = true;
             valobj = ValueObjectVariable::Create(frame, var);
             AddOneVariable(context, var, valobj, current_id);
@@ -1248,303 +1247,297 @@ void ClangExpressionDeclMap::FindExterna
       }
     }
 
-    if (!context.m_found.variable) {
-      const bool include_inlines = false;
-      const bool append = false;
-
-      if (namespace_decl && module_sp) {
-        const bool include_symbols = false;
-
-        module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
-                                 include_symbols, include_inlines, append,
-                                 sc_list);
-      } else if (target && !namespace_decl) {
-        const bool include_symbols = true;
-
-        // TODO Fix FindFunctions so that it doesn't return
-        //   instance methods for eFunctionNameTypeBase.
-
-        target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
-                                          include_symbols, include_inlines,
-                                          append, sc_list);
-      }
-
-      // If we found more than one function, see if we can use the
-      // frame's decl context to remove functions that are shadowed
-      // by other functions which match in type but are nearer in scope.
-      //
-      // AddOneFunction will not add a function whose type has already been
-      // added, so if there's another function in the list with a matching
-      // type, check to see if their decl context is a parent of the current
-      // frame's or was imported via a and using statement, and pick the
-      // best match according to lookup rules.
-      if (sc_list.GetSize() > 1) {
-        // Collect some info about our frame's context.
-        StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
-        SymbolContext frame_sym_ctx;
-        if (frame != nullptr)
-          frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
-                                                  lldb::eSymbolContextBlock);
-        CompilerDeclContext frame_decl_context =
-            frame_sym_ctx.block != nullptr
-                ? frame_sym_ctx.block->GetDeclContext()
-                : CompilerDeclContext();
-
-        // We can't do this without a compiler decl context for our frame.
-        if (frame_decl_context) {
-          clang::DeclContext *frame_decl_ctx =
-              (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
-          ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
-              frame_decl_context.GetTypeSystem());
-
-          // Structure to hold the info needed when comparing function
-          // declarations.
-          struct FuncDeclInfo {
-            ConstString m_name;
-            CompilerType m_copied_type;
-            uint32_t m_decl_lvl;
-            SymbolContext m_sym_ctx;
-          };
-
-          // First, symplify things by looping through the symbol contexts
-          // to remove unwanted functions and separate out the functions we
-          // want to compare and prune into a separate list.
-          // Cache the info needed about the function declarations in a
-          // vector for efficiency.
-          SymbolContextList sc_sym_list;
-          uint32_t num_indices = sc_list.GetSize();
-          std::vector<FuncDeclInfo> fdi_cache;
-          fdi_cache.reserve(num_indices);
-          for (uint32_t index = 0; index < num_indices; ++index) {
-            FuncDeclInfo fdi;
-            SymbolContext sym_ctx;
-            sc_list.GetContextAtIndex(index, sym_ctx);
-
-            // We don't know enough about symbols to compare them,
-            // but we should keep them in the list.
-            Function *function = sym_ctx.function;
-            if (!function) {
-              sc_sym_list.Append(sym_ctx);
-              continue;
-            }
-            // Filter out functions without declaration contexts, as well as
-            // class/instance methods, since they'll be skipped in the
-            // code that follows anyway.
-            CompilerDeclContext func_decl_context = function->GetDeclContext();
-            if (!func_decl_context ||
-                func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
-              continue;
-            // We can only prune functions for which we can copy the type.
-            CompilerType func_clang_type =
-                function->GetType()->GetFullCompilerType();
-            CompilerType copied_func_type = GuardedCopyType(func_clang_type);
-            if (!copied_func_type) {
-              sc_sym_list.Append(sym_ctx);
-              continue;
-            }
+    const bool include_inlines = false;
+    const bool append = false;
 
-            fdi.m_sym_ctx = sym_ctx;
-            fdi.m_name = function->GetName();
-            fdi.m_copied_type = copied_func_type;
-            fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
-            if (fdi.m_copied_type && func_decl_context) {
-              // Call CountDeclLevels to get the number of parent scopes we
-              // have to look through before we find the function declaration.
-              // When comparing functions of the same type, the one with a
-              // lower count will be closer to us in the lookup scope and
-              // shadows the other.
-              clang::DeclContext *func_decl_ctx =
-                  (clang::DeclContext *)
-                      func_decl_context.GetOpaqueDeclContext();
-              fdi.m_decl_lvl =
-                  ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
-                                       &fdi.m_name, &fdi.m_copied_type);
-            }
-            fdi_cache.emplace_back(fdi);
-          }
+    if (namespace_decl && module_sp) {
+      const bool include_symbols = false;
 
-          // Loop through the functions in our cache looking for matching types,
-          // then compare their scope levels to see which is closer.
-          std::multimap<CompilerType, const FuncDeclInfo *> matches;
-          for (const FuncDeclInfo &fdi : fdi_cache) {
-            const CompilerType t = fdi.m_copied_type;
-            auto q = matches.find(t);
-            if (q != matches.end()) {
-              if (q->second->m_decl_lvl > fdi.m_decl_lvl)
-                // This function is closer; remove the old set.
-                matches.erase(t);
-              else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
-                // The functions in our set are closer - skip this one.
-                continue;
-            }
-            matches.insert(std::make_pair(t, &fdi));
-          }
-
-          // Loop through our matches and add their symbol contexts to our list.
-          SymbolContextList sc_func_list;
-          for (const auto &q : matches)
-            sc_func_list.Append(q.second->m_sym_ctx);
+      module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
+                               include_symbols, include_inlines, append,
+                               sc_list);
+    } else if (target && !namespace_decl) {
+      const bool include_symbols = true;
+
+      // TODO Fix FindFunctions so that it doesn't return
+      //   instance methods for eFunctionNameTypeBase.
+
+      target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
+                                        include_symbols, include_inlines,
+                                        append, sc_list);
+    }
 
-          // Rejoin the lists with the functions in front.
-          sc_list = sc_func_list;
-          sc_list.Append(sc_sym_list);
-        }
-      }
+    // If we found more than one function, see if we can use the
+    // frame's decl context to remove functions that are shadowed
+    // by other functions which match in type but are nearer in scope.
+    //
+    // AddOneFunction will not add a function whose type has already been
+    // added, so if there's another function in the list with a matching
+    // type, check to see if their decl context is a parent of the current
+    // frame's or was imported via a and using statement, and pick the
+    // best match according to lookup rules.
+    if (sc_list.GetSize() > 1) {
+      // Collect some info about our frame's context.
+      StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+      SymbolContext frame_sym_ctx;
+      if (frame != nullptr)
+        frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+                                                lldb::eSymbolContextBlock);
+      CompilerDeclContext frame_decl_context =
+          frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
+                                         : CompilerDeclContext();
 
-      if (sc_list.GetSize()) {
-        Symbol *extern_symbol = NULL;
-        Symbol *non_extern_symbol = NULL;
+      // We can't do this without a compiler decl context for our frame.
+      if (frame_decl_context) {
+        clang::DeclContext *frame_decl_ctx =
+            (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
+        ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+            frame_decl_context.GetTypeSystem());
 
-        for (uint32_t index = 0, num_indices = sc_list.GetSize();
-             index < num_indices; ++index) {
+        // Structure to hold the info needed when comparing function
+        // declarations.
+        struct FuncDeclInfo {
+          ConstString m_name;
+          CompilerType m_copied_type;
+          uint32_t m_decl_lvl;
+          SymbolContext m_sym_ctx;
+        };
+
+        // First, symplify things by looping through the symbol contexts
+        // to remove unwanted functions and separate out the functions we
+        // want to compare and prune into a separate list.
+        // Cache the info needed about the function declarations in a
+        // vector for efficiency.
+        SymbolContextList sc_sym_list;
+        uint32_t num_indices = sc_list.GetSize();
+        std::vector<FuncDeclInfo> fdi_cache;
+        fdi_cache.reserve(num_indices);
+        for (uint32_t index = 0; index < num_indices; ++index) {
+          FuncDeclInfo fdi;
           SymbolContext sym_ctx;
           sc_list.GetContextAtIndex(index, sym_ctx);
 
-          if (sym_ctx.function) {
-            CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
-
-            if (!decl_ctx)
+          // We don't know enough about symbols to compare them,
+          // but we should keep them in the list.
+          Function *function = sym_ctx.function;
+          if (!function) {
+            sc_sym_list.Append(sym_ctx);
+            continue;
+          }
+          // Filter out functions without declaration contexts, as well as
+          // class/instance methods, since they'll be skipped in the
+          // code that follows anyway.
+          CompilerDeclContext func_decl_context = function->GetDeclContext();
+          if (!func_decl_context ||
+              func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
+            continue;
+          // We can only prune functions for which we can copy the type.
+          CompilerType func_clang_type =
+              function->GetType()->GetFullCompilerType();
+          CompilerType copied_func_type = GuardedCopyType(func_clang_type);
+          if (!copied_func_type) {
+            sc_sym_list.Append(sym_ctx);
+            continue;
+          }
+
+          fdi.m_sym_ctx = sym_ctx;
+          fdi.m_name = function->GetName();
+          fdi.m_copied_type = copied_func_type;
+          fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
+          if (fdi.m_copied_type && func_decl_context) {
+            // Call CountDeclLevels to get the number of parent scopes we
+            // have to look through before we find the function declaration.
+            // When comparing functions of the same type, the one with a
+            // lower count will be closer to us in the lookup scope and
+            // shadows the other.
+            clang::DeclContext *func_decl_ctx =
+                (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
+            fdi.m_decl_lvl = ast->CountDeclLevels(
+                frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type);
+          }
+          fdi_cache.emplace_back(fdi);
+        }
+
+        // Loop through the functions in our cache looking for matching types,
+        // then compare their scope levels to see which is closer.
+        std::multimap<CompilerType, const FuncDeclInfo *> matches;
+        for (const FuncDeclInfo &fdi : fdi_cache) {
+          const CompilerType t = fdi.m_copied_type;
+          auto q = matches.find(t);
+          if (q != matches.end()) {
+            if (q->second->m_decl_lvl > fdi.m_decl_lvl)
+              // This function is closer; remove the old set.
+              matches.erase(t);
+            else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
+              // The functions in our set are closer - skip this one.
               continue;
+          }
+          matches.insert(std::make_pair(t, &fdi));
+        }
 
-            // Filter out class/instance methods.
-            if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
-              continue;
+        // Loop through our matches and add their symbol contexts to our list.
+        SymbolContextList sc_func_list;
+        for (const auto &q : matches)
+          sc_func_list.Append(q.second->m_sym_ctx);
 
-            AddOneFunction(context, sym_ctx.function, NULL, current_id);
-            context.m_found.function_with_type_info = true;
-            context.m_found.function = true;
-          } else if (sym_ctx.symbol) {
-            if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
-              sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
-              if (sym_ctx.symbol == NULL)
-                continue;
-            }
+        // Rejoin the lists with the functions in front.
+        sc_list = sc_func_list;
+        sc_list.Append(sc_sym_list);
+      }
+    }
 
-            if (sym_ctx.symbol->IsExternal())
-              extern_symbol = sym_ctx.symbol;
-            else
-              non_extern_symbol = sym_ctx.symbol;
+    if (sc_list.GetSize()) {
+      Symbol *extern_symbol = NULL;
+      Symbol *non_extern_symbol = NULL;
+
+      for (uint32_t index = 0, num_indices = sc_list.GetSize();
+           index < num_indices; ++index) {
+        SymbolContext sym_ctx;
+        sc_list.GetContextAtIndex(index, sym_ctx);
+
+        if (sym_ctx.function) {
+          CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
+
+          if (!decl_ctx)
+            continue;
+
+          // Filter out class/instance methods.
+          if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
+            continue;
+
+          AddOneFunction(context, sym_ctx.function, NULL, current_id);
+          context.m_found.function_with_type_info = true;
+          context.m_found.function = true;
+        } else if (sym_ctx.symbol) {
+          if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
+            sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
+            if (sym_ctx.symbol == NULL)
+              continue;
           }
+
+          if (sym_ctx.symbol->IsExternal())
+            extern_symbol = sym_ctx.symbol;
+          else
+            non_extern_symbol = sym_ctx.symbol;
         }
+      }
 
-        if (!context.m_found.function_with_type_info) {
-          for (clang::NamedDecl *decl : decls_from_modules) {
-            if (llvm::isa<clang::FunctionDecl>(decl)) {
-              clang::NamedDecl *copied_decl =
-                  llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
-                      m_ast_context, &decl->getASTContext(), decl));
-              if (copied_decl) {
-                context.AddNamedDecl(copied_decl);
-                context.m_found.function_with_type_info = true;
-              }
+      if (!context.m_found.function_with_type_info) {
+        for (clang::NamedDecl *decl : decls_from_modules) {
+          if (llvm::isa<clang::FunctionDecl>(decl)) {
+            clang::NamedDecl *copied_decl =
+                llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
+                    m_ast_context, &decl->getASTContext(), decl));
+            if (copied_decl) {
+              context.AddNamedDecl(copied_decl);
+              context.m_found.function_with_type_info = true;
             }
           }
         }
+      }
 
-        if (!context.m_found.function_with_type_info) {
-          if (extern_symbol) {
-            AddOneFunction(context, NULL, extern_symbol, current_id);
-            context.m_found.function = true;
-          } else if (non_extern_symbol) {
-            AddOneFunction(context, NULL, non_extern_symbol, current_id);
-            context.m_found.function = true;
-          }
+      if (!context.m_found.function_with_type_info) {
+        if (extern_symbol) {
+          AddOneFunction(context, NULL, extern_symbol, current_id);
+          context.m_found.function = true;
+        } else if (non_extern_symbol) {
+          AddOneFunction(context, NULL, non_extern_symbol, current_id);
+          context.m_found.function = true;
         }
       }
+    }
 
-      if (!context.m_found.function_with_type_info) {
-        // Try the modules next.
+    if (!context.m_found.function_with_type_info) {
+      // Try the modules next.
 
-        do {
-          if (ClangModulesDeclVendor *modules_decl_vendor =
-                  m_target->GetClangModulesDeclVendor()) {
-            bool append = false;
-            uint32_t max_matches = 1;
-            std::vector<clang::NamedDecl *> decls;
+      do {
+        if (ClangModulesDeclVendor *modules_decl_vendor =
+                m_target->GetClangModulesDeclVendor()) {
+          bool append = false;
+          uint32_t max_matches = 1;
+          std::vector<clang::NamedDecl *> decls;
 
-            if (!modules_decl_vendor->FindDecls(name, append, max_matches,
-                                                decls))
-              break;
+          if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
+            break;
 
-            clang::NamedDecl *const decl_from_modules = decls[0];
+          clang::NamedDecl *const decl_from_modules = decls[0];
 
-            if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
-              if (log) {
-                log->Printf("  CAS::FEVD[%u] Matching function found for "
-                            "\"%s\" in the modules",
-                            current_id, name.GetCString());
-              }
-
-              clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-                  m_ast_context, &decl_from_modules->getASTContext(),
-                  decl_from_modules);
-              clang::FunctionDecl *copied_function_decl =
-                  copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
-                              : nullptr;
-
-              if (!copied_function_decl) {
-                if (log)
-                  log->Printf("  CAS::FEVD[%u] - Couldn't export a function "
-                              "declaration from the modules",
-                              current_id);
+          if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
+            if (log) {
+              log->Printf("  CAS::FEVD[%u] Matching function found for "
+                          "\"%s\" in the modules",
+                          current_id, name.GetCString());
+            }
 
-                break;
-              }
+            clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+                m_ast_context, &decl_from_modules->getASTContext(),
+                decl_from_modules);
+            clang::FunctionDecl *copied_function_decl =
+                copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
+                            : nullptr;
+
+            if (!copied_function_decl) {
+              if (log)
+                log->Printf("  CAS::FEVD[%u] - Couldn't export a function "
+                            "declaration from the modules",
+                            current_id);
 
-              MaybeRegisterFunctionBody(copied_function_decl);
+              break;
+            }
 
-              context.AddNamedDecl(copied_function_decl);
+            MaybeRegisterFunctionBody(copied_function_decl);
 
-              context.m_found.function_with_type_info = true;
-              context.m_found.function = true;
-            } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
-              if (log) {
-                log->Printf("  CAS::FEVD[%u] Matching variable found for "
-                            "\"%s\" in the modules",
-                            current_id, name.GetCString());
-              }
-
-              clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
-                  m_ast_context, &decl_from_modules->getASTContext(),
-                  decl_from_modules);
-              clang::VarDecl *copied_var_decl =
-                  copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
-                              : nullptr;
-
-              if (!copied_var_decl) {
-                if (log)
-                  log->Printf("  CAS::FEVD[%u] - Couldn't export a variable "
-                              "declaration from the modules",
-                              current_id);
+            context.AddNamedDecl(copied_function_decl);
 
-                break;
-              }
+            context.m_found.function_with_type_info = true;
+            context.m_found.function = true;
+          } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
+            if (log) {
+              log->Printf("  CAS::FEVD[%u] Matching variable found for "
+                          "\"%s\" in the modules",
+                          current_id, name.GetCString());
+            }
 
-              context.AddNamedDecl(copied_var_decl);
+            clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+                m_ast_context, &decl_from_modules->getASTContext(),
+                decl_from_modules);
+            clang::VarDecl *copied_var_decl =
+                copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
+                            : nullptr;
+
+            if (!copied_var_decl) {
+              if (log)
+                log->Printf("  CAS::FEVD[%u] - Couldn't export a variable "
+                            "declaration from the modules",
+                            current_id);
 
-              context.m_found.variable = true;
+              break;
             }
-          }
-        } while (0);
-      }
 
-      if (target && !context.m_found.variable && !namespace_decl) {
-        // We couldn't find a non-symbol variable for this.  Now we'll hunt for
-        // a generic
-        // data symbol, and -- if it is found -- treat it as a variable.
-
-        const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
-
-        if (data_symbol) {
-          std::string warning("got name from symbols: ");
-          warning.append(name.AsCString());
-          const unsigned diag_id =
-              m_ast_context->getDiagnostics().getCustomDiagID(
-                  clang::DiagnosticsEngine::Level::Warning, "%0");
-          m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
-          AddOneGenericVariable(context, *data_symbol, current_id);
-          context.m_found.variable = true;
+            context.AddNamedDecl(copied_var_decl);
+
+            context.m_found.variable = true;
+          }
         }
+      } while (0);
+    }
+
+    if (target && !context.m_found.variable && !namespace_decl) {
+      // We couldn't find a non-symbol variable for this.  Now we'll hunt for
+      // a generic
+      // data symbol, and -- if it is found -- treat it as a variable.
+
+      const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
+
+      if (data_symbol) {
+        std::string warning("got name from symbols: ");
+        warning.append(name.AsCString());
+        const unsigned diag_id =
+            m_ast_context->getDiagnostics().getCustomDiagID(
+                clang::DiagnosticsEngine::Level::Warning, "%0");
+        m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
+        AddOneGenericVariable(context, *data_symbol, current_id);
+        context.m_found.variable = true;
       }
     }
   }




More information about the lldb-commits mailing list