sgraenitz created this revision.
sgraenitz added reviewers: aleksandr.urakov, rnk, teemperor, DavidSpickett, 
aprantl, zturner, jdoerfert.
Herald added a project: All.
sgraenitz requested review of this revision.
Herald added a project: LLDB.

Let the PDB parser recognize special ObjC type names like `objc_object` for the 
id type and `objc_selector` for selectors. With this change, ObjC support for 
PDB on Windows is on par with the Linux baseline test proposed in D146058 
<https://reviews.llvm.org/D146058>.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D146547

Files:
  lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
  lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
  lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
  lldb/test/Shell/Expr/objc-gnustep-print-pdb.m
  lldb/test/Shell/Expr/objc-gnustep-print.m

Index: lldb/test/Shell/Expr/objc-gnustep-print.m
===================================================================
--- lldb/test/Shell/Expr/objc-gnustep-print.m
+++ lldb/test/Shell/Expr/objc-gnustep-print.m
@@ -1,5 +1,4 @@
 // REQUIRES: objc-gnustep
-// XFAIL: system-windows
 //
 // RUN: %build %s --compiler=clang --objc-gnustep --output=%t
 
Index: lldb/test/Shell/Expr/objc-gnustep-print-pdb.m
===================================================================
--- lldb/test/Shell/Expr/objc-gnustep-print-pdb.m
+++ /dev/null
@@ -1,73 +0,0 @@
-// REQUIRES: objc-gnustep && system-windows
-//
-// RUN: %build %s --compiler=clang --objc-gnustep --output=%t
-
-#import "objc/runtime.h"
-
-@protocol NSCoding
-@end
-
-#ifdef __has_attribute
-#if __has_attribute(objc_root_class)
-__attribute__((objc_root_class))
-#endif
-#endif
-@interface NSObject<NSCoding> {
-  id isa;
-  int refcount;
-}
-@end
-@implementation NSObject
-- (id)class {
-  return object_getClass(self);
-}
-+ (id)new {
-  return class_createInstance(self, 0);
-}
-@end
-@interface TestObj : NSObject {
-  int _int;
-  float _float;
-  char _char;
-  void *_ptr_void;
-  NSObject *_ptr_nsobject;
-  id _id_objc;
-}
-- (int)ok;
-@end
-@implementation TestObj
-- (int)ok {
-  return self ? 0 : 1;
-}
-@end
-
-// RUN: %lldb -b -o "b objc-gnustep-print-pdb.m:72" -o "run" -o "p ptr" -o "p *ptr" -- %t | FileCheck %s
-//
-// CHECK: (lldb) b objc-gnustep-print-pdb.m:72
-// CHECK: Breakpoint {{.*}} at objc-gnustep-print-pdb.m:72
-//
-// CHECK: (lldb) run
-// CHECK: Process {{[0-9]+}} stopped
-// CHECK: frame #0: {{.*}}`main  at objc-gnustep-print-pdb.m:72
-//
-// CHECK: (lldb) p ptr
-// CHECK: (TestObj *) $0 = 0x{{[0-9]+}}
-//
-// CHECK: (lldb) p *ptr
-// CHECK: (TestObj) $1 = {
-// CHECK:   NSObject = {
-// CHECK:     isa = 0x{{[0-9]+}}
-// CHECK:     refcount
-// CHECK:   }
-// CHECK:   _int = 0
-// CHECK:   _float = 0
-// CHECK:   _char = '\0'
-// CHECK:   _ptr_void = 0x{{0+}}
-// CHECK:   _ptr_nsobject = nil
-// CHECK:   _id_objc = nil
-// CHECK: }
-
-int main() {
-  TestObj *ptr = [TestObj new];
-  return [ptr ok];
-}
Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -170,6 +170,8 @@
   void DumpClangAST(lldb_private::Stream &s) override;
 
   bool IsaNSObjectOrNSProxy(const llvm::pdb::PDBSymbolTypeUDT &udt) const;
+  bool IsObjCBuiltinTypeId(lldb::user_id_t sym_uid) const;
+  bool IsObjCBuiltinTypeSel(lldb::user_id_t sym_uid) const;
 
 private:
   struct SecContribInfo {
Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -2097,3 +2097,31 @@
   auto *pdb_base_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(pdb_base_raw_up.get());
   return IsaNSObjectOrNSProxy(*pdb_base_udt);
 }
+
+bool SymbolFilePDB::IsObjCBuiltinTypeId(user_id_t sym_uid) const {
+  std::unique_ptr<PDBSymbol> pdb_sym_up = m_session_up->getSymbolById(sym_uid);
+  if (pdb_sym_up->getSymTag() != PDB_SymType::UDT)
+    return false;
+
+  auto *pdb_sym_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(pdb_sym_up.get());
+  if (pdb_sym_udt->getName() != "id" &&
+      pdb_sym_udt->getName() != "objc_object")
+    return false;
+
+  return true;
+}
+
+bool SymbolFilePDB::IsObjCBuiltinTypeSel(user_id_t sym_uid) const {
+  std::unique_ptr<PDBSymbol> pdb_sym_up = m_session_up->getSymbolById(sym_uid);
+  if (pdb_sym_up->getSymTag() != PDB_SymType::UDT)
+    return false;
+
+  auto *pdb_sym_udt = llvm::dyn_cast<PDBSymbolTypeUDT>(pdb_sym_up.get());
+  if (pdb_sym_udt->getName() != "objc_selector")
+    return false;
+
+  // TODO: ObjC selectors exist only for ObjC functions and they never occur
+  // freestanding. Thus, we know that all instances of this UDT are defined
+  // within ObjCInterfaceDecls. Can we add a check for that?
+  return true;
+}
Index: lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -760,12 +760,32 @@
     auto *pointer_type = llvm::dyn_cast<PDBSymbolTypePointer>(&type);
     assert(pointer_type);
 
-    SymbolFile *symbol_file = m_ast.GetSymbolFile();
+    auto *symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile());
     if (!symbol_file)
       return nullptr;
 
-    Type *pointee_type = symbol_file->ResolveTypeUID(
-        pointer_type->getPointeeType()->getSymIndexId());
+    auto pdb_pointee_type = pointer_type->getPointeeType()->getSymIndexId();
+    if (symbol_file->IsObjCBuiltinTypeId(pdb_pointee_type)) {
+      // Clang emits id as objc_object* and we fill in the built-in "id" type
+      CompilerType id_type = m_ast.GetBasicType(eBasicTypeObjCID);
+      AddSourceInfoToDecl(type, decl);
+      return symbol_file->MakeType(
+          pointer_type->getSymIndexId(), ConstString("id"),
+          pointer_type->getLength(), nullptr, pdb_pointee_type,
+          lldb_private::Type::eEncodingIsUID, decl, id_type,
+          lldb_private::Type::ResolveState::Full);
+    }
+    if (symbol_file->IsObjCBuiltinTypeSel(pdb_pointee_type)) {
+      CompilerType id_type = m_ast.GetBasicType(eBasicTypeObjCSel);
+      AddSourceInfoToDecl(type, decl);
+      return symbol_file->MakeType(
+          pointer_type->getSymIndexId(), ConstString("SEL"),
+          pointer_type->getLength(), nullptr, pdb_pointee_type,
+          lldb_private::Type::eEncodingIsUID, decl, id_type,
+          lldb_private::Type::ResolveState::Full);
+    }
+
+    Type *pointee_type = symbol_file->ResolveTypeUID(pdb_pointee_type);
     if (!pointee_type)
       return nullptr;
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to