Index: utils/TableGen/TGLexer.cpp |
=================================================================== |
--- utils/TableGen/TGLexer.cpp (revision 138929) |
+++ utils/TableGen/TGLexer.cpp (working copy) |
@@ -18,6 +18,7 @@ |
#include "llvm/Config/config.h" |
#include "llvm/ADT/StringSwitch.h" |
#include "llvm/ADT/Twine.h" |
+#include <algorithm> |
#include <cctype> |
#include <cstdio> |
#include <cstdlib> |
@@ -25,7 +26,8 @@ |
#include <cerrno> |
using namespace llvm; |
-TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) { |
+TGLexer::TGLexer(SourceMgr &SM, std::vector<std::string> PPD) |
+ : SrcMgr(SM), PreProcDefines(PPD) { |
CurBuffer = 0; |
CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); |
CurPtr = CurBuf->getBufferStart(); |
@@ -36,6 +38,11 @@ |
return SMLoc::getFromPointer(TokStart); |
} |
+bool TGLexer::hasPreProcDefine(const std::string &define) const { |
+ return std::find(PreProcDefines.begin(), PreProcDefines.end(), |
+ define) != PreProcDefines.end(); |
+} |
+ |
/// ReturnError - Set the error to the specified string at the specified |
/// location. This is defined to always return tgtok::Error. |
tgtok::TokKind TGLexer::ReturnError(const char *Loc, const Twine &Msg) { |
@@ -235,6 +242,10 @@ |
if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let; |
if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In; |
+ if (Len == 10 && !memcmp(IdentStart, "include_if", 10)) { |
+ if (LexIncludeIf()) return tgtok::Error; |
+ return Lex(); |
+ } |
if (Len == 7 && !memcmp(IdentStart, "include", 7)) { |
if (LexInclude()) return tgtok::Error; |
return Lex(); |
@@ -244,6 +255,39 @@ |
return tgtok::Id; |
} |
+/// LexIncludeIf - We just read the "include_if" token. Get the next two |
+/// string tokens. The first is the pre-processor symbol required, and the |
+/// next is the filename. Finally enter the include only if the |
+/// pre-processor symbol was defined at the command-line. |
+bool TGLexer::LexIncludeIf() { |
+ |
+ // The next two token after the include must be strings. |
+ tgtok::TokKind PreProcTok = LexToken(); |
+ if (PreProcTok == tgtok::Error) return true; |
+ if (PreProcTok != tgtok::StrVal) { |
+ PrintError(getLoc(), "Expected pre-proc symbol after include_if"); |
+ return true; |
+ } |
+ // Get the string. |
+ std::string PreProcSymbol = CurStrVal; |
+ |
+ // The token after the include must be a string. |
+ tgtok::TokKind FileTok = LexToken(); |
+ if (FileTok == tgtok::Error) return true; |
+ if (FileTok != tgtok::StrVal) { |
+ PrintError(getLoc(), "Expected filename after include_if"); |
+ return true; |
+ } |
+ |
+ // Get the string. |
+ std::string Filename = CurStrVal; |
+ if (hasPreProcDefine(PreProcSymbol)) |
+ return AddIncludeFile(Filename); |
+ else { |
+ return false; |
+ } |
+} |
+ |
/// LexInclude - We just read the "include" token. Get the string token that |
/// comes next and enter the include. |
bool TGLexer::LexInclude() { |
@@ -257,16 +301,18 @@ |
// Get the string. |
std::string Filename = CurStrVal; |
+ return AddIncludeFile(Filename); |
+} |
+ |
+bool TGLexer::AddIncludeFile(const std::string &Filename) { |
std::string IncludedFile; |
- |
- |
CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr), |
IncludedFile); |
if (CurBuffer == -1) { |
PrintError(getLoc(), "Could not find include file '" + Filename + "'"); |
return true; |
} |
- |
+ |
Dependencies.push_back(IncludedFile); |
// Save the line number and lex buffer of the includer. |
CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); |
@@ -432,4 +478,3 @@ |
return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator"); |
} |
- |