[llvm] [NFC][TableGen] Make PreprocessDirs array constexpr (PR #102967)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 12 14:48:23 PDT 2024
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/102967
>From 5477e0c079bd61285d1c1ad61c6d87254a2ed9b1 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Sun, 11 Aug 2024 15:59:33 -0700
Subject: [PATCH] [NFC][TableGen] Make PreprocessDirs array constexpr
- Make `PreprocessorDirs` array constexpr, move its definition outside the
anonymous namespace, and make it static.
- Change `Word` field to a StringRef.
- Simplify `prepIsDirective` to use StringRef comparison and early `continue`
per LLVM coding standards.
- Use C++17 structured bindings to iterate over the array.
---
llvm/lib/TableGen/TGLexer.cpp | 98 ++++++++++++++++-------------------
1 file changed, 44 insertions(+), 54 deletions(-)
diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index 99d866a23a68ba..6e2483a7f1423f 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -32,18 +32,19 @@ using namespace llvm;
namespace {
// A list of supported preprocessing directives with their
// internal token kinds and names.
-struct {
+struct PreprocessorDir {
tgtok::TokKind Kind;
- const char *Word;
-} PreprocessorDirs[] = {
- { tgtok::Ifdef, "ifdef" },
- { tgtok::Ifndef, "ifndef" },
- { tgtok::Else, "else" },
- { tgtok::Endif, "endif" },
- { tgtok::Define, "define" }
+ StringRef Word;
};
} // end anonymous namespace
+static constexpr PreprocessorDir PreprocessorDirs[] = {
+ {tgtok::Ifdef, "ifdef"},
+ {tgtok::Ifndef, "ifndef"},
+ {tgtok::Else, "else"},
+ {tgtok::Endif, "endif"},
+ {tgtok::Define, "define"}};
+
TGLexer::TGLexer(SourceMgr &SM, ArrayRef<std::string> Macros) : SrcMgr(SM) {
CurBuffer = SrcMgr.getMainFileID();
CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer();
@@ -641,54 +642,43 @@ bool TGLexer::prepExitInclude(bool IncludeStackMustBeEmpty) {
}
tgtok::TokKind TGLexer::prepIsDirective() const {
- for (const auto &PD : PreprocessorDirs) {
- int NextChar = *CurPtr;
- bool Match = true;
- unsigned I = 0;
- for (; I < strlen(PD.Word); ++I) {
- if (NextChar != PD.Word[I]) {
- Match = false;
- break;
- }
-
- NextChar = peekNextChar(I + 1);
- }
+ for (const auto [Kind, Word] : PreprocessorDirs) {
+ if (StringRef(CurPtr, Word.size()) != Word)
+ continue;
+ char NextChar = peekNextChar(Word.size());
- // Check for whitespace after the directive. If there is no whitespace,
+ // Check for whitespace after the directive. If there is no whitespace,
// then we do not recognize it as a preprocessing directive.
- if (Match) {
- tgtok::TokKind Kind = PD.Kind;
-
- // New line and EOF may follow only #else/#endif. It will be reported
- // as an error for #ifdef/#define after the call to prepLexMacroName().
- if (NextChar == ' ' || NextChar == '\t' || NextChar == EOF ||
- NextChar == '\n' ||
- // It looks like TableGen does not support '\r' as the actual
- // carriage return, e.g. getNextChar() treats a single '\r'
- // as '\n'. So we do the same here.
- NextChar == '\r')
- return Kind;
- // Allow comments after some directives, e.g.:
- // #else// OR #else/**/
- // #endif// OR #endif/**/
- //
- // Note that we do allow comments after #ifdef/#define here, e.g.
- // #ifdef/**/ AND #ifdef//
- // #define/**/ AND #define//
- //
- // These cases will be reported as incorrect after calling
- // prepLexMacroName(). We could have supported C-style comments
- // after #ifdef/#define, but this would complicate the code
- // for little benefit.
- if (NextChar == '/') {
- NextChar = peekNextChar(I + 1);
+ // New line and EOF may follow only #else/#endif. It will be reported
+ // as an error for #ifdef/#define after the call to prepLexMacroName().
+ if (NextChar == ' ' || NextChar == '\t' || NextChar == EOF ||
+ NextChar == '\n' ||
+ // It looks like TableGen does not support '\r' as the actual
+ // carriage return, e.g. getNextChar() treats a single '\r'
+ // as '\n'. So we do the same here.
+ NextChar == '\r')
+ return Kind;
- if (NextChar == '*' || NextChar == '/')
- return Kind;
+ // Allow comments after some directives, e.g.:
+ // #else// OR #else/**/
+ // #endif// OR #endif/**/
+ //
+ // Note that we do allow comments after #ifdef/#define here, e.g.
+ // #ifdef/**/ AND #ifdef//
+ // #define/**/ AND #define//
+ //
+ // These cases will be reported as incorrect after calling
+ // prepLexMacroName(). We could have supported C-style comments
+ // after #ifdef/#define, but this would complicate the code
+ // for little benefit.
+ if (NextChar == '/') {
+ NextChar = peekNextChar(Word.size() + 1);
+
+ if (NextChar == '*' || NextChar == '/')
+ return Kind;
- // Pretend that we do not recognize the directive.
- }
+ // Pretend that we do not recognize the directive.
}
}
@@ -698,10 +688,10 @@ tgtok::TokKind TGLexer::prepIsDirective() const {
bool TGLexer::prepEatPreprocessorDirective(tgtok::TokKind Kind) {
TokStart = CurPtr;
- for (const auto &PD : PreprocessorDirs)
- if (PD.Kind == Kind) {
+ for (const auto [PKind, PWord] : PreprocessorDirs)
+ if (PKind == Kind) {
// Advance CurPtr to the end of the preprocessing word.
- CurPtr += strlen(PD.Word);
+ CurPtr += PWord.size();
return true;
}
More information about the llvm-commits
mailing list