<div dir="ltr">(still a patch/question upthread waiting on you, Richard, regarding the deserialization of the type in the TemplateArgument, btw)<br><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Oct 18, 2014 at 4:29 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Fri, Oct 17, 2014 at 7:33 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Fri, Oct 17, 2014 at 12:30 PM, Stephen Crane <span dir="ltr"><<a href="mailto:sjcrane@uci.edu" target="_blank">sjcrane@uci.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><div>Hi,<br><br></div>It looks like this rev broke chrome builds because of typedef'd template types. Bug report: <a href="http://llvm.org/bugs/show_bug.cgi?id=21305" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=21305</a>. I'll see if I can fix this quick.</div></div></blockquote><div><br></div></span><div>Thanks for the help - committed in <span style="color:rgb(0,0,0)">r220122, including a test update.<br><br>Richard - is this reasonable? Should we instead store the desugared value in the TemplateArgument? (rather than desugaring it in debug info when emitting the type)</span></div></div></div></div></blockquote><div><br></div></span><div>We have canonical and non-canonical TemplateArguments; the former should have canonical types.</div></div></div></div></blockquote><div><br></div><div>Any idea if there are test cases would demonstrate the difference here? (I guess not, seems the only thing that cares about this is the mangling which is just "is this a reference"). Not sure how I'd tell if I got the source fidelity correct here, in particular which TemplateArguments are non-canonical and canonical... </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div> I'm not sure what kind end up in the debug info emission code, though.</div><div><div class="h5"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div><span><font color="#888888"><br></font></span></div><span><font color="#888888"><div>- stephen<br></div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 17, 2014 at 11:13 AM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><div><div>On Thu, Oct 16, 2014 at 7:17 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span>On Wed, Oct 15, 2014 at 9:21 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: dblaikie<br>
Date: Wed Oct 15 23:21:25 2014<br>
New Revision: 219900<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=219900&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=219900&view=rev</a><br>
Log:<br>
PR21246: DebugInfo: Emit the appropriate type (cv qualifiers, reference-ness, etc) for non-type template parameters<br>
<br>
Plumb through the full QualType of the TemplateArgument::Declaration, as<br>
it's insufficient to only know whether the type is a reference or<br>
pointer (that was necessary for mangling, but insufficient for debug<br>
info). This shouldn't increase the size of TemplateArgument as<br>
TemplateArgument::Integer is still longer by another 32 bits.<br>
<br>
Several bits of code were testing that the reference-ness of the<br>
parameters matched, but this seemed to be insufficient (various other<br>
features of the type could've mismatched and wouldn't've been caught)<br>
and unnecessary, at least insofar as removing those tests didn't cause<br>
anything to fail.<br>
<br>
(Richard - perchaps you can hypothesize why any of these checks might<br>
need to test reference-ness of the parameters (& explain why<br>
reference-ness is part of the mangling - I would've figured that for the<br>
reference-ness to be different, a prior template argument would have to<br>
be different). I'd be happy to add them in/beef them up and add test<br>
cases if there's a reason for them)<br></blockquote><div><br></div></span><div>It's part of the mangling for cases like:</div><div><br></div><div>extern int n;</div><div>template<int *p> int f() {}</div><div>template<int &p> int f() {}</div></div></div></div></blockquote></div></div><div><br>Huh, didn't even consider overloading like that.<br> </div><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>int n = f<n>() + f<&n>();</div><div><br></div><div>... where there would be nothing else to distinguish the two templates. However, I note that:</div><div><br></div><div><div>template<int *p> int f() {}<br></div><div>template<const int *p> int f() {}<br></div><div><br></div></div><div>... are different function templates that still mangle the same for the same argument. Oops. =)</div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Modified:<br>
    cfe/trunk/include/clang/AST/TemplateBase.h<br>
    cfe/trunk/lib/AST/ASTContext.cpp<br>
    cfe/trunk/lib/AST/ASTImporter.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
    cfe/trunk/lib/AST/MicrosoftMangle.cpp<br>
    cfe/trunk/lib/AST/TemplateBase.cpp<br>
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp<br>
    cfe/trunk/lib/Serialization/ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
    cfe/trunk/test/CodeGenCXX/debug-info-template.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/TemplateBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)<br>
+++ cfe/trunk/include/clang/AST/TemplateBase.h Wed Oct 15 23:21:25 2014<br>
@@ -76,7 +76,7 @@ private:<br>
<br>
   struct DA {<br>
     unsigned Kind;<br>
-    bool ForRefParam;<br>
+    void *QT;<br>
     ValueDecl *D;<br>
   };<br>
   struct I {<br>
@@ -132,11 +132,11 @@ public:<br>
   /// \brief Construct a template argument that refers to a<br>
   /// declaration, which is either an external declaration or a<br>
   /// template declaration.<br>
-  TemplateArgument(ValueDecl *D, bool ForRefParam) {<br>
+  TemplateArgument(ValueDecl *D, QualType QT) {<br>
     assert(D && "Expected decl");<br>
     DeclArg.Kind = Declaration;<br>
+    DeclArg.QT = QT.getAsOpaquePtr();<br>
     DeclArg.D = D;<br>
-    DeclArg.ForRefParam = ForRefParam;<br>
   }<br>
<br>
   /// \brief Construct an integral constant template argument. The memory to<br>
@@ -249,11 +249,9 @@ public:<br>
     return DeclArg.D;<br>
   }<br>
<br>
-  /// \brief Retrieve whether a declaration is binding to a<br>
-  /// reference parameter in a declaration non-type template argument.<br>
-  bool isDeclForReferenceParam() const {<br>
+  QualType getTypeForDecl() const {<br></blockquote><div><br></div></div></div><div>getParamTypeForDecl might be clearer.</div></div></div></div></blockquote></div></div><div><br>Good point -adjusted (with some other minor cleanup) in <span style="color:rgb(0,0,0)">r220060.</span><br> </div><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
     assert(getKind() == Declaration && "Unexpected kind");<br>
-    return DeclArg.ForRefParam;<br>
+    return QualType::getFromOpaquePtr(DeclArg.QT);<br>
   }<br>
<br>
   /// \brief Retrieve the type for null non-type template argument.<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Oct 15 23:21:25 2014<br>
@@ -4099,7 +4099,7 @@ ASTContext::getCanonicalTemplateArgument<br>
<br>
     case TemplateArgument::Declaration: {<br>
       ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());<br>
-      return TemplateArgument(D, Arg.isDeclForReferenceParam());<br>
+      return TemplateArgument(D, Arg.getTypeForDecl());<br>
     }<br>
<br>
     case TemplateArgument::NullPtr:<br>
<br>
Modified: cfe/trunk/lib/AST/ASTImporter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Oct 15 23:21:25 2014<br>
@@ -2094,7 +2094,7 @@ ASTNodeImporter::ImportTemplateArgument(<br>
   case TemplateArgument::Declaration: {<br>
     ValueDecl *FromD = From.getAsDecl();<br>
     if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD)))<br>
-      return TemplateArgument(To, From.isDeclForReferenceParam());<br>
+      return TemplateArgument(To, From.getTypeForDecl());<br></blockquote><div><br></div></div></div><div>I think you need to import the type here.</div></div></div></div></blockquote><div><br></div></div></div><div>Hrm. Something like this, maybe:<br><br><pre style="color:rgb(0,0,0)">-    ValueDecl *FromD = From.getAsDecl();
-    if (ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(FromD)))
-      return TemplateArgument(To, From.getParamTypeForDecl());
-    return TemplateArgument();
+    auto *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl()));
+    QualType ToType = Importer.Import(From.getParamTypeForDecl());
+    if (!To || ToType.isNull())
+      return TemplateArgument();
+    return TemplateArgument(To, ToType);

