brintos

brintos / llvm-project-archived public Read only

0
0
Text · 62.5 KiB · 330a9c6 Raw
1645 lines · cpp
1//===--- ParseTemplate.cpp - Template Parsing -----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This file implements parsing of C++ templates.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/ASTContext.h"14#include "clang/AST/DeclTemplate.h"15#include "clang/AST/ExprCXX.h"16#include "clang/Basic/DiagnosticParse.h"17#include "clang/Parse/Parser.h"18#include "clang/Parse/RAIIObjectsForParser.h"19#include "clang/Sema/DeclSpec.h"20#include "clang/Sema/EnterExpressionEvaluationContext.h"21#include "clang/Sema/ParsedTemplate.h"22#include "clang/Sema/Scope.h"23using namespace clang;24 25unsigned Parser::ReenterTemplateScopes(MultiParseScope &S, Decl *D) {26  return Actions.ActOnReenterTemplateScope(D, [&] {27    S.Enter(Scope::TemplateParamScope);28    return Actions.getCurScope();29  });30}31 32Parser::DeclGroupPtrTy33Parser::ParseDeclarationStartingWithTemplate(DeclaratorContext Context,34                                             SourceLocation &DeclEnd,35                                             ParsedAttributes &AccessAttrs) {36  ObjCDeclContextSwitch ObjCDC(*this);37 38  if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {39    return ParseExplicitInstantiation(Context, SourceLocation(), ConsumeToken(),40                                      DeclEnd, AccessAttrs,41                                      AccessSpecifier::AS_none);42  }43  return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,44                                                  AccessSpecifier::AS_none);45}46 47Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(48    DeclaratorContext Context, SourceLocation &DeclEnd,49    ParsedAttributes &AccessAttrs, AccessSpecifier AS) {50  assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&51         "Token does not start a template declaration.");52 53  MultiParseScope TemplateParamScopes(*this);54 55  // Tell the action that names should be checked in the context of56  // the declaration to come.57  ParsingDeclRAIIObject58    ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);59 60  // Parse multiple levels of template headers within this template61  // parameter scope, e.g.,62  //63  //   template<typename T>64  //     template<typename U>65  //       class A<T>::B { ... };66  //67  // We parse multiple levels non-recursively so that we can build a68  // single data structure containing all of the template parameter69  // lists to easily differentiate between the case above and:70  //71  //   template<typename T>72  //   class A {73  //     template<typename U> class B;74  //   };75  //76  // In the first case, the action for declaring A<T>::B receives77  // both template parameter lists. In the second case, the action for78  // defining A<T>::B receives just the inner template parameter list79  // (and retrieves the outer template parameter list from its80  // context).81  bool isSpecialization = true;82  bool LastParamListWasEmpty = false;83  TemplateParameterLists ParamLists;84  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);85 86  do {87    // Consume the 'export', if any.88    SourceLocation ExportLoc;89    TryConsumeToken(tok::kw_export, ExportLoc);90 91    // Consume the 'template', which should be here.92    SourceLocation TemplateLoc;93    if (!TryConsumeToken(tok::kw_template, TemplateLoc)) {94      Diag(Tok.getLocation(), diag::err_expected_template);95      return nullptr;96    }97 98    // Parse the '<' template-parameter-list '>'99    SourceLocation LAngleLoc, RAngleLoc;100    SmallVector<NamedDecl*, 4> TemplateParams;101    if (ParseTemplateParameters(TemplateParamScopes,102                                CurTemplateDepthTracker.getDepth(),103                                TemplateParams, LAngleLoc, RAngleLoc)) {104      // Skip until the semi-colon or a '}'.105      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);106      TryConsumeToken(tok::semi);107      return nullptr;108    }109 110    ExprResult OptionalRequiresClauseConstraintER;111    if (!TemplateParams.empty()) {112      isSpecialization = false;113      ++CurTemplateDepthTracker;114 115      if (TryConsumeToken(tok::kw_requires)) {116        OptionalRequiresClauseConstraintER =117            Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(118                /*IsTrailingRequiresClause=*/false));119        if (!OptionalRequiresClauseConstraintER.isUsable()) {120          // Skip until the semi-colon or a '}'.121          SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);122          TryConsumeToken(tok::semi);123          return nullptr;124        }125      }126    } else {127      LastParamListWasEmpty = true;128    }129 130    ParamLists.push_back(Actions.ActOnTemplateParameterList(131        CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,132        TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get()));133  } while (Tok.isOneOf(tok::kw_export, tok::kw_template));134 135  ParsedTemplateInfo TemplateInfo(&ParamLists, isSpecialization,136                                  LastParamListWasEmpty);137 138  // Parse the actual template declaration.139  if (Tok.is(tok::kw_concept)) {140    Decl *ConceptDecl = ParseConceptDefinition(TemplateInfo, DeclEnd);141    // We need to explicitly pass ConceptDecl to ParsingDeclRAIIObject, so that142    // delayed diagnostics (e.g. warn_deprecated) have a Decl to work with.143    ParsingTemplateParams.complete(ConceptDecl);144    return Actions.ConvertDeclToDeclGroup(ConceptDecl);145  }146 147  return ParseDeclarationAfterTemplate(148      Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);149}150 151Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(152    DeclaratorContext Context, SourceLocation &DeclEnd, AccessSpecifier AS) {153  ParsedAttributes AccessAttrs(AttrFactory);154  return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,155                                                  AS);156}157 158Parser::DeclGroupPtrTy Parser::ParseDeclarationAfterTemplate(159    DeclaratorContext Context, ParsedTemplateInfo &TemplateInfo,160    ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd,161    ParsedAttributes &AccessAttrs, AccessSpecifier AS) {162  assert(TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&163         "Template information required");164 165  if (Tok.is(tok::kw_static_assert)) {166    // A static_assert declaration may not be templated.167    Diag(Tok.getLocation(), diag::err_templated_invalid_declaration)168      << TemplateInfo.getSourceRange();169    // Parse the static_assert declaration to improve error recovery.170    return Actions.ConvertDeclToDeclGroup(171        ParseStaticAssertDeclaration(DeclEnd));172  }173 174  // We are parsing a member template.175  if (Context == DeclaratorContext::Member)176    return ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,177                                          &DiagsFromTParams);178 179  ParsedAttributes DeclAttrs(AttrFactory);180  ParsedAttributes DeclSpecAttrs(AttrFactory);181 182  // GNU attributes are applied to the declaration specification while the183  // standard attributes are applied to the declaration.  We parse the two184  // attribute sets into different containters so we can apply them during185  // the regular parsing process.186  while (MaybeParseCXX11Attributes(DeclAttrs) ||187         MaybeParseGNUAttributes(DeclSpecAttrs))188    ;189 190  if (Tok.is(tok::kw_using))191    return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,192                                            DeclAttrs);193 194  // Parse the declaration specifiers, stealing any diagnostics from195  // the template parameters.196  ParsingDeclSpec DS(*this, &DiagsFromTParams);197  DS.SetRangeStart(DeclSpecAttrs.Range.getBegin());198  DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd());199  DS.takeAttributesAppendingingFrom(DeclSpecAttrs);200 201  ParseDeclarationSpecifiers(DS, TemplateInfo, AS,202                             getDeclSpecContextFromDeclaratorContext(Context));203 204  if (Tok.is(tok::semi)) {205    ProhibitAttributes(DeclAttrs);206    DeclEnd = ConsumeToken();207    RecordDecl *AnonRecord = nullptr;208    Decl *Decl = Actions.ParsedFreeStandingDeclSpec(209        getCurScope(), AS, DS, ParsedAttributesView::none(),210        TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams211                                    : MultiTemplateParamsArg(),212        TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation,213        AnonRecord);214    Actions.ActOnDefinedDeclarationSpecifier(Decl);215    assert(!AnonRecord &&216           "Anonymous unions/structs should not be valid with template");217    DS.complete(Decl);218    return Actions.ConvertDeclToDeclGroup(Decl);219  }220 221  if (DS.hasTagDefinition())222    Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());223 224  // Move the attributes from the prefix into the DS.225  if (TemplateInfo.Kind == ParsedTemplateKind::ExplicitInstantiation)226    ProhibitAttributes(DeclAttrs);227 228  return ParseDeclGroup(DS, Context, DeclAttrs, TemplateInfo, &DeclEnd);229}230 231Decl *232Parser::ParseConceptDefinition(const ParsedTemplateInfo &TemplateInfo,233                               SourceLocation &DeclEnd) {234  assert(TemplateInfo.Kind != ParsedTemplateKind::NonTemplate &&235         "Template information required");236  assert(Tok.is(tok::kw_concept) &&237         "ParseConceptDefinition must be called when at a 'concept' keyword");238 239  ConsumeToken(); // Consume 'concept'240 241  SourceLocation BoolKWLoc;242  if (TryConsumeToken(tok::kw_bool, BoolKWLoc))243    Diag(Tok.getLocation(), diag::err_concept_legacy_bool_keyword) <<244        FixItHint::CreateRemoval(SourceLocation(BoolKWLoc));245 246  DiagnoseAndSkipCXX11Attributes();247 248  CXXScopeSpec SS;249  if (ParseOptionalCXXScopeSpecifier(250          SS, /*ObjectType=*/nullptr,251          /*ObjectHasErrors=*/false, /*EnteringContext=*/false,252          /*MayBePseudoDestructor=*/nullptr,253          /*IsTypename=*/false, /*LastII=*/nullptr, /*OnlyNamespace=*/true) ||254      SS.isInvalid()) {255    SkipUntil(tok::semi);256    return nullptr;257  }258 259  if (SS.isNotEmpty())260    Diag(SS.getBeginLoc(),261         diag::err_concept_definition_not_identifier);262 263  UnqualifiedId Result;264  if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,265                         /*ObjectHadErrors=*/false, /*EnteringContext=*/false,266                         /*AllowDestructorName=*/false,267                         /*AllowConstructorName=*/false,268                         /*AllowDeductionGuide=*/false,269                         /*TemplateKWLoc=*/nullptr, Result)) {270    SkipUntil(tok::semi);271    return nullptr;272  }273 274  if (Result.getKind() != UnqualifiedIdKind::IK_Identifier) {275    Diag(Result.getBeginLoc(), diag::err_concept_definition_not_identifier);276    SkipUntil(tok::semi);277    return nullptr;278  }279 280  const IdentifierInfo *Id = Result.Identifier;281  SourceLocation IdLoc = Result.getBeginLoc();282 283  // [C++26][basic.scope.pdecl]/p13284  // The locus of a concept-definition is immediately after its concept-name.285  ConceptDecl *D = Actions.ActOnStartConceptDefinition(286      getCurScope(), *TemplateInfo.TemplateParams, Id, IdLoc);287 288  ParsedAttributes Attrs(AttrFactory);289  MaybeParseAttributes(PAKM_GNU | PAKM_CXX11, Attrs);290 291  if (!TryConsumeToken(tok::equal)) {292    Diag(Tok.getLocation(), diag::err_expected) << tok::equal;293    SkipUntil(tok::semi);294    if (D)295      D->setInvalidDecl();296    return nullptr;297  }298 299  ExprResult ConstraintExprResult = ParseConstraintExpression();300  if (ConstraintExprResult.isInvalid()) {301    SkipUntil(tok::semi);302    if (D)303      D->setInvalidDecl();304    return nullptr;305  }306 307  DeclEnd = Tok.getLocation();308  ExpectAndConsumeSemi(diag::err_expected_semi_declaration);309  Expr *ConstraintExpr = ConstraintExprResult.get();310 311  if (!D)312    return nullptr;313 314  return Actions.ActOnFinishConceptDefinition(getCurScope(), D, ConstraintExpr,315                                              Attrs);316}317 318bool Parser::ParseTemplateParameters(319    MultiParseScope &TemplateScopes, unsigned Depth,320    SmallVectorImpl<NamedDecl *> &TemplateParams, SourceLocation &LAngleLoc,321    SourceLocation &RAngleLoc) {322  // Get the template parameter list.323  if (!TryConsumeToken(tok::less, LAngleLoc)) {324    Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";325    return true;326  }327 328  // Try to parse the template parameter list.329  bool Failed = false;330  // FIXME: Missing greatergreatergreater support.331  if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater)) {332    TemplateScopes.Enter(Scope::TemplateParamScope);333    Failed = ParseTemplateParameterList(Depth, TemplateParams);334  }335 336  if (Tok.is(tok::greatergreater)) {337    // No diagnostic required here: a template-parameter-list can only be338    // followed by a declaration or, for a template template parameter, the339    // 'class' keyword. Therefore, the second '>' will be diagnosed later.340    // This matters for elegant diagnosis of:341    //   template<template<typename>> struct S;342    Tok.setKind(tok::greater);343    RAngleLoc = Tok.getLocation();344    Tok.setLocation(Tok.getLocation().getLocWithOffset(1));345  } else if (!TryConsumeToken(tok::greater, RAngleLoc) && Failed) {346    Diag(Tok.getLocation(), diag::err_expected) << tok::greater;347    return true;348  }349  return false;350}351 352bool353Parser::ParseTemplateParameterList(const unsigned Depth,354                             SmallVectorImpl<NamedDecl*> &TemplateParams) {355  while (true) {356 357    if (NamedDecl *TmpParam358          = ParseTemplateParameter(Depth, TemplateParams.size())) {359      TemplateParams.push_back(TmpParam);360    } else {361      // If we failed to parse a template parameter, skip until we find362      // a comma or closing brace.363      SkipUntil(tok::comma, tok::greater, tok::greatergreater,364                StopAtSemi | StopBeforeMatch);365    }366 367    // Did we find a comma or the end of the template parameter list?368    if (Tok.is(tok::comma)) {369      ConsumeToken();370    } else if (Tok.isOneOf(tok::greater, tok::greatergreater)) {371      // Don't consume this... that's done by template parser.372      break;373    } else {374      // Somebody probably forgot to close the template. Skip ahead and375      // try to get out of the expression. This error is currently376      // subsumed by whatever goes on in ParseTemplateParameter.377      Diag(Tok.getLocation(), diag::err_expected_comma_greater);378      SkipUntil(tok::comma, tok::greater, tok::greatergreater,379                StopAtSemi | StopBeforeMatch);380      return false;381    }382  }383  return true;384}385 386Parser::TPResult Parser::isStartOfTemplateTypeParameter() {387  if (Tok.is(tok::kw_class)) {388    // "class" may be the start of an elaborated-type-specifier or a389    // type-parameter. Per C++ [temp.param]p3, we prefer the type-parameter.390    switch (NextToken().getKind()) {391    case tok::equal:392    case tok::comma:393    case tok::greater:394    case tok::greatergreater:395    case tok::ellipsis:396      return TPResult::True;397 398    case tok::identifier:399      // This may be either a type-parameter or an elaborated-type-specifier.400      // We have to look further.401      break;402 403    default:404      return TPResult::False;405    }406 407    switch (GetLookAheadToken(2).getKind()) {408    case tok::equal:409    case tok::comma:410    case tok::greater:411    case tok::greatergreater:412      return TPResult::True;413 414    default:415      return TPResult::False;416    }417  }418 419  if (TryAnnotateTypeConstraint())420    return TPResult::Error;421 422  if (isTypeConstraintAnnotation() &&423      // Next token might be 'auto' or 'decltype', indicating that this424      // type-constraint is in fact part of a placeholder-type-specifier of a425      // non-type template parameter.426      !GetLookAheadToken(Tok.is(tok::annot_cxxscope) ? 2 : 1)427           .isOneOf(tok::kw_auto, tok::kw_decltype))428    return TPResult::True;429 430  // 'typedef' is a reasonably-common typo/thinko for 'typename', and is431  // ill-formed otherwise.432  if (Tok.isNot(tok::kw_typename) && Tok.isNot(tok::kw_typedef))433    return TPResult::False;434 435  // C++ [temp.param]p2:436  //   There is no semantic difference between class and typename in a437  //   template-parameter. typename followed by an unqualified-id438  //   names a template type parameter. typename followed by a439  //   qualified-id denotes the type in a non-type440  //   parameter-declaration.441  Token Next = NextToken();442 443  // If we have an identifier, skip over it.444  if (Next.getKind() == tok::identifier)445    Next = GetLookAheadToken(2);446 447  switch (Next.getKind()) {448  case tok::equal:449  case tok::comma:450  case tok::greater:451  case tok::greatergreater:452  case tok::ellipsis:453    return TPResult::True;454 455  case tok::kw_typename:456  case tok::kw_typedef:457  case tok::kw_class:458    // These indicate that a comma was missed after a type parameter, not that459    // we have found a non-type parameter.460    return TPResult::True;461 462  default:463    return TPResult::False;464  }465}466 467NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {468 469  switch (isStartOfTemplateTypeParameter()) {470  case TPResult::True:471    // Is there just a typo in the input code? ('typedef' instead of472    // 'typename')473    if (Tok.is(tok::kw_typedef)) {474      Diag(Tok.getLocation(), diag::err_expected_template_parameter);475 476      Diag(Tok.getLocation(), diag::note_meant_to_use_typename)477          << FixItHint::CreateReplacement(CharSourceRange::getCharRange(478                                              Tok.getLocation(),479                                              Tok.getEndLoc()),480                                          "typename");481 482      Tok.setKind(tok::kw_typename);483    }484 485    return ParseTypeParameter(Depth, Position);486  case TPResult::False:487    break;488 489  case TPResult::Error: {490    // We return an invalid parameter as opposed to null to avoid having bogus491    // diagnostics about an empty template parameter list.492    // FIXME: Fix ParseTemplateParameterList to better handle nullptr results493    //  from here.494    // Return a NTTP as if there was an error in a scope specifier, the user495    // probably meant to write the type of a NTTP.496    DeclSpec DS(getAttrFactory());497    DS.SetTypeSpecError();498    Declarator D(DS, ParsedAttributesView::none(),499                 DeclaratorContext::TemplateParam);500    D.SetIdentifier(nullptr, Tok.getLocation());501    D.setInvalidType(true);502    NamedDecl *ErrorParam = Actions.ActOnNonTypeTemplateParameter(503        getCurScope(), D, Depth, Position, /*EqualLoc=*/SourceLocation(),504        /*DefaultArg=*/nullptr);505    ErrorParam->setInvalidDecl(true);506    SkipUntil(tok::comma, tok::greater, tok::greatergreater,507              StopAtSemi | StopBeforeMatch);508    return ErrorParam;509  }510 511  case TPResult::Ambiguous:512    llvm_unreachable("template param classification can't be ambiguous");513  }514 515  if (Tok.is(tok::kw_template))516    return ParseTemplateTemplateParameter(Depth, Position);517 518  // If it's none of the above, then it must be a parameter declaration.519  // NOTE: This will pick up errors in the closure of the template parameter520  // list (e.g., template < ; Check here to implement >> style closures.521  return ParseNonTypeTemplateParameter(Depth, Position);522}523 524bool Parser::isTypeConstraintAnnotation() {525  const Token &T = Tok.is(tok::annot_cxxscope) ? NextToken() : Tok;526  if (T.isNot(tok::annot_template_id))527    return false;528  const auto *ExistingAnnot =529      static_cast<TemplateIdAnnotation *>(T.getAnnotationValue());530  return ExistingAnnot->Kind == TNK_Concept_template;531}532 533bool Parser::TryAnnotateTypeConstraint() {534  if (!getLangOpts().CPlusPlus20)535    return false;536  // The type constraint may declare template parameters, notably537  // if it contains a generic lambda, so we need to increment538  // the template depth as these parameters would not be instantiated539  // at the current depth.540  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);541  ++CurTemplateDepthTracker;542  CXXScopeSpec SS;543  bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);544  if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,545                                     /*ObjectHasErrors=*/false,546                                     /*EnteringContext=*/false,547                                     /*MayBePseudoDestructor=*/nullptr,548                                     // If this is not a type-constraint, then549                                     // this scope-spec is part of the typename550                                     // of a non-type template parameter551                                     /*IsTypename=*/true, /*LastII=*/nullptr,552                                     // We won't find concepts in553                                     // non-namespaces anyway, so might as well554                                     // parse this correctly for possible type555                                     // names.556                                     /*OnlyNamespace=*/false))557    return true;558 559  if (Tok.is(tok::identifier)) {560    UnqualifiedId PossibleConceptName;561    PossibleConceptName.setIdentifier(Tok.getIdentifierInfo(),562                                      Tok.getLocation());563 564    TemplateTy PossibleConcept;565    bool MemberOfUnknownSpecialization = false;566    auto TNK = Actions.isTemplateName(getCurScope(), SS,567                                      /*hasTemplateKeyword=*/false,568                                      PossibleConceptName,569                                      /*ObjectType=*/ParsedType(),570                                      /*EnteringContext=*/false,571                                      PossibleConcept,572                                      MemberOfUnknownSpecialization,573                                      /*Disambiguation=*/true);574    if (MemberOfUnknownSpecialization || !PossibleConcept ||575        TNK != TNK_Concept_template) {576      if (SS.isNotEmpty())577        AnnotateScopeToken(SS, !WasScopeAnnotation);578      return false;579    }580 581    // At this point we're sure we're dealing with a constrained parameter. It582    // may or may not have a template parameter list following the concept583    // name.584    if (AnnotateTemplateIdToken(PossibleConcept, TNK, SS,585                                   /*TemplateKWLoc=*/SourceLocation(),586                                   PossibleConceptName,587                                   /*AllowTypeAnnotation=*/false,588                                   /*TypeConstraint=*/true))589      return true;590  }591 592  if (SS.isNotEmpty())593    AnnotateScopeToken(SS, !WasScopeAnnotation);594  return false;595}596 597NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {598  assert((Tok.isOneOf(tok::kw_class, tok::kw_typename) ||599          isTypeConstraintAnnotation()) &&600         "A type-parameter starts with 'class', 'typename' or a "601         "type-constraint");602 603  CXXScopeSpec TypeConstraintSS;604  TemplateIdAnnotation *TypeConstraint = nullptr;605  bool TypenameKeyword = false;606  SourceLocation KeyLoc;607  ParseOptionalCXXScopeSpecifier(TypeConstraintSS, /*ObjectType=*/nullptr,608                                 /*ObjectHasErrors=*/false,609                                 /*EnteringContext*/ false);610  if (Tok.is(tok::annot_template_id)) {611    // Consume the 'type-constraint'.612    TypeConstraint =613        static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());614    assert(TypeConstraint->Kind == TNK_Concept_template &&615           "stray non-concept template-id annotation");616    KeyLoc = ConsumeAnnotationToken();617  } else {618    assert(TypeConstraintSS.isEmpty() &&619           "expected type constraint after scope specifier");620 621    // Consume the 'class' or 'typename' keyword.622    TypenameKeyword = Tok.is(tok::kw_typename);623    KeyLoc = ConsumeToken();624  }625 626  // Grab the ellipsis (if given).627  SourceLocation EllipsisLoc;628  if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {629    Diag(EllipsisLoc,630         getLangOpts().CPlusPlus11631           ? diag::warn_cxx98_compat_variadic_templates632           : diag::ext_variadic_templates);633  }634 635  // Grab the template parameter name (if given)636  SourceLocation NameLoc = Tok.getLocation();637  IdentifierInfo *ParamName = nullptr;638  if (Tok.is(tok::identifier)) {639    ParamName = Tok.getIdentifierInfo();640    ConsumeToken();641  } else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,642                         tok::greatergreater)) {643    // Unnamed template parameter. Don't have to do anything here, just644    // don't consume this token.645  } else {646    Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;647    return nullptr;648  }649 650  // Recover from misplaced ellipsis.651  bool AlreadyHasEllipsis = EllipsisLoc.isValid();652  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))653    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);654 655  // Grab a default argument (if available).656  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before657  // we introduce the type parameter into the local scope.658  SourceLocation EqualLoc;659  ParsedType DefaultArg;660  std::optional<DelayTemplateIdDestructionRAII> DontDestructTemplateIds;661  if (TryConsumeToken(tok::equal, EqualLoc)) {662    // The default argument might contain a lambda declaration; avoid destroying663    // parsed template ids at the end of that declaration because they can be664    // used in a type constraint later.665    DontDestructTemplateIds.emplace(*this, /*DelayTemplateIdDestruction=*/true);666    // The default argument may declare template parameters, notably667    // if it contains a generic lambda, so we need to increase668    // the template depth as these parameters would not be instantiated669    // at the current level.670    TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);671    ++CurTemplateDepthTracker;672    DefaultArg =673        ParseTypeName(/*Range=*/nullptr, DeclaratorContext::TemplateTypeArg)674            .get();675  }676 677  NamedDecl *NewDecl = Actions.ActOnTypeParameter(getCurScope(),678                                                  TypenameKeyword, EllipsisLoc,679                                                  KeyLoc, ParamName, NameLoc,680                                                  Depth, Position, EqualLoc,681                                                  DefaultArg,682                                                  TypeConstraint != nullptr);683 684  if (TypeConstraint) {685    Actions.ActOnTypeConstraint(TypeConstraintSS, TypeConstraint,686                                cast<TemplateTypeParmDecl>(NewDecl),687                                EllipsisLoc);688  }689 690  return NewDecl;691}692 693NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,694                                                  unsigned Position) {695  assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");696 697  // Handle the template <...> part.698  SourceLocation TemplateLoc = ConsumeToken();699  SmallVector<NamedDecl*,8> TemplateParams;700  SourceLocation LAngleLoc, RAngleLoc;701  ExprResult OptionalRequiresClauseConstraintER;702  {703    MultiParseScope TemplateParmScope(*this);704    if (ParseTemplateParameters(TemplateParmScope, Depth + 1, TemplateParams,705                                LAngleLoc, RAngleLoc)) {706      return nullptr;707    }708    if (TryConsumeToken(tok::kw_requires)) {709      OptionalRequiresClauseConstraintER =710          Actions.ActOnRequiresClause(ParseConstraintLogicalOrExpression(711              /*IsTrailingRequiresClause=*/false));712      if (!OptionalRequiresClauseConstraintER.isUsable()) {713        SkipUntil(tok::comma, tok::greater, tok::greatergreater,714                  StopAtSemi | StopBeforeMatch);715        return nullptr;716      }717    }718  }719 720  TemplateNameKind Kind = TemplateNameKind::TNK_Non_template;721  SourceLocation NameLoc;722  IdentifierInfo *ParamName = nullptr;723  SourceLocation EllipsisLoc;724  bool TypenameKeyword = false;725 726  if (TryConsumeToken(tok::kw_class)) {727    Kind = TemplateNameKind::TNK_Type_template;728  } else {729 730    // Provide an ExtWarn if the C++1z feature of using 'typename' here is used.731    // Generate a meaningful error if the user forgot to put class before the732    // identifier, comma, or greater. Provide a fixit if the identifier, comma,733    // or greater appear immediately or after 'struct'. In the latter case,734    // replace the keyword with 'class'.735    bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);736    const Token &Next = Tok.is(tok::kw_struct) ? NextToken() : Tok;737    if (Tok.is(tok::kw_typename)) {738      TypenameKeyword = true;739      Kind = TemplateNameKind::TNK_Type_template;740      Diag(Tok.getLocation(),741           getLangOpts().CPlusPlus17742               ? diag::warn_cxx14_compat_template_template_param_typename743               : diag::ext_template_template_param_typename)744          << (!getLangOpts().CPlusPlus17745                  ? FixItHint::CreateReplacement(Tok.getLocation(), "class")746                  : FixItHint());747      Kind = TemplateNameKind::TNK_Type_template;748    } else if (TryConsumeToken(tok::kw_concept)) {749      Kind = TemplateNameKind::TNK_Concept_template;750    } else if (TryConsumeToken(tok::kw_auto)) {751      Kind = TemplateNameKind::TNK_Var_template;752    } else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,753                            tok::greatergreater, tok::ellipsis)) {754      // Provide a fixit if the identifier, comma,755      // or greater appear immediately or after 'struct'. In the latter case,756      // replace the keyword with 'class'.757      Diag(Tok.getLocation(), diag::err_class_on_template_template_param)758          << getLangOpts().CPlusPlus17759          << (Replace760                  ? FixItHint::CreateReplacement(Tok.getLocation(), "class")761                  : FixItHint::CreateInsertion(Tok.getLocation(), "class "));762    }763    if (Replace)764      ConsumeToken();765  }766 767  if (!getLangOpts().CPlusPlus26 &&768      (Kind == TemplateNameKind::TNK_Concept_template ||769       Kind == TemplateNameKind::TNK_Var_template)) {770    Diag(PrevTokLocation, diag::err_cxx26_template_template_params)771        << (Kind == TemplateNameKind::TNK_Concept_template);772  }773 774  // Parse the ellipsis, if given.775  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))776    Diag(EllipsisLoc,777         getLangOpts().CPlusPlus11778           ? diag::warn_cxx98_compat_variadic_templates779           : diag::ext_variadic_templates);780 781  // Get the identifier, if given.782  NameLoc = Tok.getLocation();783  if (Tok.is(tok::identifier)) {784    ParamName = Tok.getIdentifierInfo();785    ConsumeToken();786  } else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,787                         tok::greatergreater)) {788    // Unnamed template parameter. Don't have to do anything here, just789    // don't consume this token.790  } else {791    Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;792    return nullptr;793  }794 795  // Recover from misplaced ellipsis.796  bool AlreadyHasEllipsis = EllipsisLoc.isValid();797  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))798    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);799 800  TemplateParameterList *ParamList = Actions.ActOnTemplateParameterList(801      Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams,802      RAngleLoc, OptionalRequiresClauseConstraintER.get());803 804  // Grab a default argument (if available).805  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before806  // we introduce the template parameter into the local scope.807  SourceLocation EqualLoc;808  ParsedTemplateArgument DefaultArg;809  if (TryConsumeToken(tok::equal, EqualLoc)) {810    DefaultArg = ParseTemplateTemplateArgument();811    if (DefaultArg.isInvalid()) {812      Diag(Tok.getLocation(),813           diag::err_default_template_template_parameter_not_template);814      SkipUntil(tok::comma, tok::greater, tok::greatergreater,815                StopAtSemi | StopBeforeMatch);816    }817  }818 819  return Actions.ActOnTemplateTemplateParameter(820      getCurScope(), TemplateLoc, Kind, TypenameKeyword, ParamList, EllipsisLoc,821      ParamName, NameLoc, Depth, Position, EqualLoc, DefaultArg);822}823 824NamedDecl *825Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {826  // Parse the declaration-specifiers (i.e., the type).827  // FIXME: The type should probably be restricted in some way... Not all828  // declarators (parts of declarators?) are accepted for parameters.829  DeclSpec DS(AttrFactory);830  ParsedTemplateInfo TemplateInfo;831  ParseDeclarationSpecifiers(DS, TemplateInfo, AS_none,832                             DeclSpecContext::DSC_template_param);833 834  // Parse this as a typename.835  Declarator ParamDecl(DS, ParsedAttributesView::none(),836                       DeclaratorContext::TemplateParam);837  ParseDeclarator(ParamDecl);838  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {839    Diag(Tok.getLocation(), diag::err_expected_template_parameter);840    return nullptr;841  }842 843  // Recover from misplaced ellipsis.844  SourceLocation EllipsisLoc;845  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))846    DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);847 848  // If there is a default value, parse it.849  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before850  // we introduce the template parameter into the local scope.851  SourceLocation EqualLoc;852  ExprResult DefaultArg;853  if (TryConsumeToken(tok::equal, EqualLoc)) {854    if (Tok.is(tok::l_paren) && NextToken().is(tok::l_brace)) {855      Diag(Tok.getLocation(), diag::err_stmt_expr_in_default_arg) << 1;856      SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);857    } else {858      // C++ [temp.param]p15:859      //   When parsing a default template-argument for a non-type860      //   template-parameter, the first non-nested > is taken as the861      //   end of the template-parameter-list rather than a greater-than862      //   operator.863      GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);864 865      // The default argument may declare template parameters, notably866      // if it contains a generic lambda, so we need to increase867      // the template depth as these parameters would not be instantiated868      // at the current level.869      TemplateParameterDepthRAII CurTemplateDepthTracker(870          TemplateParameterDepth);871      ++CurTemplateDepthTracker;872      EnterExpressionEvaluationContext ConstantEvaluated(873          Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);874      DefaultArg = Actions.ActOnConstantExpression(ParseInitializer());875      if (DefaultArg.isInvalid())876        SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);877    }878  }879 880  // Create the parameter.881  return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl,882                                               Depth, Position, EqualLoc,883                                               DefaultArg.get());884}885 886void Parser::DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,887                                       SourceLocation CorrectLoc,888                                       bool AlreadyHasEllipsis,889                                       bool IdentifierHasName) {890  FixItHint Insertion;891  if (!AlreadyHasEllipsis)892    Insertion = FixItHint::CreateInsertion(CorrectLoc, "...");893  Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)894      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion895      << !IdentifierHasName;896}897 898void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,899                                                   Declarator &D) {900  assert(EllipsisLoc.isValid());901  bool AlreadyHasEllipsis = D.getEllipsisLoc().isValid();902  if (!AlreadyHasEllipsis)903    D.setEllipsisLoc(EllipsisLoc);904  DiagnoseMisplacedEllipsis(EllipsisLoc, D.getIdentifierLoc(),905                            AlreadyHasEllipsis, D.hasName());906}907 908bool Parser::ParseGreaterThanInTemplateList(SourceLocation LAngleLoc,909                                            SourceLocation &RAngleLoc,910                                            bool ConsumeLastToken,911                                            bool ObjCGenericList) {912  // What will be left once we've consumed the '>'.913  tok::TokenKind RemainingToken;914  const char *ReplacementStr = "> >";915  bool MergeWithNextToken = false;916 917  switch (Tok.getKind()) {918  default:919    Diag(getEndOfPreviousToken(), diag::err_expected) << tok::greater;920    Diag(LAngleLoc, diag::note_matching) << tok::less;921    return true;922 923  case tok::greater:924    // Determine the location of the '>' token. Only consume this token925    // if the caller asked us to.926    RAngleLoc = Tok.getLocation();927    if (ConsumeLastToken)928      ConsumeToken();929    return false;930 931  case tok::greatergreater:932    RemainingToken = tok::greater;933    break;934 935  case tok::greatergreatergreater:936    RemainingToken = tok::greatergreater;937    break;938 939  case tok::greaterequal:940    RemainingToken = tok::equal;941    ReplacementStr = "> =";942 943    // Join two adjacent '=' tokens into one, for cases like:944    //   void (*p)() = f<int>;945    //   return f<int>==p;946    if (NextToken().is(tok::equal) &&947        areTokensAdjacent(Tok, NextToken())) {948      RemainingToken = tok::equalequal;949      MergeWithNextToken = true;950    }951    break;952 953  case tok::greatergreaterequal:954    RemainingToken = tok::greaterequal;955    break;956  }957 958  // This template-id is terminated by a token that starts with a '>'.959  // Outside C++11 and Objective-C, this is now error recovery.960  //961  // C++11 allows this when the token is '>>', and in CUDA + C++11 mode, we962  // extend that treatment to also apply to the '>>>' token.963  //964  // Objective-C allows this in its type parameter / argument lists.965 966  SourceLocation TokBeforeGreaterLoc = PrevTokLocation;967  SourceLocation TokLoc = Tok.getLocation();968  Token Next = NextToken();969 970  // Whether splitting the current token after the '>' would undesirably result971  // in the remaining token pasting with the token after it. This excludes the972  // MergeWithNextToken cases, which we've already handled.973  bool PreventMergeWithNextToken =974      (RemainingToken == tok::greater ||975       RemainingToken == tok::greatergreater) &&976      (Next.isOneOf(tok::greater, tok::greatergreater,977                    tok::greatergreatergreater, tok::equal, tok::greaterequal,978                    tok::greatergreaterequal, tok::equalequal)) &&979      areTokensAdjacent(Tok, Next);980 981  // Diagnose this situation as appropriate.982  if (!ObjCGenericList) {983    // The source range of the replaced token(s).984    CharSourceRange ReplacementRange = CharSourceRange::getCharRange(985        TokLoc, Lexer::AdvanceToTokenCharacter(TokLoc, 2, PP.getSourceManager(),986                                               getLangOpts()));987 988    // A hint to put a space between the '>>'s. In order to make the hint as989    // clear as possible, we include the characters either side of the space in990    // the replacement, rather than just inserting a space at SecondCharLoc.991    FixItHint Hint1 = FixItHint::CreateReplacement(ReplacementRange,992                                                   ReplacementStr);993 994    // A hint to put another space after the token, if it would otherwise be995    // lexed differently.996    FixItHint Hint2;997    if (PreventMergeWithNextToken)998      Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");999 1000    unsigned DiagId = diag::err_two_right_angle_brackets_need_space;1001    if (getLangOpts().CPlusPlus11 &&1002        (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))1003      DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;1004    else if (Tok.is(tok::greaterequal))1005      DiagId = diag::err_right_angle_bracket_equal_needs_space;1006    Diag(TokLoc, DiagId) << Hint1 << Hint2;1007  }1008 1009  // Find the "length" of the resulting '>' token. This is not always 1, as it1010  // can contain escaped newlines.1011  unsigned GreaterLength = Lexer::getTokenPrefixLength(1012      TokLoc, 1, PP.getSourceManager(), getLangOpts());1013 1014  // Annotate the source buffer to indicate that we split the token after the1015  // '>'. This allows us to properly find the end of, and extract the spelling1016  // of, the '>' token later.1017  RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);1018 1019  // Strip the initial '>' from the token.1020  bool CachingTokens = PP.IsPreviousCachedToken(Tok);1021 1022  Token Greater = Tok;1023  Greater.setLocation(RAngleLoc);1024  Greater.setKind(tok::greater);1025  Greater.setLength(GreaterLength);1026 1027  unsigned OldLength = Tok.getLength();1028  if (MergeWithNextToken) {1029    ConsumeToken();1030    OldLength += Tok.getLength();1031  }1032 1033  Tok.setKind(RemainingToken);1034  Tok.setLength(OldLength - GreaterLength);1035 1036  // Split the second token if lexing it normally would lex a different token1037  // (eg, the fifth token in 'A<B>>>' should re-lex as '>', not '>>').1038  SourceLocation AfterGreaterLoc = TokLoc.getLocWithOffset(GreaterLength);1039  if (PreventMergeWithNextToken)1040    AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());1041  Tok.setLocation(AfterGreaterLoc);1042 1043  // Update the token cache to match what we just did if necessary.1044  if (CachingTokens) {1045    // If the previous cached token is being merged, delete it.1046    if (MergeWithNextToken)1047      PP.ReplacePreviousCachedToken({});1048 1049    if (ConsumeLastToken)1050      PP.ReplacePreviousCachedToken({Greater, Tok});1051    else1052      PP.ReplacePreviousCachedToken({Greater});1053  }1054 1055  if (ConsumeLastToken) {1056    PrevTokLocation = RAngleLoc;1057  } else {1058    PrevTokLocation = TokBeforeGreaterLoc;1059    PP.EnterToken(Tok, /*IsReinject=*/true);1060    Tok = Greater;1061  }1062 1063  return false;1064}1065 1066bool Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,1067                                              SourceLocation &LAngleLoc,1068                                              TemplateArgList &TemplateArgs,1069                                              SourceLocation &RAngleLoc,1070                                              TemplateTy Template) {1071  assert(Tok.is(tok::less) && "Must have already parsed the template-name");1072 1073  // Consume the '<'.1074  LAngleLoc = ConsumeToken();1075 1076  // Parse the optional template-argument-list.1077  bool Invalid = false;1078  {1079    GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);1080    if (!Tok.isOneOf(tok::greater, tok::greatergreater,1081                     tok::greatergreatergreater, tok::greaterequal,1082                     tok::greatergreaterequal))1083      Invalid = ParseTemplateArgumentList(TemplateArgs, Template, LAngleLoc);1084 1085    if (Invalid) {1086      // Try to find the closing '>'.1087      if (getLangOpts().CPlusPlus11)1088        SkipUntil(tok::greater, tok::greatergreater,1089                  tok::greatergreatergreater, StopAtSemi | StopBeforeMatch);1090      else1091        SkipUntil(tok::greater, StopAtSemi | StopBeforeMatch);1092    }1093  }1094 1095  return ParseGreaterThanInTemplateList(LAngleLoc, RAngleLoc, ConsumeLastToken,1096                                        /*ObjCGenericList=*/false) ||1097         Invalid;1098}1099 1100bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,1101                                     CXXScopeSpec &SS,1102                                     SourceLocation TemplateKWLoc,1103                                     UnqualifiedId &TemplateName,1104                                     bool AllowTypeAnnotation,1105                                     bool TypeConstraint) {1106  assert(getLangOpts().CPlusPlus && "Can only annotate template-ids in C++");1107  assert((Tok.is(tok::less) || TypeConstraint) &&1108         "Parser isn't at the beginning of a template-id");1109  assert(!(TypeConstraint && AllowTypeAnnotation) && "type-constraint can't be "1110                                                     "a type annotation");1111  assert((!TypeConstraint || TNK == TNK_Concept_template) && "type-constraint "1112         "must accompany a concept name");1113  assert((Template || TNK == TNK_Non_template) && "missing template name");1114 1115  // Consume the template-name.1116  SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin();1117 1118  // Parse the enclosed template argument list.1119  SourceLocation LAngleLoc, RAngleLoc;1120  TemplateArgList TemplateArgs;1121  bool ArgsInvalid = false;1122  if (!TypeConstraint || Tok.is(tok::less)) {1123    ArgsInvalid = ParseTemplateIdAfterTemplateName(1124        false, LAngleLoc, TemplateArgs, RAngleLoc, Template);1125    // If we couldn't recover from invalid arguments, don't form an annotation1126    // token -- we don't know how much to annotate.1127    // FIXME: This can lead to duplicate diagnostics if we retry parsing this1128    // template-id in another context. Try to annotate anyway?1129    if (RAngleLoc.isInvalid())1130      return true;1131  }1132 1133  ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);1134 1135  // Build the annotation token.1136  if (TNK == TNK_Type_template && AllowTypeAnnotation) {1137    TypeResult Type =1138        ArgsInvalid1139            ? TypeError()1140            : Actions.ActOnTemplateIdType(1141                  getCurScope(), ElaboratedTypeKeyword::None,1142                  /*ElaboratedKeywordLoc=*/SourceLocation(), SS, TemplateKWLoc,1143                  Template, TemplateName.Identifier, TemplateNameLoc, LAngleLoc,1144                  TemplateArgsPtr, RAngleLoc);1145 1146    Tok.setKind(tok::annot_typename);1147    setTypeAnnotation(Tok, Type);1148    if (SS.isNotEmpty())1149      Tok.setLocation(SS.getBeginLoc());1150    else if (TemplateKWLoc.isValid())1151      Tok.setLocation(TemplateKWLoc);1152    else1153      Tok.setLocation(TemplateNameLoc);1154  } else {1155    // Build a template-id annotation token that can be processed1156    // later.1157    Tok.setKind(tok::annot_template_id);1158 1159    const IdentifierInfo *TemplateII =1160        TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier1161            ? TemplateName.Identifier1162            : nullptr;1163 1164    OverloadedOperatorKind OpKind =1165        TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier1166            ? OO_None1167            : TemplateName.OperatorFunctionId.Operator;1168 1169    TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(1170        TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,1171        LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid, TemplateIds);1172 1173    Tok.setAnnotationValue(TemplateId);1174    if (TemplateKWLoc.isValid())1175      Tok.setLocation(TemplateKWLoc);1176    else1177      Tok.setLocation(TemplateNameLoc);1178  }1179 1180  // Common fields for the annotation token1181  Tok.setAnnotationEndLoc(RAngleLoc);1182 1183  // In case the tokens were cached, have Preprocessor replace them with the1184  // annotation token.1185  PP.AnnotateCachedTokens(Tok);1186  return false;1187}1188 1189void Parser::AnnotateTemplateIdTokenAsType(1190    CXXScopeSpec &SS, ImplicitTypenameContext AllowImplicitTypename,1191    bool IsClassName) {1192  assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");1193 1194  TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);1195  assert(TemplateId->mightBeType() &&1196         "Only works for type and dependent templates");1197 1198  ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),1199                                     TemplateId->NumArgs);1200 1201  TypeResult Type =1202      TemplateId->isInvalid()1203          ? TypeError()1204          : Actions.ActOnTemplateIdType(1205                getCurScope(), ElaboratedTypeKeyword::None,1206                /*ElaboratedKeywordLoc=*/SourceLocation(), SS,1207                TemplateId->TemplateKWLoc, TemplateId->Template,1208                TemplateId->Name, TemplateId->TemplateNameLoc,1209                TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc,1210                /*IsCtorOrDtorName=*/false, IsClassName, AllowImplicitTypename);1211  // Create the new "type" annotation token.1212  Tok.setKind(tok::annot_typename);1213  setTypeAnnotation(Tok, Type);1214  if (SS.isNotEmpty()) // it was a C++ qualified type name.1215    Tok.setLocation(SS.getBeginLoc());1216  // End location stays the same1217 1218  // Replace the template-id annotation token, and possible the scope-specifier1219  // that precedes it, with the typename annotation token.1220  PP.AnnotateCachedTokens(Tok);1221}1222 1223/// Determine whether the given token can end a template argument.1224static bool isEndOfTemplateArgument(Token Tok) {1225  // FIXME: Handle '>>>'.1226  return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater,1227                     tok::greatergreatergreater);1228}1229 1230ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {1231  if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&1232      !Tok.is(tok::annot_cxxscope) && !Tok.is(tok::annot_template_id) &&1233      !Tok.is(tok::annot_non_type))1234    return ParsedTemplateArgument();1235 1236  // C++0x [temp.arg.template]p1:1237  //   A template-argument for a template template-parameter shall be the name1238  //   of a class template or an alias template, expressed as id-expression.1239  //1240  // We parse an id-expression that refers to a class template or alias1241  // template. The grammar we parse is:1242  //1243  //   nested-name-specifier[opt] template[opt] identifier ...[opt]1244  //1245  // followed by a token that terminates a template argument, such as ',',1246  // '>', or (in some cases) '>>'.1247  CXXScopeSpec SS; // nested-name-specifier, if present1248  ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,1249                                 /*ObjectHasErrors=*/false,1250                                 /*EnteringContext=*/false);1251 1252  ParsedTemplateArgument Result;1253  SourceLocation EllipsisLoc;1254  if (SS.isSet() && Tok.is(tok::kw_template)) {1255    // Parse the optional 'template' keyword following the1256    // nested-name-specifier.1257    SourceLocation TemplateKWLoc = ConsumeToken();1258 1259    if (Tok.is(tok::identifier)) {1260      // We appear to have a dependent template name.1261      UnqualifiedId Name;1262      Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());1263      ConsumeToken(); // the identifier1264 1265      TryConsumeToken(tok::ellipsis, EllipsisLoc);1266 1267      // If the next token signals the end of a template argument, then we have1268      // a (possibly-dependent) template name that could be a template template1269      // argument.1270      TemplateTy Template;1271      if (isEndOfTemplateArgument(Tok) &&1272          Actions.ActOnTemplateName(getCurScope(), SS, TemplateKWLoc, Name,1273                                    /*ObjectType=*/nullptr,1274                                    /*EnteringContext=*/false, Template))1275        Result = ParsedTemplateArgument(TemplateKWLoc, SS, Template,1276                                        Name.StartLocation);1277    }1278  } else if (Tok.is(tok::identifier) || Tok.is(tok::annot_template_id) ||1279             Tok.is(tok::annot_non_type)) {1280    // We may have a (non-dependent) template name.1281    TemplateTy Template;1282    UnqualifiedId Name;1283    if (Tok.is(tok::annot_non_type)) {1284      NamedDecl *ND = getNonTypeAnnotation(Tok);1285      if (!isa<VarTemplateDecl>(ND))1286        return Result;1287      Name.setIdentifier(ND->getIdentifier(), Tok.getLocation());1288      ConsumeAnnotationToken();1289    } else if (Tok.is(tok::annot_template_id)) {1290      TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);1291      if (TemplateId->LAngleLoc.isValid())1292        return Result;1293      Name.setIdentifier(TemplateId->Name, Tok.getLocation());1294      ConsumeAnnotationToken();1295    } else {1296      Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());1297      ConsumeToken(); // the identifier1298    }1299 1300    TryConsumeToken(tok::ellipsis, EllipsisLoc);1301 1302    if (isEndOfTemplateArgument(Tok)) {1303      bool MemberOfUnknownSpecialization;1304      TemplateNameKind TNK = Actions.isTemplateName(1305          getCurScope(), SS,1306          /*hasTemplateKeyword=*/false, Name,1307          /*ObjectType=*/nullptr,1308          /*EnteringContext=*/false, Template, MemberOfUnknownSpecialization);1309      if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template ||1310          TNK == TNK_Var_template || TNK == TNK_Concept_template) {1311        // We have an id-expression that refers to a class template or1312        // (C++0x) alias template.1313        Result = ParsedTemplateArgument(/*TemplateKwLoc=*/SourceLocation(), SS,1314                                        Template, Name.StartLocation);1315      }1316    }1317  }1318 1319  Result = Actions.ActOnTemplateTemplateArgument(Result);1320 1321  // If this is a pack expansion, build it as such.1322  if (EllipsisLoc.isValid() && !Result.isInvalid())1323    Result = Actions.ActOnPackExpansion(Result, EllipsisLoc);1324 1325  return Result;1326}1327 1328ParsedTemplateArgument Parser::ParseTemplateArgument() {1329  // C++ [temp.arg]p2:1330  //   In a template-argument, an ambiguity between a type-id and an1331  //   expression is resolved to a type-id, regardless of the form of1332  //   the corresponding template-parameter.1333  //1334  // Therefore, we initially try to parse a type-id - and isCXXTypeId might look1335  // up and annotate an identifier as an id-expression during disambiguation,1336  // so enter the appropriate context for a constant expression template1337  // argument before trying to disambiguate.1338 1339  EnterExpressionEvaluationContext EnterConstantEvaluated(1340    Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,1341    /*LambdaContextDecl=*/nullptr,1342    /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);1343  if (isCXXTypeId(TentativeCXXTypeIdContext::AsTemplateArgument)) {1344    TypeResult TypeArg = ParseTypeName(1345        /*Range=*/nullptr, DeclaratorContext::TemplateArg);1346    return Actions.ActOnTemplateTypeArgument(TypeArg);1347  }1348 1349  // Try to parse a template template argument.1350  {1351    TentativeParsingAction TPA(*this);1352 1353    ParsedTemplateArgument TemplateTemplateArgument =1354        ParseTemplateTemplateArgument();1355    if (!TemplateTemplateArgument.isInvalid()) {1356      TPA.Commit();1357      return TemplateTemplateArgument;1358    }1359    // Revert this tentative parse to parse a non-type template argument.1360    TPA.Revert();1361  }1362 1363  // Parse a non-type template argument.1364  ExprResult ExprArg;1365  SourceLocation Loc = Tok.getLocation();1366  if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))1367    ExprArg = ParseBraceInitializer();1368  else1369    ExprArg = ParseConstantExpressionInExprEvalContext(1370        TypoCorrectionTypeBehavior::AllowBoth);1371  if (ExprArg.isInvalid() || !ExprArg.get()) {1372    return ParsedTemplateArgument();1373  }1374 1375  return ParsedTemplateArgument(ParsedTemplateArgument::NonType,1376                                ExprArg.get(), Loc);1377}1378 1379bool Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs,1380                                       TemplateTy Template,1381                                       SourceLocation OpenLoc) {1382 1383  ColonProtectionRAIIObject ColonProtection(*this, false);1384 1385  auto RunSignatureHelp = [&] {1386    if (!Template)1387      return QualType();1388    CalledSignatureHelp = true;1389    return Actions.CodeCompletion().ProduceTemplateArgumentSignatureHelp(1390        Template, TemplateArgs, OpenLoc);1391  };1392 1393  do {1394    PreferredType.enterFunctionArgument(Tok.getLocation(), RunSignatureHelp);1395    ParsedTemplateArgument Arg = ParseTemplateArgument();1396    SourceLocation EllipsisLoc;1397    if (TryConsumeToken(tok::ellipsis, EllipsisLoc))1398      Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);1399 1400    if (Arg.isInvalid()) {1401      if (PP.isCodeCompletionReached() && !CalledSignatureHelp)1402        RunSignatureHelp();1403      return true;1404    }1405 1406    // Save this template argument.1407    TemplateArgs.push_back(Arg);1408 1409    // If the next token is a comma, consume it and keep reading1410    // arguments.1411  } while (TryConsumeToken(tok::comma));1412 1413  return false;1414}1415 1416Parser::DeclGroupPtrTy Parser::ParseExplicitInstantiation(1417    DeclaratorContext Context, SourceLocation ExternLoc,1418    SourceLocation TemplateLoc, SourceLocation &DeclEnd,1419    ParsedAttributes &AccessAttrs, AccessSpecifier AS) {1420  // This isn't really required here.1421  ParsingDeclRAIIObject1422    ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);1423  ParsedTemplateInfo TemplateInfo(ExternLoc, TemplateLoc);1424  return ParseDeclarationAfterTemplate(1425      Context, TemplateInfo, ParsingTemplateParams, DeclEnd, AccessAttrs, AS);1426}1427 1428SourceRange Parser::ParsedTemplateInfo::getSourceRange() const {1429  if (TemplateParams)1430    return getTemplateParamsRange(TemplateParams->data(),1431                                  TemplateParams->size());1432 1433  SourceRange R(TemplateLoc);1434  if (ExternLoc.isValid())1435    R.setBegin(ExternLoc);1436  return R;1437}1438 1439void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) {1440  ((Parser *)P)->ParseLateTemplatedFuncDef(LPT);1441}1442 1443void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {1444  if (!LPT.D)1445     return;1446 1447  // Destroy TemplateIdAnnotations when we're done, if possible.1448  DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);1449 1450  // Get the FunctionDecl.1451  FunctionDecl *FunD = LPT.D->getAsFunction();1452  // Track template parameter depth.1453  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);1454 1455  // To restore the context after late parsing.1456  Sema::ContextRAII GlobalSavedContext(1457      Actions, Actions.Context.getTranslationUnitDecl());1458 1459  MultiParseScope Scopes(*this);1460 1461  // Get the list of DeclContexts to reenter.1462  SmallVector<DeclContext*, 4> DeclContextsToReenter;1463  for (DeclContext *DC = FunD; DC && !DC->isTranslationUnit();1464       DC = DC->getLexicalParent())1465    DeclContextsToReenter.push_back(DC);1466 1467  // Reenter scopes from outermost to innermost.1468  for (DeclContext *DC : reverse(DeclContextsToReenter)) {1469    CurTemplateDepthTracker.addDepth(1470        ReenterTemplateScopes(Scopes, cast<Decl>(DC)));1471    Scopes.Enter(Scope::DeclScope);1472    // We'll reenter the function context itself below.1473    if (DC != FunD)1474      Actions.PushDeclContext(Actions.getCurScope(), DC);1475  }1476 1477  // Parsing should occur with empty FP pragma stack and FP options used in the1478  // point of the template definition.1479  Sema::FpPragmaStackSaveRAII SavedStack(Actions);1480  Actions.resetFPOptions(LPT.FPO);1481 1482  assert(!LPT.Toks.empty() && "Empty body!");1483 1484  // Append the current token at the end of the new token stream so that it1485  // doesn't get lost.1486  LPT.Toks.push_back(Tok);1487  PP.EnterTokenStream(LPT.Toks, true, /*IsReinject*/true);1488 1489  // Consume the previously pushed token.1490  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);1491  assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&1492         "Inline method not starting with '{', ':' or 'try'");1493 1494  // Parse the method body. Function body parsing code is similar enough1495  // to be re-used for method bodies as well.1496  ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |1497                               Scope::CompoundStmtScope);1498 1499  // Recreate the containing function DeclContext.1500  Sema::ContextRAII FunctionSavedContext(Actions, FunD->getLexicalParent());1501 1502  Actions.ActOnStartOfFunctionDef(getCurScope(), FunD);1503 1504  if (Tok.is(tok::kw_try)) {1505    ParseFunctionTryBlock(LPT.D, FnScope);1506  } else {1507    if (Tok.is(tok::colon))1508      ParseConstructorInitializer(LPT.D);1509    else1510      Actions.ActOnDefaultCtorInitializers(LPT.D);1511 1512    if (Tok.is(tok::l_brace)) {1513      assert((!isa<FunctionTemplateDecl>(LPT.D) ||1514              cast<FunctionTemplateDecl>(LPT.D)1515                      ->getTemplateParameters()1516                      ->getDepth() == TemplateParameterDepth - 1) &&1517             "TemplateParameterDepth should be greater than the depth of "1518             "current template being instantiated!");1519      ParseFunctionStatementBody(LPT.D, FnScope);1520      Actions.UnmarkAsLateParsedTemplate(FunD);1521    } else1522      Actions.ActOnFinishFunctionBody(LPT.D, nullptr);1523  }1524}1525 1526void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {1527  tok::TokenKind kind = Tok.getKind();1528  if (!ConsumeAndStoreFunctionPrologue(Toks)) {1529    // Consume everything up to (and including) the matching right brace.1530    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);1531  }1532 1533  // If we're in a function-try-block, we need to store all the catch blocks.1534  if (kind == tok::kw_try) {1535    while (Tok.is(tok::kw_catch)) {1536      ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);1537      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);1538    }1539  }1540}1541 1542bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {1543  TentativeParsingAction TPA(*this);1544  // FIXME: We could look at the token sequence in a lot more detail here.1545  if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,1546                StopAtSemi | StopBeforeMatch)) {1547    TPA.Commit();1548 1549    SourceLocation Greater;1550    ParseGreaterThanInTemplateList(Less, Greater, true, false);1551    Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,1552                                               Less, Greater);1553    return true;1554  }1555 1556  // There's no matching '>' token, this probably isn't supposed to be1557  // interpreted as a template-id. Parse it as an (ill-formed) comparison.1558  TPA.Revert();1559  return false;1560}1561 1562void Parser::checkPotentialAngleBracket(ExprResult &PotentialTemplateName) {1563  assert(Tok.is(tok::less) && "not at a potential angle bracket");1564 1565  bool DependentTemplateName = false;1566  if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,1567                                               DependentTemplateName))1568    return;1569 1570  // OK, this might be a name that the user intended to be parsed as a1571  // template-name, followed by a '<' token. Check for some easy cases.1572 1573  // If we have potential_template<>, then it's supposed to be a template-name.1574  if (NextToken().is(tok::greater) ||1575      (getLangOpts().CPlusPlus11 &&1576       NextToken().isOneOf(tok::greatergreater, tok::greatergreatergreater))) {1577    SourceLocation Less = ConsumeToken();1578    SourceLocation Greater;1579    ParseGreaterThanInTemplateList(Less, Greater, true, false);1580    Actions.diagnoseExprIntendedAsTemplateName(1581        getCurScope(), PotentialTemplateName, Less, Greater);1582    // FIXME: Perform error recovery.1583    PotentialTemplateName = ExprError();1584    return;1585  }1586 1587  // If we have 'potential_template<type-id', assume it's supposed to be a1588  // template-name if there's a matching '>' later on.1589  {1590    // FIXME: Avoid the tentative parse when NextToken() can't begin a type.1591    TentativeParsingAction TPA(*this);1592    SourceLocation Less = ConsumeToken();1593    if (isTypeIdUnambiguously() &&1594        diagnoseUnknownTemplateId(PotentialTemplateName, Less)) {1595      TPA.Commit();1596      // FIXME: Perform error recovery.1597      PotentialTemplateName = ExprError();1598      return;1599    }1600    TPA.Revert();1601  }1602 1603  // Otherwise, remember that we saw this in case we see a potentially-matching1604  // '>' token later on.1605  AngleBracketTracker::Priority Priority =1606      (DependentTemplateName ? AngleBracketTracker::DependentName1607                             : AngleBracketTracker::PotentialTypo) |1608      (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess1609                             : AngleBracketTracker::NoSpaceBeforeLess);1610  AngleBrackets.add(*this, PotentialTemplateName.get(), Tok.getLocation(),1611                    Priority);1612}1613 1614bool Parser::checkPotentialAngleBracketDelimiter(1615    const AngleBracketTracker::Loc &LAngle, const Token &OpToken) {1616  // If a comma in an expression context is followed by a type that can be a1617  // template argument and cannot be an expression, then this is ill-formed,1618  // but might be intended to be part of a template-id.1619  if (OpToken.is(tok::comma) && isTypeIdUnambiguously() &&1620      diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {1621    AngleBrackets.clear(*this);1622    return true;1623  }1624 1625  // If a context that looks like a template-id is followed by '()', then1626  // this is ill-formed, but might be intended to be a template-id1627  // followed by '()'.1628  if (OpToken.is(tok::greater) && Tok.is(tok::l_paren) &&1629      NextToken().is(tok::r_paren)) {1630    Actions.diagnoseExprIntendedAsTemplateName(1631        getCurScope(), LAngle.TemplateName, LAngle.LessLoc,1632        OpToken.getLocation());1633    AngleBrackets.clear(*this);1634    return true;1635  }1636 1637  // After a '>' (etc), we're no longer potentially in a construct that's1638  // intended to be treated as a template-id.1639  if (OpToken.is(tok::greater) ||1640      (getLangOpts().CPlusPlus11 &&1641       OpToken.isOneOf(tok::greatergreater, tok::greatergreatergreater)))1642    AngleBrackets.clear(*this);1643  return false;1644}1645