17 #include "llvm/Config/config.h"
34 CurPtr = CurBuf.
begin();
49 int TGLexer::getNextChar() {
50 char CurChar = *CurPtr++;
53 return (
unsigned char)CurChar;
57 if (CurPtr-1 != CurBuf.
end())
63 if (ParentIncludeLoc !=
SMLoc()) {
79 if ((*CurPtr ==
'\n' || (*CurPtr ==
'\r')) &&
86 int TGLexer::peekNextChar(
int Index) {
87 return *(CurPtr + Index);
93 int CurChar = getNextChar();
98 if (isalpha(CurChar) || CurChar ==
'_')
99 return LexIdentifier();
102 return ReturnError(TokStart,
"Unexpected character");
131 else if (*CurPtr ==
'*') {
135 return ReturnError(TokStart,
"Unexpected character");
138 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
139 case '7':
case '8':
case '9': {
141 if (isdigit(CurChar)) {
147 NextChar = peekNextChar(i++);
148 }
while (isdigit(NextChar));
150 if (NextChar ==
'x' || NextChar ==
'b') {
153 int NextNextChar = peekNextChar(i);
154 switch (NextNextChar) {
161 case '2':
case '3':
case '4':
case '5':
162 case '6':
case '7':
case '8':
case '9':
163 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
164 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
172 if (isalpha(NextChar) || NextChar ==
'_')
173 return LexIdentifier();
177 case '"':
return LexString();
178 case '$':
return LexVarName();
179 case '[':
return LexBracket();
180 case '!':
return LexExclaim();
186 const char *StrStart = CurPtr;
190 while (*CurPtr !=
'"') {
192 if (*CurPtr == 0 && CurPtr == CurBuf.
end())
193 return ReturnError(StrStart,
"End of file in string literal");
195 if (*CurPtr ==
'\n' || *CurPtr ==
'\r')
196 return ReturnError(StrStart,
"End of line in string literal");
198 if (*CurPtr !=
'\\') {
199 CurStrVal += *CurPtr++;
206 case '\\':
case '\'':
case '"':
208 CurStrVal += *CurPtr++;
221 return ReturnError(CurPtr,
"escaped newlines not supported in tblgen");
225 if (CurPtr == CurBuf.
end())
226 return ReturnError(StrStart,
"End of file in string literal");
229 return ReturnError(CurPtr,
"invalid escape in string literal");
238 if (!isalpha(CurPtr[0]) && CurPtr[0] !=
'_')
239 return ReturnError(TokStart,
"Invalid variable name");
242 const char *VarNameStart = CurPtr++;
244 while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr ==
'_')
247 CurStrVal.assign(VarNameStart, CurPtr);
253 const char *IdentStart = TokStart;
256 while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr ==
'_')
260 StringRef Str(IdentStart, CurPtr-IdentStart);
262 if (Str ==
"include") {
286 CurStrVal.assign(Str.begin(), Str.end());
292 bool TGLexer::LexInclude() {
302 std::string Filename = CurStrVal;
303 std::string IncludedFile;
312 DependenciesMapTy::const_iterator Found = Dependencies.find(IncludedFile);
313 if (Found != Dependencies.end()) {
315 "File '" + IncludedFile +
"' has already been included.");
317 "previously included here");
320 Dependencies.insert(std::make_pair(IncludedFile,
getLoc()));
323 CurPtr = CurBuf.
begin();
327 void TGLexer::SkipBCPLComment() {
336 if (CurPtr == CurBuf.
end())
347 bool TGLexer::SkipCComment() {
349 unsigned CommentDepth = 1;
352 int CurChar = getNextChar();
355 PrintError(TokStart,
"Unterminated comment!");
359 if (CurPtr[0] !=
'/')
break;
362 if (--CommentDepth == 0)
367 if (CurPtr[0] !=
'*')
break;
380 if (CurPtr[-1] ==
'0') {
381 if (CurPtr[0] ==
'x') {
383 const char *NumStart = CurPtr;
384 while (isxdigit(CurPtr[0]))
388 if (CurPtr == NumStart)
389 return ReturnError(TokStart,
"Invalid hexadecimal number");
392 CurIntVal = strtoll(NumStart,
nullptr, 16);
394 return ReturnError(TokStart,
"Invalid hexadecimal number");
395 if (errno == ERANGE) {
397 CurIntVal = (int64_t)strtoull(NumStart,
nullptr, 16);
399 return ReturnError(TokStart,
"Invalid hexadecimal number");
401 return ReturnError(TokStart,
"Hexadecimal number out of range");
404 }
else if (CurPtr[0] ==
'b') {
406 const char *NumStart = CurPtr;
407 while (CurPtr[0] ==
'0' || CurPtr[0] ==
'1')
411 if (CurPtr == NumStart)
412 return ReturnError(CurPtr-2,
"Invalid binary number");
413 CurIntVal = strtoll(NumStart,
nullptr, 2);
419 if (!isdigit(CurPtr[0])) {
420 if (CurPtr[-1] ==
'-')
422 else if (CurPtr[-1] ==
'+')
426 while (isdigit(CurPtr[0]))
428 CurIntVal = strtoll(TokStart,
nullptr, 10);
435 if (CurPtr[0] !=
'{')
438 const char *CodeStart = CurPtr;
440 int Char = getNextChar();
441 if (Char == EOF)
break;
443 if (Char !=
'}')
continue;
445 Char = getNextChar();
446 if (Char == EOF)
break;
448 CurStrVal.assign(CodeStart, CurPtr-2);
453 return ReturnError(CodeStart-2,
"Unterminated Code Block");
458 if (!isalpha(*CurPtr))
459 return ReturnError(CurPtr - 1,
"Invalid \"!operator\"");
461 const char *Start = CurPtr++;
462 while (isalpha(*CurPtr))
487 return Kind !=
tgtok::Error ? Kind : ReturnError(Start-1,
"Unknown operator");
TGLexer(SourceMgr &SrcMgr)
const char * getPointer() const
StringRef getBuffer() const
unsigned getMainFileID() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
A switch()-like statement whose cases are string literals.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
SMLoc getParentIncludeLoc(unsigned i) const
static SMLoc getFromPointer(const char *Ptr)
unsigned AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
Search for a file with the specified name in the current directory or in one of the IncludeDirs...
const MemoryBuffer * getMemoryBuffer(unsigned i) const
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
StringRef - Represent a constant reference to a string, i.e.
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Emit a message about the specified location with the specified string.
Represents a location in source code.
void PrintError(ArrayRef< SMLoc > ErrorLoc, const Twine &Msg)