[Lldb-commits] [PATCH] D115277: [lldb] Workaround for type-like entities defined in a lexical block

2021-12-07 Thread Kristina Bessonova via Phabricator via lldb-commits
krisb created this revision.
krisb added reviewers: jingham, aprantl, JDevlieghere.
Herald added a subscriber: pengfei.
krisb requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

D113741  and D113743 
 makes types defined in a lexical (bracketed) 
block
correctly scoped within this block, which reveals a lack of support of
such a case in lldb.

Consider the following example:

* thread #1, name = 'a.out', stop reason = step over
frame #0: 0x0040111d a.out`foo(a=1) at test_lldb.cpp:5:12
   1  int foo(int a) {
   2  {
   3typedef int Int;
   4Int local = a;
-> 5return local;
   6  }
   7}
   8
(lldb) p local
error: expression failed to parse:
error: :45:31: no member named 'local' in namespace 
'$__lldb_local_vars'
using $__lldb_local_vars::local;
  ^
error: :1:1: use of undeclared identifier 'local'
local
  ^

lldb failed to find 'local' variable typed with a lexical block defined type 
(typedef Int).
The immediate cause of this issue is that clang failed to import this typedef:

  lldb   (x86_64) a.out: DWARFASTParserClang::ParseTypeFromDWARF (die = 
0x0070, decl_ctx = 0x2509cb0 (die 0x0055)) DW_TAG_typedef name = 'Int')
  lldb   (x86_64) a.out: SymbolFileDWARF::ResolveTypeUID (die = 0x0070) 
DW_TAG_typedef 'Int'
  lldb   (x86_64) a.out: SymbolFileDWARF::ResolveTypeUID (die = 0x0096) 
DW_TAG_base_type 'int'
  lldb   Compiler diagnostic:
  
  lldb   Couldn't import type: UnsupportedConstruct
  lldb   Couldn't copy a variable's type into the parser's AST context

The importing wasn't success because clang wasn't able to import
typedef's context, which is actually a BlockDecl (import for BlockDecl isn't 
implemented,
but this is still a question to me why DW_TAG_lexical_block is associated with 
a BlockDecl).

This workaround makes everything behaves as it was before D113741 
 / D113743 .
While looking for a context for a type-like entity scoped within a lexical 
block,
GetDeclContextDIEContainingDIE() will return a DeclContext of a parent 
subprogram,
instead of a BlockDecl.

Despite the patch doesn't fix the issue properly, looks like a step
forward to me as lldb at least may now properly display variables of
such types, which may appear in the DWARF generated by other compilers
(gcc as an example).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115277

Files:
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp


Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2616,9 +2616,27 @@
 case DW_TAG_structure_type:
 case DW_TAG_union_type:
 case DW_TAG_class_type:
-case DW_TAG_lexical_block:
 case DW_TAG_subprogram:
   return die;
+case DW_TAG_lexical_block: {
+  if (orig_die.Tag() != DW_TAG_structure_type &&
+  orig_die.Tag() != DW_TAG_union_type &&
+  orig_die.Tag() != DW_TAG_class_type &&
+  orig_die.Tag() != DW_TAG_enumeration_type &&
+  orig_die.Tag() != DW_TAG_typedef)
+return die;
+  // Make local type's context to be a subprogram.
+  // FIXME: DWARFASTParserClang doesn't properly support type-like
+  // entities scoped within a lexical block. This workaround makes
+  // it possible to correctly display variables that have such a type,
+  // but lldb still isn't able to handle properly handle more than one
+  // local type with the same name.
+  while (true) {
+die = die.GetParent();
+if (die.Tag() == DW_TAG_subprogram)
+  return die;
+  }
+}
 case DW_TAG_inlined_subroutine: {
   DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
   if (abs_die) {


Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2616,9 +2616,27 @@
 case DW_TAG_structure_type:
 case DW_TAG_union_type:
 case DW_TAG_class_type:
-case DW_TAG_lexical_block:
 case DW_TAG_subprogram:
   return die;
+case DW_TAG_lexical_block: {
+  if (orig_die.Tag() != DW_TAG_structure_type &&
+  orig_die.Tag() != DW_TAG_union_type &&
+  orig_die.Tag() != DW_TAG_class_type &&
+  orig_d

[Lldb-commits] [PATCH] D115277: [lldb] Workaround for type-like entities defined in a lexical block

2021-12-08 Thread Kristina Bessonova via Phabricator via lldb-commits
krisb added a comment.

In D115277#3178248 , @jingham wrote:

> I worry this makes the case where a function has two definitions of the same 
> type in one function a more confusing error than the "can't find type" error 
> you would get without this patch.  Is this of sufficient urgency that we 
> can't take the time to fix it correctly?

No urgency at all, I just believe it makes things a bit better than we have now.
And I want D113741  gets relanded :)

Before D113741  (which gets reverted because 
of the aforementioned issue in lldb), there was an almost the same behavior as 
we would have if both D113741  and this patch 
applied.
I mean, before D113741 , clang always put 
types to their parent subprogram scope, no matter where they were actually 
defined. So we got all the types defined within a particular function emitted 
in the same scope which is the subprogram.
As expected, if we had two types in the same name defined in the same function, 
lldb could't properly display information about this type. But there were/are 
no issues with displaying variables types for such a case.
Here is an example:

  int main() {
int a = -1; 
if (a > 0) {
  typedef int Int;
  Int local = a;
  return a * local;
} else {
  typedef long Int;
  Int local = a;
  return a * local;
}
  }

Even if in the beginning of main we can access 'Int' and lldb will always 
display as it 'int', never 'long':

  * thread #1, name = 'a.out', stop reason = breakpoint 1.1
  frame #0: 0x0040111b a.out`main at test_lldb.cpp:2:7
 1  int main() {
  -> 2int a = -1;
 3if (a > 0) {
 4  typedef int Int;
 5  Int local = a;
 6  return a * local;
 7} else {
  (lldb) image lookup -t Int
  Best match found in /home/kbessonova/workspace/llvm/llvm-project/build/a.out:
  id = {0x006c}, name = "Int", byte-size = 4, decl = test_lldb.cpp:4, 
compiler_type = "typedef Int"
   typedef 'Int': id = {0x00a0}, name = "int", byte-size = 4, 
compiler_type = "int"

There are no issues with 'local':

  * thread #1, name = 'a.out', stop reason = step over
  frame #0: 0x00401141 a.out`main at test_lldb.cpp:9:17
 6  return a * local;
 7} else {
 8  typedef long Int;
  -> 9  Int local = a;
 10 return a * local;
 11   }
 12 }
  (lldb) p local
  (Int) $0 = 4198432 + 0i

And in scripting mode we can see its proper type:

  (lldb) script
  Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D.
  >>> var = lldb.frame.FindVariable("local")
  >>> type = var.GetType()
  >>> print(type)
  typedef Int
  >>> print(type.GetCanonicalType())
  long

So 'before D113741 ' == ' D113741 
 + D115277 
' with one difference: lldb would no longer 
report errors for variables which types are defined within a lexical block, 
which looks to me more valuable than having a proper type information from 
'image lookup -t'.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115277/new/

https://reviews.llvm.org/D115277

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D115277: [lldb] Workaround for type-like entities defined in a lexical block

2022-05-16 Thread Kristina Bessonova via Phabricator via lldb-commits
krisb abandoned this revision.
krisb added a comment.
Herald added a project: All.

Abandon for now.
Issue on gitlab: https://github.com/llvm/llvm-project/issues/54475


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115277/new/

https://reviews.llvm.org/D115277

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits