[Lldb-commits] [PATCH] D156774: [lldb][DWARFASTParserClang] Resolve nested types when parsing structures

2023-08-20 Thread Vlad Serebrennikov via Phabricator via lldb-commits
Endill added a comment.

I tested this patch together with the following new code:

  uint32_t TypeSystemClang::GetNumMemberEnums(lldb::opaque_compiler_type_t 
type) {
using EnumIt = clang::DeclContext::specific_decl_iterator;
if (!type)
  return 0;
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
clang::DeclContext *ctx = qual_type->getAsRecordDecl()->getDeclContext();
return std::distance(EnumIt(ctx->decls_begin()), EnumIt(ctx->decls_end()));
  }
  
  CompilerType
  TypeSystemClang::GetMemberEnumAtIndex(lldb::opaque_compiler_type_t type,
size_t index) {
using EnumIt = clang::DeclContext::specific_decl_iterator;
if (!type)
  return CompilerType();
  
clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));
clang::DeclContext *ctx = qual_type->getAsRecordDecl()->getDeclContext();
size_t enum_index = 0;
for (EnumIt enums_it(ctx->decls_begin()), enums_end(ctx->decls_end());
 enums_it != enums_end;
 ++enums_it, ++enum_index) {
if (enum_index == index) {
  return CompilerType(weak_from_this(), *enums_it);
}
}
  }

I created all the wrappers to make it available in Python. The result was 
unsatisfactory: this code doesn't even trigger 
`DWARFASTParserClang::ParseChildMembers` that this patch touches, and return 0 
instead of 1. This doesn't change even if I trigger `ParseChildMembers` via 
other means before asking for a number of member enums in a type.

Code I tested this on:

  using intptr_t = long;
  using uintptr_t = unsigned long;
  
  struct PointerIntPairInfo {
enum MaskAndShiftConstants : uintptr_t {
  PointerBitMask =
  ~(uintptr_t)(((intptr_t)1 << 3) - 1),
};
  
int a{};
  };
  
  static uintptr_t dummy() {
return PointerIntPairInfo::PointerBitMask;
  }
  
  int main()
  {
  PointerIntPairInfo p;
  __builtin_debugtrap();
  return p.a + foo();
  }

If you have any suggestions what I missed or did wrong, please let me know.

I'll continue with this patch nevertheless, but it's clear now that there's 
still a way to go until I can access that enum without going through slow 
expression evaluator.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156774

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


[Lldb-commits] [PATCH] D156774: [lldb][DWARFASTParserClang] Resolve nested types when parsing structures

2023-08-20 Thread Michael Buch via Phabricator via lldb-commits
Michael137 added a comment.

In D156774#4601705 , @Endill wrote:

> I tested this patch together with the following new code:
>
>   uint32_t TypeSystemClang::GetNumMemberEnums(lldb::opaque_compiler_type_t 
> type) {
> using EnumIt = 
> clang::DeclContext::specific_decl_iterator;
> if (!type)
>   return 0;
> clang::QualType qual_type = 
> RemoveWrappingTypes(GetCanonicalQualType(type));
> clang::DeclContext *ctx = qual_type->getAsRecordDecl()->getDeclContext();
> return std::distance(EnumIt(ctx->decls_begin()), 
> EnumIt(ctx->decls_end()));
>   }
>   
>   CompilerType
>   TypeSystemClang::GetMemberEnumAtIndex(lldb::opaque_compiler_type_t type,
> size_t index) {
> using EnumIt = 
> clang::DeclContext::specific_decl_iterator;
> if (!type)
>   return CompilerType();
>   
> clang::QualType qual_type = 
> RemoveWrappingTypes(GetCanonicalQualType(type));
> clang::DeclContext *ctx = qual_type->getAsRecordDecl()->getDeclContext();
> size_t enum_index = 0;
> for (EnumIt enums_it(ctx->decls_begin()), enums_end(ctx->decls_end());
>  enums_it != enums_end;
>  ++enums_it, ++enum_index) {
> if (enum_index == index) {
>   return CompilerType(weak_from_this(), *enums_it);
> }
> }
>   }
>
> I created all the wrappers to make it available in Python. The result was 
> unsatisfactory: this code doesn't even trigger 
> `DWARFASTParserClang::ParseChildMembers` that this patch touches, and return 
> 0 instead of 1. This doesn't change even if I trigger `ParseChildMembers` via 
> other means before asking for a number of member enums in a type.
>
> Code I tested this on:
>
>   using intptr_t = long;
>   using uintptr_t = unsigned long;
>   
>   struct PointerIntPairInfo {
> enum MaskAndShiftConstants : uintptr_t {
>   PointerBitMask =
>   ~(uintptr_t)(((intptr_t)1 << 3) - 1),
> };
>   
> int a{};
>   };
>   
>   static uintptr_t dummy() {
> return PointerIntPairInfo::PointerBitMask;
>   }
>   
>   int main()
>   {
>   PointerIntPairInfo p;
>   __builtin_debugtrap();
>   return p.a + foo();
>   }
>
> If you have any suggestions what I missed or did wrong, please let me know.
>
> I'll continue with this patch nevertheless, but it's clear now that there's 
> still a way to go until I can access that enum without going through slow 
> expression evaluator.

