summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2014-10-16 04:21:25 +0000
committerDavid Blaikie <dblaikie@gmail.com>2014-10-16 04:21:25 +0000
commit0f62c8d8f8338cbaeb1218e7c3b870439cebd4b9 (patch)
treee3e452eb7f8d4f643e18e5b151b69af23350d3c5
parent7f52921976906112e9022006a1ca47cf80b16bc6 (diff)
downloadbcm5719-llvm-0f62c8d8f8338cbaeb1218e7c3b870439cebd4b9.tar.gz
bcm5719-llvm-0f62c8d8f8338cbaeb1218e7c3b870439cebd4b9.zip
PR21246: DebugInfo: Emit the appropriate type (cv qualifiers, reference-ness, etc) for non-type template parameters
Plumb through the full QualType of the TemplateArgument::Declaration, as it's insufficient to only know whether the type is a reference or pointer (that was necessary for mangling, but insufficient for debug info). This shouldn't increase the size of TemplateArgument as TemplateArgument::Integer is still longer by another 32 bits. Several bits of code were testing that the reference-ness of the parameters matched, but this seemed to be insufficient (various other features of the type could've mismatched and wouldn't've been caught) and unnecessary, at least insofar as removing those tests didn't cause anything to fail. (Richard - perchaps you can hypothesize why any of these checks might need to test reference-ness of the parameters (& explain why reference-ness is part of the mangling - I would've figured that for the reference-ness to be different, a prior template argument would have to be different). I'd be happy to add them in/beef them up and add test cases if there's a reason for them) llvm-svn: 219900
-rw-r--r--clang/include/clang/AST/TemplateBase.h12
-rw-r--r--clang/lib/AST/ASTContext.cpp2
-rw-r--r--clang/lib/AST/ASTImporter.cpp2
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp2
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp2
-rw-r--r--clang/lib/AST/TemplateBase.cpp3
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp8
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp11
-rw-r--r--clang/lib/Serialization/ASTReader.cpp3
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp2
-rw-r--r--clang/test/CodeGenCXX/debug-info-template.cpp25
12 files changed, 35 insertions, 43 deletions
diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index 21b71328227..b50525c8aeb 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -76,7 +76,7 @@ private:
struct DA {
unsigned Kind;
- bool ForRefParam;
+ void *QT;
ValueDecl *D;
};
struct I {
@@ -132,11 +132,11 @@ public:
/// \brief Construct a template argument that refers to a
/// declaration, which is either an external declaration or a
/// template declaration.
- TemplateArgument(ValueDecl *D, bool ForRefParam) {
+ TemplateArgument(ValueDecl *D, QualType QT) {
assert(D && "Expected decl");
DeclArg.Kind = Declaration;
+ DeclArg.QT = QT.getAsOpaquePtr();
DeclArg.D = D;
- DeclArg.ForRefParam = ForRefParam;
}
/// \brief Construct an integral constant template argument. The memory to
@@ -249,11 +249,9 @@ public:
return DeclArg.D;
}
- /// \brief Retrieve whether a declaration is binding to a
- /// reference parameter in a declaration non-type template argument.
- bool isDeclForReferenceParam() const {
+ QualType getTypeForDecl() const {
assert(getKind() == Declaration && "Unexpected kind");
- return DeclArg.ForRefParam;
+ return QualType::getFromOpaquePtr(DeclArg.QT);
}
/// \brief Retrieve the type for null non-type template argument.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b33fdb4c707..0c8fa2a894b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4099,7 +4099,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
case TemplateArgument::Declaration: {
ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
- return TemplateArgument(D, Arg.isDeclForReferenceParam());
+ return TemplateArgument(D, Arg.getTypeForDecl());
}
case TemplateArgument::NullPtr:
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 1627e477f95..6b16cacbc94 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2094,7 +2094,7 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
case TemplateArgument::Declaration: {
ValueDecl *FromD = From.getAsDecl();
if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD)))
- return TemplateArgument(To, From.isDeclForReferenceParam());
+ return TemplateArgument(To, From.getTypeForDecl());
return TemplateArgument();
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index d2d02fac03e..fe5a50271d3 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3403,7 +3403,7 @@ void CXXNameMangler::mangleTemplateArg(TemplateArgument A) {
// and pointer-to-function expressions are represented as a declaration not
// an expression. We compensate for it here to produce the correct mangling.
ValueDecl *D = A.getAsDecl();
- bool compensateMangling = !A.isDeclForReferenceParam();
+ bool compensateMangling = !A.getTypeForDecl()->isReferenceType();
if (compensateMangling) {
Out << 'X';
mangleOperatorName(OO_Amp, 1);
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index e98a2226b76..54ac2b6352a 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1139,7 +1139,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
else
mangle(FD, "$1?");
} else {
- mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
+ mangle(ND, TA.getTypeForDecl()->isReferenceType() ? "$E?" : "$1?");
}
break;
}
diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index ac6a754fe73..929fdfc7ceb 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -294,8 +294,7 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const {
return TypeOrValue.V == Other.TypeOrValue.V;
case Declaration:
- return getAsDecl() == Other.getAsDecl() &&
- isDeclForReferenceParam() && Other.isDeclForReferenceParam();
+ return getAsDecl() == Other.getAsDecl();
case Integral:
return getIntegralType() == Other.getIntegralType() &&
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 512db76a841..0a5c40ed1ac 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1256,11 +1256,7 @@ CollectTemplateParams(const TemplateParameterList *TPList,
case TemplateArgument::Declaration: {
const ValueDecl *D = TA.getAsDecl();
bool InstanceMember = D->isCXXInstanceMember();
- QualType T = InstanceMember
- ? CGM.getContext().getMemberPointerType(
- D->getType(), cast<RecordDecl>(D->getDeclContext())
- ->getTypeForDecl())
- : CGM.getContext().getPointerType(D->getType());
+ QualType T = TA.getTypeForDecl();
llvm::DIType TTy = getOrCreateType(T, Unit);
llvm::Value *V = nullptr;
// Variable pointer template parameters have a value that is the address
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b47ce684446..428f24fd2da 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4617,8 +4617,8 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
return true;
// Create the template argument.
- Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()),
- ParamType->isReferenceType());
+ Converted =
+ TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()), ParamType);
S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity, false);
return false;
}
@@ -4713,7 +4713,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
Converted = TemplateArgument(Arg);
} else {
VD = cast<ValueDecl>(VD->getCanonicalDecl());
- Converted = TemplateArgument(VD, /*isReferenceParam*/false);
+ Converted = TemplateArgument(VD, ParamType);
}
return Invalid;
}
@@ -4742,7 +4742,7 @@ static bool CheckTemplateArgumentPointerToMember(Sema &S,
Converted = TemplateArgument(Arg);
} else {
ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
- Converted = TemplateArgument(D, /*isReferenceParam*/false);
+ Converted = TemplateArgument(D, ParamType);
}
return Invalid;
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 0bfc7693fea..5cc720f4884 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -262,8 +262,7 @@ checkDeducedTemplateArguments(ASTContext &Context,
// If we deduced two declarations, make sure they they refer to the
// same declaration.
if (Y.getKind() == TemplateArgument::Declaration &&
- isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) &&
- X.isDeclForReferenceParam() == Y.isDeclForReferenceParam())
+ isSameDeclaration(X.getAsDecl(), Y.getAsDecl()))
return X;
// All other combinations are incompatible.
@@ -384,7 +383,7 @@ DeduceNonTypeTemplateArgument(Sema &S,
"Cannot deduce non-type template argument with depth > 0");
D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
- TemplateArgument New(D, NTTP->getType()->isReferenceType());
+ TemplateArgument New(D, NTTP->getType());
DeducedTemplateArgument NewDeduced(New);
DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,
Deduced[NTTP->getIndex()],
@@ -1728,8 +1727,7 @@ DeduceTemplateArguments(Sema &S,
case TemplateArgument::Declaration:
if (Arg.getKind() == TemplateArgument::Declaration &&
- isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()) &&
- Param.isDeclForReferenceParam() == Arg.isDeclForReferenceParam())
+ isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()))
return Sema::TDK_Success;
Info.FirstArg = Param;
@@ -1964,8 +1962,7 @@ static bool isSameTemplateArg(ASTContext &Context,
Context.getCanonicalType(Y.getAsType());
case TemplateArgument::Declaration:
- return isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) &&
- X.isDeclForReferenceParam() == Y.isDeclForReferenceParam();
+ return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());
case TemplateArgument::NullPtr:
return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 96639f37f0b..51cee8cf649 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7705,8 +7705,7 @@ ASTReader::ReadTemplateArgument(ModuleFile &F,
return TemplateArgument(readType(F, Record, Idx));
case TemplateArgument::Declaration: {
ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx);
- bool ForReferenceParam = Record[Idx++];
- return TemplateArgument(D, ForReferenceParam);
+ return TemplateArgument(D, readType(F, Record, Idx));
}
case TemplateArgument::NullPtr:
return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true);
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 94eead8641f..c1df9644607 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5372,7 +5372,7 @@ void ASTWriter::AddTemplateArgument(const TemplateArgument &Arg,
break;
case TemplateArgument::Declaration:
AddDeclRef(Arg.getAsDecl(), Record);
- Record.push_back(Arg.isDeclForReferenceParam());
+ AddTypeRef(Arg.getTypeForDecl(), Record);
break;
case TemplateArgument::NullPtr:
AddTypeRef(Arg.getNullPtrType(), Record);
diff --git a/clang/test/CodeGenCXX/debug-info-template.cpp b/clang/test/CodeGenCXX/debug-info-template.cpp
index 95a99ec6691..d1b13d03307 100644
--- a/clang/test/CodeGenCXX/debug-info-template.cpp
+++ b/clang/test/CodeGenCXX/debug-info-template.cpp
@@ -15,9 +15,9 @@
// CHECK: [[TCARG1]] = metadata !{metadata !"0x2f\00T\000\000", null, metadata [[UINT:![0-9]*]], null} ; [ DW_TAG_template_type_parameter ]
// CHECK: [[UINT:![0-9]*]] = {{.*}} ; [ DW_TAG_base_type ] [unsigned int]
// CHECK: [[TCARG2]] = metadata !{metadata !"0x30\00\00{{.*}}", {{[^,]+}}, metadata [[UINT]], i32 2, {{.*}} ; [ DW_TAG_template_value_parameter ]
-// CHECK: [[TCARG3]] = metadata !{metadata !"0x30\00x\00{{.*}}", {{[^,]+}}, metadata [[INTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]
-// CHECK: [[INTPTR]] = {{.*}}, metadata [[INT:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]
-// CECK: [[TCARG3]] = metadata !{metadata !"0x30\00x\00{{.*}}", {{[^,]+}}, metadata [[CINTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]
+// CHECK: [[TCARG3]] = metadata !{metadata !"0x30\00x\00{{.*}}", {{[^,]+}}, metadata [[CINTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]
+// CHECK: [[CINTPTR]] = {{.*}}, metadata [[CINT:![0-9]*]]} ; [ DW_TAG_pointer_type ] {{.*}} [from ]
+// CHECK: [[CINT]] = {{.*}}, metadata [[INT:![0-9]*]]} ; [ DW_TAG_const_type ] {{.*}} [from int]
// CHECK: [[INT]] = {{.*}} ; [ DW_TAG_base_type ] [int]
// CHECK: [[TCARG4]] = metadata !{metadata !"0x30\00a\00{{.*}}", {{[^,]+}}, metadata [[MEMINTPTR:![0-9]*]], i64 8, {{.*}} ; [ DW_TAG_template_value_parameter ]
// CHECK: [[MEMINTPTR]] = {{.*}}, metadata !"_ZTS3foo"} ; [ DW_TAG_ptr_to_member_type ] {{.*}}[from int]
@@ -49,15 +49,12 @@
// CHECK: metadata !"0x2e\00f\00f\00_ZN3foo1fEv\00{{.*}}", metadata [[FTYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ]
//
-
// CHECK: metadata !{metadata !"0x13\00{{.*}}", metadata !{{[0-9]*}}, metadata !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_Z4funcvEEJLi1ELi2ELi3EEE", {{.*}}, metadata !"[[TCNESTED:.*]]"} ; [ DW_TAG_structure_type ] [nested]
// CHECK: metadata [[TCNARGS:![0-9]*]], metadata !"[[TCNT:.*]]"} ; [ DW_TAG_structure_type ] [TC<int, -3, nullptr, nullptr, nullptr, nullptr>]
// CHECK: [[TCNARGS]] = metadata !{metadata [[TCNARG1:![0-9]*]], metadata [[TCNARG2:![0-9]*]], metadata [[TCNARG3:![0-9]*]], metadata [[TCNARG4:![0-9]*]], metadata [[TCNARG5:![0-9]*]], metadata [[TCNARG6:![0-9]*]], metadata [[TCNARG7:![0-9]*]]}
// CHECK: [[TCNARG1]] = metadata !{metadata !"0x2f\00T\000\000", null, metadata [[INT]], null} ; [ DW_TAG_template_type_parameter ]
// CHECK: [[TCNARG2]] = metadata !{metadata !"0x30\00\000\000", null, metadata [[INT]], i32 -3, null} ; [ DW_TAG_template_value_parameter ]
-// CHECK: [[TCNARG3]] = metadata !{metadata !"0x30\00x\000\000", null, metadata [[CINTPTR:![0-9]*]], i8 0, null} ; [ DW_TAG_template_value_parameter ]
-// CHECK: [[CINTPTR]] = {{.*}}, metadata [[CINT:![0-9]*]]} ; [ DW_TAG_pointer_type ] {{.*}} [from ]
-// CHECK: [[CINT]] = {{.*}}, metadata [[INT]]} ; [ DW_TAG_const_type ] {{.*}} [from int]
+// CHECK: [[TCNARG3]] = metadata !{metadata !"0x30\00x\000\000", null, metadata [[CINTPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ]
// The interesting null pointer: -1 for member data pointers (since they are
// just an offset in an object, they can be zero and non-null for the first
@@ -74,9 +71,15 @@
// CHECK: [[TCNARG6]] = metadata !{metadata !"0x30\00f\000\000", null, metadata [[FUNPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ]
// CHECK: [[TCNARG7]] = metadata !{metadata !"0x4107\00Is\000\000", null, null, metadata [[EMPTY]], null} ; [ DW_TAG_GNU_template_parameter_pack ]
-// CHECK: metadata [[NNARGS:![0-9]*]], metadata !"[[NNT:.*]]"} ; [ DW_TAG_structure_type ] [NN<tmpl_impl>]
-// CHECK: [[NNARGS]] = metadata !{metadata [[NNARG1:![0-9]*]]}
+// FIXME: these parameters should probably be rendered as 'glb' rather than
+// '&glb', since they're references, not pointers.
+// CHECK: metadata [[NNARGS:![0-9]*]], metadata !"[[NNT:.*]]"} ; [ DW_TAG_structure_type ] [NN<tmpl_impl, &glb, &glb>]
+// CHECK: [[NNARGS]] = metadata !{metadata [[NNARG1:![0-9]*]], metadata [[NNARG2:![0-9]*]], metadata [[NNARG3:![0-9]*]]}
// CHECK: [[NNARG1]] = metadata !{metadata !"0x4106\00tmpl\000\000", null, null, metadata !"tmpl_impl", null} ; [ DW_TAG_GNU_template_template_param ]
+// CHECK: [[NNARG2]] = metadata !{metadata !"0x30\00lvr\00{{.*}}", {{[^,]+}}, metadata [[INTLVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]
+// CHECK: [[INTLVR]] = {{.*}}, metadata [[INT]]} ; [ DW_TAG_reference_type ] {{.*}} [from int]
+// CHECK: [[NNARG3]] = metadata !{metadata !"0x30\00rvr\00{{.*}}", {{[^,]+}}, metadata [[INTRVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]
+// CHECK: [[INTRVR]] = {{.*}}, metadata [[INT]]} ; [ DW_TAG_rvalue_reference_type ] {{.*}} [from int]
// CHECK: metadata [[PTOARGS:![0-9]*]], metadata !"{{.*}}"} ; [ DW_TAG_structure_type ] [PaddingAtEndTemplate<&PaddedObj>]
// CHECK: [[PTOARGS]] = metadata !{metadata [[PTOARG1:![0-9]*]]}
@@ -110,11 +113,11 @@ template<typename>
struct tmpl_impl {
};
-template<template <typename> class tmpl>
+template <template <typename> class tmpl, int &lvr, int &&rvr>
struct NN {
};
-NN<tmpl_impl> nn;
+NN<tmpl_impl, glb, glb> nn;
struct PaddingAtEnd {
int i;
OpenPOWER on IntegriCloud