From 2a7002ed1e56c2b5411d8fb4ed3b63b2f9a7cdf9 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 4 Sep 2013 02:12:12 +0000 Subject: [PATCH] Revert "DebugInfo: Remove explicit declaration-emissiong handling now that we have a more principled approach (the 'requires complete type' callback)" This reverts commit r189013. This is causing a segfault crash in a test case I have. Reverting while I investigate the issue. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189906 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 64 +++++++++++++++++++++---------------- lib/CodeGen/CGDebugInfo.h | 10 +++--- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index fe503982be..4126e20860 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -543,7 +543,8 @@ 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); @@ -569,7 +570,8 @@ 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. @@ -682,7 +684,8 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, llvm::DIFile Unit) { if (Tag == llvm::dwarf::DW_TAG_reference_type || Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) - return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit)); + return DBuilder.createReferenceType( + Tag, getOrCreateType(PointeeTy, Unit, true)); // Bit size, align and offset of the type. // Size is always the size of a pointer. We can't use getTypeSize here @@ -691,8 +694,8 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag, uint64_t Size = CGM.getTarget().getPointerWidth(AS); uint64_t Align = CGM.getContext().getTypeAlign(Ty); - return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, - Align); + return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit, true), + Size, Align); } llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name, @@ -768,10 +771,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 = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit); + llvm::DIType Src = + getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit, Declaration); if (!Src) return llvm::DIType(); // We don't set size information, but do specify where the typedef was @@ -791,7 +796,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, SmallVector EltTys; // Add the result type at least. - EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit)); + EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit, true)); // Set up remainder of arguments if there is a prototype. // FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'! @@ -799,7 +804,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, EltTys.push_back(DBuilder.createUnspecifiedParameter()); else if (const FunctionProtoType *FPT = dyn_cast(Ty)) { for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i) - EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit)); + EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit, true)); } llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys); @@ -1196,7 +1201,7 @@ CollectCXXFriends(const CXXRecordDecl *RD, llvm::DIFile Unit, continue; if (TypeSourceInfo *TInfo = (*BI)->getFriendType()) EltTys.push_back(DBuilder.createFriend( - RecordTy, getOrCreateType(TInfo->getType(), Unit))); + RecordTy, getOrCreateType(TInfo->getType(), Unit, true))); } } @@ -1498,16 +1503,12 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) { } /// 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(); const CXXRecordDecl *CXXDecl = dyn_cast(RD); - // Always emit declarations for types that aren't required to be complete when - // in limit-debug-info mode. If the type is later found to be required to be - // complete this declaration will be upgraded to a definition by - // `completeRequiredType`. - // If the type is dynamic, only emit the definition in TUs that require class - // data. This is handled by `completeClassData`. - if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && + // Limited debug info should only remove struct definitions that can + // safely be replaced by a forward declaration in the source code. + if ((DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration && !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) || (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) { llvm::DIDescriptor FDContext = @@ -1885,7 +1886,7 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty, llvm::DIType ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U); if (!Ty->getPointeeType()->isFunctionType()) return DBuilder.createMemberPointerType( - getOrCreateType(Ty->getPointeeType(), U), ClassType); + getOrCreateType(Ty->getPointeeType(), U, true), ClassType); return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType( CGM.getContext().getPointerType( QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())), @@ -2065,18 +2066,26 @@ 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(); // Unwrap the type as needed for debug information. Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext()); - if (llvm::DIType T = getCompletedTypeOrNull(Ty)) + if (llvm::DIType T = getCompletedTypeOrNull(Ty)) { + // If we're looking for a definition, make sure we have definitions of any + // underlying types. + if (const TypedefType* TTy = dyn_cast(Ty)) + getOrCreateType(TTy->getDecl()->getUnderlyingType(), Unit, Declaration); + if (Ty.hasLocalQualifiers()) + getOrCreateType(QualType(Ty.getTypePtr(), 0), Unit, Declaration); 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. @@ -2145,10 +2154,11 @@ 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; @@ -2183,9 +2193,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)); case Type::FunctionProto: @@ -2371,7 +2381,7 @@ llvm::DIDescriptor CGDebugInfo::getDeclarationOrDefinition(const Decl *D) { // in unlimited debug info) if (const TypeDecl *TD = dyn_cast(D)) return getOrCreateType(CGM.getContext().getTypeDeclType(TD), - getOrCreateFile(TD->getLocation())); + getOrCreateFile(TD->getLocation()), true); // Otherwise fall back to a fairly rudimentary cache of existing declarations. // This doesn't handle providing declarations (for functions or variables) for // entities without definitions in this TU, nor when the definition proceeds diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h index a8ba14b8b3..3003ce65fd 100644 --- a/lib/CodeGen/CGDebugInfo.h +++ b/lib/CodeGen/CGDebugInfo.h @@ -107,14 +107,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 Fg); - llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile Fg); + 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 *Tyg); + llvm::DIType CreateType(const RecordType *Ty, bool Declaration); llvm::DIType CreateTypeDefinition(const RecordType *Ty); llvm::DICompositeType CreateLimitedType(const RecordType *Ty); void CollectContainingType(const CXXRecordDecl *RD, llvm::DICompositeType CT); @@ -330,14 +330,14 @@ private: /// getOrCreateType - Get the type from the cache or create a new type if /// necessary. - llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile Fg); + 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(const RecordType *Ty, llvm::DIFile F); /// CreateTypeNode - Create type metadata for a source language type. - llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile Fg); + 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. -- 2.40.0