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