@@ -32,18 +32,18 @@ using namespace llvm;
3232namespace {
3333// A list of supported preprocessing directives with their
3434// internal token kinds and names.
35- struct {
35+ struct PreprocessorDir {
3636 tgtok::TokKind Kind;
37- const char *Word;
38- } PreprocessorDirs[] = {
39- { tgtok::Ifdef, " ifdef" },
40- { tgtok::Ifndef, " ifndef" },
41- { tgtok::Else, " else" },
42- { tgtok::Endif, " endif" },
43- { tgtok::Define, " define" }
37+ StringRef Word;
4438};
4539} // end anonymous namespace
4640
41+ constexpr PreprocessorDir PreprocessorDirs[] = {{tgtok::Ifdef, " ifdef" },
42+ {tgtok::Ifndef, " ifndef" },
43+ {tgtok::Else, " else" },
44+ {tgtok::Endif, " endif" },
45+ {tgtok::Define, " define" }};
46+
4747TGLexer::TGLexer (SourceMgr &SM, ArrayRef<std::string> Macros) : SrcMgr(SM) {
4848 CurBuffer = SrcMgr.getMainFileID ();
4949 CurBuf = SrcMgr.getMemoryBuffer (CurBuffer)->getBuffer ();
@@ -641,54 +641,43 @@ bool TGLexer::prepExitInclude(bool IncludeStackMustBeEmpty) {
641641}
642642
643643tgtok::TokKind TGLexer::prepIsDirective () const {
644- for (const auto &PD : PreprocessorDirs) {
645- int NextChar = *CurPtr;
646- bool Match = true ;
647- unsigned I = 0 ;
648- for (; I < strlen (PD.Word ); ++I) {
649- if (NextChar != PD.Word [I]) {
650- Match = false ;
651- break ;
652- }
653-
654- NextChar = peekNextChar (I + 1 );
655- }
644+ for (const auto [Kind, Word] : PreprocessorDirs) {
645+ if (StringRef (CurPtr, Word.size ()) != Word)
646+ continue ;
647+ char NextChar = peekNextChar (Word.size ());
656648
657- // Check for whitespace after the directive. If there is no whitespace,
649+ // Check for whitespace after the directive. If there is no whitespace,
658650 // then we do not recognize it as a preprocessing directive.
659- if (Match) {
660- tgtok::TokKind Kind = PD.Kind ;
661-
662- // New line and EOF may follow only #else/#endif. It will be reported
663- // as an error for #ifdef/#define after the call to prepLexMacroName().
664- if (NextChar == ' ' || NextChar == ' \t ' || NextChar == EOF ||
665- NextChar == ' \n ' ||
666- // It looks like TableGen does not support '\r' as the actual
667- // carriage return, e.g. getNextChar() treats a single '\r'
668- // as '\n'. So we do the same here.
669- NextChar == ' \r ' )
670- return Kind;
671651
672- // Allow comments after some directives, e.g.:
673- // #else// OR #else/**/
674- // #endif// OR #endif/**/
675- //
676- // Note that we do allow comments after #ifdef/#define here, e.g.
677- // #ifdef/**/ AND #ifdef//
678- // #define/**/ AND #define//
679- //
680- // These cases will be reported as incorrect after calling
681- // prepLexMacroName(). We could have supported C-style comments
682- // after #ifdef/#define, but this would complicate the code
683- // for little benefit.
684- if (NextChar == ' /' ) {
685- NextChar = peekNextChar (I + 1 );
652+ // New line and EOF may follow only #else/#endif. It will be reported
653+ // as an error for #ifdef/#define after the call to prepLexMacroName().
654+ if (NextChar == ' ' || NextChar == ' \t ' || NextChar == EOF ||
655+ NextChar == ' \n ' ||
656+ // It looks like TableGen does not support '\r' as the actual
657+ // carriage return, e.g. getNextChar() treats a single '\r'
658+ // as '\n'. So we do the same here.
659+ NextChar == ' \r ' )
660+ return Kind;
686661
687- if (NextChar == ' *' || NextChar == ' /' )
688- return Kind;
662+ // Allow comments after some directives, e.g.:
663+ // #else// OR #else/**/
664+ // #endif// OR #endif/**/
665+ //
666+ // Note that we do allow comments after #ifdef/#define here, e.g.
667+ // #ifdef/**/ AND #ifdef//
668+ // #define/**/ AND #define//
669+ //
670+ // These cases will be reported as incorrect after calling
671+ // prepLexMacroName(). We could have supported C-style comments
672+ // after #ifdef/#define, but this would complicate the code
673+ // for little benefit.
674+ if (NextChar == ' /' ) {
675+ NextChar = peekNextChar (Word.size () + 1 );
676+
677+ if (NextChar == ' *' || NextChar == ' /' )
678+ return Kind;
689679
690- // Pretend that we do not recognize the directive.
691- }
680+ // Pretend that we do not recognize the directive.
692681 }
693682 }
694683
@@ -698,10 +687,10 @@ tgtok::TokKind TGLexer::prepIsDirective() const {
698687bool TGLexer::prepEatPreprocessorDirective (tgtok::TokKind Kind) {
699688 TokStart = CurPtr;
700689
701- for (const auto &PD : PreprocessorDirs)
702- if (PD. Kind == Kind) {
690+ for (const auto [PKind, PWord] : PreprocessorDirs)
691+ if (PKind == Kind) {
703692 // Advance CurPtr to the end of the preprocessing word.
704- CurPtr += strlen (PD. Word );
693+ CurPtr += PWord. size ( );
705694 return true ;
706695 }
707696
0 commit comments