mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
* Enable the use of escaped literal strings
* Unresolved variable names now have the correct line number for their error messages * Rename Def* to Value* * Check for symbol table collisions before inserting values * Remove the STRING keyword * Enable the use of string literals to initialize constant arrays * Enable the use of extended constants in more locations: eg ret [int] [4, 5] * Allow method prototypes to appear in the constant pool of the program * Support varargs methods better. Enable varargs methods with 0 fixed arguments * Allow the entire method prototype to optionally be specified in a call inst git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0add2d33e4
commit
93750fa4f8
@ -24,6 +24,8 @@
|
|||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "llvmAsmParser.h"
|
#include "llvmAsmParser.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define RET_TOK(type, Enum, sym) \
|
#define RET_TOK(type, Enum, sym) \
|
||||||
llvmAsmlval.type = Instruction::Enum; return sym
|
llvmAsmlval.type = Instruction::Enum; return sym
|
||||||
@ -51,6 +53,34 @@ uint64_t atoull(const char *Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 = false) {
|
||||||
|
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 = strtol(BIn+1, 0, 16); // Convert to number
|
||||||
|
if (!AllowNull && !*BOut)
|
||||||
|
ThrowException("String literal cannot accept \\00 escape!");
|
||||||
|
|
||||||
|
BIn[3] = Tmp; // Restore character
|
||||||
|
BIn += 3; // Skip over handled chars
|
||||||
|
++BOut;
|
||||||
|
} else {
|
||||||
|
*BOut++ = *BIn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define YY_NEVER_INTERACTIVE 1
|
#define YY_NEVER_INTERACTIVE 1
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -95,6 +125,7 @@ false { return FALSE; }
|
|||||||
declare { return DECLARE; }
|
declare { return DECLARE; }
|
||||||
implementation { return IMPLEMENTATION; }
|
implementation { return IMPLEMENTATION; }
|
||||||
\.\.\. { return DOTDOTDOT; }
|
\.\.\. { return DOTDOTDOT; }
|
||||||
|
string { return STRING; }
|
||||||
|
|
||||||
void { llvmAsmlval.TypeVal = Type::VoidTy ; return VOID; }
|
void { llvmAsmlval.TypeVal = Type::VoidTy ; return VOID; }
|
||||||
bool { llvmAsmlval.TypeVal = Type::BoolTy ; return BOOL; }
|
bool { llvmAsmlval.TypeVal = Type::BoolTy ; return BOOL; }
|
||||||
@ -148,18 +179,27 @@ store { RET_TOK(MemOpVal, Store, STORE); }
|
|||||||
getelementptr { RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); }
|
getelementptr { RET_TOK(MemOpVal, GetElementPtr, GETELEMENTPTR); }
|
||||||
|
|
||||||
|
|
||||||
{VarID} { llvmAsmlval.StrVal = strdup(yytext+1); return VAR_ID; }
|
{VarID} {
|
||||||
{Label} {
|
UnEscapeLexed(yytext+1);
|
||||||
|
llvmAsmlval.StrVal = strdup(yytext+1); // Skip %
|
||||||
|
return VAR_ID;
|
||||||
|
}
|
||||||
|
{Label} {
|
||||||
yytext[strlen(yytext)-1] = 0; // nuke colon
|
yytext[strlen(yytext)-1] = 0; // nuke colon
|
||||||
llvmAsmlval.StrVal = strdup(yytext);
|
UnEscapeLexed(yytext);
|
||||||
|
llvmAsmlval.StrVal = strdup(yytext);
|
||||||
return LABELSTR;
|
return LABELSTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
{StringConstant} {
|
{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
|
yytext[strlen(yytext)-1] = 0; // nuke end quote
|
||||||
llvmAsmlval.StrVal = strdup(yytext+1); // Nuke start quote
|
llvmAsmlval.StrVal = strdup(yytext+1); // Nuke start quote
|
||||||
return STRINGCONSTANT;
|
return STRINGCONSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{PInteger} { llvmAsmlval.UInt64Val = atoull(yytext); return EUINT64VAL; }
|
{PInteger} { llvmAsmlval.UInt64Val = atoull(yytext); return EUINT64VAL; }
|
||||||
|
@ -31,15 +31,27 @@ extern string CurFilename;
|
|||||||
Module *RunVMAsmParser(const string &Filename, FILE *F);
|
Module *RunVMAsmParser(const string &Filename, FILE *F);
|
||||||
|
|
||||||
|
|
||||||
|
// 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 = false);
|
||||||
|
|
||||||
|
|
||||||
// ThrowException - Wrapper around the ParseException class that automatically
|
// ThrowException - Wrapper around the ParseException class that automatically
|
||||||
// fills in file line number and column number and options info.
|
// fills in file line number and column number and options info.
|
||||||
//
|
//
|
||||||
// This also helps me because I keep typing 'throw new ParseException' instead
|
// This also helps me because I keep typing 'throw new ParseException' instead
|
||||||
// of just 'throw ParseException'... sigh...
|
// of just 'throw ParseException'... sigh...
|
||||||
//
|
//
|
||||||
static inline void ThrowException(const string &message) {
|
static inline void ThrowException(const string &message,
|
||||||
|
int LineNo = -1) {
|
||||||
|
if (LineNo == -1) LineNo = llvmAsmlineno;
|
||||||
// TODO: column number in exception
|
// TODO: column number in exception
|
||||||
throw ParseException(CurFilename, message, llvmAsmlineno);
|
throw ParseException(CurFilename, message, LineNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValID - Represents a reference of a definition of some sort. This may either
|
// ValID - Represents a reference of a definition of some sort. This may either
|
||||||
@ -111,13 +123,15 @@ struct ValID {
|
|||||||
|
|
||||||
|
|
||||||
template<class SuperType>
|
template<class SuperType>
|
||||||
class PlaceholderDef : public SuperType {
|
class PlaceholderValue : public SuperType {
|
||||||
ValID D;
|
ValID D;
|
||||||
// TODO: Placeholder def should hold Line #/Column # of definition in case
|
int LineNum;
|
||||||
// there is an error resolving the defintition!
|
|
||||||
public:
|
public:
|
||||||
PlaceholderDef(const Type *Ty, const ValID &d) : SuperType(Ty), D(d) {}
|
PlaceholderValue(const Type *Ty, const ValID &d) : SuperType(Ty), D(d) {
|
||||||
|
LineNum = llvmAsmlineno;
|
||||||
|
}
|
||||||
ValID &getDef() { return D; }
|
ValID &getDef() { return D; }
|
||||||
|
int getLineNum() const { return LineNum; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InstPlaceHolderHelper : public Instruction {
|
struct InstPlaceHolderHelper : public Instruction {
|
||||||
@ -140,17 +154,23 @@ struct MethPlaceHolderHelper : public Method {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef PlaceholderDef<InstPlaceHolderHelper> DefPlaceHolder;
|
typedef PlaceholderValue<InstPlaceHolderHelper> ValuePlaceHolder;
|
||||||
typedef PlaceholderDef<BBPlaceHolderHelper> BBPlaceHolder;
|
typedef PlaceholderValue<BBPlaceHolderHelper> BBPlaceHolder;
|
||||||
typedef PlaceholderDef<MethPlaceHolderHelper> MethPlaceHolder;
|
typedef PlaceholderValue<MethPlaceHolderHelper> MethPlaceHolder;
|
||||||
//typedef PlaceholderDef<ModulePlaceHolderHelper> ModulePlaceHolder;
|
|
||||||
|
|
||||||
static inline ValID &getValIDFromPlaceHolder(Value *Def) {
|
static inline ValID &getValIDFromPlaceHolder(Value *Val) {
|
||||||
switch (Def->getType()->getPrimitiveID()) {
|
switch (Val->getType()->getPrimitiveID()) {
|
||||||
case Type::LabelTyID: return ((BBPlaceHolder*)Def)->getDef();
|
case Type::LabelTyID: return ((BBPlaceHolder*)Val)->getDef();
|
||||||
case Type::MethodTyID: return ((MethPlaceHolder*)Def)->getDef();
|
case Type::MethodTyID: return ((MethPlaceHolder*)Val)->getDef();
|
||||||
//case Type::ModuleTyID: return ((ModulePlaceHolder*)Def)->getDef();
|
default: return ((ValuePlaceHolder*)Val)->getDef();
|
||||||
default: return ((DefPlaceHolder*)Def)->getDef();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int getLineNumFromPlaceHolder(Value *Val) {
|
||||||
|
switch (Val->getType()->getPrimitiveID()) {
|
||||||
|
case Type::LabelTyID: return ((BBPlaceHolder*)Val)->getLineNum();
|
||||||
|
case Type::MethodTyID: return ((MethPlaceHolder*)Val)->getLineNum();
|
||||||
|
default: return ((ValuePlaceHolder*)Val)->getLineNum();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ static struct PerMethodInfo {
|
|||||||
// Code to handle definitions of all the types
|
// Code to handle definitions of all the types
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void InsertValue(Value *D, vector<ValueList> &ValueTab = CurMeth.Values) {
|
static void InsertValue(Value *D, vector<ValueList> &ValueTab = CurMeth.Values){
|
||||||
if (!D->hasName()) { // Is this a numbered definition?
|
if (!D->hasName()) { // Is this a numbered definition?
|
||||||
unsigned type = D->getType()->getUniqueID();
|
unsigned type = D->getType()->getUniqueID();
|
||||||
if (ValueTab.size() <= type)
|
if (ValueTab.size() <= type)
|
||||||
@ -176,8 +176,6 @@ static Value *getVal(const Type *Type, const ValID &D,
|
|||||||
case 4:
|
case 4:
|
||||||
cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
|
cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
|
||||||
abort();
|
abort();
|
||||||
//CPV = new ConstPoolString(D.Name);
|
|
||||||
D.destroy(); // Free the string memory
|
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (!ConstPoolFP::isValueValidForType(Type, D.ConstPoolFP))
|
if (!ConstPoolFP::isValueValidForType(Type, D.ConstPoolFP))
|
||||||
@ -215,18 +213,17 @@ static Value *getVal(const Type *Type, const ValID &D,
|
|||||||
|
|
||||||
// TODO: Attempt to coallecse nodes that are the same with previous ones.
|
// TODO: Attempt to coallecse nodes that are the same with previous ones.
|
||||||
Value *d = 0;
|
Value *d = 0;
|
||||||
|
vector<ValueList> *LateResolver = &CurMeth.LateResolveValues;
|
||||||
|
|
||||||
switch (Type->getPrimitiveID()) {
|
switch (Type->getPrimitiveID()) {
|
||||||
case Type::LabelTyID: d = new BBPlaceHolder(Type, D); break;
|
case Type::LabelTyID: d = new BBPlaceHolder(Type, D); break;
|
||||||
case Type::MethodTyID:
|
case Type::MethodTyID: d = new MethPlaceHolder(Type, D);
|
||||||
d = new MethPlaceHolder(Type, D);
|
LateResolver = &CurModule.LateResolveValues; break;
|
||||||
InsertValue(d, CurModule.LateResolveValues);
|
default: d = new ValuePlaceHolder(Type, D); break;
|
||||||
return d;
|
|
||||||
//case Type::ClassTyID: d = new ClassPlaceHolder(Type, D); break;
|
|
||||||
default: d = new DefPlaceHolder(Type, D); break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(d != 0 && "How did we not make something?");
|
assert(d != 0 && "How did we not make something?");
|
||||||
InsertValue(d, CurMeth.LateResolveValues);
|
InsertValue(d, *LateResolver);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,10 +256,12 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers) {
|
|||||||
|
|
||||||
if (TheRealValue == 0 && DID.Type == 1)
|
if (TheRealValue == 0 && DID.Type == 1)
|
||||||
ThrowException("Reference to an invalid definition: '" +DID.getName() +
|
ThrowException("Reference to an invalid definition: '" +DID.getName() +
|
||||||
"' of type '" + V->getType()->getName() + "'");
|
"' of type '" + V->getType()->getName() + "'",
|
||||||
|
getLineNumFromPlaceHolder(V));
|
||||||
else if (TheRealValue == 0)
|
else if (TheRealValue == 0)
|
||||||
ThrowException("Reference to an invalid definition: #" +itostr(DID.Num)+
|
ThrowException("Reference to an invalid definition: #" +itostr(DID.Num)+
|
||||||
" of type '" + V->getType()->getName() + "'");
|
" of type '" + V->getType()->getName() + "'",
|
||||||
|
getLineNumFromPlaceHolder(V));
|
||||||
|
|
||||||
V->replaceAllUsesWith(TheRealValue);
|
V->replaceAllUsesWith(TheRealValue);
|
||||||
assert(V->use_empty());
|
assert(V->use_empty());
|
||||||
@ -305,25 +304,33 @@ static ConstPoolVal *addConstValToConstantPool(ConstPoolVal *C) {
|
|||||||
CPV->setName(C->getName());
|
CPV->setName(C->getName());
|
||||||
delete C; // Sorry, you're toast
|
delete C; // Sorry, you're toast
|
||||||
return CPV;
|
return CPV;
|
||||||
} else if (CPV->hasName() && C->hasName()) {
|
|
||||||
// Both values have distinct names. We cannot merge them.
|
|
||||||
CP.insert(C);
|
|
||||||
InsertValue(C, ValTab);
|
|
||||||
return C;
|
|
||||||
} else if (!CPV->hasName() && !C->hasName()) {
|
} else if (!CPV->hasName() && !C->hasName()) {
|
||||||
// Neither value has a name, trivially merge them.
|
// Neither value has a name, trivially merge them.
|
||||||
InsertValue(CPV, ValTab);
|
InsertValue(CPV, ValTab);
|
||||||
delete C;
|
delete C;
|
||||||
return CPV;
|
return CPV;
|
||||||
|
} else if (CPV->hasName() && C->hasName()) {
|
||||||
|
// Both values have distinct names. We cannot merge them.
|
||||||
|
// fall through
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(0 && "Not reached!");
|
// No duplication of value, check to see if our current symbol table already
|
||||||
return 0;
|
// has a variable of this type and name...
|
||||||
} else { // No duplication of value.
|
//
|
||||||
CP.insert(C);
|
if (C->hasName()) {
|
||||||
InsertValue(C, ValTab);
|
SymbolTable *SymTab = CurMeth.CurrentMethod ?
|
||||||
return C;
|
CurMeth.CurrentMethod->getSymbolTable() :
|
||||||
}
|
CurModule.CurrentModule->getSymbolTable();
|
||||||
|
if (SymTab && SymTab->lookup(C->getType(), C->getName()))
|
||||||
|
ThrowException("<" + C->getType()->getName() + ">:" + C->getName() +
|
||||||
|
" already defined in translation unit!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything is happy: Insert into constant pool now!
|
||||||
|
CP.insert(C);
|
||||||
|
InsertValue(C, ValTab);
|
||||||
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -450,13 +457,13 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
|||||||
// Built in types...
|
// Built in types...
|
||||||
%type <TypeVal> Types TypesV SIntType UIntType IntType FPType
|
%type <TypeVal> Types TypesV SIntType UIntType IntType FPType
|
||||||
%token <TypeVal> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
%token <TypeVal> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
||||||
%token <TypeVal> FLOAT DOUBLE STRING TYPE LABEL
|
%token <TypeVal> FLOAT DOUBLE TYPE LABEL
|
||||||
|
|
||||||
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
|
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
|
||||||
%type <StrVal> OptVAR_ID OptAssign
|
%type <StrVal> OptVAR_ID OptAssign
|
||||||
|
|
||||||
|
|
||||||
%token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE TO DOTDOTDOT
|
%token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE TO DOTDOTDOT STRING
|
||||||
|
|
||||||
// Basic Block Terminating Operators
|
// Basic Block Terminating Operators
|
||||||
%token <TermOpVal> RET BR SWITCH
|
%token <TermOpVal> RET BR SWITCH
|
||||||
@ -504,7 +511,7 @@ EINT64VAL : EUINT64VAL {
|
|||||||
// User defined types are added later...
|
// User defined types are added later...
|
||||||
//
|
//
|
||||||
Types : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT
|
Types : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT
|
||||||
Types : LONG | ULONG | FLOAT | DOUBLE | STRING | TYPE | LABEL
|
Types : LONG | ULONG | FLOAT | DOUBLE | TYPE | LABEL
|
||||||
|
|
||||||
// TypesV includes all of 'Types', but it also includes the void type.
|
// TypesV includes all of 'Types', but it also includes the void type.
|
||||||
TypesV : Types | VOID
|
TypesV : Types | VOID
|
||||||
@ -554,6 +561,22 @@ ExtendedConstVal: '[' Types ']' '[' ConstVector ']' { // Nonempty unsized array
|
|||||||
vector<ConstPoolVal*> Empty;
|
vector<ConstPoolVal*> Empty;
|
||||||
$$ = new ConstPoolArray(ArrayType::getArrayType($2), Empty);
|
$$ = new ConstPoolArray(ArrayType::getArrayType($2), Empty);
|
||||||
}
|
}
|
||||||
|
| '[' Types ']' 'c' STRINGCONSTANT {
|
||||||
|
char *EndStr = UnEscapeLexed($5, true);
|
||||||
|
vector<ConstPoolVal*> Vals;
|
||||||
|
if ($2 == Type::SByteTy) {
|
||||||
|
for (char *C = $5; C != EndStr; ++C)
|
||||||
|
Vals.push_back(addConstValToConstantPool(new ConstPoolSInt($2, *C)));
|
||||||
|
} else if ($2 == Type::UByteTy) {
|
||||||
|
for (char *C = $5; C != EndStr; ++C)
|
||||||
|
Vals.push_back(addConstValToConstantPool(new ConstPoolUInt($2, *C)));
|
||||||
|
} else {
|
||||||
|
ThrowException("Cannot build string arrays of non byte sized elements!");
|
||||||
|
}
|
||||||
|
free($5);
|
||||||
|
|
||||||
|
$$ = new ConstPoolArray(ArrayType::getArrayType($2), Vals);
|
||||||
|
}
|
||||||
| '[' EUINT64VAL 'x' Types ']' '[' ConstVector ']' {
|
| '[' EUINT64VAL 'x' Types ']' '[' ConstVector ']' {
|
||||||
// Verify all elements are correct type!
|
// Verify all elements are correct type!
|
||||||
const ArrayType *AT = ArrayType::getArrayType($4, (int)$2);
|
const ArrayType *AT = ArrayType::getArrayType($4, (int)$2);
|
||||||
@ -579,6 +602,26 @@ ExtendedConstVal: '[' Types ']' '[' ConstVector ']' { // Nonempty unsized array
|
|||||||
vector<ConstPoolVal*> Empty;
|
vector<ConstPoolVal*> Empty;
|
||||||
$$ = new ConstPoolArray(ArrayType::getArrayType($4, 0), Empty);
|
$$ = new ConstPoolArray(ArrayType::getArrayType($4, 0), Empty);
|
||||||
}
|
}
|
||||||
|
| '[' EUINT64VAL 'x' Types ']' 'c' STRINGCONSTANT {
|
||||||
|
char *EndStr = UnEscapeLexed($7, true);
|
||||||
|
if ($2 != (unsigned)(EndStr-$7))
|
||||||
|
ThrowException("Can't build string constant of size " +
|
||||||
|
itostr((int)(EndStr-$7)) +
|
||||||
|
" when array has size " + itostr((int)$2) + "!");
|
||||||
|
vector<ConstPoolVal*> Vals;
|
||||||
|
if ($4 == Type::SByteTy) {
|
||||||
|
for (char *C = $7; C != EndStr; ++C)
|
||||||
|
Vals.push_back(addConstValToConstantPool(new ConstPoolSInt($4, *C)));
|
||||||
|
} else if ($4 == Type::UByteTy) {
|
||||||
|
for (char *C = $7; C != EndStr; ++C)
|
||||||
|
Vals.push_back(addConstValToConstantPool(new ConstPoolUInt($4, *C)));
|
||||||
|
} else {
|
||||||
|
ThrowException("Cannot build string arrays of non byte sized elements!");
|
||||||
|
}
|
||||||
|
free($7);
|
||||||
|
|
||||||
|
$$ = new ConstPoolArray(ArrayType::getArrayType($4, (int)$2), Vals);
|
||||||
|
}
|
||||||
| '{' TypeList '}' '{' ConstVector '}' {
|
| '{' TypeList '}' '{' ConstVector '}' {
|
||||||
StructType::ElementTypes Types($2->begin(), $2->end());
|
StructType::ElementTypes Types($2->begin(), $2->end());
|
||||||
delete $2;
|
delete $2;
|
||||||
@ -600,8 +643,10 @@ ExtendedConstVal: '[' Types ']' '[' ConstVector ']' { // Nonempty unsized array
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ConstVal : ExtendedConstVal
|
ConstVal : ExtendedConstVal {
|
||||||
| TYPE Types { // Type constants
|
$$ = $1;
|
||||||
|
}
|
||||||
|
| TYPE TypesV { // Type constants
|
||||||
$$ = new ConstPoolType($2);
|
$$ = new ConstPoolType($2);
|
||||||
}
|
}
|
||||||
| SIntType EINT64VAL { // integral constants
|
| SIntType EINT64VAL { // integral constants
|
||||||
@ -623,12 +668,6 @@ ConstVal : ExtendedConstVal
|
|||||||
| FPType FPVAL { // Float & Double constants
|
| FPType FPVAL { // Float & Double constants
|
||||||
$$ = new ConstPoolFP($1, $2);
|
$$ = new ConstPoolFP($1, $2);
|
||||||
}
|
}
|
||||||
| STRING STRINGCONSTANT { // String constants
|
|
||||||
cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
|
|
||||||
abort();
|
|
||||||
//$$ = new ConstPoolString($2);
|
|
||||||
free($2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConstVector - A list of comma seperated constants.
|
// ConstVector - A list of comma seperated constants.
|
||||||
ConstVector : ConstVector ',' ConstVal {
|
ConstVector : ConstVector ',' ConstVal {
|
||||||
@ -653,6 +692,8 @@ ConstPool : ConstPool OptAssign ConstVal {
|
|||||||
|
|
||||||
addConstValToConstantPool($3);
|
addConstValToConstantPool($3);
|
||||||
}
|
}
|
||||||
|
| ConstPool MethodProto { // Method prototypes can be in const pool
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
| ConstPool OptAssign GlobalDecl { // Global declarations appear in CP
|
| ConstPool OptAssign GlobalDecl { // Global declarations appear in CP
|
||||||
if ($2) {
|
if ($2) {
|
||||||
@ -688,9 +729,6 @@ MethodList : MethodList Method {
|
|||||||
}
|
}
|
||||||
| MethodList MethodProto {
|
| MethodList MethodProto {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
if (!$2->getParent())
|
|
||||||
$1->getMethodList().push_back($2);
|
|
||||||
CurMeth.MethodDone();
|
|
||||||
}
|
}
|
||||||
| ConstPool IMPLEMENTATION {
|
| ConstPool IMPLEMENTATION {
|
||||||
$$ = CurModule.CurrentModule;
|
$$ = CurModule.CurrentModule;
|
||||||
@ -732,6 +770,7 @@ ArgList : ArgListH {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MethodHeaderH : TypesV STRINGCONSTANT '(' ArgList ')' {
|
MethodHeaderH : TypesV STRINGCONSTANT '(' ArgList ')' {
|
||||||
|
UnEscapeLexed($2);
|
||||||
MethodType::ParamTypes ParamTypeList;
|
MethodType::ParamTypes ParamTypeList;
|
||||||
if ($4)
|
if ($4)
|
||||||
for (list<MethodArgument*>::iterator I = $4->begin(); I != $4->end(); ++I)
|
for (list<MethodArgument*>::iterator I = $4->begin(); I != $4->end(); ++I)
|
||||||
@ -782,6 +821,9 @@ Method : BasicBlockList END {
|
|||||||
|
|
||||||
MethodProto : DECLARE { CurMeth.isDeclare = true; } MethodHeaderH {
|
MethodProto : DECLARE { CurMeth.isDeclare = true; } MethodHeaderH {
|
||||||
$$ = CurMeth.CurrentMethod;
|
$$ = CurMeth.CurrentMethod;
|
||||||
|
if (!$$->getParent())
|
||||||
|
CurModule.CurrentModule->getMethodList().push_back($$);
|
||||||
|
CurMeth.MethodDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -803,9 +845,11 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant
|
|||||||
| FALSE {
|
| FALSE {
|
||||||
$$ = ValID::create((int64_t)0);
|
$$ = ValID::create((int64_t)0);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
| STRINGCONSTANT { // Quoted strings work too... especially for methods
|
| STRINGCONSTANT { // Quoted strings work too... especially for methods
|
||||||
$$ = ValID::create_conststr($1);
|
$$ = ValID::create_conststr($1);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// ValueRef - A reference to a definition...
|
// ValueRef - A reference to a definition...
|
||||||
ValueRef : INTVAL { // Is it an integer reference...?
|
ValueRef : INTVAL { // Is it an integer reference...?
|
||||||
@ -867,6 +911,9 @@ Types : ValueRef {
|
|||||||
$$ = checkNewType(PointerType::getPointerType($1));
|
$$ = checkNewType(PointerType::getPointerType($1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TypeList - Used for struct declarations and as a basis for method type
|
||||||
|
// declaration type lists
|
||||||
|
//
|
||||||
TypeList : Types {
|
TypeList : Types {
|
||||||
$$ = new list<const Type*>();
|
$$ = new list<const Type*>();
|
||||||
$$->push_back($1);
|
$$->push_back($1);
|
||||||
@ -875,10 +922,14 @@ TypeList : Types {
|
|||||||
($$=$1)->push_back($3);
|
($$=$1)->push_back($3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ArgTypeList - List of types for a method type declaration...
|
||||||
ArgTypeList : TypeList
|
ArgTypeList : TypeList
|
||||||
| TypeList ',' DOTDOTDOT {
|
| TypeList ',' DOTDOTDOT {
|
||||||
($$=$1)->push_back(Type::VoidTy);
|
($$=$1)->push_back(Type::VoidTy);
|
||||||
}
|
}
|
||||||
|
| DOTDOTDOT {
|
||||||
|
($$ = new list<const Type*>())->push_back(Type::VoidTy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BasicBlockList : BasicBlockList BasicBlock {
|
BasicBlockList : BasicBlockList BasicBlock {
|
||||||
@ -1020,7 +1071,7 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
|
|||||||
}
|
}
|
||||||
delete $2; // Free the list...
|
delete $2; // Free the list...
|
||||||
}
|
}
|
||||||
| CALL Types ValueRef '(' ValueRefListE ')' {
|
| CALL TypesV ValueRef '(' ValueRefListE ')' {
|
||||||
const MethodType *Ty;
|
const MethodType *Ty;
|
||||||
|
|
||||||
if (!(Ty = $2->isMethodType())) {
|
if (!(Ty = $2->isMethodType())) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user