<div dir="ltr">I have reverted this in r290092 as it was leading to Clang crashes on the bots and elsewhere, e.g.:<div><a href="http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/1814" rel="noreferrer" target="_blank" class="gmail-cremed" style="font-size:12.8px">http://lab.llvm.org:8011/<wbr>builders/clang-cmake-aarch64-<wbr>quick/builds/1814</a><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 19, 2016 at 5:08 AM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Sun Dec 18 22:08:53 2016<br>
New Revision: 290080<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=290080&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=290080&view=rev</a><br>
Log:<br>
[c++1z] P0195R2: Support pack-expansion of using-declarations.<br>
<br>
This change introduces UsingPackDecl as a marker for the set of UsingDecls<br>
produced by pack expansion of a single (unresolved) using declaration. This is<br>
not strictly necessary (we just need to be able to map from the original using<br>
declaration to its expansions somehow), but it's useful to maintain the<br>
invariant that each declaration reference instantiates to refer to one<br>
declaration.<br>
<br>
Added:<br>
    cfe/trunk/test/PCH/cxx1z-<wbr>using-declaration.cpp<br>
    cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/<wbr>DeclCXX.h<br>
    cfe/trunk/include/clang/AST/<wbr>RecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/Basic/<wbr>DeclNodes.td<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticParseKinds.td<br>
    cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
    cfe/trunk/include/clang/Parse/<wbr>Parser.h<br>
    cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
    cfe/trunk/include/clang/Sema/<wbr>Template.h<br>
    cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/AST/DeclBase.cpp<br>
    cfe/trunk/lib/AST/DeclCXX.cpp<br>
    cfe/trunk/lib/CodeGen/CGDecl.<wbr>cpp<br>
    cfe/trunk/lib/Parse/<wbr>ParseDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp<br>
    cfe/trunk/lib/Sema/<wbr>SemaTemplateVariadic.cpp<br>
    cfe/trunk/lib/Sema/<wbr>TreeTransform.h<br>
    cfe/trunk/lib/Serialization/<wbr>ASTCommon.cpp<br>
    cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp<br>
    cfe/trunk/lib/Serialization/<wbr>ASTWriterDecl.cpp<br>
    cfe/trunk/test/Parser/cxx1z-<wbr>using-declaration.cpp<br>
    cfe/trunk/tools/libclang/<wbr>CIndex.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/<wbr>DeclCXX.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/DeclCXX.h?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/<wbr>DeclCXX.h (original)<br>
+++ cfe/trunk/include/clang/AST/<wbr>DeclCXX.h Sun Dec 18 22:08:53 2016<br>
@@ -3140,6 +3140,77 @@ public:<br>
   friend class ASTDeclWriter;<br>
 };<br>
<br>
+/// Represents a pack of using declarations that a single<br>
+/// using-declarator pack-expanded into.<br>
+///<br>
+/// \code<br>
+/// template<typename ...T> struct X : T... {<br>
+///   using T::operator()...;<br>
+///   using T::operator T...;<br>
+/// };<br>
+/// \endcode<br>
+///<br>
+/// In the second case above, the UsingPackDecl will have the name<br>
+/// 'operator T' (which contains an unexpanded pack), but the individual<br>
+/// UsingDecls and UsingShadowDecls will have more reasonable names.<br>
+class UsingPackDecl final<br>
+    : public NamedDecl, public Mergeable<UsingPackDecl>,<br>
+      private llvm::TrailingObjects<<wbr>UsingPackDecl, NamedDecl *> {<br>
+  void anchor() override;<br>
+<br>
+  /// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from<br>
+  /// which this waas instantiated.<br>
+  NamedDecl *InstantiatedFrom;<br>
+<br>
+  /// The number of using-declarations created by this pack expansion.<br>
+  unsigned NumExpansions;<br>
+<br>
+  UsingPackDecl(DeclContext *DC, NamedDecl *InstantiatedFrom,<br>
+                ArrayRef<NamedDecl *> UsingDecls)<br>
+      : NamedDecl(UsingPack, DC,<br>
+                  InstantiatedFrom ? InstantiatedFrom->getLocation(<wbr>)<br>
+                                   : SourceLocation(),<br>
+                  InstantiatedFrom ? InstantiatedFrom->getDeclName(<wbr>)<br>
+                                   : DeclarationName()),<br>
+        InstantiatedFrom(<wbr>InstantiatedFrom), NumExpansions(UsingDecls.size(<wbr>)) {<br>
+    std::uninitialized_copy(<wbr>UsingDecls.begin(), UsingDecls.end(),<br>
+                            getTrailingObjects<NamedDecl *>());<br>
+  }<br>
+<br>
+public:<br>
+  /// Get the using declaration from which this was instantiated. This will<br>
+  /// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl<br>
+  /// that is a pack expansion.<br>
+  NamedDecl *getInstantiatedFromUsingDecl(<wbr>) { return InstantiatedFrom; }<br>
+<br>
+  /// Get the set of using declarations that this pack expanded into. Note that<br>
+  /// some of these may still be unresolved.<br>
+  ArrayRef<NamedDecl *> expansions() const {<br>
+    return llvm::makeArrayRef(<wbr>getTrailingObjects<NamedDecl *>(), NumExpansions);<br>
+  }<br>
+<br>
+  static UsingPackDecl *Create(ASTContext &C, DeclContext *DC,<br>
+                               NamedDecl *InstantiatedFrom,<br>
+                               ArrayRef<NamedDecl *> UsingDecls);<br>
+<br>
+  static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID,<br>
+                                           unsigned NumExpansions);<br>
+<br>
+  SourceRange getSourceRange() const override LLVM_READONLY {<br>
+    return InstantiatedFrom-><wbr>getSourceRange();<br>
+  }<br>
+<br>
+  UsingPackDecl *getCanonicalDecl() override { return getFirstDecl(); }<br>
+  const UsingPackDecl *getCanonicalDecl() const { return getFirstDecl(); }<br>
+<br>
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }<br>
+  static bool classofKind(Kind K) { return K == UsingPack; }<br>
+<br>
+  friend class ASTDeclReader;<br>
+  friend class ASTDeclWriter;<br>
+  friend TrailingObjects;<br>
+};<br>
+<br>
 /// \brief Represents a dependent using declaration which was not marked with<br>
 /// \c typename.<br>
 ///<br>
@@ -3158,6 +3229,9 @@ class UnresolvedUsingValueDecl : public<br>
   /// \brief The source location of the 'using' keyword<br>
   SourceLocation UsingLocation;<br>
<br>
+  /// \brief If this is a pack expansion, the location of the '...'.<br>
+  SourceLocation EllipsisLoc;<br>
+<br>
   /// \brief The nested-name-specifier that precedes the name.<br>
   NestedNameSpecifierLoc QualifierLoc;<br>
<br>
@@ -3168,11 +3242,12 @@ class UnresolvedUsingValueDecl : public<br>
   UnresolvedUsingValueDecl(<wbr>DeclContext *DC, QualType Ty,<br>
                            SourceLocation UsingLoc,<br>
                            NestedNameSpecifierLoc QualifierLoc,<br>
-                           const DeclarationNameInfo &NameInfo)<br>
+                           const DeclarationNameInfo &NameInfo,<br>
+                           SourceLocation EllipsisLoc)<br>
     : ValueDecl(<wbr>UnresolvedUsingValue, DC,<br>
                 NameInfo.getLoc(), NameInfo.getName(), Ty),<br>
-      UsingLocation(UsingLoc), QualifierLoc(QualifierLoc),<br>
-      DNLoc(NameInfo.getInfo())<br>
+      UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc),<br>
+      QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo())<br>
   { }<br>
<br>
 public:<br>
@@ -3198,10 +3273,20 @@ public:<br>
     return DeclarationNameInfo(<wbr>getDeclName(), getLocation(), DNLoc);<br>
   }<br>
<br>
+  /// \brief Determine whether this is a pack expansion.<br>
+  bool isPackExpansion() const {<br>
+    return EllipsisLoc.isValid();<br>
+  }<br>
+<br>
+  /// \brief Get the location of the ellipsis if this is a pack expansion.<br>
+  SourceLocation getEllipsisLoc() const {<br>
+    return EllipsisLoc;<br>
+  }<br>
+<br>
   static UnresolvedUsingValueDecl *<br>
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,<br>
            NestedNameSpecifierLoc QualifierLoc,<br>
-           const DeclarationNameInfo &NameInfo);<br>
+           const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc);<br>
<br>
   static UnresolvedUsingValueDecl *<br>
   CreateDeserialized(ASTContext &C, unsigned ID);<br>
@@ -3242,6 +3327,9 @@ class UnresolvedUsingTypenameDecl<br>
   /// \brief The source location of the 'typename' keyword<br>
   SourceLocation TypenameLocation;<br>
<br>
+  /// \brief If this is a pack expansion, the location of the '...'.<br>
+  SourceLocation EllipsisLoc;<br>
+<br>
   /// \brief The nested-name-specifier that precedes the name.<br>
   NestedNameSpecifierLoc QualifierLoc;<br>
<br>
@@ -3249,10 +3337,12 @@ class UnresolvedUsingTypenameDecl<br>
                               SourceLocation TypenameLoc,<br>
                               NestedNameSpecifierLoc QualifierLoc,<br>
                               SourceLocation TargetNameLoc,<br>
-                              IdentifierInfo *TargetName)<br>
+                              IdentifierInfo *TargetName,<br>
+                              SourceLocation EllipsisLoc)<br>
     : TypeDecl(<wbr>UnresolvedUsingTypename, DC, TargetNameLoc, TargetName,<br>
                UsingLoc),<br>
-      TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { }<br>
+      TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc),<br>
+      QualifierLoc(QualifierLoc) { }<br>
<br>
   friend class ASTDeclReader;<br>
<br>
@@ -3272,10 +3362,25 @@ public:<br>
     return QualifierLoc.<wbr>getNestedNameSpecifier();<br>
   }<br>
<br>
+  DeclarationNameInfo getNameInfo() const {<br>
+    return DeclarationNameInfo(<wbr>getDeclName(), getLocation());<br>
+  }<br>
+<br>
+  /// \brief Determine whether this is a pack expansion.<br>
+  bool isPackExpansion() const {<br>
+    return EllipsisLoc.isValid();<br>
+  }<br>
+<br>
+  /// \brief Get the location of the ellipsis if this is a pack expansion.<br>
+  SourceLocation getEllipsisLoc() const {<br>
+    return EllipsisLoc;<br>
+  }<br>
+<br>
   static UnresolvedUsingTypenameDecl *<br>
     Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,<br>
            SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc,<br>
-           SourceLocation TargetNameLoc, DeclarationName TargetName);<br>
+           SourceLocation TargetNameLoc, DeclarationName TargetName,<br>
+           SourceLocation EllipsisLoc);<br>
<br>
   static UnresolvedUsingTypenameDecl *<br>
   CreateDeserialized(ASTContext &C, unsigned ID);<br>
<br>
Modified: cfe/trunk/include/clang/AST/<wbr>RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/RecursiveASTVisitor.<wbr>h?rev=290080&r1=290079&r2=<wbr>290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/AST/<wbr>RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/<wbr>RecursiveASTVisitor.h Sun Dec 18 22:08:53 2016<br>
@@ -1505,6 +1505,8 @@ DEF_TRAVERSE_DECL(UsingDecl, {<br>
   TRY_TO(<wbr>TraverseDeclarationNameInfo(D-<wbr>>getNameInfo()));<br>
 })<br>
<br>
+DEF_TRAVERSE_DECL(<wbr>UsingPackDecl, {})<br>
+<br>
 DEF_TRAVERSE_DECL(<wbr>UsingDirectiveDecl, {<br>
   TRY_TO(<wbr>TraverseNestedNameSpecifierLoc<wbr>(D->getQualifierLoc()));<br>
 })<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DeclNodes.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/DeclNodes.td?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DeclNodes.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DeclNodes.td Sun Dec 18 22:08:53 2016<br>
@@ -67,6 +67,7 @@ def Named : Decl<1>;<br>
     def TemplateTemplateParm : DDecl<Template>;<br>
     def BuiltinTemplate : DDecl<Template>;<br>
   def Using : DDecl<Named>;<br>
