aprantl updated this revision to Diff 170526.
aprantl added a comment.

Factor out caching of types as suggested. Thanks!


https://reviews.llvm.org/D53530

Files:
  include/lldb/Symbol/SymbolFile.h
  include/lldb/Symbol/Variable.h
  packages/Python/lldbsuite/test/lang/c/vla/Makefile
  packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
  packages/Python/lldbsuite/test/lang/c/vla/main.c
  
source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
  source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
  source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
  source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
  source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
  source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
  source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
  source/Symbol/ClangASTContext.cpp

Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -3696,6 +3696,9 @@
       return IsPossibleDynamicType(
           llvm::cast<clang::ParenType>(qual_type)->desugar().getAsOpaquePtr(),
           dynamic_pointee_type, check_cplusplus, check_objc);
+
+    case clang::Type::IncompleteArray:
+      return true;
     default:
       break;
     }
Index: source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
===================================================================
--- source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
+++ source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h
@@ -79,7 +79,9 @@
   size_t
   ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
 
-  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+  lldb_private::Type *
+  ResolveTypeUID(lldb::user_id_t type_uid,
+                 const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   bool CompleteType(lldb_private::CompilerType &compiler_type) override;
 
Index: source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
===================================================================
--- source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -235,7 +235,8 @@
   return 0;
 }
 
-Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) {
+Type *SymbolFileSymtab::ResolveTypeUID(
+    lldb::user_id_t type_uid, const lldb_private::ExecutionContextRef exe_ctx) {
   return NULL;
 }
 
Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
===================================================================
--- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -84,7 +84,9 @@
   size_t
   ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
 
-  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+  lldb_private::Type *
+  ResolveTypeUID(lldb::user_id_t type_uid,
+                 const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   bool CompleteType(lldb_private::CompilerType &compiler_type) override;
 
Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
===================================================================
--- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -558,7 +558,9 @@
   return num_added;
 }
 
-lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
+lldb_private::Type *
+SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid,
+                              const lldb_private::ExecutionContextRef exe_ctx) {
   auto find_result = m_types.find(type_uid);
   if (find_result != m_types.end())
     return find_result->second.get();
Index: source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
===================================================================
--- source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -116,7 +116,9 @@
   ParseVariablesForContext(const lldb_private::SymbolContext &sc) override {
     return 0;
   }
-  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override {
+  lldb_private::Type *
+  ResolveTypeUID(lldb::user_id_t type_uid,
+                 const lldb_private::ExecutionContextRef exe_ctx) override {
     return nullptr;
   }
   bool CompleteType(lldb_private::CompilerType &compiler_type) override {
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -76,7 +76,9 @@
   size_t
   ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
 
-  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+  lldb_private::Type *
+  ResolveTypeUID(lldb::user_id_t type_uid,
+                 const lldb_private::ExecutionContextRef exe_ctx = {}) override;
   lldb_private::CompilerDeclContext
   GetDeclContextForUID(lldb::user_id_t uid) override;
   lldb_private::CompilerDeclContext
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -694,11 +694,12 @@
   return 0;
 }
 
-Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) {
+Type *SymbolFileDWARFDebugMap::ResolveTypeUID(
+    lldb::user_id_t type_uid, const lldb_private::ExecutionContextRef exe_ctx) {
   const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid);
   SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx);
   if (oso_dwarf)
-    return oso_dwarf->ResolveTypeUID(type_uid);
+    return oso_dwarf->ResolveTypeUID(type_uid, exe_ctx);
   return NULL;
 }
 
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -144,13 +144,16 @@
   size_t
   ParseVariablesForContext(const lldb_private::SymbolContext &sc) override;
 
