| 12
 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
 1573
 1574
 1575
 1576
 1577
 1578
 1579
 1580
 1581
 1582
 1583
 1584
 1585
 1586
 1587
 1588
 1589
 1590
 1591
 1592
 1593
 1594
 1595
 1596
 1597
 1598
 1599
 1600
 1601
 1602
 1603
 1604
 1605
 1606
 1607
 1608
 1609
 1610
 1611
 1612
 1613
 1614
 1615
 1616
 1617
 1618
 1619
 1620
 1621
 1622
 1623
 1624
 1625
 1626
 1627
 1628
 1629
 1630
 1631
 1632
 1633
 1634
 1635
 1636
 1637
 1638
 1639
 1640
 1641
 1642
 1643
 1644
 1645
 1646
 1647
 1648
 1649
 1650
 1651
 1652
 1653
 1654
 1655
 1656
 1657
 1658
 1659
 1660
 1661
 1662
 1663
 1664
 1665
 1666
 1667
 1668
 1669
 1670
 1671
 1672
 1673
 1674
 1675
 1676
 1677
 1678
 1679
 1680
 1681
 1682
 1683
 1684
 1685
 1686
 1687
 1688
 1689
 1690
 1691
 1692
 1693
 1694
 1695
 1696
 1697
 1698
 1699
 1700
 1701
 1702
 1703
 1704
 1705
 1706
 1707
 1708
 1709
 1710
 1711
 1712
 1713
 1714
 1715
 1716
 1717
 1718
 1719
 1720
 1721
 1722
 1723
 1724
 1725
 1726
 1727
 1728
 1729
 1730
 1731
 1732
 1733
 1734
 1735
 1736
 1737
 1738
 1739
 1740
 1741
 1742
 1743
 1744
 1745
 1746
 1747
 1748
 1749
 1750
 1751
 1752
 1753
 1754
 1755
 1756
 1757
 1758
 1759
 1760
 1761
 1762
 1763
 1764
 1765
 1766
 1767
 1768
 1769
 1770
 1771
 1772
 1773
 1774
 1775
 1776
 1777
 1778
 1779
 1780
 1781
 1782
 1783
 1784
 1785
 1786
 1787
 1788
 1789
 1790
 1791
 1792
 1793
 1794
 1795
 1796
 1797
 1798
 1799
 1800
 1801
 1802
 1803
 1804
 1805
 1806
 1807
 1808
 1809
 1810
 1811
 1812
 1813
 1814
 1815
 1816
 1817
 1818
 1819
 1820
 1821
 1822
 1823
 1824
 1825
 1826
 1827
 1828
 1829
 1830
 1831
 1832
 1833
 1834
 1835
 1836
 1837
 1838
 1839
 1840
 1841
 1842
 1843
 1844
 1845
 1846
 1847
 1848
 1849
 1850
 1851
 1852
 1853
 1854
 1855
 1856
 1857
 1858
 1859
 1860
 1861
 1862
 1863
 1864
 1865
 1866
 1867
 1868
 1869
 1870
 1871
 1872
 1873
 1874
 1875
 1876
 1877
 1878
 1879
 1880
 1881
 1882
 1883
 1884
 1885
 1886
 1887
 1888
 1889
 1890
 1891
 1892
 1893
 1894
 1895
 1896
 1897
 1898
 1899
 1900
 1901
 1902
 1903
 1904
 1905
 1906
 1907
 1908
 1909
 1910
 1911
 1912
 1913
 1914
 1915
 1916
 1917
 1918
 1919
 1920
 1921
 1922
 1923
 1924
 1925
 1926
 1927
 1928
 1929
 1930
 1931
 1932
 1933
 1934
 1935
 1936
 1937
 1938
 1939
 1940
 1941
 1942
 1943
 1944
 1945
 1946
 1947
 1948
 1949
 1950
 1951
 1952
 1953
 1954
 1955
 1956
 1957
 1958
 1959
 1960
 1961
 1962
 1963
 1964
 1965
 1966
 1967
 1968
 1969
 1970
 1971
 1972
 1973
 1974
 1975
 1976
 1977
 1978
 1979
 1980
 1981
 1982
 1983
 1984
 1985
 1986
 1987
 1988
 1989
 1990
 1991
 1992
 1993
 1994
 1995
 1996
 1997
 1998
 1999
 2000
 2001
 2002
 2003
 2004
 2005
 2006
 2007
 2008
 2009
 2010
 2011
 2012
 2013
 2014
 2015
 2016
 2017
 2018
 2019
 2020
 2021
 2022
 2023
 2024
 2025
 2026
 2027
 2028
 2029
 2030
 2031
 2032
 2033
 2034
 2035
 2036
 2037
 2038
 2039
 2040
 2041
 2042
 2043
 2044
 2045
 2046
 2047
 2048
 2049
 2050
 2051
 2052
 2053
 2054
 2055
 2056
 2057
 2058
 2059
 2060
 2061
 2062
 2063
 2064
 2065
 2066
 2067
 2068
 2069
 2070
 2071
 2072
 2073
 2074
 2075
 2076
 2077
 2078
 2079
 2080
 2081
 2082
 2083
 2084
 2085
 2086
 2087
 2088
 2089
 2090
 2091
 2092
 2093
 2094
 2095
 2096
 2097
 2098
 2099
 2100
 2101
 2102
 2103
 2104
 2105
 2106
 2107
 2108
 2109
 2110
 2111
 2112
 2113
 2114
 2115
 2116
 2117
 2118
 2119
 2120
 2121
 2122
 2123
 2124
 2125
 2126
 2127
 2128
 2129
 2130
 2131
 2132
 2133
 2134
 2135
 2136
 2137
 2138
 2139
 2140
 2141
 2142
 2143
 2144
 2145
 2146
 2147
 2148
 2149
 2150
 2151
 2152
 2153
 2154
 2155
 2156
 2157
 2158
 2159
 2160
 2161
 2162
 2163
 2164
 2165
 2166
 2167
 2168
 2169
 2170
 2171
 2172
 2173
 2174
 2175
 2176
 2177
 2178
 2179
 2180
 2181
 2182
 2183
 2184
 2185
 2186
 2187
 2188
 2189
 2190
 2191
 2192
 2193
 2194
 2195
 2196
 2197
 2198
 2199
 2200
 2201
 2202
 2203
 2204
 2205
 2206
 2207
 2208
 2209
 2210
 2211
 2212
 2213
 2214
 2215
 2216
 2217
 2218
 2219
 2220
 2221
 2222
 2223
 2224
 2225
 2226
 2227
 2228
 2229
 2230
 2231
 2232
 2233
 2234
 2235
 2236
 2237
 2238
 2239
 2240
 2241
 2242
 2243
 2244
 2245
 2246
 2247
 2248
 2249
 2250
 2251
 2252
 2253
 2254
 2255
 2256
 2257
 2258
 2259
 2260
 2261
 2262
 2263
 2264
 2265
 2266
 2267
 2268
 2269
 2270
 2271
 2272
 2273
 2274
 2275
 2276
 2277
 2278
 2279
 2280
 2281
 2282
 2283
 2284
 2285
 2286
 2287
 2288
 2289
 2290
 2291
 2292
 2293
 2294
 2295
 2296
 2297
 2298
 2299
 2300
 2301
 2302
 2303
 2304
 2305
 2306
 2307
 2308
 2309
 2310
 2311
 2312
 2313
 2314
 2315
 2316
 2317
 2318
 2319
 2320
 2321
 2322
 2323
 2324
 2325
 2326
 2327
 2328
 2329
 2330
 2331
 2332
 2333
 2334
 2335
 2336
 2337
 2338
 2339
 2340
 2341
 2342
 2343
 2344
 2345
 2346
 2347
 2348
 2349
 2350
 2351
 2352
 2353
 2354
 2355
 2356
 2357
 2358
 2359
 2360
 2361
 2362
 2363
 2364
 2365
 2366
 2367
 2368
 2369
 2370
 2371
 2372
 2373
 2374
 2375
 2376
 2377
 2378
 2379
 2380
 2381
 2382
 2383
 2384
 2385
 2386
 2387
 2388
 2389
 2390
 2391
 2392
 2393
 2394
 2395
 2396
 2397
 2398
 2399
 2400
 2401
 2402
 2403
 2404
 2405
 2406
 2407
 2408
 2409
 2410
 2411
 2412
 2413
 2414
 2415
 2416
 2417
 2418
 2419
 2420
 2421
 2422
 2423
 2424
 2425
 2426
 2427
 2428
 2429
 2430
 2431
 2432
 2433
 2434
 2435
 2436
 2437
 2438
 2439
 2440
 2441
 2442
 2443
 2444
 2445
 2446
 2447
 2448
 2449
 2450
 2451
 2452
 2453
 2454
 2455
 2456
 2457
 2458
 2459
 2460
 2461
 2462
 2463
 2464
 2465
 2466
 2467
 2468
 2469
 2470
 2471
 2472
 2473
 2474
 2475
 2476
 2477
 2478
 2479
 2480
 2481
 2482
 2483
 2484
 2485
 2486
 2487
 2488
 2489
 2490
 2491
 2492
 2493
 2494
 2495
 2496
 2497
 2498
 2499
 2500
 2501
 2502
 2503
 2504
 2505
 2506
 2507
 2508
 2509
 2510
 2511
 2512
 2513
 2514
 2515
 2516
 2517
 2518
 2519
 2520
 2521
 2522
 2523
 2524
 2525
 2526
 2527
 2528
 2529
 2530
 2531
 2532
 2533
 2534
 2535
 2536
 2537
 2538
 2539
 2540
 2541
 2542
 2543
 2544
 2545
 2546
 2547
 2548
 2549
 2550
 2551
 2552
 2553
 2554
 2555
 2556
 2557
 2558
 2559
 2560
 2561
 2562
 2563
 2564
 2565
 2566
 2567
 2568
 2569
 2570
 2571
 2572
 2573
 2574
 2575
 2576
 2577
 2578
 2579
 2580
 2581
 2582
 2583
 2584
 2585
 2586
 2587
 2588
 2589
 2590
 2591
 2592
 2593
 2594
 2595
 2596
 2597
 2598
 2599
 2600
 2601
 2602
 2603
 2604
 2605
 2606
 2607
 2608
 2609
 2610
 2611
 2612
 2613
 2614
 2615
 2616
 2617
 2618
 2619
 2620
 2621
 2622
 2623
 2624
 2625
 2626
 2627
 2628
 2629
 2630
 2631
 2632
 2633
 2634
 2635
 2636
 2637
 2638
 2639
 2640
 2641
 2642
 2643
 2644
 2645
 2646
 2647
 2648
 2649
 2650
 2651
 2652
 2653
 2654
 2655
 2656
 2657
 2658
 2659
 2660
 2661
 2662
 2663
 2664
 2665
 2666
 2667
 2668
 2669
 2670
 2671
 2672
 2673
 2674
 2675
 2676
 2677
 2678
 2679
 2680
 2681
 2682
 2683
 2684
 2685
 2686
 2687
 2688
 2689
 2690
 2691
 2692
 2693
 2694
 2695
 2696
 2697
 2698
 2699
 2700
 2701
 2702
 2703
 2704
 2705
 2706
 2707
 2708
 2709
 2710
 2711
 2712
 2713
 2714
 2715
 2716
 2717
 2718
 2719
 2720
 2721
 2722
 2723
 2724
 2725
 2726
 2727
 2728
 2729
 2730
 2731
 2732
 2733
 2734
 2735
 2736
 2737
 2738
 2739
 2740
 2741
 2742
 2743
 2744
 2745
 2746
 2747
 2748
 2749
 2750
 2751
 2752
 2753
 2754
 2755
 2756
 2757
 2758
 2759
 2760
 2761
 2762
 2763
 2764
 2765
 2766
 2767
 2768
 2769
 2770
 2771
 2772
 2773
 2774
 2775
 2776
 2777
 2778
 2779
 2780
 2781
 2782
 2783
 2784
 2785
 2786
 2787
 2788
 2789
 2790
 2791
 2792
 2793
 2794
 2795
 2796
 2797
 2798
 2799
 2800
 2801
 2802
 2803
 2804
 2805
 2806
 2807
 2808
 2809
 2810
 2811
 2812
 2813
 2814
 2815
 2816
 2817
 2818
 2819
 2820
 2821
 2822
 2823
 2824
 2825
 2826
 2827
 2828
 2829
 2830
 2831
 2832
 2833
 2834
 2835
 2836
 2837
 2838
 2839
 2840
 2841
 2842
 2843
 2844
 2845
 2846
 2847
 2848
 2849
 2850
 2851
 2852
 2853
 2854
 2855
 2856
 2857
 2858
 2859
 2860
 2861
 2862
 2863
 2864
 2865
 2866
 2867
 2868
 2869
 2870
 2871
 2872
 2873
 2874
 2875
 2876
 2877
 2878
 2879
 2880
 2881
 2882
 2883
 2884
 2885
 2886
 2887
 2888
 2889
 2890
 2891
 2892
 2893
 2894
 2895
 2896
 2897
 2898
 2899
 2900
 2901
 2902
 2903
 2904
 2905
 2906
 2907
 2908
 2909
 2910
 2911
 2912
 2913
 2914
 2915
 2916
 2917
 2918
 2919
 2920
 2921
 2922
 2923
 2924
 2925
 2926
 2927
 2928
 2929
 2930
 2931
 2932
 2933
 2934
 2935
 2936
 2937
 2938
 2939
 2940
 2941
 2942
 2943
 2944
 2945
 2946
 2947
 2948
 2949
 2950
 2951
 2952
 2953
 2954
 2955
 2956
 2957
 2958
 2959
 2960
 2961
 2962
 2963
 2964
 2965
 2966
 2967
 2968
 2969
 2970
 2971
 2972
 2973
 2974
 2975
 2976
 2977
 2978
 2979
 2980
 2981
 2982
 2983
 2984
 2985
 2986
 2987
 2988
 2989
 2990
 2991
 2992
 2993
 2994
 2995
 2996
 2997
 2998
 2999
 3000
 3001
 3002
 3003
 3004
 3005
 3006
 3007
 3008
 3009
 3010
 3011
 3012
 3013
 3014
 3015
 3016
 3017
 3018
 3019
 3020
 3021
 3022
 3023
 3024
 3025
 3026
 3027
 3028
 3029
 3030
 3031
 3032
 3033
 3034
 3035
 3036
 3037
 3038
 3039
 3040
 3041
 3042
 3043
 3044
 3045
 3046
 3047
 3048
 3049
 3050
 3051
 3052
 3053
 3054
 3055
 3056
 3057
 3058
 3059
 3060
 3061
 3062
 
 | ;;; cc-langs.el --- language specific settings for CC Mode
