Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
//===--- ParseTemplate.cpp - Template Parsing -----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements parsing of C++ templates.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
using namespace clang;

/// Parse a template declaration, explicit instantiation, or
/// explicit specialization.
Decl *Parser::ParseDeclarationStartingWithTemplate(
    DeclaratorContext Context, SourceLocation &DeclEnd,
    ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
  ObjCDeclContextSwitch ObjCDC(*this);
  
  if (Tok.is(tok::kw_template) && NextToken().isNot(tok::less)) {
    return ParseExplicitInstantiation(Context, SourceLocation(), ConsumeToken(),
                                      DeclEnd, AccessAttrs, AS);
  }
  return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AccessAttrs,
                                                  AS);
}

/// Parse a template declaration or an explicit specialization.
///
/// Template declarations include one or more template parameter lists
/// and either the function or class template declaration. Explicit
/// specializations contain one or more 'template < >' prefixes
/// followed by a (possibly templated) declaration. Since the
/// syntactic form of both features is nearly identical, we parse all
/// of the template headers together and let semantic analysis sort
/// the declarations from the explicit specializations.
///
///       template-declaration: [C++ temp]
///         'export'[opt] 'template' '<' template-parameter-list '>' declaration
///
///       explicit-specialization: [ C++ temp.expl.spec]
///         'template' '<' '>' declaration
Decl *Parser::ParseTemplateDeclarationOrSpecialization(
    DeclaratorContext Context, SourceLocation &DeclEnd,
    ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
  assert(Tok.isOneOf(tok::kw_export, tok::kw_template) &&
         "Token does not start a template declaration.");

  // Enter template-parameter scope.
  ParseScope TemplateParmScope(this, Scope::TemplateParamScope);

  // Tell the action that names should be checked in the context of
  // the declaration to come.
  ParsingDeclRAIIObject
    ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);

  // Parse multiple levels of template headers within this template
  // parameter scope, e.g.,
  //
  //   template<typename T>
  //     template<typename U>
  //       class A<T>::B { ... };
  //
  // We parse multiple levels non-recursively so that we can build a
  // single data structure containing all of the template parameter
  // lists to easily differentiate between the case above and:
  //
  //   template<typename T>
  //   class A {
  //     template<typename U> class B;
  //   };
  //
  // In the first case, the action for declaring A<T>::B receives
  // both template parameter lists. In the second case, the action for
  // defining A<T>::B receives just the inner template parameter list
  // (and retrieves the outer template parameter list from its
  // context).
  bool isSpecialization = true;
  bool LastParamListWasEmpty = false;
  TemplateParameterLists ParamLists;
  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);

  do {
    // Consume the 'export', if any.
    SourceLocation ExportLoc;
    TryConsumeToken(tok::kw_export, ExportLoc);

    // Consume the 'template', which should be here.
    SourceLocation TemplateLoc;
    if (!TryConsumeToken(tok::kw_template, TemplateLoc)) {
      Diag(Tok.getLocation(), diag::err_expected_template);
      return nullptr;
    }

    // Parse the '<' template-parameter-list '>'
    SourceLocation LAngleLoc, RAngleLoc;
    SmallVector<NamedDecl*, 4> TemplateParams;
    if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(),
                                TemplateParams, LAngleLoc, RAngleLoc)) {
      // Skip until the semi-colon or a '}'.
      SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
      TryConsumeToken(tok::semi);
      return nullptr;
    }

    ExprResult OptionalRequiresClauseConstraintER;
    if (!TemplateParams.empty()) {
      isSpecialization = false;
      ++CurTemplateDepthTracker;

      if (TryConsumeToken(tok::kw_requires)) {
        OptionalRequiresClauseConstraintER =
            Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression());
        if (!OptionalRequiresClauseConstraintER.isUsable()) {
          // Skip until the semi-colon or a '}'.
          SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
          TryConsumeToken(tok::semi);
          return nullptr;
        }
      }
    } else {
      LastParamListWasEmpty = true;
    }

    ParamLists.push_back(Actions.ActOnTemplateParameterList(
        CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,
        TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get()));
  } while (Tok.isOneOf(tok::kw_export, tok::kw_template));

  unsigned NewFlags = getCurScope()->getFlags() & ~Scope::TemplateParamScope;
  ParseScopeFlags TemplateScopeFlags(this, NewFlags, isSpecialization);

  // Parse the actual template declaration.
  return ParseSingleDeclarationAfterTemplate(
      Context,
      ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty),
      ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}

/// Parse a single declaration that declares a template,
/// template specialization, or explicit instantiation of a template.
///
/// \param DeclEnd will receive the source location of the last token
/// within this declaration.
///
/// \param AS the access specifier associated with this
/// declaration. Will be AS_none for namespace-scope declarations.
///
/// \returns the new declaration.
Decl *Parser::ParseSingleDeclarationAfterTemplate(
    DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo,
    ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd,
    ParsedAttributes &AccessAttrs, AccessSpecifier AS) {
  assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate &&
         "Template information required");

  if (Tok.is(tok::kw_static_assert)) {
    // A static_assert declaration may not be templated.
    Diag(Tok.getLocation(), diag::err_templated_invalid_declaration)
      << TemplateInfo.getSourceRange();
    // Parse the static_assert declaration to improve error recovery.
    return ParseStaticAssertDeclaration(DeclEnd);
  }

  if (Context == DeclaratorContext::MemberContext) {
    // We are parsing a member template.
    ParseCXXClassMemberDeclaration(AS, AccessAttrs, TemplateInfo,
                                   &DiagsFromTParams);
    return nullptr;
  }

  ParsedAttributesWithRange prefixAttrs(AttrFactory);
  MaybeParseCXX11Attributes(prefixAttrs);

  if (Tok.is(tok::kw_using)) {
    auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
                                                         prefixAttrs);
    if (!usingDeclPtr || !usingDeclPtr.get().isSingleDecl())
      return nullptr;
    return usingDeclPtr.get().getSingleDecl();
  }

  // Parse the declaration specifiers, stealing any diagnostics from
  // the template parameters.
  ParsingDeclSpec DS(*this, &DiagsFromTParams);

  ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
                             getDeclSpecContextFromDeclaratorContext(Context));

  if (Tok.is(tok::semi)) {
    ProhibitAttributes(prefixAttrs);
    DeclEnd = ConsumeToken();
    RecordDecl *AnonRecord = nullptr;
    Decl *Decl = Actions.ParsedFreeStandingDeclSpec(
        getCurScope(), AS, DS,
        TemplateInfo.TemplateParams ? *TemplateInfo.TemplateParams
                                    : MultiTemplateParamsArg(),
        TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation,
        AnonRecord);
    assert(!AnonRecord &&
           "Anonymous unions/structs should not be valid with template");
    DS.complete(Decl);
    return Decl;
  }

  // Move the attributes from the prefix into the DS.
  if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation)
    ProhibitAttributes(prefixAttrs);
  else
    DS.takeAttributesFrom(prefixAttrs);

  // Parse the declarator.
  ParsingDeclarator DeclaratorInfo(*this, DS, (DeclaratorContext)Context);
  ParseDeclarator(DeclaratorInfo);
  // Error parsing the declarator?
  if (!DeclaratorInfo.hasName()) {
    // If so, skip until the semi-colon or a }.
    SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);
    if (Tok.is(tok::semi))
      ConsumeToken();
    return nullptr;
  }

  LateParsedAttrList LateParsedAttrs(true);
  if (DeclaratorInfo.isFunctionDeclarator())
    MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs);

  if (DeclaratorInfo.isFunctionDeclarator() &&
      isStartOfFunctionDefinition(DeclaratorInfo)) {

    // Function definitions are only allowed at file scope and in C++ classes.
    // The C++ inline method definition case is handled elsewhere, so we only
    // need to handle the file scope definition case.
    if (Context != DeclaratorContext::FileContext) {
      Diag(Tok, diag::err_function_definition_not_allowed);
      SkipMalformedDecl();
      return nullptr;
    }

    if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
      // Recover by ignoring the 'typedef'. This was probably supposed to be
      // the 'typename' keyword, which we should have already suggested adding
      // if it's appropriate.
      Diag(DS.getStorageClassSpecLoc(), diag::err_function_declared_typedef)
        << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
      DS.ClearStorageClassSpecs();
    }

    if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
      if (DeclaratorInfo.getName().getKind() !=
          UnqualifiedIdKind::IK_TemplateId) {
        // If the declarator-id is not a template-id, issue a diagnostic and
        // recover by ignoring the 'template' keyword.
        Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
        return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(),
                                       &LateParsedAttrs);
      } else {
        SourceLocation LAngleLoc
          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
        Diag(DeclaratorInfo.getIdentifierLoc(),
             diag::err_explicit_instantiation_with_definition)
            << SourceRange(TemplateInfo.TemplateLoc)
            << FixItHint::CreateInsertion(LAngleLoc, "<>");

        // Recover as if it were an explicit specialization.
        TemplateParameterLists FakedParamLists;
        FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
            0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, None,
            LAngleLoc, nullptr));

        return ParseFunctionDefinition(
            DeclaratorInfo, ParsedTemplateInfo(&FakedParamLists,
                                               /*isSpecialization=*/true,
                                               /*LastParamListWasEmpty=*/true),
            &LateParsedAttrs);
      }
    }
    return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo,
                                   &LateParsedAttrs);
  }

  // Parse this declaration.
  Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo,
                                                   TemplateInfo);

  if (Tok.is(tok::comma)) {
    Diag(Tok, diag::err_multiple_template_declarators)
      << (int)TemplateInfo.Kind;
    SkipUntil(tok::semi);
    return ThisDecl;
  }

  // Eat the semi colon after the declaration.
  ExpectAndConsumeSemi(diag::err_expected_semi_declaration);
  if (LateParsedAttrs.size() > 0)
    ParseLexedAttributeList(LateParsedAttrs, ThisDecl, true, false);
  DeclaratorInfo.complete(ThisDecl);
  return ThisDecl;
}

/// 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.
/// TemplateParams is the current list of template parameters we're building.
/// The template parameter we parse will be added to this list. LAngleLoc and
/// RAngleLoc will receive the positions of the '<' and '>', respectively,
/// that enclose this template parameter list.
///
/// \returns true if an error occurred, false otherwise.
bool Parser::ParseTemplateParameters(
    unsigned Depth, SmallVectorImpl<NamedDecl *> &TemplateParams,
    SourceLocation &LAngleLoc, SourceLocation &RAngleLoc) {
  // Get the template parameter list.
  if (!TryConsumeToken(tok::less, LAngleLoc)) {
    Diag(Tok.getLocation(), diag::err_expected_less_after) << "template";
    return true;
  }

  // Try to parse the template parameter list.
  bool Failed = false;
  if (!Tok.is(tok::greater) && !Tok.is(tok::greatergreater))
    Failed = ParseTemplateParameterList(Depth, TemplateParams);

  if (Tok.is(tok::greatergreater)) {
    // No diagnostic required here: a template-parameter-list can only be
    // followed by a declaration or, for a template template parameter, the
    // 'class' keyword. Therefore, the second '>' will be diagnosed later.
    // This matters for elegant diagnosis of:
    //   template<template<typename>> struct S;
    Tok.setKind(tok::greater);
    RAngleLoc = Tok.getLocation();
    Tok.setLocation(Tok.getLocation().getLocWithOffset(1));
  } else if (!TryConsumeToken(tok::greater, RAngleLoc) && Failed) {
    Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
    return true;
  }
  return false;
}

/// ParseTemplateParameterList - Parse a template parameter list. If
/// the parsing fails badly (i.e., closing bracket was left out), this
/// will try to put the token stream in a reasonable position (closing
/// a statement, etc.) and return false.
///
///       template-parameter-list:    [C++ temp]
///         template-parameter
///         template-parameter-list ',' template-parameter
bool
Parser::ParseTemplateParameterList(const unsigned Depth,
                             SmallVectorImpl<NamedDecl*> &TemplateParams) {
  while (1) {
    
    if (NamedDecl *TmpParam
          = ParseTemplateParameter(Depth, TemplateParams.size())) {
      TemplateParams.push_back(TmpParam);
    } else {
      // If we failed to parse a template parameter, skip until we find
      // a comma or closing brace.
      SkipUntil(tok::comma, tok::greater, tok::greatergreater,
                StopAtSemi | StopBeforeMatch);
    }

    // Did we find a comma or the end of the template parameter list?
    if (Tok.is(tok::comma)) {
      ConsumeToken();
    } else if (Tok.isOneOf(tok::greater, tok::greatergreater)) {
      // Don't consume this... that's done by template parser.
      break;
    } else {
      // Somebody probably forgot to close the template. Skip ahead and
      // try to get out of the expression. This error is currently
      // subsumed by whatever goes on in ParseTemplateParameter.
      Diag(Tok.getLocation(), diag::err_expected_comma_greater);
      SkipUntil(tok::comma, tok::greater, tok::greatergreater,
                StopAtSemi | StopBeforeMatch);
      return false;
    }
  }
  return true;
}

