114 MAI.useAtForSpecifier();
115 LexMotorolaIntegers = MAI.shouldUseMotorolaIntegers();
121 bool EndStatementAtEOF) {
125 "Buffer provided to AsmLexer lacks null terminator.");
132 CurPtr = CurBuf.begin();
135 this->EndStatementAtEOF = EndStatementAtEOF;
140AsmToken AsmLexer::ReturnError(
const char *
Loc,
const std::string &
Msg) {
146int AsmLexer::getNextChar() {
147 if (CurPtr == CurBuf.
end())
149 return (
unsigned char)*CurPtr++;
152int AsmLexer::peekNextChar() {
153 if (CurPtr == CurBuf.end())
155 return (
unsigned char)*CurPtr;
161AsmToken AsmLexer::LexFloatLiteral() {
166 if (*CurPtr ==
'-' || *CurPtr ==
'+')
167 return ReturnError(CurPtr,
"invalid sign in float literal");
170 if ((*CurPtr ==
'e' || *CurPtr ==
'E')) {
173 if (*CurPtr ==
'-' || *CurPtr ==
'+')
181 StringRef(TokStart, CurPtr - TokStart));
190AsmToken AsmLexer::LexHexFloatLiteral(
bool NoIntDigits) {
191 assert((*CurPtr ==
'p' || *CurPtr ==
'P' || *CurPtr ==
'.') &&
192 "unexpected parse state in floating hex");
193 bool NoFracDigits =
true;
196 if (*CurPtr ==
'.') {
199 const char *FracStart = CurPtr;
203 NoFracDigits = CurPtr == FracStart;
206 if (NoIntDigits && NoFracDigits)
207 return ReturnError(TokStart,
"invalid hexadecimal floating-point constant: "
208 "expected at least one significand digit");
211 if (*CurPtr !=
'p' && *CurPtr !=
'P')
212 return ReturnError(TokStart,
"invalid hexadecimal floating-point constant: "
213 "expected exponent part 'p'");
216 if (*CurPtr ==
'+' || *CurPtr ==
'-')
220 const char *ExpStart = CurPtr;
224 if (CurPtr == ExpStart)
225 return ReturnError(TokStart,
"invalid hexadecimal floating-point constant: "
226 "expected at least one exponent digit");
228 return AsmToken(
AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
233 if (CurPtr[-1] ==
'.' &&
isDigit(*CurPtr)) {
239 AllowHashInIdentifier) ||
240 *CurPtr ==
'e' || *CurPtr ==
'E')
241 return LexFloatLiteral();
244 while (
isIdentifierChar(*CurPtr, AllowAtInIdentifier, AllowHashInIdentifier))
248 if (CurPtr == TokStart+1 && TokStart[0] ==
'.')
258 if (!MAI.shouldAllowAdditionalComments()) {
259 IsAtStartOfStatement =
false;
265 IsAtStartOfStatement =
false;
269 return LexLineComment();
271 IsAtStartOfStatement =
false;
277 const char *CommentTextStart = CurPtr;
278 while (CurPtr != CurBuf.end()) {
285 if (CommentConsumer) {
286 CommentConsumer->HandleComment(
288 StringRef(CommentTextStart, CurPtr - 1 - CommentTextStart));
292 StringRef(TokStart, CurPtr - TokStart));
295 return ReturnError(TokStart,
"unterminated comment");
300AsmToken AsmLexer::LexLineComment() {
305 const char *CommentTextStart = CurPtr;
306 int CurChar = getNextChar();
307 while (CurChar !=
'\n' && CurChar !=
'\r' && CurChar != EOF)
308 CurChar = getNextChar();
309 const char *NewlinePtr = CurPtr;
310 if (CurChar ==
'\r' && CurPtr != CurBuf.end() && *CurPtr ==
'\n')
314 if (CommentConsumer) {
315 CommentConsumer->HandleComment(
317 StringRef(CommentTextStart, NewlinePtr - 1 - CommentTextStart));
320 IsAtStartOfLine =
true;
322 if (IsAtStartOfStatement)
324 StringRef(TokStart, CurPtr - TokStart));
325 IsAtStartOfStatement =
true;
328 StringRef(TokStart, CurPtr - 1 - TokStart));
333 if (CurPtr[0] ==
'U' || CurPtr[0] ==
'u')
335 if (CurPtr[0] ==
'L' || CurPtr[0] ==
'l')
337 if (CurPtr[0] ==
'L' || CurPtr[0] ==
'l')
345 const char *FirstNonDec =
nullptr;
346 const char *LookAhead = CurPtr;
352 FirstNonDec = LookAhead;
361 bool isHex = LexHex && (*LookAhead ==
'h' || *LookAhead ==
'H');
362 CurPtr = isHex || !FirstNonDec ? LookAhead : FirstNonDec;
368static const char *
findLastDigit(
const char *CurPtr,
unsigned DefaultRadix) {
376 if (
Value.isIntN(64))
390 return "hexadecimal";
392 return "base-" + std::to_string(Radix);
408 if (LexMasmIntegers && isdigit(CurPtr[-1])) {
409 const char *FirstNonBinary =
410 (CurPtr[-1] !=
'0' && CurPtr[-1] !=
'1') ? CurPtr - 1 : nullptr;
411 const char *FirstNonDecimal =
412 (CurPtr[-1] <
'0' || CurPtr[-1] >
'9') ? CurPtr - 1 : nullptr;
413 const char *OldCurPtr = CurPtr;
417 if (!FirstNonDecimal) {
418 FirstNonDecimal = CurPtr;
429 if (!FirstNonBinary) {
430 FirstNonBinary = CurPtr;
439 if (*CurPtr ==
'.') {
443 return LexFloatLiteral();
446 if (LexMasmHexFloats && (*CurPtr ==
'r' || *CurPtr ==
'R')) {
448 return AsmToken(
AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
452 if (*CurPtr ==
'h' || *CurPtr ==
'H') {
456 }
else if (*CurPtr ==
't' || *CurPtr ==
'T') {
460 }
else if (*CurPtr ==
'o' || *CurPtr ==
'O' || *CurPtr ==
'q' ||
465 }
else if (*CurPtr ==
'y' || *CurPtr ==
'Y') {
469 }
else if (FirstNonDecimal && FirstNonDecimal + 1 == CurPtr &&
471 (*FirstNonDecimal ==
'd' || *FirstNonDecimal ==
'D')) {
473 }
else if (FirstNonBinary && FirstNonBinary + 1 == CurPtr &&
475 (*FirstNonBinary ==
'b' || *FirstNonBinary ==
'B')) {
480 StringRef
Result(TokStart, CurPtr - TokStart);
481 APInt
Value(128, 0,
true);
484 return ReturnError(TokStart,
"invalid " +
radixName(Radix) +
" number");
498 if (LexMasmIntegers && UseMasmDefaultRadix) {
500 StringRef
Result(TokStart, CurPtr - TokStart);
502 APInt
Value(128, 0,
true);
504 return ReturnError(TokStart,
505 "invalid " +
radixName(DefaultRadix) +
" number");
512 if (LexMotorolaIntegers && CurPtr[-1] ==
'$') {
513 const char *NumStart = CurPtr;
518 if (StringRef(NumStart, CurPtr - NumStart).getAsInteger(16, Result))
519 return ReturnError(TokStart,
"invalid hexadecimal number");
521 return intToken(StringRef(TokStart, CurPtr - TokStart), Result);
525 if (LexMotorolaIntegers && CurPtr[-1] ==
'%') {
526 const char *NumStart = CurPtr;
527 while (*CurPtr ==
'0' || *CurPtr ==
'1')
531 if (StringRef(NumStart, CurPtr - NumStart).getAsInteger(2, Result))
532 return ReturnError(TokStart,
"invalid binary number");
534 return intToken(StringRef(TokStart, CurPtr - TokStart), Result);
541 if (LexHLASMIntegers || CurPtr[-1] !=
'0' || CurPtr[0] ==
'.') {
544 if (!LexHLASMIntegers) {
545 bool IsHex = Radix == 16;
547 if (!IsHex && (*CurPtr ==
'.' || *CurPtr ==
'e' || *CurPtr ==
'E')) {
550 return LexFloatLiteral();
554 StringRef
Result(TokStart, CurPtr - TokStart);
556 APInt
Value(128, 0,
true);
558 return ReturnError(TokStart,
"invalid " +
radixName(Radix) +
" number");
560 if (!LexHLASMIntegers)
568 if (!LexMasmIntegers && ((*CurPtr ==
'b') || (*CurPtr ==
'B'))) {
573 StringRef
Result(TokStart, CurPtr - TokStart);
576 const char *NumStart = CurPtr;
577 while (CurPtr[0] ==
'0' || CurPtr[0] ==
'1')
581 if (CurPtr == NumStart)
582 return ReturnError(TokStart,
"invalid binary number");
584 StringRef
Result(TokStart, CurPtr - TokStart);
586 APInt
Value(128, 0,
true);
588 return ReturnError(TokStart,
"invalid binary number");
597 if ((*CurPtr ==
'x') || (*CurPtr ==
'X')) {
599 const char *NumStart = CurPtr;
605 if (CurPtr[0] ==
'.' || CurPtr[0] ==
'p' || CurPtr[0] ==
'P')
606 return LexHexFloatLiteral(NumStart == CurPtr);
609 if (CurPtr == NumStart)
610 return ReturnError(CurPtr-2,
"invalid hexadecimal number");
613 if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
614 return ReturnError(TokStart,
"invalid hexadecimal number");
617 if (LexMasmIntegers && (*CurPtr ==
'h' || *CurPtr ==
'H'))
624 return intToken(StringRef(TokStart, CurPtr - TokStart), Result);
628 APInt
Value(128, 0,
true);
630 StringRef
Result(TokStart, CurPtr - TokStart);
632 return ReturnError(TokStart,
"invalid " +
radixName(Radix) +
" number");
646AsmToken AsmLexer::LexSingleQuote() {
647 int CurChar = getNextChar();
650 return ReturnError(TokStart,
"invalid usage of character literals");
652 if (LexMasmStrings) {
653 while (CurChar != EOF) {
654 if (CurChar !=
'\'') {
655 CurChar = getNextChar();
656 }
else if (peekNextChar() ==
'\'') {
660 CurChar = getNextChar();
666 return ReturnError(TokStart,
"unterminated string constant");
671 CurChar = getNextChar();
674 return ReturnError(TokStart,
"unterminated single quote");
676 CurChar = getNextChar();
679 return ReturnError(TokStart,
"single quote way too long");
683 StringRef Res = StringRef(TokStart,CurPtr - TokStart);
687 char theChar = Res[2];
689 default:
Value = theChar;
break;
690 case '\'':
Value =
'\'';
break;
691 case 't':
Value =
'\t';
break;
692 case 'n':
Value =
'\n';
break;
693 case 'b':
Value =
'\b';
break;
694 case 'f':
Value =
'\f';
break;
695 case 'r':
Value =
'\r';
break;
705 int CurChar = getNextChar();
707 return ReturnError(TokStart,
"invalid usage of string literals");
709 if (LexMasmStrings) {
710 while (CurChar != EOF) {
711 if (CurChar !=
'"') {
712 CurChar = getNextChar();
713 }
else if (peekNextChar() ==
'"') {
717 CurChar = getNextChar();
723 return ReturnError(TokStart,
"unterminated string constant");
727 while (CurChar !=
'"') {
728 if (CurChar ==
'\\') {
730 CurChar = getNextChar();
734 return ReturnError(TokStart,
"unterminated string constant");
736 CurChar = getNextChar();
745 while (!isAtStartOfComment(CurPtr) &&
746 !isAtStatementSeparator(CurPtr) &&
747 *CurPtr !=
'\n' && *CurPtr !=
'\r' && CurPtr != CurBuf.end()) {
750 return StringRef(TokStart, CurPtr-TokStart);
756 while (*CurPtr !=
'\n' && *CurPtr !=
'\r' && CurPtr != CurBuf.
end()) {
759 return StringRef(TokStart, CurPtr-TokStart);
763 bool ShouldSkipSpace) {
770 std::string SavedErr =
getErr();
774 for (ReadCount = 0; ReadCount < Buf.
size(); ++ReadCount) {
777 Buf[ReadCount] = Token;
785 SetError(SavedErrLoc, SavedErr);
789bool AsmLexer::isAtStartOfComment(
const char *Ptr) {
790 if (MAI.
isHLASM() && !IsAtStartOfStatement)
795 if (CommentString.
size() == 1)
796 return CommentString[0] == Ptr[0];
799 if (CommentString[1] ==
'#')
800 return CommentString[0] == Ptr[0];
802 return strncmp(Ptr, CommentString.
data(), CommentString.
size()) == 0;
805bool AsmLexer::isAtStatementSeparator(
const char *Ptr) {
813 int CurChar = getNextChar();
815 if (!IsPeeking && CurChar ==
'#' && IsAtStartOfStatement) {
818 AsmToken TokenBuf[2];
825 StringRef s = LexUntilEndOfLine();
831 if (MAI.shouldAllowAdditionalComments())
832 return LexLineComment();
835 if (isAtStartOfComment(TokStart)) {
836 StringRef CommentString = MAI.getCommentString();
840 if (CommentString.
size() > 1 &&
841 StringRef(TokStart, CommentString.
size()) == CommentString) {
842 CurPtr += CommentString.
size() - 1;
844 return LexLineComment();
847 if (isAtStatementSeparator(TokStart)) {
848 CurPtr += strlen(MAI.getSeparatorString()) - 1;
849 IsAtStartOfLine =
true;
850 IsAtStartOfStatement =
true;
852 StringRef(TokStart, strlen(MAI.getSeparatorString())));
857 if (CurChar == EOF && !IsAtStartOfStatement && EndStatementAtEOF) {
858 IsAtStartOfLine =
true;
859 IsAtStartOfStatement =
true;
862 IsAtStartOfLine =
false;
863 bool OldIsAtStartOfStatement = IsAtStartOfStatement;
864 IsAtStartOfStatement =
false;
871 if (isalpha(CurChar) || CurChar ==
'_' || CurChar ==
'.')
872 return LexIdentifier();
875 return ReturnError(TokStart,
"invalid character in input");
877 if (EndStatementAtEOF) {
878 IsAtStartOfLine =
true;
879 IsAtStartOfStatement =
true;
885 IsAtStartOfStatement = OldIsAtStartOfStatement;
886 while (*CurPtr ==
' ' || *CurPtr ==
'\t')
891 return AsmToken(
AsmToken::Space, StringRef(TokStart, CurPtr - TokStart));
893 IsAtStartOfLine =
true;
894 IsAtStartOfStatement =
true;
896 if (CurPtr != CurBuf.end() && *CurPtr ==
'\n')
899 StringRef(TokStart, CurPtr - TokStart));
902 IsAtStartOfLine =
true;
903 IsAtStartOfStatement =
true;
906 case '+':
return AsmToken(
AsmToken::Plus, StringRef(TokStart, 1));
914 case '*':
return AsmToken(
AsmToken::Star, StringRef(TokStart, 1));
917 if (LexMotorolaIntegers &&
isHexDigit(*CurPtr))
919 if (MAI.doesAllowDollarAtStartOfIdentifier())
920 return LexIdentifier();
924 if (MAI.doesAllowAtAtStartOfIdentifier())
925 return LexIdentifier();
929 return LexIdentifier();
932 if (MAI.doesAllowQuestionAtStartOfIdentifier())
933 return LexIdentifier();
937 if (*CurPtr ==
'=') {
943 if (*CurPtr ==
'>') {
949 if (*CurPtr ==
'|') {
956 if (*CurPtr ==
'&') {
962 if (*CurPtr ==
'=') {
968 if (LexMotorolaIntegers && (*CurPtr ==
'0' || *CurPtr ==
'1')) {
973 IsAtStartOfStatement = OldIsAtStartOfStatement;
975 case '\'':
return LexSingleQuote();
976 case '"':
return LexQuote();
977 case '0':
case '1':
case '2':
case '3':
case '4':
978 case '5':
case '6':
case '7':
case '8':
case '9':
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static std::string radixName(unsigned Radix)
static void SkipIgnoredIntegerSuffix(const char *&CurPtr)
static unsigned doHexLookAhead(const char *&CurPtr, unsigned DefaultRadix, bool LexHex)
static AsmToken intToken(StringRef Ref, APInt &Value)
static const char * findLastDigit(const char *CurPtr, unsigned DefaultRadix)
This file provides utility classes that use RAII to save and restore values.
Class for arbitrary precision integers.
size_t size() const
Get the array size.
static bool isIdentifierChar(char C, bool AllowAt, bool AllowHash)
LLVM_ABI AsmLexer(const MCAsmInfo &MAI)
void UnLex(AsmToken const &Token)
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
SMLoc getErrLoc()
Get the current error location.
const std::string & getErr()
Get the current error string.
LLVM_ABI StringRef LexUntilEndOfStatement()
LLVM_ABI void setBuffer(StringRef Buf, const char *ptr=nullptr, bool EndStatementAtEOF=true)
Set buffer to be lexed.
LLVM_ABI size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)
Look ahead an arbitrary number of tokens.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
LLVM_ABI void dump(raw_ostream &OS) const
LLVM_ABI SMRange getLocRange() const
This class is intended to be used as a base class for asm properties and features specific to the tar...
StringRef getCommentString() const
const char * getSeparatorString() const
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
Represents a range in source code.
Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
This is an optimization pass for GlobalISel generic memory operations.
unsigned hexDigitValue(char C)
Interpret the given character C as a hexadecimal digit and return its value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
@ Ref
The access may reference the value stored in memory.
bool isHexDigit(char C)
Checks if character C is a hexadecimal numeric character.
A utility class that uses RAII to save and restore the value of a variable.