-  lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
+  lldb_private::Type *
+  ResolveTypeUID(lldb::user_id_t type_uid,
+                 const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   bool CompleteType(lldb_private::CompilerType &compiler_type) override;
 
-  lldb_private::Type *ResolveType(const DWARFDIE &die,
-                                  bool assert_not_being_parsed = true,
-                                  bool resolve_function_context = false);
+  lldb_private::Type *
+  ResolveType(const DWARFDIE &die, bool assert_not_being_parsed = true,
+              bool resolve_function_context = false,
+              const lldb_private::ExecutionContextRef exe_ctx = {});
 
   SymbolFileDWARF *GetDWARFForUID(lldb::user_id_t uid);
 
@@ -371,7 +374,8 @@
                     bool parse_siblings, bool parse_children);
 
   lldb::TypeSP ParseType(const lldb_private::SymbolContext &sc,
-                         const DWARFDIE &die, bool *type_is_new);
+                         const DWARFDIE &die, bool *type_is_new,
+                         const lldb_private::ExecutionContextRef exe_ctx = {});
 
   lldb_private::Type *ResolveTypeUID(const DWARFDIE &die,
                                      bool assert_not_being_parsed);
@@ -404,8 +408,10 @@
   lldb_private::Symbol *
   GetObjCClassSymbol(const lldb_private::ConstString &objc_class_name);
 
-  lldb::TypeSP GetTypeForDIE(const DWARFDIE &die,
-                             bool resolve_function_context = false);
+  /// If exe_ctx is non-null, the type may only be valid within that context.
+  lldb::TypeSP
+  GetTypeForDIE(const DWARFDIE &die, bool resolve_function_context = false,
+                const lldb_private::ExecutionContextRef exe_ctx = {});
 
   void SetDebugMapModule(const lldb::ModuleSP &module_sp) {
     m_debug_map_module_wp = module_sp;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1362,23 +1362,23 @@
   return CompilerDeclContext();
 }
 
-Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) {
+Type *SymbolFileDWARF::ResolveTypeUID(
+    lldb::user_id_t type_uid, const lldb_private::ExecutionContextRef exe_ctx) {
   // Anytime we have a lldb::user_id_t, we must get the DIE by calling
   // SymbolFileDWARF::GetDIEFromUID(). See comments inside the
   // SymbolFileDWARF::GetDIEFromUID() for details.
   DWARFDIE type_die = GetDIEFromUID(type_uid);
   if (type_die)
-    return type_die.ResolveType();
-  else
-    return nullptr;
+    return ResolveType(type_die, true, false, exe_ctx);
+  return nullptr;
 }
 
 Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) {
   return ResolveType(GetDIE(die_ref), true);
 }
 
-Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die,
-                                      bool assert_not_being_parsed) {
+Type *SymbolFileDWARF::ResolveTypeUID(
+    const DWARFDIE &die, bool assert_not_being_parsed) {
   if (die) {
     Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
     if (log)
@@ -1486,11 +1486,12 @@
   return false;
 }
 
-Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
-                                   bool assert_not_being_parsed,
-                                   bool resolve_function_context) {
+Type *
+SymbolFileDWARF::ResolveType(const DWARFDIE &die, bool assert_not_being_parsed,
+                             bool resolve_function_context,
+                             const lldb_private::ExecutionContextRef exe_ctx) {
   if (die) {
-    Type *type = GetTypeForDIE(die, resolve_function_context).get();
+    Type *type = GetTypeForDIE(die, resolve_function_context, exe_ctx).get();
 
     if (assert_not_being_parsed) {
       if (type != DIE_IS_BEING_PARSED)
@@ -2592,33 +2593,37 @@
   return namespace_decl_ctx;
 }
 
-TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die,
-                                      bool resolve_function_context) {
-  TypeSP type_sp;
-  if (die) {
-    Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
-    if (type_ptr == NULL) {
-      CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
-      assert(lldb_cu);
-      SymbolContext sc(lldb_cu);
-      const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
-      while (parent_die != nullptr) {
-        if (parent_die->Tag() == DW_TAG_subprogram)
-          break;
-        parent_die = parent_die->GetParent();
-      }
-      SymbolContext sc_backup = sc;
-      if (resolve_function_context && parent_die != nullptr &&
-          !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
-        sc = sc_backup;
-
-      type_sp = ParseType(sc, die, NULL);
-    } else if (type_ptr != DIE_IS_BEING_PARSED) {
-      // Grab the existing type from the master types lists
-      type_sp = type_ptr->shared_from_this();
-    }
+TypeSP SymbolFileDWARF::GetTypeForDIE(
+    const DWARFDIE &die, bool resolve_function_context,
+    const lldb_private::ExecutionContextRef exe_ctx) {
+  if (!die)
+    return {};
+  Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
+  if (type_ptr == DIE_IS_BEING_PARSED)
+    return {};
+
+  // If an execution context is present, re-parse the type.
+  if (type_ptr && !exe_ctx.GetFrameSP()) {
+    // Grab the existing type from the master types lists
+    return type_ptr->shared_from_this();
   }
-  return type_sp;
+
+  // Parse the type.
+  CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
+  assert(lldb_cu);
+  SymbolContext sc(lldb_cu);
+  const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
+  while (parent_die) {
+    if (parent_die->Tag() == DW_TAG_subprogram)
+      break;
+    parent_die = parent_die->GetParent();
+  }
+  SymbolContext sc_backup = sc;
+  if (resolve_function_context && parent_die &&
+      !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc))
+    sc = sc_backup;
+
+  return ParseType(sc, die, NULL, exe_ctx);
 }
 
 DWARFDIE
@@ -3000,8 +3005,10 @@
   return type_sp;
 }
 
-TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
-                                  bool *type_is_new_ptr) {
+TypeSP
+SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
+                           bool *type_is_new_ptr,
+                           const lldb_private::ExecutionContextRef exe_ctx) {
   TypeSP type_sp;
 
   if (die) {
@@ -3012,10 +3019,11 @@
       DWARFASTParser *dwarf_ast = type_system->GetDWARFParser();
       if (dwarf_ast) {
         Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
-        type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr);
+        type_sp = dwarf_ast->ParseTypeFromDWARF(sc, die, log, type_is_new_ptr,
+                                                exe_ctx);
         if (type_sp) {
           TypeList *type_list = GetTypeList();
-          if (type_list)
+          if (type_list && !exe_ctx.GetFrameSP())
             type_list->Insert(type_sp);
 
           if (die.Tag() == DW_TAG_subprogram) {
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h
@@ -22,9 +22,10 @@
 
   lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die);
 
-  lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
-                                  const DWARFDIE &die, lldb_private::Log *log,
-                                  bool *type_is_new_ptr) override;
+  lldb::TypeSP ParseTypeFromDWARF(
+    const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+    lldb_private::Log *log, bool *type_is_new_ptr,
+    const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   lldb_private::Function *
   ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp
@@ -53,10 +53,9 @@
                                 decl, compiler_type, Type::eResolveStateFull);
 }
 
-lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc,
-                                                     const DWARFDIE &die,
-                                                     Log *log,
-                                                     bool *type_is_new_ptr) {
+lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(
+    const SymbolContext &sc, const DWARFDIE &die, Log *log,
+    bool *type_is_new_ptr, const lldb_private::ExecutionContextRef exe_ctx) {
   if (type_is_new_ptr)
     *type_is_new_ptr = false;
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h
@@ -32,9 +32,10 @@
   DWARFASTParserJava(lldb_private::JavaASTContext &ast);
   ~DWARFASTParserJava() override;
 
-  lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
-                                  const DWARFDIE &die, lldb_private::Log *log,
-                                  bool *type_is_new_ptr) override;
+  lldb::TypeSP ParseTypeFromDWARF(
+     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+     lldb_private::Log *log, bool *type_is_new_ptr,
+     const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   lldb_private::Function *
   ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
@@ -276,7 +276,8 @@
 
 lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF(
     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
-    lldb_private::Log *log, bool *type_is_new_ptr) {
+    lldb_private::Log *log, bool *type_is_new_ptr,
+    const lldb_private::ExecutionContextRef exe_ctx) {
   if (type_is_new_ptr)
     *type_is_new_ptr = false;
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h
@@ -33,9 +33,10 @@
 
   ~DWARFASTParserGo() override;
 
-  lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
-                                  const DWARFDIE &die, lldb_private::Log *log,
-                                  bool *type_is_new_ptr) override;
+  lldb::TypeSP ParseTypeFromDWARF(
+    const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+    lldb_private::Log *log, bool *type_is_new_ptr,
+    const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   lldb_private::Function *
   ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -49,7 +49,8 @@
 
 TypeSP DWARFASTParserGo::ParseTypeFromDWARF(
     const lldb_private::SymbolContext &sc, const DWARFDIE &die,
-    lldb_private::Log *log, bool *type_is_new_ptr) {
+    lldb_private::Log *log, bool *type_is_new_ptr,
+    const lldb_private::ExecutionContextRef exe_ctx) {
   TypeSP type_sp;
 
   if (type_is_new_ptr)
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -28,17 +28,19 @@
 
 class DWARFDebugInfoEntry;
 class DWARFDIECollection;
+class SymbolFileDWARF;
 
 class DWARFASTParserClang : public DWARFASTParser {
 public:
   DWARFASTParserClang(lldb_private::ClangASTContext &ast);
 
   ~DWARFASTParserClang() override;
 
   // DWARFASTParser interface.
-  lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
-                                  const DWARFDIE &die, lldb_private::Log *log,
-                                  bool *type_is_new_ptr) override;
+  lldb::TypeSP ParseTypeFromDWARF(
+      const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+      lldb_private::Log *log, bool *type_is_new_ptr,
+      const lldb_private::ExecutionContextRef exe_ctx = {}) override;
 
   lldb_private::Function *
   ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
@@ -64,7 +66,7 @@
 
 protected:
   class DelayedAddObjCClassProperty;
-  typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+ typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
 
   clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
 
@@ -104,7 +106,8 @@
   void ParseChildArrayInfo(const lldb_private::SymbolContext &sc,
                            const DWARFDIE &parent_die, int64_t &first_index,
                            std::vector<uint64_t> &element_orders,
-                           uint32_t &byte_stride, uint32_t &bit_stride);
+                           uint32_t &byte_stride, uint32_t &bit_stride,
+                           const lldb_private::ExecutionContextRef exe_ctx);
 
   size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc,
                                lldb_private::CompilerType &compiler_type,
@@ -131,7 +134,14 @@
 
   void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
 
-  lldb::TypeSP ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log);
+  /// Put this type into the uniqued list up at the module level and
+  /// cache it if requested.
+  void RegisterType(SymbolFileDWARF *dwarf, const DWARFDebugInfoEntry *die,
+                    lldb::TypeSP type_sp, bool should_cache);
+
+  lldb::TypeSP
+  ParseTypeFromDWO(const DWARFDIE &die, lldb_private::Log *log,
+                   const lldb_private::ExecutionContextRef exe_ctx = {});
 
   //----------------------------------------------------------------------
   // Return true if this type is a declaration to a type in an external
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -15,6 +15,7 @@
 #include "DWARFDebugInfo.h"
 #include "DWARFDeclContext.h"
 #include "DWARFDefines.h"
+#include "LogChannelDWARF.h"
 #include "SymbolFileDWARF.h"
 #include "SymbolFileDWARFDwo.h"
 #include "SymbolFileDWARFDebugMap.h"
@@ -137,7 +138,21 @@
   return false;
 }
 
-TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
+void DWARFASTParserClang::RegisterType(SymbolFileDWARF *dwarf,
+                                       const DWARFDebugInfoEntry *die,
+                                       TypeSP type_sp, bool should_cache) {
+  dwarf->GetTypeList()->Insert(type_sp);
+  // Cache the type if it isn't context-specific.
+  auto &cache = dwarf->GetDIEToType();
+  if (should_cache)
+    cache.insert({die, type_sp.get()});
+  else
+    cache.erase(die);
+}
+
+TypeSP DWARFASTParserClang::ParseTypeFromDWO(
+    const DWARFDIE &die, Log *log,
+    const lldb_private::ExecutionContextRef exe_ctx) {
   ModuleSP dwo_module_sp = die.GetContainingDWOModule();
   if (!dwo_module_sp)
     return TypeSP();
@@ -168,7 +183,7 @@
   if (num_dwo_types != 1)
     return TypeSP();
 
-  // We found a real definition for this type in the Clang module, so lets use
+  // We found a real definition for this type in the Clang module, so let's use
   // it and cache the fact that we found a complete type for this die.
   TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
   if (!dwo_type_sp)
@@ -188,8 +203,7 @@
       NULL, LLDB_INVALID_UID, Type::eEncodingInvalid,
       &dwo_type_sp->GetDeclaration(), type, Type::eResolveStateForward));
 
-  dwarf->GetTypeList()->Insert(type_sp);
-  dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+  RegisterType(dwarf, die.GetDIE(), type_sp, (bool)exe_ctx.GetFrameSP());
   clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
   if (tag_decl)
     LinkDeclContextToDIE(tag_decl, die);
@@ -228,9 +242,9 @@
   }
 }
 
-TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
-                                               const DWARFDIE &die, Log *log,
-                                               bool *type_is_new_ptr) {
+TypeSP DWARFASTParserClang::ParseTypeFromDWARF(
+    const SymbolContext &sc, const DWARFDIE &die, Log *log,
+    bool *type_is_new_ptr, const lldb_private::ExecutionContextRef exe_ctx) {
   TypeSP type_sp;
 
   if (type_is_new_ptr)
@@ -251,8 +265,8 @@
           context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
     }
     Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
-    TypeList *type_list = dwarf->GetTypeList();
-    if (type_ptr == NULL) {
+    // If an execution context is present, re-parse the type.
+    if (type_ptr == NULL || exe_ctx.GetFrameSP()) {
       if (type_is_new_ptr)
         *type_is_new_ptr = true;
 
@@ -1736,7 +1750,7 @@
           if (element_type) {
             std::vector<uint64_t> element_orders;
             ParseChildArrayInfo(sc, die, first_index, element_orders,
-                                byte_stride, bit_stride);
+                                byte_stride, bit_stride, exe_ctx);
             if (byte_stride == 0 && bit_stride == 0)
               byte_stride = element_type->GetByteSize();
             CompilerType array_element_type =
@@ -1885,11 +1899,7 @@
           type_sp->SetSymbolContextScope(symbol_context_scope);
         }
 
-        // We are ready to put this type into the uniqued list up at the module
-        // level
-        type_list->Insert(type_sp);
-
-        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+        RegisterType(dwarf, die.GetDIE(), type_sp, (bool)exe_ctx.GetFrameSP());
       }
     } else if (type_ptr != DIE_IS_BEING_PARSED) {
       type_sp = type_ptr->shared_from_this();
@@ -3442,7 +3452,7 @@
 void DWARFASTParserClang::ParseChildArrayInfo(
     const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
     std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
-    uint32_t &bit_stride) {
+    uint32_t &bit_stride, const lldb_private::ExecutionContextRef exe_ctx) {
   if (!parent_die)
     return;
 
@@ -3468,7 +3478,25 @@
               break;
 
             case DW_AT_count:
-              num_elements = form_value.Unsigned();
+              if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) {
+                if (var_die.Tag() == DW_TAG_variable)
+                  if (auto frame = exe_ctx.GetFrameSP()) {
+                    Status error;
+                    lldb::VariableSP var_sp;
+                    auto valobj_sp = frame->GetValueForVariableExpressionPath(
+                        var_die.GetName(), eNoDynamicValues, 0, var_sp, error);
+                    if (valobj_sp) {
+                      num_elements = valobj_sp->GetValueAsUnsigned(0);
+                      if (auto log = LogChannelDWARF::GetLogIfAll(
+                              DWARF_LOG_DEBUG_INFO))
+                        log->Printf("Reparsing array type; dynamic size=%lld",
+                                    num_elements);
+
+                      break;
+                    }
+                  }
+              } else
+                num_elements = form_value.Unsigned();
               break;
 
             case DW_AT_bit_stride:
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -14,17 +14,18 @@
 #include "lldb/Core/PluginInterface.h"
 #include "lldb/Symbol/CompilerDecl.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Target/ExecutionContext.h"
 
 class DWARFDIE;
 
 class DWARFASTParser {
 public:
   virtual ~DWARFASTParser() {}
 
-  virtual lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
-                                          const DWARFDIE &die,
-                                          lldb_private::Log *log,
-                                          bool *type_is_new_ptr) = 0;
+  virtual lldb::TypeSP
+  ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, const DWARFDIE &die,
+                     lldb_private::Log *log, bool *type_is_new_ptr,
+                     const lldb_private::ExecutionContextRef exe_ctx = {}) = 0;
 
   virtual lldb_private::Function *
   ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc,
Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
===================================================================
--- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -23,6 +23,7 @@
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/Variable.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/SectionLoadList.h"
@@ -207,16 +208,32 @@
   if (!CouldHaveDynamicValue(in_value))
     return false;
 
