forked from OSchip/llvm-project
- Remove unused STRING token from lexer & parser
- Changed parser to always use parenthesis on ConstExprs to be consistent - Parser now passes TRUE and FALSE tokens as a special case of the ConstExpr machinery instead of a special case of constant int stuff - Fix the AsmParser to use ValueRef ::= ConstExpr, and remove ResolvedVal ::= ConstExpr this allows constexprs to be used in PHI nodes llvm-svn: 3362
This commit is contained in:
parent
d0ded9899b
commit
7f325cd0bc
|
@ -158,7 +158,6 @@ internal { return INTERNAL; }
|
||||||
uninitialized { return UNINIT; }
|
uninitialized { return UNINIT; }
|
||||||
implementation { return IMPLEMENTATION; }
|
implementation { return IMPLEMENTATION; }
|
||||||
\.\.\. { return DOTDOTDOT; }
|
\.\.\. { return DOTDOTDOT; }
|
||||||
string { return STRING; }
|
|
||||||
null { return NULL_TOK; }
|
null { return NULL_TOK; }
|
||||||
to { return TO; }
|
to { return TO; }
|
||||||
except { return EXCEPT; }
|
except { return EXCEPT; }
|
||||||
|
|
|
@ -63,7 +63,8 @@ static inline void ThrowException(const std::string &message,
|
||||||
//
|
//
|
||||||
struct ValID {
|
struct ValID {
|
||||||
enum {
|
enum {
|
||||||
NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal
|
NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal,
|
||||||
|
ConstantVal,
|
||||||
} Type;
|
} Type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
@ -72,6 +73,7 @@ struct ValID {
|
||||||
int64_t ConstPool64; // Constant pool reference. This is the value
|
int64_t ConstPool64; // Constant pool reference. This is the value
|
||||||
uint64_t UConstPool64;// Unsigned constant pool reference.
|
uint64_t UConstPool64;// Unsigned constant pool reference.
|
||||||
double ConstPoolFP; // Floating point constant pool reference
|
double ConstPoolFP; // Floating point constant pool reference
|
||||||
|
Constant *ConstantValue; // Fully resolved constant for ConstantVal case.
|
||||||
};
|
};
|
||||||
|
|
||||||
static ValID create(int Num) {
|
static ValID create(int Num) {
|
||||||
|
@ -98,6 +100,10 @@ struct ValID {
|
||||||
ValID D; D.Type = ConstNullVal; return D;
|
ValID D; D.Type = ConstNullVal; return D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ValID create(Constant *Val) {
|
||||||
|
ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D;
|
||||||
|
}
|
||||||
|
|
||||||
inline void destroy() const {
|
inline void destroy() const {
|
||||||
if (Type == NameVal)
|
if (Type == NameVal)
|
||||||
free(Name); // Free this strdup'd memory...
|
free(Name); // Free this strdup'd memory...
|
||||||
|
@ -118,6 +124,10 @@ struct ValID {
|
||||||
case ConstNullVal : return "null";
|
case ConstNullVal : return "null";
|
||||||
case ConstUIntVal :
|
case ConstUIntVal :
|
||||||
case ConstSIntVal : return std::string("%") + itostr(ConstPool64);
|
case ConstSIntVal : return std::string("%") + itostr(ConstPool64);
|
||||||
|
case ConstantVal:
|
||||||
|
if (ConstantValue == ConstantBool::True) return "true";
|
||||||
|
if (ConstantValue == ConstantBool::False) return "false";
|
||||||
|
return "<constant expression>";
|
||||||
default:
|
default:
|
||||||
assert(0 && "Unknown value!");
|
assert(0 && "Unknown value!");
|
||||||
abort();
|
abort();
|
||||||
|
@ -134,6 +144,7 @@ struct ValID {
|
||||||
case ConstUIntVal: return UConstPool64 < V.UConstPool64;
|
case ConstUIntVal: return UConstPool64 < V.UConstPool64;
|
||||||
case ConstFPVal: return ConstPoolFP < V.ConstPoolFP;
|
case ConstFPVal: return ConstPoolFP < V.ConstPoolFP;
|
||||||
case ConstNullVal: return false;
|
case ConstNullVal: return false;
|
||||||
|
case ConstantVal: return ConstantValue < V.ConstantValue;
|
||||||
default: assert(0 && "Unknown value type!"); return false;
|
default: assert(0 && "Unknown value type!"); return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,15 +292,11 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
|
||||||
// Check to make sure that "Ty" is an integral type, and that our
|
// Check to make sure that "Ty" is an integral type, and that our
|
||||||
// value will fit into the specified type...
|
// value will fit into the specified type...
|
||||||
case ValID::ConstSIntVal: // Is it a constant pool reference??
|
case ValID::ConstSIntVal: // Is it a constant pool reference??
|
||||||
if (Ty == Type::BoolTy) { // Special handling for boolean data
|
|
||||||
return ConstantBool::get(D.ConstPool64 != 0);
|
|
||||||
} else {
|
|
||||||
if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64))
|
if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64))
|
||||||
ThrowException("Signed integral constant '" +
|
ThrowException("Signed integral constant '" +
|
||||||
itostr(D.ConstPool64) + "' is invalid for type '" +
|
itostr(D.ConstPool64) + "' is invalid for type '" +
|
||||||
Ty->getDescription() + "'!");
|
Ty->getDescription() + "'!");
|
||||||
return ConstantSInt::get(Ty, D.ConstPool64);
|
return ConstantSInt::get(Ty, D.ConstPool64);
|
||||||
}
|
|
||||||
|
|
||||||
case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
|
case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
|
||||||
if (!ConstantUInt::isValueValidForType(Ty, D.UConstPool64)) {
|
if (!ConstantUInt::isValueValidForType(Ty, D.UConstPool64)) {
|
||||||
|
@ -324,6 +320,11 @@ static Value *getValNonImprovising(const Type *Ty, const ValID &D) {
|
||||||
ThrowException("Cannot create a a non pointer null!");
|
ThrowException("Cannot create a a non pointer null!");
|
||||||
return ConstantPointerNull::get(cast<PointerType>(Ty));
|
return ConstantPointerNull::get(cast<PointerType>(Ty));
|
||||||
|
|
||||||
|
case ValID::ConstantVal: // Fully resolved constant?
|
||||||
|
if (D.ConstantValue->getType() != Ty)
|
||||||
|
ThrowException("Constant expression type different from required type!");
|
||||||
|
return D.ConstantValue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "Unhandled case!");
|
assert(0 && "Unhandled case!");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -670,7 +671,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) {
|
||||||
|
|
||||||
|
|
||||||
%token IMPLEMENTATION TRUE FALSE BEGINTOK ENDTOK DECLARE GLOBAL CONSTANT UNINIT
|
%token IMPLEMENTATION TRUE FALSE BEGINTOK ENDTOK DECLARE GLOBAL CONSTANT UNINIT
|
||||||
%token TO EXCEPT DOTDOTDOT STRING NULL_TOK CONST INTERNAL OPAQUE NOT
|
%token TO EXCEPT DOTDOTDOT NULL_TOK CONST INTERNAL OPAQUE NOT
|
||||||
|
|
||||||
// Basic Block Terminating Operators
|
// Basic Block Terminating Operators
|
||||||
%token <TermOpVal> RET BR SWITCH
|
%token <TermOpVal> RET BR SWITCH
|
||||||
|
@ -759,7 +760,7 @@ UpRTypes : OPAQUE {
|
||||||
| PrimType {
|
| PrimType {
|
||||||
$$ = new PATypeHolder($1);
|
$$ = new PATypeHolder($1);
|
||||||
};
|
};
|
||||||
UpRTypes : ValueRef { // Named types are also simple types...
|
UpRTypes : SymbolicValueRef { // Named types are also simple types...
|
||||||
$$ = new PATypeHolder(getTypeVal($1));
|
$$ = new PATypeHolder(getTypeVal($1));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -827,7 +828,10 @@ ArgTypeListI : TypeListI
|
||||||
};
|
};
|
||||||
|
|
||||||
// ConstVal - The various declarations that go into the constant pool. This
|
// ConstVal - The various declarations that go into the constant pool. This
|
||||||
// includes all forward declarations of types, constants, and functions.
|
// production is used ONLY to represent constants that show up AFTER a 'const',
|
||||||
|
// 'constant' or 'global' token at global scope. Constants that can be inlined
|
||||||
|
// into other expressions (such as integers and constexprs) are handled by the
|
||||||
|
// ResolvedVal, ValueRef and ConstValueRef productions.
|
||||||
//
|
//
|
||||||
ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
|
ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
|
||||||
const ArrayType *ATy = dyn_cast<const ArrayType>($1->get());
|
const ArrayType *ATy = dyn_cast<const ArrayType>($1->get());
|
||||||
|
@ -968,8 +972,11 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr
|
||||||
$$ = ConstantPointerRef::get(GV);
|
$$ = ConstantPointerRef::get(GV);
|
||||||
delete $1; // Free the type handle
|
delete $1; // Free the type handle
|
||||||
}
|
}
|
||||||
| ConstExpr {
|
| Types ConstExpr {
|
||||||
$$ = $1;
|
if ($1->get() != $2->getType())
|
||||||
|
ThrowException("Mismatched types for constant expression!");
|
||||||
|
$$ = $2;
|
||||||
|
delete $1;
|
||||||
};
|
};
|
||||||
|
|
||||||
ConstVal : SIntType EINT64VAL { // integral constants
|
ConstVal : SIntType EINT64VAL { // integral constants
|
||||||
|
@ -993,52 +1000,39 @@ ConstVal : SIntType EINT64VAL { // integral constants
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
ConstExpr: Types CAST ConstVal TO Types {
|
ConstExpr: CAST '(' ConstVal TO Types ')' {
|
||||||
$$ = ConstantExpr::getCast($3, $5->get());
|
$$ = ConstantExpr::getCast($3, $5->get());
|
||||||
if ($1->get() != $5->get())
|
|
||||||
ThrowException("Mismatching ConstExpr cast type");
|
|
||||||
delete $1;
|
|
||||||
delete $5;
|
delete $5;
|
||||||
}
|
}
|
||||||
| Types GETELEMENTPTR '(' ConstVal IndexList ')' {
|
| GETELEMENTPTR '(' ConstVal IndexList ')' {
|
||||||
if (!isa<PointerType>($4->getType()))
|
if (!isa<PointerType>($3->getType()))
|
||||||
ThrowException("GetElementPtr requires a pointer operand!");
|
ThrowException("GetElementPtr requires a pointer operand!");
|
||||||
|
|
||||||
const Type *IdxTy =
|
const Type *IdxTy =
|
||||||
GetElementPtrInst::getIndexedType($4->getType(), *$5, true);
|
GetElementPtrInst::getIndexedType($3->getType(), *$4, true);
|
||||||
if (!IdxTy)
|
if (!IdxTy)
|
||||||
ThrowException("Index list invalid for constant getelementptr!");
|
ThrowException("Index list invalid for constant getelementptr!");
|
||||||
if (PointerType::get(IdxTy) != $1->get())
|
|
||||||
ThrowException("Declared type of constant getelementptr is incorrect!");
|
|
||||||
|
|
||||||
vector<Constant*> IdxVec;
|
vector<Constant*> IdxVec;
|
||||||
for (unsigned i = 0, e = $5->size(); i != e; ++i)
|
for (unsigned i = 0, e = $4->size(); i != e; ++i)
|
||||||
if (Constant *C = dyn_cast<Constant>((*$5)[i]))
|
if (Constant *C = dyn_cast<Constant>((*$4)[i]))
|
||||||
IdxVec.push_back(C);
|
IdxVec.push_back(C);
|
||||||
else
|
else
|
||||||
ThrowException("Indices to constant getelementptr must be constants!");
|
ThrowException("Indices to constant getelementptr must be constants!");
|
||||||
|
|
||||||
delete $5;
|
delete $4;
|
||||||
|
|
||||||
$$ = ConstantExpr::getGetElementPtr($4, IdxVec);
|
$$ = ConstantExpr::getGetElementPtr($3, IdxVec);
|
||||||
delete $1;
|
|
||||||
}
|
}
|
||||||
| Types BinaryOps ConstVal ',' ConstVal {
|
| BinaryOps '(' ConstVal ',' ConstVal ')' {
|
||||||
if ($3->getType() != $5->getType())
|
if ($3->getType() != $5->getType())
|
||||||
ThrowException("Binary operator types must match!");
|
ThrowException("Binary operator types must match!");
|
||||||
if ($1->get() != $3->getType())
|
$$ = ConstantExpr::get($1, $3, $5);
|
||||||
ThrowException("Return type of binary constant must match arguments!");
|
|
||||||
$$ = ConstantExpr::get($2, $3, $5);
|
|
||||||
delete $1;
|
|
||||||
}
|
}
|
||||||
| Types ShiftOps ConstVal ',' ConstVal {
|
| ShiftOps '(' ConstVal ',' ConstVal ')' {
|
||||||
if ($1->get() != $3->getType())
|
|
||||||
ThrowException("Return type of shift constant must match argument!");
|
|
||||||
if ($5->getType() != Type::UByteTy)
|
if ($5->getType() != Type::UByteTy)
|
||||||
ThrowException("Shift count for shift constant must be unsigned byte!");
|
ThrowException("Shift count for shift constant must be unsigned byte!");
|
||||||
|
$$ = ConstantExpr::get($1, $3, $5);
|
||||||
$$ = ConstantExpr::get($2, $3, $5);
|
|
||||||
delete $1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1304,15 +1298,17 @@ ConstValueRef : ESINT64VAL { // A reference to a direct constant
|
||||||
$$ = ValID::create($1);
|
$$ = ValID::create($1);
|
||||||
}
|
}
|
||||||
| TRUE {
|
| TRUE {
|
||||||
$$ = ValID::create((int64_t)1);
|
$$ = ValID::create(ConstantBool::True);
|
||||||
}
|
}
|
||||||
| FALSE {
|
| FALSE {
|
||||||
$$ = ValID::create((int64_t)0);
|
$$ = ValID::create(ConstantBool::False);
|
||||||
}
|
}
|
||||||
| NULL_TOK {
|
| NULL_TOK {
|
||||||
$$ = ValID::createNull();
|
$$ = ValID::createNull();
|
||||||
}
|
}
|
||||||
;
|
| ConstExpr {
|
||||||
|
$$ = ValID::create($1);
|
||||||
|
};
|
||||||
|
|
||||||
// SymbolicValueRef - Reference to one of two ways of symbolically refering to
|
// SymbolicValueRef - Reference to one of two ways of symbolically refering to
|
||||||
// another value.
|
// another value.
|
||||||
|
@ -1333,9 +1329,6 @@ ValueRef : SymbolicValueRef | ConstValueRef;
|
||||||
// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
|
// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
|
||||||
ResolvedVal : Types ValueRef {
|
ResolvedVal : Types ValueRef {
|
||||||
$$ = getVal(*$1, $2); delete $1;
|
$$ = getVal(*$1, $2); delete $1;
|
||||||
}
|
|
||||||
| ConstExpr {
|
|
||||||
$$ = $1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
BasicBlockList : BasicBlockList BasicBlock {
|
BasicBlockList : BasicBlockList BasicBlock {
|
||||||
|
|
Loading…
Reference in New Issue