?

Any idea what test case would exercise this? (I don't have much of a clue about how the lazy deserialization works - which bits happen implicitly versus explicitly, etc)</pre></div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
     return TemplateArgument();<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Oct 15 23:21:25 2014<br>
@@ -3403,7 +3403,7 @@ void CXXNameMangler::mangleTemplateArg(T<br>
     // and pointer-to-function expressions are represented as a declaration not<br>
     // an expression. We compensate for it here to produce the correct mangling.<br>
     ValueDecl *D = A.getAsDecl();<br>
-    bool compensateMangling = !A.isDeclForReferenceParam();<br>
+    bool compensateMangling = !A.getTypeForDecl()->isReferenceType();<br>
     if (compensateMangling) {<br>
       Out << 'X';<br>
       mangleOperatorName(OO_Amp, 1);<br>
<br>
Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Wed Oct 15 23:21:25 2014<br>
@@ -1139,7 +1139,7 @@ void MicrosoftCXXNameMangler::mangleTemp<br>
       else<br>
         mangle(FD, "$1?");<br>
     } else {<br>
-      mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");<br>
+      mangle(ND, TA.getTypeForDecl()->isReferenceType() ? "$E?" : "$1?");<br>
     }<br>
     break;<br>
   }<br>
<br>
Modified: cfe/trunk/lib/AST/TemplateBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/TemplateBase.cpp Wed Oct 15 23:21:25 2014<br>
@@ -294,8 +294,7 @@ bool TemplateArgument::structurallyEqual<br>
     return TypeOrValue.V == Other.TypeOrValue.V;<br>
<br>
   case Declaration:<br>
-    return getAsDecl() == Other.getAsDecl() &&<br>
-           isDeclForReferenceParam() && Other.isDeclForReferenceParam();<br>
+    return getAsDecl() == Other.getAsDecl();<br>
<br>
   case Integral:<br>
     return getIntegralType() == Other.getIntegralType() &&<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Oct 15 23:21:25 2014<br>
@@ -1256,11 +1256,7 @@ CollectTemplateParams(const TemplatePara<br>
     case TemplateArgument::Declaration: {<br>
       const ValueDecl *D = TA.getAsDecl();<br>
       bool InstanceMember = D->isCXXInstanceMember();<br>
-      QualType T = InstanceMember<br>
-                       ? CGM.getContext().getMemberPointerType(<br>
-                             D->getType(), cast<RecordDecl>(D->getDeclContext())<br>
-                                               ->getTypeForDecl())<br>
-                       : CGM.getContext().getPointerType(D->getType());<br>
+      QualType T = TA.getTypeForDecl();<br>
       llvm::DIType TTy = getOrCreateType(T, Unit);<br>
       llvm::Value *V = nullptr;<br>
       // Variable pointer template parameters have a value that is the address<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Oct 15 23:21:25 2014<br>
@@ -4617,8 +4617,8 @@ CheckTemplateArgumentAddressOfObjectOrFu<br>
     return true;<br>
<br>
   // Create the template argument.<br>
-  Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()),<br>
-                               ParamType->isReferenceType());<br>
+  Converted =<br>
+      TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()), ParamType);<br>
   S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity, false);<br>
   return false;<br>
 }<br>
