diff options
author | Chris Lattner <sabre@nondot.org> | 2001-10-03 01:49:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-10-03 01:49:25 +0000 |
commit | df7306f1b93953ce99a8e4dadf74ac8f1d5686dc (patch) | |
tree | 2e7bc9376583d8ebf9611c15b0fd48e77fb13dd8 /lib | |
parent | fe5e584cd9df2e1c4c593137d0b5ab696e2d7e36 (diff) | |
download | external_llvm-df7306f1b93953ce99a8e4dadf74ac8f1d5686dc.zip external_llvm-df7306f1b93953ce99a8e4dadf74ac8f1d5686dc.tar.gz external_llvm-df7306f1b93953ce99a8e4dadf74ac8f1d5686dc.tar.bz2 |
* Add support for null as a constant
* Allow multiple definitions of a type with the same name as long as they are the same type
* Eagerly resolve types to allow #2 to work instead of after the whole const pool has been processed
* Change grammar to require a const before a local constant definition
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@699 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/Lexer.l | 1 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 86 |
2 files changed, 59 insertions, 28 deletions
diff --git a/lib/AsmParser/Lexer.l b/lib/AsmParser/Lexer.l index 06b197d..642496d 100644 --- a/lib/AsmParser/Lexer.l +++ b/lib/AsmParser/Lexer.l @@ -124,6 +124,7 @@ false { return FALSE; } declare { return DECLARE; } global { return GLOBAL; } constant { return CONSTANT; } +const { return CONST; } uninitialized { return UNINIT; } implementation { return IMPLEMENTATION; } \.\.\. { return DOTDOTDOT; } diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index a0c9673..698fd7b 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -351,6 +351,22 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers) { LateResolvers.clear(); } +// ResolveType - Take a specified unresolved type and resolve it. If there is +// nothing to resolve it to yet, return true. Otherwise resolve it and return +// false. +// +static bool ResolveType(PATypeHolder<Type> &T) { + const Type *Ty = T; + ValID &DID = getValIDFromPlaceHolder(Ty); + + const Type *TheRealType = getTypeVal(DID, true); + if (TheRealType == 0) return true; + + // Refine the opaque type we had to the new type we are getting. + cast<DerivedType>(Ty)->refineAbstractTypeTo(TheRealType); + return false; +} + // ResolveTypes - This goes through the forward referenced type table and makes // sure that all type references are complete. This code is executed after the @@ -358,12 +374,11 @@ static void ResolveDefinitions(vector<ValueList> &LateResolvers) { // static void ResolveTypes(vector<PATypeHolder<Type> > &LateResolveTypes) { while (!LateResolveTypes.empty()) { - const Type *Ty = LateResolveTypes.back(); - ValID &DID = getValIDFromPlaceHolder(Ty); + if (ResolveType(LateResolveTypes.back())) { + const Type *Ty = LateResolveTypes.back(); + ValID &DID = getValIDFromPlaceHolder(Ty); - const Type *TheRealType = getTypeVal(DID, true); - if (TheRealType == 0) { - if (DID.Type == 1) + if (DID.Type == ValID::NameVal) ThrowException("Reference to an invalid type: '" +DID.getName(), getLineNumFromPlaceHolder(Ty)); else @@ -371,14 +386,27 @@ static void ResolveTypes(vector<PATypeHolder<Type> > &LateResolveTypes) { getLineNumFromPlaceHolder(Ty)); } - // Refine the opaque type we had to the new type we are getting. - cast<DerivedType>(Ty)->refineAbstractTypeTo(TheRealType); - // No need to delete type, refine does that for us. LateResolveTypes.pop_back(); } } + +// ResolveSomeTypes - This goes through the forward referenced type table and +// completes references that are now done. This is so that types are +// immediately resolved to be as concrete as possible. This does not cause +// thrown exceptions if not everything is resolved. +// +static void ResolveSomeTypes(vector<PATypeHolder<Type> > &LateResolveTypes) { + for (unsigned i = 0; i < LateResolveTypes.size(); ) { + if (ResolveType(LateResolveTypes[i])) + ++i; // Type didn't resolve + else + LateResolveTypes.erase(LateResolveTypes.begin()+i); // Type resolved! + } +} + + // setValueName - Set the specified value to the name given. The name may be // null potentially, in which case this is a noop. The string passed in is // assumed to be a malloc'd string buffer, and is freed by this function. @@ -396,19 +424,22 @@ static void setValueName(Value *V, char *NameStr) { if (Existing) { // Inserting a name that is already defined??? // There is only one case where this is allowed: when we are refining an // opaque type. In this case, Existing will be an opaque type. - if (const Type *Ty = cast<const Type>(Existing)) + if (const Type *Ty = dyn_cast<const Type>(Existing)) { if (OpaqueType *OpTy = dyn_cast<OpaqueType>(Ty)) { // We ARE replacing an opaque type! OpTy->refineAbstractTypeTo(cast<Type>(V)); return; } + } // Otherwise, we are a simple redefinition of a value, check to see if it // is defined the same as the old one... if (const Type *Ty = dyn_cast<const Type>(Existing)) { if (Ty == cast<const Type>(V)) return; // Yes, it's equal. + cerr << "Type: " << Ty->getDescription() << " != " + << cast<const Type>(V)->getDescription() << "!\n"; } else { - + } ThrowException("Redefinition of value name '" + Name + "' in the '" + V->getType()->getDescription() + "' type plane!"); @@ -548,7 +579,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { %type <BasicBlockVal> BasicBlock InstructionList %type <TermInstVal> BBTerminatorInst %type <InstVal> Inst InstVal MemoryInst -%type <ConstVal> ConstVal ExtendedConstVal +%type <ConstVal> ConstVal %type <ConstVector> ConstVector UByteList %type <MethodArgList> ArgList ArgListH %type <MethArgVal> ArgVal @@ -589,7 +620,7 @@ Module *RunVMAsmParser(const string &Filename, FILE *F) { %token IMPLEMENTATION TRUE FALSE BEGINTOK END DECLARE GLOBAL CONSTANT UNINIT -%token TO DOTDOTDOT STRING NULL_TOK +%token TO DOTDOTDOT STRING NULL_TOK CONST // Basic Block Terminating Operators %token <TermOpVal> RET BR SWITCH @@ -768,9 +799,7 @@ ArgTypeListI : TypeListI // ConstVal - The various declarations that go into the constant pool. This // includes all forward declarations of types, constants, and functions. // -// This is broken into two sections: ExtendedConstVal and ConstVal -// -ExtendedConstVal: ArrayType '[' ConstVector ']' { // Nonempty unsized arr +ConstVal: ArrayType '[' ConstVector ']' { // Nonempty unsized arr const ArrayType *ATy = *$1; const Type *ETy = ATy->getElementType(); int NumElements = ATy->getNumElements(); @@ -830,6 +859,10 @@ ExtendedConstVal: ArrayType '[' ConstVector ']' { // Nonempty unsized arr $$ = ConstPoolStruct::get(*$1, *$3); delete $1; delete $3; } + | PointerType NULL_TOK { + $$ = ConstPoolPointer::getNullPointer(*$1); + delete $1; + } /* | Types '*' ConstVal { assert(0); @@ -837,10 +870,7 @@ ExtendedConstVal: ArrayType '[' ConstVector ']' { // Nonempty unsized arr } */ -ConstVal : ExtendedConstVal { - $$ = $1; - } - | SIntType EINT64VAL { // integral constants +ConstVal : SIntType EINT64VAL { // integral constants if (!ConstPoolSInt::isValueValidForType($1, $2)) ThrowException("Constant value doesn't fit in type!"); $$ = ConstPoolSInt::get($1, $2); @@ -875,9 +905,9 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; } // ConstPool - Constants with optional names assigned to them. -ConstPool : ConstPool OptAssign ConstVal { - setValueName($3, $2); - InsertValue($3); +ConstPool : ConstPool OptAssign CONST ConstVal { + setValueName($4, $2); + InsertValue($4); } | ConstPool OptAssign TYPE TypesV { // Types can be defined in the const pool // TODO: FIXME when Type are not const @@ -888,13 +918,16 @@ ConstPool : ConstPool OptAssign ConstVal { CurMeth.CurrentMethod ? CurMeth.Types : CurModule.Types); } delete $4; + + ResolveSomeTypes(CurMeth.CurrentMethod ? CurMeth.LateResolveTypes : + CurModule.LateResolveTypes); } | ConstPool MethodProto { // Method prototypes can be in const pool } - | ConstPool OptAssign GlobalType ResolvedVal { + | ConstPool OptAssign GlobalType ConstVal { const Type *Ty = $4->getType(); // Global declarations appear in Constant Pool - ConstPoolVal *Initializer = cast<ConstPoolVal>($4); + ConstPoolVal *Initializer = $4; if (Initializer == 0) ThrowException("Global value initializer is not a constant!"); @@ -1088,10 +1121,7 @@ ValueRef : INTVAL { // Is it an integer reference...? // ResolvedVal - a <type> <value> pair. This is used only in cases where the // type immediately preceeds the value reference, and allows complex constant // pool references (for things like: 'ret [2 x int] [ int 12, int 42]') -ResolvedVal : ExtendedConstVal { - $$ = $1; - } - | Types ValueRef { +ResolvedVal : Types ValueRef { $$ = getVal(*$1, $2); delete $1; } |