%{
#include "ParserInternals.h"
#include "llvm/Module.h"
+#include "llvm/Support/MathExtras.h"
#include <list>
#include "llvmAsmParser.h"
#include <cctype>
// point representation of it.
//
static double HexToFP(const char *Buffer) {
- // Behave nicely in the face of C TBAA rules... see:
- // http://www.nullstone.com/htmls/category/aliastyp.htm
- union {
- uint64_t UI;
- double FP;
- } UIntToFP;
- UIntToFP.UI = HexIntToVal(Buffer);
-
- assert(sizeof(double) == sizeof(uint64_t) &&
- "Data sizes incompatible on this target!");
- return UIntToFP.FP; // Cast Hex constant to double
+ return BitsToDouble(HexIntToVal(Buffer)); // Cast Hex constant to double
}
// UnEscapeLexed - Run through the specified buffer and change \xx codes to the
-// appropriate character. If AllowNull is set to false, a \00 value will cause
-// an exception to be thrown.
-//
-// If AllowNull is set to true, the return value of the function points to the
-// last character of the string in memory.
-//
-char *UnEscapeLexed(char *Buffer, bool AllowNull) {
+// appropriate character.
+char *UnEscapeLexed(char *Buffer) {
char *BOut = Buffer;
for (char *BIn = Buffer; *BIn; ) {
if (BIn[0] == '\\' && 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
- if (!AllowNull && !*BOut)
- GenerateError("String literal cannot accept \\00 escape!");
-
- BIn[3] = Tmp; // Restore character
- BIn += 3; // Skip over handled chars
+ char Tmp = BIn[3]; BIn[3] = 0; // Terminate string
+ *BOut = (char)strtol(BIn+1, 0, 16); // Convert to number
+ BIn[3] = Tmp; // Restore character
+ BIn += 3; // Skip over handled chars
++BOut;
} else {
*BOut++ = *BIn++;
}
}
-
return BOut;
}
/* Comments start with a ; and go till end of line */
Comment ;.*
-/* Variable(Value) identifiers start with a % sign */
-VarID %[-a-zA-Z$._][-a-zA-Z$._0-9]*
+/* Local Values and Type identifiers start with a % sign */
+LocalVarName %[-a-zA-Z$._][-a-zA-Z$._0-9]*
+
+/* Global Value identifiers start with an @ sign */
+GlobalVarName @[-a-zA-Z$._][-a-zA-Z$._0-9]*
/* Label identifiers end with a colon */
Label [-a-zA-Z$._0-9]+:
/* Quoted names can contain any character except " and \ */
StringConstant \"[^\"]*\"
+AtStringConstant @\"[^\"]*\"
+PctStringConstant %\"[^\"]*\"
+
+/* LocalVarID/GlobalVarID: match an unnamed local variable slot ID. */
+LocalVarID %[0-9]+
+GlobalVarID @[0-9]+
+/* Integer types are specified with i and a bitwidth */
+IntegerType i[0-9]+
-/* [PN]Integer: match positive and negative literal integer values that
- * are preceeded by a '%' character. These represent unnamed variable slots.
- */
-EPInteger %[0-9]+
-ENInteger %-[0-9]+
-
-IntegerType i[0-9]*
-
-
-/* E[PN]Integer: match positive and negative literal integer values */
+/* E[PN]Integer: match positive and negative literal integer values. */
PInteger [0-9]+
NInteger -[0-9]+
* it to deal with 64 bit numbers.
*/
HexIntConstant [us]0x[0-9A-Fa-f]+
+
%%
{Comment} { /* Ignore comments for now */ }
appending { return APPENDING; }
dllimport { return DLLIMPORT; }
dllexport { return DLLEXPORT; }
+hidden { return HIDDEN; }
+protected { return PROTECTED; }
extern_weak { return EXTERN_WEAK; }
external { return EXTERNAL; }
-implementation { return IMPLEMENTATION; }
+thread_local { return THREAD_LOCAL; }
zeroinitializer { return ZEROINITIALIZER; }
\.\.\. { return DOTDOTDOT; }
undef { return UNDEF; }
target { return TARGET; }
triple { return TRIPLE; }
deplibs { return DEPLIBS; }
-endian { return ENDIAN; }
-pointersize { return POINTERSIZE; }
datalayout { return DATALAYOUT; }
-little { return LITTLE; }
-big { return BIG; }
volatile { return VOLATILE; }
align { return ALIGN; }
section { return SECTION; }
+alias { return ALIAS; }
module { return MODULE; }
asm { return ASM_TOK; }
sideeffect { return SIDEEFFECT; }
cc { return CC_TOK; }
ccc { return CCC_TOK; }
-csretcc { return CSRETCC_TOK; }
fastcc { return FASTCC_TOK; }
coldcc { return COLDCC_TOK; }
x86_stdcallcc { return X86_STDCALLCC_TOK; }
x86_fastcallcc { return X86_FASTCALLCC_TOK; }
+inreg { return INREG; }
+sret { return SRET; }
+nounwind { return NOUNWIND; }
+noreturn { return NORETURN; }
+
void { RET_TY(Type::VoidTy, VOID); }
-bool { RET_TY(Type::Int1Ty, BOOL); }
float { RET_TY(Type::FloatTy, FLOAT); }
double { RET_TY(Type::DoubleTy,DOUBLE);}
label { RET_TY(Type::LabelTy, LABEL); }
urem { RET_TOK(BinaryOpVal, URem, UREM); }
srem { RET_TOK(BinaryOpVal, SRem, SREM); }
frem { RET_TOK(BinaryOpVal, FRem, FREM); }
+shl { RET_TOK(BinaryOpVal, Shl, SHL); }
+lshr { RET_TOK(BinaryOpVal, LShr, LSHR); }
+ashr { RET_TOK(BinaryOpVal, AShr, ASHR); }
and { RET_TOK(BinaryOpVal, And, AND); }
or { RET_TOK(BinaryOpVal, Or , OR ); }
xor { RET_TOK(BinaryOpVal, Xor, XOR); }
icmp { RET_TOK(OtherOpVal, ICmp, ICMP); }
fcmp { RET_TOK(OtherOpVal, FCmp, FCMP); }
+
eq { return EQ; }
ne { return NE; }
slt { return SLT; }
ptrtoint { RET_TOK(CastOpVal, PtrToInt, PTRTOINT); }
bitcast { RET_TOK(CastOpVal, BitCast, BITCAST); }
select { RET_TOK(OtherOpVal, Select, SELECT); }
-shl { RET_TOK(OtherOpVal, Shl, SHL); }
-lshr { RET_TOK(OtherOpVal, LShr, LSHR); }
-ashr { RET_TOK(OtherOpVal, AShr, ASHR); }
va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); }
ret { RET_TOK(TermOpVal, Ret, RET); }
br { RET_TOK(TermOpVal, Br, BR); }
shufflevector { RET_TOK(OtherOpVal, ShuffleVector, SHUFFLEVECTOR); }
-{VarID} {
- UnEscapeLexed(yytext+1);
- llvmAsmlval.StrVal = strdup(yytext+1); // Skip %
- return VAR_ID;
+{LocalVarName} {
+ llvmAsmlval.StrVal = new std::string(yytext+1); // Skip %
+ return LOCALVAR;
+ }
+{GlobalVarName} {
+ llvmAsmlval.StrVal = new std::string(yytext+1); // Skip @
+ return GLOBALVAR;
}
{Label} {
- yytext[strlen(yytext)-1] = 0; // nuke colon
- UnEscapeLexed(yytext);
- llvmAsmlval.StrVal = strdup(yytext);
+ yytext[yyleng-1] = 0; // nuke colon
+ llvmAsmlval.StrVal = new std::string(yytext);
return LABELSTR;
}
{QuoteLabel} {
- yytext[strlen(yytext)-2] = 0; // nuke colon, end quote
- UnEscapeLexed(yytext+1);
- llvmAsmlval.StrVal = strdup(yytext+1);
+ yytext[yyleng-2] = 0; // nuke colon, end quote
+ const char* EndChar = UnEscapeLexed(yytext+1);
+ llvmAsmlval.StrVal =
+ new std::string(yytext+1, EndChar - yytext - 1);
return LABELSTR;
}
-{StringConstant} { // Note that we cannot unescape a string constant here! The
- // string constant might contain a \00 which would not be
- // understood by the string stuff. It is valid to make a
- // [sbyte] c"Hello World\00" constant, for example.
- //
- yytext[strlen(yytext)-1] = 0; // nuke end quote
- llvmAsmlval.StrVal = strdup(yytext+1); // Nuke start quote
+{StringConstant} { yytext[yyleng-1] = 0; // nuke end quote
+ const char* EndChar = UnEscapeLexed(yytext+1);
+ llvmAsmlval.StrVal =
+ new std::string(yytext+1, EndChar - yytext - 1);
return STRINGCONSTANT;
}
-
-
-{PInteger} { llvmAsmlval.UInt64Val = atoull(yytext); return EUINT64VAL; }
+{AtStringConstant} {
+ yytext[yyleng-1] = 0; // nuke end quote
+ const char* EndChar = UnEscapeLexed(yytext+2);
+ llvmAsmlval.StrVal =
+ new std::string(yytext+2, EndChar - yytext - 2);
+ return ATSTRINGCONSTANT;
+ }
+{PctStringConstant} {
+ yytext[yyleng-1] = 0; // nuke end quote
+ const char* EndChar = UnEscapeLexed(yytext+2);
+ llvmAsmlval.StrVal =
+ new std::string(yytext+2, EndChar - yytext - 2);
+ return PCTSTRINGCONSTANT;
+ }
+{PInteger} {
+ uint32_t numBits = ((yyleng * 64) / 19) + 1;
+ APInt Tmp(numBits, yytext, yyleng, 10);
+ uint32_t activeBits = Tmp.getActiveBits();
+ if (activeBits > 0 && activeBits < numBits)
+ Tmp.trunc(activeBits);
+ if (Tmp.getBitWidth() > 64) {
+ llvmAsmlval.APIntVal = new APInt(Tmp);
+ return EUAPINTVAL;
+ } else {
+ llvmAsmlval.UInt64Val = Tmp.getZExtValue();
+ return EUINT64VAL;
+ }
+ }
{NInteger} {
- uint64_t Val = atoull(yytext+1);
- // +1: we have bigger negative range
- if (Val > (uint64_t)INT64_MAX+1)
- GenerateError("Constant too large for signed 64 bits!");
- llvmAsmlval.SInt64Val = -Val;
- return ESINT64VAL;
+ uint32_t numBits = (((yyleng-1) * 64) / 19) + 2;
+ APInt Tmp(numBits, yytext, yyleng, 10);
+ uint32_t minBits = Tmp.getMinSignedBits();
+ if (minBits > 0 && minBits < numBits)
+ Tmp.trunc(minBits);
+ if (Tmp.getBitWidth() > 64) {
+ llvmAsmlval.APIntVal = new APInt(Tmp);
+ return ESAPINTVAL;
+ } else {
+ llvmAsmlval.SInt64Val = Tmp.getSExtValue();
+ return ESINT64VAL;
+ }
}
-{HexIntConstant} {
- llvmAsmlval.UInt64Val = HexIntToVal(yytext+3);
- return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL;
+
+{HexIntConstant} { int len = yyleng - 3;
+ uint32_t bits = len * 4;
+ APInt Tmp(bits, yytext+3, len, 16);
+ uint32_t activeBits = Tmp.getActiveBits();
+ if (activeBits > 0 && activeBits < bits)
+ Tmp.trunc(activeBits);
+ if (Tmp.getBitWidth() > 64) {
+ llvmAsmlval.APIntVal = new APInt(Tmp);
+ return yytext[0] == 's' ? ESAPINTVAL : EUAPINTVAL;
+ } else if (yytext[0] == 's') {
+ llvmAsmlval.SInt64Val = Tmp.getSExtValue();
+ return ESINT64VAL;
+ } else {
+ llvmAsmlval.UInt64Val = Tmp.getZExtValue();
+ return EUINT64VAL;
+ }
}
-{EPInteger} {
+{LocalVarID} {
uint64_t Val = atoull(yytext+1);
if ((unsigned)Val != Val)
GenerateError("Invalid value number (too large)!");
llvmAsmlval.UIntVal = unsigned(Val);
- return UINTVAL;
+ return LOCALVAL_ID;
}
-{ENInteger} {
- uint64_t Val = atoull(yytext+2);
- // +1: we have bigger negative range
- if (Val > (uint64_t)INT32_MAX+1)
- GenerateError("Constant too large for signed 32 bits!");
- llvmAsmlval.SIntVal = (int)-Val;
- return SINTVAL;
+{GlobalVarID} {
+ uint64_t Val = atoull(yytext+1);
+ if ((unsigned)Val != Val)
+ GenerateError("Invalid value number (too large)!");
+ llvmAsmlval.UIntVal = unsigned(Val);
+ return GLOBALVAL_ID;
}
{FPConstant} { llvmAsmlval.FPVal = atof(yytext); return FPVAL; }