@@ -4713,7 +4713,7 @@ static bool CheckTemplateArgumentPointer<br>
             Converted = TemplateArgument(Arg);<br>
           } else {<br>
             VD = cast<ValueDecl>(VD->getCanonicalDecl());<br>
-            Converted = TemplateArgument(VD, /*isReferenceParam*/false);<br>
+            Converted = TemplateArgument(VD, ParamType);<br>
           }<br>
           return Invalid;<br>
         }<br>
@@ -4742,7 +4742,7 @@ static bool CheckTemplateArgumentPointer<br>
       Converted = TemplateArgument(Arg);<br>
     } else {<br>
       ValueDecl *D = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());<br>
-      Converted = TemplateArgument(D, /*isReferenceParam*/false);<br>
+      Converted = TemplateArgument(D, ParamType);<br>
     }<br>
     return Invalid;<br>
   }<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Oct 15 23:21:25 2014<br>
@@ -262,8 +262,7 @@ checkDeducedTemplateArguments(ASTContext<br>
     // If we deduced two declarations, make sure they they refer to the<br>
     // same declaration.<br>
     if (Y.getKind() == TemplateArgument::Declaration &&<br>
-        isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) &&<br>
-        X.isDeclForReferenceParam() == Y.isDeclForReferenceParam())<br>
+        isSameDeclaration(X.getAsDecl(), Y.getAsDecl()))<br>
       return X;<br>
<br>
     // All other combinations are incompatible.<br>
@@ -384,7 +383,7 @@ DeduceNonTypeTemplateArgument(Sema &S,<br>
          "Cannot deduce non-type template argument with depth > 0");<br>
<br>
   D = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;<br>
-  TemplateArgument New(D, NTTP->getType()->isReferenceType());<br>
+  TemplateArgument New(D, NTTP->getType());<br>
   DeducedTemplateArgument NewDeduced(New);<br>
   DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context,<br>
                                                      Deduced[NTTP->getIndex()],<br>
@@ -1728,8 +1727,7 @@ DeduceTemplateArguments(Sema &S,<br>
<br>
   case TemplateArgument::Declaration:<br>
     if (Arg.getKind() == TemplateArgument::Declaration &&<br>
-        isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()) &&<br>
-        Param.isDeclForReferenceParam() == Arg.isDeclForReferenceParam())<br>
+        isSameDeclaration(Param.getAsDecl(), Arg.getAsDecl()))<br>
       return Sema::TDK_Success;<br>
<br>
     Info.FirstArg = Param;<br>
