//===- LLLexer.cpp - Lexer for .ll Files ----------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implement the Lexer for .ll files.
//
//===----------------------------------------------------------------------===//
#include "LLLexer.h"
#include "ParserInternals.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MathExtras.h"
#include <list>
#include "llvmAsmParser.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// Helper functions.
//===----------------------------------------------------------------------===//
// atoull - Convert an ascii string of decimal digits into the unsigned long
// long representation... this does not have to do input error checking,
// because we know that the input will be matched by a suitable regex...
//
static uint64_t 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) { // Uh, oh, overflow detected!!!
GenerateError("constant bigger than 64 bits detected!");
return 0;
}
}
return Result;
}
static uint64_t HexIntToVal(const char *Buffer, const char *End) {
uint64_t Result = 0;
for (; Buffer != End; ++Buffer) {
uint64_t OldRes = Result;
Result *= 16;
char C = *Buffer;
if (C >= '0' && C <= '9')
Result += C-'0';
else if (C >= 'A' && C <= 'F')
Result += C-'A'+10;
else if (C >= 'a' && C <= 'f')
Result += C-'a'+10;
if (Result < OldRes) { // Uh, oh, overflow detected!!!
GenerateError("constant bigger than 64 bits detected!");
return 0;
}
}
return Result;
}
// HexToFP - Convert the ascii string in hexadecimal format to the floating
// point representation of it.
//
static double HexToFP(const char *Buffer, const char *End) {
return BitsToDouble(HexIntToVal(Buffer, End)); // Cast Hex constant to double
}
static void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]){
Pair[0] = 0;
for (int i=0; i<16; i++, Buffer++) {
assert(Buffer != End);
Pair[0] *= 16;
char C = *Buffer;
if (C >= '0' && C <= '9')
Pair[0] += C-'0';
else if (C >= 'A' && C <= 'F')
Pair[0] += C-'A'+10;
else if (C >= 'a' && C <= 'f')
Pair[0] += C-'a'+10;
}
Pair[1] = 0;
for (int i=0; i<16 && Buffer != End; i++, Buffer++) {
Pair[1] *= 16;
char C = *Buffer;
if (C >= '0' && C <= '9')
Pair[1] += C-'0';
else if (C >= 'A' && C <= 'F')
Pair[1] += C-'A'+10;
else if (C >= 'a' && C <= 'f')
Pair[1] += C-'a'+10;
}
if (Buffer != End)
GenerateError("constant bigger than 128 bits detected!");
}
// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
// appropriate character.
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++ = '\\'; // Two \ becomes one
BIn += 2;
} else if (BIn < EndBuffer-2 && isxdigit(BIn[1]) && isxdigit(BIn[2])) {
char Tmp = BIn[3]; BIn[3] = 0; // Terminate string
*BOut = (char)strtol(BIn+1, 0, 16); // Convert to number
BIn[3] = Tmp;