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