JDevlieghere updated this revision to Diff 151591. JDevlieghere added a comment.
- Use type cache & - Simplify method cache struct - Add custom test that verifies category methods are emitted https://reviews.llvm.org/D48241 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGDebugInfo.h clang/test/CodeGenObjC/debug-info-category.m
Index: clang/test/CodeGenObjC/debug-info-category.m =================================================================== --- /dev/null +++ clang/test/CodeGenObjC/debug-info-category.m @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -dwarf-version=5 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefix CHECK --check-prefix DWARF5 +// RUN: %clang_cc1 -dwarf-version=4 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s --check-prefix CHECK --check-prefix DWARF4 + +@interface Foo { + int integer; +} + +- (int)integer; +- (id)integer:(int)_integer; +@end + +@implementation Foo +- (int)integer { + return integer; +} + +- (id)integer:(int)_integer { + integer = _integer; + return self; +} +@end + +@interface Foo (Bar) +- (id)add:(Foo *)addend; +@end + +@implementation Foo (Bar) +- (id)add:(Foo *)addend { + return [self integer:[self integer] + [addend integer]]; +} +@end + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Foo" + +// DWARF5: = !DISubprogram(name: "-[Foo integer]"{{.*}}isDefinition: false +// DWARF5: = !DISubprogram(name: "-[Foo integer:]"{{.*}}isDefinition: false +// DWARF5: = !DISubprogram(name: "-[Foo(Bar) add:]"{{.*}}isDefinition: false + +// DWARF4-NOT: = !DISubprogram(name: "-[Foo integer]"{{.*}}isDefinition: false +// DWARF4-NOT: = !DISubprogram(name: "-[Foo integer:]"{{.*}}isDefinition: false +// DWARF4-NOT: = !DISubprogram(name: "-[Foo(Bar) add:]"{{.*}}isDefinition: false + +// CHECK: = distinct !DISubprogram(name: "-[Foo integer]"{{.*}}isDefinition: true +// CHECK: = distinct !DISubprogram(name: "-[Foo integer:]"{{.*}}isDefinition: true +// CHECK: = distinct !DISubprogram(name: "-[Foo(Bar) add:]"{{.*}}isDefinition: true Index: clang/lib/CodeGen/CGDebugInfo.h =================================================================== --- clang/lib/CodeGen/CGDebugInfo.h +++ clang/lib/CodeGen/CGDebugInfo.h @@ -98,6 +98,15 @@ /// Cache of previously constructed interfaces which may change. llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache; + struct ObjCMethodCacheEntry { + const ObjCMethodDecl *MD; + llvm::DISubprogram *DIMethodDecl; + }; + + /// Cache of forward declarations for method + llvm::DenseMap<const ObjCInterfaceDecl *, std::vector<ObjCMethodCacheEntry>> + ObjCMethodCache; + /// Cache of references to clang modules and precompiled headers. llvm::DenseMap<const Module *, llvm::TrackingMDRef> ModuleCache; Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -3346,6 +3346,26 @@ if (HasDecl && isa<FunctionDecl>(D)) DeclCache[D->getCanonicalDecl()].reset(SP); + if (CGM.getCodeGenOpts().DwarfVersion >= 5) { + // Starting with DWARF V5 method declarations are emitted as children of + // the interface type. + if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) { + const ObjCInterfaceDecl *ID = OMD->getClassInterface(); + QualType QTy(ID->getTypeForDecl(), 0); + auto it = TypeCache.find(QTy.getAsOpaquePtr()); + assert(it != TypeCache.end()); + llvm::DICompositeType *InterfaceDecl = + cast<llvm::DICompositeType>(it->second); + llvm::DISubprogram *FD = DBuilder.createFunction( + InterfaceDecl, Name, LinkageName, Unit, LineNo, + getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(), + false /*definition*/, ScopeLine, Flags, CGM.getLangOpts().Optimize, + TParamsArray.get()); + DBuilder.finalizeSubprogram(FD); + ObjCMethodCache[ID].push_back({OMD, FD}); + } + } + // Push the function onto the lexical block stack. LexicalBlockStack.emplace_back(SP); @@ -4213,6 +4233,31 @@ DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty); } + if (CGM.getCodeGenOpts().DwarfVersion >= 5) { + // Add methods to interface. + for (auto p : ObjCMethodCache) { + if (p.second.empty()) + continue; + + QualType QTy(p.first->getTypeForDecl(), 0); + auto it = TypeCache.find(QTy.getAsOpaquePtr()); + if (it == TypeCache.end()) + continue; + + llvm::DICompositeType *InterfaceDecl = + cast<llvm::DICompositeType>(it->second); + + SmallVector<llvm::Metadata *, 16> EltTys; + EltTys.append(InterfaceDecl->getElements().begin(), + InterfaceDecl->getElements().end()); + for (auto &M : p.second) { + EltTys.push_back(M.DIMethodDecl); + } + llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys); + DBuilder.replaceArrays(InterfaceDecl, Elements); + } + } + for (auto p : ReplaceMap) { assert(p.second); auto *Ty = cast<llvm::DIType>(p.second);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits