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 @@ -@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 @@ +@interface ObjCClass { + int ivar; +} ++ classMethod; +- instanceMethodWithInt:(int)i; +@property int property; +@end + +@interface ObjCClass (Category) +- categoryMethod; +@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 +@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 -@import DebugModule; +@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/..") _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits