@@ -575,6 +575,48 @@ void Lexer::lexIdentifier() {
575
575
return formToken (Kind, TokStart);
576
576
}
577
577
578
+ // / lexHash - Handle #], #! for shebangs, and the family of #identifiers.
579
+ void Lexer::lexHash () {
580
+ const char *TokStart = CurPtr-1 ;
581
+ if (*CurPtr == ' ]' ) { // #]
582
+ CurPtr++;
583
+ return formToken (tok::r_square_lit, TokStart);
584
+ }
585
+
586
+ // Allow a hashbang #! line at the beginning of the file.
587
+ if (CurPtr - 1 == BufferStart && *CurPtr == ' !' ) {
588
+ CurPtr--;
589
+ if (BufferID != SourceMgr.getHashbangBufferID ())
590
+ diagnose (CurPtr, diag::lex_hashbang_not_allowed);
591
+ skipHashbang ();
592
+ return lexImpl ();
593
+ }
594
+
595
+ // Scan for [a-z]+ to see what we match.
596
+ const char *tmpPtr = CurPtr;
597
+ while (clang::isLowercase (*tmpPtr))
598
+ ++tmpPtr;
599
+
600
+ // Map the character sequence onto
601
+ tok Kind = llvm::StringSwitch<tok>(StringRef (CurPtr, tmpPtr-CurPtr))
602
+ #define KEYWORD (kw )
603
+ #define POUND_KEYWORD (id ) \
604
+ .Case (#id, tok::pound_##id)
605
+ #include " swift/Parse/Tokens.def"
606
+ .Default (tok::pound);
607
+
608
+ // If we didn't find a match, then just return tok::pound. This is highly
609
+ // dubious in terms of error recovery, but is useful for code completion and
610
+ // SIL parsing.
611
+ if (Kind == tok::pound)
612
+ return formToken (tok::pound, TokStart);
613
+
614
+ // If we found something specific, return it.
615
+ CurPtr = tmpPtr;
616
+ return formToken (Kind, TokStart);
617
+ }
618
+
619
+
578
620
// / Is the operator beginning at the given character "left-bound"?
579
621
static bool isLeftBound (const char *tokBegin, const char *bufferBegin) {
580
622
// The first character in the file is not left-bound.
@@ -1584,65 +1626,10 @@ void Lexer::lexImpl() {
1584
1626
case ' ;' : return formToken (tok::semi, TokStart);
1585
1627
case ' :' : return formToken (tok::colon, TokStart);
1586
1628
1587
- case ' #' : {
1588
- if (*CurPtr == ' ]' ) { // #]
1589
- CurPtr++;
1590
- return formToken (tok::r_square_lit, TokStart);
1591
- }
1592
-
1593
- if (getSubstring (TokStart + 1 , 2 ).equals (" if" ) &&
1594
- isWhitespace (CurPtr[2 ])) {
1595
- CurPtr += 2 ;
1596
- return formToken (tok::pound_if, TokStart);
1597
- }
1598
-
1599
- if (getSubstring (TokStart + 1 , 4 ).equals (" else" ) &&
1600
- isWhitespace (CurPtr[4 ])) {
1601
- CurPtr += 4 ;
1602
- return formToken (tok::pound_else, TokStart);
1603
- }
1604
-
1605
- if (getSubstring (TokStart + 1 , 6 ).equals (" elseif" ) &&
1606
- isWhitespace (CurPtr[6 ])) {
1607
- CurPtr += 6 ;
1608
- return formToken (tok::pound_elseif, TokStart);
1609
- }
1610
-
1611
- if (getSubstring (TokStart + 1 , 5 ).equals (" endif" ) &&
1612
- (isWhitespace (CurPtr[5 ]) || CurPtr[5 ] == ' \0 ' )) {
1613
- CurPtr += 5 ;
1614
- return formToken (tok::pound_endif, TokStart);
1615
- }
1616
-
1617
- if (getSubstring (TokStart + 1 , 4 ).equals (" line" ) &&
1618
- isWhitespace (CurPtr[4 ])) {
1619
- CurPtr += 4 ;
1620
- return formToken (tok::pound_line, TokStart);
1621
- }
1622
-
1623
- if (getSubstring (TokStart + 1 , 9 ).equals (" available" )) {
1624
- CurPtr += 9 ;
1625
- return formToken (tok::pound_available, TokStart);
1626
- }
1627
-
1628
- if (getSubstring (TokStart + 1 , 8 ).equals (" selector" )) {
1629
- CurPtr += 8 ;
1630
- return formToken (tok::pound_selector, TokStart);
1631
- }
1632
-
1633
- // Allow a hashbang #! line at the beginning of the file.
1634
- if (CurPtr - 1 == BufferStart && *CurPtr == ' !' ) {
1635
- CurPtr--;
1636
- if (BufferID != SourceMgr.getHashbangBufferID ())
1637
- diagnose (CurPtr, diag::lex_hashbang_not_allowed);
1638
- skipHashbang ();
1639
- goto Restart;
1640
- }
1641
-
1642
- return formToken (tok::pound, TokStart);
1643
- }
1629
+ case ' #' :
1630
+ return lexHash ();
1644
1631
1645
- // Operator characters.
1632
+ // Operator characters.
1646
1633
case ' /' :
1647
1634
if (CurPtr[0 ] == ' /' ) { // "//"
1648
1635
skipSlashSlashComment ();
0 commit comments