diff options
author | Chris Lattner <sabre@nondot.org> | 2001-10-03 15:39:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2001-10-03 15:39:04 +0000 |
commit | b747451c9c973c5d6cd2c50a6cae52d246d4fe20 (patch) | |
tree | a3043ed9a534cd5a978cd8e876dd783818eb0689 /lib | |
parent | 7323c69a31912b352e7eab26bbd98a422b262f95 (diff) | |
download | external_llvm-b747451c9c973c5d6cd2c50a6cae52d246d4fe20.zip external_llvm-b747451c9c973c5d6cd2c50a6cae52d246d4fe20.tar.gz external_llvm-b747451c9c973c5d6cd2c50a6cae52d246d4fe20.tar.bz2 |
Allow duplicate constant values as long as they are compatible.
Clean up stuff a little bit with inMethod/ModuleContext functions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@707 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 6808f5f..f2ae016 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -102,6 +102,9 @@ static struct PerMethodInfo { } } CurMeth; // Info for the current method... +static bool inMethodScope() { return CurMeth.CurrentMethod != 0; } +static bool inModuleScope() { return CurMeth.CurrentMethod == 0; } + //===----------------------------------------------------------------------===// // Code to handle definitions of all the types @@ -140,8 +143,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { case 1: { // Is it a named definition? string Name(D.Name); SymbolTable *SymTab = 0; - if (CurMeth.CurrentMethod) - SymTab = CurMeth.CurrentMethod->getSymbolTable(); + if (inMethodScope()) SymTab = CurMeth.CurrentMethod->getSymbolTable(); Value *N = SymTab ? SymTab->lookup(Type::TypeTy, Name) : 0; if (N == 0) { @@ -167,7 +169,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { // if (DoNotImprovise) return 0; // Do we just want a null to be returned? - vector<PATypeHolder<Type> > *LateResolver = CurMeth.CurrentMethod ? + vector<PATypeHolder<Type> > *LateResolver = inMethodScope() ? &CurMeth.LateResolveTypes : &CurModule.LateResolveTypes; Type *Typ = new TypePlaceHolder(Type::TypeTy, D); @@ -177,7 +179,7 @@ static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { static Value *lookupInSymbolTable(const Type *Ty, const string &Name) { SymbolTable *SymTab = - CurMeth.CurrentMethod ? CurMeth.CurrentMethod->getSymbolTable() : 0; + inMethodScope() ? CurMeth.CurrentMethod->getSymbolTable() : 0; Value *N = SymTab ? SymTab->lookup(Ty, Name) : 0; if (N == 0) { @@ -272,7 +274,7 @@ static Value *getVal(const Type *Ty, const ValID &D, case ValID::ConstNullVal: if (!Ty->isPointerType()) ThrowException("Cannot create a a non pointer null!"); - CPV = ConstPoolPointer::getNullPointer(cast<PointerType>(Ty)); + CPV = ConstPoolPointer::getNull(cast<PointerType>(Ty)); break; default: assert(0 && "Unhandled case!"); @@ -292,7 +294,7 @@ static Value *getVal(const Type *Ty, const ValID &D, if (DoNotImprovise) return 0; // Do we just want a null to be returned? Value *d = 0; - vector<ValueList> *LateResolver = (CurMeth.CurrentMethod) ? + vector<ValueList> *LateResolver = inMethodScope() ? &CurMeth.LateResolveValues : &CurModule.LateResolveValues; if (isa<MethodType>(Ty)) @@ -423,12 +425,16 @@ static void ResolveSomeTypes(vector<PATypeHolder<Type> > &LateResolveTypes) { // 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. // -static void setValueName(Value *V, char *NameStr) { - if (NameStr == 0) return; +// This function returns true if the value has already been defined, but is +// allowed to be redefined in the specified context. If the name is a new name +// for the typeplane, false is returned. +// +static bool setValueName(Value *V, char *NameStr) { + if (NameStr == 0) return false; string Name(NameStr); // Copy string free(NameStr); // Free old string - SymbolTable *ST = CurMeth.CurrentMethod ? + SymbolTable *ST = inMethodScope() ? CurMeth.CurrentMethod->getSymbolTableSure() : CurModule.CurrentModule->getSymbolTableSure(); @@ -440,17 +446,35 @@ static void setValueName(Value *V, char *NameStr) { if (OpaqueType *OpTy = dyn_cast<OpaqueType>(Ty)) { // We ARE replacing an opaque type! OpTy->refineAbstractTypeTo(cast<Type>(V)); - return; + return true; } } // 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 { + if (Ty == cast<const Type>(V)) return true; // Yes, it's equal. + // cerr << "Type: " << Ty->getDescription() << " != " + // << cast<const Type>(V)->getDescription() << "!\n"; + } else if (GlobalVariable *EGV = dyn_cast<GlobalVariable>(Existing)) { + GlobalVariable *GV = cast<GlobalVariable>(V); + + // We are allowed to redefine a global variable in two circumstances: + // 1. If at least one of the globals is uninitialized or + // 2. If both initializers have the same value. + // + // This can only be done if the const'ness of the vars is the same. + // + if (EGV->isConstant() == GV->isConstant() && + (!EGV->hasInitializer() || !GV->hasInitializer() || + EGV->getInitializer() == GV->getInitializer())) { + + // Make sure the existing global version gets the initializer! + if (GV->hasInitializer() && !EGV->hasInitializer()) + EGV->setInitializer(GV->getInitializer()); + + return true; // They are equivalent! + } } ThrowException("Redefinition of value name '" + Name + "' in the '" + @@ -458,6 +482,7 @@ static void setValueName(Value *V, char *NameStr) { } V->setName(Name, ST); + return false; } @@ -858,7 +883,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr ThrowException("Cannot make null pointer constant with type: '" + (*$1)->getDescription() + "'!"); - $$ = ConstPoolPointer::getNullPointer(PTy); + $$ = ConstPoolPointer::getNull(PTy); delete $1; } | Types VAR_ID { @@ -920,21 +945,22 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; } // ConstPool - Constants with optional names assigned to them. ConstPool : ConstPool OptAssign CONST ConstVal { - setValueName($4, $2); + if (setValueName($4, $2)) { assert(0 && "No redefinitions allowed!"); } InsertValue($4); } | ConstPool OptAssign TYPE TypesV { // Types can be defined in the const pool // TODO: FIXME when Type are not const - setValueName(const_cast<Type*>($4->get()), $2); + if (!setValueName(const_cast<Type*>($4->get()), $2)) { + // If this is not a redefinition of a type... + if (!$2) { + InsertType($4->get(), + inMethodScope() ? CurMeth.Types : CurModule.Types); + } + delete $4; - if (!$2) { - InsertType($4->get(), - CurMeth.CurrentMethod ? CurMeth.Types : CurModule.Types); + ResolveSomeTypes(inMethodScope() ? CurMeth.LateResolveTypes : + CurModule.LateResolveTypes); } - delete $4; - - ResolveSomeTypes(CurMeth.CurrentMethod ? CurMeth.LateResolveTypes : - CurModule.LateResolveTypes); } | ConstPool MethodProto { // Method prototypes can be in const pool } @@ -946,10 +972,10 @@ ConstPool : ConstPool OptAssign CONST ConstVal { ThrowException("Global value initializer is not a constant!"); GlobalVariable *GV = new GlobalVariable(Ty, $3, Initializer); - setValueName(GV, $2); - - CurModule.CurrentModule->getGlobalList().push_back(GV); - InsertValue(GV, CurModule.Values); + if (!setValueName(GV, $2)) { // If not redefining... + CurModule.CurrentModule->getGlobalList().push_back(GV); + InsertValue(GV, CurModule.Values); + } } | ConstPool OptAssign UNINIT GlobalType Types { const Type *Ty = *$5; @@ -960,10 +986,10 @@ ConstPool : ConstPool OptAssign CONST ConstVal { } GlobalVariable *GV = new GlobalVariable(Ty, $4); - setValueName(GV, $2); - - CurModule.CurrentModule->getGlobalList().push_back(GV); - InsertValue(GV, CurModule.Values); + if (!setValueName(GV, $2)) { // If not redefining... + CurModule.CurrentModule->getGlobalList().push_back(GV); + InsertValue(GV, CurModule.Values); + } } | /* empty: end of list */ { } @@ -1007,7 +1033,7 @@ OptVAR_ID : VAR_ID | /*empty*/ { $$ = 0; } ArgVal : Types OptVAR_ID { $$ = new MethodArgument(*$1); delete $1; - setValueName($$, $2); + if (setValueName($$, $2)) { assert(0 && "No arg redef allowed!"); } } ArgListH : ArgVal ',' ArgListH { @@ -1160,7 +1186,7 @@ BasicBlock : InstructionList BBTerminatorInst { } | LABELSTR InstructionList BBTerminatorInst { $2->getInstList().push_back($3); - setValueName($2, $1); + if (setValueName($2, $1)) { assert(0 && "No label redef allowed!"); } InsertValue($2); $$ = $2; @@ -1218,8 +1244,8 @@ JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef { } Inst : OptAssign InstVal { - setValueName($2, $1); // Is this definition named?? if so, assign the name... - + // Is this definition named?? if so, assign the name... + if (setValueName($2, $1)) { assert(0 && "No redefin allowed!"); } InsertValue($2); $$ = $2; } |