[lldb] Add typedefs to the DeclContext they are created in
authorPavel Labath <pavel@labath.sk>
Tue, 18 Aug 2020 13:46:26 +0000 (15:46 +0200)
committerPavel Labath <pavel@labath.sk>
Wed, 19 Aug 2020 12:57:43 +0000 (14:57 +0200)
TypeSystemClang::CreateTypedef was creating a typedef in the right
DeclContext, but it was not actually adding it as a child of the
context. The resulting inconsistent state meant that we would be unable
to reference the typedef from an expression directly, but we could use
them if they end up being pulled in by some previous subexpression
(because the ASTImporter will set up the correct links in the expression
ast).

This patch adds the typedef to the decl context it is created in.

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

lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
lldb/test/API/lang/cpp/typedef/TestCppTypedef.py
lldb/test/API/lang/cpp/typedef/main.cpp

index 724826d..d8616ef 100644 (file)
@@ -2538,6 +2538,7 @@ FileCheck output:
         value_check = ValueCheck(type=result_type, value=result_value,
                                  summary=result_summary, children=result_children)
         value_check.check_value(self, eval_result, str(eval_result))
+        return eval_result
 
     def invoke(self, obj, name, trace=False):
         """Use reflection to call a method dynamically with no argument."""
index 608cdc2..d80d075 100644 (file)
@@ -4495,6 +4495,7 @@ CompilerType TypeSystemClang::CreateTypedef(
         clang_ast, decl_ctx, clang::SourceLocation(), clang::SourceLocation(),
         &clang_ast.Idents.get(typedef_name),
         clang_ast.getTrivialTypeSourceInfo(qual_type));
+    decl_ctx->addDecl(decl);
     SetOwningModule(decl, TypePayloadClang(payload).GetOwningModule());
 
     clang::TagDecl *tdecl = nullptr;
index 2aa2bcf..35a2fba 100644 (file)
@@ -29,8 +29,16 @@ class TestCppTypedef(TestBase):
 
         # First of all, check that we can get a typedefed type correctly in a simple case
 
-        expr_result = frame.EvaluateExpression("(SF)s")
-        self.assertTrue(expr_result.IsValid(), "Expression failed with: " + str(expr_result.GetError()))
+        expr_result = self.expect_expr("(SF)s", result_children=[ValueCheck(value="0.5")])
+        self.expect_expr("(ns::SF)s", result_children=[ValueCheck(value="0.5")])
+        self.expect_expr("(ST::SF)s", result_children=[ValueCheck(value="0.5")])
+
+        self.filecheck("image dump ast a.out", __file__, "--strict-whitespace")
+# CHECK:      {{^}}|-TypedefDecl {{.*}} SF 'S<float>'
+# CHECK:      {{^}}|-NamespaceDecl {{.*}} ns
+# CHECK-NEXT: {{^}}| `-TypedefDecl {{.*}} SF 'S<float>'
+# CHECK:      {{^}}`-CXXRecordDecl {{.*}} struct ST definition
+# CHECK:      {{^}}  `-TypedefDecl {{.*}} SF 'S<float>'
 
         typedef_type = expr_result.GetType();
         self.assertTrue(typedef_type.IsValid(), "Can't get `SF` type of evaluated expression")
index f1407b6..0575786 100644 (file)
@@ -7,7 +7,16 @@ struct S {
 
 typedef S<float> SF;
 
+namespace ns {
+typedef S<float> SF;
+}
+struct ST {
+  typedef S<float> SF;
+};
+
 int main (int argc, char const *argv[]) {
   SF s{ .5 };
+  ns::SF in_ns;
+  ST::SF in_struct;
   return 0; // Set a breakpoint here
 }