diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-20 21:35:28 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-20 21:35:28 +0000 |
commit | 151c4568581f1d6aea266aceb99f7cc683bfc10c (patch) | |
tree | 6a06c7b529f20ce83059a547db77184e03e303f1 /clang/lib/Parse/ParseDeclCXX.cpp | |
parent | d5508b4e89f8e3dcbf83d9eadbb77b2420ea5202 (diff) | |
download | bcm5719-llvm-151c4568581f1d6aea266aceb99f7cc683bfc10c.tar.gz bcm5719-llvm-151c4568581f1d6aea266aceb99f7cc683bfc10c.zip |
[c++1z] P0195R2: Support pack-expansion of using-declarations.
This change introduces UsingPackDecl as a marker for the set of UsingDecls
produced by pack expansion of a single (unresolved) using declaration. This is
not strictly necessary (we just need to be able to map from the original using
declaration to its expansions somehow), but it's useful to maintain the
invariant that each declaration reference instantiates to refer to one
declaration.
This is a re-commit of r290080 (reverted in r290092) with a fix for a
use-after-lifetime bug.
llvm-svn: 290203
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 79 |
1 files changed, 16 insertions, 63 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index d31d1142374..4002b09d2bc 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -560,7 +560,9 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) { // nested-name-specifier, the name is [...] considered to name the // constructor. if (getLangOpts().CPlusPlus11 && Context == Declarator::MemberContext && - Tok.is(tok::identifier) && NextToken().is(tok::semi) && + Tok.is(tok::identifier) && + (NextToken().is(tok::semi) || NextToken().is(tok::comma) || + NextToken().is(tok::ellipsis)) && D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() && !D.SS.getScopeRep()->getAsNamespace() && !D.SS.getScopeRep()->getAsNamespaceAlias()) { @@ -578,7 +580,10 @@ bool Parser::ParseUsingDeclarator(unsigned Context, UsingDeclarator &D) { return true; } - // FIXME: Parse optional ellipsis + if (TryConsumeToken(tok::ellipsis, D.EllipsisLoc)) + Diag(Tok.getLocation(), getLangOpts().CPlusPlus1z ? + diag::warn_cxx1z_compat_using_declaration_pack : + diag::ext_using_declaration_pack); return false; } @@ -678,9 +683,9 @@ Parser::ParseUsingDeclaration(unsigned Context, D.TypenameLoc = SourceLocation(); } - Decl *UD = - Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc, D.SS, - D.Name, Attrs.getList(), D.TypenameLoc); + Decl *UD = Actions.ActOnUsingDeclaration(getCurScope(), AS, UsingLoc, + D.TypenameLoc, D.SS, D.Name, + D.EllipsisLoc, Attrs.getList()); if (UD) DeclsInGroup.push_back(UD); } @@ -708,62 +713,6 @@ Parser::ParseUsingDeclaration(unsigned Context, return Actions.BuildDeclaratorGroup(DeclsInGroup, /*MayContainAuto*/false); } -Decl *Parser::ParseAliasTemplate(const ParsedTemplateInfo &TemplateInfo, - SourceLocation &DeclEnd, AccessSpecifier AS, - ParsedAttributesWithRange &MisplacedAttrs1) { - assert(Tok.is(tok::kw_using) && "Not using token"); - ObjCDeclContextSwitch ObjCDC(*this); - - // Eat 'using'. - SourceLocation UsingLoc = ConsumeToken(); - if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteUsing(getCurScope()); - cutOffParsing(); - return nullptr; - } - - // 'using namespace' means this is a using-directive. - if (Tok.is(tok::kw_namespace)) { - SourceRange R = TemplateInfo.getSourceRange(); - Diag(UsingLoc, diag::err_templated_using_directive_declaration) - << 0 /* directive */ << R; - SkipUntil(tok::semi); - return nullptr; - } - - // Check for misplaced attributes before the identifier. - ParsedAttributesWithRange MisplacedAttrs2(AttrFactory); - MaybeParseCXX11Attributes(MisplacedAttrs2); - - // FIXME: Just parse an identifier here? - UsingDeclarator D; - if (ParseUsingDeclarator(Declarator::FileContext, D)) { - SkipUntil(tok::semi); - return nullptr; - } - - ParsedAttributesWithRange Attrs(AttrFactory); - - // If we had any misplaced attributes from earlier, this is where they - // should have been written. - for (auto *MisplacedAttrs : {&MisplacedAttrs1, &MisplacedAttrs2}) { - if (MisplacedAttrs->Range.isValid()) { - Diag(MisplacedAttrs->Range.getBegin(), diag::err_attributes_not_allowed) - << FixItHint::CreateInsertionFromRange( - Tok.getLocation(), - CharSourceRange::getTokenRange(MisplacedAttrs->Range)) - << FixItHint::CreateRemoval(MisplacedAttrs->Range); - Attrs.takeAllFrom(*MisplacedAttrs); - } - } - - MaybeParseGNUAttributes(Attrs); - MaybeParseCXX11Attributes(Attrs); - - return ParseAliasDeclarationAfterDeclarator(TemplateInfo, UsingLoc, D, - DeclEnd, AS, Attrs); -} - Decl *Parser::ParseAliasDeclarationAfterDeclarator( const ParsedTemplateInfo &TemplateInfo, SourceLocation UsingLoc, UsingDeclarator &D, SourceLocation &DeclEnd, AccessSpecifier AS, @@ -813,6 +762,9 @@ Decl *Parser::ParseAliasDeclarationAfterDeclarator( else if (D.SS.isNotEmpty()) Diag(D.SS.getBeginLoc(), diag::err_alias_declaration_not_identifier) << FixItHint::CreateRemoval(D.SS.getRange()); + if (D.EllipsisLoc.isValid()) + Diag(D.EllipsisLoc, diag::err_alias_declaration_pack_expansion) + << FixItHint::CreateRemoval(SourceRange(D.EllipsisLoc)); Decl *DeclFromDeclSpec = nullptr; TypeResult TypeAlias = @@ -2487,8 +2439,9 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } return DeclGroupPtrTy::make(DeclGroupRef(Actions.ActOnUsingDeclaration( - getCurScope(), AS, /*UsingLoc*/SourceLocation(), SS, Name, - /*AttrList*/nullptr, /*TypenameLoc*/SourceLocation()))); + getCurScope(), AS, /*UsingLoc*/ SourceLocation(), + /*TypenameLoc*/ SourceLocation(), SS, Name, + /*EllipsisLoc*/ SourceLocation(), /*AttrList*/ nullptr))); } } |