Revert rC330794 and some dependent tiny bug fixes
See Richard's humbling feedback here:
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20180423/226482.html
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20180423/226486.html
Wish I'd had the patience to solicit the feedback prior to committing :)
Sorry for the noise guys.
Thank you Richard for being the steward that clang deserves!
llvm-svn: 330888
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 9b0828a..3d3abe3 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -1739,8 +1739,7 @@
ParsingDeclSpec DS(*this);
DeclSpecContext DSContext = getDeclSpecContextFromDeclaratorContext(Context);
- ParseDeclarationSpecifiersOrConceptDefinition(DS, ParsedTemplateInfo(),
- AS_none, DSContext);
+ ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none, DSContext);
// If we had a free-standing type definition with a missing semicolon, we
// may get this far before the problem becomes obvious.
@@ -2387,8 +2386,7 @@
/// specifier-qualifier-list is a subset of declaration-specifiers. Just
/// parse declaration-specifiers and complain about extra stuff.
/// TODO: diagnose attribute-specifiers and alignment-specifiers.
- ParseDeclarationSpecifiersOrConceptDefinition(DS, ParsedTemplateInfo(), AS,
- DSC);
+ ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
// Validate declspec for type-name.
unsigned Specs = DS.getParsedSpecifiers();
@@ -2873,12 +2871,11 @@
// and call ParsedFreeStandingDeclSpec as appropriate.
DS.ClearTypeSpecType();
ParsedTemplateInfo NotATemplate;
- ParseDeclarationSpecifiersOrConceptDefinition(DS, NotATemplate, AS, DSContext,
- LateAttrs);
+ ParseDeclarationSpecifiers(DS, NotATemplate, AS, DSContext, LateAttrs);
return false;
}
-/// ParseDeclarationSpecifiersOrConceptDefinition
+/// ParseDeclarationSpecifiers
/// declaration-specifiers: [C99 6.7]
/// storage-class-specifier declaration-specifiers[opt]
/// type-specifier declaration-specifiers[opt]
@@ -2905,8 +2902,7 @@
/// [OpenCL] '__kernel'
/// 'friend': [C++ dcl.friend]
/// 'constexpr': [C++0x dcl.constexpr]
-/// [C++2a] 'concept'
-void Parser::ParseDeclarationSpecifiersOrConceptDefinition(DeclSpec &DS,
+void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS,
DeclSpecContext DSContext,
@@ -3684,11 +3680,7 @@
ConsumeToken();
ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
continue;
-
- case tok::kw_concept:
- ConsumeToken();
- ParseConceptDefinition(Loc, DS, TemplateInfo, AS, DSContext);
- continue;
+
// cv-qualifier:
case tok::kw_const:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
@@ -6374,7 +6366,7 @@
// too much hassle.
DS.takeAttributesFrom(FirstArgAttrs);
- ParseDeclarationSpecifiersOrConceptDefinition(DS);
+ ParseDeclarationSpecifiers(DS);
// Parse the declarator. This is "PrototypeContext" or
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index e0db75c..0c789c9 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2561,8 +2561,8 @@
if (MalformedTypeSpec)
DS.SetTypeSpecError();
- ParseDeclarationSpecifiersOrConceptDefinition(
- DS, TemplateInfo, AS, DeclSpecContext::DSC_class, &CommonLateParsedAttrs);
+ ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class,
+ &CommonLateParsedAttrs);
// Turn off colon protection that was set for declspec.
X.restore();
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 203d5e6..0ac418a 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -1490,7 +1490,7 @@
cStyleParamWarned = true;
}
DeclSpec DS(AttrFactory);
- ParseDeclarationSpecifiersOrConceptDefinition(DS);
+ ParseDeclarationSpecifiers(DS);
// Parse the declarator.
Declarator ParmDecl(DS, DeclaratorContext::PrototypeContext);
ParseDeclarator(ParmDecl);
@@ -2541,7 +2541,7 @@
Scope::AtCatchScope);
if (Tok.isNot(tok::ellipsis)) {
DeclSpec DS(AttrFactory);
- ParseDeclarationSpecifiersOrConceptDefinition(DS);
+ ParseDeclarationSpecifiers(DS);
Declarator ParmDecl(DS, DeclaratorContext::ObjCCatchContext);
ParseDeclarator(ParmDecl);
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 13fb6da..88a5745 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -54,15 +54,6 @@
/// template-declaration: [C++ temp]
/// 'export'[opt] 'template' '<' template-parameter-list '>' declaration
///
-/// template-declaration: [C++2a]
-/// template-head declaration
-/// template-head concept-definition
-///
-/// TODO: requires-clause
-/// template-head: [C++2a]
-/// 'export'[opt] 'template' '<' template-parameter-list '>'
-/// requires-clause[opt]
-///
/// explicit-specialization: [ C++ temp.expl.spec]
/// 'template' '<' '>' declaration
Decl *
@@ -157,10 +148,13 @@
unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope;
ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);
- return ParseSingleDeclarationAfterTemplate(
- Context,
- ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty),
- ParsingTemplateParams, DeclEnd, AS, AccessAttrs);
+ // Parse the actual template declaration.
+ return ParseSingleDeclarationAfterTemplate(Context,
+ ParsedTemplateInfo(&ParamLists,
+ isSpecialization,
+ LastParamListWasEmpty),
+ ParsingTemplateParams,
+ DeclEnd, AS, AccessAttrs);
}
/// \brief Parse a single declaration that declares a template,
@@ -214,7 +208,7 @@
// the template parameters.
ParsingDeclSpec DS(*this, &DiagsFromTParams);
- ParseDeclarationSpecifiersOrConceptDefinition(DS, TemplateInfo, AS,
+ ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
getDeclSpecContextFromDeclaratorContext(Context));
if (Tok.is(tok::semi)) {
@@ -328,150 +322,6 @@
return ThisDecl;
}
-
-void
-Parser::ParseConceptDefinition(SourceLocation ConceptLoc,
- DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS,
- DeclSpecContext DSC) {
-
-
- auto DiagnoseAttributes = [this] {
- ParsedAttributesWithRange attrs(this->AttrFactory);
- this->MaybeParseGNUAttributes(attrs);
- this->MaybeParseCXX11Attributes(attrs);
- this->MaybeParseMicrosoftDeclSpecs(attrs);
- this->ProhibitAttributes(attrs);
- };
-
-
- // If attributes exist after 'concept' kw but before the concept name,
- // prohibit them for now (if CWG approves attributes on concepts, this is
- // likely where they will go...).
- DiagnoseAttributes();
-
- // Set the concept specifier at ConceptLoc within 'DS' along with emitting any
- // incompatible decl-specifier diagnostics.
- {
- const char *PrevSpec = 0;
- unsigned int DiagId = 0;
- if (DS.setConceptSpec(ConceptLoc, PrevSpec, DiagId,
- Actions.getASTContext().getPrintingPolicy())) {
- Diag(ConceptLoc, DiagId) << PrevSpec;
- }
- Actions.DiagnoseFunctionSpecifiers(DS);
- }
-
- if (DSC != DeclSpecContext::DSC_top_level) {
- Diag(ConceptLoc, diag::err_concept_at_non_namespace_scope);
- // If we are not in a template parameter context, skip to a '}' or ';'. The
- // error messages are better if we just ignore this within template
- // parameter lists.
- if (DSC != DeclSpecContext::DSC_template_param) {
- SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
- } else {
- tok::TokenKind Tokens[] = { tok::comma, tok::greater };
- SkipUntil(llvm::makeArrayRef(Tokens),
- StopAtSemi | StopBeforeMatch);
- }
- return;
- }
-
- // A scope-guard that (if an error occurs while parsing a concept) skips to
- // the next semi or closing brace.
- class SkipUntilSemiOrClosingBraceOnScopeExit {
- Parser &P;
- bool Disabled = false;
-
- public:
- SkipUntilSemiOrClosingBraceOnScopeExit(Parser &P)
- : P(P) {}
- void disable() { Disabled = true; }
- ~SkipUntilSemiOrClosingBraceOnScopeExit() {
- if (!Disabled) {
- // Skip until the semi-colon or a '}'.
- P.SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
- }
- }
- } SkipUntilSemiOrClosingBraceOnScopeExit(*this);
-
- if (TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate) {
- Diag(ConceptLoc, diag::err_concept_nontemplate);
- return;
- }
-
- const TemplateParameterLists &ParamLists = *TemplateInfo.TemplateParams;
-
-
- // More than one TPL wouldn't make sense here.
- if (ParamLists.size() != 1) {
- Diag(Tok.getLocation(), diag::err_concept_extra_headers);
- return;
- }
- const TemplateParameterList *const TPL = ParamLists[0];
-
- // Explicit specializations of concepts are not allowed.
- if (TPL->getLAngleLoc().getLocWithOffset(1) == TPL->getRAngleLoc()) {
- assert(!TPL->size() &&
- "can not have template parameters within empty angle brackets!");
- Diag(ConceptLoc, diag::err_concept_specialized) << 0;
- return;
- }
- // Concepts can not be defined with nested name specifiers.
- CXXScopeSpec SS;
- if (ParseOptionalCXXScopeSpecifier(SS, nullptr,
- /*EnteringContext=*/false) ||
- SS.isNotEmpty()) {
-
- if (SS.isNotEmpty())
- Diag(Tok.getLocation(), diag::err_concept_unexpected_scope_spec);
- return;
- }
- // An identifier (i.e. the concept-name) should follow 'concept'.
- if (!Tok.is(tok::identifier)) {
- Diag(Tok.getLocation(), diag::err_expected) << "concept name";
- return;
- }
-
- IdentifierInfo *Id = Tok.getIdentifierInfo();
- SourceLocation IdLoc = ConsumeToken();
-
- // If attributes exist after the identifier, parse them and diagnose
- DiagnoseAttributes();
-
- if (!TryConsumeToken(tok::equal)) {
- Diag(Tok.getLocation(), diag::err_expected) << "equal";
- return;
- }
-
- ExprResult ConstraintExprResult = ParseConstraintExpression();
- if (ConstraintExprResult.isInvalid()) {
- Diag(Tok.getLocation(), diag::err_expected_expression)
- << "constraint-expression";
- return;
- }
-
- // We can try to create a valid concept decl node now, so disable the
- // scope-guard.
- SkipUntilSemiOrClosingBraceOnScopeExit.disable();
-
- Expr *ConstraintExpr = ConstraintExprResult.get();
- ConceptDecl *const ConDecl = Actions.ActOnConceptDefinition(
- getCurScope(), *TemplateInfo.TemplateParams, Id, IdLoc, ConstraintExpr);
- DS.setConceptRep(ConDecl);
-
- if (Tok.isNot(tok::semi)) {
-
- ExpectAndConsume(tok::semi, diag::err_expected_after, "concept");
- // Push this token back into the preprocessor and change our current token
- // to ';' so that the rest of the code recovers as though there were an
- // ';' after the definition.
- PP.EnterToken(Tok);
- Tok.setKind(tok::semi);
- }
- return;
-}
-
/// ParseTemplateParameters - Parses a template-parameter-list enclosed in
/// angle brackets. Depth is the depth of this template-parameter-list, which
/// is the number of template headers directly enclosing this template header.
@@ -840,8 +690,8 @@
// FIXME: The type should probably be restricted in some way... Not all
// declarators (parts of declarators?) are accepted for parameters.
DeclSpec DS(AttrFactory);
- ParseDeclarationSpecifiersOrConceptDefinition(
- DS, ParsedTemplateInfo(), AS_none, DeclSpecContext::DSC_template_param);
+ ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
+ DeclSpecContext::DSC_template_param);
// Parse this as a typename.
Declarator ParamDecl(DS, DeclaratorContext::TemplateParamContext);
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 5648d994..ebd6f0f 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1351,7 +1351,6 @@
case tok::kw_struct:
case tok::kw_union:
case tok::kw___interface:
- case tok::kw_concept:
// enum-specifier
case tok::kw_enum:
// cv-qualifier
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 17d0469..d8f9f7a 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -919,7 +919,7 @@
AccessSpecifier AS) {
MaybeParseMicrosoftAttributes(DS.getAttributes());
// Parse the common declaration-specifiers piece.
- ParseDeclarationSpecifiersOrConceptDefinition(DS, ParsedTemplateInfo(), AS,
+ ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS,
DeclSpecContext::DSC_top_level);
// If we had a free-standing type definition with a missing semicolon, we
@@ -1287,7 +1287,7 @@
// Parse the common declaration-specifiers piece.
DeclSpec DS(AttrFactory);
- ParseDeclarationSpecifiersOrConceptDefinition(DS);
+ ParseDeclarationSpecifiers(DS);
// C99 6.9.1p6: 'each declaration in the declaration list shall have at
// least one declarator'.
@@ -1647,7 +1647,7 @@
/// Actions.getTypeName will not be needed to be called again (e.g. getTypeName
/// will not be called twice, once to check whether we have a declaration
/// specifier, and another one to get the actual type inside
-/// ParseDeclarationSpecifiersOrConceptDefinition).
+/// ParseDeclarationSpecifiers).
///
/// This returns true if an error occurred.
///