#include "LLLexer.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace llvm;
bool LLLexer::Error(LocTy ErrorLoc, const Twine &Msg) const {
ErrorInfo = SM.GetMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
return true;
}
void LLLexer::Warning(LocTy WarningLoc, const Twine &Msg) const {
SM.PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
}
uint64_t LLLexer::atoull(const char *Buffer, const char *End) {
uint64_t Result = 0;
for (; Buffer != End; Buffer++) {
uint64_t OldRes = Result;
Result *= 10;
Result += *Buffer-'0';
if (Result < OldRes) { Error("constant bigger than 64 bits detected!");
return 0;
}
}
return Result;
}
uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) {
uint64_t Result = 0;
for (; Buffer != End; ++Buffer) {
uint64_t OldRes = Result;
Result *= 16;
Result += hexDigitValue(*Buffer);
if (Result < OldRes) { Error("constant bigger than 64 bits detected!");
return 0;
}
}
return Result;
}
void LLLexer::HexToIntPair(const char *Buffer, const char *End,
uint64_t Pair[2]) {
Pair[0] = 0;
if (End - Buffer >= 16) {
for (int i = 0; i < 16; i++, Buffer++) {
assert(Buffer != End);
Pair[0] *= 16;
Pair[0] += hexDigitValue(*Buffer);
}
}
Pair[1] = 0;
for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
Pair[1] *= 16;
Pair[1] += hexDigitValue(*Buffer);
}
if (Buffer != End)
Error("constant bigger than 128 bits detected!");
}
void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End,
uint64_t Pair[2]) {
Pair[1] = 0;
for (int i=0; i<4 && Buffer != End; i++, Buffer++) {
assert(Buffer != End);
Pair[1] *= 16;
Pair[1] += hexDigitValue(*Buffer);
}
Pair[0] = 0;
for (int i = 0; i < 16 && Buffer != End; i++, Buffer++) {
Pair[0] *= 16;
Pair[0] += hexDigitValue(*Buffer);
}
if (Buffer != End)
Error("constant bigger than 128 bits detected!");
}
static void UnEscapeLexed(std::string &Str) {
if (Str.empty()) return;
char *Buffer = &Str[0], *EndBuffer = Buffer+Str.size();
char *BOut = Buffer;
for (char *BIn = Buffer; BIn != EndBuffer; ) {
if (BIn[0] == '\\') {
if (BIn < EndBuffer-1 && BIn[1] == '\\') {
*BOut++ = '\\'; BIn += 2;
} else if (BIn < EndBuffer-2 &&
isxdigit(static_cast<unsigned char>(BIn[1])) &&
isxdigit(static_cast<unsigned char>(BIn[2]))) {
*BOut = hexDigitValue(BIn[1]) * 16 + hexDigitValue(BIn[2]);
BIn += 3; ++BOut;
} else {
*BOut++ = *BIn++;
}
} else {
*BOut++ = *BIn++;
}
}
Str.resize(BOut-Buffer);
}
static bool isLabelChar(char C) {
return isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' ||
C == '.' || C == '_';
}
static const char *isLabelTail(const char *CurPtr) {
while (1) {
if (CurPtr[0] == ':') return CurPtr+1;
if (!isLabelChar(CurPtr[0])) return nullptr;
++CurPtr;
}
}
LLLexer::LLLexer(StringRef StartBuf, SourceMgr &sm, SMDiagnostic &Err,
LLVMContext &C)
: CurBuf(StartBuf), ErrorInfo(Err), SM(sm), Context(C), APFloatVal(0.0) {
CurPtr = CurBuf.begin();
}
int LLLexer::getNextChar() {
char CurChar = *CurPtr++;
switch (CurChar) {
default: return (unsigned char)CurChar;
case 0:
if (CurPtr-1 != CurBuf.end())
return 0;
--CurPtr; return EOF;
}
}
lltok::Kind LLLexer::LexToken() {
TokStart = CurPtr;
int CurChar = getNextChar();
switch (CurChar) {
default:
if (isalpha(static_cast<unsigned char>(CurChar)) || CurChar == '_')
return LexIdentifier();
return lltok::Error;
case EOF: return lltok::Eof;
case 0:
case ' ':
case '\t':
case '\n':
case '\r':
return LexToken();
case '+': return LexPositive();
case '@': return LexAt();
case '$': return LexDollar();
case '%': return LexPercent();
case '"': return LexQuote();
case '.':
if (const char *Ptr = isLabelTail(CurPtr)) {
CurPtr = Ptr;
StrVal.assign(TokStart, CurPtr-1);
return lltok::LabelStr;
}
if (CurPtr[0] == '.' && CurPtr[1] == '.') {
CurPtr += 2;
return lltok::dotdotdot;
}
return lltok::Error;
case ';':
SkipLineComment();
return LexToken();
case '!': return LexExclaim();
case '#': return LexHash();
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '-':
return LexDigitOrNegative();
case '=': return lltok::equal;
case '[': return lltok::lsquare;
case ']': return lltok::rsquare;
case '{': return lltok::lbrace;
case '}': return lltok::rbrace;
case '<': return lltok::less;
case '>': return lltok::greater;
case '(': return lltok::lparen;
case ')': return lltok::rparen;
case ',': return lltok::comma;
case '*': return lltok::star;
case '|': return lltok::bar;
}
}
void LLLexer::SkipLineComment() {
while (1) {
if (CurPtr[0] == '\n' || CurPtr[0] == '\r' || getNextChar() == EOF)
return;
}
}
lltok::Kind LLLexer::LexAt() {
return LexVar(lltok::GlobalVar, lltok::GlobalID);
}
lltok::Kind LLLexer::LexDollar() {
if (const char *Ptr = isLabelTail(TokStart)) {
CurPtr = Ptr;
StrVal.assign(TokStart, CurPtr - 1);
return lltok::LabelStr;
}
if (CurPtr[0] == '"') {
++CurPtr;
while (1) {
int CurChar = getNextChar();
if (CurChar == EOF) {
Error("end of file in COMDAT variable name");
return lltok::Error;
}
if (CurChar == '"') {
StrVal.assign(TokStart + 2, CurPtr - 1);
UnEscapeLexed(StrVal);
if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
Error("Null bytes are not allowed in names");
return lltok::Error;
}
return lltok::ComdatVar;
}
}
}
if (ReadVarName())
return lltok::ComdatVar;
return lltok::Error;
}
lltok::Kind LLLexer::ReadString(lltok::Kind kind) {
const char *Start = CurPtr;
while (1) {
int CurChar = getNextChar();
if (CurChar == EOF) {
Error("end of file in string constant");
return lltok::Error;
}
if (CurChar == '"') {
StrVal.assign(Start, CurPtr-1);
UnEscapeLexed(StrVal);
return kind;
}
}
}
bool LLLexer::ReadVarName() {
const char *NameStart = CurPtr;
if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
CurPtr[0] == '-' || CurPtr[0] == '$' ||
CurPtr[0] == '.' || CurPtr[0] == '_') {
++CurPtr;
while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
CurPtr[0] == '-' || CurPtr[0] == '$' ||
CurPtr[0] == '.' || CurPtr[0] == '_')
++CurPtr;
StrVal.assign(NameStart, CurPtr);
return true;
}
return false;
}
lltok::Kind LLLexer::LexVar(lltok::Kind Var, lltok::Kind VarID) {
if (CurPtr[0] == '"') {
++CurPtr;
while (1) {
int CurChar = getNextChar();
if (CurChar == EOF) {
Error("end of file in global variable name");
return lltok::Error;
}
if (CurChar == '"') {
StrVal.assign(TokStart+2, CurPtr-1);
UnEscapeLexed(StrVal);
if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
Error("Null bytes are not allowed in names");
return lltok::Error;
}
return Var;
}
}
}
if (ReadVarName())
return Var;
if (isdigit(static_cast<unsigned char>(CurPtr[0]))) {
for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
;
uint64_t Val = atoull(TokStart+1, CurPtr);
if ((unsigned)Val != Val)
Error("invalid value number (too large)!");
UIntVal = unsigned(Val);
return VarID;
}
return lltok::Error;
}
lltok::Kind LLLexer::LexPercent() {
return LexVar(lltok::LocalVar, lltok::LocalVarID);
}
lltok::Kind LLLexer::LexQuote() {
lltok::Kind kind = ReadString(lltok::StringConstant);
if (kind == lltok::Error || kind == lltok::Eof)
return kind;
if (CurPtr[0] == ':') {
++CurPtr;
if (StringRef(StrVal).find_first_of(0) != StringRef::npos) {
Error("Null bytes are not allowed in names");
kind = lltok::Error;
} else {
kind = lltok::LabelStr;
}
}
return kind;
}
lltok::Kind LLLexer::LexExclaim() {
if (isalpha(static_cast<unsigned char>(CurPtr[0])) ||
CurPtr[0] == '-' || CurPtr[0] == '$' ||
CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') {
++CurPtr;
while (isalnum(static_cast<unsigned char>(CurPtr[0])) ||
CurPtr[0] == '-' || CurPtr[0] == '$' ||
CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\')
++CurPtr;
StrVal.assign(TokStart+1, CurPtr); UnEscapeLexed(StrVal);
return lltok::MetadataVar;
}
return lltok::exclaim;
}
lltok::Kind LLLexer::LexHash() {
if (isdigit(static_cast<unsigned char>(CurPtr[0]))) {
for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
;
uint64_t Val = atoull(TokStart+1, CurPtr);
if ((unsigned)Val != Val)
Error("invalid value number (too large)!");
UIntVal = unsigned(Val);
return lltok::AttrGrpID;
}
return lltok::Error;
}
lltok::Kind LLLexer::LexIdentifier() {
const char *StartChar = CurPtr;
const char *IntEnd = CurPtr[-1] == 'i' ? nullptr : StartChar;
const char *KeywordEnd = nullptr;
for (; isLabelChar(*CurPtr); ++CurPtr) {
if (!IntEnd && !isdigit(static_cast<unsigned char>(*CurPtr)))
IntEnd = CurPtr;
if (!KeywordEnd && !isalnum(static_cast<unsigned char>(*CurPtr)) &&
*CurPtr != '_')
KeywordEnd = CurPtr;
}
if (*CurPtr == ':') {
StrVal.assign(StartChar-1, CurPtr++);
return lltok::LabelStr;
}
if (!IntEnd) IntEnd = CurPtr;
if (IntEnd != StartChar) {
CurPtr = IntEnd;
uint64_t NumBits = atoull(StartChar, CurPtr);
if (NumBits < IntegerType::MIN_INT_BITS ||
NumBits > IntegerType::MAX_INT_BITS) {
Error("bitwidth for integer type out of range!");
return lltok::Error;
}
TyVal = IntegerType::get(Context, NumBits);
return lltok::Type;
}
if (!KeywordEnd) KeywordEnd = CurPtr;
CurPtr = KeywordEnd;
--StartChar;
StringRef Keyword(StartChar, CurPtr - StartChar);
#define KEYWORD(STR) \
do { \
if (Keyword == #STR) \
return lltok::kw_##STR; \
} while (0)
KEYWORD(true); KEYWORD(false);
KEYWORD(declare); KEYWORD(define);
KEYWORD(global); KEYWORD(constant);
KEYWORD(private);
KEYWORD(internal);
KEYWORD(available_externally);
KEYWORD(linkonce);
KEYWORD(linkonce_odr);
KEYWORD(weak); KEYWORD(weak_odr);
KEYWORD(appending);
KEYWORD(dllimport);
KEYWORD(dllexport);
KEYWORD(common);
KEYWORD(default);
KEYWORD(hidden);
KEYWORD(protected);
KEYWORD(unnamed_addr);
KEYWORD(externally_initialized);
KEYWORD(extern_weak);
KEYWORD(external);
KEYWORD(thread_local);
KEYWORD(localdynamic);
KEYWORD(initialexec);
KEYWORD(localexec);
KEYWORD(zeroinitializer);
KEYWORD(undef);
KEYWORD(null);
KEYWORD(to);
KEYWORD(caller);
KEYWORD(tail);
KEYWORD(musttail);
KEYWORD(notail);
KEYWORD(target);
KEYWORD(triple);
KEYWORD(unwind);
KEYWORD(deplibs); KEYWORD(datalayout);
KEYWORD(volatile);
KEYWORD(atomic);
KEYWORD(unordered);
KEYWORD(monotonic);
KEYWORD(acquire);
KEYWORD(release);
KEYWORD(acq_rel);
KEYWORD(seq_cst);
KEYWORD(singlethread);
KEYWORD(nnan);
KEYWORD(ninf);
KEYWORD(nsz);
KEYWORD(arcp);
KEYWORD(fast);
KEYWORD(nuw);
KEYWORD(nsw);
KEYWORD(exact);
KEYWORD(inbounds);
KEYWORD(align);
KEYWORD(addrspace);
KEYWORD(section);
KEYWORD(alias);
KEYWORD(module);
KEYWORD(asm);
KEYWORD(sideeffect);
KEYWORD(alignstack);
KEYWORD(inteldialect);
KEYWORD(gc);
KEYWORD(prefix);
KEYWORD(prologue);
KEYWORD(ccc);
KEYWORD(fastcc);
KEYWORD(coldcc);
KEYWORD(x86_stdcallcc);
KEYWORD(x86_fastcallcc);
KEYWORD(x86_thiscallcc);
KEYWORD(x86_vectorcallcc);
KEYWORD(arm_apcscc);
KEYWORD(arm_aapcscc);
KEYWORD(arm_aapcs_vfpcc);
KEYWORD(msp430_intrcc);
KEYWORD(ptx_kernel);
KEYWORD(ptx_device);
KEYWORD(spir_kernel);
KEYWORD(spir_func);
KEYWORD(intel_ocl_bicc);
KEYWORD(x86_64_sysvcc);
KEYWORD(x86_64_win64cc);
KEYWORD(webkit_jscc);
KEYWORD(swiftcc);
KEYWORD(anyregcc);
KEYWORD(preserve_mostcc);
KEYWORD(preserve_allcc);
KEYWORD(ghccc);
KEYWORD(hhvmcc);
KEYWORD(hhvm_ccc);
KEYWORD(cc);
KEYWORD(c);
KEYWORD(attributes);
KEYWORD(alwaysinline);
KEYWORD(argmemonly);
KEYWORD(builtin);
KEYWORD(byval);
KEYWORD(inalloca);
KEYWORD(cold);
KEYWORD(convergent);
KEYWORD(dereferenceable);
KEYWORD(dereferenceable_or_null);
KEYWORD(inlinehint);
KEYWORD(inreg);
KEYWORD(jumptable);
KEYWORD(minsize);
KEYWORD(naked);
KEYWORD(nest);
KEYWORD(noalias);
KEYWORD(nobuiltin);
KEYWORD(nocapture);
KEYWORD(noduplicate);
KEYWORD(noimplicitfloat);
KEYWORD(noinline);
KEYWORD(norecurse);
KEYWORD(nonlazybind);
KEYWORD(nonnull);
KEYWORD(noredzone);
KEYWORD(noreturn);
KEYWORD(nounwind);
KEYWORD(optnone);
KEYWORD(optsize);
KEYWORD(readnone);
KEYWORD(readonly);
KEYWORD(returned);
KEYWORD(returns_twice);
KEYWORD(signext);
KEYWORD(sret);
KEYWORD(ssp);
KEYWORD(sspreq);
KEYWORD(sspstrong);
KEYWORD(safestack);
KEYWORD(sanitize_address);
KEYWORD(sanitize_thread);
KEYWORD(sanitize_memory);
KEYWORD(swifterror);
KEYWORD(swiftself);
KEYWORD(uwtable);
KEYWORD(zeroext);
KEYWORD(type);
KEYWORD(opaque);
KEYWORD(comdat);
KEYWORD(any);
KEYWORD(exactmatch);
KEYWORD(largest);
KEYWORD(noduplicates);
KEYWORD(samesize);
KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge);
KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole);
KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une);
KEYWORD(xchg); KEYWORD(nand); KEYWORD(max); KEYWORD(min); KEYWORD(umax);
KEYWORD(umin);
KEYWORD(x);
KEYWORD(blockaddress);
KEYWORD(distinct);
KEYWORD(uselistorder);
KEYWORD(uselistorder_bb);
KEYWORD(personality);
KEYWORD(cleanup);
KEYWORD(catch);
KEYWORD(filter);
#undef KEYWORD
#define TYPEKEYWORD(STR, LLVMTY) \
do { \
if (Keyword == STR) { \
TyVal = LLVMTY; \
return lltok::Type; \
} \
} while (false)
TYPEKEYWORD("void", Type::getVoidTy(Context));
TYPEKEYWORD("half", Type::getHalfTy(Context));
TYPEKEYWORD("float", Type::getFloatTy(Context));
TYPEKEYWORD("double", Type::getDoubleTy(Context));
TYPEKEYWORD("x86_fp80", Type::getX86_FP80Ty(Context));
TYPEKEYWORD("fp128", Type::getFP128Ty(Context));
TYPEKEYWORD("ppc_fp128", Type::getPPC_FP128Ty(Context));
TYPEKEYWORD("label", Type::getLabelTy(Context));
TYPEKEYWORD("metadata", Type::getMetadataTy(Context));
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
TYPEKEYWORD("token", Type::getTokenTy(Context));
#undef TYPEKEYWORD
#define INSTKEYWORD(STR, Enum) \
do { \
if (Keyword == #STR) { \
UIntVal = Instruction::Enum; \
return lltok::kw_##STR; \
} \
} while (false)
INSTKEYWORD(add, Add); INSTKEYWORD(fadd, FAdd);
INSTKEYWORD(sub, Sub); INSTKEYWORD(fsub, FSub);
INSTKEYWORD(mul, Mul); INSTKEYWORD(fmul, FMul);
INSTKEYWORD(udiv, UDiv); INSTKEYWORD(sdiv, SDiv); INSTKEYWORD(fdiv, FDiv);
INSTKEYWORD(urem, URem); INSTKEYWORD(srem, SRem); INSTKEYWORD(frem, FRem);
INSTKEYWORD(shl, Shl); INSTKEYWORD(lshr, LShr); INSTKEYWORD(ashr, AShr);
INSTKEYWORD(and, And); INSTKEYWORD(or, Or); INSTKEYWORD(xor, Xor);
INSTKEYWORD(icmp, ICmp); INSTKEYWORD(fcmp, FCmp);
INSTKEYWORD(phi, PHI);
INSTKEYWORD(call, Call);
INSTKEYWORD(trunc, Trunc);
INSTKEYWORD(zext, ZExt);
INSTKEYWORD(sext, SExt);
INSTKEYWORD(fptrunc, FPTrunc);
INSTKEYWORD(fpext, FPExt);
INSTKEYWORD(uitofp, UIToFP);
INSTKEYWORD(sitofp, SIToFP);
INSTKEYWORD(fptoui, FPToUI);
INSTKEYWORD(fptosi, FPToSI);
INSTKEYWORD(inttoptr, IntToPtr);
INSTKEYWORD(ptrtoint, PtrToInt);
INSTKEYWORD(bitcast, BitCast);
INSTKEYWORD(addrspacecast, AddrSpaceCast);
INSTKEYWORD(select, Select);
INSTKEYWORD(va_arg, VAArg);
INSTKEYWORD(ret, Ret);
INSTKEYWORD(br, Br);
INSTKEYWORD(switch, Switch);
INSTKEYWORD(indirectbr, IndirectBr);
INSTKEYWORD(invoke, Invoke);
INSTKEYWORD(resume, Resume);
INSTKEYWORD(unreachable, Unreachable);
INSTKEYWORD(alloca, Alloca);
INSTKEYWORD(load, Load);
INSTKEYWORD(store, Store);
INSTKEYWORD(cmpxchg, AtomicCmpXchg);
INSTKEYWORD(atomicrmw, AtomicRMW);
INSTKEYWORD(fence, Fence);
INSTKEYWORD(getelementptr, GetElementPtr);
INSTKEYWORD(extractelement, ExtractElement);
INSTKEYWORD(insertelement, InsertElement);
INSTKEYWORD(shufflevector, ShuffleVector);
INSTKEYWORD(extractvalue, ExtractValue);
INSTKEYWORD(insertvalue, InsertValue);
INSTKEYWORD(landingpad, LandingPad);
INSTKEYWORD(cleanupret, CleanupRet);
INSTKEYWORD(catchret, CatchRet);
INSTKEYWORD(catchpad, CatchPad);
INSTKEYWORD(terminatepad, TerminatePad);
INSTKEYWORD(cleanuppad, CleanupPad);
INSTKEYWORD(catchendpad, CatchEndPad);
INSTKEYWORD(cleanupendpad, CleanupEndPad);
#undef INSTKEYWORD
#define DWKEYWORD(TYPE, TOKEN) \
do { \
if (Keyword.startswith("DW_" #TYPE "_")) { \
StrVal.assign(Keyword.begin(), Keyword.end()); \
return lltok::TOKEN; \
} \
} while (false)
DWKEYWORD(TAG, DwarfTag);
DWKEYWORD(ATE, DwarfAttEncoding);
DWKEYWORD(VIRTUALITY, DwarfVirtuality);
DWKEYWORD(LANG, DwarfLang);
DWKEYWORD(OP, DwarfOp);
#undef DWKEYWORD
if (Keyword.startswith("DIFlag")) {
StrVal.assign(Keyword.begin(), Keyword.end());
return lltok::DIFlag;
}
if ((TokStart[0] == 'u' || TokStart[0] == 's') &&
TokStart[1] == '0' && TokStart[2] == 'x' &&
isxdigit(static_cast<unsigned char>(TokStart[3]))) {
int len = CurPtr-TokStart-3;
uint32_t bits = len * 4;
StringRef HexStr(TokStart + 3, len);
if (!std::all_of(HexStr.begin(), HexStr.end(), isxdigit)) {
CurPtr = TokStart+3;
return lltok::Error;
}
APInt Tmp(bits, HexStr, 16);
uint32_t activeBits = Tmp.getActiveBits();
if (activeBits > 0 && activeBits < bits)
Tmp = Tmp.trunc(activeBits);
APSIntVal = APSInt(Tmp, TokStart[0] == 'u');
return lltok::APSInt;
}
if (TokStart[0] == 'c' && TokStart[1] == 'c') {
CurPtr = TokStart+2;
return lltok::kw_cc;
}
CurPtr = TokStart+1;
return lltok::Error;
}
lltok::Kind LLLexer::Lex0x() {
CurPtr = TokStart + 2;
char Kind;
if ((CurPtr[0] >= 'K' && CurPtr[0] <= 'M') || CurPtr[0] == 'H') {
Kind = *CurPtr++;
} else {
Kind = 'J';
}
if (!isxdigit(static_cast<unsigned char>(CurPtr[0]))) {
CurPtr = TokStart+1;
return lltok::Error;
}
while (isxdigit(static_cast<unsigned char>(CurPtr[0])))
++CurPtr;
if (Kind == 'J') {
APFloatVal = APFloat(BitsToDouble(HexIntToVal(TokStart+2, CurPtr)));
return lltok::APFloat;
}
uint64_t Pair[2];
switch (Kind) {
default: llvm_unreachable("Unknown kind!");
case 'K':
FP80HexToIntPair(TokStart+3, CurPtr, Pair);
APFloatVal = APFloat(APFloat::x87DoubleExtended, APInt(80, Pair));
return lltok::APFloat;
case 'L':
HexToIntPair(TokStart+3, CurPtr, Pair);
APFloatVal = APFloat(APFloat::IEEEquad, APInt(128, Pair));
return lltok::APFloat;
case 'M':
HexToIntPair(TokStart+3, CurPtr, Pair);
APFloatVal = APFloat(APFloat::PPCDoubleDouble, APInt(128, Pair));
return lltok::APFloat;
case 'H':
APFloatVal = APFloat(APFloat::IEEEhalf,
APInt(16,HexIntToVal(TokStart+3, CurPtr)));
return lltok::APFloat;
}
}
lltok::Kind LLLexer::LexDigitOrNegative() {
if (!isdigit(static_cast<unsigned char>(TokStart[0])) &&
!isdigit(static_cast<unsigned char>(CurPtr[0]))) {
if (const char *End = isLabelTail(CurPtr)) {
StrVal.assign(TokStart, End-1);
CurPtr = End;
return lltok::LabelStr;
}
return lltok::Error;
}
for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
;
if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') {
if (const char *End = isLabelTail(CurPtr)) {
StrVal.assign(TokStart, End-1);
CurPtr = End;
return lltok::LabelStr;
}
}
if (CurPtr[0] != '.') {
if (TokStart[0] == '0' && TokStart[1] == 'x')
return Lex0x();
APSIntVal = APSInt(StringRef(TokStart, CurPtr - TokStart));
return lltok::APSInt;
}
++CurPtr;
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
((CurPtr[1] == '-' || CurPtr[1] == '+') &&
isdigit(static_cast<unsigned char>(CurPtr[2])))) {
CurPtr += 2;
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
}
}
APFloatVal = APFloat(std::atof(TokStart));
return lltok::APFloat;
}
lltok::Kind LLLexer::LexPositive() {
if (!isdigit(static_cast<unsigned char>(CurPtr[0])))
return lltok::Error;
for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr)
;
if (CurPtr[0] != '.') {
CurPtr = TokStart+1;
return lltok::Error;
}
++CurPtr;
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
if (CurPtr[0] == 'e' || CurPtr[0] == 'E') {
if (isdigit(static_cast<unsigned char>(CurPtr[1])) ||
((CurPtr[1] == '-' || CurPtr[1] == '+') &&
isdigit(static_cast<unsigned char>(CurPtr[2])))) {
CurPtr += 2;
while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr;
}
}
APFloatVal = APFloat(std::atof(TokStart));
return lltok::APFloat;
}