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 280b57cec5SDimitry 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 330b57cec5SDimitry 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 // 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 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 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. 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. 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]. 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. 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 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 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 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 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]+ 2570b57cec5SDimitry Andric lltok::Kind LLLexer::LexAt() { 2580b57cec5SDimitry Andric return LexVar(lltok::GlobalVar, lltok::GlobalID); 2590b57cec5SDimitry Andric } 2600b57cec5SDimitry Andric 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. 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. 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. 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 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]+ 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 "[^"]*" 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 /// ! 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]+ 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 ::= # 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]+ 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]+ 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]+ 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]+)? 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