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 +@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. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits