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

Adrian Prantl via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 8 12:20:27 PDT 2015


Author: adrian
Date: Tue Sep  8 14:20:27 2015
New Revision: 247049

URL: http://llvm.org/viewvc/llvm-project?rev=247049&view=rev
Log:
Module Debugging: Emit debug type information into clang 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 C and C++ types.

Added:
    cfe/trunk/test/Modules/Inputs/DebugCXX.h
    cfe/trunk/test/Modules/ModuleDebugInfo.cpp
Modified:
    cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
    cfe/trunk/test/Modules/Inputs/module.map

Modified: cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp?rev=247049&r1=247048&r2=247049&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp (original)
+++ cfe/trunk/lib/CodeGen/ObjectFilePCHContainerOperations.cpp Tue Sep  8 14:20:27 2015
@@ -50,6 +50,34 @@ class PCHContainerGenerator : public AST
   raw_pwrite_stream *OS;
   std::shared_ptr<PCHBuffer> Buffer;
 
+  /// Visit every type and emit debug info for it.
+  struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> {
+    clang::CodeGen::CGDebugInfo &DI;
+    ASTContext &Ctx;
+    DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx)
+        : DI(DI), Ctx(Ctx) {}
+
+    /// Determine whether this type can be represented in DWARF.
+    static bool CanRepresent(const Type *Ty) {
+      return !Ty->isDependentType() && !Ty->isUndeducedType();
+    }
+
+    bool VisitTypeDecl(TypeDecl *D) {
+      QualType QualTy = Ctx.getTypeDeclType(D);
+      if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
+        DI.getOrCreateStandaloneType(QualTy, D->getLocation());
+      return true;
+    }
+
+    bool VisitValueDecl(ValueDecl *D) {
+      QualType QualTy = D->getType();
+      if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
+        DI.getOrCreateStandaloneType(QualTy, D->getLocation());
+      return true;
+    }
+
+  };
+
 public:
   PCHContainerGenerator(DiagnosticsEngine &diags,
                         const HeaderSearchOptions &HSO,
@@ -82,6 +110,36 @@ public:
         *Ctx, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags));
   }
 
+  bool HandleTopLevelDecl(DeclGroupRef D) override {
+    if (Diags.hasErrorOccurred() ||
+        (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo))
+      return true;
+
+    // Collect debug info for all decls in this group.
+    for (auto *I : D)
+      if (!I->isFromASTFile()) {
+        DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
+        DTV.TraverseDecl(I);
+      }
+    return true;
+  }
+
+  void HandleTagDeclDefinition(TagDecl *D) override {
+    if (Diags.hasErrorOccurred())
+      return;
+
+    Builder->UpdateCompletedType(D);
+  }
+
+  void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
+    if (Diags.hasErrorOccurred())
+      return;
+
+    if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
+      if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
+        DI->completeRequiredType(RD);
+  }
+
   /// Emit a container holding the serialized AST.
   void HandleTranslationUnit(ASTContext &Ctx) override {
     assert(M && VMContext && Builder);

Added: cfe/trunk/test/Modules/Inputs/DebugCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/DebugCXX.h?rev=247049&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/DebugCXX.h (added)
+++ cfe/trunk/test/Modules/Inputs/DebugCXX.h Tue Sep  8 14:20:27 2015
@@ -0,0 +1,52 @@
+/* -*- C++ -*- */
+namespace DebugCXX {
+  // Records.
+  struct Struct {
+    int i;
+    static int static_member;
+  };
+
+  // Enums.
+  enum Enum {
+    Enumerator
+  };
+  enum {
+    e1 = '1'
+  };
+  enum {
+    e2 = '2'
+  };
+
+  // Templates (instatiations).
+  template<typename T> struct traits {};
+  template<typename T,
+           typename Traits = traits<T>
+          > class Template {
+    T member;
+  };
+  extern template class Template<int>;
+
+  extern template struct traits<float>;
+  typedef class Template<float> FloatInstatiation;
+
+  inline void fn() {
+    Template<long> invisible;
+  }
+
+  // Non-template inside a template.
+  template <class> struct Outer {
+    Outer();
+    struct Inner {
+      Inner(Outer) {}
+    };
+  };
+  template <class T> Outer<T>::Outer() {
+    Inner a(*this);
+  };
+
+  // Partial template specialization.
+  template <typename...> class A;
+  template <typename T> class A<T> {};
+  typedef A<void> B;
+  void foo(B) {}
+}

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=247049&r1=247048&r2=247049&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Tue Sep  8 14:20:27 2015
@@ -332,6 +332,10 @@ module DebugModule {
   header "DebugModule.h"
 }
 
+module DebugCXX {
+  header "DebugCXX.h"
+}
+
 module ImportNameInDir {
   header "ImportNameInDir.h"
   export *

Added: cfe/trunk/test/Modules/ModuleDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/ModuleDebugInfo.cpp?rev=247049&view=auto
==============================================================================
--- cfe/trunk/test/Modules/ModuleDebugInfo.cpp (added)
+++ cfe/trunk/test/Modules/ModuleDebugInfo.cpp Tue Sep  8 14:20:27 2015
@@ -0,0 +1,41 @@
+// Test that (the same) debug info is emitted for an Objective-C++
+// module and a C++ precompiled header.
+
+// REQUIRES: asserts, shell
+
+// Modules:
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -g -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 c++ -std=c++11 -emit-pch -fmodule-format=obj -I %S/Inputs -o %t.pch %S/Inputs/DebugCXX.h -mllvm -debug-only=pchcontainer &>%t-pch.ll
+// RUN: cat %t-pch.ll | FileCheck %s
+
+#ifdef MODULES
+ at import DebugCXX;
+#endif
+
+// CHECK: distinct !DICompileUnit(language: DW_LANG_{{.*}}C_plus_plus,
+// CHECK-SAME:                    isOptimized: false,
+// CHECK-SAME:                    splitDebugFilename:
+// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum"
+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX4EnumE")
+// CHECK: !DINamespace(name: "DebugCXX"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Struct"
+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX6StructE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME:             name: "Template<int, DebugCXX::traits<int> >"
+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIiNS_6traitsIiEEEE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME:             name: "Template<float, DebugCXX::traits<float> >"
+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type,
+// CHECK-SAME:             name: "Template<long, DebugCXX::traits<long> >"
+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIlNS_6traitsIlEEEE")
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A<void>"
+// CHECK-SAME:             identifier: "_ZTSN8DebugCXX1AIJvEEE")
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "FloatInstatiation"
+// no mangled name here yet.
+// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "B",
+// no mangled name here yet.




More information about the cfe-commits mailing list