/// Determine whether the parser is at the start of a template
/// type parameter.
bool Parser::isStartOfTemplateTypeParameter() {
  if (Tok.is(tok::kw_class)) {
    // "class" may be the start of an elaborated-type-specifier or a
    // type-parameter. Per C++ [temp.param]p3, we prefer the type-parameter.
    switch (NextToken().getKind()) {
    case tok::equal:
    case tok::comma:
    case tok::greater:
    case tok::greatergreater:
    case tok::ellipsis:
      return true;
        
    case tok::identifier:
      // This may be either a type-parameter or an elaborated-type-specifier. 
      // We have to look further.
      break;
        
    default:
      return false;
    }
    
    switch (GetLookAheadToken(2).getKind()) {
    case tok::equal:
    case tok::comma:
    case tok::greater:
    case tok::greatergreater:
      return true;
      
    default:
      return false;
    }
  }

  if (Tok.isNot(tok::kw_typename))
    return false;

  // C++ [temp.param]p2:
  //   There is no semantic difference between class and typename in a
  //   template-parameter. typename followed by an unqualified-id
  //   names a template type parameter. typename followed by a
  //   qualified-id denotes the type in a non-type
  //   parameter-declaration.
  Token Next = NextToken();

  // If we have an identifier, skip over it.
  if (Next.getKind() == tok::identifier)
    Next = GetLookAheadToken(2);

  switch (Next.getKind()) {
  case tok::equal:
  case tok::comma:
  case tok::greater:
  case tok::greatergreater:
  case tok::ellipsis:
    return true;

  default:
    return false;
  }
}

/// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]).
///
///       template-parameter: [C++ temp.param]
///         type-parameter
///         parameter-declaration
///
///       type-parameter: (see below)
///         'class' ...[opt] identifier[opt]
///         'class' identifier[opt] '=' type-id
///         'typename' ...[opt] identifier[opt]
///         'typename' identifier[opt] '=' type-id
///         'template' '<' template-parameter-list '>' 
///               'class' ...[opt] identifier[opt]
///         'template' '<' template-parameter-list '>' 'class' identifier[opt]
///               = id-expression
NamedDecl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) {
  if (isStartOfTemplateTypeParameter())
    return ParseTypeParameter(Depth, Position);

  if (Tok.is(tok::kw_template))
    return ParseTemplateTemplateParameter(Depth, Position);

  // Is there just a typo in the input code? ('typedef' instead of 'typename')
  if (Tok.is(tok::kw_typedef)) {
    Diag(Tok.getLocation(), diag::err_expected_template_parameter);

    Diag(Tok.getLocation(), diag::note_meant_to_use_typename)
        << FixItHint::CreateReplacement(CharSourceRange::getCharRange(
                                            Tok.getLocation(), Tok.getEndLoc()),
                                        "typename");

    Tok.setKind(tok::kw_typename);

    return ParseTypeParameter(Depth, Position);
  }

  // If it's none of the above, then it must be a parameter declaration.
  // NOTE: This will pick up errors in the closure of the template parameter
  // list (e.g., template < ; Check here to implement >> style closures.
  return ParseNonTypeTemplateParameter(Depth, Position);
}

/// ParseTypeParameter - Parse a template type parameter (C++ [temp.param]).
/// Other kinds of template parameters are parsed in
/// ParseTemplateTemplateParameter and ParseNonTypeTemplateParameter.
///
///       type-parameter:     [C++ temp.param]
///         'class' ...[opt][C++0x] identifier[opt]
///         'class' identifier[opt] '=' type-id
///         'typename' ...[opt][C++0x] identifier[opt]
///         'typename' identifier[opt] '=' type-id
NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
  assert(Tok.isOneOf(tok::kw_class, tok::kw_typename) &&
         "A type-parameter starts with 'class' or 'typename'");

  // Consume the 'class' or 'typename' keyword.
  bool TypenameKeyword = Tok.is(tok::kw_typename);
  SourceLocation KeyLoc = ConsumeToken();

  // Grab the ellipsis (if given).
  SourceLocation EllipsisLoc;
  if (TryConsumeToken(tok::ellipsis, EllipsisLoc)) {
    Diag(EllipsisLoc,
         getLangOpts().CPlusPlus11
           ? diag::warn_cxx98_compat_variadic_templates
           : diag::ext_variadic_templates);
  }

  // Grab the template parameter name (if given)
  SourceLocation NameLoc;
  IdentifierInfo *ParamName = nullptr;
  if (Tok.is(tok::identifier)) {
    ParamName = Tok.getIdentifierInfo();
    NameLoc = ConsumeToken();
  } else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
                         tok::greatergreater)) {
    // Unnamed template parameter. Don't have to do anything here, just
    // don't consume this token.
  } else {
    Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
    return nullptr;
  }

  // Recover from misplaced ellipsis.
  bool AlreadyHasEllipsis = EllipsisLoc.isValid();
  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);

  // Grab a default argument (if available).
  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
  // we introduce the type parameter into the local scope.
  SourceLocation EqualLoc;
  ParsedType DefaultArg;
  if (TryConsumeToken(tok::equal, EqualLoc))
    DefaultArg = ParseTypeName(/*Range=*/nullptr,
                               DeclaratorContext::TemplateTypeArgContext).get();

  return Actions.ActOnTypeParameter(getCurScope(), TypenameKeyword, EllipsisLoc,
                                    KeyLoc, ParamName, NameLoc, Depth, Position,
                                    EqualLoc, DefaultArg);
}

/// ParseTemplateTemplateParameter - Handle the parsing of template
/// template parameters.
///
///       type-parameter:    [C++ temp.param]
///         'template' '<' template-parameter-list '>' type-parameter-key
///                  ...[opt] identifier[opt]
///         'template' '<' template-parameter-list '>' type-parameter-key
///                  identifier[opt] = id-expression
///       type-parameter-key:
///         'class'
///         'typename'       [C++1z]
NamedDecl *
Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
  assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");

  // Handle the template <...> part.
  SourceLocation TemplateLoc = ConsumeToken();
  SmallVector<NamedDecl*,8> TemplateParams;
  SourceLocation LAngleLoc, RAngleLoc;
  {
    ParseScope TemplateParmScope(this, Scope::TemplateParamScope);
    if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc,
                               RAngleLoc)) {
      return nullptr;
    }
  }

  // Provide an ExtWarn if the C++1z feature of using 'typename' here is used.
  // Generate a meaningful error if the user forgot to put class before the
  // identifier, comma, or greater. Provide a fixit if the identifier, comma,
  // or greater appear immediately or after 'struct'. In the latter case,
  // replace the keyword with 'class'.
  if (!TryConsumeToken(tok::kw_class)) {
    bool Replace = Tok.isOneOf(tok::kw_typename, tok::kw_struct);
    const Token &Next = Tok.is(tok::kw_struct) ? NextToken() : Tok;
    if (Tok.is(tok::kw_typename)) {
      Diag(Tok.getLocation(),
           getLangOpts().CPlusPlus17
               ? diag::warn_cxx14_compat_template_template_param_typename
               : diag::ext_template_template_param_typename)
        << (!getLangOpts().CPlusPlus17
                ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
                : FixItHint());
    } else if (Next.isOneOf(tok::identifier, tok::comma, tok::greater,
                            tok::greatergreater, tok::ellipsis)) {
      Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
        << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
                    : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
    } else
      Diag(Tok.getLocation(), diag::err_class_on_template_template_param);

    if (Replace)
      ConsumeToken();
  }

  // Parse the ellipsis, if given.
  SourceLocation EllipsisLoc;
  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
    Diag(EllipsisLoc,
         getLangOpts().CPlusPlus11
           ? diag::warn_cxx98_compat_variadic_templates
           : diag::ext_variadic_templates);
      
  // Get the identifier, if given.
  SourceLocation NameLoc;
  IdentifierInfo *ParamName = nullptr;
  if (Tok.is(tok::identifier)) {
    ParamName = Tok.getIdentifierInfo();
    NameLoc = ConsumeToken();
  } else if (Tok.isOneOf(tok::equal, tok::comma, tok::greater,
                         tok::greatergreater)) {
    // Unnamed template parameter. Don't have to do anything here, just
    // don't consume this token.
  } else {
    Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
    return nullptr;
  }

  // Recover from misplaced ellipsis.
  bool AlreadyHasEllipsis = EllipsisLoc.isValid();
  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
    DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);

  TemplateParameterList *ParamList =
    Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
                                       TemplateLoc, LAngleLoc,
                                       TemplateParams,
                                       RAngleLoc, nullptr);

  // Grab a default argument (if available).
  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
  // we introduce the template parameter into the local scope.
  SourceLocation EqualLoc;
  ParsedTemplateArgument DefaultArg;
  if (TryConsumeToken(tok::equal, EqualLoc)) {
    DefaultArg = ParseTemplateTemplateArgument();
    if (DefaultArg.isInvalid()) {
      Diag(Tok.getLocation(), 
           diag::err_default_template_template_parameter_not_template);
      SkipUntil(tok::comma, tok::greater, tok::greatergreater,
                StopAtSemi | StopBeforeMatch);
    }
  }
  
  return Actions.ActOnTemplateTemplateParameter(getCurScope(), TemplateLoc,
                                                ParamList, EllipsisLoc, 
                                                ParamName, NameLoc, Depth, 
                                                Position, EqualLoc, DefaultArg);
}

