JDevlieghere updated this revision to Diff 151580.
JDevlieghere marked 5 inline comments as done.
JDevlieghere added a comment.

CR feedback


https://reviews.llvm.org/D48241

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  clang/test/CodeGenObjC/debug-info-synthesis.m

Index: clang/test/CodeGenObjC/debug-info-synthesis.m
===================================================================
--- clang/test/CodeGenObjC/debug-info-synthesis.m
+++ clang/test/CodeGenObjC/debug-info-synthesis.m
@@ -1,4 +1,7 @@
 // RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -w -triple x86_64-apple-darwin10 %s -o - | FileCheck %s
+// 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
+
 # 1 "foo.m" 1
 # 1 "foo.m" 2
 # 1 "./foo.h" 1
@@ -30,8 +33,14 @@
   }
 }
 
+// CHECK: ![[STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo"
 // CHECK: ![[FILE:.*]] = !DIFile(filename: "{{[^"]+}}foo.h"
-// CHECK: !DISubprogram(name: "-[Foo setDict:]"
+// DWARF5: !DISubprogram(name: "-[Foo setDict:]"
+// DWARF5-SAME:          scope: ![[STRUCT]],
+// DWARF5-SAME:          line: 8,
+// DWARF5-SAME:          isLocal: true, isDefinition: false
+// DWARF4-NOT: !DISubprogram(name: "-[Foo setDict:]"{{.*}}isDefinition: false
+// CHECK: distinct !DISubprogram(name: "-[Foo setDict:]"
 // CHECK-SAME:          file: ![[FILE]],
 // CHECK-SAME:          line: 8,
 // CHECK-SAME:          isLocal: true, isDefinition: true
Index: clang/lib/CodeGen/CGDebugInfo.h
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -98,6 +98,25 @@
   /// Cache of previously constructed interfaces which may change.
   llvm::SmallVector<ObjCInterfaceCacheEntry, 32> ObjCInterfaceCache;
 
+  struct ObjCMethodCacheEntry {
+    struct MethodData {
+      const ObjCMethodDecl *MD;
+      llvm::DISubprogram *DIMethodDecl;
+    };
+
+    // Keep track of the interface so we can update its elements with its
+    // methods.
+    llvm::DICompositeType *DIInterfaceDecl;
+    std::vector<MethodData> Methods;
+
+    ObjCMethodCacheEntry(llvm::DICompositeType *DIInterfaceDecl = nullptr)
+        : DIInterfaceDecl(DIInterfaceDecl) {}
+  };
+
+  /// Cache of forward declarations for method
+  llvm::DenseMap<const ObjCInterfaceDecl *, 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
@@ -2231,6 +2231,13 @@
       Mod ? Mod : Unit, ID->getName(), DefUnit, Line, Size, Align, Flags,
       nullptr, llvm::DINodeArray(), RuntimeLang);
 
+  if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
+    // Remember the DICompositeType in the ObjCMethodCache.
+    assert(ObjCMethodCache[ID].DIInterfaceDecl == nullptr ||
+           ObjCMethodCache[ID].DIInterfaceDecl == RealDecl);
+    ObjCMethodCache[ID].DIInterfaceDecl = RealDecl;
+  }
+
   QualType QTy(Ty, 0);
   TypeCache[QTy.getAsOpaquePtr()].reset(RealDecl);
 
@@ -3346,6 +3353,21 @@
   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();
+      llvm::DISubprogram *FD = DBuilder.createFunction(
+          ObjCMethodCache[ID].DIInterfaceDecl, Name, LinkageName, Unit, LineNo,
+          getOrCreateFunctionType(D, FnType, Unit), Fn->hasLocalLinkage(),
+          false /*definition*/, ScopeLine, Flags, CGM.getLangOpts().Optimize,
+          TParamsArray.get());
+      DBuilder.finalizeSubprogram(FD);
+      ObjCMethodCache[ID].Methods.push_back({OMD, FD});
+    }
+  }
+
   // Push the function onto the lexical block stack.
   LexicalBlockStack.emplace_back(SP);
 
@@ -4213,6 +4235,26 @@
     DBuilder.replaceTemporary(llvm::TempDIType(E.Decl), Ty);
   }
 
+  if (CGM.getCodeGenOpts().DwarfVersion >= 5) {
+    // Add methods to interface.
+    for (auto p : ObjCMethodCache) {
+      llvm::DICompositeType *RealDecl = p.second.DIInterfaceDecl;
+      if (!RealDecl)
+        continue;
+      if (p.second.Methods.empty())
+        continue;
+
+      SmallVector<llvm::Metadata *, 16> EltTys;
+      EltTys.append(RealDecl->getElements().begin(),
+                    RealDecl->getElements().end());
+      for (auto &M : p.second.Methods) {
+        EltTys.push_back(M.DIMethodDecl);
+      }
+      llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
+      DBuilder.replaceArrays(RealDecl, 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

Reply via email to