What were your lldb commands when you tested this?

LLDB currently completes types lazily when it thinks it can. Does your new API 
still fail if you run `expr p` prior? (the idea is that that would trigger 
completion of the type and parse dwarf). If we dont ever call 
`GetFullCompilerType` on your type LLDB will never try to pull in the definition


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156774

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


[Lldb-commits] [PATCH] D156774: [lldb][DWARFASTParserClang] Resolve nested types when parsing structures

2023-08-20 Thread Vlad Serebrennikov via Phabricator via lldb-commits
Endill updated this revision to Diff 551811.
Endill added a comment.

Follow the `DW_TAG_subprogram` approach for `DW_TAG_enum_type`, 
`DW_TAG_structure_type`, and `DW_TAG_union_type`: rely on `ParseType()` called 
afterwards instead of eagerly parsing them.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156774

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h


Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -157,7 +157,7 @@
   bool ParseChildMembers(
   const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
   std::vector> &base_classes,
-  std::vector &member_function_dies,
+  std::vector &member_function_and_type_dies,
   DelayedPropertyList &delayed_properties,
   const lldb::AccessType default_accessibility,
   lldb_private::ClangASTImporter::LayoutInfo &layout_info);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2149,14 +2149,14 @@
 
 std::vector> bases;
 // Parse members and base classes first
-std::vector member_function_dies;
+std::vector member_function_and_type_dies;
 
 DelayedPropertyList delayed_properties;
