From 363e5acfd93aa62d94e02b674e753257389643b1 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Tue, 7 Aug 2012 00:14:25 +0000 Subject: [PATCH] Make sure when we get the replacement type for a template argument that we attach the lost qualifiers. Fixes rdar://11882155 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161368 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDebugInfo.cpp | 19 +++++++++++---- test/CodeGenCXX/debug-info-template-quals.cpp | 23 +++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 test/CodeGenCXX/debug-info-template-quals.cpp diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index ce3d97abe3..9dedf37cc9 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -558,7 +558,7 @@ llvm::DIType CGDebugInfo::CreatePointeeType(QualType PointeeTy, // Handle qualifiers. if (PointeeTy.hasLocalQualifiers()) - return CreateQualifiedType(PointeeTy, Unit); + return CreateQualifiedType(PointeeTy.getCanonicalType(), Unit); if (const RecordType *RTy = dyn_cast(PointeeTy)) { RecordDecl *RD = RTy->getDecl(); @@ -685,8 +685,9 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty, if (isa(Ty)) EltTys.push_back(DBuilder.createUnspecifiedParameter()); else if (const FunctionProtoType *FPT = dyn_cast(Ty)) { - for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i) + for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i) { EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit)); + } } llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys); @@ -1629,8 +1630,13 @@ static QualType UnwrapTypeForDebugInfo(QualType T) { case Type::Paren: T = cast(T)->getInnerType(); break; - case Type::SubstTemplateTypeParm: + case Type::SubstTemplateTypeParm: { + // We need to keep the qualifiers handy since getReplacementType() + // will strip them away. + unsigned Quals = T.getLocalFastQualifiers(); T = cast(T)->getReplacementType(); + T.addFastQualifiers(Quals); + } break; case Type::Auto: T = cast(T)->getDeducedType(); @@ -1689,10 +1695,11 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { // Unwrap the type as needed for debug information. Ty = UnwrapTypeForDebugInfo(Ty); - + llvm::DIType T = getCompletedTypeOrNull(Ty); - if (T.Verify()) return T; + if (T.Verify()) + return T; // Otherwise create the type. llvm::DIType Res = CreateTypeNode(Ty, Unit); @@ -1707,6 +1714,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) { if (!Res.isForwardDecl()) CompletedTypeCache[Ty.getAsOpaquePtr()] = Res; + return Res; } @@ -1958,6 +1966,7 @@ llvm::DISubprogram CGDebugInfo::getFunctionDeclaration(const Decl *D) { llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl * D, QualType FnType, llvm::DIFile F) { + if (const CXXMethodDecl *Method = dyn_cast(D)) return getOrCreateMethodType(Method, F); if (const ObjCMethodDecl *OMethod = dyn_cast(D)) { diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp new file mode 100644 index 0000000000..ab7136bf54 --- /dev/null +++ b/test/CodeGenCXX/debug-info-template-quals.cpp @@ -0,0 +1,23 @@ +// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s + +template +struct basic_string { + + basic_string& + assign(const _CharT* __s) + { + return *this; + } +}; + +void foo (const char *c) { + basic_string str; + str.assign(c); +} + +// 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: [[TYPE]] = metadata !{i32 {{.*}}, null, metadata [[ARGS:.*]], i32 0, i32 0} +// CHECK: [[ARGS]] = metadata !{metadata !15, metadata !23, metadata [[P]]} -- 2.40.0