/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
/// template parameters (e.g., in "template<int Size> class array;").
///
///       template-parameter:
///         ...
///         parameter-declaration
NamedDecl *
Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
  // Parse the declaration-specifiers (i.e., the type).
  // FIXME: The type should probably be restricted in some way... Not all
  // declarators (parts of declarators?) are accepted for parameters.
  DeclSpec DS(AttrFactory);
  ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
                             DeclSpecContext::DSC_template_param);

  // Parse this as a typename.
  Declarator ParamDecl(DS, DeclaratorContext::TemplateParamContext);
  ParseDeclarator(ParamDecl);
  if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) {
    Diag(Tok.getLocation(), diag::err_expected_template_parameter);
    return nullptr;
  }

  // Recover from misplaced ellipsis.
  SourceLocation EllipsisLoc;
  if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
    DiagnoseMisplacedEllipsisInDeclarator(EllipsisLoc, ParamDecl);

  // If there is a default value, parse it.
  // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
  // we introduce the template parameter into the local scope.
  SourceLocation EqualLoc;
  ExprResult DefaultArg;
  if (TryConsumeToken(tok::equal, EqualLoc)) {
    // C++ [temp.param]p15:
    //   When parsing a default template-argument for a non-type
    //   template-parameter, the first non-nested > is taken as the
    //   end of the template-parameter-list rather than a greater-than
    //   operator.
    GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
    EnterExpressionEvaluationContext ConstantEvaluated(
        Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);

    DefaultArg = Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
    if (DefaultArg.isInvalid())
      SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
  }

  // Create the parameter.
  return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl, 
                                               Depth, Position, EqualLoc, 
                                               DefaultArg.get());
}

void Parser::DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc,
                                       SourceLocation CorrectLoc,
                                       bool AlreadyHasEllipsis,
                                       bool IdentifierHasName) {
  FixItHint Insertion;
  if (!AlreadyHasEllipsis)
    Insertion = FixItHint::CreateInsertion(CorrectLoc, "...");
  Diag(EllipsisLoc, diag::err_misplaced_ellipsis_in_declaration)
      << FixItHint::CreateRemoval(EllipsisLoc) << Insertion
      << !IdentifierHasName;
}

void Parser::DiagnoseMisplacedEllipsisInDeclarator(SourceLocation EllipsisLoc,
                                                   Declarator &D) {
  assert(EllipsisLoc.isValid());
  bool AlreadyHasEllipsis = D.getEllipsisLoc().isValid();
  if (!AlreadyHasEllipsis)
    D.setEllipsisLoc(EllipsisLoc);
  DiagnoseMisplacedEllipsis(EllipsisLoc, D.getIdentifierLoc(),
                            AlreadyHasEllipsis, D.hasName());
}