-ParseChildMembers(die, clang_type, bases, member_function_dies,
+ParseChildMembers(die, clang_type, bases, member_function_and_type_dies,
   delayed_properties, default_accessibility, layout_info);
 
-// Now parse any methods if there were any...
-for (const DWARFDIE &die : member_function_dies)
+// Now parse any methods or nested types if there were any...
+for (const DWARFDIE &die : member_function_and_type_dies)
   dwarf->ResolveType(die);
 
 if (type_is_objc_object_or_interface) {
@@ -2999,7 +2999,7 @@
 bool DWARFASTParserClang::ParseChildMembers(
 const DWARFDIE &parent_die, CompilerType &class_clang_type,
 std::vector> &base_classes,
-std::vector &member_function_dies,
+std::vector &member_function_and_type_dies,
 DelayedPropertyList &delayed_properties,
 const AccessType default_accessibility,
 ClangASTImporter::LayoutInfo &layout_info) {
@@ -3028,8 +3028,11 @@
   break;
 
 case DW_TAG_subprogram:
+case DW_TAG_enumeration_type:
+case DW_TAG_structure_type:
+case DW_TAG_union_type:
   // Let the type parsing code handle this one for us.
-  member_function_dies.push_back(die);
+  member_function_and_type_dies.push_back(die);
   break;
 
 case DW_TAG_inheritance:


Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -157,7 +157,7 @@
   bool ParseChildMembers(
   const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
   std::vector> &base_classes,
-  std::vector &member_function_dies,
+  std::vector &member_function_and_type_dies,
   DelayedPropertyList &delayed_properties,
   const lldb::AccessType default_accessibility,
   lldb_private::ClangASTImporter::LayoutInfo &layout_info);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2149,14 +2149,14 @@
 
 std::vector> bases;
 // Parse members and base classes first
-std::vector member_function_dies;
+std::vector member_function_and_type_dies;
 
 DelayedPropertyList delayed_properties;
-ParseChildMembers(die, clang_type, bases, member_function_dies,
+ParseChildMembers(die, clang_type, bases, member_function_and_type_dies,
   delayed_properties, default_accessibility, layout_info);
 
-// Now parse any methods if there were any...
-for (const DWARFDIE &die : member_function_dies)
+// Now parse any methods or nested types if there were any...
+for (const DWARFDIE &die : member_function_and_type_dies)
   dwarf->ResolveType(die);
 
 if (type_is_objc_object_or_interface) {
@@ -2999,7 +2999,7 @@
 bool DWARFASTParserClang::ParseChildMembers(
 const DWARFDIE &parent_die, CompilerType &class_clang_type,
 std::vector> &base_classes,
-std::vector &member_function_dies,
+std::vector &member_function_and_type_dies,
 Delay

[Lldb-commits] [PATCH] D156774: [lldb][DWARFASTParserClang] Resolve nested types when parsing structures

2023-08-20 Thread Vlad Serebrennikov via Phabricator via lldb-commits
Endill added a comment.

In D156774#4601736 , @Michael137 
wrote:

> What were your lldb commands when you tested this?

`script import lldb; frame = lldb.thread.GetFrameAtIndex(0); 
print(frame.variables[0].type.GetNumberOfMemberEnums())`

> LLDB currently completes types lazily when it thinks it can. Does your new 
> API still fail if you run `expr p` prior? (the idea is that that would 
> trigger completion of the type and parse dwarf). If we dont ever call 
> `GetFullCompilerType` on your type LLDB will never try to pull in the 
> definition

No amount of tinkering with `expr` makes `script 
print(frame.variables[0].type.GetNumberOfMemberEnums())` output a non-zero 
value.
I tested this with the changes I uploaded here half an hour ago.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156774

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


[Lldb-commits] [PATCH] D156774: [lldb][DWARFASTParserClang] Resolve nested types when parsing structures

2023-08-20 Thread Michael Buch via Phabricator via lldb-commits
Michael137 added a comment.

In D156774#4601767 , @Endill wrote:

> In D156774#4601736 , @Michael137 
> wrote:
>
>> What were your lldb commands when you tested this?
>
> `script import lldb; frame = lldb.thread.GetFrameAtIndex(0); 
> print(frame.variables[0].type.GetNumberOfMemberEnums())`
>
>> LLDB currently completes types lazily when it thinks it can. Does your new 
>> API still fail if you run `expr p` prior? (the idea is that that would 
>> trigger completion of the type and parse dwarf). If we dont ever call 
>> `GetFullCompilerType` on your type LLDB will never try to pull in the 
>> definition
>
> No amount of tinkering with `expr` makes `script 
> print(frame.variables[0].type.GetNumberOfMemberEnums())` output a non-zero 
> value.
> I tested this with the changes I uploaded here half an hour ago.



In D156774#4601767 , @Endill wrote:

> In D156774#4601736 , @Michael137 
> wrote:
>
>> What were your lldb commands when you tested this?
>
> `script import lldb; frame = lldb.thread.GetFrameAtIndex(0); 
> print(frame.variables[0].type.GetNumberOfMemberEnums())`
>
>> LLDB currently completes types lazily when it thinks it can. Does your new 
>> API still fail if you run `expr p` prior? (the idea is that that would 
>> trigger completion of the type and parse dwarf). If we dont ever call 
>> `GetFullCompilerType` on your type LLDB will never try to pull in the 
>> definition
>
> No amount of tinkering with `expr` makes `script 
> print(frame.variables[0].type.GetNumberOfMemberEnums())` output a non-zero 
> value.
> I tested this with the changes I uploaded here half an hour ago.

I think you may want to use `GetCompleteQualType` before iterating the 
DeclContext. That will make sure we complete the type by the time we look for 
the enums.

E.g.,:

  clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type));  
 
  if (GetCompleteQualType(&getASTContext(), qual_type)) {   
  
const clang::RecordType *record_type =  
   
llvm::cast(qual_type.getTypePtr());  
  
const clang::RecordDecl *record_decl = record_type->getDecl();  
   
assert(record_decl);
   
return std::distance(EnumIt(record_decl->decls_begin()), 
EnumIt(record_decl->decls_end())); 
  } 
   

Will review it more thoroughly on tomorrow though


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156774

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


[Lldb-commits] [PATCH] D156774: [lldb][DWARFASTParserClang] Resolve nested types when parsing structures

2023-08-20 Thread Vlad Serebrennikov via Phabricator via lldb-commits
Endill added a comment.

In D156774#4601830 , @Michael137 
wrote:

> I think you may want to use `GetCompleteQualType` before iterating the 
> DeclContext; that's how some of the other TypeSystemClang APIs do it. That 
> will make sure we complete the type by the time we look for the enums.

I tried to incorporate this function into my version of 
`GetNumberOfMemberEnums`, but it didn't work out.

> E.g.,:
>
>   clang::QualType qual_type = 
> RemoveWrappingTypes(GetCanonicalQualType(type));  
>  
>   if (GetCompleteQualType(&getASTContext(), qual_type)) { 
> 
> const clang::RecordType *record_type =
>  
> llvm::cast(qual_type.getTypePtr());
> 
> const clang::RecordDecl *record_decl = record_type->getDecl();
>  
> assert(record_decl);  
>  
> return std::distance(EnumIt(record_decl->decls_begin()), 
> EnumIt(record_decl->decls_end())); 
>   }   
>  
>
> Will review it more thoroughly on tomorrow though

But your version actually works, returning 1! Thank you very much!


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156774

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