191370c5dSAlex Lorenz //===- MILexer.cpp - Machine instructions lexer implementation ----------===// 291370c5dSAlex Lorenz // 391370c5dSAlex Lorenz // The LLVM Compiler Infrastructure 491370c5dSAlex Lorenz // 591370c5dSAlex Lorenz // This file is distributed under the University of Illinois Open Source 691370c5dSAlex Lorenz // License. See LICENSE.TXT for details. 791370c5dSAlex Lorenz // 891370c5dSAlex Lorenz //===----------------------------------------------------------------------===// 991370c5dSAlex Lorenz // 1091370c5dSAlex Lorenz // This file implements the lexing of machine instructions. 1191370c5dSAlex Lorenz // 1291370c5dSAlex Lorenz //===----------------------------------------------------------------------===// 1391370c5dSAlex Lorenz 1491370c5dSAlex Lorenz #include "MILexer.h" 15b29554daSAlex Lorenz #include "llvm/ADT/StringExtras.h" 16cb268d46SAlex Lorenz #include "llvm/ADT/StringSwitch.h" 1791370c5dSAlex Lorenz #include "llvm/ADT/Twine.h" 1891370c5dSAlex Lorenz #include <cctype> 1991370c5dSAlex Lorenz 2091370c5dSAlex Lorenz using namespace llvm; 2191370c5dSAlex Lorenz 2291370c5dSAlex Lorenz namespace { 2391370c5dSAlex Lorenz 2491370c5dSAlex Lorenz /// This class provides a way to iterate and get characters from the source 2591370c5dSAlex Lorenz /// string. 2691370c5dSAlex Lorenz class Cursor { 2791370c5dSAlex Lorenz const char *Ptr; 2891370c5dSAlex Lorenz const char *End; 2991370c5dSAlex Lorenz 3091370c5dSAlex Lorenz public: 316c6c46e4SAlex Lorenz Cursor(NoneType) : Ptr(nullptr), End(nullptr) {} 326c6c46e4SAlex Lorenz 3391370c5dSAlex Lorenz explicit Cursor(StringRef Str) { 3491370c5dSAlex Lorenz Ptr = Str.data(); 3591370c5dSAlex Lorenz End = Ptr + Str.size(); 3691370c5dSAlex Lorenz } 3791370c5dSAlex Lorenz 3891370c5dSAlex Lorenz bool isEOF() const { return Ptr == End; } 3991370c5dSAlex Lorenz 40c267b5f5SNAKAMURA Takumi char peek(int I = 0) const { return End - Ptr <= I ? 0 : Ptr[I]; } 4191370c5dSAlex Lorenz 4233f0aef3SAlex Lorenz void advance(unsigned I = 1) { Ptr += I; } 4391370c5dSAlex Lorenz 4491370c5dSAlex Lorenz StringRef remaining() const { return StringRef(Ptr, End - Ptr); } 4591370c5dSAlex Lorenz 4691370c5dSAlex Lorenz StringRef upto(Cursor C) const { 4791370c5dSAlex Lorenz assert(C.Ptr >= Ptr && C.Ptr <= End); 4891370c5dSAlex Lorenz return StringRef(Ptr, C.Ptr - Ptr); 4991370c5dSAlex Lorenz } 5091370c5dSAlex Lorenz 5191370c5dSAlex Lorenz StringRef::iterator location() const { return Ptr; } 526c6c46e4SAlex Lorenz 536c6c46e4SAlex Lorenz operator bool() const { return Ptr != nullptr; } 5491370c5dSAlex Lorenz }; 5591370c5dSAlex Lorenz 5691370c5dSAlex Lorenz } // end anonymous namespace 5791370c5dSAlex Lorenz 5891370c5dSAlex Lorenz /// Skip the leading whitespace characters and return the updated cursor. 5991370c5dSAlex Lorenz static Cursor skipWhitespace(Cursor C) { 6091370c5dSAlex Lorenz while (isspace(C.peek())) 6191370c5dSAlex Lorenz C.advance(); 6291370c5dSAlex Lorenz return C; 6391370c5dSAlex Lorenz } 6491370c5dSAlex Lorenz 65484903ecSAlex Lorenz /// Return true if the given character satisfies the following regular 66484903ecSAlex Lorenz /// expression: [-a-zA-Z$._0-9] 6791370c5dSAlex Lorenz static bool isIdentifierChar(char C) { 68484903ecSAlex Lorenz return isalpha(C) || isdigit(C) || C == '_' || C == '-' || C == '.' || 69484903ecSAlex Lorenz C == '$'; 7091370c5dSAlex Lorenz } 7191370c5dSAlex Lorenz 72970c12eaSAlex Lorenz /// Unescapes the given string value. 73970c12eaSAlex Lorenz /// 74970c12eaSAlex Lorenz /// Expects the string value to be quoted. 75970c12eaSAlex Lorenz static std::string unescapeQuotedString(StringRef Value) { 76b29554daSAlex Lorenz assert(Value.front() == '"' && Value.back() == '"'); 77b29554daSAlex Lorenz Cursor C = Cursor(Value.substr(1, Value.size() - 2)); 78b29554daSAlex Lorenz 79970c12eaSAlex Lorenz std::string Str; 80b29554daSAlex Lorenz Str.reserve(C.remaining().size()); 81b29554daSAlex Lorenz while (!C.isEOF()) { 82b29554daSAlex Lorenz char Char = C.peek(); 83b29554daSAlex Lorenz if (Char == '\\') { 84b29554daSAlex Lorenz if (C.peek(1) == '\\') { 85b29554daSAlex Lorenz // Two '\' become one 86b29554daSAlex Lorenz Str += '\\'; 87b29554daSAlex Lorenz C.advance(2); 88b29554daSAlex Lorenz continue; 89b29554daSAlex Lorenz } 90b29554daSAlex Lorenz if (isxdigit(C.peek(1)) && isxdigit(C.peek(2))) { 91b29554daSAlex Lorenz Str += hexDigitValue(C.peek(1)) * 16 + hexDigitValue(C.peek(2)); 92b29554daSAlex Lorenz C.advance(3); 93b29554daSAlex Lorenz continue; 94b29554daSAlex Lorenz } 95b29554daSAlex Lorenz } 96b29554daSAlex Lorenz Str += Char; 97b29554daSAlex Lorenz C.advance(); 98b29554daSAlex Lorenz } 99970c12eaSAlex Lorenz return Str; 100b29554daSAlex Lorenz } 101b29554daSAlex Lorenz 102b29554daSAlex Lorenz /// Lex a string constant using the following regular expression: \"[^\"]*\" 103b29554daSAlex Lorenz static Cursor lexStringConstant( 104b29554daSAlex Lorenz Cursor C, 105b29554daSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 106b29554daSAlex Lorenz assert(C.peek() == '"'); 107b29554daSAlex Lorenz for (C.advance(); C.peek() != '"'; C.advance()) { 108b29554daSAlex Lorenz if (C.isEOF()) { 109b29554daSAlex Lorenz ErrorCallback( 110b29554daSAlex Lorenz C.location(), 111b29554daSAlex Lorenz "end of machine instruction reached before the closing '\"'"); 112b29554daSAlex Lorenz return None; 113b29554daSAlex Lorenz } 114b29554daSAlex Lorenz } 115b29554daSAlex Lorenz C.advance(); 116b29554daSAlex Lorenz return C; 117b29554daSAlex Lorenz } 118b29554daSAlex Lorenz 11982a1cfdcSAlex Lorenz static Cursor lexName( 120970c12eaSAlex Lorenz Cursor C, MIToken &Token, MIToken::TokenKind Type, unsigned PrefixLength, 12182a1cfdcSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 12282a1cfdcSAlex Lorenz auto Range = C; 12382a1cfdcSAlex Lorenz C.advance(PrefixLength); 12482a1cfdcSAlex Lorenz if (C.peek() == '"') { 12582a1cfdcSAlex Lorenz if (Cursor R = lexStringConstant(C, ErrorCallback)) { 126970c12eaSAlex Lorenz StringRef String = Range.upto(R); 127970c12eaSAlex Lorenz Token = MIToken(Type, String, 128970c12eaSAlex Lorenz unescapeQuotedString(String.drop_front(PrefixLength)), 129970c12eaSAlex Lorenz PrefixLength); 13082a1cfdcSAlex Lorenz return R; 13182a1cfdcSAlex Lorenz } 13282a1cfdcSAlex Lorenz Token = MIToken(MIToken::Error, Range.remaining()); 13382a1cfdcSAlex Lorenz return Range; 13482a1cfdcSAlex Lorenz } 13582a1cfdcSAlex Lorenz while (isIdentifierChar(C.peek())) 13682a1cfdcSAlex Lorenz C.advance(); 13782a1cfdcSAlex Lorenz Token = MIToken(Type, Range.upto(C), PrefixLength); 13882a1cfdcSAlex Lorenz return C; 13982a1cfdcSAlex Lorenz } 14082a1cfdcSAlex Lorenz 141*05e3882eSAlex Lorenz static Cursor maybeLexIntegerType(Cursor C, MIToken &Token) { 142*05e3882eSAlex Lorenz if (C.peek() != 'i' || !isdigit(C.peek(1))) 143*05e3882eSAlex Lorenz return None; 144*05e3882eSAlex Lorenz auto Range = C; 145*05e3882eSAlex Lorenz C.advance(); // Skip 'i' 146*05e3882eSAlex Lorenz while (isdigit(C.peek())) 147*05e3882eSAlex Lorenz C.advance(); 148*05e3882eSAlex Lorenz Token = MIToken(MIToken::IntegerType, Range.upto(C)); 149*05e3882eSAlex Lorenz return C; 150*05e3882eSAlex Lorenz } 151*05e3882eSAlex Lorenz 152cb268d46SAlex Lorenz static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { 153cb268d46SAlex Lorenz return StringSwitch<MIToken::TokenKind>(Identifier) 154cb268d46SAlex Lorenz .Case("_", MIToken::underscore) 155cb268d46SAlex Lorenz .Case("implicit", MIToken::kw_implicit) 156cb268d46SAlex Lorenz .Case("implicit-def", MIToken::kw_implicit_define) 157cbbfd0b1SAlex Lorenz .Case("dead", MIToken::kw_dead) 158495ad879SAlex Lorenz .Case("killed", MIToken::kw_killed) 1594d026b89SAlex Lorenz .Case("undef", MIToken::kw_undef) 16001c1a5eeSAlex Lorenz .Case("early-clobber", MIToken::kw_early_clobber) 1619075258bSAlex Lorenz .Case("debug-use", MIToken::kw_debug_use) 162e5a44660SAlex Lorenz .Case("frame-setup", MIToken::kw_frame_setup) 16346d760d1SAlex Lorenz .Case("debug-location", MIToken::kw_debug_location) 1648cfc6867SAlex Lorenz .Case(".cfi_offset", MIToken::kw_cfi_offset) 1655b0d5f6fSAlex Lorenz .Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register) 166f4baeb51SAlex Lorenz .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) 167b139323fSAlex Lorenz .Case(".cfi_def_cfa", MIToken::kw_cfi_def_cfa) 168deb53490SAlex Lorenz .Case("blockaddress", MIToken::kw_blockaddress) 169ef5c196fSAlex Lorenz .Case("target-index", MIToken::kw_target_index) 170ad156fb6SAlex Lorenz .Case("half", MIToken::kw_half) 171ad156fb6SAlex Lorenz .Case("float", MIToken::kw_float) 172ad156fb6SAlex Lorenz .Case("double", MIToken::kw_double) 173ad156fb6SAlex Lorenz .Case("x86_fp80", MIToken::kw_x86_fp80) 174ad156fb6SAlex Lorenz .Case("fp128", MIToken::kw_fp128) 175ad156fb6SAlex Lorenz .Case("ppc_fp128", MIToken::kw_ppc_fp128) 176a518b796SAlex Lorenz .Case("volatile", MIToken::kw_volatile) 177cb268d46SAlex Lorenz .Default(MIToken::Identifier); 178cb268d46SAlex Lorenz } 179cb268d46SAlex Lorenz 1806c6c46e4SAlex Lorenz static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) { 181f4baeb51SAlex Lorenz if (!isalpha(C.peek()) && C.peek() != '_' && C.peek() != '.') 1826c6c46e4SAlex Lorenz return None; 18391370c5dSAlex Lorenz auto Range = C; 18491370c5dSAlex Lorenz while (isIdentifierChar(C.peek())) 18591370c5dSAlex Lorenz C.advance(); 18612b554e6SAlex Lorenz auto Identifier = Range.upto(C); 187cb268d46SAlex Lorenz Token = MIToken(getIdentifierKind(Identifier), Identifier); 18891370c5dSAlex Lorenz return C; 18991370c5dSAlex Lorenz } 19091370c5dSAlex Lorenz 1916c6c46e4SAlex Lorenz static Cursor maybeLexMachineBasicBlock( 19233f0aef3SAlex Lorenz Cursor C, MIToken &Token, 19333f0aef3SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 1946c6c46e4SAlex Lorenz if (!C.remaining().startswith("%bb.")) 1956c6c46e4SAlex Lorenz return None; 19633f0aef3SAlex Lorenz auto Range = C; 19733f0aef3SAlex Lorenz C.advance(4); // Skip '%bb.' 19833f0aef3SAlex Lorenz if (!isdigit(C.peek())) { 19933f0aef3SAlex Lorenz Token = MIToken(MIToken::Error, C.remaining()); 20033f0aef3SAlex Lorenz ErrorCallback(C.location(), "expected a number after '%bb.'"); 20133f0aef3SAlex Lorenz return C; 20233f0aef3SAlex Lorenz } 20333f0aef3SAlex Lorenz auto NumberRange = C; 20433f0aef3SAlex Lorenz while (isdigit(C.peek())) 20533f0aef3SAlex Lorenz C.advance(); 20633f0aef3SAlex Lorenz StringRef Number = NumberRange.upto(C); 20733f0aef3SAlex Lorenz unsigned StringOffset = 4 + Number.size(); // Drop '%bb.<id>' 20833f0aef3SAlex Lorenz if (C.peek() == '.') { 20933f0aef3SAlex Lorenz C.advance(); // Skip '.' 21033f0aef3SAlex Lorenz ++StringOffset; 21133f0aef3SAlex Lorenz while (isIdentifierChar(C.peek())) 21233f0aef3SAlex Lorenz C.advance(); 21333f0aef3SAlex Lorenz } 21433f0aef3SAlex Lorenz Token = MIToken(MIToken::MachineBasicBlock, Range.upto(C), APSInt(Number), 21533f0aef3SAlex Lorenz StringOffset); 21633f0aef3SAlex Lorenz return C; 21733f0aef3SAlex Lorenz } 21833f0aef3SAlex Lorenz 21931d70683SAlex Lorenz static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule, 22031d70683SAlex Lorenz MIToken::TokenKind Kind) { 22131d70683SAlex Lorenz if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size()))) 22231d70683SAlex Lorenz return None; 22331d70683SAlex Lorenz auto Range = C; 22431d70683SAlex Lorenz C.advance(Rule.size()); 22531d70683SAlex Lorenz auto NumberRange = C; 22631d70683SAlex Lorenz while (isdigit(C.peek())) 22731d70683SAlex Lorenz C.advance(); 22831d70683SAlex Lorenz Token = MIToken(Kind, Range.upto(C), APSInt(NumberRange.upto(C))); 22931d70683SAlex Lorenz return C; 23031d70683SAlex Lorenz } 23131d70683SAlex Lorenz 2327feaf7c6SAlex Lorenz static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule, 2337feaf7c6SAlex Lorenz MIToken::TokenKind Kind) { 2347feaf7c6SAlex Lorenz if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size()))) 2357feaf7c6SAlex Lorenz return None; 2367feaf7c6SAlex Lorenz auto Range = C; 2377feaf7c6SAlex Lorenz C.advance(Rule.size()); 2387feaf7c6SAlex Lorenz auto NumberRange = C; 2397feaf7c6SAlex Lorenz while (isdigit(C.peek())) 2407feaf7c6SAlex Lorenz C.advance(); 2417feaf7c6SAlex Lorenz StringRef Number = NumberRange.upto(C); 2427feaf7c6SAlex Lorenz unsigned StringOffset = Rule.size() + Number.size(); 2437feaf7c6SAlex Lorenz if (C.peek() == '.') { 2447feaf7c6SAlex Lorenz C.advance(); 2457feaf7c6SAlex Lorenz ++StringOffset; 2467feaf7c6SAlex Lorenz while (isIdentifierChar(C.peek())) 2477feaf7c6SAlex Lorenz C.advance(); 2487feaf7c6SAlex Lorenz } 2497feaf7c6SAlex Lorenz Token = MIToken(Kind, Range.upto(C), APSInt(Number), StringOffset); 2507feaf7c6SAlex Lorenz return C; 2517feaf7c6SAlex Lorenz } 2527feaf7c6SAlex Lorenz 25331d70683SAlex Lorenz static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) { 25431d70683SAlex Lorenz return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex); 25531d70683SAlex Lorenz } 25631d70683SAlex Lorenz 2577feaf7c6SAlex Lorenz static Cursor maybeLexStackObject(Cursor C, MIToken &Token) { 2587feaf7c6SAlex Lorenz return maybeLexIndexAndName(C, Token, "%stack.", MIToken::StackObject); 2597feaf7c6SAlex Lorenz } 2607feaf7c6SAlex Lorenz 2617feaf7c6SAlex Lorenz static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) { 2627feaf7c6SAlex Lorenz return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject); 2637feaf7c6SAlex Lorenz } 2647feaf7c6SAlex Lorenz 265ab980499SAlex Lorenz static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) { 266ab980499SAlex Lorenz return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem); 267ab980499SAlex Lorenz } 268ab980499SAlex Lorenz 269deb53490SAlex Lorenz static Cursor maybeLexIRBlock( 270deb53490SAlex Lorenz Cursor C, MIToken &Token, 271deb53490SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 272deb53490SAlex Lorenz const StringRef Rule = "%ir-block."; 273deb53490SAlex Lorenz if (!C.remaining().startswith(Rule)) 274deb53490SAlex Lorenz return None; 275deb53490SAlex Lorenz if (isdigit(C.peek(Rule.size()))) 276deb53490SAlex Lorenz return maybeLexIndex(C, Token, Rule, MIToken::IRBlock); 277970c12eaSAlex Lorenz return lexName(C, Token, MIToken::NamedIRBlock, Rule.size(), ErrorCallback); 2788a1915b0SAlex Lorenz } 2798a1915b0SAlex Lorenz 2804af7e610SAlex Lorenz static Cursor maybeLexIRValue( 2814af7e610SAlex Lorenz Cursor C, MIToken &Token, 2824af7e610SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 2834af7e610SAlex Lorenz const StringRef Rule = "%ir."; 2844af7e610SAlex Lorenz if (!C.remaining().startswith(Rule)) 2854af7e610SAlex Lorenz return None; 286970c12eaSAlex Lorenz return lexName(C, Token, MIToken::NamedIRValue, Rule.size(), ErrorCallback); 2874af7e610SAlex Lorenz } 2884af7e610SAlex Lorenz 28953464510SAlex Lorenz static Cursor lexVirtualRegister(Cursor C, MIToken &Token) { 29053464510SAlex Lorenz auto Range = C; 29153464510SAlex Lorenz C.advance(); // Skip '%' 29253464510SAlex Lorenz auto NumberRange = C; 29353464510SAlex Lorenz while (isdigit(C.peek())) 29453464510SAlex Lorenz C.advance(); 29553464510SAlex Lorenz Token = MIToken(MIToken::VirtualRegister, Range.upto(C), 29653464510SAlex Lorenz APSInt(NumberRange.upto(C))); 29753464510SAlex Lorenz return C; 29853464510SAlex Lorenz } 29953464510SAlex Lorenz 3006c6c46e4SAlex Lorenz static Cursor maybeLexRegister(Cursor C, MIToken &Token) { 3016c6c46e4SAlex Lorenz if (C.peek() != '%') 3026c6c46e4SAlex Lorenz return None; 30353464510SAlex Lorenz if (isdigit(C.peek(1))) 30453464510SAlex Lorenz return lexVirtualRegister(C, Token); 305f3db51deSAlex Lorenz auto Range = C; 306f3db51deSAlex Lorenz C.advance(); // Skip '%' 307f3db51deSAlex Lorenz while (isIdentifierChar(C.peek())) 308f3db51deSAlex Lorenz C.advance(); 30933f0aef3SAlex Lorenz Token = MIToken(MIToken::NamedRegister, Range.upto(C), 31033f0aef3SAlex Lorenz /*StringOffset=*/1); // Drop the '%' 311f3db51deSAlex Lorenz return C; 312f3db51deSAlex Lorenz } 313f3db51deSAlex Lorenz 314c1fbb354SAlex Lorenz static Cursor maybeLexGlobalValue( 315c1fbb354SAlex Lorenz Cursor C, MIToken &Token, 316c1fbb354SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 317c1fbb354SAlex Lorenz if (C.peek() != '@') 318c1fbb354SAlex Lorenz return None; 319c1fbb354SAlex Lorenz if (!isdigit(C.peek(1))) 320970c12eaSAlex Lorenz return lexName(C, Token, MIToken::NamedGlobalValue, /*PrefixLength=*/1, 321c1fbb354SAlex Lorenz ErrorCallback); 322c1fbb354SAlex Lorenz auto Range = C; 323c1fbb354SAlex Lorenz C.advance(1); // Skip the '@' 324c1fbb354SAlex Lorenz auto NumberRange = C; 325c1fbb354SAlex Lorenz while (isdigit(C.peek())) 326c1fbb354SAlex Lorenz C.advance(); 327c1fbb354SAlex Lorenz Token = 328c1fbb354SAlex Lorenz MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C))); 329c1fbb354SAlex Lorenz return C; 330c1fbb354SAlex Lorenz } 331c1fbb354SAlex Lorenz 3326ede3744SAlex Lorenz static Cursor maybeLexExternalSymbol( 3336ede3744SAlex Lorenz Cursor C, MIToken &Token, 3346ede3744SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 3356ede3744SAlex Lorenz if (C.peek() != '$') 3366ede3744SAlex Lorenz return None; 337970c12eaSAlex Lorenz return lexName(C, Token, MIToken::ExternalSymbol, /*PrefixLength=*/1, 338970c12eaSAlex Lorenz ErrorCallback); 3396ede3744SAlex Lorenz } 3406ede3744SAlex Lorenz 341ad156fb6SAlex Lorenz static bool isValidHexFloatingPointPrefix(char C) { 342ad156fb6SAlex Lorenz return C == 'H' || C == 'K' || C == 'L' || C == 'M'; 343ad156fb6SAlex Lorenz } 344ad156fb6SAlex Lorenz 345ad156fb6SAlex Lorenz static Cursor maybeLexHexFloatingPointLiteral(Cursor C, MIToken &Token) { 346ad156fb6SAlex Lorenz if (C.peek() != '0' || C.peek(1) != 'x') 347ad156fb6SAlex Lorenz return None; 348ad156fb6SAlex Lorenz Cursor Range = C; 349ad156fb6SAlex Lorenz C.advance(2); // Skip '0x' 350ad156fb6SAlex Lorenz if (isValidHexFloatingPointPrefix(C.peek())) 351ad156fb6SAlex Lorenz C.advance(); 352ad156fb6SAlex Lorenz while (isxdigit(C.peek())) 353ad156fb6SAlex Lorenz C.advance(); 354ad156fb6SAlex Lorenz Token = MIToken(MIToken::FloatingPointLiteral, Range.upto(C)); 355ad156fb6SAlex Lorenz return C; 356ad156fb6SAlex Lorenz } 357ad156fb6SAlex Lorenz 358ad156fb6SAlex Lorenz static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token) { 359ad156fb6SAlex Lorenz C.advance(); 360ad156fb6SAlex Lorenz // Skip over [0-9]*([eE][-+]?[0-9]+)? 361ad156fb6SAlex Lorenz while (isdigit(C.peek())) 362ad156fb6SAlex Lorenz C.advance(); 363ad156fb6SAlex Lorenz if ((C.peek() == 'e' || C.peek() == 'E') && 364ad156fb6SAlex Lorenz (isdigit(C.peek(1)) || 365ad156fb6SAlex Lorenz ((C.peek(1) == '-' || C.peek(1) == '+') && isdigit(C.peek(2))))) { 366ad156fb6SAlex Lorenz C.advance(2); 367ad156fb6SAlex Lorenz while (isdigit(C.peek())) 368ad156fb6SAlex Lorenz C.advance(); 369ad156fb6SAlex Lorenz } 370ad156fb6SAlex Lorenz Token = MIToken(MIToken::FloatingPointLiteral, Range.upto(C)); 371ad156fb6SAlex Lorenz return C; 372ad156fb6SAlex Lorenz } 373ad156fb6SAlex Lorenz 374ad156fb6SAlex Lorenz static Cursor maybeLexNumericalLiteral(Cursor C, MIToken &Token) { 3756c6c46e4SAlex Lorenz if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1)))) 3766c6c46e4SAlex Lorenz return None; 377240fc1e0SAlex Lorenz auto Range = C; 378240fc1e0SAlex Lorenz C.advance(); 379240fc1e0SAlex Lorenz while (isdigit(C.peek())) 380240fc1e0SAlex Lorenz C.advance(); 381ad156fb6SAlex Lorenz if (C.peek() == '.') 382ad156fb6SAlex Lorenz return lexFloatingPointLiteral(Range, C, Token); 383240fc1e0SAlex Lorenz StringRef StrVal = Range.upto(C); 384240fc1e0SAlex Lorenz Token = MIToken(MIToken::IntegerLiteral, StrVal, APSInt(StrVal)); 385240fc1e0SAlex Lorenz return C; 386240fc1e0SAlex Lorenz } 387240fc1e0SAlex Lorenz 388f3db51deSAlex Lorenz static MIToken::TokenKind symbolToken(char C) { 389f3db51deSAlex Lorenz switch (C) { 390f3db51deSAlex Lorenz case ',': 391f3db51deSAlex Lorenz return MIToken::comma; 392f3db51deSAlex Lorenz case '=': 393f3db51deSAlex Lorenz return MIToken::equal; 3942eacca86SAlex Lorenz case ':': 3952eacca86SAlex Lorenz return MIToken::colon; 39635e44469SAlex Lorenz case '!': 39735e44469SAlex Lorenz return MIToken::exclaim; 398deb53490SAlex Lorenz case '(': 399deb53490SAlex Lorenz return MIToken::lparen; 400deb53490SAlex Lorenz case ')': 401deb53490SAlex Lorenz return MIToken::rparen; 402f3db51deSAlex Lorenz default: 403f3db51deSAlex Lorenz return MIToken::Error; 404f3db51deSAlex Lorenz } 405f3db51deSAlex Lorenz } 406f3db51deSAlex Lorenz 4076c6c46e4SAlex Lorenz static Cursor maybeLexSymbol(Cursor C, MIToken &Token) { 4084af7e610SAlex Lorenz MIToken::TokenKind Kind; 4094af7e610SAlex Lorenz unsigned Length = 1; 4104af7e610SAlex Lorenz if (C.peek() == ':' && C.peek(1) == ':') { 4114af7e610SAlex Lorenz Kind = MIToken::coloncolon; 4124af7e610SAlex Lorenz Length = 2; 4134af7e610SAlex Lorenz } else 4144af7e610SAlex Lorenz Kind = symbolToken(C.peek()); 4156c6c46e4SAlex Lorenz if (Kind == MIToken::Error) 4166c6c46e4SAlex Lorenz return None; 417f3db51deSAlex Lorenz auto Range = C; 4184af7e610SAlex Lorenz C.advance(Length); 419f3db51deSAlex Lorenz Token = MIToken(Kind, Range.upto(C)); 420f3db51deSAlex Lorenz return C; 421f3db51deSAlex Lorenz } 422f3db51deSAlex Lorenz 42391370c5dSAlex Lorenz StringRef llvm::lexMIToken( 42491370c5dSAlex Lorenz StringRef Source, MIToken &Token, 42591370c5dSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 42691370c5dSAlex Lorenz auto C = skipWhitespace(Cursor(Source)); 42791370c5dSAlex Lorenz if (C.isEOF()) { 42891370c5dSAlex Lorenz Token = MIToken(MIToken::Eof, C.remaining()); 42991370c5dSAlex Lorenz return C.remaining(); 43091370c5dSAlex Lorenz } 43191370c5dSAlex Lorenz 432*05e3882eSAlex Lorenz if (Cursor R = maybeLexIntegerType(C, Token)) 433*05e3882eSAlex Lorenz return R.remaining(); 4346c6c46e4SAlex Lorenz if (Cursor R = maybeLexIdentifier(C, Token)) 4356c6c46e4SAlex Lorenz return R.remaining(); 4366c6c46e4SAlex Lorenz if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback)) 4376c6c46e4SAlex Lorenz return R.remaining(); 43831d70683SAlex Lorenz if (Cursor R = maybeLexJumpTableIndex(C, Token)) 43931d70683SAlex Lorenz return R.remaining(); 4407feaf7c6SAlex Lorenz if (Cursor R = maybeLexStackObject(C, Token)) 4417feaf7c6SAlex Lorenz return R.remaining(); 4427feaf7c6SAlex Lorenz if (Cursor R = maybeLexFixedStackObject(C, Token)) 4437feaf7c6SAlex Lorenz return R.remaining(); 444ab980499SAlex Lorenz if (Cursor R = maybeLexConstantPoolItem(C, Token)) 445ab980499SAlex Lorenz return R.remaining(); 446deb53490SAlex Lorenz if (Cursor R = maybeLexIRBlock(C, Token, ErrorCallback)) 4478a1915b0SAlex Lorenz return R.remaining(); 4484af7e610SAlex Lorenz if (Cursor R = maybeLexIRValue(C, Token, ErrorCallback)) 4494af7e610SAlex Lorenz return R.remaining(); 4506c6c46e4SAlex Lorenz if (Cursor R = maybeLexRegister(C, Token)) 4516c6c46e4SAlex Lorenz return R.remaining(); 452b29554daSAlex Lorenz if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback)) 4536c6c46e4SAlex Lorenz return R.remaining(); 4546ede3744SAlex Lorenz if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback)) 4556ede3744SAlex Lorenz return R.remaining(); 456ad156fb6SAlex Lorenz if (Cursor R = maybeLexHexFloatingPointLiteral(C, Token)) 457ad156fb6SAlex Lorenz return R.remaining(); 458ad156fb6SAlex Lorenz if (Cursor R = maybeLexNumericalLiteral(C, Token)) 4596c6c46e4SAlex Lorenz return R.remaining(); 4606c6c46e4SAlex Lorenz if (Cursor R = maybeLexSymbol(C, Token)) 4616c6c46e4SAlex Lorenz return R.remaining(); 4626c6c46e4SAlex Lorenz 46391370c5dSAlex Lorenz Token = MIToken(MIToken::Error, C.remaining()); 46491370c5dSAlex Lorenz ErrorCallback(C.location(), 4656c6c46e4SAlex Lorenz Twine("unexpected character '") + Twine(C.peek()) + "'"); 46691370c5dSAlex Lorenz return C.remaining(); 46791370c5dSAlex Lorenz } 468