[cfe-commits] r122896 - in /cfe/trunk: include/clang/AST/ lib/AST/ lib/CodeGen/ lib/Sema/ lib/Serialization/ test/CXX/temp/temp.decls/temp.variadic/ tools/libclang/

Douglas Gregor dgregor at apple.com
Wed Jan 5 10:58:32 PST 2011


Author: dgregor
Date: Wed Jan  5 12:58:31 2011
New Revision: 122896

URL: http://llvm.org/viewvc/llvm-project?rev=122896&view=rev
Log:
Replace the representation of template template argument pack
expansions with something that is easier to use correctly: a new
template argment kind, rather than a bit on an existing kind. Update
all of the switch statements that deal with template arguments, fixing
a few latent bugs in the process. I"m happy with this representation,
now.

And, oh look! Template instantiation and deduction work for template
template argument pack expansions.


Modified:
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/TemplateBase.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DumpXML.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/AST/TemplateBase.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CIndexUSRs.cpp

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Jan  5 12:58:31 2011
@@ -535,7 +535,9 @@
     return getDerived().TraverseType(Arg.getAsType());
 
   case TemplateArgument::Template:
-    return getDerived().TraverseTemplateName(Arg.getAsTemplate());
+  case TemplateArgument::TemplateExpansion:
+    return getDerived().TraverseTemplateName(
+                                          Arg.getAsTemplateOrTemplatePattern());
 
   case TemplateArgument::Expression:
     return getDerived().TraverseStmt(Arg.getAsExpr());
@@ -570,7 +572,9 @@
   }
 
   case TemplateArgument::Template:
-    return getDerived().TraverseTemplateName(Arg.getAsTemplate());
+  case TemplateArgument::TemplateExpansion:
+    return getDerived().TraverseTemplateName(
+                                         Arg.getAsTemplateOrTemplatePattern());
 
   case TemplateArgument::Expression:
     return getDerived().TraverseStmt(ArgLoc.getSourceExpression());

Modified: cfe/trunk/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateBase.h?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateBase.h (original)
+++ cfe/trunk/include/clang/AST/TemplateBase.h Wed Jan  5 12:58:31 2011
@@ -55,6 +55,9 @@
     /// The template argument is a template name that was provided for a 
     /// template template parameter.
     Template,
+    /// The template argument is a pack expansion of a template name that was 
+    /// provided for a template template parameter.
+    TemplateExpansion,
     /// The template argument is a value- or type-dependent expression
     /// stored in an Expr*.
     Expression,
@@ -77,10 +80,6 @@
       TemplateArgument *Args;
       unsigned NumArgs;
     } Args;
-    struct {
-      void *Template;
-      bool PackExpansion;
-    } TemplateArg;
   };
 
 public:
@@ -119,10 +118,9 @@
   /// \param Name The template name.
   /// \param PackExpansion Whether this template argument is a pack expansion.
   TemplateArgument(TemplateName Name, bool PackExpansion = false) 
-    : Kind(Template) 
+    : Kind(PackExpansion? TemplateExpansion : Template) 
   {
-    TemplateArg.Template = Name.getAsVoidPointer();
-    TemplateArg.PackExpansion = PackExpansion;
+    TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
   }
   
   /// \brief Construct a template argument that is an expression.
@@ -153,8 +151,6 @@
     } else if (Kind == Pack) {
       Args.NumArgs = Other.Args.NumArgs;
       Args.Args = Other.Args.Args;
-    } else if (Kind == Template) {
-      TemplateArg = Other.TemplateArg;
     } else
       TypeOrValue = Other.TypeOrValue;
   }
@@ -181,8 +177,6 @@
     } else if (Other.Kind == Pack) {
       Args.NumArgs = Other.Args.NumArgs;
       Args.Args = Other.Args.Args;
-    } else if (Other.Kind == Template) {
-      TemplateArg = Other.TemplateArg;
     } else {
       TypeOrValue = Other.TypeOrValue;
     }
@@ -234,9 +228,20 @@
     if (Kind != Template)
       return TemplateName();
     