+  def UsingPack : DDecl<Named>;<br>
   def UsingShadow : DDecl<Named>;<br>
     def ConstructorUsingShadow : DDecl<UsingShadow>;<br>
   def ObjCMethod : DDecl<Named>, DeclContext;<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticParseKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticParseKinds.td?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticParseKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticParseKinds.td Sun Dec 18 22:08:53 2016<br>
@@ -740,6 +740,8 @@ def err_alias_declaration_not_<wbr>identifier<br>
   "name defined in alias declaration must be an identifier">;<br>
 def err_alias_declaration_<wbr>specialization : Error<<br>
   "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">;<br>
+def err_alias_declaration_pack_<wbr>expansion : Error<<br>
+  "alias declaration cannot be a pack expansion">;<br>
<br>
 // C++1z using-declaration pack expansions<br>
 def ext_multi_using_declaration : ExtWarn<<br>
@@ -749,6 +751,11 @@ def warn_cxx1z_compat_multi_using_<wbr>declar<br>
   "use of multiple declarators in a single using declaration is "<br>
   "incompatible with C++ standards before C++1z">,<br>
   InGroup<CXXPre1zCompat>, DefaultIgnore;<br>
+def ext_using_declaration_pack : ExtWarn<<br>
+  "pack expansion of using declaration is a C++1z extension">, InGroup<CXX1z>;<br>
+def warn_cxx1z_compat_using_<wbr>declaration_pack : Warning<<br>
+  "pack expansion using declaration is incompatible with C++ standards "<br>
+  "before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore;<br>
<br>
 // C++11 override control<br>
 def ext_override_control_keyword : ExtWarn<<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticSemaKinds.td?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Sun Dec 18 22:08:53 2016<br>
@@ -474,6 +474,8 @@ def err_using_decl_conflict : Error<<br>
 def err_using_decl_conflict_<wbr>reverse : Error<<br>
   "declaration conflicts with target of using declaration already in scope">;<br>
 def note_using_decl : Note<"%select{|previous }0using declaration">;<br>
+def err_using_decl_redeclaration_<wbr>expansion : Error<<br>
+  "using declaration pack expansion at block scope produces multiple values">;<br>
<br>
 def warn_access_decl_deprecated : Warning<<br>
   "access declarations are deprecated; use using declarations instead">,<br>
@@ -4155,6 +4157,9 @@ def err_variable_instantiates_to_<wbr>functio<br>
 def err_nested_name_spec_non_tag : Error<<br>
   "type %0 cannot be used prior to '::' because it has no members">;<br>
<br>
+def err_using_pack_expansion_empty : Error<<br>
+  "%select{|member}0 using declaration %1 instantiates to an empty pack">;<br>
+<br>
 // C++ Explicit Instantiation<br>
 def err_explicit_instantiation_<wbr>duplicate : Error<<br>
     "duplicate explicit instantiation of %0">;<br>
<br>
Modified: cfe/trunk/include/clang/Parse/<wbr>Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Parse/Parser.h?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Parse/<wbr>Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/<wbr>Parser.h Sun Dec 18 22:08:53 2016<br>
@@ -2436,9 +2436,10 @@ private:<br>
     CXXScopeSpec SS;<br>
     SourceLocation TemplateKWLoc;<br>
     UnqualifiedId Name;<br>
+    SourceLocation EllipsisLoc;<br>
<br>
     void clear() {<br>
-      TypenameLoc = TemplateKWLoc = SourceLocation();<br>
+      TypenameLoc = TemplateKWLoc = EllipsisLoc = SourceLocation();<br>
       SS.clear();<br>
       Name.clear();<br>
     }<br>
@@ -2450,9 +2451,6 @@ private:<br>
                                        SourceLocation UsingLoc,<br>
                                        SourceLocation &DeclEnd,<br>
                                        AccessSpecifier AS = AS_none);<br>
-  Decl *ParseAliasTemplate(const ParsedTemplateInfo &TemplateInfo,<br>
-                           SourceLocation &DeclEnd, AccessSpecifier AS,<br>
-                           ParsedAttributesWithRange &MisplacedAttrs1);<br>
   Decl *<wbr>ParseAliasDeclarationAfterDecl<wbr>arator(<br>
       const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,<br>
       UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=290080&<wbr>r1=290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Sun Dec 18 22:08:53 2016<br>
@@ -4324,12 +4324,15 @@ public:<br>
<br>
   NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,<br>
                                    SourceLocation UsingLoc,<br>
+                                   bool HasTypenameKeyword,<br>
+                                   SourceLocation TypenameLoc,<br>
                                    CXXScopeSpec &SS,<br>
                                    DeclarationNameInfo NameInfo,<br>
+                                   SourceLocation EllipsisLoc,<br>
                                    AttributeList *AttrList,<br>
-                                   bool IsInstantiation,<br>
-                                   bool HasTypenameKeyword,<br>
-                                   SourceLocation TypenameLoc);<br>
+                                   bool IsInstantiation);<br>
+  NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom,<br>
+                                ArrayRef<NamedDecl *> Expansions);<br>
<br>
   bool CheckInheritingConstructorUsin<wbr>gDecl(UsingDecl *UD);<br>
<br>
@@ -4343,10 +4346,11 @@ public:<br>
   Decl *ActOnUsingDeclaration(Scope *CurScope,<br>
                               AccessSpecifier AS,<br>
                               SourceLocation UsingLoc,<br>
+                              SourceLocation TypenameLoc,<br>
                               CXXScopeSpec &SS,<br>
                               UnqualifiedId &Name,<br>
-                              AttributeList *AttrList,<br>
-                              SourceLocation TypenameLoc);<br>
+                              SourceLocation EllipsisLoc,<br>
+                              AttributeList *AttrList);<br>
   Decl *ActOnAliasDeclaration(Scope *CurScope,<br>
                               AccessSpecifier AS,<br>
                               MultiTemplateParamsArg TemplateParams,<br>
@@ -6351,7 +6355,7 @@ public:<br>
   ///<br>
   /// \param SS The nested-name-specifier that will be traversed to find<br>
   /// unexpanded parameter packs.<br>
-  void collectUnexpandedParameterPack<wbr>s(CXXScopeSpec &SS,<br>
+  void collectUnexpandedParameterPack<wbr>s(NestedNameSpecifierLoc NNS,<br>
                          SmallVectorImpl<<wbr>UnexpandedParameterPack> &Unexpanded);<br>
<br>
   /// \brief Collect the set of unexpanded parameter packs within the given<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Template.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Template.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Template.h?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Template.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Template.h Sun Dec 18 22:08:53 2016<br>
@@ -515,6 +515,11 @@ namespace clang {<br>
         VarTemplateDecl *VarTemplate,<br>
         VarTemplatePartialSpecializati<wbr>onDecl *PartialSpec);<br>
     void InstantiateEnumDefinition(<wbr>EnumDecl *Enum, EnumDecl *Pattern);<br>
+<br>
+  private:<br>
+    template<typename T><br>
+    Decl *<wbr>instantiateUnresolvedUsingDecl<wbr>(T *D,<br>
+                                         bool InstantiatingPackElement = false);<br>
   };<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Serialization/<wbr>ASTBitCodes.h?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/<wbr>Serialization/ASTBitCodes.h Sun Dec 18 22:08:53 2016<br>
@@ -1103,6 +1103,8 @@ namespace clang {<br>
       DECL_NAMESPACE_ALIAS,<br>
       /// \brief A UsingDecl record.<br>
       DECL_USING,<br>
+      /// \brief A UsingPackDecl record.<br>
+      DECL_USING_PACK,<br>
       /// \brief A UsingShadowDecl record.<br>
       DECL_USING_SHADOW,<br>
       /// \brief A ConstructorUsingShadowDecl record.<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>DeclBase.cpp?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Sun Dec 18 22:08:53 2016<br>
@@ -651,11 +651,13 @@ unsigned Decl::<wbr>getIdentifierNamespaceFor<br>
     case Typedef:<br>
     case TypeAlias:<br>
     case TypeAliasTemplate:<br>
-    case UnresolvedUsingTypename:<br>
     case TemplateTypeParm:<br>
     case ObjCTypeParam:<br>
       return IDNS_Ordinary | IDNS_Type;<br>
<br>
+    case UnresolvedUsingTypename:<br>
+      return IDNS_Ordinary | IDNS_Type | IDNS_Using;<br>
+<br>
     case UsingShadow:<br>
       return 0; // we'll actually overwrite this later<br>
<br>
@@ -663,6 +665,7 @@ unsigned Decl::<wbr>getIdentifierNamespaceFor<br>
       return IDNS_Ordinary | IDNS_Using;<br>
<br>
     case Using:<br>
+    case UsingPack:<br>
       return IDNS_Using;<br>
<br>
     case ObjCProtocol:<br>
<br>
Modified: cfe/trunk/lib/AST/DeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>DeclCXX.cpp?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sun Dec 18 22:08:53 2016<br>
@@ -2250,15 +2250,37 @@ SourceRange UsingDecl::getSourceRange()<br>
   return SourceRange(Begin, getNameInfo().getEndLoc());<br>
 }<br>
<br>
+void UsingPackDecl::anchor() { }<br>
+<br>
+UsingPackDecl *UsingPackDecl::Create(<wbr>ASTContext &C, DeclContext *DC,<br>
+                                     NamedDecl *InstantiatedFrom,<br>
+                                     ArrayRef<NamedDecl *> UsingDecls) {<br>
+  size_t Extra = additionalSizeToAlloc<<wbr>NamedDecl *>(UsingDecls.size());<br>
+  return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls);<br>
+}<br>
+<br>
+UsingPackDecl *UsingPackDecl::<wbr>CreateDeserialized(ASTContext &C, unsigned ID,<br>
+                                                 unsigned NumExpansions) {<br>
+  size_t Extra = additionalSizeToAlloc<<wbr>NamedDecl *>(NumExpansions);<br>
+  auto *Result = new (C, ID, Extra) UsingPackDecl(nullptr, nullptr, None);<br>
+  Result->NumExpansions = NumExpansions;<br>
+  auto *Trail = Result->getTrailingObjects<<wbr>NamedDecl *>();<br>
+  for (unsigned I = 0; I != NumExpansions; ++I)<br>
+    new (Trail + I) NamedDecl*(nullptr);<br>
+  return Result;<br>
+}<br>
+<br>
 void UnresolvedUsingValueDecl::<wbr>anchor() { }<br>
<br>
 UnresolvedUsingValueDecl *<br>
 UnresolvedUsingValueDecl::<wbr>Create(ASTContext &C, DeclContext *DC,<br>
                                  SourceLocation UsingLoc,<br>
                                  NestedNameSpecifierLoc QualifierLoc,<br>
-                                 const DeclarationNameInfo &NameInfo) {<br>
+                                 const DeclarationNameInfo &NameInfo,<br>
+                                 SourceLocation EllipsisLoc) {<br>
   return new (C, DC) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,<br>
-                                              QualifierLoc, NameInfo);<br>
+                                              QualifierLoc, NameInfo,<br>
+                                              EllipsisLoc);<br>
 }<br>
<br>
 UnresolvedUsingValueDecl *<br>
@@ -2266,7 +2288,8 @@ UnresolvedUsingValueDecl::<wbr>CreateDeserial<br>
   return new (C, ID) UnresolvedUsingValueDecl(<wbr>nullptr, QualType(),<br>
                                               SourceLocation(),<br>
                                               NestedNameSpecifierLoc(),<br>
-                                              DeclarationNameInfo());<br>
+                                              DeclarationNameInfo(),<br>
+                                              SourceLocation());<br>
 }<br>