/// Parses a '>' at the end of a template list.
///
/// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
/// to determine if these tokens were supposed to be a '>' followed by
/// '>', '>>', '>=', or '>='. It emits an appropriate diagnostic if necessary.
///
/// \param RAngleLoc the location of the consumed '>'.
///
/// \param ConsumeLastToken if true, the '>' is consumed.
///
/// \param ObjCGenericList if true, this is the '>' closing an Objective-C
/// type parameter or type argument list, rather than a C++ template parameter
/// or argument list.
///
/// \returns true, if current token does not start with '>', false otherwise.
bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
                                            bool ConsumeLastToken,
                                            bool ObjCGenericList) {
  // What will be left once we've consumed the '>'.
  tok::TokenKind RemainingToken;
  const char *ReplacementStr = "> >";
  bool MergeWithNextToken = false;

  switch (Tok.getKind()) {
  default:
    Diag(Tok.getLocation(), diag::err_expected) << tok::greater;
    return true;

  case tok::greater:
    // Determine the location of the '>' token. Only consume this token
    // if the caller asked us to.
    RAngleLoc = Tok.getLocation();
    if (ConsumeLastToken)
      ConsumeToken();
    return false;

  case tok::greatergreater:
    RemainingToken = tok::greater;
    break;

  case tok::greatergreatergreater:
    RemainingToken = tok::greatergreater;
    break;

  case tok::greaterequal:
    RemainingToken = tok::equal;
    ReplacementStr = "> =";

    // Join two adjacent '=' tokens into one, for cases like:
    //   void (*p)() = f<int>;
    //   return f<int>==p;
    if (NextToken().is(tok::equal) &&
        areTokensAdjacent(Tok, NextToken())) {
      RemainingToken = tok::equalequal;
      MergeWithNextToken = true;
    }
    break;

  case tok::greatergreaterequal:
    RemainingToken = tok::greaterequal;
    break;
  }

  // This template-id is terminated by a token that starts with a '>'.
  // Outside C++11 and Objective-C, this is now error recovery.
  //
  // C++11 allows this when the token is '>>', and in CUDA + C++11 mode, we
  // extend that treatment to also apply to the '>>>' token.
  //
  // Objective-C allows this in its type parameter / argument lists.

  SourceLocation TokBeforeGreaterLoc = PrevTokLocation;
  SourceLocation TokLoc = Tok.getLocation();
  Token Next = NextToken();

  // Whether splitting the current token after the '>' would undesirably result
  // in the remaining token pasting with the token after it. This excludes the
  // MergeWithNextToken cases, which we've already handled.
  bool PreventMergeWithNextToken =
      (RemainingToken == tok::greater ||
       RemainingToken == tok::greatergreater) &&
      (Next.isOneOf(tok::greater, tok::greatergreater,
                    tok::greatergreatergreater, tok::equal, tok::greaterequal,
                    tok::greatergreaterequal, tok::equalequal)) &&
      areTokensAdjacent(Tok, Next);

  // Diagnose this situation as appropriate.
  if (!ObjCGenericList) {
    // The source range of the replaced token(s).
    CharSourceRange ReplacementRange = CharSourceRange::getCharRange(
        TokLoc, Lexer::AdvanceToTokenCharacter(TokLoc, 2, PP.getSourceManager(),
                                               getLangOpts()));

    // A hint to put a space between the '>>'s. In order to make the hint as
    // clear as possible, we include the characters either side of the space in
    // the replacement, rather than just inserting a space at SecondCharLoc.
    FixItHint Hint1 = FixItHint::CreateReplacement(ReplacementRange,
                                                   ReplacementStr);

    // A hint to put another space after the token, if it would otherwise be
    // lexed differently.
    FixItHint Hint2;
    if (PreventMergeWithNextToken)
      Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");

    unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
    if (getLangOpts().CPlusPlus11 &&
        (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
      DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
    else if (Tok.is(tok::greaterequal))
      DiagId = diag::err_right_angle_bracket_equal_needs_space;
    Diag(TokLoc, DiagId) << Hint1 << Hint2;
  }

  // Find the "length" of the resulting '>' token. This is not always 1, as it
  // can contain escaped newlines.
  unsigned GreaterLength = Lexer::getTokenPrefixLength(
      TokLoc, 1, PP.getSourceManager(), getLangOpts());

  // Annotate the source buffer to indicate that we split the token after the
  // '>'. This allows us to properly find the end of, and extract the spelling
  // of, the '>' token later.
  RAngleLoc = PP.SplitToken(TokLoc, GreaterLength);

  // Strip the initial '>' from the token.
  bool CachingTokens = PP.IsPreviousCachedToken(Tok);

  Token Greater = Tok;
  Greater.setLocation(RAngleLoc);
  Greater.setKind(tok::greater);
  Greater.setLength(GreaterLength);

  unsigned OldLength = Tok.getLength();
  if (MergeWithNextToken) {
    ConsumeToken();
    OldLength += Tok.getLength();
  }

  Tok.setKind(RemainingToken);
  Tok.setLength(OldLength - GreaterLength);

  // Split the second token if lexing it normally would lex a different token
  // (eg, the fifth token in 'A<B>>>' should re-lex as '>', not '>>').
  SourceLocation AfterGreaterLoc = TokLoc.getLocWithOffset(GreaterLength);
  if (PreventMergeWithNextToken)
    AfterGreaterLoc = PP.SplitToken(AfterGreaterLoc, Tok.getLength());
  Tok.setLocation(AfterGreaterLoc);

  // Update the token cache to match what we just did if necessary.
  if (CachingTokens) {
    // If the previous cached token is being merged, delete it.
    if (MergeWithNextToken)
      PP.ReplacePreviousCachedToken({});

    if (ConsumeLastToken)
      PP.ReplacePreviousCachedToken({Greater, Tok});
    else
      PP.ReplacePreviousCachedToken({Greater});
  }

  if (ConsumeLastToken) {
    PrevTokLocation = RAngleLoc;
  } else {
    PrevTokLocation = TokBeforeGreaterLoc;
    PP.EnterToken(Tok);
    Tok = Greater;
  }

  return false;
}


/// Parses a template-id that after the template name has
/// already been parsed.
///
/// This routine takes care of parsing the enclosed template argument
/// list ('<' template-parameter-list [opt] '>') and placing the
/// results into a form that can be transferred to semantic analysis.
///
/// \param ConsumeLastToken if true, then we will consume the last
/// token that forms the template-id. Otherwise, we will leave the
/// last token in the stream (e.g., so that it can be replaced with an
/// annotation token).
bool
Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
                                         SourceLocation &LAngleLoc,
                                         TemplateArgList &TemplateArgs,
                                         SourceLocation &RAngleLoc) {
  assert(Tok.is(tok::less) && "Must have already parsed the template-name");

  // Consume the '<'.
  LAngleLoc = ConsumeToken();

  // Parse the optional template-argument-list.
  bool Invalid = false;
  {
    GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
    if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater))
      Invalid = ParseTemplateArgumentList(TemplateArgs);

    if (Invalid) {
      // Try to find the closing '>'.
      if (ConsumeLastToken)
        SkipUntil(tok::greater, StopAtSemi);
      else
        SkipUntil(tok::greater, StopAtSemi | StopBeforeMatch);
      return true;
    }
  }

  return ParseGreaterThanInTemplateList(RAngleLoc, ConsumeLastToken,
                                        /*ObjCGenericList=*/false);
}

