From: David Blaikie Date: Wed, 5 Jun 2013 05:32:23 +0000 (+0000) Subject: PR16214: Debug Info: -flimit-debug-info doesn't omit definitions for types used via... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f6e2f4010e1ebbc07231eff7c92e474e8912350;p=clang PR16214: Debug Info: -flimit-debug-info doesn't omit definitions for types used via typedefs In an effort to make -flimit-debug-info more consistent I over-shot the mark & made types used via typedefs never produce definitions in the debug info (even if the type was used in a way that would require a definition). The fix for this is to do exactly what I was hoping to do at some point - plumb the declaration/definition choice through the various layers of "CreateType" in CGDebugInfo. In this way we can produce declarations whenever they are sufficient & definitions otherwise - including when qualifiers are used, for example (discovered in PR14467). This may not be complete (there may be other types/situations where we need to propagate the "declaration/definition" choice) but it lays the basic foundation which we can enhance in future iterations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183296 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index c1d095ddd6..80d5f101ee 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -501,7 +501,7 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty) { /// CreateCVRType - Get the qualified type from the cache or create /// a new one if necessary. -llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) { +llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit, bool Declaration) { QualifierCollector Qc; const Type *T = Qc.strip(Ty); @@ -527,7 +527,7 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) { return getOrCreateType(QualType(T, 0), Unit); } - llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit); + llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit, Declaration); // No need to fill in the Name, Line, Size, Alignment, Offset in case of // CVR derived types. @@ -613,27 +613,7 @@ llvm::DIType CGDebugInfo::getOrCreateTypeDeclaration(QualType PointeeTy, llvm::DIFile Unit) { if (DebugKind > CodeGenOptions::LimitedDebugInfo) return getOrCreateType(PointeeTy, Unit); - - // Limit debug info for the pointee type. - - // If we have an existing type, use that, it's still smaller than creating - // a new type. - llvm::DIType Ty = getTypeOrNull(PointeeTy); - if (Ty.Verify()) return Ty; - - // Handle qualifiers. - if (PointeeTy.hasLocalQualifiers()) - return CreateQualifiedType(PointeeTy, Unit); - - if (const RecordType *RTy = dyn_cast(PointeeTy)) { - RecordDecl *RD = RTy->getDecl(); - llvm::DIDescriptor FDContext = - getContextDescriptor(cast(RD->getDeclContext())); - llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext); - TypeCache[QualType(RTy, 0).getAsOpaquePtr()] = RetTy; - return RetTy; - } - return getOrCreateType(PointeeTy, Unit); + return getOrCreateType(PointeeTy, Unit, true); } llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, @@ -730,11 +710,12 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty, return BlockLiteralGeneric; } -llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) { +llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit, + bool Declaration) { // Typedefs are derived from some other type. If we have a typedef of a // typedef, make sure to emit the whole chain. llvm::DIType Src = - getOrCreateTypeDeclaration(Ty->getDecl()->getUnderlyingType(), Unit); + getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, Declaration); if (!Src.Verify()) return llvm::DIType(); // We don't set size information, but do specify where the typedef was @@ -1394,8 +1375,15 @@ llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D, } /// CreateType - get structure or union type. -llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) { +llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) { RecordDecl *RD = Ty->getDecl(); + if (Declaration) { + llvm::DIDescriptor FDContext = + getContextDescriptor(cast(RD->getDeclContext())); + llvm::DIType RetTy = createRecordFwdDecl(RD, FDContext); + TypeCache[QualType(Ty, 0).getAsOpaquePtr()] = RetTy; + return RetTy; + } // Get overall information about the record type for the debug info. llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation()); @@ -1908,7 +1896,7 @@ llvm::Value *CGDebugInfo::getCachedInterfaceTypeOrNull(QualType Ty) { /// getOrCreateType - Get the type from the cache or create a new /// one if necessary. -llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { +llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit, bool Declaration) { if (Ty.isNull()) return llvm::DIType(); @@ -1921,7 +1909,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { return T; // Otherwise create the type. - llvm::DIType Res = CreateTypeNode(Ty, Unit); + llvm::DIType Res = CreateTypeNode(Ty, Unit, Declaration); void* TyPtr = Ty.getAsOpaquePtr(); // And update the type cache. @@ -1981,10 +1969,10 @@ ObjCInterfaceDecl *CGDebugInfo::getObjCInterfaceDecl(QualType Ty) { } /// CreateTypeNode - Create a new debug type node. -llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { +llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit, bool Declaration) { // Handle qualifiers, which recursively handles what they refer to. if (Ty.hasLocalQualifiers()) - return CreateQualifiedType(Ty, Unit); + return CreateQualifiedType(Ty, Unit, Declaration); const char *Diag = 0; @@ -2015,9 +2003,9 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) { case Type::BlockPointer: return CreateType(cast(Ty), Unit); case Type::Typedef: - return CreateType(cast(Ty), Unit); + return CreateType(cast(Ty), Unit, Declaration); case Type::Record: - return CreateType(cast(Ty)); + return CreateType(cast(Ty), Declaration); case Type::Enum: return CreateEnumType(cast(Ty)->getDecl()); case Type::FunctionProto: @@ -2174,7 +2162,7 @@ llvm::DIType CGDebugInfo::CreateLimitedTypeNode(QualType Ty,llvm::DIFile Unit) { case Type::Record: return CreateLimitedType(cast(Ty)); default: - return CreateTypeNode(Ty, Unit); + return CreateTypeNode(Ty, Unit, false); } } diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index cee96f6d9d..fc62600c32 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -108,14 +108,14 @@ class CGDebugInfo { unsigned Checksum(const ObjCInterfaceDecl *InterfaceDecl); llvm::DIType CreateType(const BuiltinType *Ty); llvm::DIType CreateType(const ComplexType *Ty); - llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F); - llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F); + llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F, bool Declaration); + llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F, bool Declaration); llvm::DIType CreateType(const ObjCObjectPointerType *Ty, llvm::DIFile F); llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F); llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F); llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F); - llvm::DIType CreateType(const RecordType *Ty); + llvm::DIType CreateType(const RecordType *Ty, bool Declaration); llvm::DIType CreateLimitedType(const RecordType *Ty); llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F); llvm::DIType CreateType(const ObjCObjectType *Ty, llvm::DIFile F); @@ -326,14 +326,14 @@ private: /// getOrCreateType - Get the type from the cache or create a new type if /// necessary. - llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F); + llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F, bool Declaration = false); /// getOrCreateLimitedType - Get the type from the cache or create a new /// partial type if necessary. llvm::DIType getOrCreateLimitedType(QualType Ty, llvm::DIFile F); /// CreateTypeNode - Create type metadata for a source language type. - llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F); + llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F, bool Declaration); /// getObjCInterfaceDecl - return the underlying ObjCInterfaceDecl /// if Ty is an ObjCInterface or a pointer to one. diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp index b16c564e73..4085b9ad32 100644 --- a/test/CodeGenCXX/debug-info.cpp +++ b/test/CodeGenCXX/debug-info.cpp @@ -76,3 +76,27 @@ incomplete (*x)[3]; // CHECK: [[INCARRAY]] = {{.*}}metadata [[INCTYPE:![0-9]*]], metadata {{![0-9]*}}, i32 0, i32 0} ; [ DW_TAG_array_type ] [line 0, size 0, align 0, offset 0] [from incomplete] // CHECK: [[INCTYPE]] = {{.*}} ; [ DW_TAG_structure_type ] [incomplete]{{.*}} [fwd] } + +namespace pr16214 { +struct a { + int i; +}; + +typedef a at; + +struct b { +}; + +typedef b bt; + +void func() { + at a_inst; + bt *b_ptr_inst; + const bt *b_cnst_ptr_inst; +} + +// CHECK: metadata [[A_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [a] +// CHECK: [[A_MEM]] = metadata !{metadata [[A_I:![0-9]*]], metadata !{{[0-9]*}}} +// CHECK: [[A_I]] = {{.*}} ; [ DW_TAG_member ] [i] {{.*}} [from int] +// CHECK: ; [ DW_TAG_structure_type ] [b] {{.*}}[fwd] +}