Implement constant pointers, and null specifically in the parser, bytecode writer...
authorChris Lattner <sabre@nondot.org>
Sun, 30 Sep 2001 22:46:54 +0000 (22:46 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 30 Sep 2001 22:46:54 +0000 (22:46 +0000)
bytecode reader.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@668 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AsmParser/Lexer.l
lib/AsmParser/ParserInternals.h
lib/AsmParser/llvmAsmParser.y
lib/Bytecode/Reader/ConstantReader.cpp
lib/Bytecode/Writer/ConstantWriter.cpp

index 84062e7837ba74fe0f11f8d459f8139d5a583224..06b197d448622f14c7f5e2b65b4e6655ed27c28b 100644 (file)
@@ -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;   }
index 31c0b24144d482618656887a7beeb727abf851a1..88986c288ab8aed2631193a68d639bcfecf9d481 100644 (file)
@@ -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();
     }
   }
 };
index 33f46fc4caa8ff14e68f84a091a17014e4603aca..a02b7d829551c7e270cfa84556b82c74383ff1bd 100644 (file)
@@ -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<Type>               *TypeVal;
   PATypeHolder<ArrayType>          *ArrayTypeTy;
   PATypeHolder<StructType>         *StructTypeTy;
+  PATypeHolder<PointerType>        *PointerTypeTy;
   Value                            *ValueVal;
 
   list<MethodArgument*>            *MethodArgList;
@@ -573,13 +581,14 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
 %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
@@ -692,6 +701,10 @@ StructTypeI : '{' TypeListI '}' {              // Structure type?
     $$ = 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.
 //
@@ -716,16 +729,15 @@ UpRTypes : '\\' EUINT64VAL {                   // Type UpReference
   | 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 
@@ -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);
index baa367d52b85ebbe7e7a3495704827949b4a4e6a..ae206daa3707428ab4a78efcb3f06f66292b6431 100644 (file)
@@ -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<ConstPoolVal *> 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 '"
index 24ceaecf2e23d0eacf234599dd241c41d800a351..dde47d52b116ea919c490bb9f01ff738f1c0a6c4 100644 (file)
@@ -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);