/// Replace the tokens that form a simple-template-id with an
/// annotation token containing the complete template-id.
///
/// The first token in the stream must be the name of a template that
/// is followed by a '<'. This routine will parse the complete
/// simple-template-id and replace the tokens with a single annotation
/// token with one of two different kinds: if the template-id names a
/// type (and \p AllowTypeAnnotation is true), the annotation token is
/// a type annotation that includes the optional nested-name-specifier
/// (\p SS). Otherwise, the annotation token is a template-id
/// annotation that does not include the optional
/// nested-name-specifier.
///
/// \param Template  the declaration of the template named by the first
/// token (an identifier), as returned from \c Action::isTemplateName().
///
/// \param TNK the kind of template that \p Template
/// refers to, as returned from \c Action::isTemplateName().
///
/// \param SS if non-NULL, the nested-name-specifier that precedes
/// this template name.
///
/// \param TemplateKWLoc if valid, specifies that this template-id
/// annotation was preceded by the 'template' keyword and gives the
/// location of that keyword. If invalid (the default), then this
/// template-id was not preceded by a 'template' keyword.
///
/// \param AllowTypeAnnotation if true (the default), then a
/// simple-template-id that refers to a class template, template
/// template parameter, or other template that produces a type will be
/// replaced with a type annotation token. Otherwise, the
/// simple-template-id is always replaced with a template-id
/// annotation token.
///
/// If an unrecoverable parse error occurs and no annotation token can be
/// formed, this function returns true.
///
bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                     CXXScopeSpec &SS,
                                     SourceLocation TemplateKWLoc,
                                     UnqualifiedId &TemplateName,
                                     bool AllowTypeAnnotation) {
  assert(getLangOpts().CPlusPlus && "Can only annotate template-ids in C++");
  assert(Template && Tok.is(tok::less) &&
         "Parser isn't at the beginning of a template-id");

  // Consume the template-name.
  SourceLocation TemplateNameLoc = TemplateName.getSourceRange().getBegin();

  // Parse the enclosed template argument list.
  SourceLocation LAngleLoc, RAngleLoc;
  TemplateArgList TemplateArgs;
  bool Invalid = ParseTemplateIdAfterTemplateName(false, LAngleLoc,
                                                  TemplateArgs,
                                                  RAngleLoc);

  if (Invalid) {
    // If we failed to parse the template ID but skipped ahead to a >, we're not
    // going to be able to form a token annotation.  Eat the '>' if present.
    TryConsumeToken(tok::greater);
    return true;
  }

  ASTTemplateArgsPtr TemplateArgsPtr(TemplateArgs);

  // Build the annotation token.
  if (TNK == TNK_Type_template && AllowTypeAnnotation) {
    TypeResult Type = Actions.ActOnTemplateIdType(
        SS, TemplateKWLoc, Template, TemplateName.Identifier,
        TemplateNameLoc, LAngleLoc, TemplateArgsPtr, RAngleLoc);
    if (Type.isInvalid()) {
      // If we failed to parse the template ID but skipped ahead to a >, we're
      // not going to be able to form a token annotation.  Eat the '>' if
      // present.
      TryConsumeToken(tok::greater);
      return true;
    }

    Tok.setKind(tok::annot_typename);
    setTypeAnnotation(Tok, Type.get());
    if (SS.isNotEmpty())
      Tok.setLocation(SS.getBeginLoc());
    else if (TemplateKWLoc.isValid())
      Tok.setLocation(TemplateKWLoc);
    else
      Tok.setLocation(TemplateNameLoc);
  } else {
    // Build a template-id annotation token that can be processed
    // later.
    Tok.setKind(tok::annot_template_id);
    
    IdentifierInfo *TemplateII =
        TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
            ? TemplateName.Identifier
            : nullptr;

    OverloadedOperatorKind OpKind =
        TemplateName.getKind() == UnqualifiedIdKind::IK_Identifier
            ? OO_None
            : TemplateName.OperatorFunctionId.Operator;

    TemplateIdAnnotation *TemplateId = TemplateIdAnnotation::Create(
      SS, TemplateKWLoc, TemplateNameLoc, TemplateII, OpKind, Template, TNK,
      LAngleLoc, RAngleLoc, TemplateArgs, TemplateIds);
    
    Tok.setAnnotationValue(TemplateId);
    if (TemplateKWLoc.isValid())
      Tok.setLocation(TemplateKWLoc);
    else
      Tok.setLocation(TemplateNameLoc);
  }

  // Common fields for the annotation token
  Tok.setAnnotationEndLoc(RAngleLoc);

  // In case the tokens were cached, have Preprocessor replace them with the
  // annotation token.
  PP.AnnotateCachedTokens(Tok);
  return false;
}

/// Replaces a template-id annotation token with a type
/// annotation token.
///
/// If there was a failure when forming the type from the template-id,
/// a type annotation token will still be created, but will have a
/// NULL type pointer to signify an error.
///
/// \param IsClassName Is this template-id appearing in a context where we
/// know it names a class, such as in an elaborated-type-specifier or
/// base-specifier? ('typename' and 'template' are unneeded and disallowed
/// in those contexts.)
void Parser::AnnotateTemplateIdTokenAsType(bool IsClassName) {
  assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");

  TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
  assert((TemplateId->Kind == TNK_Type_template ||
          TemplateId->Kind == TNK_Dependent_template_name) &&
         "Only works for type and dependent templates");

  ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
                                     TemplateId->NumArgs);

  TypeResult Type
    = Actions.ActOnTemplateIdType(TemplateId->SS,
                                  TemplateId->TemplateKWLoc,
                                  TemplateId->Template,
                                  TemplateId->Name,
                                  TemplateId->TemplateNameLoc,
                                  TemplateId->LAngleLoc,
                                  TemplateArgsPtr,
                                  TemplateId->RAngleLoc,
                                  /*IsCtorOrDtorName*/false,
                                  IsClassName);
  // Create the new "type" annotation token.
  Tok.setKind(tok::annot_typename);
  setTypeAnnotation(Tok, Type.isInvalid() ? nullptr : Type.get());
  if (TemplateId->SS.isNotEmpty()) // it was a C++ qualified type name.
    Tok.setLocation(TemplateId->SS.getBeginLoc());
  // End location stays the same

  // Replace the template-id annotation token, and possible the scope-specifier
  // that precedes it, with the typename annotation token.
  PP.AnnotateCachedTokens(Tok);
}

/// Determine whether the given token can end a template argument.
static bool isEndOfTemplateArgument(Token Tok) {
  return Tok.isOneOf(tok::comma, tok::greater, tok::greatergreater);
}

/// Parse a C++ template template argument.
ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
  if (!Tok.is(tok::identifier) && !Tok.is(tok::coloncolon) &&
      !Tok.is(tok::annot_cxxscope))
    return ParsedTemplateArgument();

  // C++0x [temp.arg.template]p1:
  //   A template-argument for a template template-parameter shall be the name
  //   of a class template or an alias template, expressed as id-expression.
  //   
  // We parse an id-expression that refers to a class template or alias
  // template. The grammar we parse is:
  //
  //   nested-name-specifier[opt] template[opt] identifier ...[opt]
  //
  // followed by a token that terminates a template argument, such as ',', 
  // '>', or (in some cases) '>>'.
  CXXScopeSpec SS; // nested-name-specifier, if present
  ParseOptionalCXXScopeSpecifier(SS, nullptr,
                                 /*EnteringContext=*/false);

  ParsedTemplateArgument Result;
  SourceLocation EllipsisLoc;
  if (SS.isSet() && Tok.is(tok::kw_template)) {
    // Parse the optional 'template' keyword following the 
    // nested-name-specifier.
    SourceLocation TemplateKWLoc = ConsumeToken();
    
    if (Tok.is(tok::identifier)) {
      // We appear to have a dependent template name.
      UnqualifiedId Name;
      Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
      ConsumeToken(); // the identifier

      TryConsumeToken(tok::ellipsis, EllipsisLoc);

      // If the next token signals the end of a template argument,
      // then we have a dependent template name that could be a template
      // template argument.
      TemplateTy Template;
      if (isEndOfTemplateArgument(Tok) &&
          Actions.ActOnDependentTemplateName(
              getCurScope(), SS, TemplateKWLoc, Name,
              /*ObjectType=*/nullptr,
              /*EnteringContext=*/false, Template))
        Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
    }
  } else if (Tok.is(tok::identifier)) {
    // We may have a (non-dependent) template name.
    TemplateTy Template;
    UnqualifiedId Name;
    Name.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
    ConsumeToken(); // the identifier

    TryConsumeToken(tok::ellipsis, EllipsisLoc);

    if (isEndOfTemplateArgument(Tok)) {
      bool MemberOfUnknownSpecialization;
      TemplateNameKind TNK = Actions.isTemplateName(
          getCurScope(), SS,
          /*hasTemplateKeyword=*/false, Name,
          /*ObjectType=*/nullptr,
          /*EnteringContext=*/false, Template, MemberOfUnknownSpecialization);
      if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
        // We have an id-expression that refers to a class template or
        // (C++0x) alias template. 
        Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
      }
    }
  }
  
  // If this is a pack expansion, build it as such.
  if (EllipsisLoc.isValid() && !Result.isInvalid())
    Result = Actions.ActOnPackExpansion(Result, EllipsisLoc);
  
  return Result;
}

