On Wed, Oct 15, 2014 at 9:21 PM, David Blaikie <[email protected]> wrote:
> Author: dblaikie > Date: Wed Oct 15 23:21:25 2014 > New Revision: 219900 > > URL: http://llvm.org/viewvc/llvm-project?rev=219900&view=rev > Log: > 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) > It's part of the mangling for cases like: extern int n; template<int *p> int f() {} template<int &p> int f() {} int n = f<n>() + f<&n>(); ... where there would be nothing else to distinguish the two templates. However, I note that: template<int *p> int f() {} template<const int *p> int f() {} ... are different function templates that still mangle the same for the same argument. Oops. =) > Modified: > cfe/trunk/include/clang/AST/TemplateBase.h > cfe/trunk/lib/AST/ASTContext.cpp > cfe/trunk/lib/AST/ASTImporter.cpp > cfe/trunk/lib/AST/ItaniumMangle.cpp > cfe/trunk/lib/AST/MicrosoftMangle.cpp > cfe/trunk/lib/AST/TemplateBase.cpp > cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > cfe/trunk/lib/Sema/SemaTemplate.cpp > cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp > cfe/trunk/lib/Serialization/ASTReader.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/test/CodeGenCXX/debug-info-template.cpp > > Modified: cfe/trunk/include/clang/AST/TemplateBase.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/AST/TemplateBase.h (original) > +++ cfe/trunk/include/clang/AST/TemplateBase.h Wed Oct 15 23:21:25 2014 > @@ -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 { > getParamTypeForDecl might be clearer. > assert(getKind() == Declaration && "Unexpected kind"); > - return DeclArg.ForRefParam; > + return QualType::getFromOpaquePtr(DeclArg.QT); > } > > /// \brief Retrieve the type for null non-type template argument. > > Modified: cfe/trunk/lib/AST/ASTContext.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/ASTContext.cpp (original) > +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Oct 15 23:21:25 2014 > @@ -4099,7 +4099,7 @@ ASTContext::getCanonicalTemplateArgument > > case TemplateArgument::Declaration: { > ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl()); > - return TemplateArgument(D, Arg.isDeclForReferenceParam()); > + return TemplateArgument(D, Arg.getTypeForDecl()); > } > > case TemplateArgument::NullPtr: > > Modified: cfe/trunk/lib/AST/ASTImporter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/ASTImporter.cpp (original) > +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Oct 15 23:21:25 2014 > @@ -2094,7 +2094,7 @@ ASTNodeImporter::ImportTemplateArgument( > 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()); > I think you need to import the type here. > return TemplateArgument(); > } > > > Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original) > +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Oct 15 23:21:25 2014 > @@ -3403,7 +3403,7 @@ void CXXNameMangler::mangleTemplateArg(T > // 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); > > Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original) > +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Wed Oct 15 23:21:25 2014 > @@ -1139,7 +1139,7 @@ void MicrosoftCXXNameMangler::mangleTemp > else > mangle(FD, "$1?"); > } else { > - mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?"); > + mangle(ND, TA.getTypeForDecl()->isReferenceType() ? "$E?" : "$1?"); > } > break; > } > > Modified: cfe/trunk/lib/AST/TemplateBase.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/TemplateBase.cpp (original) > +++ cfe/trunk/lib/AST/TemplateBase.cpp Wed Oct 15 23:21:25 2014 > @@ -294,8 +294,7 @@ bool TemplateArgument::structurallyEqual > 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() && > > Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Oct 15 23:21:25 2014 > @@ -1256,11 +1256,7 @@ CollectTemplateParams(const TemplatePara > 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 > > Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Oct 15 23:21:25 2014 > @@ -4617,8 +4617,8 @@ CheckTemplateArgumentAddressOfObjectOrFu > 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 CheckTemplateArgumentPointer > 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 CheckTemplateArgumentPointer > Converted = TemplateArgument(Arg); > } else { > ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl()); > - Converted = TemplateArgument(D, /*isReferenceParam*/false); > + Converted = TemplateArgument(D, ParamType); > } > return Invalid; > } > > Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Oct 15 23:21:25 2014 > @@ -262,8 +262,7 @@ checkDeducedTemplateArguments(ASTContext > // 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.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()); > > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Oct 15 23:21:25 2014 > @@ -7705,8 +7705,7 @@ ASTReader::ReadTemplateArgument(ModuleFi > 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); > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Oct 15 23:21:25 2014 > @@ -5372,7 +5372,7 @@ void ASTWriter::AddTemplateArgument(cons > 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); > > Modified: cfe/trunk/test/CodeGenCXX/debug-info-template.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-template.cpp?rev=219900&r1=219899&r2=219900&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/debug-info-template.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/debug-info-template.cpp Wed Oct 15 23:21:25 > 2014 > @@ -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; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
