17 #include "llvm/Config/config.h" 38 } PreprocessorDirs[] = {
49 CurPtr = CurBuf.
begin();
53 PrepIncludeStack.push_back(
54 make_unique<std::vector<PreprocessorControlDesc>>());
58 [
this](
const std::string &MacroName) {
59 DefinedMacros.
insert(MacroName);
78 bool TGLexer::processEOF() {
80 if (ParentIncludeLoc !=
SMLoc()) {
85 if (!prepExitInclude(
false))
101 prepExitInclude(
true);
105 int TGLexer::getNextChar() {
106 char CurChar = *CurPtr++;
109 return (
unsigned char)CurChar;
113 if (CurPtr-1 != CurBuf.
end())
125 if ((*CurPtr ==
'\n' || (*CurPtr ==
'\r')) &&
132 int TGLexer::peekNextChar(
int Index)
const {
133 return *(CurPtr +
Index);
139 int CurChar = getNextChar();
144 if (isalpha(CurChar) || CurChar ==
'_')
145 return LexIdentifier();
148 return ReturnError(TokStart,
"Unexpected character");
175 if (FileOrLineStart) {
178 return lexPreprocessor(Kind);
191 return LexToken(FileOrLineStart);
194 return LexToken(
true);
200 else if (*CurPtr ==
'*') {
204 return ReturnError(TokStart,
"Unexpected character");
205 return LexToken(FileOrLineStart);
207 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
208 case '7':
case '8':
case '9': {
210 if (isdigit(CurChar)) {
216 NextChar = peekNextChar(i++);
217 }
while (isdigit(NextChar));
219 if (NextChar ==
'x' || NextChar ==
'b') {
222 int NextNextChar = peekNextChar(i);
223 switch (NextNextChar) {
230 case '2':
case '3':
case '4':
case '5':
231 case '6':
case '7':
case '8':
case '9':
232 case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
233 case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
241 if (isalpha(NextChar) || NextChar ==
'_')
242 return LexIdentifier();
246 case '"':
return LexString();
247 case '$':
return LexVarName();
248 case '[':
return LexBracket();
249 case '!':
return LexExclaim();
255 const char *StrStart = CurPtr;
259 while (*CurPtr !=
'"') {
261 if (*CurPtr == 0 && CurPtr == CurBuf.
end())
262 return ReturnError(StrStart,
"End of file in string literal");
264 if (*CurPtr ==
'\n' || *CurPtr ==
'\r')
265 return ReturnError(StrStart,
"End of line in string literal");
267 if (*CurPtr !=
'\\') {
268 CurStrVal += *CurPtr++;
275 case '\\':
case '\'':
case '"':
277 CurStrVal += *CurPtr++;
290 return ReturnError(CurPtr,
"escaped newlines not supported in tblgen");
294 if (CurPtr == CurBuf.
end())
295 return ReturnError(StrStart,
"End of file in string literal");
298 return ReturnError(CurPtr,
"invalid escape in string literal");
307 if (!isalpha(CurPtr[0]) && CurPtr[0] !=
'_')
308 return ReturnError(TokStart,
"Invalid variable name");
311 const char *VarNameStart = CurPtr++;
313 while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr ==
'_')
316 CurStrVal.assign(VarNameStart, CurPtr);
322 const char *IdentStart = TokStart;
325 while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr ==
'_')
329 StringRef Str(IdentStart, CurPtr-IdentStart);
331 if (Str ==
"include") {
356 CurStrVal.assign(Str.
begin(), Str.
end());
362 bool TGLexer::LexInclude() {
372 std::string Filename = CurStrVal;
373 std::string IncludedFile;
382 DependenciesMapTy::const_iterator Found = Dependencies.find(IncludedFile);
383 if (Found != Dependencies.end()) {
385 "File '" + IncludedFile +
"' has already been included.");
387 "previously included here");
390 Dependencies.insert(std::make_pair(IncludedFile,
getLoc()));
393 CurPtr = CurBuf.
begin();
395 PrepIncludeStack.push_back(
396 make_unique<std::vector<PreprocessorControlDesc>>());
400 void TGLexer::SkipBCPLComment() {
409 if (CurPtr == CurBuf.
end())
420 bool TGLexer::SkipCComment() {
422 unsigned CommentDepth = 1;
425 int CurChar = getNextChar();
428 PrintError(TokStart,
"Unterminated comment!");
432 if (CurPtr[0] !=
'/')
break;
435 if (--CommentDepth == 0)
440 if (CurPtr[0] !=
'*')
break;
453 if (CurPtr[-1] ==
'0') {
454 if (CurPtr[0] ==
'x') {
456 const char *NumStart = CurPtr;
457 while (isxdigit(CurPtr[0]))
461 if (CurPtr == NumStart)
462 return ReturnError(TokStart,
"Invalid hexadecimal number");
465 CurIntVal = strtoll(NumStart,
nullptr, 16);
467 return ReturnError(TokStart,
"Invalid hexadecimal number");
468 if (errno == ERANGE) {
470 CurIntVal = (int64_t)strtoull(NumStart,
nullptr, 16);
472 return ReturnError(TokStart,
"Invalid hexadecimal number");
474 return ReturnError(TokStart,
"Hexadecimal number out of range");
477 }
else if (CurPtr[0] ==
'b') {
479 const char *NumStart = CurPtr;
480 while (CurPtr[0] ==
'0' || CurPtr[0] ==
'1')
484 if (CurPtr == NumStart)
485 return ReturnError(CurPtr-2,
"Invalid binary number");
486 CurIntVal = strtoll(NumStart,
nullptr, 2);
492 if (!isdigit(CurPtr[0])) {
493 if (CurPtr[-1] ==
'-')
495 else if (CurPtr[-1] ==
'+')
499 while (isdigit(CurPtr[0]))
501 CurIntVal = strtoll(TokStart,
nullptr, 10);
508 if (CurPtr[0] !=
'{')
511 const char *CodeStart = CurPtr;
513 int Char = getNextChar();
514 if (Char == EOF)
break;
516 if (Char !=
'}')
continue;
518 Char = getNextChar();
519 if (Char == EOF)
break;
521 CurStrVal.assign(CodeStart, CurPtr-2);
526 return ReturnError(CodeStart-2,
"Unterminated Code Block");
531 if (!isalpha(*CurPtr))
532 return ReturnError(CurPtr - 1,
"Invalid \"!operator\"");
534 const char *Start = CurPtr++;
535 while (isalpha(*CurPtr))
569 return Kind !=
tgtok::Error ?
Kind : ReturnError(Start-1,
"Unknown operator");
572 bool TGLexer::prepExitInclude(
bool IncludeStackMustBeEmpty) {
575 if (!PrepIncludeStack.back()->empty()) {
576 prepReportPreprocessorStackError();
582 if (PrepIncludeStack.empty()) {
586 PrepIncludeStack.pop_back();
588 if (IncludeStackMustBeEmpty) {
589 if (!PrepIncludeStack.empty())
592 if (PrepIncludeStack.empty())
601 int NextChar = *CurPtr;
604 for (; I < strlen(PreprocessorDirs[
ID].
Word); ++
I) {
605 if (NextChar != PreprocessorDirs[
ID].Word[I]) {
610 NextChar = peekNextChar(I + 1);
620 if (NextChar ==
' ' || NextChar ==
'\t' || NextChar == EOF ||
640 if (NextChar ==
'/') {
641 NextChar = peekNextChar(I + 1);
643 if (NextChar ==
'*' || NextChar ==
'/')
658 if (PreprocessorDirs[
ID].Kind == Kind) {
660 CurPtr += strlen(PreprocessorDirs[
ID].
Word);
665 "prepEatPreprocessorDirective()");
673 if (!prepEatPreprocessorDirective(
Kind))
675 "preprocessor directive");
678 StringRef MacroName = prepLexMacroName();
679 if (MacroName.
empty())
680 return ReturnError(TokStart,
"Expected macro name after #ifdef");
682 bool MacroIsDefined = DefinedMacros.
count(MacroName) != 0;
686 PrepIncludeStack.back()->push_back(
689 if (!prepSkipDirectiveEnd())
690 return ReturnError(CurPtr,
691 "Only comments are supported after #ifdef NAME");
695 if (!ReturnNextLiveToken)
707 if (prepSkipRegion(ReturnNextLiveToken))
714 if (PrepIncludeStack.back()->empty())
715 return ReturnError(TokStart,
"#else without #ifdef");
717 PreprocessorControlDesc IfdefEntry = PrepIncludeStack.back()->back();
721 return ReturnError(IfdefEntry.SrcPos,
"Previous #else is here");
726 PrepIncludeStack.back()->pop_back();
727 PrepIncludeStack.back()->push_back(
730 if (!prepSkipDirectiveEnd())
731 return ReturnError(CurPtr,
"Only comments are supported after #else");
735 if (ReturnNextLiveToken) {
736 if (prepSkipRegion(ReturnNextLiveToken))
747 if (PrepIncludeStack.back()->empty())
748 return ReturnError(TokStart,
"#endif without #ifdef");
750 auto &IfdefOrElseEntry = PrepIncludeStack.back()->back();
758 if (!prepSkipDirectiveEnd())
759 return ReturnError(CurPtr,
"Only comments are supported after #endif");
761 PrepIncludeStack.back()->pop_back();
765 if (ReturnNextLiveToken) {
772 StringRef MacroName = prepLexMacroName();
773 if (MacroName.
empty())
774 return ReturnError(TokStart,
"Expected macro name after #define");
776 if (!DefinedMacros.
insert(MacroName).second)
778 "Duplicate definition of macro: " +
Twine(MacroName));
780 if (!prepSkipDirectiveEnd())
781 return ReturnError(CurPtr,
782 "Only comments are supported after #define NAME");
784 if (!ReturnNextLiveToken) {
796 bool TGLexer::prepSkipRegion(
bool MustNeverBeFalse) {
797 if (!MustNeverBeFalse)
805 if (!prepSkipLineBegin())
833 if (Kind != ProcessedKind)
835 "returned different token kinds");
841 if (prepIsProcessingEnabled()) {
844 "preprocessing directive");
850 }
while (CurPtr != CurBuf.
end());
854 prepReportPreprocessorStackError();
860 while (*CurPtr ==
' ' || *CurPtr ==
'\t')
865 if (*CurPtr !=
'_' && !isalpha(*CurPtr))
869 while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr ==
'_')
872 return StringRef(TokStart, CurPtr - TokStart);
875 bool TGLexer::prepSkipLineBegin() {
876 while (CurPtr != CurBuf.
end()) {
885 int NextChar = peekNextChar(1);
886 if (NextChar ==
'*') {
924 bool TGLexer::prepSkipDirectiveEnd() {
925 while (CurPtr != CurBuf.
end()) {
936 int NextChar = peekNextChar(1);
937 if (NextChar ==
'/') {
943 }
else if (NextChar ==
'*') {
985 void TGLexer::prepSkipToLineEnd() {
986 while (*CurPtr !=
'\n' && *CurPtr !=
'\r' && CurPtr != CurBuf.
end())
990 bool TGLexer::prepIsProcessingEnabled() {
991 for (
auto I = PrepIncludeStack.back()->rbegin(),
992 E = PrepIncludeStack.back()->rend();
1001 void TGLexer::prepReportPreprocessorStackError() {
1002 if (PrepIncludeStack.back()->empty())
1004 "empty control stack");
1006 auto &PrepControl = PrepIncludeStack.back()->back();
1007 PrintError(CurBuf.
end(),
"Reached EOF without matching #endif");
1008 PrintError(PrepControl.SrcPos,
"The latest preprocessor control is here");
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
StringRef getBuffer() const
This class represents lattice values for constants.
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
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.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
support::ulittle32_t Word
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
const MemoryBuffer * getMemoryBuffer(unsigned i) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
unsigned getMainFileID() const
const char * getPointer() const
A switch()-like statement whose cases are string literals.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
TGLexer(SourceMgr &SrcMgr, ArrayRef< std::string > Macros)
void PrintWarning(ArrayRef< SMLoc > WarningLoc, const Twine &Msg)
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
std::pair< typename base::iterator, bool > insert(StringRef Key)
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
LLVM_ATTRIBUTE_NORETURN void PrintFatalError(const Twine &Msg)
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
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...
SMLoc getParentIncludeLoc(unsigned i) const
StringRef - Represent a constant reference to a string, i.e.
UnaryPredicate for_each(R &&Range, UnaryPredicate P)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly...
Represents a location in source code.
void PrintError(ArrayRef< SMLoc > ErrorLoc, const Twine &Msg)