/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
///
///       template-argument: [C++ 14.2]
///         constant-expression
///         type-id
///         id-expression
ParsedTemplateArgument Parser::ParseTemplateArgument() {
  // C++ [temp.arg]p2:
  //   In a template-argument, an ambiguity between a type-id and an
  //   expression is resolved to a type-id, regardless of the form of
  //   the corresponding template-parameter.
  //
  // Therefore, we initially try to parse a type-id - and isCXXTypeId might look
  // up and annotate an identifier as an id-expression during disambiguation,
  // so enter the appropriate context for a constant expression template
  // argument before trying to disambiguate.

  EnterExpressionEvaluationContext EnterConstantEvaluated(
    Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated,
    /*LambdaContextDecl=*/nullptr,
    /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
  if (isCXXTypeId(TypeIdAsTemplateArgument)) {
    TypeResult TypeArg = ParseTypeName(
        /*Range=*/nullptr, DeclaratorContext::TemplateArgContext);
    return Actions.ActOnTemplateTypeArgument(TypeArg);
  }
  
  // Try to parse a template template argument.
  {
    TentativeParsingAction TPA(*this);

    ParsedTemplateArgument TemplateTemplateArgument
      = ParseTemplateTemplateArgument();
    if (!TemplateTemplateArgument.isInvalid()) {
      TPA.Commit();
      return TemplateTemplateArgument;
    }
    
    // Revert this tentative parse to parse a non-type template argument.
    TPA.Revert();
  }
  
  // Parse a non-type template argument. 
  SourceLocation Loc = Tok.getLocation();
  ExprResult ExprArg = ParseConstantExpressionInExprEvalContext(MaybeTypeCast);
  if (ExprArg.isInvalid() || !ExprArg.get())
    return ParsedTemplateArgument();

  return ParsedTemplateArgument(ParsedTemplateArgument::NonType, 
                                ExprArg.get(), Loc);
}

/// Determine whether the current tokens can only be parsed as a 
/// template argument list (starting with the '<') and never as a '<' 
/// expression.
bool Parser::IsTemplateArgumentList(unsigned Skip) {
  struct AlwaysRevertAction : TentativeParsingAction {
    AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { }
    ~AlwaysRevertAction() { Revert(); }
  } Tentative(*this);
  
  while (Skip) {
    ConsumeAnyToken();
    --Skip;
  }
  
  // '<'
  if (!TryConsumeToken(tok::less))
    return false;

  // An empty template argument list.
  if (Tok.is(tok::greater))
    return true;
  
  // See whether we have declaration specifiers, which indicate a type.
  while (isCXXDeclarationSpecifier() == TPResult::True)
    ConsumeAnyToken();
  
  // If we have a '>' or a ',' then this is a template argument list.
  return Tok.isOneOf(tok::greater, tok::comma);
}

/// ParseTemplateArgumentList - Parse a C++ template-argument-list
/// (C++ [temp.names]). Returns true if there was an error.
///
///       template-argument-list: [C++ 14.2]
///         template-argument
///         template-argument-list ',' template-argument
bool
Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) {
  
  ColonProtectionRAIIObject ColonProtection(*this, false);

  do {
    ParsedTemplateArgument Arg = ParseTemplateArgument();
    SourceLocation EllipsisLoc;
    if (TryConsumeToken(tok::ellipsis, EllipsisLoc))
      Arg = Actions.ActOnPackExpansion(Arg, EllipsisLoc);

    if (Arg.isInvalid()) {
      SkipUntil(tok::comma, tok::greater, StopAtSemi | StopBeforeMatch);
      return true;
    }

    // Save this template argument.
    TemplateArgs.push_back(Arg);
      
    // If the next token is a comma, consume it and keep reading
    // arguments.
  } while (TryConsumeToken(tok::comma));

  return false;
}

/// Parse a C++ explicit template instantiation
/// (C++ [temp.explicit]).
///
///       explicit-instantiation:
///         'extern' [opt] 'template' declaration
///
/// Note that the 'extern' is a GNU extension and C++11 feature.
Decl *Parser::ParseExplicitInstantiation(DeclaratorContext Context,
                                         SourceLocation ExternLoc,
                                         SourceLocation TemplateLoc,
                                         SourceLocation &DeclEnd,
                                         ParsedAttributes &AccessAttrs,
                                         AccessSpecifier AS) {
  // This isn't really required here.
  ParsingDeclRAIIObject
    ParsingTemplateParams(*this, ParsingDeclRAIIObject::NoParent);

  return ParseSingleDeclarationAfterTemplate(
      Context, ParsedTemplateInfo(ExternLoc, TemplateLoc),
      ParsingTemplateParams, DeclEnd, AccessAttrs, AS);
}

SourceRange Parser::ParsedTemplateInfo::getSourceRange() const {
  if (TemplateParams)
    return getTemplateParamsRange(TemplateParams->data(),
                                  TemplateParams->size());

  SourceRange R(TemplateLoc);
  if (ExternLoc.isValid())
    R.setBegin(ExternLoc);
  return R;
}

void Parser::LateTemplateParserCallback(void *P, LateParsedTemplate &LPT) {
  ((Parser *)P)->ParseLateTemplatedFuncDef(LPT);
}