<br>
 SourceRange UnresolvedUsingValueDecl::<wbr>getSourceRange() const {<br>
@@ -2283,17 +2306,18 @@ UnresolvedUsingTypenameDecl::<wbr>Create(ASTC<br>
                                     SourceLocation TypenameLoc,<br>
                                     NestedNameSpecifierLoc QualifierLoc,<br>
                                     SourceLocation TargetNameLoc,<br>
-                                    DeclarationName TargetName) {<br>
+                                    DeclarationName TargetName,<br>
+                                    SourceLocation EllipsisLoc) {<br>
   return new (C, DC) UnresolvedUsingTypenameDecl(<br>
       DC, UsingLoc, TypenameLoc, QualifierLoc, TargetNameLoc,<br>
-      TargetName.<wbr>getAsIdentifierInfo());<br>
+      TargetName.<wbr>getAsIdentifierInfo(), EllipsisLoc);<br>
 }<br>
<br>
 UnresolvedUsingTypenameDecl *<br>
 UnresolvedUsingTypenameDecl::<wbr>CreateDeserialized(ASTContext &C, unsigned ID) {<br>
   return new (C, ID) UnresolvedUsingTypenameDecl(<br>
       nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(),<br>
-      SourceLocation(), nullptr);<br>
+      SourceLocation(), nullptr, SourceLocation());<br>
 }<br>
<br>
 void StaticAssertDecl::anchor() { }<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDecl.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/CodeGen/<wbr>CGDecl.cpp?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/CodeGen/CGDecl.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDecl.<wbr>cpp Sun Dec 18 22:08:53 2016<br>
@@ -113,6 +113,10 @@ void CodeGenFunction::EmitDecl(<wbr>const Dec<br>
     if (CGDebugInfo *DI = getDebugInfo())<br>
         DI->EmitUsingDecl(cast<<wbr>UsingDecl>(D));<br>
     return;<br>
+  case Decl::UsingPack:<br>
+    for (auto *Using : cast<UsingPackDecl>(D).<wbr>expansions())<br>
+      EmitDecl(*Using);<br>
+    return;<br>
   case Decl::UsingDirective: // using namespace X; [C++]<br>
     if (CGDebugInfo *DI = getDebugInfo())<br>
       DI->EmitUsingDirective(cast<<wbr>UsingDirectiveDecl>(D));<br>
<br>
Modified: cfe/trunk/lib/Parse/<wbr>ParseDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Parse/<wbr>ParseDeclCXX.cpp?rev=290080&<wbr>r1=290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Parse/<wbr>ParseDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/<wbr>ParseDeclCXX.cpp Sun Dec 18 22:08:53 2016<br>
@@ -560,7 +560,9 @@ bool Parser::ParseUsingDeclarator(<wbr>unsign<br>
   //   nested-name-specifier, the name is [...] considered to name the<br>
   //   constructor.<br>
   if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext &&<br>
-      Tok.is(tok::identifier) && NextToken().is(tok::semi) &&<br>
+      Tok.is(tok::identifier) &&<br>
+      (NextToken().is(tok::semi) || NextToken().is(tok::comma) ||<br>
+       NextToken().is(tok::ellipsis)) &&<br>
       D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&<br>
       !D.SS.getScopeRep()-><wbr>getAsNamespace() &&<br>
       !D.SS.getScopeRep()-><wbr>getAsNamespaceAlias()) {<br>
@@ -578,7 +580,10 @@ bool Parser::ParseUsingDeclarator(<wbr>unsign<br>
       return true;<br>
   }<br>
<br>
-  // FIXME: Parse optional ellipsis<br>
+  if (TryConsumeToken(tok::<wbr>ellipsis, D.EllipsisLoc))<br>
+    Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z ?<br>
+         diag::warn_cxx1z_compat_using_<wbr>declaration_pack :<br>
+         diag::ext_using_declaration_<wbr>pack);<br>
<br>
   return false;<br>
 }<br>
@@ -678,9 +683,9 @@ Parser::ParseUsingDeclaration(<wbr>unsigned C<br>
         D.TypenameLoc = SourceLocation();<br>
       }<br>
<br>
-      Decl *UD =<br>
-          Actions.ActOnUsingDeclaration(<wbr>getCurScope(), AS, UsingLoc, D.SS,<br>
-                                        D.Name, Attrs.getList(), D.TypenameLoc);<br>
+      Decl *UD = Actions.ActOnUsingDeclaration(<wbr>getCurScope(), AS, UsingLoc,<br>
+                                               D.TypenameLoc, D.SS, D.Name,<br>
+                                               D.EllipsisLoc, Attrs.getList());<br>
       if (UD)<br>
         DeclsInGroup.push_back(UD);<br>
     }<br>
@@ -708,62 +713,6 @@ Parser::ParseUsingDeclaration(<wbr>unsigned C<br>
   return Actions.BuildDeclaratorGroup(<wbr>DeclsInGroup, /*MayContainAuto*/false);<br>
 }<br>
<br>
-Decl *Parser::ParseAliasTemplate(<wbr>const ParsedTemplateInfo &TemplateInfo,<br>
-                                 SourceLocation &DeclEnd, AccessSpecifier AS,<br>
-                                 ParsedAttributesWithRange &MisplacedAttrs1) {<br>
-  assert(Tok.is(tok::kw_using) && "Not using token");<br>
-  ObjCDeclContextSwitch ObjCDC(*this);<br>
-<br>
-  // Eat 'using'.<br>
-  SourceLocation UsingLoc = ConsumeToken();<br>
-  if (Tok.is(tok::code_completion)) {<br>
-    Actions.CodeCompleteUsing(<wbr>getCurScope());<br>
-    cutOffParsing();<br>
-    return nullptr;<br>
-  }<br>
-<br>
-  // 'using namespace' means this is a using-directive.<br>
-  if (Tok.is(tok::kw_namespace)) {<br>
-    SourceRange R = TemplateInfo.getSourceRange();<br>
-    Diag(UsingLoc, diag::err_templated_using_<wbr>directive_declaration)<br>
-        << 0 /* directive */ << R;<br>
-    SkipUntil(tok::semi);<br>
-    return nullptr;<br>
-  }<br>
-<br>
-  // Check for misplaced attributes before the identifier.<br>
-  ParsedAttributesWithRange MisplacedAttrs2(AttrFactory);<br>
-  MaybeParseCXX11Attributes(<wbr>MisplacedAttrs2);<br>
-<br>
-  // FIXME: Just parse an identifier here?<br>
-  UsingDeclarator D;<br>
-  if (ParseUsingDeclarator(<wbr>Declarator::FileContext, D)) {<br>
-    SkipUntil(tok::semi);<br>
-    return nullptr;<br>
-  }<br>
-<br>
-  ParsedAttributesWithRange Attrs(AttrFactory);<br>
-<br>
-  // If we had any misplaced attributes from earlier, this is where they<br>
-  // should have been written.<br>
-  for (auto *MisplacedAttrs : {&MisplacedAttrs1, &MisplacedAttrs2}) {<br>
-    if (MisplacedAttrs->Range.<wbr>isValid()) {<br>
-      Diag(MisplacedAttrs->Range.<wbr>getBegin(), diag::err_attributes_not_<wbr>allowed)<br>
-        << FixItHint::<wbr>CreateInsertionFromRange(<br>
-               Tok.getLocation(),<br>
-               CharSourceRange::<wbr>getTokenRange(MisplacedAttrs-><wbr>Range))<br>
-        << FixItHint::CreateRemoval(<wbr>MisplacedAttrs->Range);<br>
-      Attrs.takeAllFrom(*<wbr>MisplacedAttrs);<br>
-    }<br>
-  }<br>
-<br>
-  MaybeParseGNUAttributes(Attrs)<wbr>;<br>
-  MaybeParseCXX11Attributes(<wbr>Attrs);<br>
-<br>
-  return ParseAliasDeclarationAfterDecl<wbr>arator(TemplateInfo, UsingLoc, D,<br>
-                                              DeclEnd, AS, Attrs);<br>
-}<br>
-<br>
 Decl *Parser::<wbr>ParseAliasDeclarationAfterDecl<wbr>arator(<br>
     const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc,<br>
     UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS,<br>
@@ -813,6 +762,9 @@ Decl *Parser::<wbr>ParseAliasDeclarationAfter<br>
   else if (D.SS.isNotEmpty())<br>
     Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_<wbr>not_identifier)<br>
       << FixItHint::CreateRemoval(D.SS.<wbr>getRange());<br>
+  if (D.EllipsisLoc.isValid())<br>
+    Diag(D.EllipsisLoc, diag::err_alias_declaration_<wbr>pack_expansion)<br>
+      << FixItHint::CreateRemoval(<wbr>SourceRange(D.EllipsisLoc));<br>
<br>
   Decl *DeclFromDeclSpec = nullptr;<br>
   TypeResult TypeAlias =<br>
@@ -2487,8 +2439,9 @@ Parser::<wbr>ParseCXXClassMemberDeclaration<wbr>(A<br>
       }<br>
<br>
       return DeclGroupPtrTy::make(<wbr>DeclGroupRef(Actions.<wbr>ActOnUsingDeclaration(<br>
-          getCurScope(), AS, /*UsingLoc*/SourceLocation(), SS, Name,<br>
-          /*AttrList*/nullptr, /*TypenameLoc*/SourceLocation(<wbr>))));<br>
+          getCurScope(), AS, /*UsingLoc*/ SourceLocation(),<br>
+          /*TypenameLoc*/ SourceLocation(), SS, Name,<br>
+          /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr)));<br>
     }<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaDeclCXX.cpp Sun Dec 18 22:08:53 2016<br>
@@ -8533,12 +8533,18 @@ void Sema::PushUsingDirective(Scope *S,<br>
 Decl *Sema::ActOnUsingDeclaration(<wbr>Scope *S,<br>
                                   AccessSpecifier AS,<br>
                                   SourceLocation UsingLoc,<br>
+                                  SourceLocation TypenameLoc,<br>
                                   CXXScopeSpec &SS,<br>
                                   UnqualifiedId &Name,<br>
-                                  AttributeList *AttrList,<br>
-                                  SourceLocation TypenameLoc) {<br>
+                                  SourceLocation EllipsisLoc,<br>
+                                  AttributeList *AttrList) {<br>
   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");<br>
<br>
+  if (SS.isEmpty()) {<br>
+    Diag(Name.getLocStart(), diag::err_using_requires_<wbr>qualname);<br>
+    return nullptr;<br>
+  }<br>
+<br>
   switch (Name.getKind()) {<br>
   case UnqualifiedId::IK_<wbr>ImplicitSelfParam:<br>
   case UnqualifiedId::IK_Identifier:<br>
@@ -8584,14 +8590,23 @@ Decl *Sema::ActOnUsingDeclaration(<wbr>Scope<br>
       << FixItHint::CreateInsertion(SS.<wbr>getRange().getBegin(), "using ");<br>
   }<br>
<br>
-  if (<wbr>DiagnoseUnexpandedParameterPac<wbr>k(SS, UPPC_UsingDeclaration) ||<br>
-      DiagnoseUnexpandedParameterPac<wbr>k(TargetNameInfo, UPPC_UsingDeclaration))<br>
-    return nullptr;<br>
+  if (EllipsisLoc.isInvalid()) {<br>
+    if (<wbr>DiagnoseUnexpandedParameterPac<wbr>k(SS, UPPC_UsingDeclaration) ||<br>
+        DiagnoseUnexpandedParameterPac<wbr>k(TargetNameInfo, UPPC_UsingDeclaration))<br>
+      return nullptr;<br>
+  } else {<br>
+    if (!SS.getScopeRep()-><wbr>containsUnexpandedParameterPac<wbr>k() &&<br>
+        !TargetNameInfo.<wbr>containsUnexpandedParameterPac<wbr>k()) {<br>
+      Diag(EllipsisLoc, diag::err_pack_expansion_<wbr>without_parameter_packs)<br>
+        << SourceRange(SS.getBeginLoc(), TargetNameInfo.getEndLoc());<br>
+      EllipsisLoc = SourceLocation();<br>
+    }<br>
+  }<br>
<br>
-  NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,<br>
-                                        TargetNameInfo, AttrList,<br>
-                                        /* IsInstantiation */ false,<br>
-                                        TypenameLoc.isValid(), TypenameLoc);<br>
+  NamedDecl *UD =<br>
+      BuildUsingDeclaration(S, AS, UsingLoc, TypenameLoc.isValid(), TypenameLoc,<br>
+                            SS, TargetNameInfo, EllipsisLoc, AttrList,<br>
+                            /*IsInstantiation*/false);<br>
   if (UD)<br>
     PushOnScopeChains(UD, S, /*AddToContext*/ false);<br>
<br>
@@ -8654,6 +8669,7 @@ bool Sema::CheckUsingShadowDecl(<wbr>UsingDec<br>
              diag::err_using_decl_nested_<wbr>name_specifier_is_current_<wbr>class)<br>
           << Using->getQualifierLoc().<wbr>getSourceRange();<br>
         Diag(Orig->getLocation(), diag::note_using_decl_target);<br>
+        Using->setInvalidDecl();<br>
         return true;<br>
       }<br>
<br>
@@ -8663,6 +8679,7 @@ bool Sema::CheckUsingShadowDecl(<wbr>UsingDec<br>
         << cast<CXXRecordDecl>(<wbr>CurContext)<br>
         << Using->getQualifierLoc().<wbr>getSourceRange();<br>
       Diag(Orig->getLocation(), diag::note_using_decl_target);<br>
+      Using->setInvalidDecl();<br>
       return true;<br>
     }<br>
   }<br>