-    return TemplateName::getFromVoidPointer(TemplateArg.Template);
+    return TemplateName::getFromVoidPointer(
+                                          reinterpret_cast<void*>(TypeOrValue));
   }
-  
+
+  /// \brief Retrieve the template argument as a template name; if the argument
+  /// is a pack expansion, return the pattern as a template name.
+  TemplateName getAsTemplateOrTemplatePattern() const {
+    if (Kind != Template && Kind != TemplateExpansion)
+      return TemplateName();
+    
+    return TemplateName::getFromVoidPointer(
+                                          reinterpret_cast<void*>(TypeOrValue));
+  }
+
   /// \brief Retrieve the template argument as an integral value.
   llvm::APSInt *getAsIntegral() {
     if (Kind != Integral)
@@ -394,12 +399,14 @@
                       SourceLocation EllipsisLoc = SourceLocation())
     : Argument(Argument), 
       LocInfo(QualifierRange, TemplateNameLoc, EllipsisLoc) {
-    assert(Argument.getKind() == TemplateArgument::Template);
+    assert(Argument.getKind() == TemplateArgument::Template ||
+           Argument.getKind() == TemplateArgument::TemplateExpansion);
   }
   
   /// \brief - Fetches the primary location of the argument.
   SourceLocation getLocation() const {
-    if (Argument.getKind() == TemplateArgument::Template)
+    if (Argument.getKind() == TemplateArgument::Template ||
+        Argument.getKind() == TemplateArgument::TemplateExpansion)
       return getTemplateNameLoc();
     
     return getSourceRange().getBegin();
@@ -432,17 +439,19 @@
   }
   
   SourceRange getTemplateQualifierRange() const {
-    assert(Argument.getKind() == TemplateArgument::Template);
+    assert(Argument.getKind() == TemplateArgument::Template ||
+           Argument.getKind() == TemplateArgument::TemplateExpansion);
     return LocInfo.getTemplateQualifierRange();
   }
   
   SourceLocation getTemplateNameLoc() const {
-    assert(Argument.getKind() == TemplateArgument::Template);
+    assert(Argument.getKind() == TemplateArgument::Template ||
+           Argument.getKind() == TemplateArgument::TemplateExpansion);
     return LocInfo.getTemplateNameLoc();
   }  
   
   SourceLocation getTemplateEllipsisLoc() const {
-    assert(Argument.getKind() == TemplateArgument::Template);
+    assert(Argument.getKind() == TemplateArgument::TemplateExpansion);
     return LocInfo.getTemplateEllipsisLoc();
   }
   

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Jan  5 12:58:31 2011
@@ -2692,7 +2692,12 @@
 
     case TemplateArgument::Template:
       return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
-      
+
+    case TemplateArgument::TemplateExpansion:
+      return TemplateArgument(getCanonicalTemplateName(
+                                         Arg.getAsTemplateOrTemplatePattern()),
+                              true);
+
     case TemplateArgument::Integral:
       return TemplateArgument(*Arg.getAsIntegral(),
                               getCanonicalType(Arg.getIntegralType()));

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Jan  5 12:58:31 2011
@@ -301,7 +301,12 @@
     return IsStructurallyEquivalent(Context, 
                                     Arg1.getAsTemplate(), 
                                     Arg2.getAsTemplate());
-      
+
+  case TemplateArgument::TemplateExpansion:
+    return IsStructurallyEquivalent(Context, 
+                                    Arg1.getAsTemplateOrTemplatePattern(), 
+                                    Arg2.getAsTemplateOrTemplatePattern());
+
   case TemplateArgument::Expression:
     return IsStructurallyEquivalent(Context, 
                                     Arg1.getAsExpr(), Arg2.getAsExpr());
@@ -1785,7 +1790,16 @@
     
     return TemplateArgument(ToTemplate);
   }
-      
+
+  case TemplateArgument::TemplateExpansion: {
+    TemplateName ToTemplate 
+      = Importer.Import(From.getAsTemplateOrTemplatePattern());
+    if (ToTemplate.isNull())
+      return TemplateArgument();
+    
+    return TemplateArgument(ToTemplate, true);
+  }
+
   case TemplateArgument::Expression:
     if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
       return TemplateArgument(ToExpr);

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Jan  5 12:58:31 2011
@@ -179,7 +179,9 @@
       break;
 
     case TemplateArgument::Template:
-      if (TemplateDecl *Template = Args[I].getAsTemplate().getAsTemplateDecl())
+    case TemplateArgument::TemplateExpansion:
+      if (TemplateDecl *Template 
+                = Args[I].getAsTemplateOrTemplatePattern().getAsTemplateDecl())
         LV = merge(LV, getLVForDecl(Template, F));
       break;
 

Modified: cfe/trunk/lib/AST/DumpXML.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DumpXML.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DumpXML.cpp (original)
+++ cfe/trunk/lib/AST/DumpXML.cpp Wed Jan  5 12:58:31 2011
@@ -319,6 +319,10 @@
       break;
     }
     case TemplateArgument::Template:
+    case TemplateArgument::TemplateExpansion:
+      // FIXME: Implement!
+      break;
+        
     case TemplateArgument::Declaration: {
       visitDeclRef(A.getAsDecl());
       break;

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Wed Jan  5 12:58:31 2011
@@ -972,7 +972,8 @@
     break;
 
   case TemplateArgument::Template:
-    VisitTemplateName(Arg.getAsTemplate());
+  case TemplateArgument::TemplateExpansion:
+    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
     break;
       
   case TemplateArgument::Declaration:

Modified: cfe/trunk/lib/AST/TemplateBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateBase.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateBase.cpp (original)
+++ cfe/trunk/lib/AST/TemplateBase.cpp Wed Jan  5 12:58:31 2011
@@ -39,7 +39,10 @@
 
   case Template:
     return getAsTemplate().isDependent();
-      
+
+  case TemplateExpansion:
+    return true;
+
   case Declaration:
     if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl()))
       return DC->isDependentContext();
@@ -70,14 +73,15 @@
   case Declaration:
   case Integral:
   case Pack:    
+  case Template:
     return false;
       
+  case TemplateExpansion:
+    return true;
+      
   case Type:
     return isa<PackExpansionType>(getAsType());
-      
-  case Template:
-    return TemplateArg.PackExpansion;
-    
+          
   case Expression:
     return isa<PackExpansionExpr>(getAsExpr());
   }
@@ -90,6 +94,7 @@
   case Null:
   case Declaration:
   case Integral:
+  case TemplateExpansion:
     break;
 
   case Type:
@@ -98,8 +103,7 @@
     break;
 
   case Template:
-    if (!TemplateArg.PackExpansion && 
-        getAsTemplate().containsUnexpandedParameterPack())
+    if (getAsTemplate().containsUnexpandedParameterPack())
       return true;
     break;
         
@@ -135,20 +139,22 @@
     break;
 
   case Template:
-    ID.AddBoolean(TemplateArg.PackExpansion);
+  case TemplateExpansion: {
+    TemplateName Template = getAsTemplateOrTemplatePattern();
     if (TemplateTemplateParmDecl *TTP
           = dyn_cast_or_null<TemplateTemplateParmDecl>(
-                                       getAsTemplate().getAsTemplateDecl())) {
+                                                Template.getAsTemplateDecl())) {
       ID.AddBoolean(true);
       ID.AddInteger(TTP->getDepth());
       ID.AddInteger(TTP->getPosition());
       ID.AddBoolean(TTP->isParameterPack());
     } else {
       ID.AddBoolean(false);
-      ID.AddPointer(Context.getCanonicalTemplateName(getAsTemplate())
-                      .getAsVoidPointer());
+      ID.AddPointer(Context.getCanonicalTemplateName(Template)
+                                                          .getAsVoidPointer());
     }
     break;
+  }
       
   case Integral:
     getAsIntegral()->Profile(ID);
@@ -173,13 +179,11 @@
   case Null:
   case Type:
   case Declaration:
-  case Expression:
+  case Expression:      
+  case Template:
+  case TemplateExpansion:
     return TypeOrValue == Other.TypeOrValue;
 
