Reapply r189013 (reverted in r189906) now that the underlying issue is fixed and tested (in r189996)
Debug info emission was tripping over an IRGen bug (fixed in r189996)
that was resulting in duplicate emission of static data members of class
templates in namespaces.
We could add more test coverage to debug info for this issue
specifically, but I think the underlying IRGen test is more targeted and
sufficient for the issue.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190001 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 4126e20..fe50398 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -543,8 +543,7 @@
/// CreateCVRType - Get the qualified type from the cache or create
/// a new one if necessary.
-llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit,
- bool Declaration) {
+llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
QualifierCollector Qc;
const Type *T = Qc.strip(Ty);
@@ -570,8 +569,7 @@
return getOrCreateType(QualType(T, 0), Unit);
}
- llvm::DIType FromTy =
- getOrCreateType(Qc.apply(CGM.getContext(), T), Unit, Declaration);
+ llvm::DIType FromTy = getOrCreateType(Qc.apply(CGM.getContext(), T), Unit);
// No need to fill in the Name, Line, Size, Alignment, Offset in case of
// CVR derived types.
@@ -684,8 +682,7 @@
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, true));
+ return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit));
// Bit size, align and offset of the type.
// Size is always the size of a pointer. We can't use getTypeSize here
@@ -694,8 +691,8 @@
uint64_t Size = CGM.getTarget().getPointerWidth(AS);
uint64_t Align = CGM.getContext().getTypeAlign(Ty);
- return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit, true),
- Size, Align);
+ return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
+ Align);
}
llvm::DIType CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
@@ -771,12 +768,10 @@
return BlockLiteralGeneric;
}
-llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit,
- bool Declaration) {
+llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty, llvm::DIFile Unit) {
// 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, Declaration);
+ llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
if (!Src)
return llvm::DIType();
// We don't set size information, but do specify where the typedef was
@@ -796,7 +791,7 @@
SmallVector<llvm::Value *, 16> EltTys;
// Add the result type at least.
- EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit, true));
+ EltTys.push_back(getOrCreateType(Ty->getResultType(), Unit));
// Set up remainder of arguments if there is a prototype.
// FIXME: IF NOT, HOW IS THIS REPRESENTED? llvm-gcc doesn't represent '...'!
@@ -804,7 +799,7 @@
EltTys.push_back(DBuilder.createUnspecifiedParameter());
else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
- EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit, true));
+ EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
}
llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -1201,7 +1196,7 @@
continue;
if (TypeSourceInfo *TInfo = (*BI)->getFriendType())
EltTys.push_back(DBuilder.createFriend(
- RecordTy, getOrCreateType(TInfo->getType(), Unit, true)));
+ RecordTy, getOrCreateType(TInfo->getType(), Unit)));
}
}
@@ -1503,12 +1498,16 @@
}
/// CreateType - get structure or union type.
-llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) {
+llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) {
RecordDecl *RD = Ty->getDecl();
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
- // 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 &&
+ // 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 &&
!RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) ||
(CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) {
llvm::DIDescriptor FDContext =
@@ -1886,7 +1885,7 @@
llvm::DIType ClassType = getOrCreateType(QualType(Ty->getClass(), 0), U);
if (!Ty->getPointeeType()->isFunctionType())
return DBuilder.createMemberPointerType(
- getOrCreateType(Ty->getPointeeType(), U, true), ClassType);
+ getOrCreateType(Ty->getPointeeType(), U), ClassType);
return DBuilder.createMemberPointerType(getOrCreateInstanceMethodType(
CGM.getContext().getPointerType(
QualType(Ty->getClass(), Ty->getPointeeType().getCVRQualifiers())),
@@ -2066,26 +2065,18 @@
/// getOrCreateType - Get the type from the cache or create a new
/// one if necessary.
-llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit,
- bool Declaration) {
+llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
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 we're looking for a definition, make sure we have definitions of any
- // underlying types.
- if (const TypedefType* TTy = dyn_cast<TypedefType>(Ty))
- getOrCreateType(TTy->getDecl()->getUnderlyingType(), Unit, Declaration);
- if (Ty.hasLocalQualifiers())
- getOrCreateType(QualType(Ty.getTypePtr(), 0), Unit, Declaration);
+ if (llvm::DIType T = getCompletedTypeOrNull(Ty))
return T;
- }
// Otherwise create the type.
- llvm::DIType Res = CreateTypeNode(Ty, Unit, Declaration);
+ llvm::DIType Res = CreateTypeNode(Ty, Unit);
void* TyPtr = Ty.getAsOpaquePtr();
// And update the type cache.
@@ -2154,11 +2145,10 @@
}
/// CreateTypeNode - Create a new debug type node.
-llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit,
- bool Declaration) {
+llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile Unit) {
// Handle qualifiers, which recursively handles what they refer to.
if (Ty.hasLocalQualifiers())
- return CreateQualifiedType(Ty, Unit, Declaration);
+ return CreateQualifiedType(Ty, Unit);
const char *Diag = 0;
@@ -2193,9 +2183,9 @@
case Type::BlockPointer:
return CreateType(cast<BlockPointerType>(Ty), Unit);
case Type::Typedef:
- return CreateType(cast<TypedefType>(Ty), Unit, Declaration);
+ return CreateType(cast<TypedefType>(Ty), Unit);
case Type::Record:
- return CreateType(cast<RecordType>(Ty), Declaration);
+ return CreateType(cast<RecordType>(Ty));
case Type::Enum:
return CreateEnumType(cast<EnumType>(Ty));
case Type::FunctionProto:
@@ -2381,7 +2371,7 @@
// in unlimited debug info)
if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
- getOrCreateFile(TD->getLocation()), true);
+ getOrCreateFile(TD->getLocation()));
// 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