diff options
-rw-r--r-- | tools/llvm-upgrade/UpgradeInternals.h | 300 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeLexer.l | 479 | ||||
-rw-r--r-- | tools/llvm-upgrade/UpgradeParser.y | 4628 |
3 files changed, 3459 insertions, 1948 deletions
diff --git a/tools/llvm-upgrade/UpgradeInternals.h b/tools/llvm-upgrade/UpgradeInternals.h index f01d415f6b..4fe0ed0756 100644 --- a/tools/llvm-upgrade/UpgradeInternals.h +++ b/tools/llvm-upgrade/UpgradeInternals.h @@ -1,65 +1,279 @@ -//===-- UpgradeInternals.h - Internal parser definitionsr -------*- C++ -*-===// +//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===// // // The LLVM Compiler Infrastructure // -// This file was developed by Reid Spencer and is distributed under +// This file was developed by the LLVM research group 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. +// This header file defines the various variables that are shared among the +// different components of the parser... // //===----------------------------------------------------------------------===// -#ifndef UPGRADE_INTERNALS_H -#define UPGRADE_INTERNALS_H +#ifndef PARSER_INTERNALS_H +#define PARSER_INTERNALS_H + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/Instructions.h" +#include "llvm/ADT/StringExtras.h" +#include <list> -#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 yydebug; +extern void error(const std::string& msg, int line = -1); +extern char* Upgradetext; +extern int Upgradeleng; extern int Upgradelineno; + +namespace llvm { + + +class Module; +Module* UpgradeAssembly(const std::string &infile, std::istream& in, + bool debug, bool addAttrs); + + +class SignedType : public IntegerType { + const IntegerType *base_type; + static SignedType *SByteTy; + static SignedType *SShortTy; + static SignedType *SIntTy; + static SignedType *SLongTy; + SignedType(const IntegerType* ITy); +public: + static const SignedType *get(const IntegerType* ITy); + + bool isSigned() const { return true; } + const IntegerType* getBaseType() const { + return base_type; + } + const IntegerType* resolve() const { + ForwardType = base_type; + return base_type; + } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SignedType *T) { return true; } + static inline bool classof(const Type *T); +}; + extern std::istream* LexInput; -// 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. The Lexer uses thse in its -/// calls to getType -enum TypeIDs { - BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy, - FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, PackedStructTy, - OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, UpRefTy +// UnEscapeLexed - Run through the specified buffer and change \xx codes to the +// appropriate character. If AllowNull is set to false, a \00 value will cause +// an error. +// +// If AllowNull is set to true, the return value of the function points to the +// last character of the string in memory. +// +char *UnEscapeLexed(char *Buffer, bool AllowNull = false); + +/// InlineAsmDescriptor - This is a simple class that holds info about inline +/// asm blocks, for use by ValID. +struct InlineAsmDescriptor { + std::string AsmString, Constraints; + bool HasSideEffects; + + InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE) + : AsmString(as), Constraints(c), HasSideEffects(HSE) {} +}; + + +// ValID - Represents a reference of a definition of some sort. This may either +// be a numeric reference or a symbolic (%var) reference. This is just a +// discriminated union. +// +// Note that I can't implement this class in a straight forward manner with +// constructors and stuff because it goes in a union. +// +struct ValID { + enum { + NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal, + ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal + } Type; + + union { + int Num; // If it's a numeric reference + char *Name; // If it's a named reference. Memory must be free'd. + int64_t ConstPool64; // Constant pool reference. This is the value + uint64_t UConstPool64;// Unsigned constant pool reference. + double ConstPoolFP; // Floating point constant pool reference + Constant *ConstantValue; // Fully resolved constant for ConstantVal case. + InlineAsmDescriptor *IAD; + }; + + static ValID create(int Num) { + ValID D; D.Type = NumberVal; D.Num = Num; return D; + } + + static ValID create(char *Name) { + ValID D; D.Type = NameVal; D.Name = Name; return D; + } + + static ValID create(int64_t Val) { + ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; return D; + } + + static ValID create(uint64_t Val) { + ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D; + } + + static ValID create(double Val) { + ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D; + } + + static ValID createNull() { + ValID D; D.Type = ConstNullVal; return D; + } + + static ValID createUndef() { + ValID D; D.Type = ConstUndefVal; return D; + } + + static ValID createZeroInit() { + ValID D; D.Type = ConstZeroVal; return D; + } + + static ValID create(Constant *Val) { + ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D; + } + + static ValID createInlineAsm(const std::string &AsmString, + const std::string &Constraints, + bool HasSideEffects) { + ValID D; + D.Type = InlineAsmVal; + D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects); + return D; + } + + inline void destroy() const { + if (Type == NameVal) + free(Name); // Free this strdup'd memory. + else if (Type == InlineAsmVal) + delete IAD; + } + + inline ValID copy() const { + if (Type != NameVal) return *this; + ValID Result = *this; + Result.Name = strdup(Name); + return Result; + } + + inline std::string getName() const { + switch (Type) { + case NumberVal : return std::string("#") + itostr(Num); + case NameVal : return Name; + case ConstFPVal : return ftostr(ConstPoolFP); + case ConstNullVal : return "null"; + case ConstUndefVal : return "undef"; + case ConstZeroVal : return "zeroinitializer"; + case ConstUIntVal : + case ConstSIntVal : return std::string("%") + itostr(ConstPool64); + case ConstantVal: + if (ConstantValue == ConstantInt::get(Type::Int1Ty, true)) + return "true"; + if (ConstantValue == ConstantInt::get(Type::Int1Ty, false)) + return "false"; + return "<constant expression>"; + default: + assert(0 && "Unknown value!"); + abort(); + return ""; + } + } + + bool operator<(const ValID &V) const { + if (Type != V.Type) return Type < V.Type; + switch (Type) { + case NumberVal: return Num < V.Num; + case NameVal: return strcmp(Name, V.Name) < 0; + case ConstSIntVal: return ConstPool64 < V.ConstPool64; + case ConstUIntVal: return UConstPool64 < V.UConstPool64; + case ConstFPVal: return ConstPoolFP < V.ConstPoolFP; + case ConstNullVal: return false; + case ConstUndefVal: return false; + case ConstZeroVal: return false; + case ConstantVal: return ConstantValue < V.ConstantValue; + default: assert(0 && "Unknown value type!"); return false; + } + } }; -namespace { -class Type; -class Value; -class Constant; -class Instruction; -} -typedef std::vector<const Type*> TypeList; -typedef std::vector<Value*> ValueList; +// This structure is used to keep track of obsolete opcodes. The lexer will +// retain the ability to parse obsolete opcode mnemonics. In this case it will +// set "obsolete" to true and the opcode will be the replacement opcode. For +// example if "rem" is encountered then opcode will be set to "urem" and the +// "obsolete" flag will be true. If the opcode is not obsolete then "obsolete" +// will be false. + +enum TermOps { + RetOp, BrOp, SwitchOp, InvokeOp, UnwindOp, UnreachableOp +}; + +enum BinaryOps { + AddOp, SubOp, MulOp, + DivOp, UDivOp, SDivOp, FDivOp, + RemOp, URemOp, SRemOp, FRemOp, + AndOp, OrOp, XorOp, + SetEQ, SetNE, SetLE, SetGE, SetLT, SetGT +}; + +enum MemoryOps { + MallocOp, FreeOp, AllocaOp, LoadOp, StoreOp, GetElementPtrOp +}; + +enum OtherOps { + PHIOp, CallOp, ShlOp, ShrOp, SelectOp, UserOp1, UserOp2, VAArg, + ExtractElementOp, InsertElementOp, ShuffleVectorOp, + ICmpOp, FCmpOp, + LShrOp, AShrOp +}; + +enum CastOps { + CastOp, TruncOp, ZExtOp, SExtOp, FPTruncOp, FPExtOp, FPToUIOp, FPToSIOp, + UIToFPOp, SIToFPOp, PtrToIntOp, IntToPtrOp, BitCastOp +}; + +enum Signedness { Signless, Unsigned, Signed }; + +struct TypeInfo { + const llvm::Type *T; + Signedness S; +}; + +struct PATypeInfo { + llvm::PATypeHolder* T; + Signedness S; +}; + +struct ConstInfo { + llvm::Constant* C; + Signedness S; +}; + +struct ValueInfo { + llvm::Value* V; + Signedness S; +}; + +struct InstrInfo { + llvm::Instruction *I; + Signedness S; +}; + +struct PHIListInfo { + std::list<std::pair<llvm::Value*, llvm::BasicBlock*> > *P; + Signedness S; +}; -/// A function to create a Typeo* used in the Lexer. -extern const Type* getType(const std::string& newTy, TypeIDs oldTy); +} // End llvm namespace #endif diff --git a/tools/llvm-upgrade/UpgradeLexer.l b/tools/llvm-upgrade/UpgradeLexer.l index d58f461548..0105e26ae3 100644 --- a/tools/llvm-upgrade/UpgradeLexer.l +++ b/tools/llvm-upgrade/UpgradeLexer.l @@ -25,8 +25,9 @@ %option noyymore %{ - #include "UpgradeInternals.h" +#include "llvm/Module.h" +#include <list> #include "UpgradeParser.h" #include <cctype> #include <cstdlib> @@ -41,17 +42,108 @@ } \ } +#define YY_NEVER_INTERACTIVE 1 // Construct a token value for a non-obsolete token -#define RET_TOK(sym) \ - Upgradelval.String = new std::string(yytext); \ +#define RET_TOK(type, Enum, sym) \ + Upgradelval.type = Enum; \ return sym -#define RET_TY(sym,OldTY,NewTY,sign) \ - Upgradelval.Ty = getType(NewTY, OldTY); \ +#define RET_TY(sym,NewTY,sign) \ + Upgradelval.PrimType.T = NewTY; \ + Upgradelval.PrimType.S = sign; \ return sym -#define YY_NEVER_INTERACTIVE 1 +namespace llvm { + +// TODO: All of the static identifiers are figured out by the lexer, +// these should be hashed to reduce the lexer size + +// UnEscapeLexed - Run through the specified buffer and change \xx codes to the +// appropriate character. If AllowNull is set to false, a \00 value will cause +// an exception to be thrown. +// +// If AllowNull is set to true, the return value of the function points to the +// last character of the string in memory. +// +char *UnEscapeLexed(char *Buffer, bool AllowNull) { + char *BOut = Buffer; + for (char *BIn = Buffer; *BIn; ) { + if (BIn[0] == '\\' && isxdigit(BIn[1]) && isxdigit(BIn[2])) { + char Tmp = BIn[3]; BIn[3] = 0; // Terminate string + *BOut = (char)strtol(BIn+1, 0, 16); // Convert to number + if (!AllowNull && !*BOut) + error("String literal cannot accept \\00 escape!"); + + BIn[3] = Tmp; // Restore character + BIn += 3; // Skip over handled chars + ++BOut; + } else { + *BOut++ = *BIn++; + } + } + + return BOut; +} + +// atoull - Convert an ascii string of decimal digits into the unsigned long +// long representation... this does not have to do input error checking, +// because we know that the input will be matched by a suitable regex... +// +static uint64_t atoull(const char *Buffer) { + uint64_t Result = 0; + for (; *Buffer; Buffer++) { + uint64_t OldRes = Result; + Result *= 10; + Result += *Buffer-'0'; + if (Result < OldRes) // Uh, oh, overflow detected!!! + error("constant bigger than 64 bits detected!"); + } + return Result; +} + +static uint64_t HexIntToVal(const char *Buffer) { + uint64_t Result = 0; + for (; *Buffer; ++Buffer) { + uint64_t OldRes = Result; + Result *= 16; + char C = *Buffer; + if (C >= '0' && C <= '9') + Result += C-'0'; + else if (C >= 'A' && C <= 'F') + Result += C-'A'+10; + else if (C >= 'a' && C <= 'f') + Result += C-'a'+10; + + if (Result < OldRes) // Uh, oh, overflow detected!!! + error("constant bigger than 64 bits detected!"); + } + return Result; +} + + +// HexToFP - Convert the ascii string in hexidecimal format to the floating +// point representation of it. +// +static double HexToFP(const char *Buffer) { + // Behave nicely in the face of C TBAA rules... see: + // http://www.nullstone.com/htmls/category/aliastyp.htm + union { + uint64_t UI; + double FP; + } UIntToFP; + UIntToFP.UI = HexIntToVal(Buffer); + + assert(sizeof(double) == sizeof(uint64_t) && + "Data sizes incompatible on this target!"); + return UIntToFP.FP; // Cast Hex constant to double +} + + +} // End llvm namespace + +using namespace llvm; + %} @@ -98,168 +190,219 @@ HexIntConstant [us]0x[0-9A-Fa-f]+ {Comment} { /* Ignore comments for now */ } -begin { RET_TOK( BEGINTOK); } -end { RET_TOK( ENDTOK); } -true { RET_TOK( TRUETOK); } -false { RET_TOK( FALSETOK); } -declare { RET_TOK( DECLARE); } -global { RET_TOK( GLOBAL); } -constant { RET_TOK( CONSTANT); } -internal { RET_TOK( INTERNAL); } -linkonce { RET_TOK( LINKONCE); } -weak { RET_TOK( WEAK); } -appending { RET_TOK( APPENDING); } -dllimport { RET_TOK( DLLIMPORT); } -dllexport { RET_TOK( DLLEXPORT); } -extern_weak { RET_TOK( EXTERN_WEAK); } -external { RET_TOK( EXTERNAL); } -uninitialized { RET_TOK( UNINITIALIZED); } // alias for external -implementation { RET_TOK( IMPLEMENTATION); } -zeroinitializer { RET_TOK( ZEROINITIALIZER); } -\.\.\. { RET_TOK( DOTDOTDOT); } -undef { RET_TOK( UNDEF); } -null { RET_TOK( NULL_TOK); } -to { RET_TOK( TO); } -tail { RET_TOK( TAIL); } -target { RET_TOK( TARGET); } -triple { RET_TOK( TRIPLE); } -deplibs { RET_TOK( DEPLIBS); } -endian { RET_TOK( ENDIAN); } -pointersize { RET_TOK( POINTERSIZE); } -datalayout { RET_TOK( DATALAYOUT); } -little { RET_TOK( LITTLE); } -big { RET_TOK( BIG); } -volatile { RET_TOK( VOLATILE); } -align { RET_TOK( ALIGN); } -section { RET_TOK( SECTION); } -module { RET_TOK( MODULE); } -asm { RET_TOK( ASM_TOK); } -sideeffect { RET_TOK( SIDEEFFECT); } - -cc { RET_TOK( CC_TOK); } -ccc { RET_TOK( CCC_TOK); } -csretcc { RET_TOK( CSRETCC_TOK); } -fastcc { RET_TOK( FASTCC_TOK); } -coldcc { RET_TOK( COLDCC_TOK); } -x86_stdcallcc { RET_TOK( X86_STDCALLCC_TOK); } -x86_fastcallcc { RET_TOK( X86_FASTCALLCC_TOK); } - -void { RET_TY(VOID,VoidTy,"void",false); } -bool { RET_TY(BOOL,BoolTy,"i1",false); } -sbyte { RET_TY(SBYTE,SByteTy,"i8",true); } -ubyte { RET_TY(UBYTE,UByteTy,"i8",false); } -short { RET_TY(SHORT,ShortTy,"i16",true); } -ushort { RET_TY(USHORT,UShortTy,"i16",false); } -int { RET_TY(INT,IntTy,"i32",true); } -uint { RET_TY(UINT,UIntTy,"i32",false); } -long { RET_TY(LONG,LongTy,"i64",true); } -ulong { RET_TY(ULONG,ULongTy,"i64",false); } -i8 { RET_TY(UBYTE,UByteTy,"i8",false); } -i16 { RET_TY(USHORT,UShortTy,"i16",false); } -i32 { RET_TY(UINT,UIntTy,"i32",false); } -i64 { RET_TY(ULONG,ULongTy,"i64",false); } -float { RET_TY(FLOAT,FloatTy,"float",false); } -double { RET_TY(DOUBLE,DoubleTy,"double",false); } -label { RET_TY(LABEL,LabelTy,"label",false); } -opaque { RET_TOK(OPAQUE); } -type { RET_TOK(TYPE); } - -add { RET_TOK( ADD); } -sub { RET_TOK( SUB); } -mul { RET_TOK( MUL); } -div { RET_TOK( DIV); } -udiv { RET_TOK( UDIV); } -sdiv { RET_TOK( SDIV); } -fdiv { RET_TOK( FDIV); } -rem { RET_TOK( REM); } -urem { RET_TOK( UREM); } -srem { RET_TOK( SREM); } -frem { RET_TOK( FREM); } -and { RET_TOK( AND); } -or { RET_TOK( OR); } -xor { RET_TOK( XOR); } -setne { RET_TOK( SETNE); } -seteq { RET_TOK( SETEQ); } -setlt { RET_TOK( SETLT); } -setgt { RET_TOK( SETGT); } -setle { RET_TOK( SETLE); } -setge { RET_TOK( SETGE); } -icmp { RET_TOK(ICMP); } -fcmp { RET_TOK(FCMP); } -eq { RET_TOK(EQ); } -ne { RET_TOK(NE); } -slt { RET_TOK(SLT); } -sgt { RET_TOK(SGT); } -sle { RET_TOK(SLE); } -sge { RET_TOK(SGE); } -oeq { RET_TOK(OEQ); } -one { RET_TOK(ONE); } -olt { RET_TOK(OLT); } -ogt { RET_TOK(OGT); } -ole { RET_TOK(OLE); } -oge { RET_TOK(OGE); } -ord { RET_TOK(ORD); } -uno { RET_TOK(UNO); } -ueq { RET_TOK(UEQ); } -une { RET_TOK(UNE); } -ult { RET_TOK(ULT); } -ugt { RET_TOK(UGT); } -ule { RET_TOK(ULE); } -uge { RET_TOK(UGE); } - -phi { RET_TOK( PHI_TOK); } -call { RET_TOK( CALL); } -cast { RET_TOK( CAST); } -trunc { RET_TOK( TRUNC); } -zext { RET_TOK( ZEXT); } -sext { RET_TOK( SEXT); } -fptrunc { RET_TOK( FPTRUNC); } -fpext { RET_TOK( FPEXT); } -fptoui { RET_TOK( FPTOUI); } -fptosi { RET_TOK( FPTOSI); } -uitofp { RET_TOK( UITOFP); } -sitofp { RET_TOK( SITOFP); } -ptrtoint { RET_TOK( PTRTOINT); } -inttoptr { RET_TOK( INTTOPTR); } -bitcast { RET_TOK( BITCAST); } -select { RET_TOK( SELECT); } -shl { RET_TOK( SHL); } -shr { RET_TOK( SHR); } -ashr { RET_TOK( ASHR); } -lshr { RET_TOK( LSHR); } -va_arg { RET_TOK( VAARG); } -ret { RET_TOK( RET); } -br { RET_TOK( BR); } -switch { RET_TOK( SWITCH); } -invoke { RET_TOK( INVOKE); } -unwind { RET_TOK( UNWIND); } -except { RET_TOK( EXCEPT); } // alias for unwind -unreachable { RET_TOK( UNREACHABLE); } - -malloc { RET_TOK( MALLOC); } -alloca { RET_TOK( ALLOCA); } -free { RET_TOK( FREE); } -load { RET_TOK( LOAD); } -store { RET_TOK( STORE); } -getelementptr { RET_TOK( GETELEMENTPTR); } - -extractelement { RET_TOK( EXTRACTELEMENT); } -insertelement { RET_TOK( INSERTELEMENT); } -shufflevector { RET_TOK( SHUFFLEVECTOR); } - - -{VarID} { RET_TOK( VAR_ID); } -{Label} { RET_TOK( LABELSTR); } -{QuoteLabel} { RET_TOK( LABELSTR); } -{StringConstant} { RET_TOK( STRINGCONSTANT ); } -{PInteger} { RET_TOK( EUINT64VAL ); } -{NInteger} { RET_TOK( ESINT64VAL ); } -{HexIntConstant} { RET_TOK( yytext[0] == 's' ? ESINT64VAL : EUINT64VAL ); } -{EPInteger} { RET_TOK( UINTVAL); } -{ENInteger} { RET_TOK( SINTVAL); } -{FPConstant} { RET_TOK( FPVAL); } -{HexFPConstant} { RET_TOK( FPVAL); } -<<EOF>> { +begin { return BEGINTOK; } +end { return ENDTOK; } +true { return TRUETOK; } +false { return FALSETOK; } +declare { return DECLARE; } +global { return GLOBAL; } +constant { return CONSTANT; } +internal { return INTERNAL; } +linkonce { return LINKONCE; } +weak { return WEAK; } +appending { return APPENDING; } +dllimport { return DLLIMPORT; } +dllexport { return DLLEXPORT; } +extern_weak { return EXTERN_WEAK; } +uninitialized { return EXTERNAL; } /* Deprecated, turn into external */ +external { return EXTERNAL; } +implementation { return IMPLEMENTATION; } +zeroinitializer { return ZEROINITIALIZER; } +\.\.\. { return DOTDOTDOT; } +undef { return UNDEF; } +null { return NULL_TOK; } +to { return TO; } +except { return EXCEPT; } +not { return NOT; } /* Deprecated, turned into XOR */ +tail { return TAIL; } +target { return TARGET; } +triple { return TRIPLE; } +deplibs { return DEPLIBS; } +endian { return ENDIAN; } +pointersize { return POINTERSIZE; } +datalayout { return DATALAYOUT; } +little { return LITTLE; } +big { return BIG; } +volatile { return VOLATILE; } +align { return ALIGN; } +section { return SECTION; } +module { return MODULE; } +asm { return ASM_TOK; } +sideeffect { return SIDEEFFECT; } + +cc { return CC_TOK; } +ccc { return CCC_TOK; } +csretcc { return CSRETCC_TOK; } +fastcc { return FASTCC_TOK; } +coldcc { return COLDCC_TOK; } +x86_stdcallcc { return X86_STDCALLCC_TOK; } +x86_fastcallcc { return X86_FASTCALLCC_TOK; } + +sbyte { RET_TY(SBYTE, Type::Int8Ty, Signed); } +ubyte { RET_TY(UBYTE, Type::Int8Ty, Unsigned); } +short { RET_TY(SHORT, Type::Int16Ty, Signed); } +ushort { RET_TY(USHORT, Type::Int16Ty, Unsigned); } +int { RET_TY(INT, Type::Int32Ty, Signed); } +uint { RET_TY(UINT, Type::Int32Ty, Unsigned); } +long { RET_TY(LONG, Type::Int64Ty, Signed); } +ulong { RET_TY(ULONG, Type::Int64Ty, Unsigned); } +void { RET_TY(VOID, Type::VoidTy, Signless ); } +bool { RET_TY(BOOL, Type::Int1Ty, Unsigned ); } +float { RET_TY(FLOAT, Type::FloatTy, Signless ); } +double { RET_TY(DOUBLE, Type::DoubleTy,Signless); } +label { RET_TY(LABEL, Type::LabelTy, Signless ); } +type { return TYPE; } +opaque { return OPAQUE; } + +add { RET_TOK(BinaryOpVal, AddOp, ADD); } +sub { RET_TOK(BinaryOpVal, SubOp, SUB); } +mul { RET_TOK(BinaryOpVal, MulOp, MUL); } +div { RET_TOK(BinaryOpVal, DivOp, DIV); } +udiv { RET_TOK(BinaryOpVal, UDivOp, UDIV); } +sdiv { RET_TOK(BinaryOpVal, SDivOp, SDIV); } +fdiv { RET_TOK(BinaryOpVal, FDivOp, FDIV); } +rem { RET_TOK(BinaryOpVal, RemOp, REM); } +urem { RET_TOK(BinaryOpVal, URemOp, UREM); } +srem { RET_TOK(BinaryOpVal, SRemOp, SREM); } +frem { RET_TOK(BinaryOpVal, FRemOp, FREM); } +and { RET_TOK(BinaryOpVal, AndOp, AND); } +or { RET_TOK(BinaryOpVal, OrOp , OR ); } +xor { RET_TOK(BinaryOpVal, XorOp, XOR); } +setne { RET_TOK(BinaryOpVal, SetNE, SETNE); } +seteq { RET_TOK(BinaryOpVal, SetEQ, SETEQ); } +setlt { RET_TOK(BinaryOpVal, SetLT, SETLT); } +setgt { RET_TOK(BinaryOpVal, SetGT, SETGT); } +setle { RET_TOK(BinaryOpVal, SetLE, SETLE); } +setge { RET_TOK(BinaryOpVal, SetGE, SETGE); } +icmp { RET_TOK(OtherOpVal, ICmpOp, ICMP); } +fcmp { RET_TOK(OtherOpVal, FCmpOp, FCMP); } + +eq { return EQ; } +ne { return NE; } +slt { return SLT; } +sgt { return SGT; } +sle { return SLE; } +sge { return SGE; } +ult { return ULT; } +ugt { return UGT; } +ule { return ULE; } +uge { return UGE; } +oeq { return OEQ; } +one { return ONE; } +olt { return OLT; } +ogt { return OGT; } +ole { return OLE; } +oge { return OGE; } +ord { return ORD; } +uno { return UNO; } +ueq { return UEQ; } +une { return UNE; } + +phi { RET_TOK(OtherOpVal, PHIOp, PHI_TOK); } +call { RET_TOK(OtherOpVal, CallOp, CALL); } +cast { RET_TOK(CastOpVal, CastOp, CAST); } +trunc { RET_TOK(CastOpVal, TruncOp, TRUNC); } +zext { RET_TOK(CastOpVal, ZExtOp , ZEXT); } +sext { RET_TOK(CastOpVal, SExtOp, SEXT); } +fptrunc { RET_TOK(CastOpVal, FPTruncOp, FPTRUNC); } +fpext { RET_TOK(CastOpVal, FPExtOp, FPEXT); } +fptoui { RET_TOK(CastOpVal, FPToUIOp, FPTOUI); } +fptosi { RET_TOK(CastOpVal, FPToSIOp, FPTOSI); } +uitofp { RET_TOK(CastOpVal, UIToFPOp, UITOFP); } +sitofp { RET_TOK(CastOpVal, SIToFPOp, SITOFP); } +ptrtoint { RET_TOK(CastOpVal, PtrToIntOp, PTRTOINT); } +inttoptr { RET_TOK(CastOpVal, IntToPtrOp, INTTOPTR); } +bitcast { RET_TOK(CastOpVal, BitCastOp, BITCAST); } +select { RET_TOK(OtherOpVal, SelectOp, SELECT); } +shl { RET_TOK(OtherOpVal, ShlOp, SHL); } +shr { RET_TOK(OtherOpVal, ShrOp, SHR); } +lshr { RET_TOK(OtherOpVal, LShrOp, LSHR); } +ashr { RET_TOK(OtherOpVal, AShrOp, ASHR); } +vanext { return VANEXT_old; } +vaarg { return VAARG_old; } +va_arg { RET_TOK(OtherOpVal, VAArg , VAARG); } +ret { RET_TOK(TermOpVal, RetOp, RET); } +br { RET_TOK(TermOpVal, BrOp, BR); } +switch { RET_TOK(TermOpVal, SwitchOp, SWITCH); } +invoke { RET_TOK(TermOpVal, InvokeOp, INVOKE); } +unwind { return UNWIND; } +unreachable { RET_TOK(TermOpVal, UnreachableOp, UNREACHABLE); } + +malloc { RET_TOK(MemOpVal, MallocOp, MALLOC); } +alloca { RET_TOK(MemOpVal, AllocaOp, ALLOCA); } +free { RET_TOK(MemOpVal, FreeOp, FREE); } +load { RET_TOK(MemOpVal, LoadOp, LOAD); } +store { RET_TOK(MemOpVal, StoreOp, STORE); } +getelementptr { RET_TOK(MemOpVal, GetElementPtrOp, GETELEMENTPTR); } + +extractelement { RET_TOK(OtherOpVal, ExtractElementOp, EXTRACTELEMENT); } +insertelement { RET_TOK(OtherOpVal, InsertElementOp, INSERTELEMENT); } +shufflevector { RET_TOK(OtherOpVal, ShuffleVectorOp, SHUFFLEVECTOR); } + + +{VarID} { + UnEscapeLexed(yytext+1); + Upgradelval.StrVal = strdup(yytext+1); // Skip % + return VAR_ID; + } +{Label} { + yytext[strlen(yytext)-1] = 0; // nuke colon + UnEscapeLexed(yytext); + Upgradelval.StrVal = strdup(yytext); + return LABELSTR; + } +{QuoteLabel} { + yytext[strlen(yytext)-2] = 0; // nuke colon, end quote + UnEscapeLexed(yytext+1); + Upgradelval.StrVal = strdup(yytext+1); + return LABELSTR; + } + +{StringConstant} { // Note that we cannot unescape a string constant here! The + // string constant might contain a \00 which would not be + // understood by the string stuff. It is valid to make a + // [sbyte] c"Hello World\00" constant, for example. + // + yytext[strlen(yytext)-1] = 0; // nuke end quote + Upgradelval.StrVal = strdup(yytext+1); // Nuke start quote + return STRINGCONSTANT; + } + + +{PInteger} { Upgradelval.UInt64Val = atoull(yytext); return EUINT64VAL; } +{NInteger} { + uint64_t Val = atoull(yytext+1); + // +1: we have bigger negative range + if (Val > (uint64_t)INT64_MAX+1) + error("Constant too large for signed 64 bits!"); + Upgradelval.SInt64Val = -Val; + return ESINT64VAL; + } +{HexIntConstant} { + Upgradelval.UInt64Val = HexIntToVal(yytext+3); + return yytext[0] == 's' ? ESINT64VAL : EUINT64VAL; + } + +{EPInteger} { + uint64_t Val = atoull(yytext+1); + if ((unsigned)Val != Val) + error("Invalid value number (too large)!"); + Upgradelval.UIntVal = unsigned(Val); + return UINTVAL; + } +{ENInteger} { + uint64_t Val = atoull(yytext+2); + // +1: we have bigger negative range + if (Val > (uint64_t)INT32_MAX+1) + error("Constant too large for signed 32 bits!"); + Upgradelval.SIntVal = (int)-Val; + return SINTVAL; + } + +{FPConstant} { Upgradelval.FPVal = atof(yytext); return FPVAL; } +{HexFPConstant} { Upgradelval.FPVal = HexToFP(yytext); return FPVAL; } + +<<EOF>> { /* Make sure to free the internal buffers for flex when we are * done reading our input! */ diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y index da0772c3bf..ca6e7cd515 100644 --- a/tools/llvm-upgrade/UpgradeParser.y +++ b/tools/llvm-upgrade/UpgradeParser.y @@ -1,1127 +1,1775 @@ -//===-- UpgradeParser.y - Upgrade parser for llvm assmbly -------*- C++ -*-===// +//===-- llvmAsmParser.y - Parser for llvm assembly files --------*- 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 file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// This file implements the bison parser for LLVM 1.9 assembly language. +// This file implements the bison parser for LLVM assembly languages files. // //===----------------------------------------------------------------------===// %{ #include "UpgradeInternals.h" +#include "llvm/CallingConv.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/SymbolTable.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/MathExtras.h" #include <algorithm> -#include <map> -#include <utility> #include <iostream> +#include <list> +#include <utility> + +// DEBUG_UPREFS - Define this symbol if you want to enable debugging output +// relating to upreferences in the input stream. +// +//#define DEBUG_UPREFS 1 +#ifdef DEBUG_UPREFS +#define UR_OUT(X) std::cerr << X +#else +#define UR_OUT(X) +#endif #define YYERROR_VERBOSE 1 #define YYINCLUDED_STDLIB_H #define YYDEBUG 1 -int yylex(); // declaration" of xxx warnings. +int yylex(); int yyparse(); -extern int yydebug; -static std::string CurFilename; -static std::ostream *O = 0; -std::istream* LexInput = 0; -unsigned SizeOfPointer = 32; +int yyerror(const char*); +static void warning(const std::string& WarningMsg); +namespace llvm { -// This bool controls whether attributes are ever added to function declarations -// definitions and calls. -static bool AddAttributes = false; -static void warning(const std::string& msg); +SignedType *SignedType::SByteTy = 0; +SignedType *SignedType::SShortTy = 0; +SignedType *SignedType::SIntTy = 0; +SignedType *SignedType::SLongTy = 0; -void UpgradeAssembly(const std::string &infile, std::istream& in, - std::ostream &out, bool debug, bool addAttrs) -{ - Upgradelineno = 1; - CurFilename = infile; - LexInput = ∈ - yydebug = debug; - AddAttributes = addAttrs; - O = &out; +inline bool SignedType::classof(const Type *T) { + if (T->getTypeID() != IntegerTyID) + return false; + return (T == SByteTy || T == SShortTy || T == SIntTy || T == SLongTy ); +} - if (yyparse()) { - std::cerr << "llvm-upgrade: parse failed.\n"; - out << "llvm-upgrade: parse failed.\n"; - exit(1); - } +SignedType::SignedType(const IntegerType* ITy) + : IntegerType(ITy->getBitWidth()), base_type(ITy) +{ } -namespace { // Anonymous namespace to keep our implementation local +const SignedType *SignedType::get(const IntegerType* ITy) { + if (ITy == Type::Int8Ty) { + if (!SByteTy) + SByteTy = new SignedType(IntegerType::get(8)); + return SByteTy; + } else if (ITy == Type::Int16Ty) { + if (!SShortTy) + SShortTy = new SignedType(IntegerType::get(16)); + return SShortTy; + } else if (ITy == Type::Int32Ty) { + if (!SIntTy) + SIntTy = new SignedType(IntegerType::get(32)); + return SIntTy; + } else if (ITy == Type::Int64Ty) { + if (!SLongTy) + SLongTy = new SignedType(IntegerType::get(64)); + return SLongTy; + } else + assert(0 && "Invalid integer type for SignedType::get"); +} +static inline Signedness getSign(const Type *&Ty) { + if (const SignedType *STy = dyn_cast<SignedType>(Ty)) { + Ty = STy->getBaseType(); + return Signed; + } else if (isa<IntegerType>(Ty)) + return Unsigned; + return Signless; +} -/// This type is used to keep track of the signedness of values. Instead -/// of creating llvm::Value directly, the parser will create Value which -/// associates a Value* with a Signedness indication. -struct Value { - std::string* val; - const Type* type; - bool constant; - bool isConstant() const { return constant; } - ~Value() { delete val; } -}; +static const Type* +resolveTypeImpl(const Type* Ty, std::vector<const Type*>& TyStack) +{ + // Nothing to resolve if it isn't a derived type + if (!Ty->isDerivedType()) + return Ty; + + // Prevent infinite recursion for recursive types + for (std::vector<const Type*>::const_iterator I = TyStack.begin(), + E = TyStack.end(); I != E; ++I) + if (Ty == *I) + return Ty; + + // Okay, haven't seen this derived type yet, push it on the stack. + const Type* Result = Ty; + T |