+++ /dev/null
-//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file was developed by Reid Spencer and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This header file defines the variables that are shared between the lexer,
-// the parser, and the main program.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef PARSER_INTERNALS_H
-#define PARSER_INTERNALS_H
-
-#include <llvm/ADT/StringExtras.h>
-#include <string>
-#include <istream>
-#include <vector>
-#include <cassert>
-
-// 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<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;
-extern unsigned SizeOfPointer;
-
-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.
-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;
- 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 {
- 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) {
- }
-
- TypeInfo(std::string *newType, Types oldType, TypeList* TL)
- : newTy(newType), oldTy(oldType), elemTy(0), resultTy(0), elements(TL),
- nelems(0) {
- }
-
- TypeInfo(std::string *newType, TypeInfo* resTy, TypeList* TL)
- : newTy(newType), oldTy(FunctionTy), elemTy(0), resultTy(resTy),
- elements(TL), nelems(0) {
- }
-
- TypeInfo(const TypeInfo& that)
- : newTy(0), oldTy(that.oldTy), elemTy(0), resultTy(0), elements(0),
- nelems(0) {
- *this = that;
- }
-
- 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;
- }
-
- ~TypeInfo() {
- delete newTy; delete elemTy; delete resultTy; delete elements;
- }
-
- TypeInfo* clone() const {
- return new TypeInfo(*this);
- }
-
- Types getElementTy() const {
- if (elemTy) {
- return elemTy->oldTy;
- }
- return UnresolvedTy;
- }
-
- const std::string& getNewTy() const { return *newTy; }
- void setOldTy(Types Ty) { oldTy = Ty; }
-
- TypeInfo* getResultType() const { return resultTy; }
- TypeInfo* getElementType() const { return elemTy; }
-
- TypeInfo* getPointerType() const {
- std::string* ty = new std::string(*newTy + "*");
- return new TypeInfo(ty, PointerTy, this->clone(), (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;
- }
-
- 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;
- }
- }
- }
-
- 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 getNumStructElements() const {
- return (elements ? elements->size() : 0);
- }
-
- TypeInfo* getElement(unsigned idx) {
- if (elements)
- if (idx < elements->size())
- return (*elements)[idx];
- return 0;
- }
-
-private:
- std::string* newTy;
- Types oldTy;
- TypeInfo *elemTy;
- TypeInfo *resultTy;
- TypeList *elements;
- uint64_t nelems;
-};
-
-/// This type is used to keep track of the signedness of constants.
-struct ConstInfo {
- std::string *cnst;
- TypeInfo *type;
- void destroy() { delete cnst; }
-};
-
-typedef std::vector<ValueInfo> ValueList;
-
-inline void ValueInfo::destroy() { delete val; }
-
-#endif
--- /dev/null
+//===-- UpgradeInternals.h - Internal parser definitionsr -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines the variables that are shared between the lexer,
+// the parser, and the main program.
+//
+//===----------------------------------------------------------------------===//
+
+#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...
+
+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...
+extern char* Upgradetext;
+extern int Upgradeleng;
+extern unsigned SizeOfPointer;
+
+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.
+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
+ }
+
+ 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;
+
+inline void ValueInfo::destroy() { delete val; }
+
+#endif
//===----------------------------------------------------------------------===//
%{
-#include "ParserInternals.h"
+#include "UpgradeInternals.h"
#include <algorithm>
#include <map>
#include <utility>
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()) {
}
}
-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(
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;
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
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() + ")";
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")
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");
// 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();
}
}
// 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++;
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;
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() + "(");
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("{");
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("<{");
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();
: 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*/ {
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;
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);
// 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';
}
| 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;
}
| 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");
*O << Name << " = ";
- Globals[Name] = *$5;
}
*O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
delete $2; delete $3; delete $4; delete $6;
$$ = 0;
}
- | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
+ | ConstPool OptAssign DLLIMPORT GlobalType Types GlobalVarAttributes {
if (!$2->empty()) {
- std::string Name = getUniqueName($2,$5);
+ std::string Name = getGlobalName($2,*$3,$5->getPointerType(),
+ *$4 == "constant");
*O << Name << " = ";
- Globals[Name] = *$5;
}
*O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
delete $2; delete $3; delete $4; delete $6;
}
| ConstPool OptAssign EXTERN_WEAK GlobalType Types GlobalVarAttributes {
if (!$2->empty()) {
- std::string Name = getUniqueName($2,$5);
+ std::string Name = getGlobalName($2,*$3,$5->getPointerType(),
+ *$4 == "constant");
*O << Name << " = ";
- Globals[Name] = *$5;
}
*O << *$3 << ' ' << *$4 << ' ' << $5->getNewTy() << ' ' << *$6 << '\n';
delete $2; delete $3; delete $4; delete $6;
ArgVal : Types OptName {
$$ = new std::string($1->getNewTy());
if (!$2->empty()) {
- std::string Name = getUniqueName($2, $1);
+ std::string Name = getUniqueName($2, $1->resolve());
*$$ += " " + Name;
}
delete $2;
: SymbolicValueRef {
$$.val = $1;
$$.constant = false;
- $$.type = new TypeInfo();
+ $$.type = 0;
}
| ConstValueRef {
$$.val = $1;
$$.constant = true;
- $$.type = new TypeInfo();
+ $$.type = 0;
}
;
// type immediately preceeds the value reference, and allows complex constant
// pool references (for things like: 'ret [2 x int] [ int 12, int 42]')
ResolvedVal : Types ValueRef {
- ResolveType($1);
+ $1 = $1->resolve();
std::string Name = getUniqueName($2.val, $1);
$$ = $2;
delete $$.val;
- delete $$.type;
$$.val = new std::string($1->getNewTy() + " " + Name);
$$.type = $1;
};
}
| RET VOID { // Return with no result...
*O << " " << *$1 << ' ' << $2->getNewTy() << '\n';
- delete $1; delete $2;
+ delete $1;
$$ = 0;
}
| BR LABEL ValueRef { // Unconditional Branch...
*O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << *$3.val << '\n';
- delete $1; delete $2; $3.destroy();
+ delete $1; $3.destroy();
$$ = 0;
} // Conditional Branch...
| BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef {
*O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
<< $5->getNewTy() << ' ' << *$6.val << ", " << $8->getNewTy() << ' '
<< *$9.val << '\n';
- delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
- delete $8; $9.destroy();
+ delete $1; $3.destroy(); $6.destroy(); $9.destroy();
$$ = 0;
}
| SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' {
std::string Name = getUniqueName($3.val, $2);
*O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
<< $5->getNewTy() << ' ' << *$6.val << " [" << *$8 << " ]\n";
- delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
+ delete $1; $3.destroy(); $6.destroy();
delete $8;
$$ = 0;
}
std::string Name = getUniqueName($3.val, $2);
*O << " " << *$1 << ' ' << $2->getNewTy() << ' ' << Name << ", "
<< $5->getNewTy() << ' ' << *$6.val << "[]\n";
- delete $1; delete $2; $3.destroy(); delete $5; $6.destroy();
+ delete $1; $3.destroy(); $6.destroy();
$$ = 0;
}
| OptAssign INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')'
TO LABEL ValueRef Unwind LABEL ValueRef {
- TypeInfo* ResTy = getFunctionReturnType($4);
+ const TypeInfo* ResTy = getFunctionReturnType($4);
*O << " ";
if (!$1->empty()) {
std::string Name = getUniqueName($1, ResTy);
}
*O << ") " << *$9 << ' ' << $10->getNewTy() << ' ' << *$11.val << ' '
<< *$12 << ' ' << $13->getNewTy() << ' ' << *$14.val << '\n';
- delete $1; delete $2; delete $3; delete $4; $5.destroy(); delete $7;
- delete $9; delete $10; $11.destroy(); delete $12; delete $13;
- $14.destroy();
+ delete $1; delete $2; delete $3; $5.destroy(); delete $7;
+ delete $9; $11.destroy(); delete $12; $14.destroy();
$$ = 0;
}
| Unwind {
JumpTable : JumpTable IntType ConstValueRef ',' LABEL ValueRef {
*$1 += " " + $2->getNewTy() + " " + *$3 + ", " + $5->getNewTy() + " " +
*$6.val;
- delete $2; delete $3; delete $5; $6.destroy();
+ delete $3; $6.destroy();
$$ = $1;
}
| IntType ConstValueRef ',' LABEL ValueRef {
$2->insert(0, $1->getNewTy() + " " );
*$2 += ", " + $4->getNewTy() + " " + *$5.val;
- delete $1; delete $4; $5.destroy();
+ $5.destroy();
$$ = $2;
};
Inst
: OptAssign InstVal {
if (!$1->empty()) {
- if (deleteUselessCastFlag && *deleteUselessCastName == *$1) {
- *$1 += " = ";
- $1->insert(0, "; "); // don't actually delete it, just comment it out
+ // Get a unique name for this value, based on its type.
+ std::string Name = getUniqueName($1, $2.type);
+ *$1 = Name + " = ";
+ if (deleteUselessCastFlag && *deleteUselessCastName == Name) {
+ // don't actually delete it, just comment it out
+ $1->insert(0, "; USELSS BITCAST: ");
delete deleteUselessCastName;
- } else {
- // Get a unique name for the name of this value, based on its type.
- *$1 = getUniqueName($1, $2.type) + " = ";
}
}
*$1 += *$2.val;
*$1 = getCompareOp(*$1, $2);
*$1 += " " + $2->getNewTy() + " " + Name1 + ", " + Name2;
$$.val = $1;
- $$.type = new TypeInfo("bool",BoolTy);
+ $$.type = TypeInfo::get("bool",BoolTy);
$3.destroy(); $5.destroy();
}
| ICMP IPredicates Types ValueRef ',' ValueRef {
std::string Name2 = getUniqueName($6.val, $3);
*$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
$$.val = $1;
- $$.type = new TypeInfo("bool",BoolTy);
+ $$.type = TypeInfo::get("bool",BoolTy);
delete $2; $4.destroy(); $6.destroy();
}
| FCMP FPredicates Types ValueRef ',' ValueRef {
std::string Name2 = getUniqueName($6.val, $3);
*$1 += " " + *$2 + " " + $3->getNewTy() + " " + Name1 + "," + Name2;
$$.val = $1;
- $$.type = new TypeInfo("bool",BoolTy);
+ $$.type = TypeInfo::get("bool",BoolTy);
delete $2; $4.destroy(); $6.destroy();
}
| NOT ResolvedVal {
}
| CastOps ResolvedVal TO Types {
std::string source = *$2.val;
- TypeInfo* SrcTy = $2.type;
- TypeInfo* DstTy = ResolveType($4);
+ const TypeInfo* SrcTy = $2.type->resolve();
+ const TypeInfo* DstTy = $4->resolve();
$$.val = new std::string();
+ $$.type = DstTy;
if (*$1 == "cast") {
- *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
+ *$$.val += getCastUpgrade(source, SrcTy, DstTy, false);
} else {
*$$.val += *$1 + " " + source + " to " + DstTy->getNewTy();
}
- $$.type = $4;
// Check to see if this is a useless cast of a value to the same name
// and the same type. Such casts will probably cause redefinition errors
// when assembled and perform no code gen action so just remove them.
if (*$1 == "cast" || *$1 == "bitcast")
- if ($2.type->isInteger() && DstTy->isInteger() &&
- $2.type->getBitWidth() == DstTy->getBitWidth()) {
+ if (SrcTy->isInteger() && DstTy->isInteger() &&
+ SrcTy->getBitWidth() == DstTy->getBitWidth()) {
deleteUselessCastFlag = true; // Flag the "Inst" rule
deleteUselessCastName = new std::string(*$2.val); // save the name
size_t pos = deleteUselessCastName->find_first_of("%\"",0);
| EXTRACTELEMENT ResolvedVal ',' ResolvedVal {
*$1 += " " + *$2.val + ", " + *$4.val;
$$.val = $1;
- ResolveType($2.type);
+ $2.type = $2.type->resolve();;
$$.type = $2.type->getElementType();
delete $2.val; $4.destroy();
}
*$1 += ")";
$$.val = $1;
$$.type = getFunctionReturnType($3);
- delete $2; delete $3; $4.destroy(); delete $6;
+ delete $2; $4.destroy(); delete $6;
}
| MemoryInst ;
*$1 += " " + *$3;
$$.val = $1;
$$.type = $2->getPointerType();
- delete $2; delete $3;
+ delete $3;
}
| MALLOC Types ',' UINT ValueRef OptCAlign {
std::string Name = getUniqueName($5.val, $4);
*$1 += " " + *$6;
$$.val = $1;
$$.type = $2->getPointerType();
- delete $2; delete $4; $5.destroy(); delete $6;
+ $5.destroy(); delete $6;
}
| ALLOCA Types OptCAlign {
*$1 += " " + $2->getNewTy();
*$1 += " " + *$3;
$$.val = $1;
$$.type = $2->getPointerType();
- delete $2; delete $3;
+ delete $3;
}
| ALLOCA Types ',' UINT ValueRef OptCAlign {
std::string Name = getUniqueName($5.val, $4);
*$1 += " " + *$6;
$$.val = $1;
$$.type = $2->getPointerType();
- delete $2; delete $4; $5.destroy(); delete $6;
+ $5.destroy(); delete $6;
}
| FREE ResolvedVal {
*$1 += " " + *$2.val;
$$.val = $1;
- $$.type = new TypeInfo("void", VoidTy);
+ $$.type = TypeInfo::get("void", VoidTy);
$2.destroy();
}
| OptVolatile LOAD Types ValueRef {
*$1 += " ";
*$1 += *$2 + " " + $3->getNewTy() + " " + Name;
$$.val = $1;
- $$.type = $3->getElementType()->clone();
- delete $2; delete $3; $4.destroy();
+ $$.type = $3->getElementType();
+ delete $2; $4.destroy();
}
| OptVolatile STORE ResolvedVal ',' Types ValueRef {
std::string Name = getUniqueName($6.val, $5);
*$1 += " ";
*$1 += *$2 + " " + *$3.val + ", " + $5->getNewTy() + " " + Name;
$$.val = $1;
- $$.type = new TypeInfo("void", VoidTy);
- delete $2; $3.destroy(); delete $5; $6.destroy();
+ $$.type = TypeInfo::get("void", VoidTy);
+ delete $2; $3.destroy(); $6.destroy();
}
| GETELEMENTPTR Types ValueRef IndexList {
std::string Name = getUniqueName($3.val, $2);
*O << " %gep_upgrade" << unique << " = zext " << *old
<< " to i64\n";
VI.val = new std::string("i64 %gep_upgrade" + llvm::utostr(unique++));
- VI.type->setOldTy(ULongTy);
+ VI.type = TypeInfo::get("i64",ULongTy);
}
}
*$1 += " " + $2->getNewTy() + " " + Name;
std::string where
= std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
- std::string errMsg = std::string(ErrorMsg) + "\n" + where + " while reading ";
+ std::string errMsg = where + "error: " + std::string(ErrorMsg) +
+ " while reading ";
if (yychar == YYEMPTY || yychar == 0)
errMsg += "end-of-file.";
else
*O << "llvm-upgrade parse failed.\n";
exit(1);
}
+
+static void warning(const std::string& ErrorMsg) {
+ std::string where
+ = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename)
+ + ":" + llvm::utostr((unsigned) Upgradelineno) + ": ";
+ std::string errMsg = where + "warning: " + std::string(ErrorMsg) +
+ " while reading ";
+ if (yychar == YYEMPTY || yychar == 0)
+ errMsg += "end-of-file.";
+ else
+ errMsg += "token: '" + std::string(Upgradetext, Upgradeleng) + "'";
+ std::cerr << "llvm-upgrade: " << errMsg << '\n';
+}