brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.5 KiB · ef1515c Raw
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