summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-20 21:35:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-20 21:35:28 +0000
commit151c4568581f1d6aea266aceb99f7cc683bfc10c (patch)
tree6a06c7b529f20ce83059a547db77184e03e303f1 /clang/lib/Parse/ParseDeclCXX.cpp
parentd5508b4e89f8e3dcbf83d9eadbb77b2420ea5202 (diff)
downloadbcm5719-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.cpp79
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)));
}
}
OpenPOWER on IntegriCloud