1256 lines · cpp
1//===- LLLexer.cpp - Lexer for .ll Files ----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Implement the Lexer for .ll files.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/AsmParser/LLLexer.h"14#include "llvm/ADT/APInt.h"15#include "llvm/ADT/STLExtras.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/ADT/Twine.h"18#include "llvm/IR/DerivedTypes.h"19#include "llvm/IR/Instruction.h"20#include "llvm/Support/ErrorHandling.h"21#include "llvm/Support/SourceMgr.h"22#include <cassert>23#include <cctype>24#include <cstdio>25 26using namespace llvm;27 28// Both the lexer and parser can issue error messages. If the lexer issues a29// lexer error, since we do not terminate execution immediately, usually that30// is followed by the parser issuing a parser error. However, the error issued31// by the lexer is more relevant in that case as opposed to potentially more32// generic parser error. So instead of always recording the last error message33// use the `Priority` to establish a priority, with Lexer > Parser > None. We34// record the issued message only if the message has same or higher priority35// than the existing one. This prevents lexer errors from being overwritten by36// parser errors.37void LLLexer::Error(LocTy ErrorLoc, const Twine &Msg,38 LLLexer::ErrorPriority Priority) {39 if (Priority < ErrorInfo.Priority)40 return;41 ErrorInfo.Error = SM.GetMessage(ErrorLoc, SourceMgr::DK_Error, Msg);42 ErrorInfo.Priority = Priority;43}44 45void LLLexer::Warning(LocTy WarningLoc, const Twine &Msg) const {46 SM.PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);47}48 49//===----------------------------------------------------------------------===//50// Helper functions.51//===----------------------------------------------------------------------===//52 53// atoull - Convert an ascii string of decimal digits into the unsigned long54// long representation... this does not have to do input error checking,55// because we know that the input will be matched by a suitable regex...56//57uint64_t LLLexer::atoull(const char *Buffer, const char *End) {58 uint64_t Result = 0;59 for (; Buffer != End; Buffer++) {60 uint64_t OldRes = Result;61 Result *= 10;62 Result += *Buffer-'0';63 if (Result < OldRes) { // overflow detected.64 LexError("constant bigger than 64 bits detected");65 return 0;66 }67 }68 return Result;69}70 71uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) {72 uint64_t Result = 0;73 for (; Buffer != End; ++Buffer) {74 uint64_t OldRes = Result;75 Result *= 16;76 Result += hexDigitValue(*Buffer);77 78 if (Result < OldRes) { // overflow detected.79 LexError("constant bigger than 64 bits detected");80 return 0;81 }82 }83 return Result;84}85 86void LLLexer::HexToIntPair(const char *Buffer, const char *End,87 uint64_t Pair[2]) {88 Pair[0] = 0;89 if (End - Buffer >= 16) {90 for (int i = 0; i < 16; i++, Buffer++) {91 assert(Buffer != End);92 Pair[0] *= 16;93 Pair[0] += hexDigitValue(*Buffer);94 }95 }96 Pair[1] = 0;97 for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {98 Pair[1] *= 16;99 Pair[1] += hexDigitValue(*Buffer);100 }101 if (Buffer != End)102 LexError("constant bigger than 128 bits detected");103}104 105/// FP80HexToIntPair - translate an 80 bit FP80 number (20 hexits) into106/// { low64, high16 } as usual for an APInt.107void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,108 uint64_t Pair[2]) {109 Pair[1] = 0;110 for (int i=0; i<4 && Buffer != End; i++, Buffer++) {111 assert(Buffer != End);112 Pair[1] *= 16;113 Pair[1] += hexDigitValue(*Buffer);114 }115 Pair[0] = 0;116 for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {117 Pair[0] *= 16;118 Pair[0] += hexDigitValue(*Buffer);119 }120 if (Buffer != End)121 LexError("constant bigger than 128 bits detected");122}123 124// UnEscapeLexed - Run through the specified buffer and change \xx codes to the125// appropriate character.126static void UnEscapeLexed(std::string &Str) {127 if (Str.empty()) return;128 129 char *Buffer = &Str[0], *EndBuffer = Buffer+Str.size();130 char *BOut = Buffer;131 for (char *BIn = Buffer; BIn != EndBuffer; ) {132 if (BIn[0] == '\\') {133 if (BIn < EndBuffer-1 && BIn[1] == '\\') {134 *BOut++ = '\\'; // Two \ becomes one135 BIn += 2;136 } else if (BIn < EndBuffer-2 &&137 isxdigit(static_cast<unsigned char>(BIn[1])) &&138 isxdigit(static_cast<unsigned char>(BIn[2]))) {139 *BOut = hexDigitValue(BIn[1]) * 16 + hexDigitValue(BIn[2]);140 BIn += 3; // Skip over handled chars141 ++BOut;142 } else {143 *BOut++ = *BIn++;144 }145 } else {146 *BOut++ = *BIn++;147 }148 }149 Str.resize(BOut-Buffer);150}151 152/// isLabelChar - Return true for [-a-zA-Z$._0-9].153static bool isLabelChar(char C) {154 return isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||155 C == '.' || C == '_';156}157 158/// isLabelTail - Return true if this pointer points to a valid end of a label.159static const char *isLabelTail(const char *CurPtr) {160 while (true) {161 if (CurPtr[0] == ':') return CurPtr+1;162 if (!isLabelChar(CurPtr[0])) return nullptr;163 ++CurPtr;164 }165}166 167//===----------------------------------------------------------------------===//168// Lexer definition.169//===----------------------------------------------------------------------===//170 171LLLexer::LLLexer(StringRef StartBuf, SourceMgr &SM, SMDiagnostic &Err,172 LLVMContext &C)173 : CurBuf(StartBuf), ErrorInfo(Err), SM(SM), Context(C) {174 CurPtr = CurBuf.begin();175}176 177int LLLexer::getNextChar() {178 char CurChar = *CurPtr++;179 switch (CurChar) {180 default: return (unsigned char)CurChar;181 case 0:182 // A nul character in the stream is either the end of the current buffer or183 // a random nul in the file. Disambiguate that here.184 if (CurPtr-1 != CurBuf.end())185 return 0; // Just whitespace.186 187 // Otherwise, return end of file.188 --CurPtr; // Another call to lex will return EOF again.189 return EOF;190 }191}192 193lltok::Kind LLLexer::LexToken() {194 // Set token end to next location, since the end is exclusive.195 PrevTokEnd = CurPtr;196 while (true) {197 TokStart = CurPtr;198 199 int CurChar = getNextChar();200 switch (CurChar) {201 default:202 // Handle letters: [a-zA-Z_]203 if (isalpha(static_cast<unsigned char>(CurChar)) || CurChar == '_')204 return LexIdentifier();205 return lltok::Error;206 case EOF: return lltok::Eof;207 case 0:208 case ' ':209 case '\t':210 case '\n':211 case '\r':212 // Ignore whitespace.213 continue;214 case '+': return LexPositive();215 case '@': return LexAt();216 case '$': return LexDollar();217 case '%': return LexPercent();218 case '"': return LexQuote();219 case '.':220 if (const char *Ptr = isLabelTail(CurPtr)) {221 CurPtr = Ptr;222 StrVal.assign(TokStart, CurPtr-1);223 return lltok::LabelStr;224 }225 if (CurPtr[0] == '.' && CurPtr[1] == '.') {226 CurPtr += 2;227 return lltok::dotdotdot;228 }229 return lltok::Error;230 case ';':231 SkipLineComment();232 continue;233 case '!': return LexExclaim();234 case '^':235 return LexCaret();236 case ':':237 return lltok::colon;238 case '#': return LexHash();239 case '0': case '1': case '2': case '3': case '4':240 case '5': case '6': case '7': case '8': case '9':241 case '-':242 return LexDigitOrNegative();243 case '=': return lltok::equal;244 case '[': return lltok::lsquare;245 case ']': return lltok::rsquare;246 case '{': return lltok::lbrace;247 case '}': return lltok::rbrace;248 case '<': return lltok::less;249 case '>': return lltok::greater;250 case '(': return lltok::lparen;251 case ')': return lltok::rparen;252 case ',': return lltok::comma;253 case '*': return lltok::star;254 case '|': return lltok::bar;255 case '/':256 if (getNextChar() != '*')257 return lltok::Error;258 if (SkipCComment())259 return lltok::Error;260 continue;261 }262 }263}264 265void LLLexer::SkipLineComment() {266 while (true) {267 if (CurPtr[0] == '\n' || CurPtr[0] == '\r' || getNextChar() == EOF)268 return;269 }270}271 272/// This skips C-style /**/ comments. Returns true if there273/// was an error.274bool LLLexer::SkipCComment() {275 while (true) {276 int CurChar = getNextChar();277 switch (CurChar) {278 case EOF:279 LexError("unterminated comment");280 return true;281 case '*':282 // End of the comment?283 CurChar = getNextChar();284 if (CurChar == '/')285 return false;286 if (CurChar == EOF) {287 LexError("unterminated comment");288 return true;289 }290 }291 }292}293 294/// Lex all tokens that start with an @ character.295/// GlobalVar @\"[^\"]*\"296/// GlobalVar @[-a-zA-Z$._][-a-zA-Z$._0-9]*297/// GlobalVarID @[0-9]+298lltok::Kind LLLexer::LexAt() {299 return LexVar(lltok::GlobalVar, lltok::GlobalID);300}301 302lltok::Kind LLLexer::LexDollar() {303 if (const char *Ptr = isLabelTail(TokStart)) {304 CurPtr = Ptr;305 StrVal.assign(TokStart, CurPtr - 1);306 return lltok::LabelStr;307 }308 309 // Handle DollarStringConstant: $\"[^\"]*\"310 if (CurPtr[0] == '"') {311 ++CurPtr;312 313 while (true) {314 int CurChar = getNextChar();315 316 if (CurChar == EOF) {317 LexError("end of file in COMDAT variable name");318 return lltok::Error;319 }320 if (CurChar == '"') {321 StrVal.assign(TokStart + 2, CurPtr - 1);322 UnEscapeLexed(StrVal);323 if (StringRef(StrVal).contains(0)) {324 LexError("NUL character is not allowed in names");325 return lltok::Error;326 }327 return lltok::ComdatVar;328 }329 }330 }331 332 // Handle ComdatVarName: $[-a-zA-Z$._][-a-zA-Z$._0-9]*333 if (ReadVarName())334 return lltok::ComdatVar;335 336 return lltok::Error;337}338 339/// ReadString - Read a string until the closing quote.340lltok::Kind LLLexer::ReadString(lltok::Kind kind) {341 const char *Start = CurPtr;342 while (true) {343 int CurChar = getNextChar();344 345 if (CurChar == EOF) {346 LexError("end of file in string constant");347 return lltok::Error;348 }349 if (CurChar == '"') {350 StrVal.assign(Start, CurPtr-1);351 UnEscapeLexed(StrVal);352 return kind;353 }354 }355}356 357/// ReadVarName - Read the rest of a token containing a variable name.358bool LLLexer::ReadVarName() {359 const char *NameStart = CurPtr;360 if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||361 CurPtr[0] == '-' || CurPtr[0] == '$' ||362 CurPtr[0] == '.' || CurPtr[0] == '_') {363 ++CurPtr;364 while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||365 CurPtr[0] == '-' || CurPtr[0] == '$' ||366 CurPtr[0] == '.' || CurPtr[0] == '_')367 ++CurPtr;368 369 StrVal.assign(NameStart, CurPtr);370 return true;371 }372 return false;373}374 375// Lex an ID: [0-9]+. On success, the ID is stored in UIntVal and Token is376// returned, otherwise the Error token is returned.377lltok::Kind LLLexer::LexUIntID(lltok::Kind Token) {378 if (!isdigit(static_cast<unsigned char>(CurPtr[0])))379 return lltok::Error;380 381 for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)382 /*empty*/;383 384 uint64_t Val = atoull(TokStart + 1, CurPtr);385 if ((unsigned)Val != Val)386 LexError("invalid value number (too large)");387 UIntVal = unsigned(Val);388 return Token;389}390 391lltok::Kind LLLexer::LexVar(lltok::Kind Var, lltok::Kind VarID) {392 // Handle StringConstant: \"[^\"]*\"393 if (CurPtr[0] == '"') {394 ++CurPtr;395 396 while (true) {397 int CurChar = getNextChar();398 399 if (CurChar == EOF) {400 LexError("end of file in global variable name");401 return lltok::Error;402 }403 if (CurChar == '"') {404 StrVal.assign(TokStart+2, CurPtr-1);405 UnEscapeLexed(StrVal);406 if (StringRef(StrVal).contains(0)) {407 LexError("NUL character is not allowed in names");408 return lltok::Error;409 }410 return Var;411 }412 }413 }414 415 // Handle VarName: [-a-zA-Z$._][-a-zA-Z$._0-9]*416 if (ReadVarName())417 return Var;418 419 // Handle VarID: [0-9]+420 return LexUIntID(VarID);421}422 423/// Lex all tokens that start with a % character.424/// LocalVar ::= %\"[^\"]*\"425/// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]*426/// LocalVarID ::= %[0-9]+427lltok::Kind LLLexer::LexPercent() {428 return LexVar(lltok::LocalVar, lltok::LocalVarID);429}430 431/// Lex all tokens that start with a " character.432/// QuoteLabel "[^"]+":433/// StringConstant "[^"]*"434lltok::Kind LLLexer::LexQuote() {435 lltok::Kind kind = ReadString(lltok::StringConstant);436 if (kind == lltok::Error || kind == lltok::Eof)437 return kind;438 439 if (CurPtr[0] == ':') {440 ++CurPtr;441 if (StringRef(StrVal).contains(0)) {442 LexError("NUL character is not allowed in names");443 kind = lltok::Error;444 } else {445 kind = lltok::LabelStr;446 }447 }448 449 return kind;450}451 452/// Lex all tokens that start with a ! character.453/// !foo454/// !455lltok::Kind LLLexer::LexExclaim() {456 // Lex a metadata name as a MetadataVar.457 if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||458 CurPtr[0] == '-' || CurPtr[0] == '$' ||459 CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') {460 ++CurPtr;461 while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||462 CurPtr[0] == '-' || CurPtr[0] == '$' ||463 CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\')464 ++CurPtr;465 466 StrVal.assign(TokStart+1, CurPtr); // Skip !467 UnEscapeLexed(StrVal);468 return lltok::MetadataVar;469 }470 return lltok::exclaim;471}472 473/// Lex all tokens that start with a ^ character.474/// SummaryID ::= ^[0-9]+475lltok::Kind LLLexer::LexCaret() {476 // Handle SummaryID: ^[0-9]+477 return LexUIntID(lltok::SummaryID);478}479 480/// Lex all tokens that start with a # character.481/// AttrGrpID ::= #[0-9]+482/// Hash ::= #483lltok::Kind LLLexer::LexHash() {484 // Handle AttrGrpID: #[0-9]+485 if (isdigit(static_cast<unsigned char>(CurPtr[0])))486 return LexUIntID(lltok::AttrGrpID);487 return lltok::hash;488}489 490/// Lex a label, integer type, keyword, or hexadecimal integer constant.491/// Label [-a-zA-Z$._0-9]+:492/// IntegerType i[0-9]+493/// Keyword sdiv, float, ...494/// HexIntConstant [us]0x[0-9A-Fa-f]+495lltok::Kind LLLexer::LexIdentifier() {496 const char *StartChar = CurPtr;497 const char *IntEnd = CurPtr[-1] == 'i' ? nullptr : StartChar;498 const char *KeywordEnd = nullptr;499 500 for (; isLabelChar(*CurPtr); ++CurPtr) {501 // If we decide this is an integer, remember the end of the sequence.502 if (!IntEnd && !isdigit(static_cast<unsigned char>(*CurPtr)))503 IntEnd = CurPtr;504 if (!KeywordEnd && !isalnum(static_cast<unsigned char>(*CurPtr)) &&505 *CurPtr != '_')506 KeywordEnd = CurPtr;507 }508 509 // If we stopped due to a colon, unless we were directed to ignore it,510 // this really is a label.511 if (!IgnoreColonInIdentifiers && *CurPtr == ':') {512 StrVal.assign(StartChar-1, CurPtr++);513 return lltok::LabelStr;514 }515 516 // Otherwise, this wasn't a label. If this was valid as an integer type,517 // return it.518 if (!IntEnd) IntEnd = CurPtr;519 if (IntEnd != StartChar) {520 CurPtr = IntEnd;521 uint64_t NumBits = atoull(StartChar, CurPtr);522 if (NumBits < IntegerType::MIN_INT_BITS ||523 NumBits > IntegerType::MAX_INT_BITS) {524 LexError("bitwidth for integer type out of range");525 return lltok::Error;526 }527 TyVal = IntegerType::get(Context, NumBits);528 return lltok::Type;529 }530 531 // Otherwise, this was a letter sequence. See which keyword this is.532 if (!KeywordEnd) KeywordEnd = CurPtr;533 CurPtr = KeywordEnd;534 --StartChar;535 StringRef Keyword(StartChar, CurPtr - StartChar);536 537#define KEYWORD(STR) \538 do { \539 if (Keyword == #STR) \540 return lltok::kw_##STR; \541 } while (false)542 543 KEYWORD(true); KEYWORD(false);544 KEYWORD(declare); KEYWORD(define);545 KEYWORD(global); KEYWORD(constant);546 547 KEYWORD(dso_local);548 KEYWORD(dso_preemptable);549 550 KEYWORD(private);551 KEYWORD(internal);552 KEYWORD(available_externally);553 KEYWORD(linkonce);554 KEYWORD(linkonce_odr);555 KEYWORD(weak); // Use as a linkage, and a modifier for "cmpxchg".556 KEYWORD(weak_odr);557 KEYWORD(appending);558 KEYWORD(dllimport);559 KEYWORD(dllexport);560 KEYWORD(common);561 KEYWORD(default);562 KEYWORD(hidden);563 KEYWORD(protected);564 KEYWORD(unnamed_addr);565 KEYWORD(local_unnamed_addr);566 KEYWORD(externally_initialized);567 KEYWORD(extern_weak);568 KEYWORD(external);569 KEYWORD(thread_local);570 KEYWORD(localdynamic);571 KEYWORD(initialexec);572 KEYWORD(localexec);573 KEYWORD(zeroinitializer);574 KEYWORD(undef);575 KEYWORD(null);576 KEYWORD(none);577 KEYWORD(poison);578 KEYWORD(to);579 KEYWORD(caller);580 KEYWORD(within);581 KEYWORD(from);582 KEYWORD(tail);583 KEYWORD(musttail);584 KEYWORD(notail);585 KEYWORD(target);586 KEYWORD(triple);587 KEYWORD(source_filename);588 KEYWORD(unwind);589 KEYWORD(datalayout);590 KEYWORD(volatile);591 KEYWORD(atomic);592 KEYWORD(unordered);593 KEYWORD(monotonic);594 KEYWORD(acquire);595 KEYWORD(release);596 KEYWORD(acq_rel);597 KEYWORD(seq_cst);598 KEYWORD(syncscope);599 600 KEYWORD(nnan);601 KEYWORD(ninf);602 KEYWORD(nsz);603 KEYWORD(arcp);604 KEYWORD(contract);605 KEYWORD(reassoc);606 KEYWORD(afn);607 KEYWORD(fast);608 KEYWORD(nuw);609 KEYWORD(nsw);610 KEYWORD(nusw);611 KEYWORD(exact);612 KEYWORD(disjoint);613 KEYWORD(inbounds);614 KEYWORD(nneg);615 KEYWORD(samesign);616 KEYWORD(inrange);617 KEYWORD(addrspace);618 KEYWORD(section);619 KEYWORD(partition);620 KEYWORD(code_model);621 KEYWORD(alias);622 KEYWORD(ifunc);623 KEYWORD(module);624 KEYWORD(asm);625 KEYWORD(sideeffect);626 KEYWORD(inteldialect);627 KEYWORD(gc);628 KEYWORD(prefix);629 KEYWORD(prologue);630 631 KEYWORD(no_sanitize_address);632 KEYWORD(no_sanitize_hwaddress);633 KEYWORD(sanitize_address_dyninit);634 635 KEYWORD(ccc);636 KEYWORD(fastcc);637 KEYWORD(coldcc);638 KEYWORD(cfguard_checkcc);639 KEYWORD(x86_stdcallcc);640 KEYWORD(x86_fastcallcc);641 KEYWORD(x86_thiscallcc);642 KEYWORD(x86_vectorcallcc);643 KEYWORD(arm_apcscc);644 KEYWORD(arm_aapcscc);645 KEYWORD(arm_aapcs_vfpcc);646 KEYWORD(aarch64_vector_pcs);647 KEYWORD(aarch64_sve_vector_pcs);648 KEYWORD(aarch64_sme_preservemost_from_x0);649 KEYWORD(aarch64_sme_preservemost_from_x1);650 KEYWORD(aarch64_sme_preservemost_from_x2);651 KEYWORD(msp430_intrcc);652 KEYWORD(avr_intrcc);653 KEYWORD(avr_signalcc);654 KEYWORD(ptx_kernel);655 KEYWORD(ptx_device);656 KEYWORD(spir_kernel);657 KEYWORD(spir_func);658 KEYWORD(intel_ocl_bicc);659 KEYWORD(x86_64_sysvcc);660 KEYWORD(win64cc);661 KEYWORD(x86_regcallcc);662 KEYWORD(swiftcc);663 KEYWORD(swifttailcc);664 KEYWORD(anyregcc);665 KEYWORD(preserve_mostcc);666 KEYWORD(preserve_allcc);667 KEYWORD(preserve_nonecc);668 KEYWORD(ghccc);669 KEYWORD(x86_intrcc);670 KEYWORD(hhvmcc);671 KEYWORD(hhvm_ccc);672 KEYWORD(cxx_fast_tlscc);673 KEYWORD(amdgpu_vs);674 KEYWORD(amdgpu_ls);675 KEYWORD(amdgpu_hs);676 KEYWORD(amdgpu_es);677 KEYWORD(amdgpu_gs);678 KEYWORD(amdgpu_ps);679 KEYWORD(amdgpu_cs);680 KEYWORD(amdgpu_cs_chain);681 KEYWORD(amdgpu_cs_chain_preserve);682 KEYWORD(amdgpu_kernel);683 KEYWORD(amdgpu_gfx);684 KEYWORD(amdgpu_gfx_whole_wave);685 KEYWORD(tailcc);686 KEYWORD(m68k_rtdcc);687 KEYWORD(graalcc);688 KEYWORD(riscv_vector_cc);689 KEYWORD(riscv_vls_cc);690 KEYWORD(cheriot_compartmentcallcc);691 KEYWORD(cheriot_compartmentcalleecc);692 KEYWORD(cheriot_librarycallcc);693 694 KEYWORD(cc);695 KEYWORD(c);696 697 KEYWORD(attributes);698 KEYWORD(sync);699 KEYWORD(async);700 701#define GET_ATTR_NAMES702#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \703 KEYWORD(DISPLAY_NAME);704#include "llvm/IR/Attributes.inc"705 706 KEYWORD(read);707 KEYWORD(write);708 KEYWORD(readwrite);709 KEYWORD(argmem);710 KEYWORD(target_mem0);711 KEYWORD(target_mem1);712 KEYWORD(inaccessiblemem);713 KEYWORD(errnomem);714 KEYWORD(argmemonly);715 KEYWORD(inaccessiblememonly);716 KEYWORD(inaccessiblemem_or_argmemonly);717 KEYWORD(nocapture);718 KEYWORD(address_is_null);719 KEYWORD(address);720 KEYWORD(provenance);721 KEYWORD(read_provenance);722 723 // nofpclass attribute724 KEYWORD(all);725 KEYWORD(nan);726 KEYWORD(snan);727 KEYWORD(qnan);728 KEYWORD(inf);729 // ninf already a keyword730 KEYWORD(pinf);731 KEYWORD(norm);732 KEYWORD(nnorm);733 KEYWORD(pnorm);734 // sub already a keyword735 KEYWORD(nsub);736 KEYWORD(psub);737 KEYWORD(zero);738 KEYWORD(nzero);739 KEYWORD(pzero);740 741 KEYWORD(type);742 KEYWORD(opaque);743 744 KEYWORD(comdat);745 746 // Comdat types747 KEYWORD(any);748 KEYWORD(exactmatch);749 KEYWORD(largest);750 KEYWORD(nodeduplicate);751 KEYWORD(samesize);752 753 KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);754 KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);755 KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole);756 KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une);757 758 KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);759 KEYWORD(umin); KEYWORD(fmax); KEYWORD(fmin);760 KEYWORD(fmaximum);761 KEYWORD(fminimum);762 KEYWORD(uinc_wrap);763 KEYWORD(udec_wrap);764 KEYWORD(usub_cond);765 KEYWORD(usub_sat);766 767 KEYWORD(splat);768 KEYWORD(vscale);769 KEYWORD(x);770 KEYWORD(blockaddress);771 KEYWORD(dso_local_equivalent);772 KEYWORD(no_cfi);773 KEYWORD(ptrauth);774 775 // Metadata types.776 KEYWORD(distinct);777 778 // Use-list order directives.779 KEYWORD(uselistorder);780 KEYWORD(uselistorder_bb);781 782 KEYWORD(personality);783 KEYWORD(cleanup);784 KEYWORD(catch);785 KEYWORD(filter);786 787 // Summary index keywords.788 KEYWORD(path);789 KEYWORD(hash);790 KEYWORD(gv);791 KEYWORD(guid);792 KEYWORD(name);793 KEYWORD(summaries);794 KEYWORD(flags);795 KEYWORD(blockcount);796 KEYWORD(linkage);797 KEYWORD(visibility);798 KEYWORD(notEligibleToImport);799 KEYWORD(live);800 KEYWORD(dsoLocal);801 KEYWORD(canAutoHide);802 KEYWORD(importType);803 KEYWORD(definition);804 KEYWORD(declaration);805 KEYWORD(function);806 KEYWORD(insts);807 KEYWORD(funcFlags);808 KEYWORD(readNone);809 KEYWORD(readOnly);810 KEYWORD(noRecurse);811 KEYWORD(returnDoesNotAlias);812 KEYWORD(noInline);813 KEYWORD(alwaysInline);814 KEYWORD(noUnwind);815 KEYWORD(mayThrow);816 KEYWORD(hasUnknownCall);817 KEYWORD(mustBeUnreachable);818 KEYWORD(calls);819 KEYWORD(callee);820 KEYWORD(params);821 KEYWORD(param);822 KEYWORD(hotness);823 KEYWORD(unknown);824 KEYWORD(critical);825 KEYWORD(relbf);826 KEYWORD(variable);827 KEYWORD(vTableFuncs);828 KEYWORD(virtFunc);829 KEYWORD(aliasee);830 KEYWORD(refs);831 KEYWORD(typeIdInfo);832 KEYWORD(typeTests);833 KEYWORD(typeTestAssumeVCalls);834 KEYWORD(typeCheckedLoadVCalls);835 KEYWORD(typeTestAssumeConstVCalls);836 KEYWORD(typeCheckedLoadConstVCalls);837 KEYWORD(vFuncId);838 KEYWORD(offset);839 KEYWORD(args);840 KEYWORD(typeid);841 KEYWORD(typeidCompatibleVTable);842 KEYWORD(summary);843 KEYWORD(typeTestRes);844 KEYWORD(kind);845 KEYWORD(unsat);846 KEYWORD(byteArray);847 KEYWORD(inline);848 KEYWORD(single);849 KEYWORD(allOnes);850 KEYWORD(sizeM1BitWidth);851 KEYWORD(alignLog2);852 KEYWORD(sizeM1);853 KEYWORD(bitMask);854 KEYWORD(inlineBits);855 KEYWORD(vcall_visibility);856 KEYWORD(wpdResolutions);857 KEYWORD(wpdRes);858 KEYWORD(indir);859 KEYWORD(singleImpl);860 KEYWORD(branchFunnel);861 KEYWORD(singleImplName);862 KEYWORD(resByArg);863 KEYWORD(byArg);864 KEYWORD(uniformRetVal);865 KEYWORD(uniqueRetVal);866 KEYWORD(virtualConstProp);867 KEYWORD(info);868 KEYWORD(byte);869 KEYWORD(bit);870 KEYWORD(varFlags);871 KEYWORD(callsites);872 KEYWORD(clones);873 KEYWORD(stackIds);874 KEYWORD(allocs);875 KEYWORD(versions);876 KEYWORD(memProf);877 KEYWORD(notcold);878 879#undef KEYWORD880 881 // Keywords for types.882#define TYPEKEYWORD(STR, LLVMTY) \883 do { \884 if (Keyword == STR) { \885 TyVal = LLVMTY; \886 return lltok::Type; \887 } \888 } while (false)889 890 TYPEKEYWORD("void", Type::getVoidTy(Context));891 TYPEKEYWORD("half", Type::getHalfTy(Context));892 TYPEKEYWORD("bfloat", Type::getBFloatTy(Context));893 TYPEKEYWORD("float", Type::getFloatTy(Context));894 TYPEKEYWORD("double", Type::getDoubleTy(Context));895 TYPEKEYWORD("x86_fp80", Type::getX86_FP80Ty(Context));896 TYPEKEYWORD("fp128", Type::getFP128Ty(Context));897 TYPEKEYWORD("ppc_fp128", Type::getPPC_FP128Ty(Context));898 TYPEKEYWORD("label", Type::getLabelTy(Context));899 TYPEKEYWORD("metadata", Type::getMetadataTy(Context));900 TYPEKEYWORD("x86_amx", Type::getX86_AMXTy(Context));901 TYPEKEYWORD("token", Type::getTokenTy(Context));902 TYPEKEYWORD("ptr", PointerType::getUnqual(Context));903 904#undef TYPEKEYWORD905 906 // Keywords for instructions.907#define INSTKEYWORD(STR, Enum) \908 do { \909 if (Keyword == #STR) { \910 UIntVal = Instruction::Enum; \911 return lltok::kw_##STR; \912 } \913 } while (false)914 915 INSTKEYWORD(fneg, FNeg);916 917 INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);918 INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);919 INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);920 INSTKEYWORD(udiv, UDiv); INSTKEYWORD(sdiv, SDiv); INSTKEYWORD(fdiv, FDiv);921 INSTKEYWORD(urem, URem); INSTKEYWORD(srem, SRem); INSTKEYWORD(frem, FRem);922 INSTKEYWORD(shl, Shl); INSTKEYWORD(lshr, LShr); INSTKEYWORD(ashr, AShr);923 INSTKEYWORD(and, And); INSTKEYWORD(or, Or); INSTKEYWORD(xor, Xor);924 INSTKEYWORD(icmp, ICmp); INSTKEYWORD(fcmp, FCmp);925 926 INSTKEYWORD(phi, PHI);927 INSTKEYWORD(call, Call);928 INSTKEYWORD(trunc, Trunc);929 INSTKEYWORD(zext, ZExt);930 INSTKEYWORD(sext, SExt);931 INSTKEYWORD(fptrunc, FPTrunc);932 INSTKEYWORD(fpext, FPExt);933 INSTKEYWORD(uitofp, UIToFP);934 INSTKEYWORD(sitofp, SIToFP);935 INSTKEYWORD(fptoui, FPToUI);936 INSTKEYWORD(fptosi, FPToSI);937 INSTKEYWORD(inttoptr, IntToPtr);938 INSTKEYWORD(ptrtoaddr, PtrToAddr);939 INSTKEYWORD(ptrtoint, PtrToInt);940 INSTKEYWORD(bitcast, BitCast);941 INSTKEYWORD(addrspacecast, AddrSpaceCast);942 INSTKEYWORD(select, Select);943 INSTKEYWORD(va_arg, VAArg);944 INSTKEYWORD(ret, Ret);945 INSTKEYWORD(br, Br);946 INSTKEYWORD(switch, Switch);947 INSTKEYWORD(indirectbr, IndirectBr);948 INSTKEYWORD(invoke, Invoke);949 INSTKEYWORD(resume, Resume);950 INSTKEYWORD(unreachable, Unreachable);951 INSTKEYWORD(callbr, CallBr);952 953 INSTKEYWORD(alloca, Alloca);954 INSTKEYWORD(load, Load);955 INSTKEYWORD(store, Store);956 INSTKEYWORD(cmpxchg, AtomicCmpXchg);957 INSTKEYWORD(atomicrmw, AtomicRMW);958 INSTKEYWORD(fence, Fence);959 INSTKEYWORD(getelementptr, GetElementPtr);960 961 INSTKEYWORD(extractelement, ExtractElement);962 INSTKEYWORD(insertelement, InsertElement);963 INSTKEYWORD(shufflevector, ShuffleVector);964 INSTKEYWORD(extractvalue, ExtractValue);965 INSTKEYWORD(insertvalue, InsertValue);966 INSTKEYWORD(landingpad, LandingPad);967 INSTKEYWORD(cleanupret, CleanupRet);968 INSTKEYWORD(catchret, CatchRet);969 INSTKEYWORD(catchswitch, CatchSwitch);970 INSTKEYWORD(catchpad, CatchPad);971 INSTKEYWORD(cleanuppad, CleanupPad);972 973 INSTKEYWORD(freeze, Freeze);974 975#undef INSTKEYWORD976 977#define DWKEYWORD(TYPE, TOKEN) \978 do { \979 if (Keyword.starts_with("DW_" #TYPE "_")) { \980 StrVal.assign(Keyword.begin(), Keyword.end()); \981 return lltok::TOKEN; \982 } \983 } while (false)984 985 DWKEYWORD(TAG, DwarfTag);986 DWKEYWORD(ATE, DwarfAttEncoding);987 DWKEYWORD(VIRTUALITY, DwarfVirtuality);988 DWKEYWORD(LANG, DwarfLang);989 DWKEYWORD(LNAME, DwarfSourceLangName);990 DWKEYWORD(CC, DwarfCC);991 DWKEYWORD(OP, DwarfOp);992 DWKEYWORD(MACINFO, DwarfMacinfo);993 DWKEYWORD(APPLE_ENUM_KIND, DwarfEnumKind);994 995#undef DWKEYWORD996 997// Keywords for debug record types.998#define DBGRECORDTYPEKEYWORD(STR) \999 do { \1000 if (Keyword == "dbg_" #STR) { \1001 StrVal = #STR; \1002 return lltok::DbgRecordType; \1003 } \1004 } while (false)1005 1006 DBGRECORDTYPEKEYWORD(value);1007 DBGRECORDTYPEKEYWORD(declare);1008 DBGRECORDTYPEKEYWORD(assign);1009 DBGRECORDTYPEKEYWORD(label);1010 DBGRECORDTYPEKEYWORD(declare_value);1011#undef DBGRECORDTYPEKEYWORD1012 1013 if (Keyword.starts_with("DIFlag")) {1014 StrVal.assign(Keyword.begin(), Keyword.end());1015 return lltok::DIFlag;1016 }1017 1018 if (Keyword.starts_with("DISPFlag")) {1019 StrVal.assign(Keyword.begin(), Keyword.end());1020 return lltok::DISPFlag;1021 }1022 1023 if (Keyword.starts_with("CSK_")) {1024 StrVal.assign(Keyword.begin(), Keyword.end());1025 return lltok::ChecksumKind;1026 }1027 1028 if (Keyword == "NoDebug" || Keyword == "FullDebug" ||1029 Keyword == "LineTablesOnly" || Keyword == "DebugDirectivesOnly") {1030 StrVal.assign(Keyword.begin(), Keyword.end());1031 return lltok::EmissionKind;1032 }1033 1034 if (Keyword == "GNU" || Keyword == "Apple" || Keyword == "None" ||1035 Keyword == "Default") {1036 StrVal.assign(Keyword.begin(), Keyword.end());1037 return lltok::NameTableKind;1038 }1039 1040 if (Keyword == "Binary" || Keyword == "Decimal" || Keyword == "Rational") {1041 StrVal.assign(Keyword.begin(), Keyword.end());1042 return lltok::FixedPointKind;1043 }1044 1045 // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by1046 // the CFE to avoid forcing it to deal with 64-bit numbers.1047 if ((TokStart[0] == 'u' || TokStart[0] == 's') &&1048 TokStart[1] == '0' && TokStart[2] == 'x' &&1049 isxdigit(static_cast<unsigned char>(TokStart[3]))) {1050 int len = CurPtr-TokStart-3;1051 uint32_t bits = len * 4;1052 StringRef HexStr(TokStart + 3, len);1053 if (!all_of(HexStr, isxdigit)) {1054 // Bad token, return it as an error.1055 CurPtr = TokStart+3;1056 return lltok::Error;1057 }1058 APInt Tmp(bits, HexStr, 16);1059 uint32_t activeBits = Tmp.getActiveBits();1060 if (activeBits > 0 && activeBits < bits)1061 Tmp = Tmp.trunc(activeBits);1062 APSIntVal = APSInt(Tmp, TokStart[0] == 'u');1063 return lltok::APSInt;1064 }1065 1066 // If this is "cc1234", return this as just "cc".1067 if (TokStart[0] == 'c' && TokStart[1] == 'c') {1068 CurPtr = TokStart+2;1069 return lltok::kw_cc;1070 }1071 1072 // Finally, if this isn't known, return an error.1073 CurPtr = TokStart+1;1074 return lltok::Error;1075}1076 1077/// Lex all tokens that start with a 0x prefix, knowing they match and are not1078/// labels.1079/// HexFPConstant 0x[0-9A-Fa-f]+1080/// HexFP80Constant 0xK[0-9A-Fa-f]+1081/// HexFP128Constant 0xL[0-9A-Fa-f]+1082/// HexPPC128Constant 0xM[0-9A-Fa-f]+1083/// HexHalfConstant 0xH[0-9A-Fa-f]+1084/// HexBFloatConstant 0xR[0-9A-Fa-f]+1085lltok::Kind LLLexer::Lex0x() {1086 CurPtr = TokStart + 2;1087 1088 char Kind;1089 if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H' ||1090 CurPtr[0] == 'R') {1091 Kind = *CurPtr++;1092 } else {1093 Kind = 'J';1094 }1095 1096 if (!isxdigit(static_cast<unsigned char>(CurPtr[0]))) {1097 // Bad token, return it as an error.1098 CurPtr = TokStart+1;1099 return lltok::Error;1100 }1101 1102 while (isxdigit(static_cast<unsigned char>(CurPtr[0])))1103 ++CurPtr;1104 1105 if (Kind == 'J') {1106 // HexFPConstant - Floating point constant represented in IEEE format as a1107 // hexadecimal number for when exponential notation is not precise enough.1108 // Half, BFloat, Float, and double only.1109 APFloatVal = APFloat(APFloat::IEEEdouble(),1110 APInt(64, HexIntToVal(TokStart + 2, CurPtr)));1111 return lltok::APFloat;1112 }1113 1114 uint64_t Pair[2];1115 switch (Kind) {1116 default: llvm_unreachable("Unknown kind!");1117 case 'K':1118 // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)1119 FP80HexToIntPair(TokStart+3, CurPtr, Pair);1120 APFloatVal = APFloat(APFloat::x87DoubleExtended(), APInt(80, Pair));1121 return lltok::APFloat;1122 case 'L':1123 // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)1124 HexToIntPair(TokStart+3, CurPtr, Pair);1125 APFloatVal = APFloat(APFloat::IEEEquad(), APInt(128, Pair));1126 return lltok::APFloat;1127 case 'M':1128 // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)1129 HexToIntPair(TokStart+3, CurPtr, Pair);1130 APFloatVal = APFloat(APFloat::PPCDoubleDouble(), APInt(128, Pair));1131 return lltok::APFloat;1132 case 'H':1133 APFloatVal = APFloat(APFloat::IEEEhalf(),1134 APInt(16,HexIntToVal(TokStart+3, CurPtr)));1135 return lltok::APFloat;1136 case 'R':1137 // Brain floating point1138 APFloatVal = APFloat(APFloat::BFloat(),1139 APInt(16, HexIntToVal(TokStart + 3, CurPtr)));1140 return lltok::APFloat;1141 }1142}1143 1144/// Lex tokens for a label or a numeric constant, possibly starting with -.1145/// Label [-a-zA-Z$._0-9]+:1146/// NInteger -[0-9]+1147/// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?1148/// PInteger [0-9]+1149/// HexFPConstant 0x[0-9A-Fa-f]+1150/// HexFP80Constant 0xK[0-9A-Fa-f]+1151/// HexFP128Constant 0xL[0-9A-Fa-f]+1152/// HexPPC128Constant 0xM[0-9A-Fa-f]+1153lltok::Kind LLLexer::LexDigitOrNegative() {1154 // If the letter after the negative is not a number, this is probably a label.1155 if (!isdigit(static_cast<unsigned char>(TokStart[0])) &&1156 !isdigit(static_cast<unsigned char>(CurPtr[0]))) {1157 // Okay, this is not a number after the -, it's probably a label.1158 if (const char *End = isLabelTail(CurPtr)) {1159 StrVal.assign(TokStart, End-1);1160 CurPtr = End;1161 return lltok::LabelStr;1162 }1163 1164 return lltok::Error;1165 }1166 1167 // At this point, it is either a label, int or fp constant.1168 1169 // Skip digits, we have at least one.1170 for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)1171 /*empty*/;1172 1173 // Check if this is a fully-numeric label:1174 if (isdigit(TokStart[0]) && CurPtr[0] == ':') {1175 uint64_t Val = atoull(TokStart, CurPtr);1176 ++CurPtr; // Skip the colon.1177 if ((unsigned)Val != Val)1178 LexError("invalid value number (too large)");1179 UIntVal = unsigned(Val);1180 return lltok::LabelID;1181 }1182 1183 // Check to see if this really is a string label, e.g. "-1:".1184 if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {1185 if (const char *End = isLabelTail(CurPtr)) {1186 StrVal.assign(TokStart, End-1);1187 CurPtr = End;1188 return lltok::LabelStr;1189 }1190 }1191 1192 // If the next character is a '.', then it is a fp value, otherwise its1193 // integer.1194 if (CurPtr[0] != '.') {1195 if (TokStart[0] == '0' && TokStart[1] == 'x')1196 return Lex0x();1197 APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));1198 return lltok::APSInt;1199 }1200 1201 ++CurPtr;1202 1203 // Skip over [0-9]*([eE][-+]?[0-9]+)?1204 while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;1205 1206 if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {1207 if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||1208 ((CurPtr[1] == '-' || CurPtr[1] == '+') &&1209 isdigit(static_cast<unsigned char>(CurPtr[2])))) {1210 CurPtr += 2;1211 while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;1212 }1213 }1214 1215 APFloatVal = APFloat(APFloat::IEEEdouble(),1216 StringRef(TokStart, CurPtr - TokStart));1217 return lltok::APFloat;1218}1219 1220/// Lex a floating point constant starting with +.1221/// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?1222lltok::Kind LLLexer::LexPositive() {1223 // If the letter after the negative is a number, this is probably not a1224 // label.1225 if (!isdigit(static_cast<unsigned char>(CurPtr[0])))1226 return lltok::Error;1227 1228 // Skip digits.1229 for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)1230 /*empty*/;1231 1232 // At this point, we need a '.'.1233 if (CurPtr[0] != '.') {1234 CurPtr = TokStart+1;1235 return lltok::Error;1236 }1237 1238 ++CurPtr;1239 1240 // Skip over [0-9]*([eE][-+]?[0-9]+)?1241 while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;1242 1243 if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {1244 if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||1245 ((CurPtr[1] == '-' || CurPtr[1] == '+') &&1246 isdigit(static_cast<unsigned char>(CurPtr[2])))) {1247 CurPtr += 2;1248 while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;1249 }1250 }1251 1252 APFloatVal = APFloat(APFloat::IEEEdouble(),1253 StringRef(TokStart, CurPtr - TokStart));1254 return lltok::APFloat;1255}1256