@@ -8686,7 +8703,7 @@ bool Sema::CheckUsingShadowDecl(<wbr>UsingDec<br>
     // We can have UsingDecls in our Previous results because we use the same<br>
     // LookupResult for checking whether the UsingDecl itself is a valid<br>
     // redeclaration.<br>
-    if (isa<UsingDecl>(D))<br>
+    if (isa<UsingDecl>(D) || isa<UsingPackDecl>(D))<br>
       continue;<br>
<br>
     if (IsEquivalentForUsingDecl(<wbr>Context, D, Target)) {<br>
@@ -8732,6 +8749,7 @@ bool Sema::CheckUsingShadowDecl(<wbr>UsingDec<br>
<br>
     Diag(Target->getLocation(), diag::note_using_decl_target);<br>
     Diag(OldDecl->getLocation(), diag::note_using_decl_<wbr>conflict);<br>
+    Using->setInvalidDecl();<br>
     return true;<br>
   }<br>
<br>
@@ -8744,6 +8762,7 @@ bool Sema::CheckUsingShadowDecl(<wbr>UsingDec<br>
     Diag(Using->getLocation(), diag::err_using_decl_conflict)<wbr>;<br>
     Diag(Target->getLocation(), diag::note_using_decl_target);<br>
     Diag(Tag->getLocation(), diag::note_using_decl_<wbr>conflict);<br>
+    Using->setInvalidDecl();<br>
     return true;<br>
   }<br>
<br>
@@ -8753,6 +8772,7 @@ bool Sema::CheckUsingShadowDecl(<wbr>UsingDec<br>
   Diag(Using->getLocation(), diag::err_using_decl_conflict)<wbr>;<br>
   Diag(Target->getLocation(), diag::note_using_decl_target);<br>
   Diag(NonTag->getLocation(), diag::note_using_decl_<wbr>conflict);<br>
+  Using->setInvalidDecl();<br>
   return true;<br>
 }<br>
<br>
@@ -8960,23 +8980,19 @@ private:<br>
 ///   the lookup differently for these declarations.<br>
 NamedDecl *Sema::BuildUsingDeclaration(<wbr>Scope *S, AccessSpecifier AS,<br>
                                        SourceLocation UsingLoc,<br>
+                                       bool HasTypenameKeyword,<br>
+                                       SourceLocation TypenameLoc,<br>
                                        CXXScopeSpec &SS,<br>
                                        DeclarationNameInfo NameInfo,<br>
+                                       SourceLocation EllipsisLoc,<br>
                                        AttributeList *AttrList,<br>
-                                       bool IsInstantiation,<br>
-                                       bool HasTypenameKeyword,<br>
-                                       SourceLocation TypenameLoc) {<br>
+                                       bool IsInstantiation) {<br>
   assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");<br>
   SourceLocation IdentLoc = NameInfo.getLoc();<br>
   assert(IdentLoc.isValid() && "Invalid TargetName location.");<br>
<br>
   // FIXME: We ignore attributes for now.<br>
<br>
-  if (SS.isEmpty()) {<br>
-    Diag(IdentLoc, diag::err_using_requires_<wbr>qualname);<br>
-    return nullptr;<br>
-  }<br>
-<br>
   // For an inheriting constructor declaration, the name of the using<br>
   // declaration is the name of a constructor in this class, not in the<br>
   // base class.<br>
@@ -9042,16 +9058,17 @@ NamedDecl *Sema::BuildUsingDeclaration(S<br>
   DeclContext *LookupContext = computeDeclContext(SS);<br>
   NamedDecl *D;<br>
   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(<wbr>Context);<br>
-  if (!LookupContext) {<br>
+  if (!LookupContext || EllipsisLoc.isValid()) {<br>
     if (HasTypenameKeyword) {<br>
       // FIXME: not all declaration name kinds are legal here<br>
       D = UnresolvedUsingTypenameDecl::<wbr>Create(Context, CurContext,<br>
                                               UsingLoc, TypenameLoc,<br>
                                               QualifierLoc,<br>
-                                              IdentLoc, NameInfo.getName());<br>
+                                              IdentLoc, NameInfo.getName(),<br>
+                                              EllipsisLoc);<br>
     } else {<br>
       D = UnresolvedUsingValueDecl::<wbr>Create(Context, CurContext, UsingLoc,<br>
-                                           QualifierLoc, NameInfo);<br>
+                                           QualifierLoc, NameInfo, EllipsisLoc);<br>
     }<br>
     D->setAccess(AS);<br>
     CurContext->addDecl(D);<br>
@@ -9211,6 +9228,19 @@ NamedDecl *Sema::BuildUsingDeclaration(S<br>
   return UD;<br>
 }<br>
<br>
+NamedDecl *Sema::BuildUsingPackDecl(<wbr>NamedDecl *InstantiatedFrom,<br>
+                                    ArrayRef<NamedDecl *> Expansions) {<br>
+  assert(isa<<wbr>UnresolvedUsingValueDecl>(<wbr>InstantiatedFrom) ||<br>
+         isa<<wbr>UnresolvedUsingTypenameDecl>(<wbr>InstantiatedFrom) ||<br>
+         isa<UsingPackDecl>(<wbr>InstantiatedFrom));<br>
+<br>
+  auto *UPD =<br>
+      UsingPackDecl::Create(Context, CurContext, InstantiatedFrom, Expansions);<br>
+  UPD->setAccess(<wbr>InstantiatedFrom->getAccess())<wbr>;<br>
+  CurContext->addDecl(UPD);<br>
+  return UPD;<br>
+}<br>
+<br>
 /// Additional checks for a using declaration referring to a constructor name.<br>
 bool Sema::<wbr>CheckInheritingConstructorUsin<wbr>gDecl(UsingDecl *UD) {<br>
   assert(!UD->hasTypename() && "expecting a constructor name");<br>
@@ -9264,7 +9294,7 @@ bool Sema::<wbr>CheckUsingDeclRedeclaration(S<br>
     // scope?<br>
     if (Qual->isDependent() && !HasTypenameKeyword) {<br>
       for (auto *D : Prev) {<br>
-        if (!isa<TypeDecl>(D) && !isa<UsingDecl>(D)) {<br>
+        if (!isa<TypeDecl>(D) && !isa<UsingDecl>(D) && !isa<UsingPackDecl>(D)) {<br>
           bool OldCouldBeEnumerator =<br>
               isa<UnresolvedUsingValueDecl>(<wbr>D) || isa<EnumConstantDecl>(D);<br>
           Diag(NameLoc,<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaExprCXX.cpp Sun Dec 18 22:08:53 2016<br>
@@ -7462,17 +7462,11 @@ Sema::<wbr>CheckMicrosoftIfExistsSymbol(<wbr>Scope<br>
                                    UnqualifiedId &Name) {<br>
   DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name)<wbr>;<br>
<br>
-  // Check for unexpanded parameter packs.<br>
-  SmallVector<<wbr>UnexpandedParameterPack, 4> Unexpanded;<br>
-  collectUnexpandedParameterPack<wbr>s(SS, Unexpanded);<br>
-  collectUnexpandedParameterPack<wbr>s(TargetNameInfo, Unexpanded);<br>
-  if (!Unexpanded.empty()) {<br>
-    DiagnoseUnexpandedParameterPac<wbr>ks(KeywordLoc,<br>
-                                     IsIfExists? UPPC_IfExists<br>
-                                               : UPPC_IfNotExists,<br>
-                                     Unexpanded);<br>
+  // Check for an unexpanded parameter pack.<br>
+  auto UPPC = IsIfExists ? UPPC_IfExists : UPPC_IfNotExists;<br>
+  if (<wbr>DiagnoseUnexpandedParameterPac<wbr>k(SS, UPPC) ||<br>
+      DiagnoseUnexpandedParameterPac<wbr>k(TargetNameInfo, UPPC))<br>
     return IER_Error;<br>
-  }<br>
<br>
   return CheckMicrosoftIfExistsSymbol(<wbr>S, SS, TargetNameInfo);<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp?rev=290080&<wbr>r1=290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaOverload.cpp Sun Dec 18 22:08:53 2016<br>
@@ -981,7 +981,7 @@ Sema::CheckOverload(Scope *S, FunctionDe<br>
         Match = *I;<br>
         return Ovl_Match;<br>
       }<br>
-    } else if (isa<UsingDecl>(OldD)) {<br>
+    } else if (isa<UsingDecl>(OldD) || isa<UsingPackDecl>(OldD)) {<br>
       // We can overload with these, which can show up when doing<br>
       // redeclaration checks for UsingDecls.<br>
       assert(Old.getLookupKind() == LookupUsingDeclName);<br>
@@ -11420,6 +11420,12 @@ BuildRecoveryCallExpr(Sema &SemaRef, Sco<br>
<br>
   assert(!R.empty() && "lookup results empty despite recovery");<br>
<br>
+  // If recovery created an ambiguity, just bail out.<br>
+  if (R.isAmbiguous()) {<br>
+    R.suppressDiagnostics();<br>
+    return ExprError();<br>
+  }<br>
+<br>
   // Build an implicit member call if appropriate.  Just drop the<br>
   // casts and such from the call, we don't really care.<br>
   ExprResult NewFn = ExprError();<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp?rev=290080&r1=290079&r2=<wbr>290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp Sun Dec 18 22:08:53 2016<br>
@@ -2495,35 +2495,76 @@ Decl *TemplateDeclInstantiator::<wbr>VisitCon<br>
   return nullptr;<br>
 }<br>
<br>
-Decl * TemplateDeclInstantiator<br>
-    ::<wbr>VisitUnresolvedUsingTypenameDe<wbr>cl(UnresolvedUsingTypenameDecl *D) {<br>
-  NestedNameSpecifierLoc QualifierLoc<br>
-    = SemaRef.<wbr>SubstNestedNameSpecifierLoc(D-<wbr>>getQualifierLoc(),<br>
-                                          TemplateArgs);<br>
-  if (!QualifierLoc)<br>
-    return nullptr;<br>
+template <typename T><br>
+Decl *TemplateDeclInstantiator::<wbr>instantiateUnresolvedUsingDecl<wbr>(<br>
+    T *D, bool InstantiatingPackElement) {<br>
+  // If this is a pack expansion, expand it now.<br>
+  if (D->isPackExpansion() && !InstantiatingPackElement) {<br>
+    SmallVector<<wbr>UnexpandedParameterPack, 2> Unexpanded;<br>
+    SemaRef.<wbr>collectUnexpandedParameterPack<wbr>s(D->getQualifierLoc(), Unexpanded);<br>
+    SemaRef.<wbr>collectUnexpandedParameterPack<wbr>s(D->getNameInfo(), Unexpanded);<br>
+<br>
+    // Determine whether the set of unexpanded parameter packs can and should<br>
+    // be expanded.<br>
+    bool Expand = true;<br>
+    bool RetainExpansion = false;<br>
+    Optional<unsigned> NumExpansions;<br>
+    if (SemaRef.<wbr>CheckParameterPacksForExpansio<wbr>n(<br>
+          D->getEllipsisLoc(), D->getSourceRange(), Unexpanded, TemplateArgs,<br>
+            Expand, RetainExpansion, NumExpansions))<br>
+      return nullptr;<br>
<br>
-  CXXScopeSpec SS;<br>
-  SS.Adopt(QualifierLoc);<br>
+    // This declaration cannot appear within a function template signature,<br>
+    // so we can't have a partial argument list for a parameter pack.<br>
+    assert(!RetainExpansion &&<br>
+           "should never need to retain an expansion for UsingPackDecl");<br>
+<br>
+    if (!Expand) {<br>
+      // We cannot fully expand the pack expansion now, so substitute into the<br>
+      // pattern and create a new pack expansion.<br>
+      Sema::<wbr>ArgumentPackSubstitutionIndexR<wbr>AII SubstIndex(SemaRef, -1);<br>
+      return instantiateUnresolvedUsingDecl<wbr>(D, true);<br>
+    }<br>
+<br>
+    // Within a function, we don't have any normal way to check for conflicts<br>
+    // between shadow declarations from different using declarations in the<br>
+    // same pack expansion, but this is always ill-formed because all expansions<br>
+    // must produce (conflicting) enumerators.<br>
+    //<br>
+    // Sadly we can't just reject this in the template definition because it<br>
+    // could be valid if the pack is empty or has exactly one expansion.<br>
+    if (D->getDeclContext()-><wbr>isFunctionOrMethod() && *NumExpansions > 1) {<br>
+      SemaRef.Diag(D-><wbr>getEllipsisLoc(),<br>
+                   diag::err_using_decl_<wbr>redeclaration_expansion);<br>
+      return nullptr;<br>
+    }<br>
<br>
-  // Since NameInfo refers to a typename, it cannot be a C++ special name.<br>
-  // Hence, no transformation is required for it.<br>
-  DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());<br>
-  NamedDecl *UD =<br>
-    SemaRef.BuildUsingDeclaration(<wbr>/*Scope*/ nullptr, D->getAccess(),<br>
-                                  D->getUsingLoc(), SS, NameInfo, nullptr,<br>
-                                  /*instantiation*/ true,<br>
-                                  /*typename*/ true, D->getTypenameLoc());<br>
-  if (UD)<br>
-    SemaRef.Context.<wbr>setInstantiatedFromUsingDecl(<wbr>UD, D);<br>
+    // Instantiate the slices of this pack and build a UsingPackDecl.<br>
+    SmallVector<NamedDecl*, 8> Expansions;<br>
+    for (unsigned I = 0; I != *NumExpansions; ++I) {<br>
+      Sema::<wbr>ArgumentPackSubstitutionIndexR<wbr>AII SubstIndex(SemaRef, I);<br>
+      Decl *Slice = instantiateUnresolvedUsingDecl<wbr>(D, true);<br>
+      if (!Slice)<br>
+        return nullptr;<br>
+      // Note that we can still get unresolved using declarations here, if we<br>
+      // had arguments for all packs but the pattern also contained other<br>
+      // template arguments (this only happens during partial substitution, eg<br>
+      // into the body of a generic lambda in a function template).<br>
+      Expansions.push_back(cast<<wbr>NamedDecl>(Slice));<br>
+    }<br>
+<br>
+    auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);<br>
+    if (isDeclWithinFunction(D))<br>
+      SemaRef.<wbr>CurrentInstantiationScope-><wbr>InstantiatedLocal(D, NewD);<br>
+    return NewD;<br>
+  }<br>
<br>
-  return UD;<br>
-}<br>
+  UnresolvedUsingTypenameDecl *TD = dyn_cast<<wbr>UnresolvedUsingTypenameDecl>(<wbr>D);<br>
+  SourceLocation TypenameLoc = TD ? TD->getTypenameLoc() : SourceLocation();<br>
<br>
-Decl * TemplateDeclInstantiator<br>
-    ::<wbr>VisitUnresolvedUsingValueDecl(<wbr>UnresolvedUsingValueDecl *D) {<br>
   NestedNameSpecifierLoc QualifierLoc<br>
-      = SemaRef.<wbr>SubstNestedNameSpecifierLoc(D-<wbr>>getQualifierLoc(), TemplateArgs);<br>
+    = SemaRef.<wbr>SubstNestedNameSpecifierLoc(D-<wbr>>getQualifierLoc(),<br>
+                                          TemplateArgs);<br>
   if (!QualifierLoc)<br>
     return nullptr;<br>
<br>
@@ -2533,17 +2574,48 @@ Decl * TemplateDeclInstantiator<br>
   DeclarationNameInfo NameInfo<br>
     = SemaRef.<wbr>SubstDeclarationNameInfo(D-><wbr>getNameInfo(), TemplateArgs);<br>
<br>
-  NamedDecl *UD =<br>
-    SemaRef.BuildUsingDeclaration(<wbr>/*Scope*/ nullptr, D->getAccess(),<br>
-                                  D->getUsingLoc(), SS, NameInfo, nullptr,<br>
-                                  /*instantiation*/ true,<br>
-                                  /*typename*/ false, SourceLocation());<br>
+  // Produce a pack expansion only if we're not instantiating a particular<br>
+  // slice of a pack expansion.<br>
+  bool InstantiatingSlice = D->getEllipsisLoc().isValid() &&<br>
+                            SemaRef.<wbr>ArgumentPackSubstitutionIndex != -1;<br>
+  SourceLocation EllipsisLoc =<br>
+      InstantiatingSlice ? SourceLocation() : D->getEllipsisLoc();<br>
+<br>
+  NamedDecl *UD = SemaRef.BuildUsingDeclaration(<br>
+      /*Scope*/ nullptr, D->getAccess(), D->getUsingLoc(),<br>
+      /*HasTypename*/ TD, TypenameLoc, SS, NameInfo, EllipsisLoc, nullptr,<br>
+      /*IsInstantiation*/ true);<br>
   if (UD)<br>
     SemaRef.Context.<wbr>setInstantiatedFromUsingDecl(<wbr>UD, D);<br>
<br>
   return UD;<br>
 }<br>
<br>
+Decl *TemplateDeclInstantiator::<wbr>VisitUnresolvedUsingTypenameDe<wbr>cl(<br>
+    UnresolvedUsingTypenameDecl *D) {<br>
+  return instantiateUnresolvedUsingDecl<wbr>(D);<br>
+}<br>
+<br>
+Decl *TemplateDeclInstantiator::<wbr>VisitUnresolvedUsingValueDecl(<br>
+    UnresolvedUsingValueDecl *D) {<br>
+  return instantiateUnresolvedUsingDecl<wbr>(D);<br>
+}<br>
+<br>
+Decl *TemplateDeclInstantiator::<wbr>VisitUsingPackDecl(<wbr>UsingPackDecl *D) {<br>
+  SmallVector<NamedDecl*, 8> Expansions;<br>
+  for (auto *UD : D->expansions()) {<br>
+    if (auto *NewUD =<br>
+            SemaRef.FindInstantiatedDecl(<wbr>D->getLocation(), UD, TemplateArgs))<br>
+      Expansions.push_back(cast<<wbr>NamedDecl>(NewUD));<br>
+    else<br>
+      return nullptr;<br>
+  }<br>
+<br>
+  auto *NewD = SemaRef.BuildUsingPackDecl(D, Expansions);<br>
+  if (isDeclWithinFunction(D))<br>
+    SemaRef.<wbr>CurrentInstantiationScope-><wbr>InstantiatedLocal(D, NewD);<br>
+  return NewD;<br>
+}<br>
<br>
 Decl *TemplateDeclInstantiator::<wbr>VisitClassScopeFunctionSpecial<wbr>izationDecl(<br>
                                      ClassScopeFunctionSpecializati<wbr>onDecl *Decl) {<br>
@@ -4513,22 +4585,36 @@ static bool isInstantiationOf(UsingShado<br>
                             Pattern);<br>
 }<br>
<br>
-static bool isInstantiationOf(UsingDecl *Pattern,<br>
-                              UsingDecl *Instance,<br>
-                              ASTContext &C) {<br>
-  return declaresSameEntity(C.<wbr>getInstantiatedFromUsingDecl(<wbr>Instance), Pattern);<br>
-}<br>
-<br>
-static bool isInstantiationOf(<wbr>UnresolvedUsingValueDecl *Pattern,<br>
-                              NamedDecl *Instance,<br>
+static bool isInstantiationOf(UsingDecl *Pattern, UsingDecl *Instance,<br>
                               ASTContext &C) {<br>
   return declaresSameEntity(C.<wbr>getInstantiatedFromUsingDecl(<wbr>Instance), Pattern);<br>
 }<br>
<br>
-static bool isInstantiationOf(<wbr>UnresolvedUsingTypenameDecl *Pattern,<br>
-                              NamedDecl *Instance,<br>
-                              ASTContext &C) {<br>
-  return declaresSameEntity(C.<wbr>getInstantiatedFromUsingDecl(<wbr>Instance), Pattern);<br>
+template<typename T><br>
+static bool isInstantiationOfUnresolvedUsi<wbr>ngDecl(T *Pattern, Decl *Other,<br>
+                                                 ASTContext &Ctx) {<br>
+  // An unresolved using declaration can instantiate to an unresolved using<br>
+  // declaration, or to a using declaration or a using declaration pack.<br>
+  //<br>
+  // Multiple declarations can claim to be instantiated from an unresolved<br>
+  // using declaration if it's a pack expansion. We want the UsingPackDecl<br>
+  // in that case, not the individual UsingDecls within the pack.<br>
+  bool OtherIsPackExpansion;<br>
+  NamedDecl *OtherFrom;<br>
+  if (auto *OtherUUD = dyn_cast<T>(Other)) {<br>
+    OtherIsPackExpansion = OtherUUD->isPackExpansion();<br>
+    OtherFrom = Ctx.<wbr>getInstantiatedFromUsingDecl(<wbr>OtherUUD);<br>
+  } else if (auto *OtherUPD = dyn_cast<UsingPackDecl>(Other)<wbr>) {<br>
+    OtherIsPackExpansion = true;<br>
+    OtherFrom = OtherUPD-><wbr>getInstantiatedFromUsingDecl()<wbr>;<br>
+  } else if (auto *OtherUD = dyn_cast<UsingDecl>(Other)) {<br>
+    OtherIsPackExpansion = false;<br>
+    OtherFrom = Ctx.<wbr>getInstantiatedFromUsingDecl(<wbr>OtherUD);<br>
+  } else {<br>
+    return false;<br>
+  }<br>
+  return Pattern->isPackExpansion() == OtherIsPackExpansion &&<br>
+         declaresSameEntity(OtherFrom, Pattern);<br>
 }<br>
<br>
 static bool isInstantiationOfStaticDataMem<wbr>ber(VarDecl *Pattern,<br>
@@ -4549,21 +4635,14 @@ static bool isInstantiationOfStaticDataM<br>
 // Other is the prospective instantiation<br>
 // D is the prospective pattern<br>
 static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {<br>
-  if (D->getKind() != Other->getKind()) {<br>
-    if (auto *UUD = dyn_cast<<wbr>UnresolvedUsingTypenameDecl>(<wbr>D)) {<br>
-      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {<br>
-        return isInstantiationOf(UUD, UD, Ctx);<br>
-      }<br>
-    }<br>
+  if (auto *UUD = dyn_cast<<wbr>UnresolvedUsingTypenameDecl>(<wbr>D))<br>
+    return isInstantiationOfUnresolvedUsi<wbr>ngDecl(UUD, Other, Ctx);<br>
<br>
-    if (auto *UUD = dyn_cast<<wbr>UnresolvedUsingValueDecl>(D)) {<br>
-      if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {<br>
-        return isInstantiationOf(UUD, UD, Ctx);<br>
-      }<br>
-    }<br>
+  if (auto *UUD = dyn_cast<<wbr>UnresolvedUsingValueDecl>(D))<br>
+    return isInstantiationOfUnresolvedUsi<wbr>ngDecl(UUD, Other, Ctx);<br>
<br>
+  if (D->getKind() != Other->getKind())<br>
     return false;<br>
-  }<br>
<br>
   if (auto *Record = dyn_cast<CXXRecordDecl>(Other)<wbr>)<br>
     return isInstantiationOf(cast<<wbr>CXXRecordDecl>(D), Record);<br>
@@ -4600,12 +4679,6 @@ static bool isInstantiationOf(ASTContext<br>
   if (auto *Using = dyn_cast<UsingDecl>(Other))<br>
     return isInstantiationOf(cast<<wbr>UsingDecl>(D), Using, Ctx);<br>
<br>
-  if (auto *Using = dyn_cast<<wbr>UnresolvedUsingValueDecl>(<wbr>Other))<br>
-    return isInstantiationOf(cast<<wbr>UnresolvedUsingValueDecl>(D), Using, Ctx);<br>
-<br>
-  if (auto *Using = dyn_cast<<wbr>UnresolvedUsingTypenameDecl>(<wbr>Other))<br>
-    return isInstantiationOf(cast<<wbr>UnresolvedUsingTypenameDecl>(<wbr>D), Using, Ctx);<br>
-<br>
   if (auto *Shadow = dyn_cast<UsingShadowDecl>(<wbr>Other))<br>
     return isInstantiationOf(cast<<wbr>UsingShadowDecl>(D), Shadow, Ctx);<br>
<br>
@@ -4846,6 +4919,8 @@ NamedDecl *Sema::FindInstantiatedDecl(So<br>
     }<br>
<br>
     NamedDecl *Result = nullptr;<br>
+    // FIXME: If the name is a dependent name, this lookup won't necessarily<br>
+    // find it. Does that ever matter?<br>
     if (D->getDeclName()) {<br>
       DeclContext::lookup_result Found = ParentDC->lookup(D-><wbr>getDeclName());<br>
       Result = findInstantiationOf(Context, D, Found.begin(), Found.end());<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplateVariadic.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplateVariadic.cpp?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaTemplateVariadic.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaTemplateVariadic.cpp Sun Dec 18 22:08:53 2016<br>
@@ -390,21 +390,18 @@ void Sema::<wbr>collectUnexpandedParameterPac<br>
 void Sema::<wbr>collectUnexpandedParameterPack<wbr>s(TypeLoc TL,<br>
                    SmallVectorImpl<<wbr>UnexpandedParameterPack> &Unexpanded) {<br>
   CollectUnexpandedParameterPack<wbr>sVisitor(Unexpanded).<wbr>TraverseTypeLoc(TL);<br>
-}<br>
+}<br>
<br>
-void Sema::<wbr>collectUnexpandedParameterPack<wbr>s(CXXScopeSpec &SS,<br>
-                                           SmallVectorImpl<<wbr>UnexpandedParameterPack> &Unexpanded) {<br>
-  NestedNameSpecifier *Qualifier = SS.getScopeRep();<br>
-  if (!Qualifier)<br>
-    return;<br>
-<br>
-  NestedNameSpecifierLoc QualifierLoc(Qualifier, SS.location_data());<br>
+void Sema::<wbr>collectUnexpandedParameterPack<wbr>s(<br>
+    NestedNameSpecifierLoc NNS,<br>
+    SmallVectorImpl<<wbr>UnexpandedParameterPack> &Unexpanded) {<br>
   CollectUnexpandedParameterPack<wbr>sVisitor(Unexpanded)<br>
-    .<wbr>TraverseNestedNameSpecifierLoc<wbr>(QualifierLoc);<br>
+      .<wbr>TraverseNestedNameSpecifierLoc<wbr>(NNS);<br>
 }<br>
<br>
-void Sema::<wbr>collectUnexpandedParameterPack<wbr>s(const DeclarationNameInfo &NameInfo,<br>
-                         SmallVectorImpl<<wbr>UnexpandedParameterPack> &Unexpanded) {<br>
+void Sema::<wbr>collectUnexpandedParameterPack<wbr>s(<br>
+    const DeclarationNameInfo &NameInfo,<br>
+    SmallVectorImpl<<wbr>UnexpandedParameterPack> &Unexpanded) {<br>
   CollectUnexpandedParameterPack<wbr>sVisitor(Unexpanded)<br>
     .TraverseDeclarationNameInfo(<wbr>NameInfo);<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>TreeTransform.h?rev=290080&r1=<wbr>290079&r2=290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>TreeTransform.h Sun Dec 18 22:08:53 2016<br>
@@ -457,6 +457,10 @@ public:<br>
     return cast_or_null<NamedDecl>(<wbr>getDerived().TransformDecl(<wbr>Loc, D));<br>
   }<br>
<br>
+  /// Transform the set of declarations in an OverloadExpr.<br>
+  bool TransformOverloadExprDecls(<wbr>OverloadExpr *Old, bool RequiresADL,<br>
+                                  LookupResult &R);<br>
+<br>
   /// \brief Transform the given nested-name-specifier with source-location<br>
   /// information.<br>
   ///<br>
@@ -821,7 +825,7 @@ public:<br>
<br>
   /// \brief Rebuild an unresolved typename type, given the decl that<br>
   /// the UnresolvedUsingTypenameDecl was transformed to.<br>
-  QualType RebuildUnresolvedUsingType(<wbr>Decl *D);<br>
+  QualType RebuildUnresolvedUsingType(<wbr>SourceLocation NameLoc, Decl *D);<br>
<br>
   /// \brief Build a new typedef type.<br>
   QualType RebuildTypedefType(<wbr>TypedefNameDecl *Typedef) {<br>
@@ -5161,7 +5165,7 @@ TreeTransform<Derived>::<wbr>TransformUnresol<br>
<br>
   QualType Result = TL.getType();<br>
   if (getDerived().AlwaysRebuild() || D != T->getDecl()) {<br>
-    Result = getDerived().<wbr>RebuildUnresolvedUsingType(D);<br>
+    Result = getDerived().<wbr>RebuildUnresolvedUsingType(TL.<wbr>getNameLoc(), D);<br>
     if (Result.isNull())<br>
       return QualType();<br>
   }<br>
@@ -9794,44 +9798,71 @@ TreeTransform<Derived>::<wbr>TransformCXXPseu<br>
                                                      Destroyed);<br>
 }<br>
<br>
-template<typename Derived><br>
-ExprResult<br>
-TreeTransform<Derived>::<wbr>TransformUnresolvedLookupExpr(<br>
-                                                  UnresolvedLookupExpr *Old) {<br>
-  LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),<br>
-                 Sema::LookupOrdinaryName);<br>
-<br>
+template <typename Derived><br>
+bool TreeTransform<Derived>::<wbr>TransformOverloadExprDecls(<wbr>OverloadExpr *Old,<br>
+                                                        bool RequiresADL,<br>
+                                                        LookupResult &R) {<br>
   // Transform all the decls.<br>
-  for (UnresolvedLookupExpr::decls_<wbr>iterator I = Old->decls_begin(),<br>
-         E = Old->decls_end(); I != E; ++I) {<br>
-    NamedDecl *InstD = static_cast<NamedDecl*>(<br>
-                                 getDerived().TransformDecl(<wbr>Old->getNameLoc(),<br>
-                                                            *I));<br>
+  bool AllEmptyPacks = true;<br>
+  for (auto *OldD : Old->decls()) {<br>
+    Decl *InstD = getDerived().TransformDecl(<wbr>Old->getNameLoc(), OldD);<br>
     if (!InstD) {<br>
       // Silently ignore these if a UsingShadowDecl instantiated to nothing.<br>
       // This can happen because of dependent hiding.<br>
-      if (isa<UsingShadowDecl>(*I))<br>
+      if (isa<UsingShadowDecl>(OldD))<br>
         continue;<br>
       else {<br>
         R.clear();<br>
-        return ExprError();<br>
+        return true;<br>
       }<br>
     }<br>
<br>
+    // Expand using pack declarations.<br>
+    ArrayRef<NamedDecl*> Decls = cast<NamedDecl>(InstD);<br>
+    if (auto *UPD = dyn_cast<UsingPackDecl>(InstD)<wbr>)<br>
+      Decls = UPD->expansions();<br>
+<br>
     // Expand using declarations.<br>
-    if (isa<UsingDecl>(InstD)) {<br>
-      UsingDecl *UD = cast<UsingDecl>(InstD);<br>
-      for (auto *I : UD->shadows())<br>
-        R.addDecl(I);<br>
-      continue;<br>
+    for (auto *D : Decls) {<br>
+      if (auto *UD = dyn_cast<UsingDecl>(D)) {<br>
+        for (auto *SD : UD->shadows())<br>
+          R.addDecl(SD);<br>
+      } else {<br>
+        R.addDecl(D);<br>
+      }<br>
     }<br>
<br>
-    R.addDecl(InstD);<br>
+    AllEmptyPacks &= Decls.empty();<br>
+  };<br>
+<br>
+  // C++ [temp.res]/8.4.2:<br>
+  //   The program is ill-formed, no diagnostic required, if [...] lookup for<br>
+  //   a name in the template definition found a using-declaration, but the<br>
+  //   lookup in the corresponding scope in the instantiation odoes not find<br>
+  //   any declarations because the using-declaration was a pack expansion and<br>
+  //   the corresponding pack is empty<br>
+  if (AllEmptyPacks && !RequiresADL) {<br>
+    getSema().Diag(Old-><wbr>getNameLoc(), diag::err_using_pack_<wbr>expansion_empty)<br>
+        << isa<UnresolvedMemberExpr>(Old) << Old->getNameInfo().getName();<br>
+    return true;<br>
   }<br>
<br>
   // Resolve a kind, but don't do any further analysis.  If it's<br>
   // ambiguous, the callee needs to deal with it.<br>
   R.resolveKind();<br>
+  return false;<br>
+}<br>
+<br>
+template<typename Derived><br>
+ExprResult<br>
+TreeTransform<Derived>::<wbr>TransformUnresolvedLookupExpr(<br>
+                                                  UnresolvedLookupExpr *Old) {<br>
+  LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),<br>
+                 Sema::LookupOrdinaryName);<br>
+<br>
+  // Transform the declaration set.<br>
+  if (TransformOverloadExprDecls(<wbr>Old, Old->requiresADL(), R))<br>
+    return ExprError();<br>
<br>
   // Rebuild the nested-name qualifier, if present.<br>
   CXXScopeSpec SS;<br>
@@ -10699,35 +10730,9 @@ TreeTransform<Derived>::<wbr>TransformUnresol<br>
   LookupResult R(SemaRef, Old->getMemberNameInfo(),<br>
                  Sema::LookupOrdinaryName);<br>
<br>
-  // Transform all the decls.<br>
-  for (UnresolvedMemberExpr::decls_<wbr>iterator I = Old->decls_begin(),<br>
-         E = Old->decls_end(); I != E; ++I) {<br>
-    NamedDecl *InstD = static_cast<NamedDecl*>(<br>
-                                getDerived().TransformDecl(<wbr>Old->getMemberLoc(),<br>
-                                                           *I));<br>
-    if (!InstD) {<br>
-      // Silently ignore these if a UsingShadowDecl instantiated to nothing.<br>
-      // This can happen because of dependent hiding.<br>
-      if (isa<UsingShadowDecl>(*I))<br>
-        continue;<br>
-      else {<br>
-        R.clear();<br>
-        return ExprError();<br>
-      }<br>
-    }<br>
-<br>
-    // Expand using declarations.<br>
-    if (isa<UsingDecl>(InstD)) {<br>
-      UsingDecl *UD = cast<UsingDecl>(InstD);<br>
-      for (auto *I : UD->shadows())<br>
-        R.addDecl(I);<br>
-      continue;<br>
-    }<br>
-<br>
-    R.addDecl(InstD);<br>
-  }<br>
-<br>
-  R.resolveKind();<br>
+  // Transform the declaration set.<br>
+  if (TransformOverloadExprDecls(<wbr>Old, /*RequiresADL*/false, R))<br>
+    return ExprError();<br>
<br>
   // Determine the naming class.<br>
   if (Old->getNamingClass()) {<br>
@@ -11842,21 +11847,48 @@ QualType TreeTransform<Derived>::<wbr>Rebuild<br>
 }<br>
<br>
 template<typename Derived><br>
-QualType TreeTransform<Derived>::<wbr>RebuildUnresolvedUsingType(<wbr>Decl *D) {<br>
+QualType TreeTransform<Derived>::<wbr>RebuildUnresolvedUsingType(<wbr>SourceLocation Loc,<br>
+                                                            Decl *D) {<br>
   assert(D && "no decl found");<br>
   if (D->isInvalidDecl()) return QualType();<br>
<br>
   // FIXME: Doesn't account for ObjCInterfaceDecl!<br>
   TypeDecl *Ty;<br>
-  if (isa<UsingDecl>(D)) {<br>
-    UsingDecl *Using = cast<UsingDecl>(D);<br>
+  if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {<br>
+    // A valid resolved using typename pack expansion decl can have multiple<br>
+    // UsingDecls, but they must each have exactly one type, and it must be<br>
+    // the same type in every case. But we must have at least one expansion!<br>
+    if (UPD->expansions().empty()) {<br>
+      getSema().Diag(Loc, diag::err_using_pack_<wbr>expansion_empty)<br>
+          << UPD->isCXXClassMember() << UPD;<br>
+      return QualType();<br>
+    }<br>
+<br>
+    // We might still have some unresolved types. Try to pick a resolved type<br>
+    // if we can. The final instantiation will check that the remaining<br>
+    // unresolved types instantiate to the type we pick.<br>
+    QualType FallbackT;<br>
+    QualType T;<br>
+    for (auto *E : UPD->expansions()) {<br>
+      QualType ThisT = RebuildUnresolvedUsingType(<wbr>Loc, E);<br>
+      if (ThisT.isNull())<br>
+        continue;<br>
+      else if (ThisT->getAs<<wbr>UnresolvedUsingType>())<br>
+        FallbackT = ThisT;<br>
+      else if (T.isNull())<br>
+        T = ThisT;<br>
+      else<br>
+        assert(getSema().Context.<wbr>hasSameType(ThisT, T) &&<br>
+               "mismatched resolved types in using pack expansion");<br>
+    }<br>
+    return T.isNull() ? FallbackT : T;<br>
+  } else if (auto *Using = dyn_cast<UsingDecl>(D)) {<br>
     assert(Using->hasTypename() &&<br>
            "UnresolvedUsingTypenameDecl transformed to non-typename using");<br>
<br>
     // A valid resolved using typename decl points to exactly one type decl.<br>
     assert(++Using->shadow_begin() == Using->shadow_end());<br>
     Ty = cast<TypeDecl>((*Using-><wbr>shadow_begin())-><wbr>getTargetDecl());<br>
-<br>
   } else {<br>
     assert(isa<<wbr>UnresolvedUsingTypenameDecl>(<wbr>D) &&<br>
            "UnresolvedUsingTypenameDecl transformed to non-using decl");<br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTCommon.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTCommon.cpp?<wbr>rev=290080&r1=290079&r2=<wbr>290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTCommon.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTCommon.cpp Sun Dec 18 22:08:53 2016<br>
@@ -285,6 +285,7 @@ bool serialization::<wbr>isRedeclarableDeclKi<br>
   case Decl::NonTypeTemplateParm:<br>
   case Decl::TemplateTemplateParm:<br>
   case Decl::Using:<br>
+  case Decl::UsingPack:<br>
   case Decl::ObjCMethod:<br>
   case Decl::ObjCCategory:<br>
   case Decl::ObjCCategoryImpl:<br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTReaderDecl.<wbr>cpp?rev=290080&r1=290079&r2=<wbr>290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp Sun Dec 18 22:08:53 2016<br>
@@ -322,6 +322,7 @@ namespace clang {<br>
     void VisitTemplateTemplateParmDecl(<wbr>TemplateTemplateParmDecl *D);<br>
     void VisitTypeAliasTemplateDecl(<wbr>TypeAliasTemplateDecl *D);<br>
     void VisitUsingDecl(UsingDecl *D);<br>
+    void VisitUsingPackDecl(<wbr>UsingPackDecl *D);<br>
     void VisitUsingShadowDecl(<wbr>UsingShadowDecl *D);<br>
     void VisitConstructorUsingShadowDec<wbr>l(ConstructorUsingShadowDecl *D);<br>
     void VisitLinkageSpecDecl(<wbr>LinkageSpecDecl *D);<br>
@@ -1419,6 +1420,15 @@ void ASTDeclReader::VisitUsingDecl(<wbr>Using<br>
   mergeMergeable(D);<br>
 }<br>
<br>
+void ASTDeclReader::<wbr>VisitUsingPackDecl(<wbr>UsingPackDecl *D) {<br>
+  VisitNamedDecl(D);<br>
+  D->InstantiatedFrom = ReadDeclAs<NamedDecl>();<br>
+  NamedDecl **Expansions = D->getTrailingObjects<<wbr>NamedDecl*>();<br>
+  for (unsigned I = 0; I != D->NumExpansions; ++I)<br>
+    Expansions[I] = ReadDeclAs<NamedDecl>();<br>
+  mergeMergeable(D);<br>
+}<br>
+<br>
 void ASTDeclReader::<wbr>VisitUsingShadowDecl(<wbr>UsingShadowDecl *D) {<br>
   RedeclarableResult Redecl = VisitRedeclarable(D);<br>
   VisitNamedDecl(D);<br>
@@ -1452,6 +1462,7 @@ void ASTDeclReader::<wbr>VisitUnresolvedUsing<br>
   D->setUsingLoc(<wbr>ReadSourceLocation());<br>
   D->QualifierLoc = Record.<wbr>ReadNestedNameSpecifierLoc(<wbr>Idx);<br>
   ReadDeclarationNameLoc(D-><wbr>DNLoc, D->getDeclName());<br>
+  D->EllipsisLoc = ReadSourceLocation();<br>
   mergeMergeable(D);<br>
 }<br>
<br>
@@ -1460,6 +1471,7 @@ void ASTDeclReader::<wbr>VisitUnresolvedUsing<br>
   VisitTypeDecl(D);<br>
   D->TypenameLocation = ReadSourceLocation();<br>
   D->QualifierLoc = Record.<wbr>ReadNestedNameSpecifierLoc(<wbr>Idx);<br>
+  D->EllipsisLoc = ReadSourceLocation();<br>
   mergeMergeable(D);<br>
 }<br>
<br>
@@ -3297,6 +3309,9 @@ Decl *ASTReader::ReadDeclRecord(<wbr>DeclID I<br>
   case DECL_USING:<br>
     D = UsingDecl::CreateDeserialized(<wbr>Context, ID);<br>
     break;<br>
+  case DECL_USING_PACK:<br>
+    D = UsingPackDecl::<wbr>CreateDeserialized(Context, ID, Record[Idx++]);<br>
+    break;<br>
   case DECL_USING_SHADOW:<br>
     D = UsingShadowDecl::<wbr>CreateDeserialized(Context, ID);<br>
     break;<br>
<br>
Modified: cfe/trunk/lib/Serialization/<wbr>ASTWriterDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTWriterDecl.<wbr>cpp?rev=290080&r1=290079&r2=<wbr>290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Serialization/<wbr>ASTWriterDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/<wbr>ASTWriterDecl.cpp Sun Dec 18 22:08:53 2016<br>
@@ -107,6 +107,7 @@ namespace clang {<br>
     void VisitTemplateTemplateParmDecl(<wbr>TemplateTemplateParmDecl *D);<br>
     void VisitTypeAliasTemplateDecl(<wbr>TypeAliasTemplateDecl *D);<br>
     void VisitUsingDecl(UsingDecl *D);<br>
+    void VisitUsingPackDecl(<wbr>UsingPackDecl *D);<br>
     void VisitUsingShadowDecl(<wbr>UsingShadowDecl *D);<br>
     void VisitConstructorUsingShadowDec<wbr>l(ConstructorUsingShadowDecl *D);<br>
     void VisitLinkageSpecDecl(<wbr>LinkageSpecDecl *D);<br>
@@ -1142,6 +1143,15 @@ void ASTDeclWriter::VisitUsingDecl(<wbr>Using<br>
   Code = serialization::DECL_USING;<br>
 }<br>
<br>
+void ASTDeclWriter::<wbr>VisitUsingPackDecl(<wbr>UsingPackDecl *D) {<br>
+  Record.push_back(D-><wbr>NumExpansions);<br>
+  VisitNamedDecl(D);<br>
+  Record.AddDeclRef(D-><wbr>getInstantiatedFromUsingDecl()<wbr>);<br>
+  for (auto *E : D->expansions())<br>
+    Record.AddDeclRef(E);<br>
+  Code = serialization::DECL_USING_<wbr>PACK;<br>
+}<br>
+<br>
 void ASTDeclWriter::<wbr>VisitUsingShadowDecl(<wbr>UsingShadowDecl *D) {<br>
   VisitRedeclarable(D);<br>
   VisitNamedDecl(D);<br>
@@ -1175,6 +1185,7 @@ void ASTDeclWriter::<wbr>VisitUnresolvedUsing<br>
   Record.AddSourceLocation(D-><wbr>getUsingLoc());<br>
   Record.<wbr>AddNestedNameSpecifierLoc(D-><wbr>getQualifierLoc());<br>
   Record.AddDeclarationNameLoc(<wbr>D->DNLoc, D->getDeclName());<br>
+  Record.AddSourceLocation(D-><wbr>getEllipsisLoc());<br>
   Code = serialization::DECL_<wbr>UNRESOLVED_USING_VALUE;<br>
 }<br>
<br>
@@ -1183,6 +1194,7 @@ void ASTDeclWriter::<wbr>VisitUnresolvedUsing<br>
   VisitTypeDecl(D);<br>
   Record.AddSourceLocation(D-><wbr>getTypenameLoc());<br>
   Record.<wbr>AddNestedNameSpecifierLoc(D-><wbr>getQualifierLoc());<br>
+  Record.AddSourceLocation(D-><wbr>getEllipsisLoc());<br>
   Code = serialization::DECL_<wbr>UNRESOLVED_USING_TYPENAME;<br>
 }<br>
<br>
<br>
Added: cfe/trunk/test/PCH/cxx1z-<wbr>using-declaration.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx1z-using-declaration.cpp?rev=290080&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/PCH/<wbr>cxx1z-using-declaration.cpp?<wbr>rev=290080&view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/PCH/cxx1z-<wbr>using-declaration.cpp (added)<br>
+++ cfe/trunk/test/PCH/cxx1z-<wbr>using-declaration.cpp Sun Dec 18 22:08:53 2016<br>
@@ -0,0 +1,35 @@<br>
+// No PCH:<br>
+// RUN: %clang_cc1 -pedantic -std=c++1z -include %s -verify %s<br>
+//<br>
+// With PCH:<br>
+// RUN: %clang_cc1 -pedantic -std=c++1z -emit-pch %s -o %t<br>
+// RUN: %clang_cc1 -pedantic -std=c++1z -include-pch %t -verify %s<br>
+<br>
+#ifndef HEADER<br>
+#define HEADER<br>
+<br>
+template<typename ...T> struct A : T... {<br>
+  using T::f ...;<br>
+  template<typename ...U> void g(U ...u) { f(u...); }<br>
+};<br>
+<br>
+struct X { void f(); };<br>
+struct Y { void f(int); };<br>
+struct Z { void f(int, int); };<br>
+<br>
+inline A<X, Y, Z> a;<br>
+<br>
+#else<br>
+<br>
+void test() {<br>
+  a.g();<br>
+  a.g(0);<br>
+  a.g(0, 0);<br>
+  // expected-error@13 {{no match}}<br>
+  // expected-note@16 {{candidate}}<br>
+  // expected-note@17 {{candidate}}<br>
+  // expected-note@18 {{candidate}}<br>
+  a.g(0, 0, 0); // expected-note {{instantiation of}}<br>
+}<br>
+<br>
+#endif<br>
<br>
Modified: cfe/trunk/test/Parser/cxx1z-<wbr>using-declaration.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z-using-declaration.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/Parser/<wbr>cxx1z-using-declaration.cpp?<wbr>rev=290080&r1=290079&r2=<wbr>290080&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/Parser/cxx1z-<wbr>using-declaration.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx1z-<wbr>using-declaration.cpp Sun Dec 18 22:08:53 2016<br>
@@ -10,10 +10,10 @@ namespace B {<br>
 }<br>
<br>
 struct X {<br>
-  int x1, x2, y, z; // expected-note {{conflicting}}<br>
+  int x1, x2, y, z; // expected-note 2{{conflicting}}<br>
 };<br>
 struct Y {<br>
-  int x1, x2, y, z; // expected-note {{target}}<br>
+  int x1, x2, y, z; // expected-note 2{{target}}<br>
 };<br>
 struct Z : X, Y {<br>
   using X::x1,<br>
@@ -28,3 +28,8 @@ int X::*px1 = &Z::x1;<br>
 int X::*px2 = &Z::x2;<br>
 int Y::*py = &Z::y;<br>
 int X::*pz = &Z::z;<br>
+<br>
+template<typename ...T> struct Q : T... {<br>
+  using T::z...; // expected-error {{conflicts}}<br>
+};<br>
+Q<X,Y> q; // expected-note {{instantiation of}}<br>
<br>
Added: cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/cxx1z-using-declaration.cpp?rev=290080&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaTemplate/cxx1z-using-<wbr>declaration.cpp?rev=290080&<wbr>view=auto</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp (added)<br>
+++ cfe/trunk/test/SemaTemplate/<wbr>cxx1z-using-declaration.cpp Sun Dec 18 22:08:53 2016<br>
@@ -0,0 +1,230 @@<br>
+// RUN: %clang_cc1 -std=c++1z -verify %s<br>
+<br>
+// Test that we cope with failure to expand a pack.<br>
+template<typename ...T> struct Unexpanded : T... {<br>
+  using T::f; // expected-error {{unexpanded}}<br>
+  using typename T::type; // expected-error {{unexpanded}}<br>
+  template<typename ...U> void g(U ...u) { f(u...); } // expected-error {{undeclared identifier 'f'}}<br>
+  void h() {<br>
+    Unexpanded<type...> *p; // expected-error {{undeclared identifier 'type'}}<br>
+  }<br>
+};<br>
+void test_Unexpanded() {<br>
+  struct A { void f(); }; // expected-note {{must qualify}}<br>
+  struct B { void f(int); }; // expected-note {{must qualify}}<br>
+  Unexpanded<A, B>().g(0); // expected-note {{instantiation of}}<br>
+}<br>
+<br>
+// Test using non-type members from pack of base classes.<br>
+template<typename ...T> struct A : T... { // expected-note 2{{candidate}}<br>
+  using T::T ...; // expected-note 6{{inherited here}}<br>
+  using T::operator() ...;<br>
+  using T::operator T* ...;<br>
+  using T::h ...;<br>
+<br>
+  void f(int n) { h(n); } // expected-error {{ambiguous}}<br>
+  void f(int n, int m) { h(n, m); } // expected-error {{member using declaration 'h' instantiates to an empty pack}}<br>
+  void g(int n) { (*this)(n); } // expected-error {{ambiguous}}<br>
+  void g(int n, int m) { (*this)(n, m); } // expected-error {{does not provide a call operator}}<br>
+};<br>
+<br>
+namespace test_A {<br>
+  struct X { // expected-note 2{{candidate}}<br>
+    X();<br>
+    X(int); // expected-note {{candidate}}<br>
+    void operator()(int); // expected-note 2{{candidate}}<br>
+    operator X *();<br>
+    void h(int); // expected-note {{candidate}}<br>
+  };<br>
+  struct Y {<br>
+    Y();<br>
+    Y(int, int);<br>
+    void operator()(int, int);<br>
+    operator Y *();<br>
+    void h(int, int); // expected-note {{not viable}}<br>
+  };<br>
+  struct Z { // expected-note 2{{candidate}}<br>
+    Z();<br>
+    Z(int); // expected-note {{candidate}}<br>
+    void operator()(int); // expected-note 2{{candidate}}<br>
+    operator Z *();<br>
+    void h(int); // expected-note {{candidate}}<br>
+  };<br>
+<br>
+  void f() {<br>
+    A<> a;<br>
+    a.f(0, 0); // expected-note {{instantiation of}}<br>
+    a.g(0, 0); // expected-note {{instantiation of}}<br>
+<br>
+    A<X, Y> axy(0);<br>
+    A<X, Y>(0, 0);<br>
+    axy.f(0);<br>
+    axy.f(0, 0);<br>
+    axy.g(0);<br>
+    axy.g(0, 0);<br>
+    axy(0);<br>
+    axy(0, 0);<br>
+<br>
+    A<X, Y, Z>(0); // expected-error {{ambiguous}}<br>
+    A<X, Y, Z> axyz(0, 0);<br>
+    axyz.f(0); // expected-note {{instantiation of}}<br>
+    axyz.f(0, 0);<br>
+    axyz.g(0); // expected-note {{instantiation of}}<br>
+    axyz.g(0, 0);<br>
+    axyz(0); // expected-error {{ambiguous}}<br>
+    axyz(0, 0);<br>
+<br>
+    X *x;<br>
+    x = a; // expected-error {{incompatible}}<br>
+    x = axy;<br>
+    x = axyz;<br>
+    x = a.operator X*(); // expected-error {{no member}}<br>
+    x = axy.operator X*();<br>
+    x = axyz.operator X*();<br>
+<br>
+    Z *z;<br>
+    z = axyz;<br>
+    z = axyz.operator Z*();<br>
+  }<br>
+}<br>
+<br>
+// Test using pack of non-type members from single base class.<br>
+template<typename X, typename Y, typename ...T> struct B : X, Y {<br>
+  using X::operator T* ...;<br>
+};<br>
+<br>
+namespace test_B {<br>
+  struct X { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}}<br>
+  struct Y { operator int*(); operator float*(); operator char*(); }; // expected-note {{candidate}}<br>
+  B<X, Y, int, float> bif;<br>
+  int *pi = bif;<br>
+  float *pf = bif;<br>
+  char *pc = bif; // expected-error {{ambiguous}}<br>
+}<br>
+<br>
+// Test using type member from pack of base classes.<br>
+template<typename ...T> struct C : T... {<br>
+  using typename T::type ...; // expected-error {{target of using declaration conflicts}}<br>
+  void f() { type value; } // expected-error {{member using declaration 'type' instantiates to an empty pack}}<br>
+};<br>
+<br>
+namespace test_C {<br>
+  struct X { typedef int type; };<br>
+  struct Y { typedef int type; }; // expected-note {{conflicting}}<br>
+  struct Z { typedef float type; }; // expected-note {{target}}<br>
+<br>
+  void f() {<br>
+    C<> c;<br>
+    c.f(); // expected-note {{instantiation of}}<br>
+<br>
+    C<X, Y> cxy;<br>
+    cxy.f();<br>
+<br>
+    C<X, Y, Z> cxyz; // expected-note {{instantiation of}}<br>
+    cxyz.f();<br>
+  }<br>
+}<br>
+<br>
+// Test using pack of non-types at block scope.<br>
+template<typename ...T> int fn1() {<br>
+  using T::e ...; // expected-error 2{{class member}} expected-note 2{{instead}}<br>
+  // expected-error@-1 2{{produces multiple values}}<br>
+  return e; // expected-error {{using declaration 'e' instantiates to an empty pack}}<br>
+}<br>
+<br>
+namespace test_fn1 {<br>
+  struct X { static int e; };<br>
+  struct Y { typedef int e; };<br>
+  inline namespace P { enum E { e }; }<br>
+  inline namespace Q { enum F { e }; }<br>
+  void f() {<br>
+    fn1<>(); // expected-note {{instantiation of}}<br>
+    fn1<X>(); // expected-note {{instantiation of}}<br>
+    fn1<Y>(); // expected-note {{instantiation of}}<br>
+    fn1<E>();<br>
+    fn1<E, F>(); // expected-note {{instantiation of}}<br>
+    fn1<E, X>(); // expected-note {{instantiation of}}<br>
+  }<br>
+}<br>
+<br>
+// Test using pack of types at block scope.<br>
+template<typename ...T> void fn2() {<br>
+  // This cannot ever be valid: in order for T::type to be a type, T must be a<br>
+  // class, and a class member cannot be named by a block-scope using declaration.<br>
+  using typename T::type ...; // expected-error {{class member}}<br>
+  type x; // expected-error {{unknown type name 'type'}}<br>
+}<br>
+<br>
+// Test partial substitution into class-scope pack.<br>
+template<typename ...T> auto lambda1() {<br>
+  return [](auto x) {<br>
+    struct A : T::template X<decltype(x)>... { // expected-note 1+{{instantiation of}}<br>
+      using T::template X<decltype(x)>::f ...;<br>
+      using typename T::template X<decltype(x)>::type ...;<br>
+      void g(int n) { f(n); } // expected-error {{empty pack}} expected-error {{expected 2, have 1}} expected-error {{ambiguous}}<br>
+      void h() { type value; } // expected-error {{empty pack}}<br>
+    };<br>
+    return A();<br>
+  };<br>
+}<br>
+<br>
+namespace test_lambda1 {<br>
+  struct A {<br>
+    template<typename> struct X {<br>
+      void f(int); // expected-note {{candidate}}<br>
+      using type = int;<br>
+    };<br>
+  };<br>
+  struct B {<br>
+    template<typename> struct X {<br>
+      void f(int, int); // expected-note {{declared here}} expected-note {{not viable}}<br>
+      using type = int;<br>
+    };<br>
+  };<br>
+  struct C {<br>
+    template<typename> struct X {<br>
+      void f(int); // expected-note {{candidate}}<br>
+      void f(int, int); // expected-note {{not viable}}<br>
+      using type = int;<br>
+    };<br>
+  };<br>
+<br>
+  void f() {<br>
+    lambda1<>() // expected-note 2{{instantiation of}}<br>
+      (0)<br>
+      // FIXME: This is poor error recovery<br>
+      .g(0); // expected-error {{no member named 'g'}}<br>
+    lambda1<A>()<br>
+      (0)<br>
+      .g(0);<br>
+    lambda1<B>()<br>
+      (0) // expected-note {{instantiation of}}<br>
+      .g(0);<br>
+    lambda1<A, B, C>()<br>
+      (0) // expected-note {{instantiation of}}<br>
+      .g(0);<br>
+  }<br>
+}<br>
+<br>
+namespace p0195r2_example {<br>
+  template<typename ...Ts><br>
+  struct Overloader : Ts... {<br>
+    using Ts::operator() ...;<br>
+  };<br>
+<br>
+  template<typename ...Ts><br>
+  constexpr auto make_overloader(Ts &&...ts) {<br>
+    return Overloader<Ts...>{static_cast<<wbr>Ts&&>(ts)...};<br>
+  }<br>
+<br>
+  void test() {<br>
+    auto o = make_overloader(<br>
+      [&](int &r) -> int & { return r; }, // expected-note {{candidate function}}<br>
+      [&](float &r) -> float & { return r; } // expected-note {{candidate function}}<br>
+    );<br>
+    int a; float f; double d;<br>
+    int &ra = o(a);<br>
+    float &rf = o(f);<br>
+    double &rd = o(d); // expected-error {{no matching function}}<br>
+  }<br>
+}<br>
<br>
Modified: cfe/trunk/tools/libclang/<wbr>CIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=290080&r1=290079&r2=290080&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/tools/<wbr>libclang/CIndex.cpp?rev=<wbr>290080&r1=290079&r2=290080&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/tools/libclang/<wbr>CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/<wbr>CIndex.cpp Sun Dec 18 22:08:53 2016<br>
@@ -5733,6 +5733,7 @@ CXCursor clang_getCursorDefinition(<wbr>CXCur<br>
   case Decl::BuiltinTemplate:<br>
   case Decl::PragmaComment:<br>
   case Decl::PragmaDetectMismatch:<br>
+  case Decl::UsingPack:<br>
     return C;<br>
<br>
   // Declaration kinds that don't make any sense here, but are<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>