TableGen: support #ifndef in addition to #ifdef.

TableGen has a limited preprocessor, which only really supports
easier.

llvm-svn: 360670
This commit is contained in:
Tim Northover 2019-05-14 13:04:25 +00:00
parent 62f5b591f4
commit 717b62a146
6 changed files with 33 additions and 7 deletions

View File

@ -36,6 +36,7 @@ struct {
const char *Word;
} PreprocessorDirs[] = {
{ tgtok::Ifdef, "ifdef" },
{ tgtok::Ifndef, "ifndef" },
{ tgtok::Else, "else" },
{ tgtok::Endif, "endif" },
{ tgtok::Define, "define" }
@ -676,21 +677,28 @@ tgtok::TokKind TGLexer::lexPreprocessor(
PrintFatalError("lexPreprocessor() called for unknown "
"preprocessor directive");
if (Kind == tgtok::Ifdef) {
if (Kind == tgtok::Ifdef || Kind == tgtok::Ifndef) {
StringRef MacroName = prepLexMacroName();
StringRef IfTokName = Kind == tgtok::Ifdef ? "#ifdef" : "#ifndef";
if (MacroName.empty())
return ReturnError(TokStart, "Expected macro name after #ifdef");
return ReturnError(TokStart, "Expected macro name after " + IfTokName);
bool MacroIsDefined = DefinedMacros.count(MacroName) != 0;
// Canonicalize ifndef to ifdef equivalent
if (Kind == tgtok::Ifndef) {
MacroIsDefined = !MacroIsDefined;
Kind = tgtok::Ifdef;
}
// Regardless of whether we are processing tokens or not,
// we put the #ifdef control on stack.
PrepIncludeStack.back()->push_back(
{Kind, MacroIsDefined, SMLoc::getFromPointer(TokStart)});
if (!prepSkipDirectiveEnd())
return ReturnError(CurPtr,
"Only comments are supported after #ifdef NAME");
return ReturnError(CurPtr, "Only comments are supported after " +
IfTokName + " NAME");
// If we were not processing tokens before this #ifdef,
// then just return back to the lines skipping code.
@ -714,7 +722,7 @@ tgtok::TokKind TGLexer::lexPreprocessor(
// Check if this #else is correct before calling prepSkipDirectiveEnd(),
// which will move CurPtr away from the beginning of #else.
if (PrepIncludeStack.back()->empty())
return ReturnError(TokStart, "#else without #ifdef");
return ReturnError(TokStart, "#else without #ifdef or #ifndef");
PreprocessorControlDesc IfdefEntry = PrepIncludeStack.back()->back();

View File

@ -65,7 +65,7 @@ namespace tgtok {
// Preprocessing tokens for internal usage by the lexer.
// They are never returned as a result of Lex().
Ifdef, Else, Endif, Define
Ifdef, Ifndef, Else, Endif, Define
};
}

View File

@ -1,6 +1,6 @@
// RUN: not llvm-tblgen -I %p %s 2>&1 | FileCheck %s
// CHECK: error: #else without #ifdef
// CHECK: error: #else without #ifdef or #ifndef
#else
#else
#endif

View File

@ -0,0 +1,4 @@
// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s
// CHECK: error: Expected macro name after #ifndef
#ifndef 1

View File

@ -0,0 +1,4 @@
// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s
// CHECK: error: Only comments are supported after #ifndef NAME
#ifndef MACRO 42

View File

@ -0,0 +1,10 @@
// RUN: llvm-tblgen %s -DMACRO | FileCheck %s
// RUN: llvm-tblgen %s | FileCheck %s --check-prefix=CHECK-NOMACRO
#ifndef MACRO
// CHECK-NOMACRO: def nomacro
def nomacro;
#else
// CHECK: def macro
def macro;
#endif