/// Late parse a C++ function template in Microsoft mode.
void Parser::ParseLateTemplatedFuncDef(LateParsedTemplate &LPT) {
  if (!LPT.D)
     return;

  // Get the FunctionDecl.
  FunctionDecl *FunD = LPT.D->getAsFunction();
  // Track template parameter depth.
  TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);

  // To restore the context after late parsing.
  Sema::ContextRAII GlobalSavedContext(
      Actions, Actions.Context.getTranslationUnitDecl());

  SmallVector<ParseScope*, 4> TemplateParamScopeStack;

  // Get the list of DeclContexts to reenter.
  SmallVector<DeclContext*, 4> DeclContextsToReenter;
  DeclContext *DD = FunD;
  while (DD && !DD->isTranslationUnit()) {
    DeclContextsToReenter.push_back(DD);
    DD = DD->getLexicalParent();
  }

  // Reenter template scopes from outermost to innermost.
  SmallVectorImpl<DeclContext *>::reverse_iterator II =
      DeclContextsToReenter.rbegin();
  for (; II != DeclContextsToReenter.rend(); ++II) {
    TemplateParamScopeStack.push_back(new ParseScope(this,
          Scope::TemplateParamScope));
    unsigned NumParamLists =
      Actions.ActOnReenterTemplateScope(getCurScope(), cast<Decl>(*II));
    CurTemplateDepthTracker.addDepth(NumParamLists);
    if (*II != FunD) {
      TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
      Actions.PushDeclContext(Actions.getCurScope(), *II);
    }
  }

  assert(!LPT.Toks.empty() && "Empty body!");

  // Append the current token at the end of the new token stream so that it
  // doesn't get lost.
  LPT.Toks.push_back(Tok);
  PP.EnterTokenStream(LPT.Toks, true);

  // Consume the previously pushed token.
  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
  assert(Tok.isOneOf(tok::l_brace, tok::colon, tok::kw_try) &&
         "Inline method not starting with '{', ':' or 'try'");

  // Parse the method body. Function body parsing code is similar enough
  // to be re-used for method bodies as well.
  ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope |
                               Scope::CompoundStmtScope);

  // Recreate the containing function DeclContext.
  Sema::ContextRAII FunctionSavedContext(Actions,
                                         Actions.getContainingDC(FunD));

  Actions.ActOnStartOfFunctionDef(getCurScope(), FunD);

  if (Tok.is(tok::kw_try)) {
    ParseFunctionTryBlock(LPT.D, FnScope);
  } else {
    if (Tok.is(tok::colon))
      ParseConstructorInitializer(LPT.D);
    else
      Actions.ActOnDefaultCtorInitializers(LPT.D);

    if (Tok.is(tok::l_brace)) {
      assert((!isa<FunctionTemplateDecl>(LPT.D) ||
              cast<FunctionTemplateDecl>(LPT.D)
                      ->getTemplateParameters()
                      ->getDepth() == TemplateParameterDepth - 1) &&
             "TemplateParameterDepth should be greater than the depth of "
             "current template being instantiated!");
      ParseFunctionStatementBody(LPT.D, FnScope);
      Actions.UnmarkAsLateParsedTemplate(FunD);
    } else
      Actions.ActOnFinishFunctionBody(LPT.D, nullptr);
  }

  // Exit scopes.
  FnScope.Exit();
  SmallVectorImpl<ParseScope *>::reverse_iterator I =
   TemplateParamScopeStack.rbegin();
  for (; I != TemplateParamScopeStack.rend(); ++I)
    delete *I;
}

/// Lex a delayed template function for late parsing.
void Parser::LexTemplateFunctionForLateParsing(CachedTokens &Toks) {
  tok::TokenKind kind = Tok.getKind();
  if (!ConsumeAndStoreFunctionPrologue(Toks)) {
    // Consume everything up to (and including) the matching right brace.
    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
  }

  // If we're in a function-try-block, we need to store all the catch blocks.
  if (kind == tok::kw_try) {
    while (Tok.is(tok::kw_catch)) {
      ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
      ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
    }
  }
}

/// We've parsed something that could plausibly be intended to be a template
/// name (\p LHS) followed by a '<' token, and the following code can't possibly
/// be an expression. Determine if this is likely to be a template-id and if so,
/// diagnose it.
bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
  TentativeParsingAction TPA(*this);
  // FIXME: We could look at the token sequence in a lot more detail here.
  if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
                StopAtSemi | StopBeforeMatch)) {
    TPA.Commit();

    SourceLocation Greater;
    ParseGreaterThanInTemplateList(Greater, true, false);
    Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,
                                               Less, Greater);
    return true;
  }

  // There's no matching '>' token, this probably isn't supposed to be
  // interpreted as a template-id. Parse it as an (ill-formed) comparison.
  TPA.Revert();
  return false;
}

void Parser::checkPotentialAngleBracket(ExprResult &PotentialTemplateName) {
  assert(Tok.is(tok::less) && "not at a potential angle bracket");

  bool DependentTemplateName = false;
  if (!Actions.mightBeIntendedToBeTemplateName(PotentialTemplateName,
                                               DependentTemplateName))
    return;

  // OK, this might be a name that the user intended to be parsed as a
  // template-name, followed by a '<' token. Check for some easy cases.

  // If we have potential_template<>, then it's supposed to be a template-name.
  if (NextToken().is(tok::greater) ||
      (getLangOpts().CPlusPlus11 &&
       NextToken().isOneOf(tok::greatergreater, tok::greatergreatergreater))) {
    SourceLocation Less = ConsumeToken();
    SourceLocation Greater;
    ParseGreaterThanInTemplateList(Greater, true, false);
    Actions.diagnoseExprIntendedAsTemplateName(
        getCurScope(), PotentialTemplateName, Less, Greater);
    // FIXME: Perform error recovery.
    PotentialTemplateName = ExprError();
    return;
  }

  // If we have 'potential_template<type-id', assume it's supposed to be a
  // template-name if there's a matching '>' later on.
  {
    // FIXME: Avoid the tentative parse when NextToken() can't begin a type.
    TentativeParsingAction TPA(*this);
    SourceLocation Less = ConsumeToken();
    if (isTypeIdUnambiguously() &&
        diagnoseUnknownTemplateId(PotentialTemplateName, Less)) {
      TPA.Commit();
      // FIXME: Perform error recovery.
      PotentialTemplateName = ExprError();
      return;
    }
    TPA.Revert();
  }

  // Otherwise, remember that we saw this in case we see a potentially-matching
  // '>' token later on.
  AngleBracketTracker::Priority Priority =
      (DependentTemplateName ? AngleBracketTracker::DependentName
                             : AngleBracketTracker::PotentialTypo) |
      (Tok.hasLeadingSpace() ? AngleBracketTracker::SpaceBeforeLess
                             : AngleBracketTracker::NoSpaceBeforeLess);
  AngleBrackets.add(*this, PotentialTemplateName.get(), Tok.getLocation(),
                    Priority);
}

bool Parser::checkPotentialAngleBracketDelimiter(
    const AngleBracketTracker::Loc &LAngle, const Token &OpToken) {
  // If a comma in an expression context is followed by a type that can be a
  // template argument and cannot be an expression, then this is ill-formed,
  // but might be intended to be part of a template-id.
  if (OpToken.is(tok::comma) && isTypeIdUnambiguously() &&
      diagnoseUnknownTemplateId(LAngle.TemplateName, LAngle.LessLoc)) {
    AngleBrackets.clear(*this);
    return true;
  }

  // If a context that looks like a template-id is followed by '()', then
  // this is ill-formed, but might be intended to be a template-id
  // followed by '()'.
  if (OpToken.is(tok::greater) && Tok.is(tok::l_paren) &&
      NextToken().is(tok::r_paren)) {
    Actions.diagnoseExprIntendedAsTemplateName(
        getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
        OpToken.getLocation());
    AngleBrackets.clear(*this);
    return true;
  }

  // After a '>' (etc), we're no longer potentially in a construct that's
  // intended to be treated as a template-id.
  if (OpToken.is(tok::greater) ||
      (getLangOpts().CPlusPlus11 &&
       OpToken.isOneOf(tok::greatergreater, tok::greatergreatergreater)))
    AngleBrackets.clear(*this);
  return false;
}