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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits