diff options
-rw-r--r-- | tools/llvm-upgrade/UpgradeInternals.h (renamed from tools/llvm-upgrade/ParserInternals.h) | 179 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeLexer.l | 4 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeParser.y | 589 |
3 files changed, 534 insertions, 238 deletions
diff --git a/tools/llvm-upgrade/ParserInternals.h b/tools/llvm-upgrade/UpgradeInternals.h index 4add8fb447..5616c511e2 100644 --- a/tools/llvm-upgrade/ParserInternals.h +++ b/tools/llvm-upgrade/UpgradeInternals.h @@ -1,4 +1,4 @@ -//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===// +//===-- UpgradeInternals.h - Internal parser definitionsr -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,13 +12,14 @@ // //===----------------------------------------------------------------------===// -#ifndef PARSER_INTERNALS_H -#define PARSER_INTERNALS_H +#ifndef UPGRADE_INTERNALS_H +#define UPGRADE_INTERNALS_H #include <llvm/ADT/StringExtras.h> #include <string> #include <istream> #include <vector> +#include <set> #include <cassert> // Global variables exported from the lexer... @@ -29,14 +30,12 @@ extern int Upgradelineno; extern std::istream* LexInput; struct TypeInfo; -typedef std::vector<TypeInfo*> TypeList; +typedef std::vector<const TypeInfo*> TypeList; void UpgradeAssembly( const std::string & infile, std::istream& in, std::ostream &out, bool debug, bool addAttrs); -TypeInfo* ResolveType(TypeInfo*& Ty); - // Globals exported by the parser... extern char* Upgradetext; extern int Upgradeleng; @@ -58,7 +57,7 @@ enum Types { /// associates a Value* with a Signedness indication. struct ValueInfo { std::string* val; - TypeInfo* type; + const TypeInfo* type; bool constant; bool isConstant() const { return constant; } inline void destroy(); @@ -72,83 +71,47 @@ struct ValueInfo { /// to "int32" and the "second" field will be set to "isUnsigned". If the /// type is not obsolete then "second" will be set to "isSignless". struct TypeInfo { - TypeInfo() - : newTy(0), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0), - nelems(0) { - } - TypeInfo(const char * newType, Types oldType) - : newTy(0), oldTy(oldType), elemTy(0), resultTy(0), elements(0), nelems(0) { - newTy = new std::string(newType); - } - - TypeInfo(std::string *newType, Types oldType, TypeInfo* eTy = 0, - TypeInfo *rTy = 0) - : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(rTy), elements(0), - nelems(0) { - } - - TypeInfo(std::string *newType, Types oldType, TypeInfo *eTy, uint64_t elems) - : newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(0), elements(0), - nelems(elems) { - } + static const TypeInfo* get(const std::string &newType, Types oldType); + static const TypeInfo* get(const std::string& newType, Types oldType, + const TypeInfo* eTy, const TypeInfo* rTy); - TypeInfo(std::string *newType, Types oldType, TypeList* TL) - : newTy(newType), oldTy(oldType), elemTy(0), resultTy(0), elements(TL), - nelems(0) { - } + static const TypeInfo* get(const std::string& newType, Types oldType, + const TypeInfo *eTy, uint64_t elems); - TypeInfo(std::string *newType, TypeInfo* resTy, TypeList* TL) - : newTy(newType), oldTy(FunctionTy), elemTy(0), resultTy(resTy), - elements(TL), nelems(0) { - } + static const TypeInfo* get(const std::string& newType, Types oldType, + TypeList* TL); - TypeInfo(const TypeInfo& that) - : newTy(0), oldTy(that.oldTy), elemTy(0), resultTy(0), elements(0), - nelems(0) { - *this = that; - } + static const TypeInfo* get(const std::string& newType, const TypeInfo* resTy, + TypeList* TL); - TypeInfo& operator=(const TypeInfo& that) { - oldTy = that.oldTy; - nelems = that.nelems; - if (that.newTy) - newTy = new std::string(*that.newTy); - if (that.elemTy) - elemTy = that.elemTy->clone(); - if (that.resultTy) - resultTy = that.resultTy->clone(); - if (that.elements) { - elements = new std::vector<TypeInfo*>(that.elements->size()); - *elements = *that.elements; - } - return *this; - } + const TypeInfo* resolve() const; + bool operator<(const TypeInfo& that) const; - ~TypeInfo() { - delete newTy; delete elemTy; delete resultTy; delete elements; + bool sameNewTyAs(const TypeInfo* that) const { + return this->newTy == that->newTy; } - TypeInfo* clone() const { - return new TypeInfo(*this); - } + bool sameOldTyAs(const TypeInfo* that) const; - Types getElementTy() const { + Types getElementTy() const { if (elemTy) { return elemTy->oldTy; } return UnresolvedTy; } - const std::string& getNewTy() const { return *newTy; } - void setOldTy(Types Ty) { oldTy = Ty; } + unsigned getUpRefNum() const { + assert(oldTy == UpRefTy && "Can't getUpRefNum on non upreference"); + return atoi(&((getNewTy().c_str())[1])); // skip the slash + } - TypeInfo* getResultType() const { return resultTy; } - TypeInfo* getElementType() const { return elemTy; } + const std::string& getNewTy() const { return newTy; } + const TypeInfo* getResultType() const { return resultTy; } + const TypeInfo* getElementType() const { return elemTy; } - TypeInfo* getPointerType() const { - std::string* ty = new std::string(*newTy + "*"); - return new TypeInfo(ty, PointerTy, this->clone(), (TypeInfo*)0); + const TypeInfo* getPointerType() const { + return get(newTy + "*", PointerTy, this, (TypeInfo*)0); } bool isUnresolved() const { return oldTy == UnresolvedTy; } @@ -164,8 +127,6 @@ struct TypeInfo { return oldTy == UByteTy || oldTy == UShortTy || oldTy == UIntTy || oldTy == ULongTy; } - - bool isSignless() const { return !isSigned() && !isUnsigned(); } bool isInteger() const { return isSigned() || isUnsigned(); } bool isIntegral() const { return oldTy == BoolTy || isInteger(); } @@ -185,78 +146,60 @@ struct TypeInfo { return isIntegral() && getBitWidth() < 32; } - unsigned getBitWidth() const { - switch (oldTy) { - default: - case LabelTy: - case VoidTy : return 0; - case BoolTy : return 1; - case SByteTy: case UByteTy : return 8; - case ShortTy: case UShortTy : return 16; - case IntTy: case UIntTy: case FloatTy: return 32; - case LongTy: case ULongTy: case DoubleTy : return 64; - case PointerTy: return SizeOfPointer; // global var - case PackedTy: - case ArrayTy: - return nelems * elemTy->getBitWidth(); - case StructTy: - case PackedStructTy: { - uint64_t size = 0; - for (unsigned i = 0; i < elements->size(); i++) { - ResolveType((*elements)[i]); - size += (*elements)[i]->getBitWidth(); - } - return size; - } - } - } + bool isUnresolvedDeep() const; - TypeInfo* getIndexedType(const ValueInfo& VI) { - if (isStruct()) { - if (VI.isConstant() && VI.type->isInteger()) { - size_t pos = VI.val->find(' ') + 1; - if (pos < VI.val->size()) { - uint64_t idx = atoi(VI.val->substr(pos).c_str()); - return (*elements)[idx]; - } else { - yyerror("Invalid value for constant integer"); - return 0; - } - } else { - yyerror("Structure requires constant index"); - return 0; - } - } - if (isArray() || isPacked() || isPointer()) - return elemTy; - yyerror("Invalid type for getIndexedType"); - return 0; - } + unsigned getBitWidth() const; + + const TypeInfo* getIndexedType(const ValueInfo& VI) const; unsigned getNumStructElements() const { return (elements ? elements->size() : 0); } - TypeInfo* getElement(unsigned idx) { + const TypeInfo* getElement(unsigned idx) const { if (elements) if (idx < elements->size()) return (*elements)[idx]; return 0; } + private: - std::string* newTy; + TypeInfo() + : newTy(), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0), + nelems(0) { + } + + TypeInfo(const TypeInfo& that); // do not implement + TypeInfo& operator=(const TypeInfo& that); // do not implement + + ~TypeInfo() { delete elements; } + + struct ltfunctor + { + bool operator()(const TypeInfo* X, const TypeInfo* Y) const { + assert(X && "Can't compare null pointer"); + assert(Y && "Can't compare null pointer"); + return *X < *Y; + } + }; + + typedef std::set<const TypeInfo*, ltfunctor> TypeRegMap; + static const TypeInfo* add_new_type(TypeInfo* existing); + + std::string newTy; Types oldTy; TypeInfo *elemTy; TypeInfo *resultTy; TypeList *elements; uint64_t nelems; + static TypeRegMap registry; }; /// This type is used to keep track of the signedness of constants. struct ConstInfo { std::string *cnst; - TypeInfo *type; + const TypeInfo *type; void destroy() { delete cnst; } }; diff --git a/tools/llvm-upgrade/UpgradeLexer.l b/tools/llvm-upgrade/UpgradeLexer.l index d9e5d0ebe3..5b575606ce 100644 --- a/tools/llvm-upgrade/UpgradeLexer.l +++ b/tools/llvm-upgrade/UpgradeLexer.l @@ -26,7 +26,7 @@ %{ -#include "ParserInternals.h" +#include "UpgradeInternals.h" #include "UpgradeParser.h" #include <cctype> #include <cstdlib> @@ -48,7 +48,7 @@ return sym #define RET_TY(sym,OldTY,NewTY,sign) \ - Upgradelval.Type = new TypeInfo(NewTY, OldTY); \ + Upgradelval.Type = TypeInfo::get(NewTY, OldTY); \ return sym #define YY_NEVER_INTERACTIVE 1 diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y index 2b3315d8f1..ca8ee4f52e 100644 --- a/tools/llvm-upgrade/UpgradeParser.y +++ b/tools/llvm-upgrade/UpgradeParser.y @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// %{ -#include "ParserInternals.h" +#include "UpgradeInternals.h" #include <algorithm> #include <map> #include <utility> @@ -45,11 +45,15 @@ static bool AddAttributes = false; static bool deleteUselessCastFlag = false; static std::string* deleteUselessCastName = 0; -typedef std::vector<TypeInfo> TypeVector; +typedef std::vector<const TypeInfo*> TypeVector; static TypeVector EnumeratedTypes; -typedef std::map<std::string,TypeInfo> TypeMap; +typedef std::map<std::string,const TypeInfo*> TypeMap; static TypeMap NamedTypes; -static TypeMap Globals; +typedef std::map<const TypeInfo*,std::string> TypePlaneMap; +typedef std::map<std::string,TypePlaneMap> GlobalsTypeMap; +static GlobalsTypeMap Globals; + +static void warning(const std::string& msg); void destroy(ValueList* VL) { while (!VL->empty()) { @@ -77,32 +81,261 @@ void UpgradeAssembly(const std::string &infile, std::istream& in, } } -TypeInfo* ResolveType(TypeInfo*& Ty) { - if (Ty->isUnresolved()) { - if (Ty->getNewTy()[0] == '%' && isdigit(Ty->getNewTy()[1])) { - unsigned ref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the % +TypeInfo::TypeRegMap TypeInfo::registry; + +const TypeInfo* TypeInfo::get(const std::string &newType, Types oldType) { + TypeInfo* Ty = new TypeInfo(); + Ty->newTy = newType; + Ty->oldTy = oldType; + return add_new_type(Ty); +} + +const TypeInfo* TypeInfo::get(const std::string& newType, Types oldType, + const TypeInfo* eTy, const TypeInfo* rTy) { + TypeInfo* Ty= new TypeInfo(); + Ty->newTy = newType; + Ty->oldTy = oldType; + Ty->elemTy = const_cast<TypeInfo*>(eTy); + Ty->resultTy = const_cast<TypeInfo*>(rTy); + return add_new_type(Ty); +} + +const TypeInfo* TypeInfo::get(const std::string& newType, Types oldType, + const TypeInfo *eTy, uint64_t elems) { + TypeInfo* Ty = new TypeInfo(); + Ty->newTy = newType; + Ty->oldTy = oldType; + Ty->elemTy = const_cast<TypeInfo*>(eTy); + Ty->nelems = elems; + return add_new_type(Ty); +} + +const TypeInfo* TypeInfo::get(const std::string& newType, Types oldType, + TypeList* TL) { + TypeInfo* Ty = new TypeInfo(); + Ty->newTy = newType; + Ty->oldTy = oldType; + Ty->elements = TL; + return add_new_type(Ty); +} + +const TypeInfo* TypeInfo::get(const std::string& newType, const TypeInfo* resTy, + TypeList* TL) { + TypeInfo* Ty = new TypeInfo(); + Ty->newTy = newType; + Ty->oldTy = FunctionTy; + Ty->resultTy = const_cast<TypeInfo*>(resTy); + Ty->elements = TL; + return add_new_type(Ty); +} + +const TypeInfo* TypeInfo::resolve() const { + if (isUnresolved()) { + if (getNewTy()[0] == '%' && isdigit(getNewTy()[1])) { + unsigned ref = atoi(&((getNewTy().c_str())[1])); // skip the % if (ref < EnumeratedTypes.size()) { - Ty = &EnumeratedTypes[ref]; - return Ty; + return EnumeratedTypes[ref]; } else { std::string msg("Can't resolve numbered type: "); - msg += Ty->getNewTy(); + msg += getNewTy(); yyerror(msg.c_str()); } } else { - TypeMap::iterator I = NamedTypes.find(Ty->getNewTy()); + TypeMap::iterator I = NamedTypes.find(getNewTy()); if (I != NamedTypes.end()) { - Ty = &I->second; - return Ty; + return I->second; } else { std::string msg("Cannot resolve type: "); - msg += Ty->getNewTy(); + msg += getNewTy(); yyerror(msg.c_str()); } } } // otherwise its already resolved. - return Ty; + return this; +} + +bool TypeInfo::operator<(const TypeInfo& that) const { + if (this == &that) + return false; + if (oldTy != that.oldTy) + return oldTy < that.oldTy; + switch (oldTy) { + case UpRefTy: { + unsigned thisUp = this->getUpRefNum(); + unsigned thatUp = that.getUpRefNum(); + return thisUp < thatUp; + } + case PackedTy: + case ArrayTy: + if (this->nelems != that.nelems) + return nelems < that.nelems; + case PointerTy: { + const TypeInfo* thisTy = this->elemTy; + const TypeInfo* thatTy = that.elemTy; + return *thisTy < *thatTy; + } + case FunctionTy: { + const TypeInfo* thisTy = this->resultTy; + const TypeInfo* thatTy = that.resultTy; + if (!thisTy->sameOldTyAs(thatTy)) + return *thisTy < *thatTy; + /* FALL THROUGH */ + } + case StructTy: + case PackedStructTy: { + if (elements->size() != that.elements->size()) + return elements->size() < that.elements->size(); + for (unsigned i = 0; i < elements->size(); i++) { + const TypeInfo* thisTy = (*this->elements)[i]; + const TypeInfo* thatTy = (*that.elements)[i]; + if (!thisTy->sameOldTyAs(thatTy)) + return *thisTy < *thatTy; + } + break; + } + case UnresolvedTy: + return this->newTy < that.newTy; + default: + break; + } + return false; +} + +bool TypeInfo::sameOldTyAs(const TypeInfo* that) const { + if (that == 0) + return false; + if ( this == that ) + return true; + if (oldTy != that->oldTy) + return false; + switch (oldTy) { + case PackedTy: + case ArrayTy: + if (nelems != that->nelems) + return false; + /* FALL THROUGH */ + case PointerTy: { + const TypeInfo* thisTy = this->elemTy; + const TypeInfo* thatTy = that->elemTy; + return thisTy->sameOldTyAs(thatTy); + } + case FunctionTy: { + const TypeInfo* thisTy = this->resultTy; + const TypeInfo* thatTy = that->resultTy; + if (!thisTy->sameOldTyAs(thatTy)) + return false; + /* FALL THROUGH */ + } + case StructTy: + case PackedStructTy: { + if (elements->size() != that->elements->size()) + return false; + for (unsigned i = 0; i < elements->size(); i++) { + const TypeInfo* thisTy = (*this->elements)[i]; + const TypeInfo* thatTy = (*that->elements)[i]; + if (!thisTy->sameOldTyAs(thatTy)) + return false; + } + return true; + } + case UnresolvedTy: + return this->newTy == that->newTy; + default: + return true; // for all others oldTy == that->oldTy is sufficient + } + return true; +} + +bool TypeInfo::isUnresolvedDeep() const { + switch (oldTy) { + case UnresolvedTy: + return true; + case PackedTy: + case ArrayTy: + case PointerTy: + return elemTy->isUnresolvedDeep(); + case PackedStructTy: + case StructTy: + for (unsigned i = 0; i < elements->size(); i++) + if ((*elements)[i]->isUnresolvedDeep()) + return true; + return false; + default: + return false; + } +} + +unsigned TypeInfo::getBitWidth() const { + switch (oldTy) { + default: + case LabelTy: + case VoidTy : return 0; + case BoolTy : return 1; + case SByteTy: case UByteTy : return 8; + case ShortTy: case UShortTy : return 16; + case IntTy: case UIntTy: case FloatTy: return 32; + case LongTy: case ULongTy: case DoubleTy : return 64; + case PointerTy: return SizeOfPointer; // global var + case PackedTy: + case ArrayTy: + return nelems * elemTy->getBitWidth(); + case StructTy: + case PackedStructTy: { + uint64_t size = 0; + for (unsigned i = 0; i < elements->size(); i++) { + size += (*elements)[i]->getBitWidth(); + } + return size; + } + } +} + +const TypeInfo* TypeInfo::getIndexedType(const ValueInfo& VI) const { + if (isStruct()) { + if (VI.isConstant() && VI.type->isInteger()) { + size_t pos = VI.val->find(' ') + 1; + if (pos < VI.val->size()) { + uint64_t idx = atoi(VI.val->substr(pos).c_str()); + return (*elements)[idx]; + } else { + yyerror("Invalid value for constant integer"); + return 0; + } + } else { + yyerror("Structure requires constant index"); + return 0; + } + } + if (isArray() || isPacked() || isPointer()) + return elemTy; + yyerror("Invalid type for getIndexedType"); + return 0; +} + +TypeInfo& TypeInfo::operator=(const TypeInfo& that) { + oldTy = that.oldTy; + nelems = that.nelems; + newTy = that.newTy; + elemTy = that.elemTy; + resultTy = that.resultTy; + if (that.elements) { + elements = new TypeList(that.elements->size()); + *elements = *that.elements; + } else { + elements = 0; + } + return *this; +} + +const TypeInfo* TypeInfo::add_new_type(TypeInfo* newTy) { + TypeRegMap::iterator I = registry.find(newTy); + if (I != registry.end()) { + delete newTy; + return *I; + } + registry.insert(newTy); + return newTy; } static const char* getCastOpcode( @@ -183,8 +416,8 @@ static const char* getCastOpcode( return opcode; } -static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy, - TypeInfo* DstTy, bool isConst) +static std::string getCastUpgrade(const std::string& Src, const TypeInfo* SrcTy, + const TypeInfo* DstTy, bool isConst) { std::string Result; std::string Source = Src; @@ -199,8 +432,7 @@ static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy, Source = "i64 %cast_upgrade" + llvm::utostr(unique); } // Update the SrcTy for the getCastOpcode call below - delete SrcTy; - SrcTy = new TypeInfo("i64", ULongTy); + SrcTy = TypeInfo::get("i64", ULongTy); } else if (DstTy->isBool()) { // cast type %x to bool was previously defined as setne type %x, null // The cast semantic is now to truncate, not compare so we must retain @@ -216,8 +448,8 @@ static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy, Result = compareOp + Source + comparator; return Result; // skip cast processing below } - ResolveType(SrcTy); - ResolveType(DstTy); + SrcTy = SrcTy->resolve(); + DstTy = DstTy->resolve(); std::string Opcode(getCastOpcode(Source, SrcTy, DstTy)); if (isConst) Result += Opcode + "( " + Source + " to " + DstTy->getNewTy() + ")"; @@ -226,9 +458,9 @@ static std::string getCastUpgrade(const std::string& Src, TypeInfo* SrcTy, return Result; } -const char* getDivRemOpcode(const std::string& opcode, TypeInfo* TI) { +const char* getDivRemOpcode(const std::string& opcode, const TypeInfo* TI) { const char* op = opcode.c_str(); - const TypeInfo* Ty = ResolveType(TI); + const TypeInfo* Ty = TI->resolve(); if (Ty->isPacked()) Ty = Ty->getElementType(); if (opcode == "div") @@ -283,35 +515,36 @@ getCompareOp(const std::string& setcc, const TypeInfo* TI) { return result; } -static TypeInfo* getFunctionReturnType(TypeInfo* PFTy) { - ResolveType(PFTy); +static const TypeInfo* getFunctionReturnType(const TypeInfo* PFTy) { + PFTy = PFTy->resolve(); if (PFTy->isPointer()) { - TypeInfo* ElemTy = PFTy->getElementType(); - ResolveType(ElemTy); + const TypeInfo* ElemTy = PFTy->getElementType(); + ElemTy = ElemTy->resolve(); if (ElemTy->isFunction()) - return ElemTy->getResultType()->clone(); + return ElemTy->getResultType(); } else if (PFTy->isFunction()) { - return PFTy->getResultType()->clone(); + return PFTy->getResultType(); } - return PFTy->clone(); + return PFTy; } -typedef std::vector<TypeInfo*> UpRefStack; -static TypeInfo* ResolveUpReference(TypeInfo* Ty, UpRefStack* stack) { +typedef std::vector<const TypeInfo*> UpRefStack; +static const TypeInfo* ResolveUpReference(const TypeInfo* Ty, + UpRefStack* stack) { assert(Ty->isUpReference() && "Can't resolve a non-upreference"); - unsigned upref = atoi(&((Ty->getNewTy().c_str())[1])); // skip the slash + unsigned upref = Ty->getUpRefNum(); assert(upref < stack->size() && "Invalid up reference"); return (*stack)[upref - stack->size() - 1]; } -static TypeInfo* getGEPIndexedType(TypeInfo* PTy, ValueList* idxs) { - TypeInfo* Result = ResolveType(PTy); +static const TypeInfo* getGEPIndexedType(const TypeInfo* PTy, ValueList* idxs) { + const TypeInfo* Result = PTy = PTy->resolve(); assert(PTy->isPointer() && "GEP Operand is not a pointer?"); UpRefStack stack; for (unsigned i = 0; i < idxs->size(); ++i) { if (Result->isComposite()) { Result = Result->getIndexedType((*idxs)[i]); - ResolveType(Result); + Result = Result->resolve(); stack.push_back(Result); } else yyerror("Invalid type for index"); @@ -344,25 +577,47 @@ static std::string makeUniqueName(const std::string *Name, bool isSigned) { // were previously unsigned or signed, respectively. This avoids name // collisions since the unsigned and signed type planes have collapsed // into a single signless type plane. -static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) { +static std::string getUniqueName(const std::string *Name, const TypeInfo* Ty, + bool isGlobal = false) { + // If its not a symbolic name, don't modify it, probably a constant val. if ((*Name)[0] != '%' && (*Name)[0] != '"') return *Name; + // If its a numeric reference, just leave it alone. if (isdigit((*Name)[1])) return *Name; // Resolve the type - ResolveType(Ty); + Ty = Ty->resolve(); + + // If its a global name, get its uniquified name, if any + GlobalsTypeMap::iterator GI = Globals.find(*Name); + if (GI != Globals.end()) { + TypePlaneMap::iterator TPI = GI->second.begin(); + TypePlaneMap::iterator TPE = GI->second.end(); + for ( ; TPI != TPE ; ++TPI) { + if (TPI->first->sameNewTyAs(Ty)) + return TPI->second; + } + } + + if (isGlobal) { + // We didn't find a global name, but if its supposed to be global then all + // we can do is return the name. This is probably a forward reference of a + // global value that hasn't been defined yet. Since we have no definition + // we don't know its linkage class. Just assume its an external and the name + // shouldn't change. + return *Name; + } // Remove as many levels of pointer nesting that we have. if (Ty->isPointer()) { // Avoid infinite loops in recursive types - TypeInfo* Last = 0; - while (Ty->isPointer() && Last != Ty) { + const TypeInfo* Last = 0; + while (Ty->isPointer() && !Ty->sameOldTyAs(Last)) { Last = Ty; - Ty = Ty->getElementType(); - ResolveType(Ty); + Ty = Ty->getElementType()->resolve(); } } @@ -381,7 +636,7 @@ static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) { // Scan the fields and count the signed and unsigned fields int isSigned = 0; for (unsigned i = 0; i < Ty->getNumStructElements(); ++i) { - TypeInfo* Tmp = Ty->getElement(i); + const TypeInfo* Tmp = Ty->getElement(i); if (Tmp->isInteger()) if (Tmp->isSigned()) isSigned++; @@ -394,13 +649,99 @@ static std::string getUniqueName(const std::string *Name, TypeInfo* Ty) { return Result; } +static unsigned UniqueNameCounter = 0; + +std::string getGlobalName(const std::string* Name, const std::string Linkage, + const TypeInfo* Ty, bool isConstant) { + // Default to given name + std::string Result = *Name; + // Look up the name in the Globals Map + GlobalsTypeMap::iterator GI = Globals.find(*Name); + // Did we see this global name before? + if (GI != Globals.end()) { + if (Ty->isUnresolvedDeep()) { + // The Gval's type is unresolved. Consequently, we can't disambiguate it + // by type. We'll just change its name and emit a warning. + warning("Cannot disambiguate global value '" + *Name + + "' because type '" + Ty->getNewTy() + "'is unresolved.\n"); + Result = *Name + ".unique"; + UniqueNameCounter++; + Result += llvm::utostr(UniqueNameCounter); + return Result; + } else { + TypePlaneMap::iterator TPI = GI->second.find(Ty); + if (TPI != GI->second.end()) { + // We found an existing name of the same old type. This isn't allowed + // in LLVM 2.0. Consequently, we must alter the name of the global so it + // can at least compile. References to the global will yield the first + // definition, which is okay. We also must warn about this. + Result = *Name + ".unique"; + UniqueNameCounter++; + Result += llvm::utostr(UniqueNameCounter); + warning(std::string("Global variable '") + *Name + "' was renamed to '"+ + Result + "'"); + } else { + // There isn't an existing definition for this name according to the + // old types. Now search the TypePlanMap for types with the same new + // name. + TypePlaneMap::iterator TPI = GI->second.begin(); + TypePlaneMap::iterator TPE = GI->second.end(); + for ( ; TPI != TPE; ++TPI) { + if (TPI->first->sameNewTyAs(Ty)) { + // The new types are the same but the old types are different so + // this is a global name collision resulting from type planes + // collapsing. + if (Linkage == "external" || Linkage == "dllimport" || + Linkage == "extern_weak" || Linkage == "") { + // The linkage of this gval is external so we can't reliably + // rename it because it could potentially create a linking + // problem. However, we can't leave the name conflict in the + // output either or it won't assemble with LLVM 2.0. So, all we + // can do is rename this one to something unique and emit a + // warning about the problem. + Result = *Name + ".unique"; + UniqueNameCounter++; + Result += llvm::utostr(UniqueNameCounter); + warning("Renaming global value '" + *Name + "' to '" + Result + + "' may cause linkage errors."); + return Result; + } else { + // Its linkage is internal and its type is known so we can + // disambiguate the name collision successfully based on the type. + Result = getUniqueName(Name, Ty); + TPI->second = Result; + return Result; + } + } + } + // We didn't find an entry in the type plane with the same new type and + // the old types differ so this is a new type plane for this global + // variable. We just fall through to the logic below which inserts + // the global. + } + } + } + + // Its a new global name, if it is external we can't change it + if (isConstant || Linkage == "external" || Linkage == "dllimport" || + Linkage == "extern_weak" || Linkage == "") { + Globals[Result][Ty] = Result; + return Result; + } + + // Its a new global name, and it is internal, change the name to make it + // unique for its type. + // Result = getUniqueName(Name, Ty); + Globals[*Name][Ty] = Result; + return Result; +} %} // %file-prefix="UpgradeParser" %union { std::string* String; - TypeInfo* Type; + const TypeInfo* Type; ValueInfo Value; ConstInfo Const; ValueList* ValList; @@ -570,17 +911,17 @@ PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ; PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL; UpRTypes : OPAQUE { - $$ = new TypeInfo($1, OpaqueTy); + $$ = TypeInfo::get(*$1, OpaqueTy); } | SymbolicValueRef { - $$ = new TypeInfo($1, UnresolvedTy); + $$ = TypeInfo::get(*$1, UnresolvedTy); } | PrimType { $$ = $1; } | '\\' EUINT64VAL { // Type UpReference $2->insert(0, "\\"); - $$ = new TypeInfo($2, UpRefTy); + $$ = TypeInfo::get(*$2, UpRefTy); } | UpRTypesV '(' ArgTypeListI ')' { // Function derived type? std::string newTy( $1->getNewTy() + "("); @@ -593,19 +934,19 @@ UpRTypes newTy += (*$3)[i]->getNewTy(); } newTy += ")"; - $$ = new TypeInfo(new std::string(newTy), $1, $3); + $$ = TypeInfo::get(newTy, $1, $3); } | '[' EUINT64VAL 'x' UpRTypes ']' { // Sized array type? + uint64_t elems = atoi($2->c_str()); $2->insert(0,"[ "); *$2 += " x " + $4->getNewTy() + " ]"; - uint64_t elems = atoi($2->c_str()); - $$ = new TypeInfo($2, ArrayTy, $4, elems); + $$ = TypeInfo::get(*$2, ArrayTy, $4, elems); } | '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type? + uint64_t elems = atoi($2->c_str()); $2->insert(0,"< "); *$2 += " x " + $4->getNewTy() + " >"; - uint64_t elems = atoi($2->c_str()); - $$ = new TypeInfo($2, PackedTy, $4, elems); + $$ = TypeInfo::get(*$2, PackedTy, $4, elems); } | '{' TypeListI '}' { // Structure type? std::string newTy("{"); @@ -615,10 +956,10 @@ UpRTypes newTy += (*$2)[i]->getNewTy(); } newTy += "}"; - $$ = new TypeInfo(new std::string(newTy), StructTy, $2); + $$ = TypeInfo::get(newTy, StructTy, $2); } | '{' '}' { // Empty structure type? - $$ = new TypeInfo(new std::string("{}"), StructTy, new TypeList()); + $$ = TypeInfo::get("{}", StructTy, new TypeList()); } | '<' '{' TypeListI '}' '>' { // Packed Structure type? std::string newTy("<{"); @@ -628,10 +969,10 @@ UpRTypes newTy += (*$3)[i]->getNewTy(); } newTy += "}>"; - $$ = new TypeInfo(new std::string(newTy), PackedStructTy, $3); + $$ = TypeInfo::get(newTy, PackedStructTy, $3); } | '<' '{' '}' '>' { // Empty packed structure type? - $$ = new TypeInfo(new std::string("<{}>"), PackedStructTy, new TypeList()); + $$ = TypeInfo::get("<{}>", PackedStructTy, new TypeList()); } | UpRTypes '*' { // Pointer type? $$ = $1->getPointerType(); @@ -655,12 +996,12 @@ ArgTypeListI : TypeListI | TypeListI ',' DOTDOTDOT { $$ = $1; - $$->push_back(new TypeInfo("void",VoidTy)); + $$->push_back(TypeInfo::get("void",VoidTy)); delete $3; } | DOTDOTDOT { $$ = new TypeList(); - $$->push_back(new TypeInfo("void",VoidTy)); + $$->push_back(TypeInfo::get("void",VoidTy)); delete $1; } | /*empty*/ { @@ -720,7 +1061,7 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr delete $2; } | Types SymbolicValueRef { - std::string Name = getUniqueName($2,$1); + std::string Name = getUniqueName($2, $1->resolve(), true); $$.type = $1; $$.cnst = new std::string($1->getNewTy()); *$$.cnst += " " + Name; @@ -772,10 +1113,11 @@ ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr ConstExpr: CastOps '(' ConstVal TO Types ')' { std::string source = *$3.cnst; - TypeInfo* DstTy = ResolveType($5); + const TypeInfo* SrcTy = $3.type->resolve(); + const TypeInfo* DstTy = $5->resolve(); if (*$1 == "cast") { // Call getCastUpgrade to upgrade the old cast - $$ = new std::string(getCastUpgrade(source, $3.type, DstTy, true)); + $$ = new std::string(getCastUpgrade(source, SrcTy, DstTy, true)); } else { // Nothing to upgrade, just create the cast constant expr $$ = new std::string(*$1); @@ -902,9 +1244,9 @@ External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; } // ConstPool - Constants with optional names assigned to them. ConstPool : ConstPool OptAssign TYPE TypesV { - EnumeratedTypes.push_back(*$4); + EnumeratedTypes.push_back($4); if (!$2->empty()) { - NamedTypes[*$2] = *$4; + NamedTypes[*$2] = $4; *O << *$2 << " = "; } *O << "type " << $4->getNewTy() << '\n'; @@ -923,9 +1265,9 @@ ConstPool : ConstPool OptAssign TYPE TypesV { } | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes { if (!$2->empty()) { - std::string Name = getUniqueName($2,$5.type); + std::string Name = getGlobalName($2,*$3, $5.type->getPointerType(), + *$4 == "constant"); *O << Name << " = "; - Globals[Name] = *$5.type; } *O << *$3 << ' ' << *$4 << ' ' << *$5.cnst << ' ' << *$6 << '\n'; delete $2; delete $3; delete $4; delete $6; @@ -933,19 +1275,19 @@ ConstPool : ConstPool OptAssign TYPE TypesV { } | ConstPool OptAssign External GlobalType Types GlobalVarAttributes { if (!$2->empty()) { - std::string Name = getUniqueName($2,$5); + std::string Name = getGlobalName($2,*$3,$5->getPointerType(), + *$4 == "constant"); |