+  ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
+  
+  // Handle variables with incomplete array types.
+  auto *type = in_value.GetCompilerType().GetOpaqueQualType();
+  auto qual_type = clang::QualType::getFromOpaquePtr(type).getCanonicalType();
+  if (qual_type->getTypeClass() == clang::Type::IncompleteArray) {
+    if (auto variable = in_value.GetVariable()) {
+      auto *lldb_type = variable->GetType();
+      auto *symbol_file = lldb_type->GetSymbolFile();
+      auto uid = lldb_type->GetID();
+      if (auto dyn_type = symbol_file->ResolveTypeUID(uid, exe_ctx)) {
+        class_type_or_name.SetCompilerType(dyn_type->GetFullCompilerType());
+        value_type = Value::ValueType::eValueTypeLoadAddress;
+        dynamic_address = in_value.GetAddressOf();
+        return true;
+      }
+    }
+  }
+
   // First job, pull out the address at 0 offset from the object.
   AddressType address_type;
   lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type);
   if (original_ptr == LLDB_INVALID_ADDRESS)
     return false;
 
-  ExecutionContext exe_ctx(in_value.GetExecutionContextRef());
-
   Process *process = exe_ctx.GetProcessPtr();
-
   if (process == nullptr)
     return false;
 
Index: packages/Python/lldbsuite/test/lang/c/vla/main.c
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/lang/c/vla/main.c
@@ -0,0 +1,15 @@
+void pause() {}
+
+int foo(int a) {
+  int vla[a];
+
+  for (int i = 0; i < a; ++i)
+    vla[i] = i;
+
+  pause(); // break here
+  return vla[a-1];
+}
+
+int main (void) {
+  return foo(2) + foo(4);
+}
Index: packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/lang/c/vla/TestVLA.py
@@ -0,0 +1,26 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.lldbutil as lldbutil
+
+
+class TestVLA(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def test_vla(self):
+        self.build()
+        _, process, _, _ = lldbutil.run_to_source_breakpoint(
+            self, "break here", lldb.SBFileSpec('main.c'))
+
+        for i in range(2):
+            self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%i])
+            self.expect("expr vla[%d]"%i, substrs=["int", "%d"%i])
+        array = ["int [2]", "1", "2"]
+        self.expect("fr v -d run-target -- vla", substrs=array)
+
+        process.Continue()
+        for i in range(4):
+            self.expect("fr v vla[%d]"%i, substrs=["int", "%d"%i])
+            self.expect("expr vla[%d]"%i, substrs=["int", "%d"%i])
+        array = ["int [4]", "1", "2", "3", "4"]
+        self.expect("fr v -d run-target -- vla", substrs=array)
Index: packages/Python/lldbsuite/test/lang/c/vla/Makefile
===================================================================
--- /dev/null
+++ packages/Python/lldbsuite/test/lang/c/vla/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
Index: include/lldb/Symbol/Variable.h
===================================================================
--- include/lldb/Symbol/Variable.h
+++ include/lldb/Symbol/Variable.h
@@ -64,7 +64,7 @@
   bool NameMatches(const RegularExpression &regex) const;
 
   Type *GetType();
-
+ 
   lldb::LanguageType GetLanguage() const;
 
   lldb::ValueType GetScope() const { return m_scope; }
Index: include/lldb/Symbol/SymbolFile.h
===================================================================
--- include/lldb/Symbol/SymbolFile.h
+++ include/lldb/Symbol/SymbolFile.h
@@ -128,7 +128,9 @@
   virtual size_t ParseFunctionBlocks(const SymbolContext &sc) = 0;
   virtual size_t ParseTypes(const SymbolContext &sc) = 0;
   virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0;
-  virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0;
+  virtual Type *
+  ResolveTypeUID(lldb::user_id_t type_uid,
+                 const lldb_private::ExecutionContextRef exe_ctx = {}) = 0;
   virtual bool CompleteType(CompilerType &compiler_type) = 0;
   virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {}
   virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to