10b57cec5SDimitry Andric //===- LLLexer.cpp - Lexer for .ll Files ----------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Implement the Lexer for .ll files.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
13fe6060f1SDimitry Andric #include "llvm/AsmParser/LLLexer.h"
140b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
160b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
170b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
180b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
190b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
220b57cec5SDimitry Andric #include <cassert>
230b57cec5SDimitry Andric #include <cctype>
240b57cec5SDimitry Andric #include <cstdio>
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric
Error(LocTy ErrorLoc,const Twine & Msg) const280b57cec5SDimitry Andric bool LLLexer::Error(LocTy ErrorLoc, const Twine &Msg) const {
290b57cec5SDimitry Andric ErrorInfo = SM.GetMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
300b57cec5SDimitry Andric return true;
310b57cec5SDimitry Andric }
320b57cec5SDimitry Andric
Warning(LocTy WarningLoc,const Twine & Msg) const330b57cec5SDimitry Andric void LLLexer::Warning(LocTy WarningLoc, const Twine &Msg) const {
340b57cec5SDimitry Andric SM.PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric
370b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
380b57cec5SDimitry Andric // Helper functions.
390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric // atoull - Convert an ascii string of decimal digits into the unsigned long
420b57cec5SDimitry Andric // long representation... this does not have to do input error checking,
430b57cec5SDimitry Andric // because we know that the input will be matched by a suitable regex...
440b57cec5SDimitry Andric //
atoull(const char * Buffer,const char * End)450b57cec5SDimitry Andric uint64_t LLLexer::atoull(const char *Buffer, const char *End) {
460b57cec5SDimitry Andric uint64_t Result = 0;
470b57cec5SDimitry Andric for (; Buffer != End; Buffer++) {
480b57cec5SDimitry Andric uint64_t OldRes = Result;
490b57cec5SDimitry Andric Result *= 10;
500b57cec5SDimitry Andric Result += *Buffer-'0';
510b57cec5SDimitry Andric if (Result < OldRes) { // Uh, oh, overflow detected!!!
520b57cec5SDimitry Andric Error("constant bigger than 64 bits detected!");
530b57cec5SDimitry Andric return 0;
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric return Result;
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric
HexIntToVal(const char * Buffer,const char * End)590b57cec5SDimitry Andric uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) {
600b57cec5SDimitry Andric uint64_t Result = 0;
610b57cec5SDimitry Andric for (; Buffer != End; ++Buffer) {
620b57cec5SDimitry Andric uint64_t OldRes = Result;
630b57cec5SDimitry Andric Result *= 16;
640b57cec5SDimitry Andric Result += hexDigitValue(*Buffer);
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric if (Result < OldRes) { // Uh, oh, overflow detected!!!
670b57cec5SDimitry Andric Error("constant bigger than 64 bits detected!");
680b57cec5SDimitry Andric return 0;
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric return Result;
720b57cec5SDimitry Andric }
730b57cec5SDimitry Andric
HexToIntPair(const char * Buffer,const char * End,uint64_t Pair[2])740b57cec5SDimitry Andric void LLLexer::HexToIntPair(const char *Buffer, const char *End,
750b57cec5SDimitry Andric uint64_t Pair[2]) {
760b57cec5SDimitry Andric Pair[0] = 0;
770b57cec5SDimitry Andric if (End - Buffer >= 16) {
780b57cec5SDimitry Andric for (int i = 0; i < 16; i++, Buffer++) {
790b57cec5SDimitry Andric assert(Buffer != End);
800b57cec5SDimitry Andric Pair[0] *= 16;
810b57cec5SDimitry Andric Pair[0] += hexDigitValue(*Buffer);
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric Pair[1] = 0;
850b57cec5SDimitry Andric for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
860b57cec5SDimitry Andric Pair[1] *= 16;
870b57cec5SDimitry Andric Pair[1] += hexDigitValue(*Buffer);
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric if (Buffer != End)
900b57cec5SDimitry Andric Error("constant bigger than 128 bits detected!");
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric /// FP80HexToIntPair - translate an 80 bit FP80 number (20 hexits) into
940b57cec5SDimitry Andric /// { low64, high16 } as usual for an APInt.
FP80HexToIntPair(const char * Buffer,const char * End,uint64_t Pair[2])950b57cec5SDimitry Andric void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,
960b57cec5SDimitry Andric uint64_t Pair[2]) {
970b57cec5SDimitry Andric Pair[1] = 0;
980b57cec5SDimitry Andric for (int i=0; i<4 && Buffer != End; i++, Buffer++) {
990b57cec5SDimitry Andric assert(Buffer != End);
1000b57cec5SDimitry Andric Pair[1] *= 16;
1010b57cec5SDimitry Andric Pair[1] += hexDigitValue(*Buffer);
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric Pair[0] = 0;
1040b57cec5SDimitry Andric for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
1050b57cec5SDimitry Andric Pair[0] *= 16;
1060b57cec5SDimitry Andric Pair[0] += hexDigitValue(*Buffer);
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric if (Buffer != End)
1090b57cec5SDimitry Andric Error("constant bigger than 128 bits detected!");
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric // UnEscapeLexed - Run through the specified buffer and change \xx codes to the
1130b57cec5SDimitry Andric // appropriate character.
UnEscapeLexed(std::string & Str)1140b57cec5SDimitry Andric static void UnEscapeLexed(std::string &Str) {
1150b57cec5SDimitry Andric if (Str.empty()) return;
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric char *Buffer = &Str[0], *EndBuffer = Buffer+Str.size();
1180b57cec5SDimitry Andric char *BOut = Buffer;
1190b57cec5SDimitry Andric for (char *BIn = Buffer; BIn != EndBuffer; ) {
1200b57cec5SDimitry Andric if (BIn[0] == '\\') {
1210b57cec5SDimitry Andric if (BIn < EndBuffer-1 && BIn[1] == '\\') {
1220b57cec5SDimitry Andric *BOut++ = '\\'; // Two \ becomes one
1230b57cec5SDimitry Andric BIn += 2;
1240b57cec5SDimitry Andric } else if (BIn < EndBuffer-2 &&
1250b57cec5SDimitry Andric isxdigit(static_cast<unsigned char>(BIn[1])) &&
1260b57cec5SDimitry Andric isxdigit(static_cast<unsigned char>(BIn[2]))) {
1270b57cec5SDimitry Andric *BOut = hexDigitValue(BIn[1]) * 16 + hexDigitValue(BIn[2]);
1280b57cec5SDimitry Andric BIn += 3; // Skip over handled chars
1290b57cec5SDimitry Andric ++BOut;
1300b57cec5SDimitry Andric } else {
1310b57cec5SDimitry Andric *BOut++ = *BIn++;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric } else {
1340b57cec5SDimitry Andric *BOut++ = *BIn++;
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric Str.resize(BOut-Buffer);
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric
1400b57cec5SDimitry Andric /// isLabelChar - Return true for [-a-zA-Z$._0-9].
isLabelChar(char C)1410b57cec5SDimitry Andric static bool isLabelChar(char C) {
1420b57cec5SDimitry Andric return isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||
1430b57cec5SDimitry Andric C == '.' || C == '_';
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric
1460b57cec5SDimitry Andric /// isLabelTail - Return true if this pointer points to a valid end of a label.
isLabelTail(const char * CurPtr)1470b57cec5SDimitry Andric static const char *isLabelTail(const char *CurPtr) {
1480b57cec5SDimitry Andric while (true) {
1490b57cec5SDimitry Andric if (CurPtr[0] == ':') return CurPtr+1;
1500b57cec5SDimitry Andric if (!isLabelChar(CurPtr[0])) return nullptr;
1510b57cec5SDimitry Andric ++CurPtr;
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric
1550b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1560b57cec5SDimitry Andric // Lexer definition.
1570b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1580b57cec5SDimitry Andric
LLLexer(StringRef StartBuf,SourceMgr & SM,SMDiagnostic & Err,LLVMContext & C)1590b57cec5SDimitry Andric LLLexer::LLLexer(StringRef StartBuf, SourceMgr &SM, SMDiagnostic &Err,
1600b57cec5SDimitry Andric LLVMContext &C)
16106c3fb27SDimitry Andric : CurBuf(StartBuf), ErrorInfo(Err), SM(SM), Context(C) {
1620b57cec5SDimitry Andric CurPtr = CurBuf.begin();
1630b57cec5SDimitry Andric }
1640b57cec5SDimitry Andric
getNextChar()1650b57cec5SDimitry Andric int LLLexer::getNextChar() {
1660b57cec5SDimitry Andric char CurChar = *CurPtr++;
1670b57cec5SDimitry Andric switch (CurChar) {
1680b57cec5SDimitry Andric default: return (unsigned char)CurChar;
1690b57cec5SDimitry Andric case 0:
1700b57cec5SDimitry Andric // A nul character in the stream is either the end of the current buffer or
1710b57cec5SDimitry Andric // a random nul in the file. Disambiguate that here.
1720b57cec5SDimitry Andric if (CurPtr-1 != CurBuf.end())
1730b57cec5SDimitry Andric return 0; // Just whitespace.
1740b57cec5SDimitry Andric
1750b57cec5SDimitry Andric // Otherwise, return end of file.
1760b57cec5SDimitry Andric --CurPtr; // Another call to lex will return EOF again.
1770b57cec5SDimitry Andric return EOF;
1780b57cec5SDimitry Andric }
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric
LexToken()1810b57cec5SDimitry Andric lltok::Kind LLLexer::LexToken() {
1820b57cec5SDimitry Andric while (true) {
1830b57cec5SDimitry Andric TokStart = CurPtr;
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andric int CurChar = getNextChar();
1860b57cec5SDimitry Andric switch (CurChar) {
1870b57cec5SDimitry Andric default:
1880b57cec5SDimitry Andric // Handle letters: [a-zA-Z_]
1890b57cec5SDimitry Andric if (isalpha(static_cast<unsigned char>(CurChar)) || CurChar == '_')
1900b57cec5SDimitry Andric return LexIdentifier();
1910b57cec5SDimitry Andric
1920b57cec5SDimitry Andric return lltok::Error;
1930b57cec5SDimitry Andric case EOF: return lltok::Eof;
1940b57cec5SDimitry Andric case 0:
1950b57cec5SDimitry Andric case ' ':
1960b57cec5SDimitry Andric case '\t':
1970b57cec5SDimitry Andric case '\n':
1980b57cec5SDimitry Andric case '\r':
1990b57cec5SDimitry Andric // Ignore whitespace.
2000b57cec5SDimitry Andric continue;
2010b57cec5SDimitry Andric case '+': return LexPositive();
2020b57cec5SDimitry Andric case '@': return LexAt();
2030b57cec5SDimitry Andric case '$': return LexDollar();
2040b57cec5SDimitry Andric case '%': return LexPercent();
2050b57cec5SDimitry Andric case '"': return LexQuote();
2060b57cec5SDimitry Andric case '.':
2070b57cec5SDimitry Andric if (const char *Ptr = isLabelTail(CurPtr)) {
2080b57cec5SDimitry Andric CurPtr = Ptr;
2090b57cec5SDimitry Andric StrVal.assign(TokStart, CurPtr-1);
2100b57cec5SDimitry Andric return lltok::LabelStr;
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric if (CurPtr[0] == '.' && CurPtr[1] == '.') {
2130b57cec5SDimitry Andric CurPtr += 2;
2140b57cec5SDimitry Andric return lltok::dotdotdot;
2150b57cec5SDimitry Andric }
2160b57cec5SDimitry Andric return lltok::Error;
2170b57cec5SDimitry Andric case ';':
2180b57cec5SDimitry Andric SkipLineComment();
2190b57cec5SDimitry Andric continue;
2200b57cec5SDimitry Andric case '!': return LexExclaim();
2210b57cec5SDimitry Andric case '^':
2220b57cec5SDimitry Andric return LexCaret();
2230b57cec5SDimitry Andric case ':':
2240b57cec5SDimitry Andric return lltok::colon;
2250b57cec5SDimitry Andric case '#': return LexHash();
2260b57cec5SDimitry Andric case '0': case '1': case '2': case '3': case '4':
2270b57cec5SDimitry Andric case '5': case '6': case '7': case '8': case '9':
2280b57cec5SDimitry Andric case '-':
2290b57cec5SDimitry Andric return LexDigitOrNegative();
2300b57cec5SDimitry Andric case '=': return lltok::equal;
2310b57cec5SDimitry Andric case '[': return lltok::lsquare;
2320b57cec5SDimitry Andric case ']': return lltok::rsquare;
2330b57cec5SDimitry Andric case '{': return lltok::lbrace;
2340b57cec5SDimitry Andric case '}': return lltok::rbrace;
2350b57cec5SDimitry Andric case '<': return lltok::less;
2360b57cec5SDimitry Andric case '>': return lltok::greater;
2370b57cec5SDimitry Andric case '(': return lltok::lparen;
2380b57cec5SDimitry Andric case ')': return lltok::rparen;
2390b57cec5SDimitry Andric case ',': return lltok::comma;
2400b57cec5SDimitry Andric case '*': return lltok::star;
2410b57cec5SDimitry Andric case '|': return lltok::bar;
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric }
2450b57cec5SDimitry Andric
SkipLineComment()2460b57cec5SDimitry Andric void LLLexer::SkipLineComment() {
2470b57cec5SDimitry Andric while (true) {
2480b57cec5SDimitry Andric if (CurPtr[0] == '\n' || CurPtr[0] == '\r' || getNextChar() == EOF)
2490b57cec5SDimitry Andric return;
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric }
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric /// Lex all tokens that start with an @ character.
2540b57cec5SDimitry Andric /// GlobalVar @\"[^\"]*\"
2550b57cec5SDimitry Andric /// GlobalVar @[-a-zA-Z$._][-a-zA-Z$._0-9]*
2560b57cec5SDimitry Andric /// GlobalVarID @[0-9]+
LexAt()2570b57cec5SDimitry Andric lltok::Kind LLLexer::LexAt() {
2580b57cec5SDimitry Andric return LexVar(lltok::GlobalVar, lltok::GlobalID);
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric
LexDollar()2610b57cec5SDimitry Andric lltok::Kind LLLexer::LexDollar() {
2620b57cec5SDimitry Andric if (const char *Ptr = isLabelTail(TokStart)) {
2630b57cec5SDimitry Andric CurPtr = Ptr;
2640b57cec5SDimitry Andric StrVal.assign(TokStart, CurPtr - 1);
2650b57cec5SDimitry Andric return lltok::LabelStr;
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric
2680b57cec5SDimitry Andric // Handle DollarStringConstant: $\"[^\"]*\"
2690b57cec5SDimitry Andric if (CurPtr[0] == '"') {
2700b57cec5SDimitry Andric ++CurPtr;
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andric while (true) {
2730b57cec5SDimitry Andric int CurChar = getNextChar();
2740b57cec5SDimitry Andric
2750b57cec5SDimitry Andric if (CurChar == EOF) {
2760b57cec5SDimitry Andric Error("end of file in COMDAT variable name");
2770b57cec5SDimitry Andric return lltok::Error;
2780b57cec5SDimitry Andric }
2790b57cec5SDimitry Andric if (CurChar == '"') {
2800b57cec5SDimitry Andric StrVal.assign(TokStart + 2, CurPtr - 1);
2810b57cec5SDimitry Andric UnEscapeLexed(StrVal);
2825f757f3fSDimitry Andric if (StringRef(StrVal).contains(0)) {
2830b57cec5SDimitry Andric Error("Null bytes are not allowed in names");
2840b57cec5SDimitry Andric return lltok::Error;
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric return lltok::ComdatVar;
2870b57cec5SDimitry Andric }
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric // Handle ComdatVarName: $[-a-zA-Z$._][-a-zA-Z$._0-9]*
2920b57cec5SDimitry Andric if (ReadVarName())
2930b57cec5SDimitry Andric return lltok::ComdatVar;
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric return lltok::Error;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andric /// ReadString - Read a string until the closing quote.
ReadString(lltok::Kind kind)2990b57cec5SDimitry Andric lltok::Kind LLLexer::ReadString(lltok::Kind kind) {
3000b57cec5SDimitry Andric const char *Start = CurPtr;
3010b57cec5SDimitry Andric while (true) {
3020b57cec5SDimitry Andric int CurChar = getNextChar();
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andric if (CurChar == EOF) {
3050b57cec5SDimitry Andric Error("end of file in string constant");
3060b57cec5SDimitry Andric return lltok::Error;
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric if (CurChar == '"') {
3090b57cec5SDimitry Andric StrVal.assign(Start, CurPtr-1);
3100b57cec5SDimitry Andric UnEscapeLexed(StrVal);
3110b57cec5SDimitry Andric return kind;
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric /// ReadVarName - Read the rest of a token containing a variable name.
ReadVarName()3170b57cec5SDimitry Andric bool LLLexer::ReadVarName() {
3180b57cec5SDimitry Andric const char *NameStart = CurPtr;
3190b57cec5SDimitry Andric if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
3200b57cec5SDimitry Andric CurPtr[0] == '-' || CurPtr[0] == '$' ||
3210b57cec5SDimitry Andric CurPtr[0] == '.' || CurPtr[0] == '_') {
3220b57cec5SDimitry Andric ++CurPtr;
3230b57cec5SDimitry Andric while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
3240b57cec5SDimitry Andric CurPtr[0] == '-' || CurPtr[0] == '$' ||
3250b57cec5SDimitry Andric CurPtr[0] == '.' || CurPtr[0] == '_')
3260b57cec5SDimitry Andric ++CurPtr;
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric StrVal.assign(NameStart, CurPtr);
3290b57cec5SDimitry Andric return true;
3300b57cec5SDimitry Andric }
3310b57cec5SDimitry Andric return false;
3320b57cec5SDimitry Andric }
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andric // Lex an ID: [0-9]+. On success, the ID is stored in UIntVal and Token is
3350b57cec5SDimitry Andric // returned, otherwise the Error token is returned.
LexUIntID(lltok::Kind Token)3360b57cec5SDimitry Andric lltok::Kind LLLexer::LexUIntID(lltok::Kind Token) {
3370b57cec5SDimitry Andric if (!isdigit(static_cast<unsigned char>(CurPtr[0])))
3380b57cec5SDimitry Andric return lltok::Error;
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andric for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
3410b57cec5SDimitry Andric /*empty*/;
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric uint64_t Val = atoull(TokStart + 1, CurPtr);
3440b57cec5SDimitry Andric if ((unsigned)Val != Val)
3450b57cec5SDimitry Andric Error("invalid value number (too large)!");
3460b57cec5SDimitry Andric UIntVal = unsigned(Val);
3470b57cec5SDimitry Andric return Token;
3480b57cec5SDimitry Andric }
3490b57cec5SDimitry Andric
LexVar(lltok::Kind Var,lltok::Kind VarID)3500b57cec5SDimitry Andric lltok::Kind LLLexer::LexVar(lltok::Kind Var, lltok::Kind VarID) {
3510b57cec5SDimitry Andric // Handle StringConstant: \"[^\"]*\"
3520b57cec5SDimitry Andric if (CurPtr[0] == '"') {
3530b57cec5SDimitry Andric ++CurPtr;
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric while (true) {
3560b57cec5SDimitry Andric int CurChar = getNextChar();
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andric if (CurChar == EOF) {
3590b57cec5SDimitry Andric Error("end of file in global variable name");
3600b57cec5SDimitry Andric return lltok::Error;
3610b57cec5SDimitry Andric }
3620b57cec5SDimitry Andric if (CurChar == '"') {
3630b57cec5SDimitry Andric StrVal.assign(TokStart+2, CurPtr-1);
3640b57cec5SDimitry Andric UnEscapeLexed(StrVal);
3655f757f3fSDimitry Andric if (StringRef(StrVal).contains(0)) {
3660b57cec5SDimitry Andric Error("Null bytes are not allowed in names");
3670b57cec5SDimitry Andric return lltok::Error;
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric return Var;
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric
3740b57cec5SDimitry Andric // Handle VarName: [-a-zA-Z$._][-a-zA-Z$._0-9]*
3750b57cec5SDimitry Andric if (ReadVarName())
3760b57cec5SDimitry Andric return Var;
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric // Handle VarID: [0-9]+
3790b57cec5SDimitry Andric return LexUIntID(VarID);
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric
3820b57cec5SDimitry Andric /// Lex all tokens that start with a % character.
3830b57cec5SDimitry Andric /// LocalVar ::= %\"[^\"]*\"
3840b57cec5SDimitry Andric /// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]*
3850b57cec5SDimitry Andric /// LocalVarID ::= %[0-9]+
LexPercent()3860b57cec5SDimitry Andric lltok::Kind LLLexer::LexPercent() {
3870b57cec5SDimitry Andric return LexVar(lltok::LocalVar, lltok::LocalVarID);
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric /// Lex all tokens that start with a " character.
3910b57cec5SDimitry Andric /// QuoteLabel "[^"]+":
3920b57cec5SDimitry Andric /// StringConstant "[^"]*"
LexQuote()3930b57cec5SDimitry Andric lltok::Kind LLLexer::LexQuote() {
3940b57cec5SDimitry Andric lltok::Kind kind = ReadString(lltok::StringConstant);
3950b57cec5SDimitry Andric if (kind == lltok::Error || kind == lltok::Eof)
3960b57cec5SDimitry Andric return kind;
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric if (CurPtr[0] == ':') {
3990b57cec5SDimitry Andric ++CurPtr;
4005f757f3fSDimitry Andric if (StringRef(StrVal).contains(0)) {
4010b57cec5SDimitry Andric Error("Null bytes are not allowed in names");
4020b57cec5SDimitry Andric kind = lltok::Error;
4030b57cec5SDimitry Andric } else {
4040b57cec5SDimitry Andric kind = lltok::LabelStr;
4050b57cec5SDimitry Andric }
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric
4080b57cec5SDimitry Andric return kind;
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andric /// Lex all tokens that start with a ! character.
4120b57cec5SDimitry Andric /// !foo
4130b57cec5SDimitry Andric /// !
LexExclaim()4140b57cec5SDimitry Andric lltok::Kind LLLexer::LexExclaim() {
4150b57cec5SDimitry Andric // Lex a metadata name as a MetadataVar.
4160b57cec5SDimitry Andric if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
4170b57cec5SDimitry Andric CurPtr[0] == '-' || CurPtr[0] == '$' ||
4180b57cec5SDimitry Andric CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') {
4190b57cec5SDimitry Andric ++CurPtr;
4200b57cec5SDimitry Andric while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
4210b57cec5SDimitry Andric CurPtr[0] == '-' || CurPtr[0] == '$' ||
4220b57cec5SDimitry Andric CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\')
4230b57cec5SDimitry Andric ++CurPtr;
4240b57cec5SDimitry Andric
4250b57cec5SDimitry Andric StrVal.assign(TokStart+1, CurPtr); // Skip !
4260b57cec5SDimitry Andric UnEscapeLexed(StrVal);
4270b57cec5SDimitry Andric return lltok::MetadataVar;
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric return lltok::exclaim;
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric /// Lex all tokens that start with a ^ character.
4330b57cec5SDimitry Andric /// SummaryID ::= ^[0-9]+
LexCaret()4340b57cec5SDimitry Andric lltok::Kind LLLexer::LexCaret() {
4350b57cec5SDimitry Andric // Handle SummaryID: ^[0-9]+
4360b57cec5SDimitry Andric return LexUIntID(lltok::SummaryID);
4370b57cec5SDimitry Andric }
4380b57cec5SDimitry Andric
4390b57cec5SDimitry Andric /// Lex all tokens that start with a # character.
4400b57cec5SDimitry Andric /// AttrGrpID ::= #[0-9]+
441*0fca6ea1SDimitry Andric /// Hash ::= #
LexHash()4420b57cec5SDimitry Andric lltok::Kind LLLexer::LexHash() {
4430b57cec5SDimitry Andric // Handle AttrGrpID: #[0-9]+
444*0fca6ea1SDimitry Andric if (isdigit(static_cast<unsigned char>(CurPtr[0])))
4450b57cec5SDimitry Andric return LexUIntID(lltok::AttrGrpID);
446*0fca6ea1SDimitry Andric return lltok::hash;
4470b57cec5SDimitry Andric }
4480b57cec5SDimitry Andric
4490b57cec5SDimitry Andric /// Lex a label, integer type, keyword, or hexadecimal integer constant.
4500b57cec5SDimitry Andric /// Label [-a-zA-Z$._0-9]+:
4510b57cec5SDimitry Andric /// IntegerType i[0-9]+
4520b57cec5SDimitry Andric /// Keyword sdiv, float, ...
4530b57cec5SDimitry Andric /// HexIntConstant [us]0x[0-9A-Fa-f]+
LexIdentifier()4540b57cec5SDimitry Andric lltok::Kind LLLexer::LexIdentifier() {
4550b57cec5SDimitry Andric const char *StartChar = CurPtr;
4560b57cec5SDimitry Andric const char *IntEnd = CurPtr[-1] == 'i' ? nullptr : StartChar;
4570b57cec5SDimitry Andric const char *KeywordEnd = nullptr;
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andric for (; isLabelChar(*CurPtr); ++CurPtr) {
4600b57cec5SDimitry Andric // If we decide this is an integer, remember the end of the sequence.
4610b57cec5SDimitry Andric if (!IntEnd && !isdigit(static_cast<unsigned char>(*CurPtr)))
4620b57cec5SDimitry Andric IntEnd = CurPtr;
4630b57cec5SDimitry Andric if (!KeywordEnd && !isalnum(static_cast<unsigned char>(*CurPtr)) &&
4640b57cec5SDimitry Andric *CurPtr != '_')
4650b57cec5SDimitry Andric KeywordEnd = CurPtr;
4660b57cec5SDimitry Andric }
4670b57cec5SDimitry Andric
4680b57cec5SDimitry Andric // If we stopped due to a colon, unless we were directed to ignore it,
4690b57cec5SDimitry Andric // this really is a label.
4700b57cec5SDimitry Andric if (!IgnoreColonInIdentifiers && *CurPtr == ':') {
4710b57cec5SDimitry Andric StrVal.assign(StartChar-1, CurPtr++);
4720b57cec5SDimitry Andric return lltok::LabelStr;
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric
4750b57cec5SDimitry Andric // Otherwise, this wasn't a label. If this was valid as an integer type,
4760b57cec5SDimitry Andric // return it.
4770b57cec5SDimitry Andric if (!IntEnd) IntEnd = CurPtr;
4780b57cec5SDimitry Andric if (IntEnd != StartChar) {
4790b57cec5SDimitry Andric CurPtr = IntEnd;
4800b57cec5SDimitry Andric uint64_t NumBits = atoull(StartChar, CurPtr);
4810b57cec5SDimitry Andric if (NumBits < IntegerType::MIN_INT_BITS ||
4820b57cec5SDimitry Andric NumBits > IntegerType::MAX_INT_BITS) {
4830b57cec5SDimitry Andric Error("bitwidth for integer type out of range!");
4840b57cec5SDimitry Andric return lltok::Error;
4850b57cec5SDimitry Andric }
4860b57cec5SDimitry Andric TyVal = IntegerType::get(Context, NumBits);
4870b57cec5SDimitry Andric return lltok::Type;
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andric // Otherwise, this was a letter sequence. See which keyword this is.
4910b57cec5SDimitry Andric if (!KeywordEnd) KeywordEnd = CurPtr;
4920b57cec5SDimitry Andric CurPtr = KeywordEnd;
4930b57cec5SDimitry Andric --StartChar;
4940b57cec5SDimitry Andric StringRef Keyword(StartChar, CurPtr - StartChar);
4950b57cec5SDimitry Andric
4960b57cec5SDimitry Andric #define KEYWORD(STR) \
4970b57cec5SDimitry Andric do { \
4980b57cec5SDimitry Andric if (Keyword == #STR) \
4990b57cec5SDimitry Andric return lltok::kw_##STR; \
5000b57cec5SDimitry Andric } while (false)
5010b57cec5SDimitry Andric
5020b57cec5SDimitry Andric KEYWORD(true); KEYWORD(false);
5030b57cec5SDimitry Andric KEYWORD(declare); KEYWORD(define);
5040b57cec5SDimitry Andric KEYWORD(global); KEYWORD(constant);
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric KEYWORD(dso_local);
5070b57cec5SDimitry Andric KEYWORD(dso_preemptable);
5080b57cec5SDimitry Andric
5090b57cec5SDimitry Andric KEYWORD(private);
5100b57cec5SDimitry Andric KEYWORD(internal);
5110b57cec5SDimitry Andric KEYWORD(available_externally);
5120b57cec5SDimitry Andric KEYWORD(linkonce);
5130b57cec5SDimitry Andric KEYWORD(linkonce_odr);
5140b57cec5SDimitry Andric KEYWORD(weak); // Use as a linkage, and a modifier for "cmpxchg".
5150b57cec5SDimitry Andric KEYWORD(weak_odr);
5160b57cec5SDimitry Andric KEYWORD(appending);
5170b57cec5SDimitry Andric KEYWORD(dllimport);
5180b57cec5SDimitry Andric KEYWORD(dllexport);
5190b57cec5SDimitry Andric KEYWORD(common);
5200b57cec5SDimitry Andric KEYWORD(default);
5210b57cec5SDimitry Andric KEYWORD(hidden);
5220b57cec5SDimitry Andric KEYWORD(protected);
5230b57cec5SDimitry Andric KEYWORD(unnamed_addr);
5240b57cec5SDimitry Andric KEYWORD(local_unnamed_addr);
5250b57cec5SDimitry Andric KEYWORD(externally_initialized);
5260b57cec5SDimitry Andric KEYWORD(extern_weak);
5270b57cec5SDimitry Andric KEYWORD(external);
5280b57cec5SDimitry Andric KEYWORD(thread_local);
5290b57cec5SDimitry Andric KEYWORD(localdynamic);
5300b57cec5SDimitry Andric KEYWORD(initialexec);
5310b57cec5SDimitry Andric KEYWORD(localexec);
5320b57cec5SDimitry Andric KEYWORD(zeroinitializer);
5330b57cec5SDimitry Andric KEYWORD(undef);
5340b57cec5SDimitry Andric KEYWORD(null);
5350b57cec5SDimitry Andric KEYWORD(none);
536e8d8bef9SDimitry Andric KEYWORD(poison);
5370b57cec5SDimitry Andric KEYWORD(to);
5380b57cec5SDimitry Andric KEYWORD(caller);
5390b57cec5SDimitry Andric KEYWORD(within);
5400b57cec5SDimitry Andric KEYWORD(from);
5410b57cec5SDimitry Andric KEYWORD(tail);
5420b57cec5SDimitry Andric KEYWORD(musttail);
5430b57cec5SDimitry Andric KEYWORD(notail);
5440b57cec5SDimitry Andric KEYWORD(target);
5450b57cec5SDimitry Andric KEYWORD(triple);
5460b57cec5SDimitry Andric KEYWORD(source_filename);
5470b57cec5SDimitry Andric KEYWORD(unwind);
5480b57cec5SDimitry Andric KEYWORD(datalayout);
5490b57cec5SDimitry Andric KEYWORD(volatile);
5500b57cec5SDimitry Andric KEYWORD(atomic);
5510b57cec5SDimitry Andric KEYWORD(unordered);
5520b57cec5SDimitry Andric KEYWORD(monotonic);
5530b57cec5SDimitry Andric KEYWORD(acquire);
5540b57cec5SDimitry Andric KEYWORD(release);
5550b57cec5SDimitry Andric KEYWORD(acq_rel);
5560b57cec5SDimitry Andric KEYWORD(seq_cst);
5570b57cec5SDimitry Andric KEYWORD(syncscope);
5580b57cec5SDimitry Andric
5590b57cec5SDimitry Andric KEYWORD(nnan);
5600b57cec5SDimitry Andric KEYWORD(ninf);
5610b57cec5SDimitry Andric KEYWORD(nsz);
5620b57cec5SDimitry Andric KEYWORD(arcp);
5630b57cec5SDimitry Andric KEYWORD(contract);
5640b57cec5SDimitry Andric KEYWORD(reassoc);
5650b57cec5SDimitry Andric KEYWORD(afn);
5660b57cec5SDimitry Andric KEYWORD(fast);
5670b57cec5SDimitry Andric KEYWORD(nuw);
5680b57cec5SDimitry Andric KEYWORD(nsw);
569*0fca6ea1SDimitry Andric KEYWORD(nusw);
5700b57cec5SDimitry Andric KEYWORD(exact);
5715f757f3fSDimitry Andric KEYWORD(disjoint);
5720b57cec5SDimitry Andric KEYWORD(inbounds);
5735f757f3fSDimitry Andric KEYWORD(nneg);
5740b57cec5SDimitry Andric KEYWORD(inrange);
5750b57cec5SDimitry Andric KEYWORD(addrspace);
5760b57cec5SDimitry Andric KEYWORD(section);
5770b57cec5SDimitry Andric KEYWORD(partition);
5785f757f3fSDimitry Andric KEYWORD(code_model);
5790b57cec5SDimitry Andric KEYWORD(alias);
5800b57cec5SDimitry Andric KEYWORD(ifunc);
5810b57cec5SDimitry Andric KEYWORD(module);
5820b57cec5SDimitry Andric KEYWORD(asm);
5830b57cec5SDimitry Andric KEYWORD(sideeffect);
5840b57cec5SDimitry Andric KEYWORD(inteldialect);
5850b57cec5SDimitry Andric KEYWORD(gc);
5860b57cec5SDimitry Andric KEYWORD(prefix);
5870b57cec5SDimitry Andric KEYWORD(prologue);
5880b57cec5SDimitry Andric
58981ad6265SDimitry Andric KEYWORD(no_sanitize_address);
59081ad6265SDimitry Andric KEYWORD(no_sanitize_hwaddress);
59181ad6265SDimitry Andric KEYWORD(sanitize_address_dyninit);
59281ad6265SDimitry Andric
5930b57cec5SDimitry Andric KEYWORD(ccc);
5940b57cec5SDimitry Andric KEYWORD(fastcc);
5950b57cec5SDimitry Andric KEYWORD(coldcc);
596480093f4SDimitry Andric KEYWORD(cfguard_checkcc);
5970b57cec5SDimitry Andric KEYWORD(x86_stdcallcc);
5980b57cec5SDimitry Andric KEYWORD(x86_fastcallcc);
5990b57cec5SDimitry Andric KEYWORD(x86_thiscallcc);
6000b57cec5SDimitry Andric KEYWORD(x86_vectorcallcc);
6010b57cec5SDimitry Andric KEYWORD(arm_apcscc);
6020b57cec5SDimitry Andric KEYWORD(arm_aapcscc);
6030b57cec5SDimitry Andric KEYWORD(arm_aapcs_vfpcc);
6040b57cec5SDimitry Andric KEYWORD(aarch64_vector_pcs);
605480093f4SDimitry Andric KEYWORD(aarch64_sve_vector_pcs);
606bdd1243dSDimitry Andric KEYWORD(aarch64_sme_preservemost_from_x0);
607*0fca6ea1SDimitry Andric KEYWORD(aarch64_sme_preservemost_from_x1);
608bdd1243dSDimitry Andric KEYWORD(aarch64_sme_preservemost_from_x2);
6090b57cec5SDimitry Andric KEYWORD(msp430_intrcc);
6100b57cec5SDimitry Andric KEYWORD(avr_intrcc);
6110b57cec5SDimitry Andric KEYWORD(avr_signalcc);
6120b57cec5SDimitry Andric KEYWORD(ptx_kernel);
6130b57cec5SDimitry Andric KEYWORD(ptx_device);
6140b57cec5SDimitry Andric KEYWORD(spir_kernel);
6150b57cec5SDimitry Andric KEYWORD(spir_func);
6160b57cec5SDimitry Andric KEYWORD(intel_ocl_bicc);
6170b57cec5SDimitry Andric KEYWORD(x86_64_sysvcc);
6180b57cec5SDimitry Andric KEYWORD(win64cc);
6190b57cec5SDimitry Andric KEYWORD(x86_regcallcc);
6200b57cec5SDimitry Andric KEYWORD(swiftcc);
621fe6060f1SDimitry Andric KEYWORD(swifttailcc);
6220b57cec5SDimitry Andric KEYWORD(anyregcc);
6230b57cec5SDimitry Andric KEYWORD(preserve_mostcc);
6240b57cec5SDimitry Andric KEYWORD(preserve_allcc);
625*0fca6ea1SDimitry Andric KEYWORD(preserve_nonecc);
6260b57cec5SDimitry Andric KEYWORD(ghccc);
6270b57cec5SDimitry Andric KEYWORD(x86_intrcc);
6280b57cec5SDimitry Andric KEYWORD(hhvmcc);
6290b57cec5SDimitry Andric KEYWORD(hhvm_ccc);
6300b57cec5SDimitry Andric KEYWORD(cxx_fast_tlscc);
6310b57cec5SDimitry Andric KEYWORD(amdgpu_vs);
6320b57cec5SDimitry Andric KEYWORD(amdgpu_ls);
6330b57cec5SDimitry Andric KEYWORD(amdgpu_hs);
6340b57cec5SDimitry Andric KEYWORD(amdgpu_es);
6350b57cec5SDimitry Andric KEYWORD(amdgpu_gs);
6360b57cec5SDimitry Andric KEYWORD(amdgpu_ps);
6370b57cec5SDimitry Andric KEYWORD(amdgpu_cs);
63806c3fb27SDimitry Andric KEYWORD(amdgpu_cs_chain);
63906c3fb27SDimitry Andric KEYWORD(amdgpu_cs_chain_preserve);
6400b57cec5SDimitry Andric KEYWORD(amdgpu_kernel);
641e8d8bef9SDimitry Andric KEYWORD(amdgpu_gfx);
6428bcb0991SDimitry Andric KEYWORD(tailcc);
6435f757f3fSDimitry Andric KEYWORD(m68k_rtdcc);
6445f757f3fSDimitry Andric KEYWORD(graalcc);
645*0fca6ea1SDimitry Andric KEYWORD(riscv_vector_cc);
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andric KEYWORD(cc);
6480b57cec5SDimitry Andric KEYWORD(c);
6490b57cec5SDimitry Andric
6500b57cec5SDimitry Andric KEYWORD(attributes);
65181ad6265SDimitry Andric KEYWORD(sync);
65281ad6265SDimitry Andric KEYWORD(async);
6530b57cec5SDimitry Andric
65481ad6265SDimitry Andric #define GET_ATTR_NAMES
65581ad6265SDimitry Andric #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
65681ad6265SDimitry Andric KEYWORD(DISPLAY_NAME);
65781ad6265SDimitry Andric #include "llvm/IR/Attributes.inc"
6580b57cec5SDimitry Andric
659bdd1243dSDimitry Andric KEYWORD(read);
660bdd1243dSDimitry Andric KEYWORD(write);
661bdd1243dSDimitry Andric KEYWORD(readwrite);
662bdd1243dSDimitry Andric KEYWORD(argmem);
663bdd1243dSDimitry Andric KEYWORD(inaccessiblemem);
664bdd1243dSDimitry Andric KEYWORD(argmemonly);
665bdd1243dSDimitry Andric KEYWORD(inaccessiblememonly);
666bdd1243dSDimitry Andric KEYWORD(inaccessiblemem_or_argmemonly);
667bdd1243dSDimitry Andric
66806c3fb27SDimitry Andric // nofpclass attribute
66906c3fb27SDimitry Andric KEYWORD(all);
67006c3fb27SDimitry Andric KEYWORD(nan);
67106c3fb27SDimitry Andric KEYWORD(snan);
67206c3fb27SDimitry Andric KEYWORD(qnan);
67306c3fb27SDimitry Andric KEYWORD(inf);
67406c3fb27SDimitry Andric // ninf already a keyword
67506c3fb27SDimitry Andric KEYWORD(pinf);
67606c3fb27SDimitry Andric KEYWORD(norm);
67706c3fb27SDimitry Andric KEYWORD(nnorm);
67806c3fb27SDimitry Andric KEYWORD(pnorm);
67906c3fb27SDimitry Andric // sub already a keyword
68006c3fb27SDimitry Andric KEYWORD(nsub);
68106c3fb27SDimitry Andric KEYWORD(psub);
68206c3fb27SDimitry Andric KEYWORD(zero);
68306c3fb27SDimitry Andric KEYWORD(nzero);
68406c3fb27SDimitry Andric KEYWORD(pzero);
68506c3fb27SDimitry Andric
6860b57cec5SDimitry Andric KEYWORD(type);
6870b57cec5SDimitry Andric KEYWORD(opaque);
6880b57cec5SDimitry Andric
6890b57cec5SDimitry Andric KEYWORD(comdat);
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric // Comdat types
6920b57cec5SDimitry Andric KEYWORD(any);
6930b57cec5SDimitry Andric KEYWORD(exactmatch);
6940b57cec5SDimitry Andric KEYWORD(largest);
695fe6060f1SDimitry Andric KEYWORD(nodeduplicate);
6960b57cec5SDimitry Andric KEYWORD(samesize);
6970b57cec5SDimitry Andric
6980b57cec5SDimitry Andric KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
6990b57cec5SDimitry Andric KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);
7000b57cec5SDimitry Andric KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole);
7010b57cec5SDimitry Andric KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une);
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andric KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);
704753f127fSDimitry Andric KEYWORD(umin); KEYWORD(fmax); KEYWORD(fmin);
705bdd1243dSDimitry Andric KEYWORD(uinc_wrap);
706bdd1243dSDimitry Andric KEYWORD(udec_wrap);
7070b57cec5SDimitry Andric
7085f757f3fSDimitry Andric KEYWORD(splat);
7090b57cec5SDimitry Andric KEYWORD(vscale);
7100b57cec5SDimitry Andric KEYWORD(x);
7110b57cec5SDimitry Andric KEYWORD(blockaddress);
712e8d8bef9SDimitry Andric KEYWORD(dso_local_equivalent);
7130eae32dcSDimitry Andric KEYWORD(no_cfi);
714*0fca6ea1SDimitry Andric KEYWORD(ptrauth);
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andric // Metadata types.
7170b57cec5SDimitry Andric KEYWORD(distinct);
7180b57cec5SDimitry Andric
7190b57cec5SDimitry Andric // Use-list order directives.
7200b57cec5SDimitry Andric KEYWORD(uselistorder);
7210b57cec5SDimitry Andric KEYWORD(uselistorder_bb);
7220b57cec5SDimitry Andric
7230b57cec5SDimitry Andric KEYWORD(personality);
7240b57cec5SDimitry Andric KEYWORD(cleanup);
7250b57cec5SDimitry Andric KEYWORD(catch);
7260b57cec5SDimitry Andric KEYWORD(filter);
7270b57cec5SDimitry Andric
7280b57cec5SDimitry Andric // Summary index keywords.
7290b57cec5SDimitry Andric KEYWORD(path);
7300b57cec5SDimitry Andric KEYWORD(hash);
7310b57cec5SDimitry Andric KEYWORD(gv);
7320b57cec5SDimitry Andric KEYWORD(guid);
7330b57cec5SDimitry Andric KEYWORD(name);
7340b57cec5SDimitry Andric KEYWORD(summaries);
7350b57cec5SDimitry Andric KEYWORD(flags);
7365ffd83dbSDimitry Andric KEYWORD(blockcount);
7370b57cec5SDimitry Andric KEYWORD(linkage);
738fe6060f1SDimitry Andric KEYWORD(visibility);
7390b57cec5SDimitry Andric KEYWORD(notEligibleToImport);
7400b57cec5SDimitry Andric KEYWORD(live);
7410b57cec5SDimitry Andric KEYWORD(dsoLocal);
7420b57cec5SDimitry Andric KEYWORD(canAutoHide);
743*0fca6ea1SDimitry Andric KEYWORD(importType);
744*0fca6ea1SDimitry Andric KEYWORD(definition);
745*0fca6ea1SDimitry Andric KEYWORD(declaration);
7460b57cec5SDimitry Andric KEYWORD(function);
7470b57cec5SDimitry Andric KEYWORD(insts);
7480b57cec5SDimitry Andric KEYWORD(funcFlags);
7490b57cec5SDimitry Andric KEYWORD(readNone);
7500b57cec5SDimitry Andric KEYWORD(readOnly);
7510b57cec5SDimitry Andric KEYWORD(noRecurse);
7520b57cec5SDimitry Andric KEYWORD(returnDoesNotAlias);
7530b57cec5SDimitry Andric KEYWORD(noInline);
754480093f4SDimitry Andric KEYWORD(alwaysInline);
755349cc55cSDimitry Andric KEYWORD(noUnwind);
756349cc55cSDimitry Andric KEYWORD(mayThrow);
757349cc55cSDimitry Andric KEYWORD(hasUnknownCall);
7580eae32dcSDimitry Andric KEYWORD(mustBeUnreachable);
7590b57cec5SDimitry Andric KEYWORD(calls);
7600b57cec5SDimitry Andric KEYWORD(callee);
7615ffd83dbSDimitry Andric KEYWORD(params);
7625ffd83dbSDimitry Andric KEYWORD(param);
7630b57cec5SDimitry Andric KEYWORD(hotness);
7640b57cec5SDimitry Andric KEYWORD(unknown);
7650b57cec5SDimitry Andric KEYWORD(critical);
7660b57cec5SDimitry Andric KEYWORD(relbf);
7670b57cec5SDimitry Andric KEYWORD(variable);
7680b57cec5SDimitry Andric KEYWORD(vTableFuncs);
7690b57cec5SDimitry Andric KEYWORD(virtFunc);
7700b57cec5SDimitry Andric KEYWORD(aliasee);
7710b57cec5SDimitry Andric KEYWORD(refs);
7720b57cec5SDimitry Andric KEYWORD(typeIdInfo);
7730b57cec5SDimitry Andric KEYWORD(typeTests);
7740b57cec5SDimitry Andric KEYWORD(typeTestAssumeVCalls);
7750b57cec5SDimitry Andric KEYWORD(typeCheckedLoadVCalls);
7760b57cec5SDimitry Andric KEYWORD(typeTestAssumeConstVCalls);
7770b57cec5SDimitry Andric KEYWORD(typeCheckedLoadConstVCalls);
7780b57cec5SDimitry Andric KEYWORD(vFuncId);
7790b57cec5SDimitry Andric KEYWORD(offset);
7800b57cec5SDimitry Andric KEYWORD(args);
7810b57cec5SDimitry Andric KEYWORD(typeid);
7820b57cec5SDimitry Andric KEYWORD(typeidCompatibleVTable);
7830b57cec5SDimitry Andric KEYWORD(summary);
7840b57cec5SDimitry Andric KEYWORD(typeTestRes);
7850b57cec5SDimitry Andric KEYWORD(kind);
7860b57cec5SDimitry Andric KEYWORD(unsat);
7870b57cec5SDimitry Andric KEYWORD(byteArray);
7880b57cec5SDimitry Andric KEYWORD(inline);
7890b57cec5SDimitry Andric KEYWORD(single);
7900b57cec5SDimitry Andric KEYWORD(allOnes);
7910b57cec5SDimitry Andric KEYWORD(sizeM1BitWidth);
7920b57cec5SDimitry Andric KEYWORD(alignLog2);
7930b57cec5SDimitry Andric KEYWORD(sizeM1);
7940b57cec5SDimitry Andric KEYWORD(bitMask);
7950b57cec5SDimitry Andric KEYWORD(inlineBits);
7965ffd83dbSDimitry Andric KEYWORD(vcall_visibility);
7970b57cec5SDimitry Andric KEYWORD(wpdResolutions);
7980b57cec5SDimitry Andric KEYWORD(wpdRes);
7990b57cec5SDimitry Andric KEYWORD(indir);
8000b57cec5SDimitry Andric KEYWORD(singleImpl);
8010b57cec5SDimitry Andric KEYWORD(branchFunnel);
8020b57cec5SDimitry Andric KEYWORD(singleImplName);
8030b57cec5SDimitry Andric KEYWORD(resByArg);
8040b57cec5SDimitry Andric KEYWORD(byArg);
8050b57cec5SDimitry Andric KEYWORD(uniformRetVal);
8060b57cec5SDimitry Andric KEYWORD(uniqueRetVal);
8070b57cec5SDimitry Andric KEYWORD(virtualConstProp);
8080b57cec5SDimitry Andric KEYWORD(info);
8090b57cec5SDimitry Andric KEYWORD(byte);
8100b57cec5SDimitry Andric KEYWORD(bit);
8110b57cec5SDimitry Andric KEYWORD(varFlags);
812bdd1243dSDimitry Andric KEYWORD(callsites);
813bdd1243dSDimitry Andric KEYWORD(clones);
814bdd1243dSDimitry Andric KEYWORD(stackIds);
815bdd1243dSDimitry Andric KEYWORD(allocs);
816bdd1243dSDimitry Andric KEYWORD(versions);
817bdd1243dSDimitry Andric KEYWORD(memProf);
818bdd1243dSDimitry Andric KEYWORD(notcold);
8190b57cec5SDimitry Andric
8200b57cec5SDimitry Andric #undef KEYWORD
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric // Keywords for types.
8230b57cec5SDimitry Andric #define TYPEKEYWORD(STR, LLVMTY) \
8240b57cec5SDimitry Andric do { \
8250b57cec5SDimitry Andric if (Keyword == STR) { \
8260b57cec5SDimitry Andric TyVal = LLVMTY; \
8270b57cec5SDimitry Andric return lltok::Type; \
8280b57cec5SDimitry Andric } \
8290b57cec5SDimitry Andric } while (false)
8300b57cec5SDimitry Andric
8310b57cec5SDimitry Andric TYPEKEYWORD("void", Type::getVoidTy(Context));
8320b57cec5SDimitry Andric TYPEKEYWORD("half", Type::getHalfTy(Context));
8335ffd83dbSDimitry Andric TYPEKEYWORD("bfloat", Type::getBFloatTy(Context));
8340b57cec5SDimitry Andric TYPEKEYWORD("float", Type::getFloatTy(Context));
8350b57cec5SDimitry Andric TYPEKEYWORD("double", Type::getDoubleTy(Context));
8360b57cec5SDimitry Andric TYPEKEYWORD("x86_fp80", Type::getX86_FP80Ty(Context));
8370b57cec5SDimitry Andric TYPEKEYWORD("fp128", Type::getFP128Ty(Context));
8380b57cec5SDimitry Andric TYPEKEYWORD("ppc_fp128", Type::getPPC_FP128Ty(Context));
8390b57cec5SDimitry Andric TYPEKEYWORD("label", Type::getLabelTy(Context));
8400b57cec5SDimitry Andric TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
8410b57cec5SDimitry Andric TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
842e8d8bef9SDimitry Andric TYPEKEYWORD("x86_amx", Type::getX86_AMXTy(Context));
8430b57cec5SDimitry Andric TYPEKEYWORD("token", Type::getTokenTy(Context));
84406c3fb27SDimitry Andric TYPEKEYWORD("ptr", PointerType::getUnqual(Context));
8450b57cec5SDimitry Andric
8460b57cec5SDimitry Andric #undef TYPEKEYWORD
8470b57cec5SDimitry Andric
8480b57cec5SDimitry Andric // Keywords for instructions.
8490b57cec5SDimitry Andric #define INSTKEYWORD(STR, Enum) \
8500b57cec5SDimitry Andric do { \
8510b57cec5SDimitry Andric if (Keyword == #STR) { \
8520b57cec5SDimitry Andric UIntVal = Instruction::Enum; \
8530b57cec5SDimitry Andric return lltok::kw_##STR; \
8540b57cec5SDimitry Andric } \
8550b57cec5SDimitry Andric } while (false)
8560b57cec5SDimitry Andric
8570b57cec5SDimitry Andric INSTKEYWORD(fneg, FNeg);
8580b57cec5SDimitry Andric
8590b57cec5SDimitry Andric INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);
8600b57cec5SDimitry Andric INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);
8610b57cec5SDimitry Andric INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);
8620b57cec5SDimitry Andric INSTKEYWORD(udiv, UDiv); INSTKEYWORD(sdiv, SDiv); INSTKEYWORD(fdiv, FDiv);
8630b57cec5SDimitry Andric INSTKEYWORD(urem, URem); INSTKEYWORD(srem, SRem); INSTKEYWORD(frem, FRem);
8640b57cec5SDimitry Andric INSTKEYWORD(shl, Shl); INSTKEYWORD(lshr, LShr); INSTKEYWORD(ashr, AShr);
8650b57cec5SDimitry Andric INSTKEYWORD(and, And); INSTKEYWORD(or, Or); INSTKEYWORD(xor, Xor);
8660b57cec5SDimitry Andric INSTKEYWORD(icmp, ICmp); INSTKEYWORD(fcmp, FCmp);
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andric INSTKEYWORD(phi, PHI);
8690b57cec5SDimitry Andric INSTKEYWORD(call, Call);
8700b57cec5SDimitry Andric INSTKEYWORD(trunc, Trunc);
8710b57cec5SDimitry Andric INSTKEYWORD(zext, ZExt);
8720b57cec5SDimitry Andric INSTKEYWORD(sext, SExt);
8730b57cec5SDimitry Andric INSTKEYWORD(fptrunc, FPTrunc);
8740b57cec5SDimitry Andric INSTKEYWORD(fpext, FPExt);
8750b57cec5SDimitry Andric INSTKEYWORD(uitofp, UIToFP);
8760b57cec5SDimitry Andric INSTKEYWORD(sitofp, SIToFP);
8770b57cec5SDimitry Andric INSTKEYWORD(fptoui, FPToUI);
8780b57cec5SDimitry Andric INSTKEYWORD(fptosi, FPToSI);
8790b57cec5SDimitry Andric INSTKEYWORD(inttoptr, IntToPtr);
8800b57cec5SDimitry Andric INSTKEYWORD(ptrtoint, PtrToInt);
8810b57cec5SDimitry Andric INSTKEYWORD(bitcast, BitCast);
8820b57cec5SDimitry Andric INSTKEYWORD(addrspacecast, AddrSpaceCast);
8830b57cec5SDimitry Andric INSTKEYWORD(select, Select);
8840b57cec5SDimitry Andric INSTKEYWORD(va_arg, VAArg);
8850b57cec5SDimitry Andric INSTKEYWORD(ret, Ret);
8860b57cec5SDimitry Andric INSTKEYWORD(br, Br);
8870b57cec5SDimitry Andric INSTKEYWORD(switch, Switch);
8880b57cec5SDimitry Andric INSTKEYWORD(indirectbr, IndirectBr);
8890b57cec5SDimitry Andric INSTKEYWORD(invoke, Invoke);
8900b57cec5SDimitry Andric INSTKEYWORD(resume, Resume);
8910b57cec5SDimitry Andric INSTKEYWORD(unreachable, Unreachable);
8920b57cec5SDimitry Andric INSTKEYWORD(callbr, CallBr);
8930b57cec5SDimitry Andric
8940b57cec5SDimitry Andric INSTKEYWORD(alloca, Alloca);
8950b57cec5SDimitry Andric INSTKEYWORD(load, Load);
8960b57cec5SDimitry Andric INSTKEYWORD(store, Store);
8970b57cec5SDimitry Andric INSTKEYWORD(cmpxchg, AtomicCmpXchg);
8980b57cec5SDimitry Andric INSTKEYWORD(atomicrmw, AtomicRMW);
8990b57cec5SDimitry Andric INSTKEYWORD(fence, Fence);
9000b57cec5SDimitry Andric INSTKEYWORD(getelementptr, GetElementPtr);
9010b57cec5SDimitry Andric
9020b57cec5SDimitry Andric INSTKEYWORD(extractelement, ExtractElement);
9030b57cec5SDimitry Andric INSTKEYWORD(insertelement, InsertElement);
9040b57cec5SDimitry Andric INSTKEYWORD(shufflevector, ShuffleVector);
9050b57cec5SDimitry Andric INSTKEYWORD(extractvalue, ExtractValue);
9060b57cec5SDimitry Andric INSTKEYWORD(insertvalue, InsertValue);
9070b57cec5SDimitry Andric INSTKEYWORD(landingpad, LandingPad);
9080b57cec5SDimitry Andric INSTKEYWORD(cleanupret, CleanupRet);
9090b57cec5SDimitry Andric INSTKEYWORD(catchret, CatchRet);
9100b57cec5SDimitry Andric INSTKEYWORD(catchswitch, CatchSwitch);
9110b57cec5SDimitry Andric INSTKEYWORD(catchpad, CatchPad);
9120b57cec5SDimitry Andric INSTKEYWORD(cleanuppad, CleanupPad);
9130b57cec5SDimitry Andric
914480093f4SDimitry Andric INSTKEYWORD(freeze, Freeze);
915480093f4SDimitry Andric
9160b57cec5SDimitry Andric #undef INSTKEYWORD
9170b57cec5SDimitry Andric
9180b57cec5SDimitry Andric #define DWKEYWORD(TYPE, TOKEN) \
9190b57cec5SDimitry Andric do { \
9205f757f3fSDimitry Andric if (Keyword.starts_with("DW_" #TYPE "_")) { \
9210b57cec5SDimitry Andric StrVal.assign(Keyword.begin(), Keyword.end()); \
9220b57cec5SDimitry Andric return lltok::TOKEN; \
9230b57cec5SDimitry Andric } \
9240b57cec5SDimitry Andric } while (false)
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andric DWKEYWORD(TAG, DwarfTag);
9270b57cec5SDimitry Andric DWKEYWORD(ATE, DwarfAttEncoding);
9280b57cec5SDimitry Andric DWKEYWORD(VIRTUALITY, DwarfVirtuality);
9290b57cec5SDimitry Andric DWKEYWORD(LANG, DwarfLang);
9300b57cec5SDimitry Andric DWKEYWORD(CC, DwarfCC);
9310b57cec5SDimitry Andric DWKEYWORD(OP, DwarfOp);
9320b57cec5SDimitry Andric DWKEYWORD(MACINFO, DwarfMacinfo);
9330b57cec5SDimitry Andric
9340b57cec5SDimitry Andric #undef DWKEYWORD
9350b57cec5SDimitry Andric
936*0fca6ea1SDimitry Andric // Keywords for debug record types.
937*0fca6ea1SDimitry Andric #define DBGRECORDTYPEKEYWORD(STR) \
938*0fca6ea1SDimitry Andric do { \
939*0fca6ea1SDimitry Andric if (Keyword == "dbg_" #STR) { \
940*0fca6ea1SDimitry Andric StrVal = #STR; \
941*0fca6ea1SDimitry Andric return lltok::DbgRecordType; \
942*0fca6ea1SDimitry Andric } \
943*0fca6ea1SDimitry Andric } while (false)
944*0fca6ea1SDimitry Andric
945*0fca6ea1SDimitry Andric DBGRECORDTYPEKEYWORD(value);
946*0fca6ea1SDimitry Andric DBGRECORDTYPEKEYWORD(declare);
947*0fca6ea1SDimitry Andric DBGRECORDTYPEKEYWORD(assign);
948*0fca6ea1SDimitry Andric DBGRECORDTYPEKEYWORD(label);
949*0fca6ea1SDimitry Andric #undef DBGRECORDTYPEKEYWORD
950*0fca6ea1SDimitry Andric
9515f757f3fSDimitry Andric if (Keyword.starts_with("DIFlag")) {
9520b57cec5SDimitry Andric StrVal.assign(Keyword.begin(), Keyword.end());
9530b57cec5SDimitry Andric return lltok::DIFlag;
9540b57cec5SDimitry Andric }
9550b57cec5SDimitry Andric
9565f757f3fSDimitry Andric if (Keyword.starts_with("DISPFlag")) {
9570b57cec5SDimitry Andric StrVal.assign(Keyword.begin(), Keyword.end());
9580b57cec5SDimitry Andric return lltok::DISPFlag;
9590b57cec5SDimitry Andric }
9600b57cec5SDimitry Andric
9615f757f3fSDimitry Andric if (Keyword.starts_with("CSK_")) {
9620b57cec5SDimitry Andric StrVal.assign(Keyword.begin(), Keyword.end());
9630b57cec5SDimitry Andric return lltok::ChecksumKind;
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric
9660b57cec5SDimitry Andric if (Keyword == "NoDebug" || Keyword == "FullDebug" ||
9670b57cec5SDimitry Andric Keyword == "LineTablesOnly" || Keyword == "DebugDirectivesOnly") {
9680b57cec5SDimitry Andric StrVal.assign(Keyword.begin(), Keyword.end());
9690b57cec5SDimitry Andric return lltok::EmissionKind;
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric
97206c3fb27SDimitry Andric if (Keyword == "GNU" || Keyword == "Apple" || Keyword == "None" ||
97306c3fb27SDimitry Andric Keyword == "Default") {
9740b57cec5SDimitry Andric StrVal.assign(Keyword.begin(), Keyword.end());
9750b57cec5SDimitry Andric return lltok::NameTableKind;
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andric // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
9790b57cec5SDimitry Andric // the CFE to avoid forcing it to deal with 64-bit numbers.
9800b57cec5SDimitry Andric if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
9810b57cec5SDimitry Andric TokStart[1] == '0' && TokStart[2] == 'x' &&
9820b57cec5SDimitry Andric isxdigit(static_cast<unsigned char>(TokStart[3]))) {
9830b57cec5SDimitry Andric int len = CurPtr-TokStart-3;
9840b57cec5SDimitry Andric uint32_t bits = len * 4;
9850b57cec5SDimitry Andric StringRef HexStr(TokStart + 3, len);
9860b57cec5SDimitry Andric if (!all_of(HexStr, isxdigit)) {
9870b57cec5SDimitry Andric // Bad token, return it as an error.
9880b57cec5SDimitry Andric CurPtr = TokStart+3;
9890b57cec5SDimitry Andric return lltok::Error;
9900b57cec5SDimitry Andric }
9910b57cec5SDimitry Andric APInt Tmp(bits, HexStr, 16);
9920b57cec5SDimitry Andric uint32_t activeBits = Tmp.getActiveBits();
9930b57cec5SDimitry Andric if (activeBits > 0 && activeBits < bits)
9940b57cec5SDimitry Andric Tmp = Tmp.trunc(activeBits);
9950b57cec5SDimitry Andric APSIntVal = APSInt(Tmp, TokStart[0] == 'u');
9960b57cec5SDimitry Andric return lltok::APSInt;
9970b57cec5SDimitry Andric }
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andric // If this is "cc1234", return this as just "cc".
10000b57cec5SDimitry Andric if (TokStart[0] == 'c' && TokStart[1] == 'c') {
10010b57cec5SDimitry Andric CurPtr = TokStart+2;
10020b57cec5SDimitry Andric return lltok::kw_cc;
10030b57cec5SDimitry Andric }
10040b57cec5SDimitry Andric
10050b57cec5SDimitry Andric // Finally, if this isn't known, return an error.
10060b57cec5SDimitry Andric CurPtr = TokStart+1;
10070b57cec5SDimitry Andric return lltok::Error;
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric
10100b57cec5SDimitry Andric /// Lex all tokens that start with a 0x prefix, knowing they match and are not
10110b57cec5SDimitry Andric /// labels.
10120b57cec5SDimitry Andric /// HexFPConstant 0x[0-9A-Fa-f]+
10130b57cec5SDimitry Andric /// HexFP80Constant 0xK[0-9A-Fa-f]+
10140b57cec5SDimitry Andric /// HexFP128Constant 0xL[0-9A-Fa-f]+
10150b57cec5SDimitry Andric /// HexPPC128Constant 0xM[0-9A-Fa-f]+
10160b57cec5SDimitry Andric /// HexHalfConstant 0xH[0-9A-Fa-f]+
10175ffd83dbSDimitry Andric /// HexBFloatConstant 0xR[0-9A-Fa-f]+
Lex0x()10180b57cec5SDimitry Andric lltok::Kind LLLexer::Lex0x() {
10190b57cec5SDimitry Andric CurPtr = TokStart + 2;
10200b57cec5SDimitry Andric
10210b57cec5SDimitry Andric char Kind;
10225ffd83dbSDimitry Andric if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H' ||
10235ffd83dbSDimitry Andric CurPtr[0] == 'R') {
10240b57cec5SDimitry Andric Kind = *CurPtr++;
10250b57cec5SDimitry Andric } else {
10260b57cec5SDimitry Andric Kind = 'J';
10270b57cec5SDimitry Andric }
10280b57cec5SDimitry Andric
10290b57cec5SDimitry Andric if (!isxdigit(static_cast<unsigned char>(CurPtr[0]))) {
10300b57cec5SDimitry Andric // Bad token, return it as an error.
10310b57cec5SDimitry Andric CurPtr = TokStart+1;
10320b57cec5SDimitry Andric return lltok::Error;
10330b57cec5SDimitry Andric }
10340b57cec5SDimitry Andric
10350b57cec5SDimitry Andric while (isxdigit(static_cast<unsigned char>(CurPtr[0])))
10360b57cec5SDimitry Andric ++CurPtr;
10370b57cec5SDimitry Andric
10380b57cec5SDimitry Andric if (Kind == 'J') {
10390b57cec5SDimitry Andric // HexFPConstant - Floating point constant represented in IEEE format as a
10400b57cec5SDimitry Andric // hexadecimal number for when exponential notation is not precise enough.
10415ffd83dbSDimitry Andric // Half, BFloat, Float, and double only.
10420b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::IEEEdouble(),
10430b57cec5SDimitry Andric APInt(64, HexIntToVal(TokStart + 2, CurPtr)));
10440b57cec5SDimitry Andric return lltok::APFloat;
10450b57cec5SDimitry Andric }
10460b57cec5SDimitry Andric
10470b57cec5SDimitry Andric uint64_t Pair[2];
10480b57cec5SDimitry Andric switch (Kind) {
10490b57cec5SDimitry Andric default: llvm_unreachable("Unknown kind!");
10500b57cec5SDimitry Andric case 'K':
10510b57cec5SDimitry Andric // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
10520b57cec5SDimitry Andric FP80HexToIntPair(TokStart+3, CurPtr, Pair);
10530b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::x87DoubleExtended(), APInt(80, Pair));
10540b57cec5SDimitry Andric return lltok::APFloat;
10550b57cec5SDimitry Andric case 'L':
10560b57cec5SDimitry Andric // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
10570b57cec5SDimitry Andric HexToIntPair(TokStart+3, CurPtr, Pair);
10580b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::IEEEquad(), APInt(128, Pair));
10590b57cec5SDimitry Andric return lltok::APFloat;
10600b57cec5SDimitry Andric case 'M':
10610b57cec5SDimitry Andric // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
10620b57cec5SDimitry Andric HexToIntPair(TokStart+3, CurPtr, Pair);
10630b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::PPCDoubleDouble(), APInt(128, Pair));
10640b57cec5SDimitry Andric return lltok::APFloat;
10650b57cec5SDimitry Andric case 'H':
10660b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::IEEEhalf(),
10670b57cec5SDimitry Andric APInt(16,HexIntToVal(TokStart+3, CurPtr)));
10680b57cec5SDimitry Andric return lltok::APFloat;
10695ffd83dbSDimitry Andric case 'R':
10705ffd83dbSDimitry Andric // Brain floating point
10715ffd83dbSDimitry Andric APFloatVal = APFloat(APFloat::BFloat(),
10725ffd83dbSDimitry Andric APInt(16, HexIntToVal(TokStart + 3, CurPtr)));
10735ffd83dbSDimitry Andric return lltok::APFloat;
10740b57cec5SDimitry Andric }
10750b57cec5SDimitry Andric }
10760b57cec5SDimitry Andric
10770b57cec5SDimitry Andric /// Lex tokens for a label or a numeric constant, possibly starting with -.
10780b57cec5SDimitry Andric /// Label [-a-zA-Z$._0-9]+:
10790b57cec5SDimitry Andric /// NInteger -[0-9]+
10800b57cec5SDimitry Andric /// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
10810b57cec5SDimitry Andric /// PInteger [0-9]+
10820b57cec5SDimitry Andric /// HexFPConstant 0x[0-9A-Fa-f]+
10830b57cec5SDimitry Andric /// HexFP80Constant 0xK[0-9A-Fa-f]+
10840b57cec5SDimitry Andric /// HexFP128Constant 0xL[0-9A-Fa-f]+
10850b57cec5SDimitry Andric /// HexPPC128Constant 0xM[0-9A-Fa-f]+
LexDigitOrNegative()10860b57cec5SDimitry Andric lltok::Kind LLLexer::LexDigitOrNegative() {
10870b57cec5SDimitry Andric // If the letter after the negative is not a number, this is probably a label.
10880b57cec5SDimitry Andric if (!isdigit(static_cast<unsigned char>(TokStart[0])) &&
10890b57cec5SDimitry Andric !isdigit(static_cast<unsigned char>(CurPtr[0]))) {
10900b57cec5SDimitry Andric // Okay, this is not a number after the -, it's probably a label.
10910b57cec5SDimitry Andric if (const char *End = isLabelTail(CurPtr)) {
10920b57cec5SDimitry Andric StrVal.assign(TokStart, End-1);
10930b57cec5SDimitry Andric CurPtr = End;
10940b57cec5SDimitry Andric return lltok::LabelStr;
10950b57cec5SDimitry Andric }
10960b57cec5SDimitry Andric
10970b57cec5SDimitry Andric return lltok::Error;
10980b57cec5SDimitry Andric }
10990b57cec5SDimitry Andric
11000b57cec5SDimitry Andric // At this point, it is either a label, int or fp constant.
11010b57cec5SDimitry Andric
11020b57cec5SDimitry Andric // Skip digits, we have at least one.
11030b57cec5SDimitry Andric for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
11040b57cec5SDimitry Andric /*empty*/;
11050b57cec5SDimitry Andric
11060b57cec5SDimitry Andric // Check if this is a fully-numeric label:
11070b57cec5SDimitry Andric if (isdigit(TokStart[0]) && CurPtr[0] == ':') {
11080b57cec5SDimitry Andric uint64_t Val = atoull(TokStart, CurPtr);
11090b57cec5SDimitry Andric ++CurPtr; // Skip the colon.
11100b57cec5SDimitry Andric if ((unsigned)Val != Val)
11110b57cec5SDimitry Andric Error("invalid value number (too large)!");
11120b57cec5SDimitry Andric UIntVal = unsigned(Val);
11130b57cec5SDimitry Andric return lltok::LabelID;
11140b57cec5SDimitry Andric }
11150b57cec5SDimitry Andric
11160b57cec5SDimitry Andric // Check to see if this really is a string label, e.g. "-1:".
11170b57cec5SDimitry Andric if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {
11180b57cec5SDimitry Andric if (const char *End = isLabelTail(CurPtr)) {
11190b57cec5SDimitry Andric StrVal.assign(TokStart, End-1);
11200b57cec5SDimitry Andric CurPtr = End;
11210b57cec5SDimitry Andric return lltok::LabelStr;
11220b57cec5SDimitry Andric }
11230b57cec5SDimitry Andric }
11240b57cec5SDimitry Andric
11250b57cec5SDimitry Andric // If the next character is a '.', then it is a fp value, otherwise its
11260b57cec5SDimitry Andric // integer.
11270b57cec5SDimitry Andric if (CurPtr[0] != '.') {
11280b57cec5SDimitry Andric if (TokStart[0] == '0' && TokStart[1] == 'x')
11290b57cec5SDimitry Andric return Lex0x();
11300b57cec5SDimitry Andric APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
11310b57cec5SDimitry Andric return lltok::APSInt;
11320b57cec5SDimitry Andric }
11330b57cec5SDimitry Andric
11340b57cec5SDimitry Andric ++CurPtr;
11350b57cec5SDimitry Andric
11360b57cec5SDimitry Andric // Skip over [0-9]*([eE][-+]?[0-9]+)?
11370b57cec5SDimitry Andric while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
11380b57cec5SDimitry Andric
11390b57cec5SDimitry Andric if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
11400b57cec5SDimitry Andric if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
11410b57cec5SDimitry Andric ((CurPtr[1] == '-' || CurPtr[1] == '+') &&
11420b57cec5SDimitry Andric isdigit(static_cast<unsigned char>(CurPtr[2])))) {
11430b57cec5SDimitry Andric CurPtr += 2;
11440b57cec5SDimitry Andric while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
11450b57cec5SDimitry Andric }
11460b57cec5SDimitry Andric }
11470b57cec5SDimitry Andric
11480b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::IEEEdouble(),
11490b57cec5SDimitry Andric StringRef(TokStart, CurPtr - TokStart));
11500b57cec5SDimitry Andric return lltok::APFloat;
11510b57cec5SDimitry Andric }
11520b57cec5SDimitry Andric
11530b57cec5SDimitry Andric /// Lex a floating point constant starting with +.
11540b57cec5SDimitry Andric /// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
LexPositive()11550b57cec5SDimitry Andric lltok::Kind LLLexer::LexPositive() {
11560b57cec5SDimitry Andric // If the letter after the negative is a number, this is probably not a
11570b57cec5SDimitry Andric // label.
11580b57cec5SDimitry Andric if (!isdigit(static_cast<unsigned char>(CurPtr[0])))
11590b57cec5SDimitry Andric return lltok::Error;
11600b57cec5SDimitry Andric
11610b57cec5SDimitry Andric // Skip digits.
11620b57cec5SDimitry Andric for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
11630b57cec5SDimitry Andric /*empty*/;
11640b57cec5SDimitry Andric
11650b57cec5SDimitry Andric // At this point, we need a '.'.
11660b57cec5SDimitry Andric if (CurPtr[0] != '.') {
11670b57cec5SDimitry Andric CurPtr = TokStart+1;
11680b57cec5SDimitry Andric return lltok::Error;
11690b57cec5SDimitry Andric }
11700b57cec5SDimitry Andric
11710b57cec5SDimitry Andric ++CurPtr;
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andric // Skip over [0-9]*([eE][-+]?[0-9]+)?
11740b57cec5SDimitry Andric while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
11750b57cec5SDimitry Andric
11760b57cec5SDimitry Andric if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
11770b57cec5SDimitry Andric if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
11780b57cec5SDimitry Andric ((CurPtr[1] == '-' || CurPtr[1] == '+') &&
11790b57cec5SDimitry Andric isdigit(static_cast<unsigned char>(CurPtr[2])))) {
11800b57cec5SDimitry Andric CurPtr += 2;
11810b57cec5SDimitry Andric while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
11820b57cec5SDimitry Andric }
11830b57cec5SDimitry Andric }
11840b57cec5SDimitry Andric
11850b57cec5SDimitry Andric APFloatVal = APFloat(APFloat::IEEEdouble(),
11860b57cec5SDimitry Andric StringRef(TokStart, CurPtr - TokStart));
11870b57cec5SDimitry Andric return lltok::APFloat;
11880b57cec5SDimitry Andric }
1189