diff options
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 119 | ||||
-rw-r--r-- | clang/include/clang/AST/RecursiveASTVisitor.h | 2 | ||||
-rw-r--r-- | clang/include/clang/Basic/DeclNodes.td | 1 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticParseKinds.td | 7 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 | ||||
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 6 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 16 | ||||
-rw-r--r-- | clang/include/clang/Sema/Template.h | 5 | ||||
-rw-r--r-- | clang/include/clang/Serialization/ASTBitCodes.h | 2 |
9 files changed, 146 insertions, 17 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 46434c4c7bb..06ecd3c3734 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -3140,6 +3140,77 @@ public: friend class ASTDeclWriter; }; +/// Represents a pack of using declarations that a single +/// using-declarator pack-expanded into. +/// +/// \code +/// template<typename ...T> struct X : T... { +/// using T::operator()...; +/// using T::operator T...; +/// }; +/// \endcode +/// +/// In the second case above, the UsingPackDecl will have the name +/// 'operator T' (which contains an unexpanded pack), but the individual +/// UsingDecls and UsingShadowDecls will have more reasonable names. +class UsingPackDecl final + : public NamedDecl, public Mergeable<UsingPackDecl>, + private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> { + void anchor() override; + + /// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from + /// which this waas instantiated. + NamedDecl *InstantiatedFrom; + + /// The number of using-declarations created by this pack expansion. + unsigned NumExpansions; + + UsingPackDecl(DeclContext *DC, NamedDecl *InstantiatedFrom, + ArrayRef<NamedDecl *> UsingDecls) + : NamedDecl(UsingPack, DC, + InstantiatedFrom ? InstantiatedFrom->getLocation() + : SourceLocation(), + InstantiatedFrom ? InstantiatedFrom->getDeclName() + : DeclarationName()), + InstantiatedFrom(InstantiatedFrom), NumExpansions(UsingDecls.size()) { + std::uninitialized_copy(UsingDecls.begin(), UsingDecls.end(), + getTrailingObjects<NamedDecl *>()); + } + +public: + /// Get the using declaration from which this was instantiated. This will + /// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl + /// that is a pack expansion. + NamedDecl *getInstantiatedFromUsingDecl() { return InstantiatedFrom; } + + /// Get the set of using declarations that this pack expanded into. Note that + /// some of these may still be unresolved. + ArrayRef<NamedDecl *> expansions() const { + return llvm::makeArrayRef(getTrailingObjects<NamedDecl *>(), NumExpansions); + } + + static UsingPackDecl *Create(ASTContext &C, DeclContext *DC, + NamedDecl *InstantiatedFrom, + ArrayRef<NamedDecl *> UsingDecls); + + static UsingPackDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NumExpansions); + + SourceRange getSourceRange() const override LLVM_READONLY { + return InstantiatedFrom->getSourceRange(); + } + + UsingPackDecl *getCanonicalDecl() override { return getFirstDecl(); } + const UsingPackDecl *getCanonicalDecl() const { return getFirstDecl(); } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == UsingPack; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend TrailingObjects; +}; + /// \brief Represents a dependent using declaration which was not marked with /// \c typename. /// @@ -3158,6 +3229,9 @@ class UnresolvedUsingValueDecl : public ValueDecl, /// \brief The source location of the 'using' keyword SourceLocation UsingLocation; + /// \brief If this is a pack expansion, the location of the '...'. + SourceLocation EllipsisLoc; + /// \brief The nested-name-specifier that precedes the name. NestedNameSpecifierLoc QualifierLoc; @@ -3168,11 +3242,12 @@ class UnresolvedUsingValueDecl : public ValueDecl, UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty, SourceLocation UsingLoc, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo) + const DeclarationNameInfo &NameInfo, + SourceLocation EllipsisLoc) : ValueDecl(UnresolvedUsingValue, DC, NameInfo.getLoc(), NameInfo.getName(), Ty), - UsingLocation(UsingLoc), QualifierLoc(QualifierLoc), - DNLoc(NameInfo.getInfo()) + UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc), + QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo()) { } public: @@ -3198,10 +3273,20 @@ public: return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } + /// \brief Determine whether this is a pack expansion. + bool isPackExpansion() const { + return EllipsisLoc.isValid(); + } + + /// \brief Get the location of the ellipsis if this is a pack expansion. + SourceLocation getEllipsisLoc() const { + return EllipsisLoc; + } + static UnresolvedUsingValueDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo); + const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); static UnresolvedUsingValueDecl * CreateDeserialized(ASTContext &C, unsigned ID); @@ -3242,6 +3327,9 @@ class UnresolvedUsingTypenameDecl /// \brief The source location of the 'typename' keyword SourceLocation TypenameLocation; + /// \brief If this is a pack expansion, the location of the '...'. + SourceLocation EllipsisLoc; + /// \brief The nested-name-specifier that precedes the name. NestedNameSpecifierLoc QualifierLoc; @@ -3249,10 +3337,12 @@ class UnresolvedUsingTypenameDecl SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TargetNameLoc, - IdentifierInfo *TargetName) + IdentifierInfo *TargetName, + SourceLocation EllipsisLoc) : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName, UsingLoc), - TypenameLocation(TypenameLoc), QualifierLoc(QualifierLoc) { } + TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc), + QualifierLoc(QualifierLoc) { } friend class ASTDeclReader; @@ -3272,10 +3362,25 @@ public: return QualifierLoc.getNestedNameSpecifier(); } + DeclarationNameInfo getNameInfo() const { + return DeclarationNameInfo(getDeclName(), getLocation()); + } + + /// \brief Determine whether this is a pack expansion. + bool isPackExpansion() const { + return EllipsisLoc.isValid(); + } + + /// \brief Get the location of the ellipsis if this is a pack expansion. + SourceLocation getEllipsisLoc() const { + return EllipsisLoc; + } + static UnresolvedUsingTypenameDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TargetNameLoc, DeclarationName TargetName); + SourceLocation TargetNameLoc, DeclarationName TargetName, + SourceLocation EllipsisLoc); static UnresolvedUsingTypenameDecl * CreateDeserialized(ASTContext &C, unsigned ID); diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 058ab1fcbe9..afacfd57231 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1505,6 +1505,8 @@ DEF_TRAVERSE_DECL(UsingDecl, { TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); }) +DEF_TRAVERSE_DECL(UsingPackDecl, {}) + DEF_TRAVERSE_DECL(UsingDirectiveDecl, { TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); }) diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td index 6da2c2c3d6c..7b581d3eec0 100644 --- a/clang/include/clang/Basic/DeclNodes.td +++ b/clang/include/clang/Basic/DeclNodes.td @@ -67,6 +67,7 @@ def Named : Decl<1>; def TemplateTemplateParm : DDecl<Template>; def BuiltinTemplate : DDecl<Template>; def Using : DDecl<Named>; + def UsingPack : DDecl<Named>; def UsingShadow : DDecl<Named>; def ConstructorUsingShadow : DDecl<UsingShadow>; def ObjCMethod : DDecl<Named>, DeclContext; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 31e55b4affe..0943feae950 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -740,6 +740,8 @@ def err_alias_declaration_not_identifier : Error< "name defined in alias declaration must be an identifier">; def err_alias_declaration_specialization : Error< "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">; +def err_alias_declaration_pack_expansion : Error< + "alias declaration cannot be a pack expansion">; // C++1z using-declaration pack expansions def ext_multi_using_declaration : ExtWarn< @@ -749,6 +751,11 @@ def warn_cxx1z_compat_multi_using_declaration : Warning< "use of multiple declarators in a single using declaration is " "incompatible with C++ standards before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore; +def ext_using_declaration_pack : ExtWarn< + "pack expansion of using declaration is a C++1z extension">, InGroup<CXX1z>; +def warn_cxx1z_compat_using_declaration_pack : Warning< + "pack expansion using declaration is incompatible with C++ standards " + "before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore; // C++11 override control def ext_override_control_keyword : ExtWarn< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 69322f0f75b..f32364e9afe 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -474,6 +474,8 @@ def err_using_decl_conflict : Error< def err_using_decl_conflict_reverse : Error< "declaration conflicts with target of using declaration already in scope">; def note_using_decl : Note<"%select{|previous }0using declaration">; +def err_using_decl_redeclaration_expansion : Error< + "using declaration pack expansion at block scope produces multiple values">; def warn_access_decl_deprecated : Warning< "access declarations are deprecated; use using declarations instead">, @@ -4155,6 +4157,9 @@ def err_variable_instantiates_to_function : Error< def err_nested_name_spec_non_tag : Error< "type %0 cannot be used prior to '::' because it has no members">; +def err_using_pack_expansion_empty : Error< + "%select{|member}0 using declaration %1 instantiates to an empty pack">; + // C++ Explicit Instantiation def err_explicit_instantiation_duplicate : Error< "duplicate explicit instantiation of %0">; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 3d098fab84a..972f13daca4 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2436,9 +2436,10 @@ private: CXXScopeSpec SS; SourceLocation TemplateKWLoc; UnqualifiedId Name; + SourceLocation EllipsisLoc; void clear() { - TypenameLoc = TemplateKWLoc = SourceLocation(); + TypenameLoc = TemplateKWLoc = EllipsisLoc = SourceLocation(); SS.clear(); Name.clear(); } @@ -2450,9 +2451,6 @@ private: SourceLocation UsingLoc, SourceLocation &DeclEnd, AccessSpecifier AS = AS_none); - Decl *ParseAliasTemplate(const ParsedTemplateInfo &TemplateInfo, - SourceLocation &DeclEnd, AccessSpecifier AS, - ParsedAttributesWithRange &MisplacedAttrs1); Decl *ParseAliasDeclarationAfterDeclarator( const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc, UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 136f8483388..ebbc1e1b3e8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4324,12 +4324,15 @@ public: NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, + bool HasTypenameKeyword, + SourceLocation TypenameLoc, CXXScopeSpec &SS, DeclarationNameInfo NameInfo, + SourceLocation EllipsisLoc, AttributeList *AttrList, - bool IsInstantiation, - bool HasTypenameKeyword, - SourceLocation TypenameLoc); + bool IsInstantiation); + NamedDecl *BuildUsingPackDecl(NamedDecl *InstantiatedFrom, + ArrayRef<NamedDecl *> Expansions); bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); @@ -4343,10 +4346,11 @@ public: Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, + SourceLocation TypenameLoc, CXXScopeSpec &SS, UnqualifiedId &Name, - AttributeList *AttrList, - SourceLocation TypenameLoc); + SourceLocation EllipsisLoc, + AttributeList *AttrList); Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, MultiTemplateParamsArg TemplateParams, @@ -6351,7 +6355,7 @@ public: /// /// \param SS The nested-name-specifier that will be traversed to find /// unexpanded parameter packs. - void collectUnexpandedParameterPacks(CXXScopeSpec &SS, + void collectUnexpandedParameterPacks(NestedNameSpecifierLoc NNS, SmallVectorImpl<UnexpandedParameterPack> &Unexpanded); /// \brief Collect the set of unexpanded parameter packs within the given diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 0d128803541..401bbbf1e56 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -515,6 +515,11 @@ namespace clang { VarTemplateDecl *VarTemplate, VarTemplatePartialSpecializationDecl *PartialSpec); void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); + + private: + template<typename T> + Decl *instantiateUnresolvedUsingDecl(T *D, + bool InstantiatingPackElement = false); }; } diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 611c00d0e9e..4e29ad6a02a 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -1103,6 +1103,8 @@ namespace clang { DECL_NAMESPACE_ALIAS, /// \brief A UsingDecl record. DECL_USING, + /// \brief A UsingPackDecl record. + DECL_USING_PACK, /// \brief A UsingShadowDecl record. DECL_USING_SHADOW, /// \brief A ConstructorUsingShadowDecl record. |