@@ -575,6 +575,48 @@ void Lexer::lexIdentifier() {
575575 return formToken (Kind, TokStart);
576576}
577577
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+
578620// / Is the operator beginning at the given character "left-bound"?
579621static bool isLeftBound (const char *tokBegin, const char *bufferBegin) {
580622 // The first character in the file is not left-bound.
@@ -1584,65 +1626,10 @@ void Lexer::lexImpl() {
15841626 case ' ;' : return formToken (tok::semi, TokStart);
15851627 case ' :' : return formToken (tok::colon, TokStart);
15861628
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 ();
16441631
1645- // Operator characters.
1632+ // Operator characters.
16461633 case ' /' :
16471634 if (CurPtr[0 ] == ' /' ) { // "//"
16481635 skipSlashSlashComment ();
0 commit comments