Skip to content

Commit aa2c5dc

Browse files
Merge pull request #368 from adrian-prantl/57327663-11
Cherry-pick objc_direct support
2 parents a6caa95 + 4fc7e5f commit aa2c5dc

File tree

3 files changed

+50
-24
lines changed

3 files changed

+50
-24
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3504,14 +3504,15 @@ llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
35043504
if (!D || DebugKind <= codegenoptions::DebugLineTablesOnly)
35053505
return nullptr;
35063506

3507-
if (CGM.getCodeGenOpts().DwarfVersion < 5)
3507+
const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
3508+
if (!OMD)
3509+
return nullptr;
3510+
3511+
if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->isDirectMethod())
35083512
return nullptr;
35093513

35103514
// Starting with DWARF V5 method declarations are emitted as children of
35113515
// the interface type.
3512-
const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
3513-
if (!OMD)
3514-
return nullptr;
35153516
auto *ID = dyn_cast_or_null<ObjCInterfaceDecl>(D->getDeclContext());
35163517
if (!ID)
35173518
ID = OMD->getClassInterface();
@@ -3526,7 +3527,7 @@ llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
35263527
InterfaceType, getObjCMethodName(OMD), StringRef(),
35273528
InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
35283529
DBuilder.finalizeSubprogram(FD);
3529-
ObjCMethodCache[ID].push_back(FD);
3530+
ObjCMethodCache[ID].push_back({FD, OMD->isDirectMethod()});
35303531
return FD;
35313532
}
35323533

@@ -4751,27 +4752,28 @@ void CGDebugInfo::finalize() {
47514752
DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
47524753
}
47534754

4754-
if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
4755-
// Add methods to interface.
4756-
for (const auto &P : ObjCMethodCache) {
4757-
if (P.second.empty())
4758-
continue;
4755+
// Add methods to interface.
4756+
for (const auto &P : ObjCMethodCache) {
4757+
if (P.second.empty())
4758+
continue;
47594759

4760-
QualType QTy(P.first->getTypeForDecl(), 0);
4761-
auto It = TypeCache.find(QTy.getAsOpaquePtr());
4762-
assert(It != TypeCache.end());
4760+
QualType QTy(P.first->getTypeForDecl(), 0);
4761+
auto It = TypeCache.find(QTy.getAsOpaquePtr());
4762+
assert(It != TypeCache.end());
47634763

4764-
llvm::DICompositeType *InterfaceDecl =
4765-
cast<llvm::DICompositeType>(It->second);
4764+
llvm::DICompositeType *InterfaceDecl =
4765+
cast<llvm::DICompositeType>(It->second);
47664766

4767-
SmallVector<llvm::Metadata *, 16> EltTys;
4768-
auto CurrenetElts = InterfaceDecl->getElements();
4769-
EltTys.append(CurrenetElts.begin(), CurrenetElts.end());
4770-
for (auto &MD : P.second)
4771-
EltTys.push_back(MD);
4772-
llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4773-
DBuilder.replaceArrays(InterfaceDecl, Elements);
4774-
}
4767+
auto CurElts = InterfaceDecl->getElements();
4768+
SmallVector<llvm::Metadata *, 16> EltTys(CurElts.begin(), CurElts.end());
4769+
4770+
// For DWARF v4 or earlier, only add objc_direct methods.
4771+
for (auto &SubprogramDirect : P.second)
4772+
if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
4773+
EltTys.push_back(SubprogramDirect.getPointer());
4774+
4775+
llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
4776+
DBuilder.replaceArrays(InterfaceDecl, Elements);
47754777
}
47764778

47774779
for (const auto &P : ReplaceMap) {

clang/lib/CodeGen/CGDebugInfo.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ class CGDebugInfo {
114114
llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
115115

116116
/// Cache of forward declarations for methods belonging to the interface.
117-
llvm::DenseMap<const ObjCInterfaceDecl *, std::vector<llvm::DISubprogram *>>
117+
/// The extra bit on the DISubprogram specifies whether a method is
118+
/// "objc_direct".
119+
llvm::DenseMap<const ObjCInterfaceDecl *,
120+
std::vector<llvm::PointerIntPair<llvm::DISubprogram *, 1>>>
118121
ObjCMethodCache;
119122

120123
/// Cache of references to clang modules and precompiled headers.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -dwarf-version=5 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
2+
// RUN: %clang_cc1 -dwarf-version=4 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
3+
4+
__attribute__((objc_root_class))
5+
@interface Root
6+
@end
7+
8+
@implementation Root
9+
- (int)getInt __attribute__((objc_direct)) {
10+
return 42;
11+
}
12+
@end
13+
14+
// Test that objc_direct methods are always (even in DWARF < 5) emitted
15+
// as members of their containing class.
16+
17+
// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Root",
18+
// CHECK-SAME: elements: ![[MEMBERS:[0-9]+]],
19+
// CHECK-SAME: runtimeLang: DW_LANG_ObjC)
20+
// CHECK: ![[MEMBERS]] = !{![[GETTER:[0-9]+]]}
21+
// CHECK: ![[GETTER]] = !DISubprogram(name: "-[Root getInt]",

0 commit comments

Comments
 (0)