-  case Template:
-    return TemplateArg.Template == Other.TemplateArg.Template &&
-           TemplateArg.PackExpansion == Other.TemplateArg.PackExpansion;
-      
   case Integral:
     return getIntegralType() == Other.getIntegralType() &&
            *getAsIntegral() == *Other.getAsIntegral();
@@ -206,13 +210,14 @@
   case Expression:
     return cast<PackExpansionExpr>(getAsExpr())->getPattern();
     
-  case Template:
-    return TemplateArgument(getAsTemplate(), false);
+  case TemplateExpansion:
+    return TemplateArgument(getAsTemplateOrTemplatePattern(), false);
     
   case Declaration:
   case Integral:
   case Pack:
   case Null:
+  case Template:
     return TemplateArgument();
   }
   
@@ -248,13 +253,15 @@
     break;
   }
     
-  case Template: {
+  case Template:
     getAsTemplate().print(Out, Policy);
-    if (TemplateArg.PackExpansion)
-      Out << "...";
     break;
-  }
-    
+
+  case TemplateExpansion:
+    getAsTemplateOrTemplatePattern().print(Out, Policy);
+    Out << "...";
+    break;
+      
   case Integral: {
     Out << getAsIntegral()->toString(10);
     break;
@@ -299,15 +306,18 @@
     else
       return SourceRange();
 
-  case TemplateArgument::Template: {
-    SourceLocation End = getTemplateNameLoc();
-    if (getTemplateEllipsisLoc().isValid())
-      End = getTemplateEllipsisLoc();
+  case TemplateArgument::Template:
     if (getTemplateQualifierRange().isValid())
-      return SourceRange(getTemplateQualifierRange().getBegin(), End);
-    return SourceRange(getTemplateNameLoc(), End);
-  }
-      
+      return SourceRange(getTemplateQualifierRange().getBegin(), 
+                         getTemplateNameLoc());
+    return SourceRange(getTemplateNameLoc());
+
+  case TemplateArgument::TemplateExpansion:
+    if (getTemplateQualifierRange().isValid())
+      return SourceRange(getTemplateQualifierRange().getBegin(), 
+                         getTemplateEllipsisLoc());
+    return SourceRange(getTemplateNameLoc(), getTemplateEllipsisLoc());
+
   case TemplateArgument::Integral:
   case TemplateArgument::Pack:
   case TemplateArgument::Null:
@@ -355,13 +365,14 @@
     Expr *Pattern = cast<PackExpansionExpr>(Argument.getAsExpr())->getPattern();
     return TemplateArgumentLoc(Pattern, Pattern);
   }
-      
-  case TemplateArgument::Template:
+
+  case TemplateArgument::TemplateExpansion:
     return TemplateArgumentLoc(Argument.getPackExpansionPattern(),
                                getTemplateQualifierRange(),
                                getTemplateNameLoc());
     
   case TemplateArgument::Declaration:
+  case TemplateArgument::Template:
   case TemplateArgument::Integral:
   case TemplateArgument::Pack:
   case TemplateArgument::Null:
@@ -389,11 +400,11 @@
     return DB << Arg.getAsIntegral()->toString(10);
       
   case TemplateArgument::Template:
-    DB << Arg.getAsTemplate();
-    if (Arg.isPackExpansion())
-      DB << "...";
-    return DB;
-      
+    return DB << Arg.getAsTemplate();
+
+  case TemplateArgument::TemplateExpansion:
+    return DB << Arg.getAsTemplateOrTemplatePattern() << "...";
+
   case TemplateArgument::Expression: {
     // This shouldn't actually ever happen, so it's okay that we're
     // regurgitating an expression here.

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Wed Jan  5 12:58:31 2011
@@ -2169,6 +2169,11 @@
     // This is mangled as <type>.
     mangleType(A.getAsTemplate());
     break;
+  case TemplateArgument::TemplateExpansion:
+    // This is mangled as Dp <type>.
+    Out << "Dp";
+    mangleType(A.getAsTemplateOrTemplatePattern());
+    break;
   case TemplateArgument::Expression:
     Out << 'X';
     mangleExpression(A.getAsExpr());

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Jan  5 12:58:31 2011
@@ -1693,11 +1693,12 @@
       addAssociatedClassesAndNamespaces(Result, Arg.getAsType());
       break;
 
-    case TemplateArgument::Template: {
+    case TemplateArgument::Template: 
+    case TemplateArgument::TemplateExpansion: {
       // [...] the namespaces in which any template template arguments are
       // defined; and the classes in which any member templates used as
       // template template arguments are defined.
-      TemplateName Template = Arg.getAsTemplate();
+      TemplateName Template = Arg.getAsTemplateOrTemplatePattern();
       if (ClassTemplateDecl *ClassTemplate
                  = dyn_cast<ClassTemplateDecl>(Template.getAsTemplateDecl())) {
         DeclContext *Ctx = ClassTemplate->getDeclContext();

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jan  5 12:58:31 2011
@@ -2256,10 +2256,12 @@
       break;
       
     case TemplateArgument::Template:
+    case TemplateArgument::TemplateExpansion:
       // We were given a template template argument. It may not be ill-formed;
       // see below.
       if (DependentTemplateName *DTN
-            = Arg.getArgument().getAsTemplate().getAsDependentTemplateName()) {
+            = Arg.getArgument().getAsTemplateOrTemplatePattern()
+                                              .getAsDependentTemplateName()) {
         // We have a template argument such as \c T::template X, which we
         // parsed as a template template argument. However, since we now
         // know that we need a non-type template argument, convert this
@@ -2273,6 +2275,17 @@
                                                Arg.getTemplateQualifierRange(),
                                                     NameInfo);
         
+        // If we parsed the template argument as a pack expansion, create a
+        // pack expansion expression.
+        if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
+          ExprResult Expansion = ActOnPackExpansion(E, 
+                                                  Arg.getTemplateEllipsisLoc());
+          if (Expansion.isInvalid())
+            return true;
+          
+          E = Expansion.get();
+        }
+        
         TemplateArgument Result;
         if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
           return true;
@@ -2348,6 +2361,7 @@
     return true;
     
   case TemplateArgument::Template:
+  case TemplateArgument::TemplateExpansion:
     if (CheckTemplateArgument(TempParm, Arg))
       return true;
       

Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Jan  5 12:58:31 2011
@@ -168,7 +168,16 @@
     
     // All other combinations are incompatible.
     return DeducedTemplateArgument();      
-      
+
+  case TemplateArgument::TemplateExpansion:
+    if (Y.getKind() == TemplateArgument::TemplateExpansion &&
+        Context.hasSameTemplateName(X.getAsTemplateOrTemplatePattern(), 
+                                    Y.getAsTemplateOrTemplatePattern()))
+      return X;
+    
+    // All other combinations are incompatible.
+    return DeducedTemplateArgument();      
+
   case TemplateArgument::Expression:
     // If we deduced a dependent expression in one case and either an integral 
     // constant or a declaration in another case, keep the integral constant 
@@ -934,7 +943,7 @@
     Info.FirstArg = Param;
     Info.SecondArg = Arg;
     return Sema::TDK_NonDeducedMismatch;
-      
+
   case TemplateArgument::Template:
     if (Arg.getKind() == TemplateArgument::Template)
       return DeduceTemplateArguments(S, TemplateParams, 
@@ -943,6 +952,10 @@
     Info.FirstArg = Param;
     Info.SecondArg = Arg;
     return Sema::TDK_NonDeducedMismatch;
+
+  case TemplateArgument::TemplateExpansion:
+    llvm_unreachable("caller should handle pack expansions");
+    break;
       
   case TemplateArgument::Declaration:
     if (Arg.getKind() == TemplateArgument::Declaration &&
@@ -1282,10 +1295,11 @@
              Y.getAsDecl()->getCanonicalDecl();
 
     case TemplateArgument::Template:
-      return Context.getCanonicalTemplateName(X.getAsTemplate())
-               .getAsVoidPointer() ==
-             Context.getCanonicalTemplateName(Y.getAsTemplate())
-               .getAsVoidPointer();
+    case TemplateArgument::TemplateExpansion:
+      return Context.getCanonicalTemplateName(
+                    X.getAsTemplateOrTemplatePattern()).getAsVoidPointer() ==
+             Context.getCanonicalTemplateName(
+                    Y.getAsTemplateOrTemplatePattern()).getAsVoidPointer();
       
     case TemplateArgument::Integral:
       return *X.getAsIntegral() == *Y.getAsIntegral();
@@ -1356,9 +1370,11 @@
   }
     
   case TemplateArgument::Template:
-    return TemplateArgumentLoc(Arg, SourceRange(), Loc,
-                               Arg.isPackExpansion()? Loc : SourceLocation());
-    
+    return TemplateArgumentLoc(Arg, SourceRange(), Loc);
+
+  case TemplateArgument::TemplateExpansion:
+    return TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc);
+
   case TemplateArgument::Expression:
     return TemplateArgumentLoc(Arg, Arg.getAsExpr());
     
@@ -3244,7 +3260,9 @@
     break;
 
   case TemplateArgument::Template:
-    MarkUsedTemplateParameters(SemaRef, TemplateArg.getAsTemplate(), 
+  case TemplateArgument::TemplateExpansion:
+    MarkUsedTemplateParameters(SemaRef, 
+                               TemplateArg.getAsTemplateOrTemplatePattern(), 
                                OnlyDeduced, Depth, Used);
     break;
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Jan  5 12:58:31 2011
@@ -2123,12 +2123,18 @@
     }
         
     case TemplateArgument::Template:
-      llvm_unreachable("Unsupported pack expansion of templates");
+      return TemplateArgumentLoc(TemplateArgument(
+                                          Pattern.getArgument().getAsTemplate(),
+                                                  true),
+                                 Pattern.getTemplateQualifierRange(),
+                                 Pattern.getTemplateNameLoc(),
+                                 EllipsisLoc);
         
     case TemplateArgument::Null:
     case TemplateArgument::Integral:
     case TemplateArgument::Declaration:
     case TemplateArgument::Pack:
+    case TemplateArgument::TemplateExpansion:
       llvm_unreachable("Pack expansion pattern has no parameter packs");
         
     case TemplateArgument::Type:
@@ -2531,7 +2537,11 @@
   case TemplateArgument::Template:
     Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
     break;
-      
+
+  case TemplateArgument::TemplateExpansion:
+    Output = TemplateArgumentLoc(Arg, SourceRange(), Loc, Loc);
+    break;
+
   case TemplateArgument::Expression:
     Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
     break;
@@ -2600,7 +2610,10 @@
                                  Input.getTemplateNameLoc());
     return false;
   }
-      
+
+  case TemplateArgument::TemplateExpansion:
+    llvm_unreachable("Caller should expand pack expansions");
+
   case TemplateArgument::Expression: {
     // Template argument expressions are not potentially evaluated.
     EnterExpressionEvaluationContext Unevaluated(getSema(),

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Jan  5 12:58:31 2011
@@ -3381,6 +3381,12 @@
   case TemplateArgument::Template: {
     SourceRange QualifierRange = ReadSourceRange(F, Record, Index);
     SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
+    return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc,
+                                   SourceLocation());
+  }
+  case TemplateArgument::TemplateExpansion: {
+    SourceRange QualifierRange = ReadSourceRange(F, Record, Index);
+    SourceLocation TemplateNameLoc = ReadSourceLocation(F, Record, Index);
     SourceLocation EllipsisLoc = ReadSourceLocation(F, Record, Index);
     return TemplateArgumentLocInfo(QualifierRange, TemplateNameLoc, 
                                    EllipsisLoc);
@@ -4216,7 +4222,8 @@
 TemplateArgument
 ASTReader::ReadTemplateArgument(PerFileData &F,
                                 const RecordData &Record, unsigned &Idx) {
-  switch ((TemplateArgument::ArgKind)Record[Idx++]) {
+  TemplateArgument::ArgKind Kind = (TemplateArgument::ArgKind)Record[Idx++];
+  switch (Kind) {
   case TemplateArgument::Null:
     return TemplateArgument();
   case TemplateArgument::Type:
@@ -4228,10 +4235,10 @@
     QualType T = GetType(Record[Idx++]);
     return TemplateArgument(Value, T);
   }
-  case TemplateArgument::Template: {
+  case TemplateArgument::Template: 
+  case TemplateArgument::TemplateExpansion: {
     TemplateName Name = ReadTemplateName(Record, Idx);
-    bool IsPackExpansion = Record[Idx++];
-    return TemplateArgument(Name, IsPackExpansion);
+    return TemplateArgument(Name, Kind == TemplateArgument::TemplateExpansion);
   }
   case TemplateArgument::Expression:
     return TemplateArgument(ReadExpr(F));

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Jan  5 12:58:31 2011
@@ -2889,6 +2889,10 @@
   case TemplateArgument::Template:
     AddSourceRange(Arg.getTemplateQualifierRange(), Record);
     AddSourceLocation(Arg.getTemplateNameLoc(), Record);
+    break;
+  case TemplateArgument::TemplateExpansion:
+    AddSourceRange(Arg.getTemplateQualifierRange(), Record);
+    AddSourceLocation(Arg.getTemplateNameLoc(), Record);
     AddSourceLocation(Arg.getTemplateEllipsisLoc(), Record);
     break;
   case TemplateArgument::Null:
@@ -3176,8 +3180,8 @@
     AddTypeRef(Arg.getIntegralType(), Record);
     break;
   case TemplateArgument::Template:
-    AddTemplateName(Arg.getAsTemplate(), Record);
-    Record.push_back(Arg.isPackExpansion());
+  case TemplateArgument::TemplateExpansion:
+    AddTemplateName(Arg.getAsTemplateOrTemplatePattern(), Record);
     break;
   case TemplateArgument::Expression:
     AddStmt(Arg.getAsExpr());

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp Wed Jan  5 12:58:31 2011
@@ -163,4 +163,44 @@
   int check0[is_same<apply_each<int, 
                                 add_reference, add_pointer, add_const>::type,
                      tuple<int&, int*, int const>>::value? 1 : -1];
+
+  template<typename T, template<class> class ...Meta>
+  struct apply_each_indirect {
+    typedef typename apply_each<T, Meta...>::type type;
+  };
+
+  int check1[is_same<apply_each_indirect<int, add_reference, add_pointer, 
+                                         add_const>::type,
+                     tuple<int&, int*, int const>>::value? 1 : -1];
+
+  template<typename T, typename ...Meta>
+  struct apply_each_nested {
+    typedef typename apply_each<T, Meta::template apply...>::type type;
+  };
+
+  struct add_reference_meta {
+    template<typename T>
+    struct apply {
+      typedef T& type;
+    };
+  };
+
+  struct add_pointer_meta {
+    template<typename T>
+    struct apply {
+      typedef T* type;
+    };
+  };
+
+  struct add_const_meta {
+    template<typename T>
+    struct apply {
+      typedef const T type;
+    };
+  };
+
+  int check2[is_same<apply_each_nested<int, add_reference_meta, 
+                                       add_pointer_meta, add_const_meta>::type,
+                     tuple<int&, int*, int const>>::value? 1 : -1];
+
 }

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp Wed Jan  5 12:58:31 2011
@@ -18,7 +18,7 @@
   static const bool value = true;
 };
 
-// FIXME: Many more bullets to go
+// FIXME: Several more bullets to go
 
 // In an initializer-list (8.5); the pattern is an initializer-clause.
 // Note: this also covers expression-lists, since expression-list is

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Jan  5 12:58:31 2011
@@ -1256,7 +1256,8 @@
     return false;
   
   case TemplateArgument::Template:
-    return VisitTemplateName(TAL.getArgument().getAsTemplate(), 
+  case TemplateArgument::TemplateExpansion:
+    return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(), 
                              TAL.getTemplateNameLoc());
   }
   

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=122896&r1=122895&r2=122896&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Wed Jan  5 12:58:31 2011
@@ -708,7 +708,9 @@
     break;
       
   case TemplateArgument::Template:
-    VisitTemplateName(Arg.getAsTemplate());
+  case TemplateArgument::TemplateExpansion:
+      // FIXME: variadic templates
+    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
     break;
       
   case TemplateArgument::Expression:





More information about the cfe-commits mailing list