%{
#include "ParserInternals.h"
#include "llvm/Module.h"
+#include "llvm/Support/MathExtras.h"
#include <list>
#include "llvmAsmParser.h"
#include <cctype>
return Result;
}
-
-// HexToFP - Convert the ascii string in hexidecimal format to the floating
+// HexToFP - Convert the ascii string in hexadecimal format to the floating
// 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
}
+static void HexToIntPair(const char *Buffer, uint64_t Pair[2]) {
+ Pair[0] = 0;
+ for (int i=0; i<16; i++, Buffer++) {
+ assert(*Buffer);
+ 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; 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)
+ GenerateError("constant bigger than 128 bits detected!");
+}
// 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* EndBuffer) {
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
- ++BOut;
+ 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; // Restore character
+ BIn += 3; // Skip over handled chars
+ ++BOut;
+ } else {
+ *BOut++ = *BIn++;
+ }
} else {
*BOut++ = *BIn++;
}
}
-
return BOut;
}
/* Quoted names can contain any character except " and \ */
StringConstant \"[^\"]*\"
AtStringConstant @\"[^\"]*\"
+PctStringConstant %\"[^\"]*\"
/* LocalVarID/GlobalVarID: match an unnamed local variable slot ID. */
LocalVarID %[0-9]+
PInteger [0-9]+
NInteger -[0-9]+
-/* FPConstant - A Floating point constant.
+/* FPConstant - A Floating point constant. Float and double only.
*/
FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
/* HexFPConstant - Floating point constant represented in IEEE format as a
* hexadecimal number for when exponential notation is not precise enough.
+ * Float and double only.
*/
HexFPConstant 0x[0-9A-Fa-f]+
+/* F80HexFPConstant - x87 long double in hexadecimal format (10 bytes)
+ */
+HexFP80Constant 0xK[0-9A-Fa-f]+
+
+/* F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes)
+ */
+HexFP128Constant 0xL[0-9A-Fa-f]+
+
+/* PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes)
+ */
+HexPPC128Constant 0xM[0-9A-Fa-f]+
+
/* HexIntConstant - Hexadecimal constant generated by the CFE to avoid forcing
* it to deal with 64 bit numbers.
*/
HexIntConstant [us]0x[0-9A-Fa-f]+
+/* WSNL - shorthand for whitespace followed by newline */
+WSNL [ \r\t]*$
%%
{Comment} { /* Ignore comments for now */ }
dllimport { return DLLIMPORT; }
dllexport { return DLLEXPORT; }
hidden { return HIDDEN; }
+protected { return PROTECTED; }
extern_weak { return EXTERN_WEAK; }
external { return EXTERNAL; }
-checkpoint { return CHECKPOINT; }
+thread_local { return THREAD_LOCAL; }
zeroinitializer { return ZEROINITIALIZER; }
\.\.\. { return DOTDOTDOT; }
undef { return UNDEF; }
volatile { return VOLATILE; }
align { return ALIGN; }
section { return SECTION; }
+alias { return ALIAS; }
module { return MODULE; }
asm { return ASM_TOK; }
sideeffect { return SIDEEFFECT; }
x86_stdcallcc { return X86_STDCALLCC_TOK; }
x86_fastcallcc { return X86_FASTCALLCC_TOK; }
+signext { return SIGNEXT; }
+zeroext { return ZEROEXT; }
inreg { return INREG; }
sret { return SRET; }
nounwind { return NOUNWIND; }
noreturn { return NORETURN; }
+noalias { return NOALIAS; }
+byval { return BYVAL; }
+nest { return NEST; }
+sext{WSNL} { // For auto-upgrade only, drop in LLVM 3.0
+ return SIGNEXT; }
+zext{WSNL} { // For auto-upgrade only, drop in LLVM 3.0
+ return ZEROEXT; }
void { RET_TY(Type::VoidTy, VOID); }
float { RET_TY(Type::FloatTy, FLOAT); }
double { RET_TY(Type::DoubleTy,DOUBLE);}
+x86_fp80 { RET_TY(Type::X86_FP80Ty, X86_FP80);}
+fp128 { RET_TY(Type::FP128Ty, FP128);}
+ppc_fp128 { RET_TY(Type::PPC_FP128Ty, PPC_FP128);}
label { RET_TY(Type::LabelTy, LABEL); }
type { return TYPE; }
opaque { return OPAQUE; }
{LocalVarName} {
- UnEscapeLexed(yytext+1);
- llvmAsmlval.StrVal = strdup(yytext+1); // Skip %
+ llvmAsmlval.StrVal = new std::string(yytext+1); // Skip %
return LOCALVAR;
}
{GlobalVarName} {
- UnEscapeLexed(yytext+1);
- llvmAsmlval.StrVal = strdup(yytext+1); // Skip @
+ 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, yytext+yyleng);
+ 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, yytext+yyleng);
+ llvmAsmlval.StrVal =
+ new std::string(yytext+1, EndChar - yytext - 1);
return STRINGCONSTANT;
}
{AtStringConstant} {
- yytext[strlen(yytext)-1] = 0; // nuke end quote
- llvmAsmlval.StrVal = strdup(yytext+2); // Nuke @, quote
+ yytext[yyleng-1] = 0; // nuke end quote
+ const char* EndChar =
+ UnEscapeLexed(yytext+2, yytext+yyleng);
+ llvmAsmlval.StrVal =
+ new std::string(yytext+2, EndChar - yytext - 2);
return ATSTRINGCONSTANT;
}
-
-{PInteger} { int len = strlen(yytext);
- uint32_t numBits = ((len * 64) / 19) + 1;
- APInt Tmp(numBits, yytext, len, 10);
+{PctStringConstant} {
+ yytext[yyleng-1] = 0; // nuke end quote
+ const char* EndChar =
+ UnEscapeLexed(yytext+2, yytext+yyleng);
+ 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);
return EUINT64VAL;
}
}
-{NInteger} { int len = strlen(yytext);
- uint32_t numBits = (((len-1) * 64) / 19) + 2;
- APInt Tmp(numBits, yytext, len, 10);
+{NInteger} {
+ 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);
}
}
-{HexIntConstant} { int len = strlen(yytext+3) - 3;
+{HexIntConstant} { int len = yyleng - 3;
uint32_t bits = len * 4;
APInt Tmp(bits, yytext+3, len, 16);
uint32_t activeBits = Tmp.getActiveBits();
return GLOBALVAL_ID;
}
-{FPConstant} { llvmAsmlval.FPVal = atof(yytext); return FPVAL; }
-{HexFPConstant} { llvmAsmlval.FPVal = HexToFP(yytext); return FPVAL; }
+{FPConstant} { llvmAsmlval.FPVal = new APFloat(atof(yytext)); return FPVAL; }
+{HexFPConstant} { llvmAsmlval.FPVal = new APFloat(HexToFP(yytext+2));
+ return FPVAL;
+ }
+{HexFP80Constant} { uint64_t Pair[2];
+ HexToIntPair(yytext+3, Pair);
+ llvmAsmlval.FPVal = new APFloat(APInt(80, 2, Pair));
+ return FPVAL;
+ }
+{HexFP128Constant} { uint64_t Pair[2];
+ HexToIntPair(yytext+3, Pair);
+ llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true);
+ return FPVAL;
+ }
+{HexPPC128Constant} { uint64_t Pair[2];
+ HexToIntPair(yytext+3, Pair);
+ llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair));
+ return FPVAL;
+ }
<<EOF>> {
/* Make sure to free the internal buffers for flex when we are