;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
;;   Free Software Foundation, Inc.
;; Authors:    2002- Alan Mackenzie
;;             1998- Martin Stjernholm
;;             1992-1999 Barry A. Warsaw
;;             1987 Dave Detlefs and Stewart Clamen
;;             1985 Richard M. Stallman
;; Maintainer: bug-cc-mode@gnu.org
;; Created:    22-Apr-1997 (split from cc-mode.el)
;; Version:    See cc-mode.el
;; Keywords:   c languages oop
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with this program; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;; Commentary:
;; HACKERS NOTE: There's heavy macro magic here.  If you need to make
;; changes in this or other files containing `c-lang-defconst' but
;; don't want to read through the longer discussion below then read
;; this:
;;
;; o  A change in a `c-lang-defconst' or `c-lang-defvar' will not take
;;    effect if the file containing the mode init function (typically
;;    cc-mode.el) is byte compiled.
;; o  To make changes show in font locking you need to reevaluate the
;;    `*-font-lock-keywords-*' constants, which normally is easiest to
;;    do with M-x eval-buffer in cc-fonts.el.
;; o  In either case it's necessary to reinitialize the mode to make
;;    the changes show in an existing buffer.
;;; Introduction to the language dependent variable system:
;;
;; This file contains all the language dependent variables, except
;; those specific for font locking which reside in cc-fonts.el.  As
;; far as possible, all the differences between the languages that CC
;; Mode supports are described with these variables only, so that the
;; code can be shared.
;;
;; The language constant system (see cc-defs.el) is used to specify
;; various language dependent info at a high level, such as lists of
;; keywords, and then from them generate - at compile time - the
;; various regexps and other low-level structures actually employed in
;; the code at runtime.
;;
;; This system is also designed to make it easy for developers of
;; derived modes to customize the source constants for new language
;; variants, without having to keep up with the exact regexps etc that
;; are used in each CC Mode version.  It's possible from an external
;; package to add a new language by inheriting an existing one, and
;; then change specific constants as necessary for the new language.
;; The old values for those constants (and the values of all the other
;; high-level constants) may be used to build the new ones, and those
;; new values will in turn be used by the low-level definitions here
;; to build the runtime constants appropriately for the new language
;; in the current version of CC Mode.
;;
;; Like elsewhere in CC Mode, the existence of a doc string signifies
;; that a language constant is part of the external API, and that it
;; therefore can be used with a high confidence that it will continue
;; to work with future versions of CC Mode.  Even so, it's not
;; unlikely that such constants will change meaning slightly as this
;; system is refined further; a certain degree of dependence on the CC
;; Mode version is unavoidable when hooking in at this level.  Also
;; note that there's still work to be done to actually use these
;; constants everywhere inside CC Mode; there are still hardcoded
;; values in many places in the code.
;;
;; Separate packages will also benefit from the compile time
;; evaluation; the byte compiled file(s) for them will contain the
;; compiled runtime constants ready for use by (the byte compiled) CC
;; Mode, and the source definitions in this file don't have to be
;; loaded then.  However, if a byte compiled package is loaded that
;; has been compiled with a different version of CC Mode than the one
;; currently loaded, then the compiled-in values will be discarded and
;; new ones will be built when the mode is initialized.  That will
;; automatically trig a load of the file(s) containing the source
;; definitions (i.e. this file and/or cc-fonts.el) if necessary.
;;
;; A small example of a derived mode is available at
;; <http://cc-mode.sourceforge.net/derived-mode-ex.el>.  It also
;; contains some useful hints for derived mode developers.
;;; Using language variables:
;;
;; The `c-lang-defvar' forms in this file comprise the language
;; variables that CC Mode uses.  It does not work to use
;; `c-lang-defvar' anywhere else (which isn't much of a limitation
;; since these variables sole purpose is to interface with the CC Mode
;; core functions).  The values in these `c-lang-defvar's are not
;; evaluated right away but instead collected to a single large `setq'
;; that can be inserted for a particular language with the
;; `c-init-language-vars' macro.
;; This file is only required at compile time, or when not running
;; from byte compiled files, or when the source definitions for the
;; language constants are requested.
;;; Code:
(eval-when-compile
  (let ((load-path
	 (if (and (boundp 'byte-compile-dest-file)
		  (stringp byte-compile-dest-file))
	     (cons (file-name-directory byte-compile-dest-file) load-path)
	   load-path)))
    (load "cc-bytecomp" nil t)))
(cc-require 'cc-defs)
(cc-require 'cc-vars)
;; This file is not always loaded.  See note above.
(cc-external-require 'cl)
;;; Setup for the `c-lang-defvar' system.
(eval-and-compile
  ;; These are used to collect the init forms from the subsequent
  ;; `c-lang-defvar' and `c-lang-setvar'.  They are used to build the
  ;;  lambda in `c-make-init-lang-vars-fun' below, and to build `defvar's
  ;;  and `make-variable-buffer-local's in cc-engine and
  ;;  `make-local-variable's in `c-init-language-vars-for'.
  (defvar c-lang-variable-inits nil)
  (defvar c-lang-variable-inits-tail nil)
  (setq c-lang-variable-inits (list nil)
	c-lang-variable-inits-tail c-lang-variable-inits)
  (defvar c-emacs-variable-inits nil)
  (defvar c-emacs-variable-inits-tail nil)
  (setq c-emacs-variable-inits (list nil)
	c-emacs-variable-inits-tail c-emacs-variable-inits))
(defmacro c-lang-defvar (var val &optional doc)
  "Declares the buffer local variable VAR to get the value VAL.  VAL is
evaluated and assigned at mode initialization.  More precisely, VAL is
evaluated and bound to VAR when the result from the macro
`c-init-language-vars' is evaluated.
`c-lang-const' is typically used in VAL to get the right value for the
language being initialized, and such calls will be macro expanded to
the evaluated constant value at compile time."
  (when (and (not doc)
	     (eq (car-safe val) 'c-lang-const)
	     (eq (nth 1 val) var)
	     (not (nth 2 val)))
    ;; Special case: If there's no docstring and the value is a
    ;; simple (c-lang-const foo) where foo is the same name as VAR
    ;; then take the docstring from the language constant foo.
    (setq doc (get (intern (symbol-name (nth 1 val)) c-lang-constants)
		   'variable-documentation)))
  (or (stringp doc)
      (setq doc nil))
  (let ((elem (assq var (cdr c-lang-variable-inits))))
    (if elem
	(setcdr elem (list val doc))
      (setcdr c-lang-variable-inits-tail (list (list var val doc)))
      (setq c-lang-variable-inits-tail (cdr c-lang-variable-inits-tail))))
  ;; Return the symbol, like the other def* forms.
  `',var)
(defmacro c-lang-setvar (var val)
  "Causes the variable VAR to be made buffer local and to get set to the
value VAL.  VAL is evaluated and assigned at mode initialization.  More
precisely, VAL is evaluated and bound to VAR when the result from the
macro `c-init-language-vars' is evaluated.  VAR is typically a standard
Emacs variable like `comment-start'.
`c-lang-const' is typically used in VAL to get the right value for the
language being initialized, and such calls will be macro expanded to
the evaluated constant value at compile time."
  (let ((elem (assq var (cdr c-emacs-variable-inits))))
    (if elem
	(setcdr elem (list val)) ; Maybe remove "list", sometime. 2006-07-19
      (setcdr c-emacs-variable-inits-tail (list (list var val)))
      (setq c-emacs-variable-inits-tail (cdr c-emacs-variable-inits-tail))))
  ;; Return the symbol, like the other def* forms.
  `',var)
(put 'c-lang-defvar 'lisp-indent-function 'defun)
; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el.
;  '
(def-edebug-spec c-lang-defvar
  (&define name def-form &optional stringp)) ;)
(eval-and-compile
  ;; Some helper functions used when building the language constants.
  (defun c-filter-ops (ops opgroup-filter op-filter &optional xlate)
    ;; Extract a subset of the operators in the list OPS in a DWIM:ey
    ;; way.  The return value is a plain list of operators:
    ;;
    ;; OPS either has the structure of `c-operators', is a single
    ;; group in `c-operators', or is a plain list of operators.
    ;; 
    ;; OPGROUP-FILTER specifies how to select the operator groups.  It
    ;; can be t to choose all groups, a list of group type symbols
    ;; (such as 'prefix) to accept, or a function which will be called
    ;; with the group symbol for each group and should return non-nil
    ;; if that group is to be included.
    ;;
    ;; If XLATE is given, it's a function which is called for each
    ;; matching operator and its return value is collected instead.
    ;; If it returns a list, the elements are spliced directly into
    ;; the final result, which is returned as a list with duplicates
    ;; removed using `equal'.
    ;;
    ;; `c-mode-syntax-table' for the current mode is in effect during
    ;; the whole procedure.
    (unless (listp (car-safe ops))
      (setq ops (list ops)))
    (cond ((eq opgroup-filter t)
	   (setq opgroup-filter (lambda (opgroup) t)))
	  ((not (functionp opgroup-filter))
	   (setq opgroup-filter `(lambda (opgroup)
				   (memq opgroup ',opgroup-filter)))))
    (cond ((eq op-filter t)
	   (setq op-filter (lambda (op) t)))
	  ((stringp op-filter)
	   (setq op-filter `(lambda (op)
			      (string-match ,op-filter op)))))
    (unless xlate
      (setq xlate 'identity))
    (c-with-syntax-table (c-lang-const c-mode-syntax-table)
      (delete-duplicates
       (mapcan (lambda (opgroup)
		 (when (if (symbolp (car opgroup))
			   (when (funcall opgroup-filter (car opgroup))
			     (setq opgroup (cdr opgroup))
			     t)
			 t)
		   (mapcan (lambda (op)
			     (when (funcall op-filter op)
			       (let ((res (funcall xlate op)))
				 (if (listp res) res (list res)))))
			   opgroup)))
	       ops)
       :test 'equal))))
;;; Various mode specific values that aren't language related.
(c-lang-defconst c-mode-menu
  ;; The definition for the mode menu.  The menu title is prepended to
  ;; this before it's fed to `easy-menu-define'.
  t `(["Comment Out Region"     comment-region
       (c-fn-region-is-active-p)]
      ["Uncomment Region"       (comment-region (region-beginning)
						(region-end) '(4))
       (c-fn-region-is-active-p)]
      ["Indent Expression"      c-indent-exp
       (memq (char-after) '(?\( ?\[ ?\{))]
      ["Indent Line or Region"  c-indent-line-or-region t]
      ["Fill Comment Paragraph" c-fill-paragraph t]
      "----"
      ["Backward Statement"     c-beginning-of-statement t]
      ["Forward Statement"      c-end-of-statement t]
      ,@(when (c-lang-const c-opt-cpp-prefix)
	  ;; Only applicable if there's a cpp preprocessor.
	  `(["Up Conditional"         c-up-conditional t]
	    ["Backward Conditional"   c-backward-conditional t]
	    ["Forward Conditional"    c-forward-conditional t]
	    "----"
	    ["Macro Expand Region"    c-macro-expand
	     (c-fn-region-is-active-p)]
	    ["Backslashify"           c-backslash-region
	     (c-fn-region-is-active-p)]))
      "----"
      ("Toggle..."
       ["Syntactic indentation" c-toggle-syntactic-indentation
	:style toggle :selected c-syntactic-indentation]
       ["Electric mode"         c-toggle-electric-state
	:style toggle :selected c-electric-flag]
       ["Auto newline"          c-toggle-auto-newline
	:style toggle :selected c-auto-newline]
       ["Hungry delete"         c-toggle-hungry-state
	:style toggle :selected c-hungry-delete-key]
       ["Subword mode"          c-subword-mode
	:style toggle :selected (and (boundp 'c-subword-mode)
                                     c-subword-mode)])))
;;; Syntax tables.
(defun c-populate-syntax-table (table)
  "Populate the given syntax table as necessary for a C-like language.
This includes setting ' and \" as string delimiters, and setting up
the comment syntax to handle both line style \"//\" and block style
\"/*\" \"*/\" comments."
  (modify-syntax-entry ?_  "_"     table)
  (modify-syntax-entry ?\\ "\\"    table)
  (modify-syntax-entry ?+  "."     table)
  (modify-syntax-entry ?-  "."     table)
  (modify-syntax-entry ?=  "."     table)
  (modify-syntax-entry ?%  "."     table)
  (modify-syntax-entry ?<  "."     table)
  (modify-syntax-entry ?>  "."     table)
  (modify-syntax-entry ?&  "."     table)
  (modify-syntax-entry ?|  "."     table)
  (modify-syntax-entry ?\' "\""    table)
  (modify-syntax-entry ?\240 "."   table)
  ;; Set up block and line oriented comments.  The new C
  ;; standard mandates both comment styles even in C, so since
  ;; all languages now require dual comments, we make this the
  ;; default.
  (cond
   ;; XEmacs
   ((memq '8-bit c-emacs-features)
    (modify-syntax-entry ?/  ". 1456" table)
    (modify-syntax-entry ?*  ". 23"   table))
   ;; Emacs
   ((memq '1-bit c-emacs-features)
    (modify-syntax-entry ?/  ". 124b" table)
    (modify-syntax-entry ?*  ". 23"   table))
   ;; incompatible
   (t (error "CC Mode is incompatible with this version of Emacs")))
  (modify-syntax-entry ?\n "> b"  table)
  ;; Give CR the same syntax as newline, for selective-display
  (modify-syntax-entry ?\^m "> b" table))
(c-lang-defconst c-make-mode-syntax-table
  "Functions that generates the mode specific syntax tables.
The syntax tables aren't stored directly since they're quite large."
  t `(lambda ()
       (let ((table (make-syntax-table)))
	 (c-populate-syntax-table table)
	 ;; Mode specific syntaxes.
	 ,(cond ((c-major-mode-is 'objc-mode)
		 ;; Let '@' be part of symbols in ObjC to cope with
		 ;; its compiler directives as single keyword tokens.
		 ;; This is then necessary since it's assumed that
		 ;; every keyword is a single symbol.
		 `(modify-syntax-entry ?@ "_" table))
		((c-major-mode-is 'pike-mode)
		 `(modify-syntax-entry ?@ "." table)))
	 table)))
(c-lang-defconst c-mode-syntax-table
  ;; The syntax tables in evaluated form.  Only used temporarily when
  ;; the constants in this file are evaluated.
  t (funcall (c-lang-const c-make-mode-syntax-table)))
(c-lang-defconst c++-make-template-syntax-table
  ;; A variant of `c++-mode-syntax-table' that defines `<' and `>' as
  ;; parenthesis characters.  Used temporarily when template argument
  ;; lists are parsed.  Note that this encourages incorrect parsing of
  ;; templates since they might contain normal operators that uses the
  ;; '<' and '>' characters.  Therefore this syntax table might go
  ;; away when CC Mode handles templates correctly everywhere.
  t   nil
  c++ `(lambda ()
	 (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table))))
	   (modify-syntax-entry ?< "(>" table)
	   (modify-syntax-entry ?> ")<" table)
	   table)))
(c-lang-defvar c++-template-syntax-table
  (and (c-lang-const c++-make-template-syntax-table)
       (funcall (c-lang-const c++-make-template-syntax-table))))
(c-lang-defconst c-identifier-syntax-modifications
  "A list that describes the modifications that should be done to the
mode syntax table to get a syntax table that matches all identifiers
and keywords as words.
The list is just like the one used in `font-lock-defaults': Each
element is a cons where the car is the character to modify and the cdr
the new syntax, as accepted by `modify-syntax-entry'."
  ;; The $ character is not allowed in most languages (one exception
  ;; is Java which allows it for legacy reasons) but we still classify
  ;; it as an indentifier character since it's often used in various
  ;; machine generated identifiers.
  t    '((?_ . "w") (?$ . "w"))
  objc (append '((?@ . "w"))
	       (c-lang-const c-identifier-syntax-modifications))
  awk  '((?_ . "w")))
(c-lang-defvar c-identifier-syntax-modifications
  (c-lang-const c-identifier-syntax-modifications))
(c-lang-defvar c-identifier-syntax-table
  (let ((table (copy-syntax-table (c-mode-var "mode-syntax-table")))
	(mods c-identifier-syntax-modifications)
	mod)
    (while mods
      (setq mod (car mods)
	    mods (cdr mods))
      (modify-syntax-entry (car mod) (cdr mod) table))
    table)
  "Syntax table built on the mode syntax table but additionally
classifies symbol constituents like '_' and '$' as word constituents,
so that all identifiers are recognized as words.")
(c-lang-defconst c-get-state-before-change-function
  "If non-nil, a function called from c-before-change-hook.
Typically it will record enough state to allow
`c-before-font-lock-function' to extend the region to fontify,
and may do such things as removing text-properties which must be
recalculated.
It takes 2 parameters, the BEG and END supplied to every
before-change function; on entry, the buffer will have been
widened and match-data will have been saved; point is undefined
on both entry and exit; the return value is ignored.
When the mode is initialized, this function is called with
parameters \(point-min) and \(point-max)."
  t nil
  (c c++ objc) 'c-extend-region-for-CPP
  awk 'c-awk-record-region-clear-NL)
(c-lang-defvar c-get-state-before-change-function
	       (c-lang-const c-get-state-before-change-function))
  
(c-lang-defconst c-before-font-lock-function
  "If non-nil, a function called just before font locking.
Typically it will extend the region about to be fontified \(see
below) and will set `syntax-table' text properties on the region.
It takes 3 parameters, the BEG, END, and OLD-LEN supplied to
every after-change function; point is undefined on both entry and
exit; on entry, the buffer will have been widened and match-data
will have been saved; the return value is ignored.
The function may extend the region to be fontified by setting the
buffer local variables c-old-BEG and c-old-END.
The function is called even when font locking is disabled.
When the mode is initialized, this function is called with
parameters \(point-min), \(point-max) and <buffer size>."
  t nil
  (c c++ objc) 'c-neutralize-syntax-in-CPP
  awk 'c-awk-extend-and-syntax-tablify-region)
(c-lang-defvar c-before-font-lock-function
	       (c-lang-const c-before-font-lock-function))
;;; Lexer-level syntax (identifiers, tokens etc).
(c-lang-defconst c-symbol-start
  "Regexp that matches the start of a symbol, i.e. any identifier or
keyword.  It's unspecified how far it matches.  Does not contain a \\|
operator at the top level."
  t    (concat "[" c-alpha "_]")
  objc (concat "[" c-alpha "@]")
  pike (concat "[" c-alpha "_`]"))
(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
(c-lang-defconst c-symbol-chars
  "Set of characters that can be part of a symbol.
This is on the form that fits inside [ ] in a regexp."
  ;; Pike note: With the backquote identifiers this would include most
  ;; operator chars too, but they are handled with other means instead.
  t    (concat c-alnum "_$")
  objc (concat c-alnum "_$@"))
(c-lang-defconst c-symbol-key
  "Regexp matching identifiers and keywords (with submatch 0).  Assumed
to match if `c-symbol-start' matches on the same position."
  t    (concat (c-lang-const c-symbol-start)
	       "[" (c-lang-const c-symbol-chars) "]*")
  pike (concat
	;; Use the value from C here since the operator backquote is
	;; covered by the other alternative.
	(c-lang-const c-symbol-key c)
	"\\|"
	(c-make-keywords-re nil
	  (c-lang-const c-overloadable-operators))))
(c-lang-defvar c-symbol-key (c-lang-const c-symbol-key))
(c-lang-defconst c-symbol-key-depth
  ;; Number of regexp grouping parens in `c-symbol-key'.
  t (regexp-opt-depth (c-lang-const c-symbol-key)))
(c-lang-defconst c-nonsymbol-chars
  "This is the set of chars that can't be part of a symbol, i.e. the
negation of `c-symbol-chars'."
  t (concat "^" (c-lang-const c-symbol-chars)))
(c-lang-defvar c-nonsymbol-chars (c-lang-const c-nonsymbol-chars))
(c-lang-defconst c-nonsymbol-key
  "Regexp that matches any character that can't be part of a symbol.
It's usually appended to other regexps to avoid matching a prefix.
It's assumed to not contain any submatchers."
  ;; The same thing regarding Unicode identifiers applies here as to
  ;; `c-symbol-key'.
  t (concat "[" (c-lang-const c-nonsymbol-chars) "]"))
(c-lang-defconst c-identifier-ops
  "The operators that make up fully qualified identifiers.  nil in
languages that don't have such things.  See `c-operators' for a
description of the format.  Binary operators can concatenate symbols,
e.g. \"::\" in \"A::B::C\".  Prefix operators can precede identifiers,
e.g. \"~\" in \"~A::B\".  Other types of operators aren't supported.
This value is by default merged into `c-operators'."
  t    nil
  c++  '((prefix "~" "??-" "compl")
	 (right-assoc "::")
	 (prefix "::"))
  ;; Java has "." to concatenate identifiers but it's also used for
  ;; normal indexing.  There's special code in the Java font lock
  ;; rules to fontify qualified identifiers based on the standard
  ;; naming conventions.  We still define "." here to make
  ;; `c-forward-name' move over as long names as possible which is
  ;; necessary to e.g. handle throws clauses correctly.
  java '((left-assoc "."))
  idl  '((left-assoc "::")
	 (prefix "::"))
  pike '((left-assoc "::")
	 (prefix "::")
	 (left-assoc ".")))
(c-lang-defconst c-opt-identifier-concat-key
  ;; Appendable adorned regexp matching the operators that join
  ;; symbols to fully qualified identifiers, or nil in languages that
  ;; don't have such things.
  ;;
  ;; This was a docstring constant in 5.30.  It still works but is now
  ;; considered internal - change `c-identifier-ops' instead.
  t (let ((ops (c-filter-ops (c-lang-const c-identifier-ops)
			     '(left-assoc right-assoc)
			     t)))
      (when ops
	(c-make-keywords-re 'appendable ops))))
(c-lang-defvar c-opt-identifier-concat-key
  (c-lang-const c-opt-identifier-concat-key)
  'dont-doc)
(c-lang-defconst c-opt-identifier-concat-key-depth
  ;; Number of regexp grouping parens in `c-opt-identifier-concat-key'.
  t (regexp-opt-depth (c-lang-const c-opt-identifier-concat-key)))
(c-lang-defconst c-opt-identifier-prefix-key
  ;; Appendable adorned regexp matching operators that might precede
  ;; an identifier and that are part of the identifier in that case.
  ;; nil in languages without such things.
  t (let ((ops (c-filter-ops (c-lang-const c-identifier-ops)
			     '(prefix)
			     t)))
      (when ops
	(c-make-keywords-re 'appendable ops))))
(c-lang-defconst c-after-id-concat-ops
  "Operators that can occur after a binary operator on `c-identifier-ops'
in identifiers.  nil in languages that don't have such things.
Operators here should also have appropriate entries in `c-operators' -
it's not taken care of by default."
  t    nil
  ;; '~' for destructors in C++, '*' for member pointers.
  c++  '("~" "*")
  ;; In Java we recognize '*' to deal with "foo.bar.*" that can occur
  ;; in import declarations.  (This will also match bogus things like
  ;; "foo.*bar" but we don't bother.)
  java '("*"))
(c-lang-defconst c-opt-after-id-concat-key
  ;; Regexp that must match the token after
  ;; `c-opt-identifier-concat-key' for it to be considered an
  ;; identifier concatenation operator (which e.g. causes the
  ;; preceding identifier to be fontified as a reference).  Assumed to
  ;; be a string if `c-opt-identifier-concat-key' is.
  ;;
  ;; This was a docstring constant in 5.30.  It still works but is now
  ;; considered internal - change `c-after-id-concat-ops' instead.
  t (concat (c-lang-const c-symbol-start)
	    (if (c-lang-const c-after-id-concat-ops)
		(concat "\\|" (c-make-keywords-re 'appendable
				(c-lang-const c-after-id-concat-ops)))
	      "")))
(c-lang-defconst c-identifier-start
  "Regexp that matches the start of an (optionally qualified) identifier.
It should also match all keywords.  It's unspecified how far it
matches."
  t (concat (c-lang-const c-symbol-start)
	    (if (c-lang-const c-opt-identifier-prefix-key)
		(concat "\\|"
			(c-lang-const c-opt-identifier-prefix-key))
	      "")))
(c-lang-defvar c-identifier-start (c-lang-const c-identifier-start))
(c-lang-defconst c-identifier-key
  "Regexp matching a fully qualified identifier, like \"A::B::c\" in
C++.  It does not recognize the full range of syntactic whitespace
between the tokens; `c-forward-name' has to be used for that.  It
should also not match identifiers containing parenthesis groupings,
e.g. identifiers with template arguments such as \"A<X,Y>\" in C++."
  ;; This regexp is more complex than strictly necessary to ensure
  ;; that it can be matched with a minimum of backtracking.
  t (concat (if (c-lang-const c-opt-identifier-prefix-key)
		(concat
		 "\\("
		 (c-lang-const c-opt-identifier-prefix-key)
		 (c-lang-const c-simple-ws) "*"
		 "\\)?")
	      "")
	    "\\(" (c-lang-const c-symbol-key) "\\)"
	    (if (c-lang-const c-opt-identifier-concat-key)
		(concat
		 "\\("
		 (c-lang-const c-simple-ws) "*"
		 (c-lang-const c-opt-identifier-concat-key)
		 (c-lang-const c-simple-ws) "*"
		 (if (c-lang-const c-after-id-concat-ops)
		     (concat
		      "\\("
		       (c-make-keywords-re 'appendable
			 (c-lang-const c-after-id-concat-ops))
		      (concat
		       ;; For flexibility, consider the symbol match
		       ;; optional if we've hit a
		       ;; `c-after-id-concat-ops' operator.  This is
		       ;; also necessary to handle the "*" that can
		       ;; end import declaration identifiers in Java.
		       "\\("
		       (c-lang-const c-simple-ws) "*"
		       "\\(" (c-lang-const c-symbol-key) "\\)"
		       "\\)?")
		      "\\|"
		      "\\(" (c-lang-const c-symbol-key) "\\)"
		      "\\)")
		   (concat "\\(" (c-lang-const c-symbol-key) "\\)"))
		 "\\)*")
	      "")))
(c-lang-defvar c-identifier-key (c-lang-const c-identifier-key))
(c-lang-defconst c-identifier-last-sym-match
  ;; This was a docstring constant in 5.30 but it's no longer used.
  ;; It's only kept to avoid breaking third party code.
  ;;
  ;; Used to identify the submatch in `c-identifier-key' that
  ;; surrounds the last symbol in the qualified identifier.  It's a
  ;; list of submatch numbers, of which the first that has a match is
  ;; taken.  It's assumed that at least one does when the regexp has
  ;; matched.
  t nil)
(c-lang-defconst c-string-escaped-newlines
  "Set if the language support backslash escaped newlines inside string
literals."
  t nil
  (c c++ objc pike) t)
(c-lang-defvar c-string-escaped-newlines
  (c-lang-const c-string-escaped-newlines))
(c-lang-defconst c-multiline-string-start-char
  "Set if the language supports multiline string literals without escaped
newlines.  If t, all string literals are multiline.  If a character,
only literals where the open quote is immediately preceded by that
literal are multiline."
  t    nil
  pike ?#)
(c-lang-defvar c-multiline-string-start-char
  (c-lang-const c-multiline-string-start-char))
(c-lang-defconst c-opt-cpp-prefix
  "Regexp matching the prefix of a cpp directive in the languages that
normally use that macro preprocessor.  Tested at bol or at boi.
Assumed to not contain any submatches or \\| operators."
  ;; TODO (ACM, 2005-04-01).  Amend the following to recognise escaped NLs;
  ;; amend all uses of c-opt-cpp-prefix which count regexp-depth.
  t "\\s *#\\s *"
  (java awk) nil)
(c-lang-defvar c-opt-cpp-prefix (c-lang-const c-opt-cpp-prefix))
(c-lang-defconst c-anchored-cpp-prefix
  "Regexp matching the prefix of a cpp directive anchored to BOL,
in the languages that have a macro preprocessor."
  t (if (c-lang-const c-opt-cpp-prefix)
	(concat "^" (c-lang-const c-opt-cpp-prefix))))
(c-lang-defvar c-anchored-cpp-prefix (c-lang-const c-anchored-cpp-prefix))
(c-lang-defconst c-opt-cpp-start
  "Regexp matching the prefix of a cpp directive including the directive
name, or nil in languages without preprocessor support.  The first
submatch surrounds the directive name."
  t    (if (c-lang-const c-opt-cpp-prefix)
	   (concat (c-lang-const c-opt-cpp-prefix)
		   "\\([" c-alnum "]+\\)"))
  ;; Pike, being a scripting language, recognizes hash-bangs too.
  pike (concat (c-lang-const c-opt-cpp-prefix)
	       "\\([" c-alnum "]+\\|!\\)"))
(c-lang-defvar c-opt-cpp-start (c-lang-const c-opt-cpp-start))
(c-lang-defconst c-cpp-message-directives
  "List of cpp directives (without the prefix) that are followed by a
string message."
  t    (if (c-lang-const c-opt-cpp-prefix)
	   '("error"))
  (c c++ objc pike) '("error" "warning"))
(c-lang-defconst c-cpp-include-directives
  "List of cpp directives (without the prefix) that are followed by a
file name in angle brackets or quotes."
  t    (if (c-lang-const c-opt-cpp-prefix)
	   '("include"))
  objc '("include" "import"))
(c-lang-defconst c-opt-cpp-macro-define
  "Cpp directive (without the prefix) that is followed by a macro
definition, or nil if the language doesn't have any."
  t (if (c-lang-const c-opt-cpp-prefix)
	"define"))
(c-lang-defconst c-opt-cpp-macro-define-start
  ;; Regexp matching everything up to the macro body of a cpp define,
  ;; or the end of the logical line if there is none.  Set if
  ;; c-opt-cpp-macro-define is.
  t (if (c-lang-const c-opt-cpp-macro-define)
	(concat (c-lang-const c-opt-cpp-prefix)
		(c-lang-const c-opt-cpp-macro-define)
		"[ \t]+\\(\\sw\\|_\\)+\\(\([^\)]*\)\\)?"
		"\\([ \t]\\|\\\\\n\\)*")))
(c-lang-defvar c-opt-cpp-macro-define-start
  (c-lang-const c-opt-cpp-macro-define-start))
(c-lang-defconst c-opt-cpp-macro-define-id
  ;; Regexp matching everything up to the end of the identifier defined
  ;; by a cpp define.
  t (if (c-lang-const c-opt-cpp-macro-define)
	(concat (c-lang-const c-opt-cpp-prefix)	; #
		(c-lang-const c-opt-cpp-macro-define) ; define
		"[ \t]+\\(\\sw\\|_\\)+")))
(c-lang-defvar c-opt-cpp-macro-define-id
  (c-lang-const c-opt-cpp-macro-define-id))
(c-lang-defconst c-cpp-expr-directives
  "List of cpp directives (without the prefix) that are followed by an
expression."
  t (if (c-lang-const c-opt-cpp-prefix)
	'("if" "elif")))
(c-lang-defconst c-cpp-expr-functions
  "List of functions in cpp expressions."
  t    (if (c-lang-const c-opt-cpp-prefix)
	   '("defined"))
  pike '("defined" "efun" "constant"))
(c-lang-defconst c-assignment-operators
  "List of all assignment operators."
  t    '("=" "*=" "/=" "%=" "+=" "-=" ">>=" "<<=" "&=" "^=" "|=")
  java (append (c-lang-const c-assignment-operators)
	       '(">>>="))
  c++  (append (c-lang-const c-assignment-operators)
	       '("and_eq" "or_eq" "xor_eq" "??!=" "??'="))
  idl  nil)
(c-lang-defconst c-operators
  "List describing all operators, along with their precedence and
associativity.  The order in the list corresponds to the precedence of
the operators: The operators in each element are a group with the same
precedence, and the group has higher precedence than the groups in all
following elements.  The car of each element describes the type of the
operator group, and the cdr is a list of the operator tokens in it.
The operator group types are:
'prefix         Unary prefix operators.
'postfix        Unary postfix operators.
'postfix-if-paren
		Unary postfix operators if and only if the chars have
		parenthesis syntax.
'left-assoc     Binary left associative operators (i.e. a+b+c means (a+b)+c).
'right-assoc    Binary right associative operators (i.e. a=b=c means a=(b=c)).
'right-assoc-sequence
                Right associative operator that constitutes of a
                sequence of tokens that separate expressions.  All the
                tokens in the group are in this case taken as
                describing the sequence in one such operator, and the
                order between them is therefore significant.
Operators containing a character with paren syntax are taken to match
with a corresponding open/close paren somewhere else.  A postfix
operator with close paren syntax is taken to end a postfix expression
started somewhere earlier, rather than start a new one at point.  Vice
versa for prefix operators with open paren syntax.
Note that operators like \".\" and \"->\" which in language references
often are described as postfix operators are considered binary here,
since CC Mode treats every identifier as an expression."
  ;; There's currently no code in CC Mode that exploit all the info
  ;; in this variable; precedence, associativity etc are present as a
  ;; preparation for future work.
  t `(;; Preprocessor.
      ,@(when (c-lang-const c-opt-cpp-prefix)
	  `((prefix "#"
		    ,@(when (c-major-mode-is '(c-mode c++-mode))
			'("%:" "??=")))
	    (left-assoc "##"
			,@(when (c-major-mode-is '(c-mode c++-mode))
			    '("%:%:" "??=??=")))))
      ;; Primary.
      ,@(c-lang-const c-identifier-ops)
      ,@(cond ((c-major-mode-is 'c++-mode)
	       `((postfix-if-paren "<" ">"))) ; Templates.
	      ((c-major-mode-is 'pike-mode)
	       `((prefix "global" "predef")))
	      ((c-major-mode-is 'java-mode)
	       `((prefix "super"))))
      ;; Postfix.
      ,@(when (c-major-mode-is 'c++-mode)
	  ;; The following need special treatment.
	  `((prefix "dynamic_cast" "static_cast"
		    "reinterpret_cast" "const_cast" "typeid")))
      (left-assoc "."
		  ,@(unless (c-major-mode-is 'java-mode)
		      '("->")))
      (postfix "++" "--" "[" "]" "(" ")"
	       ,@(when (c-major-mode-is '(c-mode c++-mode))
		   '("<:" ":>" "??(" "??)")))
      ;; Unary.
      (prefix "++" "--" "+" "-" "!" "~"
	      ,@(when (c-major-mode-is 'c++-mode) '("not" "compl"))
	      ,@(when (c-major-mode-is '(c-mode c++-mode))
		  '("*" "&" "sizeof" "??-"))
	      ,@(when (c-major-mode-is 'objc-mode)
		  '("@selector" "@protocol" "@encode"))
	      ;; The following need special treatment.
	      ,@(cond ((c-major-mode-is 'c++-mode)
		       '("new" "delete"))
		      ((c-major-mode-is 'java-mode)
		       '("new"))
		      ((c-major-mode-is 'pike-mode)
		       '("class" "lambda" "catch" "throw" "gauge")))
	      "(" ")"			; Cast.
	      ,@(when (c-major-mode-is 'pike-mode)
		  '("[" "]")))		; Type cast.
      ;; Member selection.
      ,@(when (c-major-mode-is 'c++-mode)
	  `((left-assoc ".*" "->*")))
      ;; Multiplicative.
      (left-assoc "*" "/" "%")
      ;; Additive.
      (left-assoc "+" "-")
      ;; Shift.
      (left-assoc "<<" ">>"
		  ,@(when (c-major-mode-is 'java-mode)
		      '(">>>")))
      ;; Relational.
      (left-assoc "<" ">" "<=" ">="
		  ,@(when (c-major-mode-is 'java-mode)
		      '("instanceof")))
      ;; Equality.
      (left-assoc "==" "!="
		  ,@(when (c-major-mode-is 'c++-mode) '("not_eq")))
      ;; Bitwise and.
      (left-assoc "&"
		  ,@(when (c-major-mode-is 'c++-mode) '("bitand")))
      ;; Bitwise exclusive or.
      (left-assoc "^"
		  ,@(when (c-major-mode-is '(c-mode c++-mode))
		      '("??'"))
		  ,@(when (c-major-mode-is 'c++-mode) '("xor")))
      ;; Bitwise or.
      (left-assoc "|"
		  ,@(when (c-major-mode-is '(c-mode c++-mode))
		      '("??!"))
		  ,@(when (c-major-mode-is 'c++-mode) '("bitor")))
      ;; Logical and.
      (left-assoc "&&"
		  ,@(when (c-major-mode-is 'c++-mode) '("and")))
      ;; Logical or.
      (left-assoc "||"
		  ,@(when (c-major-mode-is '(c-mode c++-mode))
		      '("??!??!"))
		  ,@(when (c-major-mode-is 'c++-mode) '("or")))
      ;; Conditional.
      (right-assoc-sequence "?" ":")
      ;; Assignment.
      (right-assoc ,@(c-lang-const c-assignment-operators))
      ;; Exception.
      ,@(when (c-major-mode-is 'c++-mode)
	  '((prefix "throw")))
      ;; Sequence.
      (left-assoc ","))
  ;; IDL got its own definition since it has a much smaller operator
  ;; set than the other languages.
  idl `(;; Preprocessor.
	(prefix "#")
	(left-assoc "##")
	;; Primary.
	,@(c-lang-const c-identifier-ops)
	;; Unary.
	(prefix  "+" "-" "~")
	;; Multiplicative.
	(left-assoc "*" "/" "%")
	;; Additive.
	(left-assoc "+" "-")
	;; Shift.
	(left-assoc "<<" ">>")
	;; And.
	(left-assoc "&")
	;; Xor.
	(left-assoc "^")
	;; Or.
	(left-assoc "|")))
(c-lang-defconst c-operator-list
  ;; The operators as a flat list (without duplicates).
  t (c-filter-ops (c-lang-const c-operators) t t))
(c-lang-defconst c-overloadable-operators
  "List of the operators that are overloadable, in their \"identifier
form\".  See also `c-op-identifier-prefix'."
  t    nil
  c++  '("new" "delete" ;; Can be followed by "[]" but we ignore that.
	 "+" "-" "*" "/" "%"
	 "^" "??'" "xor" "&" "bitand" "|" "??!" "bitor" "~" "??-" "compl"
	 "!" "=" "<" ">" "+=" "-=" "*=" "/=" "%=" "^="
	 "??'=" "xor_eq" "&=" "and_eq" "|=" "??!=" "or_eq"
	 "<<" ">>" ">>=" "<<=" "==" "!=" "not_eq" "<=" ">="
	 "&&" "and" "||" "??!??!" "or" "++" "--" "," "->*" "->"
	 "()" "[]" "<::>" "??(??)")
  ;; These work like identifiers in Pike.
  pike '("`+" "`-" "`&" "`|" "`^" "`<<" "`>>" "`*" "`/" "`%" "`~"
	 "`==" "`<" "`>" "`!" "`[]" "`[]=" "`->" "`->=" "`()" "``+"
	 "``-" "``&" "``|" "``^" "``<<" "``>>" "``*" "``/" "``%"
	 "`+="))
(c-lang-defconst c-overloadable-operators-regexp
  ;; Regexp tested after an "operator" token in C++.
  t   nil
  c++ (c-make-keywords-re nil (c-lang-const c-overloadable-operators)))
(c-lang-defvar c-overloadable-operators-regexp
  (c-lang-const c-overloadable-operators-regexp))
(c-lang-defconst c-opt-op-identifier-prefix
  "Regexp matching the token before the ones in
`c-overloadable-operators' when operators are specified in their
\"identifier form\".  This typically matches \"operator\" in C++ where
operator functions are specified as e.g. \"operator +\".  It's nil in
languages without operator functions or where the complete operator
identifier is listed in `c-overloadable-operators'.
This regexp is assumed to not match any non-operator identifier."
  t   nil
  c++ (c-make-keywords-re t '("operator")))
(c-lang-defvar c-opt-op-identifier-prefix
  (c-lang-const c-opt-op-identifier-prefix))
;; Note: the following alias is an old name which was a mis-spelling.  It has
;; been corrected above and throughout cc-engine.el.  It will be removed at
;; some release very shortly in the future.  ACM, 2006-04-14.
(defalias 'c-opt-op-identitier-prefix 'c-opt-op-identifier-prefix)
(make-obsolete-variable 'c-opt-op-identitier-prefix 'c-opt-op-identifier-prefix
			"CC Mode 5.31.4, 2006-04-14")
(c-lang-defconst c-other-op-syntax-tokens
  "List of the tokens made up of characters in the punctuation or
parenthesis syntax classes that have uses other than as expression
operators."
  t '("{" "}" "(" ")" "[" "]" ";" ":" "," "=" "/*" "*/" "//")
  (c c++ pike) (append '("#" "##"	; Used by cpp.
			 "::" "...")
		       (c-lang-const c-other-op-syntax-tokens))
  (c c++) (append '("*") (c-lang-const c-other-op-syntax-tokens))
  c++  (append '("&" "<%" "%>" "<:" ":>" "%:" "%:%:")
	       (c-lang-const c-other-op-syntax-tokens))
  objc (append '("#" "##"		; Used by cpp.
		 "+" "-") (c-lang-const c-other-op-syntax-tokens))
  idl  (append '("#" "##")		; Used by cpp.
	       (c-lang-const c-other-op-syntax-tokens))
  pike (append '("..")
	       (c-lang-const c-other-op-syntax-tokens)
	       (c-lang-const c-overloadable-operators))
  awk '("{" "}" "(" ")" "[" "]" ";" "," "=" "/"))
(c-lang-defconst c-all-op-syntax-tokens
  ;; List of all tokens in the punctuation and parenthesis syntax
  ;; classes.
  t (delete-duplicates (append (c-lang-const c-other-op-syntax-tokens)
			       (c-lang-const c-operator-list))
		       :test 'string-equal))
(c-lang-defconst c-nonsymbol-token-char-list
  ;; List containing all chars not in the word, symbol or
  ;; syntactically irrelevant syntax classes, i.e. all punctuation,
  ;; parenthesis and string delimiter chars.
  t (c-with-syntax-table (c-lang-const c-mode-syntax-table)
      ;; Only go through the chars in the printable ASCII range.  No
      ;; language so far has 8-bit or widestring operators.
      (let (list (char 32))
	(while (< char 127)
	  (or (memq (char-syntax char) '(?w ?_ ?< ?> ?\ ))
	      (setq list (cons (c-int-to-char char) list)))
	  (setq char (1+ char)))
	list)))
(c-lang-defconst c-nonsymbol-token-regexp
  ;; Regexp matching all tokens in the punctuation and parenthesis
  ;; syntax classes.  Note that this also matches ".", which can start
  ;; a float.
  t (c-make-keywords-re nil
      (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
		    t
		    "\\`\\(\\s.\\|\\s\(\\|\\s\)\\)+\\'")))
(c-lang-defvar c-nonsymbol-token-regexp
  (c-lang-const c-nonsymbol-token-regexp))
(c-lang-defconst c-assignment-op-regexp
  ;; Regexp matching all assignment operators and only them.  The
  ;; beginning of the first submatch is used to detect the end of the
  ;; token, along with the end of the whole match.
  t (if (c-lang-const c-assignment-operators)
	(concat
	 ;; Need special case for "=" since it's a prefix of "==".
	 "=\\([^=]\\|$\\)"
	 "\\|"
	 (c-make-keywords-re nil
	   (set-difference (c-lang-const c-assignment-operators)
			   '("=")
			   :test 'string-equal)))
      "\\<\\>"))
(c-lang-defvar c-assignment-op-regexp
  (c-lang-const c-assignment-op-regexp))
(c-lang-defconst c-<>-multichar-token-regexp
  ;; Regexp matching all tokens containing "<" or ">" which are longer
  ;; than one char.
  t (c-make-keywords-re nil
      (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
		    t
		    ".[<>]\\|[<>].")))
(c-lang-defvar c-<>-multichar-token-regexp
  (c-lang-const c-<>-multichar-token-regexp))
(c-lang-defconst c-<-op-cont-regexp
  ;; Regexp matching the second and subsequent characters of all
  ;; multicharacter tokens that begin with "<".
  t (c-make-keywords-re nil
      (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
		    t
		    "\\`<."
		    (lambda (op) (substring op 1)))))
(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp))
(c-lang-defconst c->-op-cont-regexp
  ;; Regexp matching the second and subsequent characters of all
  ;; multicharacter tokens that begin with ">".
  t (c-make-keywords-re nil
      (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
		    t
		    "\\`>."
		    (lambda (op) (substring op 1)))))
(c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp))
(c-lang-defconst c-stmt-delim-chars
  ;; The characters that should be considered to bound statements.  To
  ;; optimize `c-crosses-statement-barrier-p' somewhat, it's assumed to
  ;; begin with "^" to negate the set.  If ? : operators should be
  ;; detected then the string must end with "?:".
  t    "^;{}?:"
  awk  "^;{}#\n\r?:") ; The newline chars gets special treatment.
(c-lang-defvar c-stmt-delim-chars (c-lang-const c-stmt-delim-chars))
(c-lang-defconst c-stmt-delim-chars-with-comma
  ;; Variant of `c-stmt-delim-chars' that additionally contains ','.
  t    "^;,{}?:"
  awk  "^;,{}\n\r?:") ; The newline chars gets special treatment.
(c-lang-defvar c-stmt-delim-chars-with-comma
  (c-lang-const c-stmt-delim-chars-with-comma))
;;; Syntactic whitespace.
(c-lang-defconst c-simple-ws
  "Regexp matching an ordinary whitespace character.
Does not contain a \\| operator at the top level."
  ;; "\\s " is not enough since it doesn't match line breaks.
  t "\\(\\s \\|[\n\r]\\)")
(c-lang-defconst c-simple-ws-depth
  ;; Number of regexp grouping parens in `c-simple-ws'.
  t (regexp-opt-depth (c-lang-const c-simple-ws)))
(c-lang-defconst c-line-comment-starter
  "String that starts line comments, or nil if such don't exist.
Line comments are always terminated by newlines.  At least one of
`c-block-comment-starter' and this one is assumed to be set.
Note that it's currently not enough to set this to support a new
comment style.  Other stuff like the syntax table must also be set up
properly."
  t    "//"
  awk  "#")
(c-lang-defvar c-line-comment-starter (c-lang-const c-line-comment-starter))
(c-lang-defconst c-block-comment-starter
  "String that starts block comments, or nil if such don't exist.
Block comments are ended by `c-block-comment-ender', which is assumed
to be set if this is.  At least one of `c-line-comment-starter' and
this one is assumed to be set.
Note that it's currently not enough to set this to support a new
comment style.  Other stuff like the syntax table must also be set up
properly."
  t    "/*"
  awk  nil)
(c-lang-defconst c-block-comment-ender
  "String that ends block comments, or nil if such don't exist.
Note that it's currently not enough to set this to support a new
comment style.  Other stuff like the syntax table must also be set up
properly."
  t    "*/"
  awk  nil)
(c-lang-defconst c-comment-start-regexp
  ;; Regexp to match the start of any type of comment.
  t (let ((re (c-make-keywords-re nil
		(list (c-lang-const c-line-comment-starter)
		      (c-lang-const c-block-comment-starter)))))
      (if (memq 'gen-comment-delim c-emacs-features)
	  (concat re "\\|\\s!")
	re)))
(c-lang-defvar c-comment-start-regexp (c-lang-const c-comment-start-regexp))
;;;; Added by ACM, 2003/9/18.
(c-lang-defconst c-block-comment-start-regexp
  ;; Regexp which matches the start of a block comment (if such exists in the
  ;; language)
  t (if (c-lang-const c-block-comment-starter)
	(regexp-quote (c-lang-const c-block-comment-starter))
      "\\<\\>"))
(c-lang-defvar c-block-comment-start-regexp
  (c-lang-const c-block-comment-start-regexp))
(c-lang-defconst c-literal-start-regexp
  ;; Regexp to match the start of comments and string literals.
  t (concat (c-lang-const c-comment-start-regexp)
	    "\\|"
	    (if (memq 'gen-string-delim c-emacs-features)
		"\"|"
	      "\"")))
(c-lang-defvar c-literal-start-regexp (c-lang-const c-literal-start-regexp))
(c-lang-defconst c-doc-comment-start-regexp
  "Regexp to match the start of documentation comments."
  t    "\\<\\>"
  ;; From font-lock.el: `doxygen' uses /*! while others use /**.
  (c c++ objc) "/\\*[*!]"
  java "/\\*\\*"
  pike "/[/*]!")
(c-lang-defvar c-doc-comment-start-regexp
  (c-lang-const c-doc-comment-start-regexp))
(c-lang-defconst comment-start
  "String that starts comments inserted with M-; etc.
`comment-start' is initialized from this."
  ;; Default: Prefer line comments to block comments, and pad with a space.
  t (concat (or (c-lang-const c-line-comment-starter)
		(c-lang-const c-block-comment-starter))
	    " ")
  ;; In C we still default to the block comment style since line
  ;; comments aren't entirely portable.
  c "/* ")
(c-lang-setvar comment-start (c-lang-const comment-start))
(c-lang-defconst comment-end
  "String that ends comments inserted with M-; etc.
`comment-end' is initialized from this."
  ;; Default: Use block comment style if comment-start uses block
  ;; comments, and pad with a space in that case.
  t (if (string-match (concat "\\`\\("
			      (c-lang-const c-block-comment-start-regexp)
			      "\\)")
		      (c-lang-const comment-start))
	(concat " " (c-lang-const c-block-comment-ender))
      ""))
(c-lang-setvar comment-end (c-lang-const comment-end))
(c-lang-defconst comment-start-skip
  "Regexp to match the start of a comment plus everything up to its body.
`comment-start-skip' is initialized from this."
  ;; Default: Allow the last char of the comment starter(s) to be
  ;; repeated, then allow any amount of horizontal whitespace.
  t (concat "\\("
	    (c-concat-separated
	     (mapcar (lambda (cs)
		       (when cs
			 (concat (regexp-quote cs) "+")))
		     (list (c-lang-const c-line-comment-starter)
			   (c-lang-const c-block-comment-starter)))
	     "\\|")
	    "\\)\\s *"))
(c-lang-setvar comment-start-skip (c-lang-const comment-start-skip))
(c-lang-defconst c-syntactic-ws-start
  ;; Regexp matching any sequence that can start syntactic whitespace.
  ;; The only uncertain case is '#' when there are cpp directives.
  t (concat "\\s \\|"
	    (c-make-keywords-re nil
	      (append (list (c-lang-const c-line-comment-starter)
			    (c-lang-const c-block-comment-starter)
			    (when (c-lang-const c-opt-cpp-prefix)
			      "#"))
		      '("\n" "\r")))
	    "\\|\\\\[\n\r]"
	    (when (memq 'gen-comment-delim c-emacs-features)
	      "\\|\\s!")))
(c-lang-defvar c-syntactic-ws-start (c-lang-const c-syntactic-ws-start))
(c-lang-defconst c-syntactic-ws-end
  ;; Regexp matching any single character that might end syntactic whitespace.
  t (concat "\\s \\|"
	    (c-make-keywords-re nil
	      (append (when (c-lang-const c-block-comment-ender)
			(list
			 (string
			  (elt (c-lang-const c-block-comment-ender)
			       (1- (length
				    (c-lang-const c-block-comment-ender)))))))
		      '("\n" "\r")))
	    (when (memq 'gen-comment-delim c-emacs-features)
	      "\\|\\s!")))
(c-lang-defvar c-syntactic-ws-end (c-lang-const c-syntactic-ws-end))
(c-lang-defconst c-unterminated-block-comment-regexp
  ;; Regexp matching an unterminated block comment that doesn't
  ;; contain line breaks, or nil in languages without block comments.
  ;; Does not contain a \| operator at the top level.
  t (when (c-lang-const c-block-comment-starter)
      (concat
       (regexp-quote (c-lang-const c-block-comment-starter))
       ;; It's messy to cook together a regexp that matches anything
       ;; but c-block-comment-ender.
       (let ((end (c-lang-const c-block-comment-ender)))
	 (cond ((= (length end) 1)
		(concat "[^" end "\n\r]*"))
	       ((= (length end) 2)
		(concat "[^" (substring end 0 1) "\n\r]*"
			"\\("
			(regexp-quote (substring end 0 1)) "+"
			"[^"
			;; The quoting rules inside char classes are silly. :P
			(cond ((= (elt end 0) (elt end 1))
			       (concat (substring end 0 1) "\n\r"))
			      ((= (elt end 1) ?\])
			       (concat (substring end 1 2) "\n\r"
				       (substring end 0 1)))
			      (t
			       (concat (substring end 0 1) "\n\r"
				       (substring end 1 2))))
			"]"
			"[^" (substring end 0 1) "\n\r]*"
			"\\)*"))
	       (t
		(error "Can't handle a block comment ender of length %s"
		       (length end))))))))
(c-lang-defconst c-block-comment-regexp
  ;; Regexp matching a block comment that doesn't contain line breaks,
  ;; or nil in languages without block comments.  The reason we don't
  ;; allow line breaks is to avoid going very far and risk running out
  ;; of regexp stack; this regexp is intended to handle only short
  ;; comments that might be put in the middle of limited constructs
  ;; like declarations.  Does not contain a \| operator at the top
  ;; level.
  t (when (c-lang-const c-unterminated-block-comment-regexp)
      (concat
       (c-lang-const c-unterminated-block-comment-regexp)
       (let ((end (c-lang-const c-block-comment-ender)))
	 (cond ((= (length end) 1)
		(regexp-quote end))
	       ((= (length end) 2)
		(concat (regexp-quote (substring end 0 1)) "+"
			(regexp-quote (substring end 1 2))))
	       (t
		(error "Can't handle a block comment ender of length %s"
		       (length end))))))))
(c-lang-defconst c-nonwhite-syntactic-ws
  ;; Regexp matching a piece of syntactic whitespace that isn't a
  ;; sequence of simple whitespace characters.  As opposed to
  ;; `c-(forward|backward)-syntactic-ws', this doesn't regard cpp
  ;; directives as syntactic whitespace.
  t (c-concat-separated
     (list (when (c-lang-const c-line-comment-starter)
	     (concat (regexp-quote (c-lang-const c-line-comment-starter))
		     "[^\n\r]*[\n\r]"))
	   (c-lang-const c-block-comment-regexp)
	   "\\\\[\n\r]"
	   (when (memq 'gen-comment-delim c-emacs-features)
	     "\\s!\\S!*\\s!"))
     "\\|"))
(c-lang-defconst c-syntactic-ws
  ;; Regexp matching syntactic whitespace, including possibly the
  ;; empty string.  As opposed to `c-(forward|backward)-syntactic-ws',
  ;; this doesn't regard cpp directives as syntactic whitespace.  Does
  ;; not contain a \| operator at the top level.
  t (concat (c-lang-const c-simple-ws) "*"
	    "\\("
	    (concat "\\(" (c-lang-const c-nonwhite-syntactic-ws) "\\)"
		    (c-lang-const c-simple-ws) "*")
	    "\\)*"))
(c-lang-defconst c-syntactic-ws-depth
  ;; Number of regexp grouping parens in `c-syntactic-ws'.
  t (regexp-opt-depth (c-lang-const c-syntactic-ws)))
(c-lang-defconst c-nonempty-syntactic-ws
  ;; Regexp matching syntactic whitespace, which is at least one
  ;; character long.  As opposed to `c-(forward|backward)-syntactic-ws',
  ;; this doesn't regard cpp directives as syntactic whitespace.  Does
  ;; not contain a \| operator at the top level.
  t (concat "\\("
	    (c-lang-const c-simple-ws)
	    "\\|"
	    (c-lang-const c-nonwhite-syntactic-ws)
	    "\\)+"))
(c-lang-defconst c-nonempty-syntactic-ws-depth
  ;; Number of regexp grouping parens in `c-nonempty-syntactic-ws'.
  t (regexp-opt-depth (c-lang-const c-nonempty-syntactic-ws)))
(c-lang-defconst c-single-line-syntactic-ws
  ;; Regexp matching syntactic whitespace without any line breaks.  As
  ;; opposed to `c-(forward|backward)-syntactic-ws', this doesn't
  ;; regard cpp directives as syntactic whitespace.  Does not contain
  ;; a \| operator at the top level.
  t (if (c-lang-const c-block-comment-regexp)
	(concat "\\s *\\("
		(c-lang-const c-block-comment-regexp)
		"\\s *\\)*")
      "\\s *"))
(c-lang-defconst c-single-line-syntactic-ws-depth
  ;; Number of regexp grouping parens in `c-single-line-syntactic-ws'.
  t (regexp-opt-depth (c-lang-const c-single-line-syntactic-ws)))
(c-lang-defconst c-syntactic-eol
  ;; Regexp that matches when there is no syntactically significant
  ;; text before eol.  Macros are regarded as syntactically
  ;; significant text here.
  t (concat (c-lang-const c-single-line-syntactic-ws)
	    ;; Match eol (possibly inside a block comment or preceded
	    ;; by a line continuation backslash), or the beginning of a
	    ;; line comment.  Note: This has to be modified for awk
	    ;; where line comments start with '#'.
	    "\\("
	    (c-concat-separated
	     (list (when (c-lang-const c-line-comment-starter)
		     (regexp-quote (c-lang-const c-line-comment-starter)))
		   (when (c-lang-const c-unterminated-block-comment-regexp)
		     (concat (c-lang-const c-unterminated-block-comment-regexp)
			     "$"))
		   "\\\\$"
		   "$")
	     "\\|")
	    "\\)"))
(c-lang-defvar c-syntactic-eol (c-lang-const c-syntactic-eol))
;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK).
(c-lang-defconst c-at-vsemi-p-fn
  "Contains a function \"Is there a virtual semicolon at POS or point?\".
Such a function takes one optional parameter, a buffer position (defaults to
point), and returns nil or t.  This variable contains nil for languages which
don't have EOL terminated statements. "
  t nil
  awk 'c-awk-at-vsemi-p)
(c-lang-defvar c-at-vsemi-p-fn (c-lang-const c-at-vsemi-p-fn))
(c-lang-defconst c-vsemi-status-unknown-p-fn
  "Contains a function \"are we unsure whether there is a virtual semicolon on this line?\".
The (admittedly kludgey) purpose of such a function is to prevent an infinite
recursion in c-beginning-of-statement-1 when point starts at a `while' token.
The function MUST NOT UNDER ANY CIRCUMSTANCES call c-beginning-of-statement-1,
even indirectly.  This variable contains nil for languages which don't have
EOL terminated statements."
  t nil
  awk 'c-awk-vsemi-status-unknown-p)
(c-lang-defvar c-vsemi-status-unknown-p-fn
  (c-lang-const c-vsemi-status-unknown-p-fn))
;;; Defun functions
;; The Emacs variables beginning-of-defun-function and
;; end-of-defun-function will be set so that commands like
;; `mark-defun' and `narrow-to-defun' work right.  The key sequences
;; C-M-a and C-M-e are, however, bound directly to the CC Mode
;; functions, allowing optimisation for large n.
(c-lang-defconst beginning-of-defun-function
  "Function to which beginning-of-defun-function will be set."
  t 'c-beginning-of-defun
  awk 'c-awk-beginning-of-defun)
(c-lang-setvar beginning-of-defun-function
	       (c-lang-const beginning-of-defun-function))
(c-lang-defconst end-of-defun-function
  "Function to which end-of-defun-function will be set."
  t 'c-end-of-defun
  awk 'c-awk-end-of-defun)
(c-lang-setvar end-of-defun-function (c-lang-const end-of-defun-function))
;;; In-comment text handling.
(c-lang-defconst c-paragraph-start
  "Regexp to append to `paragraph-start'."
  t    "$"
  java "\\(@[a-zA-Z]+\\>\\|$\\)"	; For Javadoc.
  pike "\\(@[a-zA-Z_-]+\\>\\([^{]\\|$\\)\\|$\\)") ; For Pike refdoc.
(c-lang-defvar c-paragraph-start (c-lang-const c-paragraph-start))
(c-lang-defconst c-paragraph-separate
  "Regexp to append to `paragraph-separate'."
  t    "$"
  pike (c-lang-const c-paragraph-start))
(c-lang-defvar c-paragraph-separate (c-lang-const c-paragraph-separate))
;;; Keyword lists.
;; Note: All and only all language constants containing keyword lists
;; should end with "-kwds"; they're automatically collected into the
;; `c-kwds-lang-consts' list below and used to build `c-keywords' etc.
(c-lang-defconst c-primitive-type-kwds
  "Primitive type keywords.  As opposed to the other keyword lists, the
keywords listed here are fontified with the type face instead of the
keyword face.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled.
Do not try to modify this list for end user customizations; the
`*-font-lock-extra-types' variable, where `*' is the mode prefix, is
the appropriate place for that."
  t    '("char" "double" "float" "int" "long" "short" "signed"
	 "unsigned" "void")
  c    (append
	'("_Bool" "_Complex" "_Imaginary") ; Conditionally defined in C99.
	(c-lang-const c-primitive-type-kwds))
  c++  (append
	'("bool" "wchar_t")
	(c-lang-const c-primitive-type-kwds))
  ;; Objective-C extends C, but probably not the new stuff in C99.
  objc (append
	'("id" "Class" "SEL" "IMP" "BOOL")
	(c-lang-const c-primitive-type-kwds))
  java '("boolean" "byte" "char" "double" "float" "int" "long" "short" "void")
  idl  '("Object" "ValueBase" "any" "boolean" "char" "double" "fixed" "float"
	 "long" "octet" "sequence" "short" "string" "void" "wchar" "wstring"
	 ;; In CORBA PSDL:
	 "ref"
	 ;; The following can't really end a type, but we have to specify them
	 ;; here due to the assumption in `c-primitive-type-prefix-kwds'.  It
	 ;; doesn't matter that much.
	 "unsigned" "strong")
  pike '(;; this_program isn't really a keyword, but it's practically
	 ;; used as a builtin type.
	 "array" "float" "function" "int" "mapping" "mixed" "multiset"
	 "object" "program" "string" "this_program" "void"))
(c-lang-defconst c-primitive-type-key
  ;; An adorned regexp that matches `c-primitive-type-kwds'.
  t (c-make-keywords-re t (c-lang-const c-primitive-type-kwds)))
(c-lang-defvar c-primitive-type-key (c-lang-const c-primitive-type-key))
(c-lang-defconst c-primitive-type-prefix-kwds
  "Keywords that might act as prefixes for primitive types.  Assumed to
be a subset of `c-primitive-type-kwds'."
  t       nil
  (c c++) '("long" "short" "signed" "unsigned")
  idl     '("long" "unsigned"
	    ;; In CORBA PSDL:
	    "strong"))
(c-lang-defconst c-type-prefix-kwds
  "Keywords where the following name - if any - is a type name, and
where the keyword together with the symbol works as a type in
declarations.
Note that an alternative if the second part doesn't hold is
`c-type-list-kwds'.  Keywords on this list are typically also present
on one of the `*-decl-kwds' lists."
  t    nil
  c    '("struct" "union" "enum")
  c++  (append '("class" "typename")
	       (c-lang-const c-type-prefix-kwds c)))
(c-lang-defconst c-type-prefix-key
  ;; Adorned regexp matching `c-type-prefix-kwds'.
  t (c-make-keywords-re t (c-lang-const c-type-prefix-kwds)))
(c-lang-defvar c-type-prefix-key (c-lang-const c-type-prefix-key))
(c-lang-defconst c-type-modifier-kwds
  "Type modifier keywords.  These can occur almost anywhere in types
but they don't build a type of themselves.  Unlike the keywords on
`c-primitive-type-kwds', they are fontified with the keyword face and
not the type face."
  t    nil
  c    '("const" "restrict" "volatile")
  c++  '("const" "volatile" "throw")
  objc '("const" "volatile"))
(c-lang-defconst c-opt-type-modifier-key
  ;; Adorned regexp matching `c-type-modifier-kwds', or nil in
  ;; languages without such keywords.
  t (and (c-lang-const c-type-modifier-kwds)
	 (c-make-keywords-re t (c-lang-const c-type-modifier-kwds))))
(c-lang-defvar c-opt-type-modifier-key (c-lang-const c-opt-type-modifier-key))
(c-lang-defconst c-opt-type-component-key
  ;; An adorned regexp that matches `c-primitive-type-prefix-kwds' and
  ;; `c-type-modifier-kwds', or nil in languages without any of them.
  t (and (or (c-lang-const c-primitive-type-prefix-kwds)
	     (c-lang-const c-type-modifier-kwds))
	 (c-make-keywords-re t
	   (append (c-lang-const c-primitive-type-prefix-kwds)
		   (c-lang-const c-type-modifier-kwds)))))
(c-lang-defvar c-opt-type-component-key
  (c-lang-const c-opt-type-component-key))
(c-lang-defconst c-type-start-kwds
  ;; All keywords that can start a type (i.e. are either a type prefix
  ;; or a complete type).
  t (delete-duplicates (append (c-lang-const c-primitive-type-kwds)
			       (c-lang-const c-type-prefix-kwds)
			       (c-lang-const c-type-modifier-kwds))
		       :test 'string-equal))
(c-lang-defconst c-class-decl-kwds
  "Keywords introducing declarations where the following block (if any)
contains another declaration level that should be considered a class.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled.
Note that presence on this list does not automatically treat the
following identifier as a type; the keyword must also be present on
`c-type-prefix-kwds' or `c-type-list-kwds' to accomplish that."
  t    nil
  c    '("struct" "union")
  c++  '("class" "struct" "union")
  objc '("struct" "union"
	 "@interface" "@implementation" "@protocol")
  java '("class" "interface")
  idl  '("component" "eventtype" "exception" "home" "interface" "struct"
	 "union" "valuetype"
	 ;; In CORBA PSDL:
	 "storagehome" "storagetype"
	 ;; In CORBA CIDL:
	 "catalog" "executor" "manages" "segment")
  pike '("class"))
(c-lang-defconst c-class-key
  ;; Regexp matching the start of a class.
  t (c-make-keywords-re t (c-lang-const c-class-decl-kwds)))
(c-lang-defvar c-class-key (c-lang-const c-class-key))
(c-lang-defconst c-brace-list-decl-kwds
  "Keywords introducing declarations where the following block (if
any) is a brace list.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
  t    '("enum")
  (java awk) nil)
(c-lang-defconst c-brace-list-key
  ;; Regexp matching the start of declarations where the following
  ;; block is a brace list.
  t (c-make-keywords-re t (c-lang-const c-brace-list-decl-kwds)))
(c-lang-defvar c-brace-list-key (c-lang-const c-brace-list-key))
(c-lang-defconst c-other-block-decl-kwds
  "Keywords where the following block (if any) contains another
declaration level that should not be considered a class.  For every
keyword here, CC Mode will add a set of special syntactic symbols for
those blocks.  E.g. if the keyword is \"foo\" then there will be
`foo-open', `foo-close', and `infoo' symbols.
The intention is that this category should be used for block
constructs that aren't related to object orientation concepts like
classes (which thus also include e.g. interfaces, templates,
contracts, structs, etc).  The more pragmatic distinction is that
while most want some indentation inside classes, it's fairly common
that they don't want it in some of these constructs, so it should be
simple to configure that differently from classes.  See also
`c-class-decl-kwds'.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
  t   nil
  (c objc) '("extern")
  c++ '("namespace" "extern")
  idl '("module"
	;; In CORBA CIDL:
	"composition"))
(c-lang-defconst c-other-decl-block-key
  ;; Regexp matching the start of blocks besides classes that contain
  ;; another declaration level.
  t (c-make-keywords-re t (c-lang-const c-other-block-decl-kwds)))
(c-lang-defvar c-other-decl-block-key (c-lang-const c-other-decl-block-key))
(c-lang-defvar c-other-decl-block-key-in-symbols-alist
  (mapcar
   (lambda (elt)
     (cons elt
	   (if (string= elt "extern")
	       'inextern-lang
	     (intern (concat "in" elt)))))
   (c-lang-const c-other-block-decl-kwds))
  "Alist associating keywords in c-other-decl-block-decl-kwds with
their matching \"in\" syntactic symbols.")
(c-lang-defconst c-typedef-decl-kwds
  "Keywords introducing declarations where the identifier(s) being
declared are types.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
  ;; Default to `c-class-decl-kwds' and `c-brace-list-decl-kwds'
  ;; (since e.g. "Foo" is a type that's being defined in "class Foo
  ;; {...}").
  t    (append (c-lang-const c-class-decl-kwds)
	       (c-lang-const c-brace-list-decl-kwds))
  ;; Languages that have a "typedef" construct.
  (c c++ objc idl pike) (append (c-lang-const c-typedef-decl-kwds)
				'("typedef"))
  ;; Unlike most other languages, exception names are not handled as
  ;; types in IDL since they only can occur in "raises" specs.
  idl  (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil)))
(c-lang-defconst c-typeless-decl-kwds
  "Keywords introducing declarations where the \(first) identifier
\(declarator) follows directly after the keyword, without any type.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
  ;; Default to `c-class-decl-kwds' and `c-brace-list-decl-kwds'
  ;; (since e.g. "Foo" is the identifier being defined in "class Foo
  ;; {...}").
  t    (append (c-lang-const c-class-decl-kwds)
	       (c-lang-const c-brace-list-decl-kwds))
  ;; Note: "manages" for CORBA CIDL clashes with its presence on
  ;; `c-type-list-kwds' for IDL.
  idl  (append (c-lang-const c-typeless-decl-kwds)
	       '("factory" "finder" "native"
		 ;; In CORBA PSDL:
		 "key" "stores"
		 ;; In CORBA CIDL:
		 "facet"))
  pike (append (c-lang-const c-class-decl-kwds)
	       '("constant")))
(c-lang-defconst c-modifier-kwds
  "Keywords that can prefix normal declarations of identifiers
\(and typically act as flags).  Things like argument declarations
inside function headers are also considered declarations in this
sense.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
  t    nil
  (c c++) '("auto" "extern" "inline" "register" "static")
  c++  (append '("explicit" "friend" "mutable" "template" "using" "virtual")
	       (c-lang-const c-modifier-kwds))
  objc '("auto" "bycopy" "byref" "extern" "in" "inout" "oneway" "out" "static")
  ;; FIXME: Some of those below ought to be on `c-other-decl-kwds' instead.
  idl  '("abstract" "attribute" "const" "consumes" "custom" "emits" "import"
	 "in" "inout" "local" "multiple" "oneway" "out" "private" "provides"
	 "public" "publishes" "readonly" "typeid" "typeprefix" "uses"
	 ;; In CORBA PSDL:
	 "primary" "state"
	 ;; In CORBA CIDL:
	 "bindsTo" "delegatesTo" "implements" "proxy" "storedOn")
  ;; Note: "const" is not used in Java, but it's still a reserved keyword.
  java '("abstract" "const" "final" "native" "private" "protected" "public"
	 "static" "strictfp" "synchronized" "transient" "volatile")
  pike '("final" "inline" "local" "nomask" "optional" "private" "protected"
	 "public" "static" "variant"))
(c-lang-defconst c-other-decl-kwds
  "Keywords that can start or prefix any declaration level construct,
besides those on `c-class-decl-kwds', `c-brace-list-decl-kwds',
`c-other-block-decl-kwds', `c-typedef-decl-kwds',
`c-typeless-decl-kwds' and `c-modifier-kwds'.
If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
will be handled."
  t       nil
  objc    '("@class" "@end" "@defs")
  java    '("import" "package")
  pike    '("import" "inherit"))
(c-lang-defconst c-decl-start-kwds
  "Keywords that always start declarations, wherever they occur.
This can be used for declarations that aren't recognized by the normal
combination of `c-decl-prefix-re' and `c-decl-start-re'."
  t    nil
  ;; Classes can be declared anywhere in a Pike expression.
  pike '("class"))
(c-lang-defconst c-decl-hangon-kwds
  "Keywords that can occur anywhere in a declaration level construct.
This is used for self-contained things that can be tacked on anywhere
on a declaration and that should be ignored to be able to recognize it
correctly.  Typical cases are compiler extensions like
\"__attribute__\" or \"__declspec\":
    __declspec(noreturn) void foo();
    class __declspec(dllexport) classname {...};
    void foo() __attribute__((noreturn));
Note that unrecognized plain symbols are skipped anyway if they occur
before the type, so such things are not necessary to mention here.
Mentioning them here is necessary only if they can occur in other
places, or if they are followed by a construct that must be skipped
over \(like the parens in the \"__attribute__\" and \"__declspec\"
examples above).  In the last case, they alse need to be present on
one of `c-type-list-kwds', `c-ref-list-kwds',
`c-colon-type-list-kwds', `c-paren-nontype-kwds', `c-paren-type-kwds',
`c-<>-type-kwds', or `c-<>-arglist-kwds'."
  ;; NB: These are currently not recognized in all parts of a
  ;; declaration.  Specifically, they aren't recognized in the middle
  ;; of multi-token types, inside declarators, and between the
  ;; identifier and the arglist paren of a function declaration.
  ;;
  ;; FIXME: This ought to be user customizable since compiler stuff
  ;; like this usually is wrapped in project specific macros.  (It'd
  ;; of course be even better if we could cope without knowing this.)
  t nil
  (c c++) '(;; GCC extension.
	    "__attribute__"
	    ;; MSVC extension.
	    "__declspec"))
(c-lang-defconst c-decl-hangon-key
  ;; Adorned regexp matching `c-decl-hangon-kwds'.
  t (c-make-keywords-re t (c-lang-const c-decl-hangon-kwds)))
(c-lang-defvar c-decl-hangon-key (c-lang-const c-decl-hangon-key))
(c-lang-defconst c-prefix-spec-kwds
  ;; All keywords that can occur in the preamble of a declaration.
  ;; They typically occur before the type, but they are also matched
  ;; after presumptive types since we often can't be sure that
  ;; something is a type or just some sort of macro in front of the
  ;; declaration.  They might be ambiguous with types or type
  ;; prefixes.
  t (delete-duplicates (append (c-lang-const c-class-decl-kwds)
			       (c-lang-const c-brace-list-decl-kwds)
			       (c-lang-const c-other-block-decl-kwds)
			       (c-lang-const c-typedef-decl-kwds)
			       (c-lang-const c-typeless-decl-kwds)
			       (c-lang-const c-modifier-kwds)
			       (c-lang-const c-other-decl-kwds)
			       (c-lang-const c-decl-start-kwds)
			       (c-lang-const c-decl-hangon-kwds))
		       :test 'string-equal))
(c-lang-defconst c-prefix-spec-kwds-re
  ;; Adorned regexp of `c-prefix-spec-kwds'.
  t (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds)))
(c-lang-defvar c-prefix-spec-kwds-re (c-lang-const c-prefix-spec-kwds-re))
(c-lang-defconst c-specifier-key
  ;; Adorned regexp of the keywords in `c-prefix-spec-kwds' that aren't
  ;; ambiguous with types or type prefixes.  These are the keywords (like
  ;; extern, namespace, but NOT template) that can modify a declaration.
  t (c-make-keywords-re t
      (set-difference (c-lang-const c-prefix-spec-kwds)
		      (append (c-lang-const c-type-start-kwds)
			      (c-lang-const c-<>-arglist-kwds))
		      :test 'string-equal)))
(c-lang-defvar c-specifier-key (c-lang-const c-specifier-key))
(c-lang-defconst c-postfix-spec-kwds
  ;; Keywords that can occur after argument list of a function header
  ;; declaration, i.e. in the "K&R region".
  t (append (c-lang-const c-postfix-decl-spec-kwds)
	    (c-lang-const c-decl-hangon-kwds)))
(c-lang-defconst c-not-decl-init-keywords
  ;; Adorned regexp matching all keywords that can't appear at the
  ;; start of a declaration.
  t (c-make-keywords-re t
      (set-difference (c-lang-const c-keywords)
		      (append (c-lang-const c-type-start-kwds)
			      (c-lang-const c-prefix-spec-kwds))
		      :test 'string-equal)))
(c-lang-defvar c-not-decl-init-keywords
  (c-lang-const c-not-decl-init-keywords))
(c-lang-defconst c-protection-kwds
  "Access protection label keywords in classes."
  t    nil
  c++  '("private" "protected" "public")
  objc '("@private" "@protected" "@public"))
(c-lang-defconst c-block-decls-with-vars
  "Keywords introducing declarations that can contain a block which
might be followed by variable declarations, e.g. like \"foo\" in
\"class Foo { ... } foo;\".  So if there is a block in a declaration
like that, it ends with the following ';' and not right away.
The keywords on list are assumed to also be present on one of the
`*-decl-kwds' lists."
  t        nil
  (c objc) '("struct" "union" "enum" "typedef")
  c++      '("class" "struct" "union" "enum" "typedef"))
(c-lang-defconst c-opt-block-decls-with-vars-key
  ;; Regexp matching the `c-block-decls-with-vars' keywords, or nil in
  ;; languages without such constructs.
  t (and (c-lang-const c-block-decls-with-vars)
	 (c-make-keywords-re t (c-lang-const c-block-decls-with-vars))))
(c-lang-defvar c-opt-block-decls-with-vars-key
  (c-lang-const c-opt-block-decls-with-vars-key))
(c-lang-defconst c-postfix-decl-spec-kwds
  "Keywords introducing extra declaration specifiers in the region
between the header and the body \(i.e. the \"K&R-region\") in
declarations."
  t    nil
  java '("extends" "implements" "throws")
  idl  '("context" "getraises" "manages" "primarykey" "raises" "setraises"
	 "supports"
	 ;; In CORBA PSDL:
	 "as" "const" "implements" "of" "ref"))
(c-lang-defconst c-nonsymbol-sexp-kwds
  "Keywords that may be followed by a nonsymbol sexp before whatever
construct it's part of continues."
  t    nil
  (c c++ objc) '("extern"))
(c-lang-defconst c-type-list-kwds
  "Keywords that may be followed by a comma separated list of type
identifiers, where each optionally can be prefixed by keywords.  (Can
also be used for the special case when the list can contain only one
element.)
Assumed to be mutually exclusive with `c-ref-list-kwds'.  There's no
reason to put keywords on this list if they are on `c-type-prefix-kwds'.
There's also no reason to add keywords that prefixes a normal
declaration consisting of a type followed by a declarator (list), so
the keywords on `c-modifier-kwds' should normally not be listed here
either.
Note: Use `c-typeless-decl-kwds' for keywords followed by a function
or variable identifier (that's being defined)."
  t    nil
  c++  '("operator")
  objc '("@class")
  java '("import" "new" "extends" "implements" "throws")
  idl  '("manages" "native" "primarykey" "supports"
	 ;; In CORBA PSDL:
	 "as" "implements" "of" "scope")
  pike '("inherit"))
(c-lang-defconst c-ref-list-kwds
  "Keywords that may be followed by a comma separated list of
reference (i.e. namespace/scope/module) identifiers, where each
optionally can be prefixed by keywords.  (Can also be used for the
special case when the list can contain only one element.)  Assumed to
be mutually exclusive with `c-type-list-kwds'.
Note: Use `c-typeless-decl-kwds' for keywords followed by a function
or variable identifier (that's being defined)."
  t    nil
  c++  '("namespace")
  java '("package")
  idl  '("import" "module"
	 ;; In CORBA CIDL:
	 "composition")
  pike '("import"))
(c-lang-defconst c-colon-type-list-kwds
  "Keywords that may be followed (not necessarily directly) by a colon
and then a comma separated list of type identifiers, where each
optionally can be prefixed by keywords.  (Can also be used for the
special case when the list can contain only one element.)"
  t    nil
  c++  '("class" "struct")
  idl  '("component" "eventtype" "home" "interface" "valuetype"
	 ;; In CORBA PSDL:
	 "storagehome" "storagetype"))
(c-lang-defconst c-colon-type-list-re
  "Regexp matched after the keywords in `c-colon-type-list-kwds' to skip
forward to the colon.  The end of the match is assumed to be directly
after the colon, so the regexp should end with \":\".  Must be a
regexp if `c-colon-type-list-kwds' isn't nil."
  t (if (c-lang-const c-colon-type-list-kwds)
	;; Disallow various common punctuation chars that can't come
	;; before the ":" that starts the inherit list after "class"
	;; or "struct" in C++.  (Also used as default for other
	;; languages.)
	"[^\]\[{}();,/#=:]*:"))
(c-lang-defvar c-colon-type-list-re (c-lang-const c-colon-type-list-re))
(c-lang-defconst c-paren-nontype-kwds
  "Keywords that may be followed by a parenthesis expression that doesn't
contain type identifiers."
  t       nil
  (c c++) '(;; GCC extension.
	    "__attribute__"
	    ;; MSVC extension.
	    "__declspec"))
(c-lang-defconst c-paren-type-kwds
  "Keywords that may be followed by a parenthesis expression containing
type identifiers separated by arbitrary tokens."
  t    nil
  c++  '("throw")
  objc '("@defs")
  idl  '("switch")
  pike '("array" "function" "int" "mapping" "multiset" "object" "program"))
(c-lang-defconst c-paren-any-kwds
  t (delete-duplicates (append (c-lang-const c-paren-nontype-kwds)
			       (c-lang-const c-paren-type-kwds))
		       :test 'string-equal))
(c-lang-defconst c-<>-type-kwds
  "Keywords that may be followed by an angle bracket expression
containing type identifiers separated by \",\".  The difference from
`c-<>-arglist-kwds' is that unknown names are taken to be types and
not other identifiers.  `c-recognize-<>-arglists' is assumed to be set
if this isn't nil."
  t    nil
  objc '("id")
  idl  '("sequence"
	 ;; In CORBA PSDL:
	 "ref"))
(c-lang-defconst c-<>-arglist-kwds
  "Keywords that can be followed by a C++ style template arglist; see
`c-recognize-<>-arglists' for details.  That language constant is
assumed to be set if this isn't nil."
  t    nil
  c++  '("template")
  idl  '("fixed" "string" "wstring"))
(c-lang-defconst c-<>-sexp-kwds
  ;; All keywords that can be followed by an angle bracket sexp.
  t (delete-duplicates (append (c-lang-const c-<>-type-kwds)
			       (c-lang-const c-<>-arglist-kwds))
		       :test 'string-equal))
(c-lang-defconst c-opt-<>-sexp-key
  ;; Adorned regexp matching keywords that can be followed by an angle
  ;; bracket sexp.  Always set when `c-recognize-<>-arglists' is.
  t (if (c-lang-const c-recognize-<>-arglists)
	(c-make-keywords-re t (c-lang-const c-<>-sexp-kwds))))
(c-lang-defvar c-opt-<>-sexp-key (c-lang-const c-opt-<>-sexp-key))
(c-lang-defconst c-brace-id-list-kwds
  "Keywords that may be followed by a brace block containing a comma
separated list of identifier definitions, i.e. like the list of
identifiers that follows the type in a normal declaration."
  t (c-lang-const c-brace-list-decl-kwds))
(c-lang-defconst c-block-stmt-1-kwds
  "Statement keywords followed directly by a substatement."
  t    '("do" "else")
  c++  '("do" "else" "try")
  objc '("do" "else" "@finally" "@try")
  java '("do" "else" "finally" "try")
  idl  nil)
(c-lang-defconst c-block-stmt-1-key
  ;; Regexp matching the start of any statement followed directly by a
  ;; substatement (doesn't match a bare block, however).
  t (c-make-keywords-re t (c-lang-const c-block-stmt-1-kwds)))
(c-lang-defvar c-block-stmt-1-key (c-lang-const c-block-stmt-1-key))
(c-lang-defconst c-block-stmt-2-kwds
  "Statement keywords followed by a paren sexp and then by a substatement."
  t    '("for" "if" "switch" "while")
  c++  '("for" "if" "switch" "while" "catch")
  objc '("for" "if" "switch" "while" "@catch" "@synchronized")
  java '("for" "if" "switch" "while" "catch" "synchronized")
  idl  nil
  pike '("for" "if" "switch" "while" "foreach")
  awk  '("for" "if" "while"))
(c-lang-defconst c-block-stmt-2-key
  ;; Regexp matching the start of any statement followed by a paren sexp
  ;; and then by a substatement.
  t (c-make-keywords-re t (c-lang-const c-block-stmt-2-kwds)))
(c-lang-defvar c-block-stmt-2-key (c-lang-const c-block-stmt-2-key))
(c-lang-defconst c-block-stmt-kwds
  ;; Union of `c-block-stmt-1-kwds' and `c-block-stmt-2-kwds'.
  t (delete-duplicates (append (c-lang-const c-block-stmt-1-kwds)
			       (c-lang-const c-block-stmt-2-kwds))
		       :test 'string-equal))
(c-lang-defconst c-opt-block-stmt-key
  ;; Regexp matching the start of any statement that has a
  ;; substatement (except a bare block).  Nil in languages that
  ;; don't have such constructs.
  t (if (or (c-lang-const c-block-stmt-1-kwds)
	    (c-lang-const c-block-stmt-2-kwds))
	(c-make-keywords-re t
	  (append (c-lang-const c-block-stmt-1-kwds)
		  (c-lang-const c-block-stmt-2-kwds)))))
(c-lang-defvar c-opt-block-stmt-key (c-lang-const c-opt-block-stmt-key))
(c-lang-defconst c-simple-stmt-kwds
  "Statement keywords followed by an expression or nothing."
  t    '("break" "continue" "goto" "return")
  objc '("break" "continue" "goto" "return" "@throw")
  ;; Note: `goto' is not valid in Java, but the keyword is still reserved.
  java '("break" "continue" "goto" "return" "throw")
  idl  nil
  pike '("break" "continue" "return")
  awk  '(;; Not sure about "delete", "exit", "getline", etc. ; ACM 2002/5/30
	 "break" "continue" "return" "delete" "exit" "getline" "next"
	 "nextfile" "print" "printf"))
(c-lang-defconst c-simple-stmt-key
  ;; Adorned regexp matching `c-simple-stmt-kwds'.
  t (c-make-keywords-re t (c-lang-const c-simple-stmt-kwds)))
(c-lang-defvar c-simple-stmt-key (c-lang-const c-simple-stmt-key))
(c-lang-defconst c-paren-stmt-kwds
  "Statement keywords followed by a parenthesis expression that
nevertheless contains a list separated with ';' and not ','."
  t    '("for")
  idl  nil)
(c-lang-defconst c-paren-stmt-key
  ;; Adorned regexp matching `c-paren-stmt-kwds'.
  t (c-make-keywords-re t (c-lang-const c-paren-stmt-kwds)))
(c-lang-defvar c-paren-stmt-key (c-lang-const c-paren-stmt-key))
(c-lang-defconst c-asm-stmt-kwds
  "Statement keywords followed by an assembler expression."
  t nil
  (c c++) '("asm" "__asm__")) ;; Not standard, but common.
(c-lang-defconst c-opt-asm-stmt-key
  ;; Regexp matching the start of an assembler statement.  Nil in
  ;; languages that don't support that.
  t (if (c-lang-const c-asm-stmt-kwds)
	(c-make-keywords-re t (c-lang-const c-asm-stmt-kwds))))
(c-lang-defvar c-opt-asm-stmt-key (c-lang-const c-opt-asm-stmt-key))
(c-lang-defconst c-label-kwds
  "Keywords introducing colon terminated labels in blocks."
  t '("case" "default")
  awk nil)
(c-lang-defconst c-label-kwds-regexp
  ;; Adorned regexp matching any keyword that introduces a label.
  t (c-make-keywords-re t (c-lang-const c-label-kwds)))
(c-lang-defvar c-label-kwds-regexp (c-lang-const c-label-kwds-regexp))
(c-lang-defconst c-before-label-kwds
  "Keywords that might be followed by a label identifier."
  t    '("goto")
  (java pike) (append '("break" "continue")
		      (c-lang-const c-before-label-kwds))
  idl  nil
  awk  nil)
(c-lang-defconst c-constant-kwds
  "Keywords for constants."
  t       nil
  (c c++) '("NULL" ;; Not a keyword, but practically works as one.
	    "false" "true")		; Defined in C99.
  objc    '("nil" "Nil")
  idl     '("TRUE" "FALSE")
  java    '("true" "false" "null") ; technically "literals", not keywords
  pike    '("UNDEFINED")) ;; Not a keyword, but practically works as one.
(c-lang-defconst c-primary-expr-kwds
  "Keywords besides constants and operators that start primary expressions."
  t    nil
  c++  '("operator" "this")
  objc '("super" "self")
  java '("this")
  pike '("this")) ;; Not really a keyword, but practically works as one.
(c-lang-defconst c-expr-kwds
  ;; Keywords that can occur anywhere in expressions.  Built from
  ;; `c-primary-expr-kwds' and all keyword operators in `c-operators'.
  t (delete-duplicates
     (append (c-lang-const c-primary-expr-kwds)
	     (c-filter-ops (c-lang-const c-operator-list)
			   t
			   "\\`\\(\\w\\|\\s_\\)+\\'"))
     :test 'string-equal))
(c-lang-defconst c-lambda-kwds
  "Keywords that start lambda constructs, i.e. function definitions in
expressions."
  t    nil
  pike '("lambda"))
(c-lang-defconst c-inexpr-block-kwds
  "Keywords that start constructs followed by statement blocks which can
be used in expressions \(the gcc extension for this in C and C++ is
handled separately by `c-recognize-paren-inexpr-blocks')."
  t    nil
  pike '("catch" "gauge"))
(c-lang-defconst c-inexpr-class-kwds
  "Keywords that can start classes inside expressions."
  t    nil
  java '("new")
  pike '("class"))
(c-lang-defconst c-inexpr-brace-list-kwds
  "Keywords that can start brace list blocks inside expressions.
Note that Java specific rules are currently applied to tell this from
`c-inexpr-class-kwds'."
  t    nil
  java '("new"))
(c-lang-defconst c-opt-inexpr-brace-list-key
  ;; Regexp matching the start of a brace list in an expression, or
  ;; nil in languages that don't have such things.  This should not
  ;; match brace lists recognized through `c-special-brace-lists'.
  t (and (c-lang-const c-inexpr-brace-list-kwds)
	 (c-make-keywords-re t (c-lang-const c-inexpr-brace-list-kwds))))
(c-lang-defvar c-opt-inexpr-brace-list-key
  (c-lang-const c-opt-inexpr-brace-list-key))
(c-lang-defconst c-decl-block-key
  ;; Regexp matching keywords in any construct that contain another
  ;; declaration level, i.e. that isn't followed by a function block
  ;; or brace list.  When the first submatch matches, it's an
  ;; unambiguous construct, otherwise it's an ambiguous match that
  ;; might also be the return type of a function declaration.
  t (let* ((decl-kwds (append (c-lang-const c-class-decl-kwds)
			      (c-lang-const c-other-block-decl-kwds)
			      (c-lang-const c-inexpr-class-kwds)))
	   (unambiguous (set-difference decl-kwds
					(c-lang-const c-type-start-kwds)
					:test 'string-equal))
	   (ambiguous (intersection decl-kwds
				    (c-lang-const c-type-start-kwds)
				    :test 'string-equal)))
      (if ambiguous
	  (concat (c-make-keywords-re t unambiguous)
		  "\\|"
		  (c-make-keywords-re t ambiguous))
	(c-make-keywords-re t unambiguous))))
(c-lang-defvar c-decl-block-key (c-lang-const c-decl-block-key))
(c-lang-defconst c-bitfield-kwds
  "Keywords that can introduce bitfields."
  t nil
  (c c++ objc) '("char" "int" "long" "signed" "unsigned"))
(c-lang-defconst c-opt-bitfield-key
  ;; Regexp matching the start of a bitfield (not uniquely), or nil in
  ;; languages without bitfield support.
  t       nil
  (c c++) (c-make-keywords-re t (c-lang-const c-bitfield-kwds)))
(c-lang-defvar c-opt-bitfield-key (c-lang-const c-opt-bitfield-key))
(c-lang-defconst c-other-kwds
  "Keywords not accounted for by any other `*-kwds' language constant."
  t    nil
  idl  '("truncatable"
	 ;; In CORBA CIDL: (These are declaration keywords that never
	 ;; can start a declaration.)
	 "entity" "process" "service" "session" "storage"))
;;; Constants built from keywords.
;; Note: No `*-kwds' language constants may be defined below this point.
(eval-and-compile
  (defconst c-kwds-lang-consts
    ;; List of all the language constants that contain keyword lists.
    (let (list)
      (mapatoms (lambda (sym)
		  (when (and (boundp sym)
			     (string-match "-kwds\\'" (symbol-name sym)))
		    ;; Make the list of globally interned symbols
		    ;; instead of ones interned in `c-lang-constants'.
		    (setq list (cons (intern (symbol-name sym)) list))))
		c-lang-constants)
      list)))
(c-lang-defconst c-keywords
  ;; All keywords as a list.
  t (delete-duplicates
     (c-lang-defconst-eval-immediately
      `(append ,@(mapcar (lambda (kwds-lang-const)
			   `(c-lang-const ,kwds-lang-const))
			 c-kwds-lang-consts)
	       nil))
     :test 'string-equal))
(c-lang-defconst c-keywords-regexp
  ;; All keywords as an adorned regexp.
  t (c-make-keywords-re t (c-lang-const c-keywords)))
(c-lang-defvar c-keywords-regexp (c-lang-const c-keywords-regexp))
(c-lang-defconst c-keyword-member-alist
  ;; An alist with all the keywords in the cars.  The cdr for each
  ;; keyword is a list of the symbols for the `*-kwds' lists that
  ;; contains it.
  t (let ((kwd-list-alist
	   (c-lang-defconst-eval-immediately
	    `(list ,@(mapcar (lambda (kwds-lang-const)
			       `(cons ',kwds-lang-const
				      (c-lang-const ,kwds-lang-const)))
			     c-kwds-lang-consts))))
	  lang-const kwd-list kwd
	  result-alist elem)
      (while kwd-list-alist
	(setq lang-const (caar kwd-list-alist)
	      kwd-list (cdar kwd-list-alist)
	      kwd-list-alist (cdr kwd-list-alist))
	(while kwd-list
	  (setq kwd (car kwd-list)
		kwd-list (cdr kwd-list))
	  (unless (setq elem (assoc kwd result-alist))
	    (setq result-alist (cons (setq elem (list kwd)) result-alist)))
	  (unless (memq lang-const (cdr elem))
	    (setcdr elem (cons lang-const (cdr elem))))))
      result-alist))
(c-lang-defvar c-keywords-obarray
  ;; An obarray containing all keywords as symbols.  The property list
  ;; of each symbol has a non-nil entry for the specific `*-kwds'
  ;; lists it's a member of.
  ;;
  ;; E.g. to see whether the string str contains a keyword on
  ;; `c-class-decl-kwds', one can do like this:
  ;;     (get (intern-soft str c-keyword-obarray) 'c-class-decl-kwds)
  ;; Which preferably is written using the associated functions in
  ;; cc-engine:
  ;;     (c-keyword-member (c-keyword-sym str) 'c-class-decl-kwds)
  ;; The obarray is not stored directly as a language constant since
  ;; the printed representation for obarrays used in .elc files isn't
  ;; complete.
  (let* ((alist (c-lang-const c-keyword-member-alist))
	 kwd lang-const-list
	 (obarray (make-vector (* (length alist) 2) 0)))
    (while alist
      (setq kwd (caar alist)
	    lang-const-list (cdar alist)
	    alist (cdr alist))
      (setplist (intern kwd obarray)
		;; Emacs has an odd bug that causes `mapcan' to fail
		;; with unintelligible errors.  (XEmacs works.)
		;;(mapcan (lambda (lang-const)
		;;	      (list lang-const t))
		;;	    lang-const-list)
		(apply 'nconc (mapcar (lambda (lang-const)
					(list lang-const t))
				      lang-const-list))))
    obarray))
(c-lang-defconst c-regular-keywords-regexp
  ;; Adorned regexp matching all keywords that should be fontified
  ;; with the keywords face.  I.e. that aren't types or constants.
  t (c-make-keywords-re t
      (set-difference (c-lang-const c-keywords)
		      (append (c-lang-const c-primitive-type-kwds)
			      (c-lang-const c-constant-kwds))
		      :test 'string-equal)))
(c-lang-defvar c-regular-keywords-regexp
  (c-lang-const c-regular-keywords-regexp))
(c-lang-defconst c-primary-expr-regexp
  ;; Regexp matching the start of any primary expression, i.e. any
  ;; literal, symbol, prefix operator, and '('.  It doesn't need to
  ;; exclude keywords; they are excluded afterwards unless the second
  ;; submatch matches. If the first but not the second submatch
  ;; matches then it is an ambiguous primary expression; it could also
  ;; be a match of e.g. an infix operator. (The case with ambiguous
  ;; keyword operators isn't handled.)
  t (let* ((prefix-ops
	    (c-filter-ops (c-lang-const c-operators)
			  '(prefix)
			  (lambda (op)
			    ;; Filter out the special case prefix
			    ;; operators that are close parens.
			    (not (string-match "\\s)" op)))))
	   (nonkeyword-prefix-ops
	    (c-filter-ops prefix-ops
			  t
			  "\\`\\(\\s.\\|\\s(\\|\\s)\\)+\\'"))
	   (in-or-postfix-ops
	    (c-filter-ops (c-lang-const c-operators)
			  '(postfix
			    postfix-if-paren
			    left-assoc
			    right-assoc
			    right-assoc-sequence)
			  t))
	   (unambiguous-prefix-ops (set-difference nonkeyword-prefix-ops
						   in-or-postfix-ops
						   :test 'string-equal))
	   (ambiguous-prefix-ops (intersection nonkeyword-prefix-ops
					       in-or-postfix-ops
					       :test 'string-equal)))
      (concat
       "\\("
       ;; Take out all symbol class operators from `prefix-ops' and make the
       ;; first submatch from them together with `c-primary-expr-kwds'.
       (c-make-keywords-re t
	 (append (c-lang-const c-primary-expr-kwds)
		 (set-difference prefix-ops nonkeyword-prefix-ops
				 :test 'string-equal)))
       "\\|"
       ;; Match all ambiguous operators.
       (c-make-keywords-re nil
	 (intersection nonkeyword-prefix-ops in-or-postfix-ops
		       :test 'string-equal))
       "\\)"
       "\\|"
       ;; Now match all other symbols.
       (c-lang-const c-symbol-start)
       "\\|"
       ;; The chars that can start integer and floating point
       ;; constants.
       "\\.?[0-9]"
       "\\|"
       ;; The nonambiguous operators from `prefix-ops'.
       (c-make-keywords-re nil
	 (set-difference nonkeyword-prefix-ops in-or-postfix-ops
			 :test 'string-equal))
       "\\|"
       ;; Match string and character literals.
       "\\s\""
       (if (memq 'gen-string-delim c-emacs-features)
	   "\\|\\s|"
	 ""))))
(c-lang-defvar c-primary-expr-regexp (c-lang-const c-primary-expr-regexp))
;;; Additional constants for parser-level constructs.
(c-lang-defconst c-decl-prefix-re
  "Regexp matching something that might precede a declaration, cast or
label, such as the last token of a preceding statement or declaration.
This is used in the common situation where a declaration or cast
doesn't start with any specific token that can be searched for.
The regexp should not match bob; that is done implicitly.  It can't
require a match longer than one token.  The end of the token is taken
to be at the end of the first submatch, which is assumed to always
match.  It's undefined whether identifier syntax (see
`c-identifier-syntax-table') is in effect or not.  This regexp is
assumed to be a superset of `c-label-prefix-re' if
`c-recognize-colon-labels' is set.
Besides this, `c-decl-start-kwds' is used to find declarations.
Note: This variable together with `c-decl-start-re' and
`c-decl-start-kwds' is only used to detect \"likely\"
declaration/cast/label starts.  I.e. they might produce more matches
but should not miss anything (or else it's necessary to use text
properties - see the next note).  Wherever they match, the following
construct is analyzed to see if it indeed is a declaration, cast or
label.  That analysis is not cheap, so it's important that not too
many false matches are triggered.
Note: If a declaration/cast/label start can't be detected with this
variable, it's necessary to use the `c-type' text property with the
value `c-decl-end' on the last char of the last token preceding the
declaration.  See the comment blurb at the start of cc-engine.el for
more info."
  ;; We match a sequence of characters to skip over things like \"};\"
  ;; more quickly.  We match ")" in C for K&R region declarations, and
  ;; in all languages except Java for when a cpp macro definition
  ;; begins with a declaration.
  t "\\([\{\}\(\);,]+\\)"
  java "\\([\{\}\(;,]+\\)"
  ;; Match "<" in C++ to get the first argument in a template arglist.
  ;; In that case there's an additional check in `c-find-decl-spots'
  ;; that it got open paren syntax.
  c++ "\\([\{\}\(\);,<]+\\)"
  ;; Additionally match the protection directives in Objective-C.
  ;; Note that this doesn't cope with the longer directives, which we
  ;; would have to match from start to end since they don't end with
  ;; any easily recognized characters.
  objc (concat "\\([\{\}\(\);,]+\\|"
	       (c-make-keywords-re nil (c-lang-const c-protection-kwds))
	       "\\)")
  ;; Pike is like C but we also match "[" for multiple value
  ;; assignments and type casts.
  pike "\\([\{\}\(\)\[;,]+\\)")
(c-lang-defvar c-decl-prefix-re (c-lang-const c-decl-prefix-re)
  'dont-doc)
(c-lang-defconst c-decl-start-re
  "Regexp matching the start of any declaration, cast or label.
It's used on the token after the one `c-decl-prefix-re' matched.  This
regexp should not try to match those constructs accurately as it's
only used as a sieve to avoid spending more time checking other
constructs."
  t (c-lang-const c-identifier-start))
(c-lang-defvar c-decl-start-re (c-lang-const c-decl-start-re))
(c-lang-defconst c-decl-prefix-or-start-re
  ;; Regexp matching something that might precede or start a
  ;; declaration, cast or label.
  ;;
  ;; If the first submatch matches, it's taken to match the end of a
  ;; token that might precede such a construct, e.g. ';', '}' or '{'.
  ;; It's built from `c-decl-prefix-re'.
  ;;
  ;; If the first submatch did not match, the match of the whole
  ;; regexp is taken to be at the first token in the declaration.
  ;; `c-decl-start-re' is not checked in this case.
  ;;
  ;; Design note: The reason the same regexp is used to match both
  ;; tokens that precede declarations and start them is to avoid an
  ;; extra regexp search from the previous declaration spot in
  ;; `c-find-decl-spots'.  Users of `c-find-decl-spots' also count on
  ;; that it finds all declaration/cast/label starts in approximately
  ;; linear order, so we can't do the searches in two separate passes.
  t (if (c-lang-const c-decl-start-kwds)
	(concat (c-lang-const c-decl-prefix-re)
		"\\|"
		(c-make-keywords-re t (c-lang-const c-decl-start-kwds)))
      (c-lang-const c-decl-prefix-re)))
(c-lang-defvar c-decl-prefix-or-start-re
  (c-lang-const c-decl-prefix-or-start-re)
  'dont-doc)
(c-lang-defconst c-cast-parens
  ;; List containing the paren characters that can open a cast, or nil in
  ;; languages without casts.
  t (c-filter-ops (c-lang-const c-operators)
		  '(prefix)
		  "\\`\\s\(\\'"
		  (lambda (op) (elt op 0))))
(c-lang-defvar c-cast-parens (c-lang-const c-cast-parens))
(c-lang-defconst c-block-prefix-disallowed-chars
  "List of syntactically relevant characters that never can occur before
the open brace in any construct that contains a brace block, e.g. in
the \"class Foo: public Bar\" part of:
    class Foo: public Bar {int x();} a, *b;
If parens can occur, the chars inside those aren't filtered with this
list.
'<' and '>' should be disallowed even if angle bracket arglists can
occur.  That since the search function needs to stop at them anyway to
ensure they are given paren syntax.
This is used to skip backward from the open brace to find the region
in which to look for a construct like \"class\", \"enum\",
\"namespace\" or whatever.  That skipping should be as tight as
possible for good performance."
  ;; Default to all chars that only occurs in nonsymbol tokens outside
  ;; identifiers.
  t (set-difference
     (c-lang-const c-nonsymbol-token-char-list)
     (c-filter-ops (append (c-lang-const c-identifier-ops)
			   (list (cons nil
				       (c-lang-const c-after-id-concat-ops))))
		   t
		   t
		   (lambda (op)
		     (let ((pos 0) res)
		       (while (string-match "\\(\\s.\\|\\s(\\|\\s)\\)"
					    op pos)
			 (setq res (cons (aref op (match-beginning 1)) res)
			       pos (match-end 0)))
		       res))))
  ;; Allow cpp operatios (where applicable).
  t (if (c-lang-const c-opt-cpp-prefix)
	(set-difference (c-lang-const c-block-prefix-disallowed-chars)
			'(?#))
      (c-lang-const c-block-prefix-disallowed-chars))
  ;; Allow ':' for inherit list starters.
  (c++ objc idl) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
				 '(?:))
  ;; Allow ',' for multiple inherits.
  (c++ java) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
			     '(?,))
  ;; Allow parentheses for anonymous inner classes in Java and class
  ;; initializer lists in Pike.
  (java pike) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
			      '(?\( ?\)))
  ;; Allow '"' for extern clauses (e.g. extern "C" {...}).
  (c c++ objc) (set-difference (c-lang-const c-block-prefix-disallowed-chars)
			       '(?\" ?')))
(c-lang-defconst c-block-prefix-charset
  ;; `c-block-prefix-disallowed-chars' as an inverted charset suitable
  ;; for `c-syntactic-skip-backward'.
  t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t))
(c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset))
(c-lang-defconst c-type-decl-prefix-key
  "Regexp matching the declarator operators that might precede the
identifier in a declaration, e.g. the \"*\" in \"char *argv\".  This
regexp should match \"(\" if parentheses are valid in declarators.
The end of the first submatch is taken as the end of the operator.
Identifier syntax is in effect when this is matched \(see
`c-identifier-syntax-table')."
  t (if (c-lang-const c-type-modifier-kwds)
	(concat (regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>")
      ;; Default to a regexp that never matches.
      "\\<\\>")
  ;; Check that there's no "=" afterwards to avoid matching tokens
  ;; like "*=".
  (c objc) (concat "\\("
		   "[*\(]"
		   "\\|"
		   (c-lang-const c-type-decl-prefix-key)
		   "\\)"
		   "\\([^=]\\|$\\)")
  c++  (concat "\\("
	       "[*\(&]"
	       "\\|"
	       (concat "\\("	; 2
		       ;; If this matches there's special treatment in
		       ;; `c-font-lock-declarators' and
		       ;; `c-font-lock-declarations' that check for a
		       ;; complete name followed by ":: *".
		       (c-lang-const c-identifier-start)
		       "\\)")
	       "\\|"
	       (c-lang-const c-type-decl-prefix-key)
	       "\\)"
	       "\\([^=]\\|$\\)")
  pike "\\(\\*\\)\\([^=]\\|$\\)")
(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
  'dont-doc)
(c-lang-defconst c-type-decl-suffix-key
  "Regexp matching the declarator operators that might follow after the
identifier in a declaration, e.g. the \"[\" in \"char argv[]\".  This
regexp should match \")\" if parentheses are valid in declarators.  If
it matches an open paren of some kind, the type declaration check
continues at the corresponding close paren, otherwise the end of the
first submatch is taken as the end of the operator.  Identifier syntax
is in effect when this is matched (see `c-identifier-syntax-table')."
  ;; Default to a regexp that matches `c-type-modifier-kwds' and a
  ;; function argument list parenthesis.
  t    (if (c-lang-const c-type-modifier-kwds)
	   (concat "\\(\(\\|"
		   (regexp-opt (c-lang-const c-type-modifier-kwds) t) "\\>"
		   "\\)")
	 "\\(\(\\)")
  (c c++ objc) (concat
		"\\("
		"[\)\[\(]"
		(if (c-lang-const c-type-modifier-kwds)
		    (concat
		     "\\|"
		     ;; "throw" in `c-type-modifier-kwds' is followed
		     ;; by a parenthesis list, but no extra measures
		     ;; are necessary to handle that.
		     (regexp-opt (c-lang-const c-type-modifier-kwds) t)
		     "\\>")
		  "")
		"\\)")
  (java idl) "\\([\[\(]\\)")
(c-lang-defvar c-type-decl-suffix-key (c-lang-const c-type-decl-suffix-key)
  'dont-doc)
(c-lang-defconst c-after-suffixed-type-decl-key
  "This regexp is matched after a declarator expression where
`c-type-decl-suffix-key' has matched.  If it matches then the
construct is taken as a declaration.  It's typically used to match the
beginning of a function body or whatever might occur after the
function header in a function declaration or definition.  It's
undefined whether identifier syntax (see `c-identifier-syntax-table')
is in effect or not.
Note that it's used in cases like after \"foo (bar)\" so it should
only match when it's certain that it's a declaration, e.g \"{\" but
not \",\" or \";\"."
  t "{"
  ;; If K&R style declarations should be recognized then one could
  ;; consider to match the start of any symbol since we want to match
  ;; the start of the first declaration in the "K&R region".  That
  ;; could however produce false matches on code like "FOO(bar) x"
  ;; where FOO is a cpp macro, so it's better to leave it out and rely
  ;; on the other heuristics in that case.
  t (if (c-lang-const c-postfix-spec-kwds)
	;; Add on the keywords in `c-postfix-spec-kwds'.
	(concat (c-lang-const c-after-suffixed-type-decl-key)
		"\\|"
		(c-make-keywords-re t (c-lang-const c-postfix-spec-kwds)))
      (c-lang-const c-after-suffixed-type-decl-key))
  ;; Also match the colon that starts a base class initializer list in
  ;; C++.  That can be confused with a function call before the colon
  ;; in a ? : operator, but we count on that `c-decl-prefix-re' won't
  ;; match before such a thing (as a declaration-level construct;
  ;; matches inside arglist contexts are already excluded).
  c++ "[{:]")
(c-lang-defvar c-after-suffixed-type-decl-key
  (c-lang-const c-after-suffixed-type-decl-key)
  'dont-doc)
(c-lang-defconst c-after-suffixed-type-maybe-decl-key
  ;; Regexp that in addition to `c-after-suffixed-type-decl-key'
  ;; matches ";" and ",".
  t (concat "\\(" (c-lang-const c-after-suffixed-type-decl-key) "\\)"
	    "\\|[;,]"))
(c-lang-defvar c-after-suffixed-type-maybe-decl-key
  (c-lang-const c-after-suffixed-type-maybe-decl-key))
(c-lang-defconst c-opt-type-concat-key
  "Regexp matching operators that concatenate types, e.g. the \"|\" in
\"int|string\" in Pike.  The end of the first submatch is taken as the
end of the operator.  nil in languages without such operators.  It's
undefined whether identifier syntax (see `c-identifier-syntax-table')
is in effect or not."
  t nil
  pike "\\([|.&]\\)\\($\\|[^|.&]\\)")
(c-lang-defvar c-opt-type-concat-key (c-lang-const c-opt-type-concat-key)
  'dont-doc)
(c-lang-defconst c-opt-type-suffix-key
  "Regexp matching operators that might follow after a type, or nil in
languages that don't have such operators.  The end of the first
submatch is taken as the end of the operator.  This should not match
things like C++ template arglists if `c-recognize-<>-arglists' is set.
It's undefined whether identifier syntax (see `c-identifier-syntax-table')
is in effect or not."
  t nil
  (c c++ objc pike) "\\(\\.\\.\\.\\)"
  java (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\)"))
(c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key))
(c-lang-defvar c-known-type-key
  ;; Regexp matching the known type identifiers.  This is initialized
  ;; from the type keywords and `*-font-lock-extra-types'.  The first
  ;; submatch is the one that matches the type.  Note that this regexp
  ;; assumes that symbol constituents like '_' and '$' have word
  ;; syntax.
  (let* ((extra-types
	  (when (boundp (c-mode-symbol "font-lock-extra-types"))
	    (c-mode-var "font-lock-extra-types")))
	 (regexp-strings
	  (apply 'nconc
		 (mapcar (lambda (re)
		    (when (string-match "[][.*+?^$\\]" re)
		      (list re)))
		  extra-types)))
	 (plain-strings
	  (apply 'nconc
		 (mapcar (lambda (re)
		    (unless (string-match "[][.*+?^$\\]" re)
		      (list re)))
		  extra-types))))
    (concat "\\<\\("
	    (c-concat-separated
	     (append (list (c-make-keywords-re nil
			     (append (c-lang-const c-primitive-type-kwds)
				     plain-strings)))
		     regexp-strings)
	     "\\|")
	    "\\)\\>")))
(c-lang-defconst c-special-brace-lists
"List of open- and close-chars that makes up a pike-style brace list,
i.e. for a ([]) list there should be a cons (?\\[ . ?\\]) in this
list."
  t    nil
  pike '((?{ . ?}) (?\[ . ?\]) (?< . ?>)))
(c-lang-defvar c-special-brace-lists (c-lang-const c-special-brace-lists))
(c-lang-defconst c-recognize-knr-p
  "Non-nil means K&R style argument declarations are valid."
  t nil
  c t)
(c-lang-defvar c-recognize-knr-p (c-lang-const c-recognize-knr-p))
(c-lang-defconst c-recognize-typeless-decls
  "Non-nil means function declarations without return type should be
recognized.  That can introduce an ambiguity with parenthesized macro
calls before a brace block.  This setting does not affect declarations
that are preceded by a declaration starting keyword, so
e.g. `c-typeless-decl-kwds' may still be used when it's set to nil."
  t nil
  (c c++ objc) t)
(c-lang-defvar c-recognize-typeless-decls
  (c-lang-const c-recognize-typeless-decls))
(c-lang-defconst c-recognize-<>-arglists
  "Non-nil means C++ style template arglists should be handled.  More
specifically, this means a comma separated list of types or
expressions surrounded by \"<\" and \">\".  It's always preceded by an
identifier or one of the keywords on `c-<>-type-kwds' or
`c-<>-arglist-kwds'.  If there's an identifier before then the whole
expression is considered to be a type."
  t (or (consp (c-lang-const c-<>-type-kwds))
	(consp (c-lang-const c-<>-arglist-kwds))))
(c-lang-defvar c-recognize-<>-arglists (c-lang-const c-recognize-<>-arglists))
(c-lang-defconst c-recognize-paren-inits
  "Non-nil means that parenthesis style initializers exist,
i.e. constructs like
Foo bar (gnu);
in addition to the more classic
Foo bar = gnu;"
  t nil
  c++ t)
(c-lang-defvar c-recognize-paren-inits (c-lang-const c-recognize-paren-inits))
(c-lang-defconst c-recognize-paren-inexpr-blocks
  "Non-nil to recognize gcc style in-expression blocks,
i.e. compound statements surrounded by parentheses inside expressions."
  t nil
  (c c++) t)
(c-lang-defvar c-recognize-paren-inexpr-blocks
  (c-lang-const c-recognize-paren-inexpr-blocks))
(c-lang-defconst c-opt-<>-arglist-start
  ;; Regexp matching the start of angle bracket arglists in languages
  ;; where `c-recognize-<>-arglists' is set.  Does not exclude
  ;; keywords outside `c-<>-arglist-kwds'.  The first submatch is
  ;; assumed to surround the preceding symbol.  The whole match is
  ;; assumed to end directly after the opening "<".
  t (if (c-lang-const c-recognize-<>-arglists)
	(concat "\\("
		(c-lang-const c-symbol-key)
		"\\)"
		(c-lang-const c-syntactic-ws)
		"<")))
(c-lang-defvar c-opt-<>-arglist-start (c-lang-const c-opt-<>-arglist-start))
(c-lang-defconst c-opt-<>-arglist-start-in-paren
  ;; Regexp that in addition to `c-opt-<>-arglist-start' matches close
  ;; parens.  The first submatch is assumed to surround
  ;; `c-opt-<>-arglist-start'.
  t (if (c-lang-const c-opt-<>-arglist-start)
	(concat "\\("
		(c-lang-const c-opt-<>-arglist-start)
		"\\)\\|\\s\)")))
(c-lang-defvar c-opt-<>-arglist-start-in-paren
  (c-lang-const c-opt-<>-arglist-start-in-paren))
(c-lang-defconst c-opt-postfix-decl-spec-key
  ;; Regexp matching the beginning of a declaration specifier in the
  ;; region between the header and the body of a declaration.
  ;;
  ;; TODO: This is currently not used uniformly; c++-mode and
  ;; java-mode each have their own ways of using it.
  t    nil
  c++  (concat ":?"
	       (c-lang-const c-simple-ws) "*"
	       "\\(virtual" (c-lang-const c-simple-ws) "+\\)?\\("
	       (c-make-keywords-re nil (c-lang-const c-protection-kwds))
	       "\\)" (c-lang-const c-simple-ws) "+"
	       "\\(" (c-lang-const c-symbol-key) "\\)")
  java (c-make-keywords-re t (c-lang-const c-postfix-spec-kwds)))
(c-lang-defvar c-opt-postfix-decl-spec-key
  (c-lang-const c-opt-postfix-decl-spec-key))
(c-lang-defconst c-recognize-colon-labels
  "Non-nil if generic labels ending with \":\" should be recognized.
That includes labels in code and access keys in classes.  This does
not apply to labels recognized by `c-label-kwds' and
`c-opt-extra-label-key'."
  t nil
  (c c++ objc java pike) t)
(c-lang-defvar c-recognize-colon-labels
  (c-lang-const c-recognize-colon-labels))
(c-lang-defconst c-label-prefix-re
  "Regexp like `c-decl-prefix-re' that matches any token that can precede
a generic colon label.  Not used if `c-recognize-colon-labels' is
nil."
  t "\\([{};]+\\)")
(c-lang-defvar c-label-prefix-re
  (c-lang-const c-label-prefix-re))
(c-lang-defconst c-nonlabel-token-key
  "Regexp matching things that can't occur in generic colon labels,
neither in a statement nor in a declaration context.  The regexp is
tested at the beginning of every sexp in a suspected label,
i.e. before \":\".  Only used if `c-recognize-colon-labels' is set."
  t (concat
     ;; Don't allow string literals.
     "[\"']\\|"
     ;; All keywords except `c-label-kwds' and `c-protection-kwds'.
     (c-make-keywords-re t
       (set-difference (c-lang-const c-keywords)
		       (append (c-lang-const c-label-kwds)
			       (c-lang-const c-protection-kwds))
		       :test 'string-equal)))
  ;; Also check for open parens in C++, to catch member init lists in
  ;; constructors.  We normally allow it so that macros with arguments
  ;; work in labels.
  c++ (concat "\\s\(\\|" (c-lang-const c-nonlabel-token-key)))
(c-lang-defvar c-nonlabel-token-key (c-lang-const c-nonlabel-token-key))
(c-lang-defconst c-opt-extra-label-key
  "Optional regexp matching labels.
Normally, labels are detected according to `c-nonlabel-token-key',
`c-decl-prefix-re' and `c-nonlabel-decl-prefix-re'.  This regexp can
be used if there are additional labels that aren't recognized that
way."
  t    nil
  objc (c-make-keywords-re t (c-lang-const c-protection-kwds)))
(c-lang-defvar c-opt-extra-label-key (c-lang-const c-opt-extra-label-key))
(c-lang-defconst c-opt-friend-key
  ;; Regexp describing friend declarations classes, or nil in
  ;; languages that don't have such things.
  ;;
  ;; TODO: Ought to use `c-prefix-spec-kwds-re' or similar, and the
  ;; template skipping isn't done properly.  This will disappear soon.
  t    nil
  c++  (concat "friend" (c-lang-const c-simple-ws) "+"
	       "\\|"
	       (concat "template"
		       (c-lang-const c-simple-ws) "*"
		       "<.+>"
		       (c-lang-const c-simple-ws) "*"
		       "friend"
		       (c-lang-const c-simple-ws) "+")))
(c-lang-defvar c-opt-friend-key (c-lang-const c-opt-friend-key))
(c-lang-defconst c-opt-method-key
  ;; Special regexp to match the start of Objective-C methods.  The
  ;; first submatch is assumed to end after the + or - key.
  t    nil
  objc (concat
	;; TODO: Ought to use a better method than anchoring on bol.
	"^\\s *"
	"\\([+-]\\)"
	(c-lang-const c-simple-ws) "*"
	(concat "\\("			; Return type.
		"([^\)]*)"
		(c-lang-const c-simple-ws) "*"
		"\\)?")
	"\\(" (c-lang-const c-symbol-key) "\\)"))
(c-lang-defvar c-opt-method-key (c-lang-const c-opt-method-key))
(c-lang-defconst c-type-decl-end-used
  ;; Must be set in buffers where the `c-type' text property might be
  ;; used with the value `c-decl-end'.
  ;;
  ;; `c-decl-end' is used to mark the ends of labels and access keys
  ;; to make interactive refontification work better.
  t (or (c-lang-const c-recognize-colon-labels)
	(and (c-lang-const c-label-kwds) t))
  ;; `c-decl-end' is used to mark the end of the @-style directives in
  ;; Objective-C.
  objc t)
(c-lang-defvar c-type-decl-end-used (c-lang-const c-type-decl-end-used))
;;; Wrap up the `c-lang-defvar' system.
;; Compile in the list of language variables that has been collected
;; with the `c-lang-defvar' and `c-lang-setvar' macros.  Note that the
;; first element of each is nil.
(defconst c-lang-variable-inits (cc-eval-when-compile c-lang-variable-inits))
(defconst c-emacs-variable-inits (cc-eval-when-compile c-emacs-variable-inits))
;; Make the `c-lang-setvar' variables buffer local in the current buffer.
;; These are typically standard emacs variables such as `comment-start'.
(defmacro c-make-emacs-variables-local ()
  `(progn
     ,@(mapcar (lambda (init)
		 `(make-local-variable ',(car init)))
	       (cdr c-emacs-variable-inits))))
(defun c-make-init-lang-vars-fun (mode)
  "Create a function that initializes all the language dependent variables
for the given mode.
This function should be evaluated at compile time, so that the
function it returns is byte compiled with all the evaluated results
from the language constants.  Use the `c-init-language-vars' macro to
accomplish that conveniently."
  (if (and (not load-in-progress)
	   (boundp 'byte-compile-dest-file)
	   (stringp byte-compile-dest-file))
      ;; No need to byte compile this lambda since the byte compiler is
      ;; smart enough to detect the `funcall' construct in the
      ;; `c-init-language-vars' macro below and compile it all straight
      ;; into the function that contains `c-init-language-vars'.
      `(lambda ()
	 ;; This let sets up the context for `c-mode-var' and similar
	 ;; that could be in the result from `cl-macroexpand-all'.
	 (let ((c-buffer-is-cc-mode ',mode)
	       current-var source-eval)
	   (c-make-emacs-variables-local)
	   (condition-case err
	       (if (eq c-version-sym ',c-version-sym)
		   (setq ,@(let ((c-buffer-is-cc-mode mode)
				 (c-lang-const-expansion 'immediate))
			     ;; `c-lang-const' will expand to the evaluated
			     ;; constant immediately in `cl-macroexpand-all'
			     ;; below.
			      (mapcan
			       (lambda (init)
				 `(current-var ',(car init)
				   ,(car init) ,(cl-macroexpand-all
						 (elt init 1))))
			       ;; Note: The following `append' copies the
			       ;; first argument.  That list is small, so
			       ;; this doesn't matter too much.
			      (append (cdr c-emacs-variable-inits)
				      (cdr c-lang-variable-inits)))))
		 ;; This diagnostic message isn't useful for end
		 ;; users, so it's disabled.
		 ;;(unless (get ',mode 'c-has-warned-lang-consts)
		 ;;  (message ,(concat "%s compiled with CC Mode %s "
		 ;;		       "but loaded with %s - evaluating "
		 ;;		       "language constants from source")
		 ;;	      ',mode ,c-version c-version)
		 ;;  (put ',mode 'c-has-warned-lang-consts t))
		 (require 'cc-langs)
		 (setq source-eval t)
		 (let ((init (append (cdr c-emacs-variable-inits)
				     (cdr c-lang-variable-inits))))
		   (while init
		     (setq current-var (caar init))
		     (set (caar init) (eval (cadar init)))
		     (setq init (cdr init)))))
	     (error
	      (if current-var
		  (message "Eval error in the `c-lang-defvar' or `c-lang-setvar' for `%s'%s: %S"
			   current-var
			   (if source-eval
			       (format "\
 (fallback source eval - %s compiled with CC Mode %s but loaded with %s)"
				       ',mode ,c-version c-version)
			     "")
			   err)
		(signal (car err) (cdr err)))))))
    ;; Being evaluated from source.  Always use the dynamic method to
    ;; work well when `c-lang-defvar's in this file are reevaluated
    ;; interactively.
    `(lambda ()
       (require 'cc-langs)
       (let ((c-buffer-is-cc-mode ',mode)
	     (init (append (cdr c-emacs-variable-inits)
			   (cdr c-lang-variable-inits)))
	     current-var)
	 (c-make-emacs-variables-local)
	 (condition-case err
	     (while init
	       (setq current-var (caar init))
	       (set (caar init) (eval (cadar init)))
	       (setq init (cdr init)))
	   (error
	    (if current-var
		(message
		 "Eval error in the `c-lang-defvar' or `c-lang-setver' for `%s' (source eval): %S"
		 current-var err)
	      (signal (car err) (cdr err)))))))
    ))
(defmacro c-init-language-vars (mode)
  "Initialize all the language dependent variables for the given mode.
This macro is expanded at compile time to a form tailored for the mode
in question, so MODE must be a constant.  Therefore MODE is not
evaluated and should not be quoted."
  `(funcall ,(c-make-init-lang-vars-fun mode)))
(cc-provide 'cc-langs)
;;; arch-tag: 1ab57482-cfc2-4c5b-b628-3539c3098822
;;; cc-langs.el ends here
 |