<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>