diff options
-rw-r--r-- | tools/llvm-upgrade/UpgradeInternals.h | 184 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeLexer.l | 2 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeParser.y | 889 |
3 files changed, 574 insertions, 501 deletions
diff --git a/tools/llvm-upgrade/UpgradeInternals.h b/tools/llvm-upgrade/UpgradeInternals.h index 9c8b6a0142..ca574b283c 100644 --- a/tools/llvm-upgrade/UpgradeInternals.h +++ b/tools/llvm-upgrade/UpgradeInternals.h @@ -22,193 +22,43 @@ #include <set> #include <cassert> -// Global variables exported from the lexer... - +// Global variables exported from the lexer. extern std::string CurFileName; extern std::string Textin; extern int Upgradelineno; extern std::istream* LexInput; -struct TypeInfo; -typedef std::vector<const TypeInfo*> TypeList; - -void UpgradeAssembly( - const std::string & infile, std::istream& in, std::ostream &out, bool debug, - bool addAttrs); - -// Globals exported by the parser... +// Global variables exported from the parser. extern char* Upgradetext; extern int Upgradeleng; extern unsigned SizeOfPointer; +// Functions exported by the parser +void UpgradeAssembly( + const std::string & infile, std::istream& in, std::ostream &out, bool debug, + bool addAttrs); int yyerror(const char *ErrorMsg) ; /// This enum is used to keep track of the original (1.9) type used to form /// a type. These are needed for type upgrades and to determine how to upgrade -/// signed instructions with signless operands. +/// signed instructions with signless operands. The Lexer uses thse in its +/// calls to getTypeInfo enum Types { BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy, FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, PackedStructTy, OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, UpRefTy }; -/// This type is used to keep track of the signedness of values. Instead -/// of creating llvm::Value directly, the parser will create ValueInfo which -/// associates a Value* with a Signedness indication. -struct ValueInfo { - std::string* val; - const TypeInfo* type; - bool constant; - bool isConstant() const { return constant; } - inline void destroy(); -}; - -/// This type is used to keep track of the signedness of the obsolete -/// integer types. Instead of creating an llvm::Type directly, the Lexer will -/// create instances of TypeInfo which retains the signedness indication so -/// it can be used by the parser for upgrade decisions. -/// For example if "uint" is encountered then the "first" field will be set -/// 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 { - - 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); - - static const TypeInfo* get(const std::string& newType, Types oldType, - const TypeInfo *eTy, uint64_t elems); - - static const TypeInfo* get(const std::string& newType, Types oldType, - TypeList* TL); - - static const TypeInfo* get(const std::string& newType, const TypeInfo* resTy, - TypeList* TL); - - const TypeInfo* resolve() const; - bool operator<(const TypeInfo& that) const; - - bool sameNewTyAs(const TypeInfo* that) const { - return this->newTy == that->newTy; - } - - bool sameOldTyAs(const TypeInfo* that) const; - - Types getElementTy() const { - if (elemTy) { - return elemTy->oldTy; - } - return UnresolvedTy; - } - - unsigned getUpRefNum() const { - assert(oldTy == UpRefTy && "Can't getUpRefNum on non upreference"); - return atoi(&((getNewTy().c_str())[1])); // skip the slash - } - - typedef std::vector<const TypeInfo*> UpRefStack; - void getSignedness(unsigned &sNum, unsigned &uNum, UpRefStack& stk) const; - std::string makeUniqueName(const std::string& BaseName) const; +namespace { +class TypeInfo; +class ValueInfo; +class ConstInfo; +} - const std::string& getNewTy() const { return newTy; } - const TypeInfo* getResultType() const { return resultTy; } - const TypeInfo* getElementType() const { return elemTy; } - - const TypeInfo* getPointerType() const { - return get(newTy + "*", PointerTy, this, (TypeInfo*)0); - } - - bool isUnresolved() const { return oldTy == UnresolvedTy; } - bool isUpReference() const { return oldTy == UpRefTy; } - bool isVoid() const { return oldTy == VoidTy; } - bool isBool() const { return oldTy == BoolTy; } - bool isSigned() const { - return oldTy == SByteTy || oldTy == ShortTy || - oldTy == IntTy || oldTy == LongTy; - } - - bool isUnsigned() const { - 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(); } - bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; } - bool isPacked() const { return oldTy == PackedTy; } - bool isPointer() const { return oldTy == PointerTy; } - bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; } - bool isArray() const { return oldTy == ArrayTy; } - bool isOther() const { - return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); } - bool isFunction() const { return oldTy == FunctionTy; } - bool isComposite() const { - return isStruct() || isPointer() || isArray() || isPacked(); - } - - bool isAttributeCandidate() const { - return isIntegral() && getBitWidth() < 32; - } - - bool isUnresolvedDeep() const; - - unsigned getBitWidth() const; - - const TypeInfo* getIndexedType(const ValueInfo& VI) const; - - unsigned getNumStructElements() const { - return (elements ? elements->size() : 0); - } - - const TypeInfo* getElement(unsigned idx) const { - if (elements) - if (idx < elements->size()) - return (*elements)[idx]; - return 0; - } - - -private: - 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; - const TypeInfo *type; - void destroy() { delete cnst; } -}; - -typedef std::vector<ValueInfo> ValueList; +typedef std::vector<const TypeInfo*> TypeList; +typedef std::vector<ValueInfo*> ValueList; -inline void ValueInfo::destroy() { delete val; } +/// A function to create a TypeInfo* used in the Lexer. +extern const TypeInfo* getTypeInfo(const std::string& newTy, Types oldTy); #endif diff --git a/tools/llvm-upgrade/UpgradeLexer.l b/tools/llvm-upgrade/UpgradeLexer.l index 8b39045801..f32645dfe7 100644 --- a/tools/llvm-upgrade/UpgradeLexer.l +++ b/tools/llvm-upgrade/UpgradeLexer.l @@ -48,7 +48,7 @@ return sym #define RET_TY(sym,OldTY,NewTY,sign) \ - Upgradelval.Type = TypeInfo::get(NewTY, OldTY); \ + Upgradelval.Type = getTypeInfo(NewTY, OldTY); \ return sym #define YY_NEVER_INTERACTIVE 1 diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y index 25211aaa21..7501c0c4f5 100644 --- a/tools/llvm-upgrade/UpgradeParser.y +++ b/tools/llvm-upgrade/UpgradeParser.y @@ -30,44 +30,14 @@ static std::string CurFilename; static std::ostream *O = 0; std::istream* LexInput = 0; unsigned SizeOfPointer = 32; -static uint64_t unique = 1; + // This bool controls whether attributes are ever added to function declarations // definitions and calls. static bool AddAttributes = false; -// This is set when a DECLARE keyword is recognized so that subsequent parsing -// of a function prototype can know if its a declaration or definition. -static bool isDeclare = false; - -// This bool is used to communicate between the InstVal and Inst rules about -// whether or not a cast should be deleted. When the flag is set, InstVal has -// determined that the cast is a candidate. However, it can only be deleted if -// the value being casted is the same value name as the instruction. The Inst -// rule makes that comparison if the flag is set and comments out the -// instruction if they match. -static bool deleteUselessCastFlag = false; -static std::string* deleteUselessCastName = 0; - -typedef std::vector<const TypeInfo*> TypeVector; -static TypeVector EnumeratedTypes; -typedef std::map<std::string,const TypeInfo*> TypeMap; -static TypeMap NamedTypes; -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()) { - ValueInfo& VI = VL->back(); - VI.destroy(); - VL->pop_back(); - } - delete VL; -} - void UpgradeAssembly(const std::string &infile, std::istream& in, std::ostream &out, bool debug, bool addAttrs) { @@ -79,13 +49,176 @@ void UpgradeAssembly(const std::string &infile, std::istream& in, O = &out; if (yyparse()) { - std::cerr << "Parse failed.\n"; - out << "llvm-upgrade parse failed.\n"; + std::cerr << "llvm-upgrade: parse failed.\n"; + out << "llvm-upgrade: parse failed.\n"; exit(1); } } -TypeInfo::TypeRegMap TypeInfo::registry; +namespace { // Anonymous namespace to keep our implementation local + + +/// This type is used to keep track of the signedness of values. Instead +/// of creating llvm::Value directly, the parser will create ValueInfo which +/// associates a Value* with a Signedness indication. +struct ValueInfo { + std::string* val; + const TypeInfo* type; + bool constant; + bool isConstant() const { return constant; } + ~ValueInfo() { delete val; } +}; + + +/// This type is used to keep track of the signedness of the obsolete +/// integer types. Instead of creating an llvm::Type directly, the Lexer will +/// create instances of TypeInfo which retains the signedness indication so +/// it can be used by the parser for upgrade decisions. +/// For example if "uint" is encountered then the "first" field will be set +/// to "int32" and the "second" field will be set to "isUnsigned". If the +/// type is not obsolete then "second" will be set to "isSignless". +class TypeInfo { +public: + 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); + + static const TypeInfo* get(const std::string& newType, Types oldType, + const TypeInfo *eTy, uint64_t elems); + + static const TypeInfo* get(const std::string& newType, Types oldType, + TypeList* TL); + + static const TypeInfo* get(const std::string& newType, const TypeInfo* resTy, + TypeList* TL); + + const TypeInfo* resolve() const; + bool operator<(const TypeInfo& that) const; + + bool sameNewTyAs(const TypeInfo* that) const { + return this->newTy == that->newTy; + } + + bool sameOldTyAs(const TypeInfo* that) const; + + Types getElementTy() const { + if (elemTy) { + return elemTy->oldTy; + } + return UnresolvedTy; + } + + unsigned getUpRefNum() const { + assert(oldTy == UpRefTy && "Can't getUpRefNum on non upreference"); + return atoi(&((getNewTy().c_str())[1])); // skip the slash + } + + typedef std::vector<const TypeInfo*> UpRefStack; + void getSignedness(unsigned &sNum, unsigned &uNum, UpRefStack& stk) const; + std::string makeUniqueName(const std::string& BaseName) const; + + const std::string& getNewTy() const { return newTy; } + const TypeInfo* getResultType() const { return resultTy; } + const TypeInfo* getElementType() const { return elemTy; } + + const TypeInfo* getPointerType() const { + return get(newTy + "*", PointerTy, this, (TypeInfo*)0); + } + + bool isUnresolved() const { return oldTy == UnresolvedTy; } + bool isUpReference() const { return oldTy == UpRefTy; } + bool isVoid() const { return oldTy == VoidTy; } + bool isBool() const { return oldTy == BoolTy; } + bool isSigned() const { + return oldTy == SByteTy || oldTy == ShortTy || + oldTy == IntTy || oldTy == LongTy; + } + + bool isUnsigned() const { + 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(); } + bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; } + bool isPacked() const { return oldTy == PackedTy; } + bool isPointer() const { return oldTy == PointerTy; } + bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; } + bool isArray() const { return oldTy == ArrayTy; } + bool isOther() const { + return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); } + bool isFunction() const { return oldTy == FunctionTy; } + bool isComposite() const { + return isStruct() || isPointer() || isArray() || isPacked(); + } + + bool isAttributeCandidate() const { + return isIntegral() && getBitWidth() < 32; + } + + bool isUnresolvedDeep() const; + + unsigned getBitWidth() const; + + const TypeInfo* getIndexedType(const ValueInfo* VI) const; + + unsigned getNumStructElements() const { + return (elements ? elements->size() : 0); + } + + const TypeInfo* getElement(unsigned idx) const { + if (elements) + if (idx < elements->size()) + return (*elements)[idx]; + return 0; + } + +private: + 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; +public: + typedef std::vector<const TypeInfo*> TypeVector; + typedef std::map<std::string,const TypeInfo*> TypeMap; + typedef std::map<const TypeInfo*,std::string> TypePlaneMap; + typedef std::map<std::string,TypePlaneMap> GlobalsTypeMap; + static TypeVector EnumeratedTypes; + static TypeMap NamedTypes; + static GlobalsTypeMap Globals; +}; + +TypeInfo::TypeRegMap TypeInfo::registry; +TypeInfo::TypeVector TypeInfo::EnumeratedTypes; +TypeInfo::TypeMap TypeInfo::NamedTypes; +TypeInfo::GlobalsTypeMap TypeInfo::Globals; const TypeInfo* TypeInfo::get(const std::string &newType, Types oldType) { TypeInfo* Ty = new TypeInfo(); @@ -145,7 +278,7 @@ const TypeInfo* TypeInfo::resolve() const { yyerror(msg.c_str()); } } else { - TypeMap::iterator I = NamedTypes.find(newTy); + TypeInfo::TypeMap::iterator I = NamedTypes.find(newTy); if (I != NamedTypes.end()) { return I->second; } else { @@ -295,12 +428,12 @@ unsigned TypeInfo::getBitWidth() const { } } -const TypeInfo* TypeInfo::getIndexedType(const ValueInfo& VI) const { +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()); + 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"); @@ -446,9 +579,34 @@ const TypeInfo* TypeInfo::add_new_type(TypeInfo* newTy) { return newTy; } -static const char* getCastOpcode( - std::string& Source, const TypeInfo* SrcTy, const TypeInfo* DstTy) -{ +/// This type is used to keep track of the signedness of constants. +struct ConstInfo { + std::string *cnst; + const TypeInfo *type; + ~ConstInfo() { delete cnst; } +}; + +/// This variable provides a counter for unique names. It is used in various +/// productions to ensure a unique name is generated. +static uint64_t UniqueNameCounter = 1; + +// This is set when a DECLARE keyword is recognized so that subsequent parsing +// of a function prototype can know if its a declaration or definition. +static bool isDeclare = false; + +// This bool is used to communicate between the InstVal and Inst rules about +// whether or not a cast should be deleted. When the flag is set, InstVal has +// determined that the cast is a candidate. However, it can only be deleted if +// the value being casted is the same value name as the instruction. The Inst +// rule makes that comparison if the flag is set and comments out the +// instruction if they match. +static bool deleteUselessCastFlag = false; +static std::string* deleteUselessCastName = 0; + + + +const char* getCastOpcode(std::string& Source, const TypeInfo* SrcTy, + const TypeInfo* DstTy) { unsigned SrcBits = SrcTy->getBitWidth(); unsigned DstBits = DstTy->getBitWidth(); const char* opcode = "bitcast"; @@ -524,9 +682,8 @@ static const char* getCastOpcode( return opcode; } -static std::string getCastUpgrade(const std::string& Src, const TypeInfo* SrcTy, - const TypeInfo* DstTy, bool isConst) -{ +std::string getCastUpgrade(const std::string& Src, const TypeInfo* SrcTy, + const TypeInfo* DstTy, bool isConst) { std::string Result; std::string Source = Src; if (SrcTy->isFloatingPoint() && DstTy->isPointer()) { @@ -535,9 +692,9 @@ static std::string getCastUpgrade(const std::string& Src, const TypeInfo* SrcTy, if (isConst) Source = "i64 fptoui(" + Source + " to i64)"; else { - *O << " %cast_upgrade" << unique << " = fptoui " << Source - << " to i64\n"; - Source = "i64 %cast_upgrade" + llvm::utostr(unique); + *O << " %cast_upgrade" << UniqueNameCounter++ << " = fptoui " + << Source << " to i64\n"; + Source = "i64 %cast_upgrade" + llvm::utostr(UniqueNameCounter); } // Update the SrcTy for the getCastOpcode call below SrcTy = TypeInfo::get("i64", ULongTy); @@ -592,8 +749,7 @@ const char* getDivRemOpcode(const std::string& opcode, const TypeInfo* TI) { return op; } -std::string -getCompareOp(const std::string& setcc, const TypeInfo* TI) { +std::string getCompareOp(const std::string& setcc, const TypeInfo* TI) { assert(setcc.length() == 5); char cc1 = setcc[3]; char cc2 = setcc[4]; @@ -623,7 +779,7 @@ getCompareOp(const std::string& setcc, const TypeInfo* TI) { return result; } -static const TypeInfo* getFunctionReturnType(const TypeInfo* PFTy) { +const TypeInfo* getFunctionReturnType(const TypeInfo* PFTy) { PFTy = PFTy->resolve(); if (PFTy->isPointer()) { const TypeInfo* ElemTy = PFTy->getElementType(); @@ -636,15 +792,15 @@ static const TypeInfo* getFunctionReturnType(const TypeInfo* PFTy) { return PFTy; } -static const TypeInfo* ResolveUpReference(const TypeInfo* Ty, - TypeInfo::UpRefStack* stack) { +const TypeInfo* ResolveUpReference(const TypeInfo* Ty, + TypeInfo::UpRefStack* stack) { assert(Ty->isUpReference() && "Can't resolve a non-upreference"); unsigned upref = Ty->getUpRefNum(); assert(upref < stack->size() && "Invalid up reference"); return (*stack)[upref - stack->size() - 1]; } -static const TypeInfo* getGEPIndexedType(const TypeInfo* PTy, ValueList* idxs) { +const TypeInfo* getGEPIndexedType(const TypeInfo* PTy, ValueList* idxs) { const TypeInfo* Result = PTy = PTy->resolve(); assert(PTy->isPointer() && "GEP Operand is not a pointer?"); TypeInfo::UpRefStack stack; @@ -668,13 +824,12 @@ static const TypeInfo* getGEPIndexedType(const TypeInfo* PTy, ValueList* idxs) { return Result->getPointerType(); } - // This function handles appending .u or .s to integer value names that // 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, const TypeInfo* Ty, - bool isGlobal = false, bool isDef = false) { +std::string getUniqueName(const std::string *Name, const TypeInfo* Ty, + bool isGlobal = false, bool isDef = false) { // If its not a symbolic name, don't modify it, probably a constant val. if ((*Name)[0] != '%' && (*Name)[0] != '"') @@ -688,10 +843,10 @@ static std::string getUniqueName(const std::string *Name, const TypeInfo* 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(); + TypeInfo::GlobalsTypeMap::iterator GI = TypeInfo::Globals.find(*Name); + if (GI != TypeInfo::Globals.end()) { + TypeInfo::TypePlaneMap::iterator TPI = GI->second.begin(); + TypeInfo::TypePlaneMap::iterator TPE = GI->second.end(); for ( ; TPI != TPE ; ++TPI) { if (TPI->first->sameNewTyAs(Ty)) return TPI->second; @@ -713,16 +868,14 @@ static std::string getUniqueName(const std::string *Name, const 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); + TypeInfo::GlobalsTypeMap::iterator GI = TypeInfo::Globals.find(*Name); // Did we see this global name before? - if (GI != Globals.end()) { + if (GI != TypeInfo::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. @@ -733,7 +886,7 @@ std::string getGlobalName(const std::string* Name, const std::string Linkage, Result += llvm::utostr(UniqueNameCounter); return Result; } else { - TypePlaneMap::iterator TPI = GI->second.find(Ty); + TypeInfo::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 @@ -748,8 +901,8 @@ std::string getGlobalName(const std::string* Name, const std::string Linkage, // 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(); + TypeInfo::TypePlaneMap::iterator TPI = GI->second.begin(); + TypeInfo::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 @@ -789,16 +942,25 @@ std::string getGlobalName(const std::string* Name, const std::string Linkage, // 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; + TypeInfo::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; + TypeInfo::Globals[*Name][Ty] = Result; return Result; } + +} // End anonymous namespace + +// This function is used by the Lexer to create a TypeInfo. It can't be +// in the anonymous namespace. +const TypeInfo* getTypeInfo(const std::string& newTy, Types oldTy) { + return TypeInfo::get(newTy, oldTy); +} + %} // %file-prefix="UpgradeParser" @@ -806,8 +968,8 @@ std::string getGlobalName(const std::string* Name, const std::string Linkage, %union { std::string* String; const TypeInfo* Type; - ValueInfo Value; - ConstInfo Const; + ValueInfo* Value; + ConstInfo* Const; ValueList* ValList; TypeList* TypeVec; } @@ -1079,105 +1241,120 @@ ArgTypeListI // ResolvedVal, ValueRef and ConstValueRef productions. // ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " [ " + *$3 + " ]"; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " [ " + *$3 + " ]"; delete $3; } | Types '[' ']' { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += "[ ]"; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += "[ ]"; } | Types 'c' STRINGCONSTANT { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " c" + *$3; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " c" + *$3; delete $3; } | Types '<' ConstVector '>' { // Nonempty unsized arr - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " < " + *$3 + " >"; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " < " + *$3 + " >"; delete $3; } | Types '{' ConstVector '}' { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " { " + *$3 + " }"; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " { " + *$3 + " }"; delete $3; } | Types '{' '}' { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " {}"; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " {}"; } | Types NULL_TOK { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | Types UNDEF { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | Types SymbolicValueRef { + $$ = new ConstInfo; std::string Name = getUniqueName($2, $1->resolve(), true); - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + Name; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + Name; delete $2; } | Types ConstExpr { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | Types ZEROINITIALIZER { - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | SIntType EInt64Val { // integral constants - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | UIntType EInt64Val { // integral constants - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | BOOL TRUETOK { // Boolean constants - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | BOOL FALSETOK { // Boolean constants - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; } | FPType FPVAL { // Float & Double constants - $$.type = $1; - $$.cnst = new std::string($1->getNewTy()); - *$$.cnst += " " + *$2; + $$ = new ConstInfo; + $$->type = $1; + $$->cnst = new std::string($1->getNewTy()); + *$$->cnst += " " + *$2; delete $2; }; - ConstExpr: CastOps '(' ConstVal TO Types ')' { - std::string source = *$3.cnst; - const TypeInfo* SrcTy = $3.type->resolve(); + std::string source = *$3->cnst; + const TypeInfo* SrcTy = $3->type->resolve(); const TypeInfo* DstTy = $5->resolve(); if (*$1 == "cast") { // Call getCastUpgrade to upgrade the old cast @@ -1187,73 +1364,73 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { $$ = new std::string(*$1); *$$ += "( " + source + " to " + $5->getNewTy() + ")"; } - delete $1; $3.destroy(); delete $4; + delete $1; delete $3; delete $4; } | GETELEMENTPTR '(' ConstVal IndexList ')' { - *$1 += "(" + *$3.cnst; + *$1 += "(" + *$3->cnst; for (unsigned i = 0; i < $4->size(); ++i) { - ValueInfo& VI = (*$4)[i]; - *$1 += ", " + *VI.val; - VI.destroy(); + ValueInfo* VI = (*$4)[i]; + *$1 += ", " + *VI->val; + delete VI; } *$1 += ")"; $$ = $1; - $3.destroy(); + delete $3; delete $4; } | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { - *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")"; - $3.destroy(); $5.destroy(); $7.destroy(); + *$1 += "(" + *$3->cnst + "," + *$5->cnst + "," + *$7->cnst + ")"; + delete $3; delete $5; delete $7; $$ = $1; } | ArithmeticOps '(' ConstVal ',' ConstVal ')' { - const char* op = getDivRemOpcode(*$1, $3.type); + const char* op = getDivRemOpcode(*$1, $3->type); $$ = new std::string(op); - *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")"; - delete $1; $3.destroy(); $5.destroy(); + *$$ += "(" + *$3->cnst + "," + *$5->cnst + ")"; + delete $1; delete $3; delete $5; } | LogicalOps '(' ConstVal ',' ConstVal ')' { - *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")"; - $3.destroy(); $5.destroy(); + *$1 += "(" + *$3->cnst + "," + *$5->cnst + ")"; + delete $3; delete $5; $$ = $1; } | SetCondOps '(' ConstVal ',' ConstVal ')' { - *$1 = getCompareOp(*$1, $3.type); - *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")"; - $3.destroy(); $5.destroy(); + *$1 = getCompareOp(*$1, $3->type); + *$1 += "(" + *$3->cnst + "," + *$5->cnst + ")"; + delete $3; delete $5; $$ = $1; } | ICMP IPredicates '(' ConstVal ',' ConstVal ')' { - *$1 += " " + *$2 + " (" + *$4.cnst + "," + *$6.cnst + ")"; - delete $2; $4.destroy(); $6.destroy(); + *$1 += " " + *$2 + " (" + *$4->cnst + "," + *$6->cnst + ")"; + delete $2; delete $4; delete $6; $$ = $1; } | FCMP FPredicates '(' ConstVal ',' ConstVal ')' { - *$1 += " " + *$2 + " (" + *$4.cnst + "," + *$6.cnst + ")"; - delete $2; $4.destroy(); $6.destroy(); + *$1 += " " + *$2 + " (" + *$4->cnst + "," + *$6->cnst + ")"; + delete $2; delete $4; delete $6; $$ = $1; } | ShiftOps '(' ConstVal ',' ConstVal ')' { const char* shiftop = $1->c_str(); if (*$1 == "shr") - shiftop = ($3.type->isUnsigned()) ? "lshr" : "ashr"; + shiftop = ($3->type->isUnsigned()) ? "lshr" : "ashr"; $$ = new std::string(shiftop); - *$$ += "(" + *$3.cnst + "," + *$5.cnst + ")"; - delete $1; $3.destroy(); $5.destroy(); + *$$ += "(" + *$3->cnst + "," + *$5->cnst + ")"; + delete $1; delete $3; delete $5; } | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { - *$1 += "(" + *$3.cnst + "," + *$5.cnst + ")"; - $3.destroy(); $5.destroy(); + *$1 += "(" + *$3->cnst + "," + *$5->cnst + ")"; + delete $3; delete $5; $$ = $1; } | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' { - *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")"; - $3.destroy(); $5.destroy(); $7.destroy(); + *$1 += "(" + *$3->cnst + "," + *$5->cnst + "," + *$7->cnst + ")"; + delete $3; delete $5; delete $7; $$ = $1; } | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' { - *$1 += "(" + *$3.cnst + "," + *$5.cnst + "," + *$7.cnst + ")"; - $3.destroy(); $5.destroy(); $7.destroy(); + *$1 += "(" + *$3->cnst + "," + *$5->cnst + "," + *$7->cnst + ")"; + delete $3; delete $5; delete $7; $$ = $1; }; @@ -1262,11 +1439,11 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' { ConstVector : ConstVector ',' ConstVal { - *$1 += ", " + *$3.cnst; - $3.destroy(); + *$1 += ", " + *$3->cnst; + delete $3; $$ = $1; } - | ConstVal { $$ = new std::string(*$1.cnst); $1.destroy(); } + | ConstVal { $$ = new std::string(*$1->cnst); delete $1; } ; @@ -1308,9 +1485,9 @@ External : EXTERNAL | UNINITIALIZED { $$ = $1; *$$ = "external"; } // ConstPool - Constants with optional names assigned to them. ConstPool : ConstPool OptAssign TYPE TypesV { - EnumeratedTypes.push_back($4); + TypeInfo::EnumeratedTypes.push_back($4); if (!$2->empty()) { - NamedTypes[*$2] = $4; + TypeInfo::NamedTypes[*$2] = $4; *O << *$2 << " = "; } *O << "type " << $4->getNewTy() << '\n'; @@ -1329,11 +1506,11 @@ ConstPool : ConstPool OptAssign TYPE TypesV { } | ConstPool OptAssign OptLinkage GlobalType ConstVal GlobalVarAttributes { if (!$2->empty()) { - std::string Name = getGlobalName($2,*$3, $5.type->getPointerType(), + std::string Name = getGlobalName($2,*$3, $5->type->getPointerType(), *$4 == "constant"); |