aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-01-21 04:37:12 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-01-21 04:37:12 +0000
commit4b12be6a354fcad670ed440ce6c1c0583ee28186 (patch)
tree925cd9470709a447df982a8eeee9813a5cb48db0
parentd9e26f59c25528b9de3c3f3939962a211a9a786d (diff)
PR14472: Preserve qualifiers while unwrapping types for debug info
Looks like r161368 fixed this for one case but not all. This change generalizes the solution over all the unwrapping cases. Now that preserving the qualifiers is done independent of the particular type being unwrapped I won't bother adding test cases for each one but at least demonstrate that this change was necessary & sufficient to fix the bug. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173002 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp23
-rw-r--r--test/CodeGenCXX/debug-info-template-quals.cpp11
2 files changed, 16 insertions, 18 deletions
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 264d075e5c..719bb69de4 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1697,12 +1697,14 @@ llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {
return DbgTy;
}
-static QualType UnwrapTypeForDebugInfo(QualType T) {
+static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
+ Qualifiers Quals;
do {
+ Quals += T.getLocalQualifiers();
QualType LastT = T;
switch (T->getTypeClass()) {
default:
- return T;
+ return C.getQualifiedType(T.getTypePtr(), Quals);
case Type::TemplateSpecialization:
T = cast<TemplateSpecializationType>(T)->desugar();
break;
@@ -1727,13 +1729,8 @@ static QualType UnwrapTypeForDebugInfo(QualType T) {
case Type::Paren:
T = cast<ParenType>(T)->getInnerType();
break;
- case Type::SubstTemplateTypeParm: {
- // We need to keep the qualifiers handy since getReplacementType()
- // will strip them away.
- unsigned Quals = T.getLocalFastQualifiers();
+ case Type::SubstTemplateTypeParm:
T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
- T.addFastQualifiers(Quals);
- }
break;
case Type::Auto:
T = cast<AutoType>(T)->getDeducedType();
@@ -1741,8 +1738,6 @@ static QualType UnwrapTypeForDebugInfo(QualType T) {
}
assert(T != LastT && "Type unwrapping failed to unwrap!");
- if (T == LastT)
- return T;
} while (true);
}
@@ -1750,7 +1745,7 @@ static QualType UnwrapTypeForDebugInfo(QualType T) {
llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {
// Unwrap the type as needed for debug information.
- Ty = UnwrapTypeForDebugInfo(Ty);
+ Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
// Check for existing entry.
llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
@@ -1769,7 +1764,7 @@ llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {
llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) {
// Unwrap the type as needed for debug information.
- Ty = UnwrapTypeForDebugInfo(Ty);
+ Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
// Check for existing entry.
llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
@@ -1791,7 +1786,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
return llvm::DIType();
// Unwrap the type as needed for debug information.
- Ty = UnwrapTypeForDebugInfo(Ty);
+ Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
llvm::DIType T = getCompletedTypeOrNull(Ty);
@@ -1903,7 +1898,7 @@ llvm::DIType CGDebugInfo::getOrCreateLimitedType(QualType Ty,
return llvm::DIType();
// Unwrap the type as needed for debug information.
- Ty = UnwrapTypeForDebugInfo(Ty);
+ Ty = UnwrapTypeForDebugInfo(Ty, CGM.getContext());
llvm::DIType T = getTypeOrNull(Ty);
diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp
index ffb1ca3849..82b9765d4c 100644
--- a/test/CodeGenCXX/debug-info-template-quals.cpp
+++ b/test/CodeGenCXX/debug-info-template-quals.cpp
@@ -4,7 +4,7 @@ template<typename _CharT>
struct basic_string {
basic_string&
- assign(const _CharT* __s)
+ assign(const _CharT* __s, const basic_string<_CharT> &x)
{
return *this;
}
@@ -12,12 +12,15 @@ struct basic_string {
void foo (const char *c) {
basic_string<char> str;
- str.assign(c);
+ str.assign(c, str);
}
// CHECK: [[P:.*]] = metadata !{i32 {{.*}}, metadata [[CON:.*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
// CHECK: [[CON]] = metadata !{i32 {{.*}}, metadata [[CH:.*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char]
// CHECK: [[CH]] = metadata !{i32 {{.*}}, metadata !"char", {{.*}}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
-// CHECK: metadata !{i32 {{.*}}, metadata !"_ZN12basic_stringIcE6assignEPKc", metadata !6, i32 7, metadata [[TYPE:.*]], i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, %struct.basic_string* (%struct.basic_string*, i8*)* @_ZN12basic_stringIcE6assignEPKc, null, metadata !18, metadata !1, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign]
+// CHECK: metadata !{i32 {{.*}}, metadata !"_ZN12basic_stringIcE6assignEPKcRKS0_", metadata !6, i32 7, metadata [[TYPE:.*]], i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, %struct.basic_string* (%struct.basic_string*, i8*, %struct.basic_string*)* @_ZN12basic_stringIcE6assignEPKcRKS0_, null, metadata !18, metadata !1, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign]
// CHECK: [[TYPE]] = metadata !{i32 {{.*}}, null, metadata [[ARGS:.*]], i32 0, i32 0}
-// CHECK: [[ARGS]] = metadata !{metadata !15, metadata !24, metadata [[P]]}
+// CHECK: [[ARGS]] = metadata !{metadata !15, metadata !24, metadata [[P]], metadata [[R:.*]]}
+// CHECK: [[BS:.*]] = metadata !{i32 {{.*}}, null, metadata !"basic_string<char>", metadata !6, i32 4, i64 8, i64 8, i32 0, i32 0, null, metadata !17, i32 0, null, metadata !27} ; [ DW_TAG_structure_type ] [basic_string<char>] [line 4, size 8, align 8, offset 0] [from ]
+// CHECK: [[R]] = metadata !{i32 {{.*}}, null, null, null, i32 0, i64 0, i64 0, i64 0, i32 0, metadata [[CON2:.*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ]
+// CHECK: [[CON2]] = metadata !{i32 {{.*}}, metadata [[BS]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from basic_string<char>]