diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 84062e7837b..06b197d4486 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -128,6 +128,7 @@ uninitialized { return UNINIT; } implementation { return IMPLEMENTATION; } \.\.\. { return DOTDOTDOT; } string { return STRING; } +null { return NULL_TOK; } void { llvmAsmlval.PrimType = Type::VoidTy ; return VOID; } bool { llvmAsmlval.PrimType = Type::BoolTy ; return BOOL; } diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h index 31c0b24144d..88986c288ab 100644 --- a/lib/AsmParser/ParserInternals.h +++ b/lib/AsmParser/ParserInternals.h @@ -63,9 +63,11 @@ static inline void ThrowException(const string &message, // 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. @@ -75,35 +77,40 @@ struct ValID { }; 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; @@ -111,11 +118,16 @@ struct ValID { 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(); } } }; diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 33f46fc4caa..a02b7d82955 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -180,7 +180,7 @@ static Value *getVal(const Type *Ty, const ValID &D, 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; @@ -202,7 +202,7 @@ static Value *getVal(const Type *Ty, const ValID &D, 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) @@ -223,16 +223,17 @@ static Value *getVal(const Type *Ty, const ValID &D, 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 { @@ -243,7 +244,7 @@ static Value *getVal(const Type *Ty, const ValID &D, 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!"); @@ -254,16 +255,22 @@ static Value *getVal(const Type *Ty, const ValID &D, 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; @@ -508,6 +515,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { PATypeHolder *TypeVal; PATypeHolder *ArrayTypeTy; PATypeHolder *StructTypeTy; + PATypeHolder *PointerTypeTy; Value *ValueVal; list *MethodArgList; @@ -573,13 +581,14 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { %token FLOAT DOUBLE TYPE LABEL %type ArrayType ArrayTypeI %type StructType StructTypeI +%type PointerType PointerTypeI %token VAR_ID LABELSTR STRINGCONSTANT %type 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 RET BR SWITCH @@ -692,6 +701,10 @@ StructTypeI : '{' TypeListI '}' { // Structure type? $$ = newTH(StructType::get(vector())); } +PointerTypeI : UpRTypes '*' { // Pointer type? + $$ = newTHC(HandleUpRefs(PointerType::get(*$1))); + delete $1; // Delete the type handle + } // Include derived types in the Types production. // @@ -716,16 +729,15 @@ UpRTypes : '\\' EUINT64VAL { // Type UpReference | StructTypeI { // Structure type? $$ = newTHC(*$1); delete $1; } - | UpRTypes '*' { // Pointer type? - $$ = newTH(HandleUpRefs(PointerType::get(*$1))); - delete $1; // Delete the type handle + | PointerTypeI { // Pointer type? + $$ = newTHC(*$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 @@ -1051,6 +1063,10 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant | FALSE { $$ = ValID::create((int64_t)0); } + | NULL_TOK { + $$ = ValID::createNull(); + } + /* | STRINGCONSTANT { // Quoted strings work too... especially for methods $$ = ValID::create_conststr($1); diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp index baa367d52b8..ae206daa370 100644 --- a/lib/Bytecode/Reader/ConstantReader.cpp +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -250,7 +250,7 @@ bool BytecodeParser::parseConstPoolValue(const uchar *&Buf, } case Type::StructTyID: { - const StructType *ST = (const StructType*)Ty; + const StructType *ST = Ty->castStructType(); const StructType::ElementTypes &ET = ST->getElementTypes(); vector Elements; @@ -267,6 +267,17 @@ bool BytecodeParser::parseConstPoolValue(const uchar *&Buf, break; } + case Type::PointerTyID: { + const PointerType *PT = Ty->castPointerType(); + unsigned SubClass; + if (read_vbr(Buf, EndBuf, SubClass)) return failure(true); + if (SubClass != 0) return failure(true); + + + V = ConstPoolPointer::getNullPointer(PT); + break; + } + default: cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to deserialize constant value of type '" diff --git a/lib/Bytecode/Writer/ConstantWriter.cpp b/lib/Bytecode/Writer/ConstantWriter.cpp index 24ceaecf2e2..dde47d52b11 100644 --- a/lib/Bytecode/Writer/ConstantWriter.cpp +++ b/lib/Bytecode/Writer/ConstantWriter.cpp @@ -141,6 +141,11 @@ bool BytecodeWriter::outputConstant(const ConstPoolVal *CPV) { break; } + case Type::PointerTyID: { + output_vbr((unsigned)0, Out); + break; + } + case Type::FloatTyID: { // Floating point types... float Tmp = (float)((const ConstPoolFP*)CPV)->getValue(); output_data(&Tmp, &Tmp+1, Out);