r247068 - Module Debugging: Emit debug type information into clang ObjC modules.

Adrian Prantl via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 8 13:41:52 PDT 2015


Author: adrian
Date: Tue Sep  8 15:41:52 2015
New Revision: 247068

URL: http://llvm.org/viewvc/llvm-project?rev=247068&view=rev
Log:
Module Debugging: Emit debug type information into clang ObjC modules.

When -fmodule-format is set to "obj", emit debug info for all types
declared in a module or referenced by a declaration into the module's
object file container.

This patch adds support for Objective-C types and methods.

Added:
    cfe/trunk/test/Modules/Inputs/DebugObjC.h
    cfe/trunk/test/Modules/ModuleDebugInfo.m
Removed:
    cfe/trunk/test/Modules/Inputs/DebugModule.h
Modified:
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.h
    cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
    cfe/trunk/test/Modules/Inputs/module.map
    cfe/trunk/test/Modules/debug-info-moduleimport.m

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=247068&r1=247067&r2=247068&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Sep  8 15:41:52 2015
@@ -2515,11 +2515,17 @@ llvm::DISubroutineType *CGDebugInfo::get
 
     Elts.push_back(getOrCreateType(ResultTy, F));
     // "self" pointer is always first argument.
-    QualType SelfDeclTy = OMethod->getSelfDecl()->getType();
-    Elts.push_back(CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
+    QualType SelfDeclTy;
+    if (auto *SelfDecl = OMethod->getSelfDecl())
+      SelfDeclTy = SelfDecl->getType();
+    else if (auto *FPT = dyn_cast<FunctionProtoType>(FnType))
+      if (FPT->getNumParams() > 1)
+        SelfDeclTy = FPT->getParamType(0);
+    if (!SelfDeclTy.isNull())
+      Elts.push_back(CreateSelfType(SelfDeclTy, getOrCreateType(SelfDeclTy, F)));
     // "_cmd" pointer is always second argument.
     Elts.push_back(DBuilder.createArtificialType(
-        getOrCreateType(OMethod->getCmdDecl()->getType(), F)));
+        getOrCreateType(CGM.getContext().getObjCSelType(), F)));
     // Get rest of the arguments.
     for (const auto *PI : OMethod->params())
       Elts.push_back(getOrCreateType(PI->getType(), F));
@@ -2623,6 +2629,49 @@ void CGDebugInfo::EmitFunctionStart(Glob
     RegionMap[D].reset(SP);
 }
 
+void CGDebugInfo::EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
+                                   QualType FnType) {
+  StringRef Name;
+  StringRef LinkageName;
+
+  const Decl *D = GD.getDecl();
+  if (!D)
+    return;
+
+  unsigned Flags = 0;
+  llvm::DIFile *Unit = getOrCreateFile(Loc);
+  llvm::DIScope *FDContext = Unit;
+  llvm::DINodeArray TParamsArray;
+  if (isa<FunctionDecl>(D)) {
+    // If there is a DISubprogram for this function available then use it.
+    collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
+                             TParamsArray, Flags);
+  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
+    Name = getObjCMethodName(OMD);
+    Flags |= llvm::DINode::FlagPrototyped;
+  } else {
+    llvm_unreachable("not a function or ObjC method");
+  }
+  if (!Name.empty() && Name[0] == '\01')
+    Name = Name.substr(1);
+
+  if (D->isImplicit()) {
+    Flags |= llvm::DINode::FlagArtificial;
+    // Artificial functions without a location should not silently reuse CurLoc.
+    if (Loc.isInvalid())
+      CurLoc = SourceLocation();
+  }
+  unsigned LineNo = getLineNumber(Loc);
+  unsigned ScopeLine = 0;
+
+  DBuilder.createFunction(FDContext, Name, LinkageName, Unit, LineNo,
+                          getOrCreateFunctionType(D, FnType, Unit),
+                          false /*internalLinkage*/, true /*definition*/,
+                          ScopeLine, Flags, CGM.getLangOpts().Optimize, nullptr,
+                          TParamsArray.get(),
+                          getFunctionDeclaration(D));
+}
+
 void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
   // Update our current location
   setLocation(Loc);

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=247068&r1=247067&r2=247068&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Tue Sep  8 15:41:52 2015
@@ -281,6 +281,9 @@ public:
                          SourceLocation ScopeLoc, QualType FnType,
                          llvm::Function *Fn, CGBuilderTy &Builder);
 
+  /// Emit debug info for a function declaration.
+  void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType);
+
   /// Constructs the debug code for exiting a function.
   void EmitFunctionEnd(CGBuilderTy &Builder);
 

Modified: cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp?rev=247068&r1=247067&r2=247068&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp (original)
+++ cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp Tue Sep  8 15:41:52 2015
@@ -76,6 +76,48 @@ class PCHContainerGenerator : public AST
       return true;
     }
 
