r219900 - PR21246: DebugInfo: Emit the appropriate type (cv qualifiers, reference-ness, etc) for non-type template parameters

David Blaikie dblaikie at gmail.com
Wed Oct 15 21:21:25 PDT 2014


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)

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 {
     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());
     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;





More information about the cfe-commits mailing list