17 #include "llvm/Config/config.h"
47 int TGLexer::getNextChar() {
48 char CurChar = *CurPtr++;
51 return (
unsigned char)CurChar;
61 if (ParentIncludeLoc !=
SMLoc()) {
77 if ((*CurPtr ==
'\n' || (*CurPtr ==
'\r')) &&
84 int TGLexer::peekNextChar(
int Index) {
85 return *(CurPtr + Index);
91 int CurChar = getNextChar();
96 if (isalpha(CurChar) || CurChar ==
'_')
97 return LexIdentifier();
100 return ReturnError(TokStart,
"Unexpected character");
129 else if (*CurPtr ==
'*') {
133 return ReturnError(TokStart,
"Unexpected character");
136 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
137 case '7':
case '8':
case '9': {
145 NextChar = peekNextChar(i++);
148 if (NextChar ==
'x' || NextChar ==
'b') {
151 int NextNextChar = peekNextChar(i);
152 switch (NextNextChar) {
159 case '2':
case '3':
case '4':
case '5':
160 case '6':
case '7':
case '8':
case '9':
161 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
162 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
170 if (isalpha(NextChar) || NextChar ==
'_')
171 return LexIdentifier();
175 case '"':
return LexString();
176 case '$':
return LexVarName();
177 case '[':
return LexBracket();
178 case '!':
return LexExclaim();
184 const char *StrStart = CurPtr;
188 while (*CurPtr !=
'"') {
191 return ReturnError(StrStart,
"End of file in string literal");
193 if (*CurPtr ==
'\n' || *CurPtr ==
'\r')
194 return ReturnError(StrStart,
"End of line in string literal");
196 if (*CurPtr !=
'\\') {
197 CurStrVal += *CurPtr++;
204 case '\\':
case '\'':
case '"':
206 CurStrVal += *CurPtr++;
219 return ReturnError(CurPtr,
"escaped newlines not supported in tblgen");
224 return ReturnError(StrStart,
"End of file in string literal");
227 return ReturnError(CurPtr,
"invalid escape in string literal");
236 if (!isalpha(CurPtr[0]) && CurPtr[0] !=
'_')
237 return ReturnError(TokStart,
"Invalid variable name");
240 const char *VarNameStart = CurPtr++;
242 while (isalpha(*CurPtr) ||
isdigit(*CurPtr) || *CurPtr ==
'_')
245 CurStrVal.assign(VarNameStart, CurPtr);
252 const char *IdentStart = TokStart;
255 while (isalpha(*CurPtr) ||
isdigit(*CurPtr) || *CurPtr ==
'_')
259 StringRef Str(IdentStart, CurPtr-IdentStart);
261 if (Str ==
"include") {
285 CurStrVal.assign(Str.begin(), Str.end());
291 bool TGLexer::LexInclude() {
301 std::string Filename = CurStrVal;
302 std::string IncludedFile;
307 if (CurBuffer == -1) {
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()));
327 void TGLexer::SkipBCPLComment() {
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, 0, 16);
394 return ReturnError(TokStart,
"Invalid hexadecimal number");
395 if (errno == ERANGE) {
397 CurIntVal = (int64_t)
strtoull(NumStart, 0, 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, 0, 2);
420 if (CurPtr[-1] ==
'-')
422 else if (CurPtr[-1] ==
'+')
428 CurIntVal =
strtoll(TokStart, 0, 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))
484 return Kind !=
tgtok::Error ? Kind : ReturnError(Start-1,
"Unknown operator");
TGLexer(SourceMgr &SrcMgr)
const char * getPointer() const
const char * getBufferStart() const
StringSwitch & Case(const char(&S)[N], const T &Value)
size_t AddIncludeFile(const std::string &Filename, SMLoc IncludeLoc, std::string &IncludedFile)
long long int strtoll(const char *nptr, char **endptr, int base);
A switch()-like statement whose cases are string literals.
SMLoc getParentIncludeLoc(unsigned i) const
R Default(const T &Value) const
static SMLoc getFromPointer(const char *Ptr)
const MemoryBuffer * getMemoryBuffer(unsigned i) const
int FindBufferContainingLoc(SMLoc Loc) const
const char * getBufferEnd() const
void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges=None, ArrayRef< SMFixIt > FixIts=None, bool ShowColors=true) const
Represents a location in source code.
void PrintError(ArrayRef< SMLoc > ErrorLoc, const Twine &Msg)