@@ -1964,8 +1962,7 @@ static bool isSameTemplateArg(ASTContext<br>
              Context.getCanonicalType(Y.getAsType());<br>
<br>
     case TemplateArgument::Declaration:<br>
-      return isSameDeclaration(X.getAsDecl(), Y.getAsDecl()) &&<br>
-             X.isDeclForReferenceParam() == Y.isDeclForReferenceParam();<br>
+      return isSameDeclaration(X.getAsDecl(), Y.getAsDecl());<br>
<br>
     case TemplateArgument::NullPtr:<br>
       return Context.hasSameType(X.getNullPtrType(), Y.getNullPtrType());<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Oct 15 23:21:25 2014<br>
@@ -7705,8 +7705,7 @@ ASTReader::ReadTemplateArgument(ModuleFi<br>
     return TemplateArgument(readType(F, Record, Idx));<br>
   case TemplateArgument::Declaration: {<br>
     ValueDecl *D = ReadDeclAs<ValueDecl>(F, Record, Idx);<br>
-    bool ForReferenceParam = Record[Idx++];<br>
-    return TemplateArgument(D, ForReferenceParam);<br>
+    return TemplateArgument(D, readType(F, Record, Idx));<br>
   }<br>
   case TemplateArgument::NullPtr:<br>
     return TemplateArgument(readType(F, Record, Idx), /*isNullPtr*/true);<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Oct 15 23:21:25 2014<br>
@@ -5372,7 +5372,7 @@ void ASTWriter::AddTemplateArgument(cons<br>
     break;<br>
   case TemplateArgument::Declaration:<br>
     AddDeclRef(Arg.getAsDecl(), Record);<br>
-    Record.push_back(Arg.isDeclForReferenceParam());<br>
+    AddTypeRef(Arg.getTypeForDecl(), Record);<br>
     break;<br>
   case TemplateArgument::NullPtr:<br>
     AddTypeRef(Arg.getNullPtrType(), Record);<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/debug-info-template.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-template.cpp?rev=219900&r1=219899&r2=219900&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-template.cpp?rev=219900&r1=219899&r2=219900&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/debug-info-template.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/debug-info-template.cpp Wed Oct 15 23:21:25 2014<br>
@@ -15,9 +15,9 @@<br>
 // CHECK: [[TCARG1]] = metadata !{metadata !"0x2f\00T\000\000", null, metadata [[UINT:![0-9]*]], null} ; [ DW_TAG_template_type_parameter ]<br>
 // CHECK: [[UINT:![0-9]*]] = {{.*}} ; [ DW_TAG_base_type ] [unsigned int]<br>
 // CHECK: [[TCARG2]] = metadata !{metadata !"0x30\00\00{{.*}}", {{[^,]+}}, metadata [[UINT]], i32 2, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
-// CHECK: [[TCARG3]] = metadata !{metadata !"0x30\00x\00{{.*}}", {{[^,]+}}, metadata [[INTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
-// CHECK: [[INTPTR]] = {{.*}}, metadata [[INT:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int]<br>
-// CECK: [[TCARG3]] = metadata !{metadata !"0x30\00x\00{{.*}}", {{[^,]+}}, metadata [[CINTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
+// CHECK: [[TCARG3]] = metadata !{metadata !"0x30\00x\00{{.*}}", {{[^,]+}}, metadata [[CINTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
+// CHECK: [[CINTPTR]] = {{.*}}, metadata [[CINT:![0-9]*]]} ; [ DW_TAG_pointer_type ] {{.*}} [from ]<br>
+// CHECK: [[CINT]] = {{.*}}, metadata [[INT:![0-9]*]]} ; [ DW_TAG_const_type ] {{.*}} [from int]<br>
 // CHECK: [[INT]] = {{.*}} ; [ DW_TAG_base_type ] [int]<br>
 // CHECK: [[TCARG4]] = metadata !{metadata !"0x30\00a\00{{.*}}", {{[^,]+}}, metadata [[MEMINTPTR:![0-9]*]], i64 8, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
 // CHECK: [[MEMINTPTR]] = {{.*}}, metadata !"_ZTS3foo"} ; [ DW_TAG_ptr_to_member_type ] {{.*}}[from int]<br>
@@ -49,15 +49,12 @@<br>
 // CHECK: metadata !"0x2e\00f\00f\00_ZN3foo1fEv\00{{.*}}", metadata [[FTYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ]<br>
 //<br>
<br>
-<br>
 // CHECK: metadata !{metadata !"0x13\00{{.*}}", metadata !{{[0-9]*}}, metadata !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_Z4funcvEEJLi1ELi2ELi3EEE", {{.*}}, metadata !"[[TCNESTED:.*]]"} ; [ DW_TAG_structure_type ] [nested]<br>
 // CHECK: metadata [[TCNARGS:![0-9]*]], metadata !"[[TCNT:.*]]"} ; [ DW_TAG_structure_type ] [TC<int, -3, nullptr, nullptr, nullptr, nullptr>]<br>
 // 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]*]]}<br>
 // CHECK: [[TCNARG1]] = metadata !{metadata !"0x2f\00T\000\000", null, metadata [[INT]], null} ; [ DW_TAG_template_type_parameter ]<br>
 // CHECK: [[TCNARG2]] = metadata !{metadata !"0x30\00\000\000", null, metadata [[INT]], i32 -3, null} ; [ DW_TAG_template_value_parameter ]<br>
-// CHECK: [[TCNARG3]] = metadata !{metadata !"0x30\00x\000\000", null, metadata [[CINTPTR:![0-9]*]], i8 0, null} ; [ DW_TAG_template_value_parameter ]<br>
-// CHECK: [[CINTPTR]] = {{.*}}, metadata [[CINT:![0-9]*]]} ; [ DW_TAG_pointer_type ] {{.*}} [from ]<br>
-// CHECK: [[CINT]] = {{.*}}, metadata [[INT]]} ; [ DW_TAG_const_type ] {{.*}} [from int]<br>
+// CHECK: [[TCNARG3]] = metadata !{metadata !"0x30\00x\000\000", null, metadata [[CINTPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ]<br>
<br>
 // The interesting null pointer: -1 for member data pointers (since they are<br>
 // just an offset in an object, they can be zero and non-null for the first<br>
@@ -74,9 +71,15 @@<br>
 // CHECK: [[TCNARG6]] = metadata !{metadata !"0x30\00f\000\000", null, metadata [[FUNPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ]<br>
 // CHECK: [[TCNARG7]] = metadata !{metadata !"0x4107\00Is\000\000", null, null, metadata [[EMPTY]], null} ; [ DW_TAG_GNU_template_parameter_pack ]<br>
<br>
-// CHECK: metadata [[NNARGS:![0-9]*]], metadata !"[[NNT:.*]]"} ; [ DW_TAG_structure_type ] [NN<tmpl_impl>]<br>
-// CHECK: [[NNARGS]] = metadata !{metadata [[NNARG1:![0-9]*]]}<br>
+// FIXME: these parameters should probably be rendered as 'glb' rather than<br>
+// '&glb', since they're references, not pointers.<br>
+// CHECK: metadata [[NNARGS:![0-9]*]], metadata !"[[NNT:.*]]"} ; [ DW_TAG_structure_type ] [NN<tmpl_impl, &glb, &glb>]<br>
+// CHECK: [[NNARGS]] = metadata !{metadata [[NNARG1:![0-9]*]], metadata [[NNARG2:![0-9]*]], metadata [[NNARG3:![0-9]*]]}<br>
 // CHECK: [[NNARG1]] = metadata !{metadata !"0x4106\00tmpl\000\000", null, null, metadata !"tmpl_impl", null} ; [ DW_TAG_GNU_template_template_param ]<br>
+// CHECK: [[NNARG2]] = metadata !{metadata !"0x30\00lvr\00{{.*}}", {{[^,]+}}, metadata [[INTLVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
+// CHECK: [[INTLVR]] = {{.*}}, metadata [[INT]]} ; [ DW_TAG_reference_type ] {{.*}} [from int]<br>
+// CHECK: [[NNARG3]] = metadata !{metadata !"0x30\00rvr\00{{.*}}", {{[^,]+}}, metadata [[INTRVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ]<br>
+// CHECK: [[INTRVR]] = {{.*}}, metadata [[INT]]} ; [ DW_TAG_rvalue_reference_type ] {{.*}} [from int]<br>
<br>
 // CHECK: metadata [[PTOARGS:![0-9]*]], metadata !"{{.*}}"} ; [ DW_TAG_structure_type ] [PaddingAtEndTemplate<&PaddedObj>]<br>
 // CHECK: [[PTOARGS]] = metadata !{metadata [[PTOARG1:![0-9]*]]}<br>
@@ -110,11 +113,11 @@ template<typename><br>
 struct tmpl_impl {<br>
 };<br>
<br>
-template<template <typename> class tmpl><br>
+template <template <typename> class tmpl, int &lvr, int &&rvr><br>
 struct NN {<br>
 };<br>
<br>
-NN<tmpl_impl> nn;<br>
+NN<tmpl_impl, glb, glb> nn;<br>
<br>
 struct PaddingAtEnd {<br>
   int i;<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>