[clang] e0cabe2 - Debug info: Emit objc_direct methods as members of their containing class

Adrian Prantl via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 21 11:01:19 PST 2019


Author: Adrian Prantl
Date: 2019-11-21T11:01:10-08:00
New Revision: e0cabe280b80ab71045d90b2d6f1a70e5d4c5d05

URL: https://github.com/llvm/llvm-project/commit/e0cabe280b80ab71045d90b2d6f1a70e5d4c5d05
DIFF: https://github.com/llvm/llvm-project/commit/e0cabe280b80ab71045d90b2d6f1a70e5d4c5d05.diff

LOG: Debug info: Emit objc_direct methods as members of their containing class

even in DWARF 4 and earlier. This allows the debugger to recognize
them as direct functions as opposed to Objective-C methods.

<rdar://problem/57327663>

Differential Revision: https://reviews.llvm.org/D70544

Added: 
    clang/test/CodeGenObjC/debug-info-direct-method.m

Modified: 
    clang/lib/CodeGen/CGDebugInfo.cpp
    clang/lib/CodeGen/CGDebugInfo.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index a9b3831aa0b5..a8d4ed12808e 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3495,14 +3495,15 @@ llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
   if (!D || DebugKind <= codegenoptions::DebugLineTablesOnly)
     return nullptr;
 
-  if (CGM.getCodeGenOpts().DwarfVersion < 5)
+  const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
+  if (!OMD)
+    return nullptr;
+
+  if (CGM.getCodeGenOpts().DwarfVersion < 5 && !OMD->isDirectMethod())
     return nullptr;
 
   // Starting with DWARF V5 method declarations are emitted as children of
   // the interface type.
-  const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
-  if (!OMD)
-    return nullptr;
   auto *ID = dyn_cast_or_null<ObjCInterfaceDecl>(D->getDeclContext());
   if (!ID)
     ID = OMD->getClassInterface();
@@ -3517,7 +3518,7 @@ llvm::DISubprogram *CGDebugInfo::getObjCMethodDeclaration(
       InterfaceType, getObjCMethodName(OMD), StringRef(),
       InterfaceType->getFile(), LineNo, FnType, LineNo, Flags, SPFlags);
   DBuilder.finalizeSubprogram(FD);
-  ObjCMethodCache[ID].push_back(FD);
+  ObjCMethodCache[ID].push_back({FD, OMD->isDirectMethod()});
   return FD;
 }
 
@@ -4713,27 +4714,28 @@ void CGDebugInfo::finalize() {
     DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
   }
 
-  if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
-    // Add methods to interface.
-    for (const auto &P : ObjCMethodCache) {
-      if (P.second.empty())
-        continue;
+  // Add methods to interface.
+  for (const auto &P : ObjCMethodCache) {
+    if (P.second.empty())
+      continue;
 
-      QualType QTy(P.first->getTypeForDecl(), 0);
-      auto It = TypeCache.find(QTy.getAsOpaquePtr());
-      assert(It != TypeCache.end());
+    QualType QTy(P.first->getTypeForDecl(), 0);
+    auto It = TypeCache.find(QTy.getAsOpaquePtr());
+    assert(It != TypeCache.end());
 
-      llvm::DICompositeType *InterfaceDecl =
-          cast<llvm::DICompositeType>(It->second);
+    llvm::DICompositeType *InterfaceDecl =
+        cast<llvm::DICompositeType>(It->second);
 
-      SmallVector<llvm::Metadata *, 16> EltTys;
-      auto CurrenetElts = InterfaceDecl->getElements();
-      EltTys.append(CurrenetElts.begin(), CurrenetElts.end());
-      for (auto &MD : P.second)
-        EltTys.push_back(MD);
-      llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
-      DBuilder.replaceArrays(InterfaceDecl, Elements);
-    }
+    auto CurElts = InterfaceDecl->getElements();
+    SmallVector<llvm::Metadata *, 16> EltTys(CurElts.begin(), CurElts.end());
+
+    // For DWARF v4 or earlier, only add objc_direct methods.
+    for (auto &SubprogramDirect : P.second)
+      if (CGM.getCodeGenOpts().DwarfVersion >= 5 || SubprogramDirect.getInt())
+        EltTys.push_back(SubprogramDirect.getPointer());
+
+    llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
+    DBuilder.replaceArrays(InterfaceDecl, Elements);
   }
 
   for (const auto &P : ReplaceMap) {

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 5341bfa7f350..13e9c7a38fcc 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -114,7 +114,10 @@ class CGDebugInfo {
   llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
 
   /// Cache of forward declarations for methods belonging to the interface.
-  llvm::DenseMap<const ObjCInterfaceDecl *, std::vector<llvm::DISubprogram *>>
+  /// The extra bit on the DISubprogram specifies whether a method is
+  /// "objc_direct".
+  llvm::DenseMap<const ObjCInterfaceDecl *,
+                 std::vector<llvm::PointerIntPair<llvm::DISubprogram *, 1>>>
       ObjCMethodCache;
 
   /// Cache of references to clang modules and precompiled headers.

diff  --git a/clang/test/CodeGenObjC/debug-info-direct-method.m b/clang/test/CodeGenObjC/debug-info-direct-method.m
new file mode 100644
index 000000000000..f822088f946c
--- /dev/null
+++ b/clang/test/CodeGenObjC/debug-info-direct-method.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -dwarf-version=5 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -dwarf-version=4 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+
+__attribute__((objc_root_class))
+ at interface Root
+ at end
+
+ at implementation Root
+- (int)getInt __attribute__((objc_direct)) {
+  return 42;
+}
+ at end
+
+// Test that objc_direct methods are always (even in DWARF < 5) emitted
+// as members of their containing class.
+
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Root",
+// CHECK-SAME:             elements: ![[MEMBERS:[0-9]+]],
+// CHECK-SAME:             runtimeLang: DW_LANG_ObjC)
+// CHECK: ![[MEMBERS]] = !{![[GETTER:[0-9]+]]}
+// CHECK: ![[GETTER]] = !DISubprogram(name: "-[Root getInt]",


        


More information about the cfe-commits mailing list