aprantl created this revision.
aprantl added reviewers: jasonmolenda, JDevlieghere, labath, clayborg.

I'm planning to modify this API shortly and thought best to first make it 
independently testable.

This adds a -compiler-context=<...> option to lldb-test that translates a 
JSON-formatted string that is a list of kind/name pairs and translates it into 
a std::vector<CompilerContext>, a CompilerContext being a pair of context-kind 
and name.


https://reviews.llvm.org/D66453

Files:
  lldb/lit/SymbolFile/DWARF/compilercontext.ll
  lldb/lit/SymbolFile/DWARF/compilercontext.test
  lldb/tools/lldb-test/lldb-test.cpp

Index: lldb/tools/lldb-test/lldb-test.cpp
===================================================================
--- lldb/tools/lldb-test/lldb-test.cpp
+++ lldb/tools/lldb-test/lldb-test.cpp
@@ -30,6 +30,7 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/CleanUp.h"
 #include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/JSON.h"
 #include "lldb/Utility/State.h"
 #include "lldb/Utility/StreamString.h"
 
@@ -139,6 +140,11 @@
             cl::desc("Restrict search to the context of the given variable."),
             cl::value_desc("variable"), cl::sub(SymbolsSubcommand));
 
+static cl::opt<std::string> CompilerContext(
+    "compiler-context",
+    cl::desc("Specify a compiler context as \"[(type,name),...]\"."),
+    cl::value_desc("context"), cl::sub(SymbolsSubcommand));
+
 static cl::list<FunctionNameType> FunctionNameFlags(
     "function-flags", cl::desc("Function search flags:"),
     cl::values(clEnumValN(eFunctionNameTypeAuto, "auto",
@@ -220,6 +226,62 @@
 
 } // namespace opts
 
+std::vector<CompilerContext> parseCompilerContext() {
+  std::vector<CompilerContext> result;
+  if (opts::symbols::CompilerContext.empty())
+    return result;
+
+  JSONParser parser(StringRef{opts::symbols::CompilerContext});
+  auto val = parser.ParseJSONValue();
+  auto array = dyn_cast_or_null<JSONArray>(val.get());
+  if (!array) {
+    WithColor::error() << "compiler context is not a JSON array\n";
+    exit(1);
+  }
+  for (unsigned i = 0; i < array->GetNumElements(); ++i) {
+    auto val = array->GetObject(i);
+    auto entry = dyn_cast<JSONObject>(val.get());
+    if (!entry) {
+      WithColor::error() << "compiler context entry is not a JSON object\n";
+      exit(1);
+    }
+    auto kind_val =
+        dyn_cast_or_null<JSONString>(entry->GetObject("kind").get());
+    if (!kind_val) {
+      WithColor::error() << "compiler context entry has no \"kind\"\n";
+      exit(1);
+    }
+    auto kind =
+        StringSwitch<CompilerContextKind>(kind_val->GetData())
+            .Case("TranslationUnit", CompilerContextKind::TranslationUnit)
+            .Case("Module", CompilerContextKind::Module)
+            .Case("Namespace", CompilerContextKind::Namespace)
+            .Case("Class", CompilerContextKind::Class)
+            .Case("Structure", CompilerContextKind::Structure)
+            .Case("Union", CompilerContextKind::Union)
+            .Case("Function", CompilerContextKind::Function)
+            .Case("Variable", CompilerContextKind::Variable)
+            .Case("Enumeration", CompilerContextKind::Enumeration)
+            .Case("Typedef", CompilerContextKind::Typedef)
+            .Default(CompilerContextKind::Invalid);
+    auto name_val =
+        dyn_cast_or_null<JSONString>(entry->GetObject("name").get());
+    if (!name_val) {
+      WithColor::error() << "compiler context entry has no \"name\"\n";
+      exit(1);
+    }
+    result.push_back({kind, ConstString{name_val->GetData()}});
+  }
+  outs() << "Search context: {\n";
+  for (auto entry: result) {
+    outs() << " " << (unsigned)entry.type;
+    outs() << " \"" << entry.name.GetStringRef() << "\"\n";
+  }
+  outs() << "}\n";
+
+  return result;
+}
+
 template <typename... Args>
 static Error make_string_error(const char *Format, Args &&... args) {
   return llvm::make_error<llvm::StringError>(
@@ -464,8 +526,11 @@
 
   DenseSet<SymbolFile *> SearchedFiles;
   TypeMap Map;
-  Symfile.FindTypes(ConstString(Name), ContextPtr, true, UINT32_MAX,
-                   SearchedFiles, Map);
+  if (!Name.empty())
+    Symfile.FindTypes(ConstString(Name), ContextPtr, true, UINT32_MAX,
+                      SearchedFiles, Map);
+  else
+    Symfile.FindTypes(parseCompilerContext(), true, Map);
 
   outs() << formatv("Found {0} types:\n", Map.GetSize());
   StreamString Stream;
@@ -679,6 +744,9 @@
     if (Regex || !File.empty() || Line != 0)
       return make_string_error("Cannot search for types using regular "
                                "expressions, file names or line numbers.");
+    if (!Name.empty() && !CompilerContext.empty())
+      return make_string_error("Name is ignored if compiler context present.");
+
     return findTypes;
 
   case FindType::Variable:
Index: lldb/lit/SymbolFile/DWARF/compilercontext.test
===================================================================
--- /dev/null
+++ lldb/lit/SymbolFile/DWARF/compilercontext.test
@@ -0,0 +1,11 @@
+Test finding types by CompilerContext.
+RUN: llc %S/compilercontext.ll -filetype=obj -o %t.o
+RUN: lldb-test symbols %t.o -find=type -compiler-context='[{"kind":"Module","name":"CModule"},{"kind":"Module","name":"SubModule"},{"kind":"Structure","name":"FromSubmodule"}]' | FileCheck %s
+
+
+CHECK: Found 1 types:
+CHECK: struct FromSubmodule {
+CHECK-NEXT:     unsigned int x;
+CHECK-NEXT:     unsigned int y;
+CHECK-NEXT:     unsigned int z;
+CHECK-NEXT: }
Index: lldb/lit/SymbolFile/DWARF/compilercontext.ll
===================================================================
--- /dev/null
+++ lldb/lit/SymbolFile/DWARF/compilercontext.ll
@@ -0,0 +1,23 @@
+; This simulates the debug info for a Clang module.
+source_filename = "/t.c"
+target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.14.0"
+
+!llvm.dbg.cu = !{!2}
+!llvm.linker.options = !{}
+!llvm.module.flags = !{!18, !19}
+!llvm.ident = !{!22}
+
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, nameTableKind: GNU, retainedTypes: !{!11})
+!3 = !DIFile(filename: "t.c", directory: "/")
+!8 = !DIModule(scope: !9, name: "SubModule", includePath: "", isysroot: "/")
+!9 = !DIModule(scope: null, name: "CModule", includePath: "", isysroot: "/")
+!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "FromSubmodule", scope: !8, file: !3, line: 1, size: 96, elements: !13)
+!13 = !{!14, !16, !17}
+!14 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !11, file: !3, line: 2, baseType: !15, size: 32)
+!15 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
+!16 = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: !11, file: !3, line: 2, baseType: !15, size: 32, offset: 32)
+!17 = !DIDerivedType(tag: DW_TAG_member, name: "z", scope: !11, file: !3, line: 2, baseType: !15, size: 32, offset: 64)
+!18 = !{i32 2, !"Dwarf Version", i32 4}
+!19 = !{i32 2, !"Debug Info Version", i32 3}
+!22 = !{!"clang version 10.0.0 (https://github.com/llvm/llvm-project 056f1b5cc7c2133f0cb3e30e7f24808d321096d7)"}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to