// putting classes with ctor's in unions. :(
//
struct ValID {
- int Type; // 0 = number, 1 = name, 2 = const pool,
- // 3 = unsigned const pool, 4 = const string,
- // 5 = const fp
+ enum {
+ NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstStringVal,
+ ConstFPVal, ConstNullVal
+ } Type;
+
union {
int Num; // If it's a numeric reference
char *Name; // If it's a named reference. Memory must be free'd.
};
static ValID create(int Num) {
- ValID D; D.Type = 0; D.Num = Num; return D;
+ ValID D; D.Type = NumberVal; D.Num = Num; return D;
}
static ValID create(char *Name) {
- ValID D; D.Type = 1; D.Name = Name; return D;
+ ValID D; D.Type = NameVal; D.Name = Name; return D;
}
static ValID create(int64_t Val) {
- ValID D; D.Type = 2; D.ConstPool64 = Val; return D;
+ ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; return D;
}
static ValID create(uint64_t Val) {
- ValID D; D.Type = 3; D.UConstPool64 = Val; return D;
+ ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D;
}
static ValID create_conststr(char *Name) {
- ValID D; D.Type = 4; D.Name = Name; return D;
+ ValID D; D.Type = ConstStringVal; D.Name = Name; return D;
}
static ValID create(double Val) {
- ValID D; D.Type = 5; D.ConstPoolFP = Val; return D;
+ ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D;
+ }
+
+ static ValID createNull() {
+ ValID D; D.Type = ConstNullVal; return D;
}
inline void destroy() const {
- if (Type == 1 || Type == 4) free(Name); // Free this strdup'd memory...
+ if (Type == NameVal || Type == ConstStringVal)
+ free(Name); // Free this strdup'd memory...
}
inline ValID copy() const {
- if (Type != 1 && Type != 4) return *this;
+ if (Type != NameVal && Type != ConstStringVal) return *this;
ValID Result = *this;
Result.Name = strdup(Name);
return Result;
inline string getName() const {
switch (Type) {
- case 0: return string("#") + itostr(Num);
- case 1: return Name;
- case 4: return string("\"") + Name + string("\"");
- case 5: return ftostr(ConstPoolFP);
- default: return string("%") + itostr(ConstPool64);
+ case NumberVal : return string("#") + itostr(Num);
+ case NameVal : return Name;
+ case ConstStringVal: return string("\"") + Name + string("\"");
+ case ConstFPVal : return ftostr(ConstPoolFP);
+ case ConstNullVal : return "null";
+ case ConstUIntVal :
+ case ConstSIntVal : return string("%") + itostr(ConstPool64);
+ default:
+ assert(0 && "Unknown value!");
+ abort();
}
}
};
assert(Ty != Type::TypeTy && "Should use getTypeVal for types!");
switch (D.Type) {
- case 0: { // Is it a numbered definition?
+ case ValID::NumberVal: { // Is it a numbered definition?
unsigned type = Ty->getUniqueID();
unsigned Num = (unsigned)D.Num;
return CurMeth.Values[type][Num];
}
- case 1: { // Is it a named definition?
+ case ValID::NameVal: { // Is it a named definition?
string Name(D.Name);
SymbolTable *SymTab = 0;
if (CurMeth.CurrentMethod)
return N;
}
- case 2: // Is it a constant pool reference??
- case 3: // Is it an unsigned const pool reference?
- case 4: // Is it a string const pool reference?
- case 5:{ // Is it a floating point const pool reference?
+ case ValID::ConstSIntVal: // Is it a constant pool reference??
+ case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
+ case ValID::ConstStringVal: // Is it a string const pool reference?
+ case ValID::ConstFPVal: // Is it a floating point const pool reference?
+ case ValID::ConstNullVal: { // Is it a null value?
ConstPoolVal *CPV = 0;
// Check to make sure that "Ty" is an integral type, and that our
// value will fit into the specified type...
switch (D.Type) {
- case 2:
+ case ValID::ConstSIntVal:
if (Ty == Type::BoolTy) { // Special handling for boolean data
CPV = ConstPoolBool::get(D.ConstPool64 != 0);
} else {
CPV = ConstPoolSInt::get(Ty, D.ConstPool64);
}
break;
- case 3:
+ case ValID::ConstUIntVal:
if (!ConstPoolUInt::isValueValidForType(Ty, D.UConstPool64)) {
if (!ConstPoolSInt::isValueValidForType(Ty, D.ConstPool64)) {
ThrowException("Integral constant pool reference is invalid!");
CPV = ConstPoolUInt::get(Ty, D.UConstPool64);
}
break;
- case 4:
+ case ValID::ConstStringVal:
cerr << "FIXME: TODO: String constants [sbyte] not implemented yet!\n";
abort();
break;
- case 5:
+ case ValID::ConstFPVal:
if (!ConstPoolFP::isValueValidForType(Ty, D.ConstPoolFP))
ThrowException("FP constant invalid for type!!");
- else
- CPV = ConstPoolFP::get(Ty, D.ConstPoolFP);
+ CPV = ConstPoolFP::get(Ty, D.ConstPoolFP);
break;
+ case ValID::ConstNullVal:
+ if (!Ty->isPointerType())
+ ThrowException("Cannot create a a non pointer null!");
+ CPV = ConstPoolPointer::getNullPointer(Ty->castPointerType());
+ break;
+ default:
+ assert(0 && "Unhandled case!");
}
assert(CPV && "How did we escape creating a constant??");
return CPV;
PATypeHolder<Type> *TypeVal;
PATypeHolder<ArrayType> *ArrayTypeTy;
PATypeHolder<StructType> *StructTypeTy;
+ PATypeHolder<PointerType> *PointerTypeTy;
Value *ValueVal;
list<MethodArgument*> *MethodArgList;
%token <PrimType> FLOAT DOUBLE TYPE LABEL
%type <ArrayTypeTy> ArrayType ArrayTypeI
%type <StructTypeTy> StructType StructTypeI
+%type <PointerTypeTy> PointerType PointerTypeI
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
%type <StrVal> OptVAR_ID OptAssign
%token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE GLOBAL CONSTANT UNINIT
-%token TO DOTDOTDOT STRING
+%token TO DOTDOTDOT STRING NULL_TOK
// Basic Block Terminating Operators
%token <TermOpVal> RET BR SWITCH
$$ = newTH(StructType::get(vector<const Type*>()));
}
+PointerTypeI : UpRTypes '*' { // Pointer type?
+ $$ = newTHC<PointerType>(HandleUpRefs(PointerType::get(*$1)));
+ delete $1; // Delete the type handle
+ }
// Include derived types in the Types production.
//
| StructTypeI { // Structure type?
$$ = newTHC<Type>(*$1); delete $1;
}
- | UpRTypes '*' { // Pointer type?
- $$ = newTH(HandleUpRefs(PointerType::get(*$1)));
- delete $1; // Delete the type handle
+ | PointerTypeI { // Pointer type?
+ $$ = newTHC<Type>(*$1); delete $1;
}
// Define some helpful top level types that do not allow UpReferences to escape
//
-ArrayType : ArrayTypeI { TypeDone($$ = $1); }
-StructType : StructTypeI { TypeDone($$ = $1); }
-
+ArrayType : ArrayTypeI { TypeDone($$ = $1); }
+StructType : StructTypeI { TypeDone($$ = $1); }
+PointerType : PointerTypeI { TypeDone($$ = $1); }
// TypeList - Used for struct declarations and as a basis for method type
| FALSE {
$$ = ValID::create((int64_t)0);
}
+ | NULL_TOK {
+ $$ = ValID::createNull();
+ }
+
/*
| STRINGCONSTANT { // Quoted strings work too... especially for methods
$$ = ValID::create_conststr($1);