+    bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+      QualType QualTy(D->getTypeForDecl(), 0);
+      if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
+        DI.getOrCreateStandaloneType(QualTy, D->getLocation());
+      return true;
+    }
+
+    bool VisitFunctionDecl(FunctionDecl *D) {
+      if (isa<CXXMethodDecl>(D))
+        // This is not yet supported. Constructing the `this' argument
+        // mandates a CodeGenFunction.
+        return true;
+
+      SmallVector<QualType, 16> ArgTypes;
+      for (auto i : D->params())
+        ArgTypes.push_back(i->getType());
+      QualType RetTy = D->getReturnType();
+      QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
+                                          FunctionProtoType::ExtProtoInfo());
+      if (CanRepresent(FnTy.getTypePtr()))
+        DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
+      return true;
+    }
+
+    bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
+      if (!D->getClassInterface())
+        return true;
+
+      bool selfIsPseudoStrong, selfIsConsumed;
+      SmallVector<QualType, 16> ArgTypes;
+      ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(),
+                                        selfIsPseudoStrong, selfIsConsumed));
+      ArgTypes.push_back(Ctx.getObjCSelType());
+      for (auto i : D->params())
+        ArgTypes.push_back(i->getType());
+      QualType RetTy = D->getReturnType();
+      QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
+                                          FunctionProtoType::ExtProtoInfo());
+      if (CanRepresent(FnTy.getTypePtr()))
+        DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
+      return true;
+    }
   };
 
 public:

Removed: cfe/trunk/test/Modules/Inputs/DebugModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DebugModule.h?rev=247067&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DebugModule.h (original)
+++ cfe/trunk/test/Modules/Inputs/DebugModule.h (removed)
@@ -1 +0,0 @@
- at class F;

Added: cfe/trunk/test/Modules/Inputs/DebugObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DebugObjC.h?rev=247068&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DebugObjC.h (added)
+++ cfe/trunk/test/Modules/Inputs/DebugObjC.h Tue Sep  8 15:41:52 2015
@@ -0,0 +1,11 @@
+ at interface ObjCClass {
+  int ivar;
+}
++ classMethod;
+- instanceMethodWithInt:(int)i;
+ at property int property;
+ at end
+
+ at interface ObjCClass (Category)
+- categoryMethod;
+ at end

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=247068&r1=247067&r2=247068&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Tue Sep  8 15:41:52 2015
@@ -328,14 +328,14 @@ module crash {
   header "crash.h"
 }
 
-module DebugModule {
-  header "DebugModule.h"
-}
-
 module DebugCXX {
   header "DebugCXX.h"
 }
 
+module DebugObjC {
+  header "DebugObjC.h"
+}
+
 module ImportNameInDir {
   header "ImportNameInDir.h"
   export *

Added: cfe/trunk/test/Modules/ModuleDebugInfo.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ModuleDebugInfo.m?rev=247068&view=auto
==============================================================================
--- cfe/trunk/test/Modules/ModuleDebugInfo.m (added)
+++ cfe/trunk/test/Modules/ModuleDebugInfo.m Tue Sep  8 15:41:52 2015
@@ -0,0 +1,27 @@
+// Test that debug info is emitted for an Objective-C module and
+// a precompiled header.
+
+// REQUIRES: asserts, shell
+
+// Modules:
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodule-format=obj -fimplicit-module-maps -DMODULES -fmodules-cache-path=%t %s -I %S/Inputs -I %t -emit-llvm -o %t.ll -mllvm -debug-only=pchcontainer &>%t-mod.ll
+// RUN: cat %t-mod.ll | FileCheck %s
+
+// PCH:
+// RUN: %clang_cc1 -x objective-c -emit-pch -fmodule-format=obj -I %S/Inputs -o %t.pch %S/Inputs/DebugObjC.h -mllvm -debug-only=pchcontainer &>%t-pch.ll
+// RUN: cat %t-pch.ll | FileCheck %s
+
+#ifdef MODULES
+ at import DebugObjC;
+#endif
+
+// CHECK: distinct !DICompileUnit(language: DW_LANG_ObjC
+// CHECK-SAME:                    isOptimized: false,
+// CHECK-SAME:                    splitDebugFilename:
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ObjCClass"
+// CHECK: !DIObjCProperty(name: "property",
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "ivar"
+// CHECK: !DISubprogram(name: "+[ObjCClass classMethod]"
+// CHECK: !DISubprogram(name: "-[ObjCClass instanceMethodWithInt:]"
+// CHECK: !DISubprogram(name: "-[ categoryMethod]"

Modified: cfe/trunk/test/Modules/debug-info-moduleimport.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/debug-info-moduleimport.m?rev=247068&r1=247067&r2=247068&view=diff
==============================================================================
--- cfe/trunk/test/Modules/debug-info-moduleimport.m (original)
+++ cfe/trunk/test/Modules/debug-info-moduleimport.m Tue Sep  8 15:41:52 2015
@@ -2,6 +2,6 @@
 // RUN: %clang_cc1 -g -fmodules -DGREETING="Hello World" -UNDEBUG -fimplicit-module-maps -fmodules-cache-path=%t %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - | FileCheck %s
 
 // CHECK: ![[CU:.*]] = distinct !DICompileUnit
- at import DebugModule;
+ at import DebugObjC;
 // CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[CU]], entity: ![[MODULE:.*]], line: 5)
-// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugModule", configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22", includePath: "{{.*}}test{{.*}}Modules{{.*}}Inputs", isysroot: "/tmp/..")
+// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugObjC", configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22", includePath: "{{.*}}test{{.*}}Modules{{.*}}Inputs", isysroot: "/tmp/..")




More information about the cfe-commits mailing list