diff options
Diffstat (limited to 'tools/llvm-upgrade/ParserInternals.h')
-rw-r--r-- | tools/llvm-upgrade/ParserInternals.h | 173 |
1 files changed, 146 insertions, 27 deletions
diff --git a/tools/llvm-upgrade/ParserInternals.h b/tools/llvm-upgrade/ParserInternals.h index 85182c5dc1..9de3588f8c 100644 --- a/tools/llvm-upgrade/ParserInternals.h +++ b/tools/llvm-upgrade/ParserInternals.h @@ -15,9 +15,11 @@ #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... @@ -26,11 +28,15 @@ 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; @@ -47,6 +53,17 @@ enum Types { OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, NumericTy }; +/// 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 @@ -55,20 +72,89 @@ enum Types { /// 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 { - std::string* newTy; - Types oldTy; - Types elemTy; + 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; + } - void destroy() const { delete newTy; } + ~TypeInfo() { + delete newTy; delete elemTy; delete resultTy; delete elements; + } - TypeInfo clone() const { - TypeInfo result = *this; - result.newTy = new std::string(*newTy); - return result; + TypeInfo* clone() const { + return new TypeInfo(*this); } - Types getElementType() const { return elemTy; } + 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 isNumeric() const { return oldTy == NumericTy; } + bool isVoid() const { return oldTy == VoidTy; } + bool isBool() const { return oldTy == BoolTy; } bool isSigned() const { return oldTy == SByteTy || oldTy == ShortTy || oldTy == IntTy || oldTy == LongTy; @@ -79,9 +165,6 @@ struct TypeInfo { oldTy == UIntTy || oldTy == ULongTy; } - bool isBool() const { - return oldTy == BoolTy; - } bool isSignless() const { return !isSigned() && !isUnsigned(); } bool isInteger() const { return isSigned() || isUnsigned(); } @@ -89,8 +172,14 @@ struct TypeInfo { 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; @@ -98,6 +187,7 @@ struct TypeInfo { unsigned getBitWidth() const { switch (oldTy) { + default: case LabelTy: case VoidTy : return 0; case BoolTy : return 1; @@ -106,32 +196,61 @@ struct TypeInfo { case IntTy: case UIntTy: case FloatTy: return 32; case LongTy: case ULongTy: case DoubleTy : return 64; case PointerTy: return SizeOfPointer; // global var - default: - return 128; /// Struct/Packed/Array --> doesn't matter - + 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; + } } } -}; -/// 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; } - void destroy() { delete val; type.destroy(); } + 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; + } + +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; type.destroy(); } + TypeInfo *type; + void destroy() { delete cnst; delete type; } }; typedef std::vector<ValueInfo> ValueList; +inline void ValueInfo::destroy() { delete val; delete type; } #endif |