diff options
Diffstat (limited to 'tools/llvm-upgrade/UpgradeParser.cpp.cvs')
-rw-r--r-- | tools/llvm-upgrade/UpgradeParser.cpp.cvs | 7920 |
1 files changed, 4754 insertions, 3166 deletions
diff --git a/tools/llvm-upgrade/UpgradeParser.cpp.cvs b/tools/llvm-upgrade/UpgradeParser.cpp.cvs index b65ac101d2..acaeade09a 100644 --- a/tools/llvm-upgrade/UpgradeParser.cpp.cvs +++ b/tools/llvm-upgrade/UpgradeParser.cpp.cvs @@ -1,7 +1,7 @@ -/* A Bison parser, made from /usr/home/jeffc/llvm/tools/llvm-upgrade/UpgradeParser.y, by GNU bison 1.75. */ +/* A Bison parser, made by GNU Bison 2.1. */ /* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,8 +15,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. @@ -34,16 +34,21 @@ USER NAME SPACE" below. */ /* Identify Bison output. */ -#define YYBISON 1 +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.1" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ -#define YYPURE 0 +#define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 -/* If NAME_PREFIX is specified substitute the variables and functions - names. */ +/* Substitute the variable and function names. */ #define yyparse Upgradeparse #define yylex Upgradelex #define yyerror Upgradeerror @@ -59,61 +64,61 @@ /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - VOID = 258, - BOOL = 259, - SBYTE = 260, - UBYTE = 261, - SHORT = 262, - USHORT = 263, - INT = 264, - UINT = 265, - LONG = 266, - ULONG = 267, - FLOAT = 268, - DOUBLE = 269, - LABEL = 270, - OPAQUE = 271, - ESINT64VAL = 272, - EUINT64VAL = 273, - SINTVAL = 274, - UINTVAL = 275, - FPVAL = 276, - NULL_TOK = 277, - UNDEF = 278, - ZEROINITIALIZER = 279, - TRUETOK = 280, - FALSETOK = 281, - TYPE = 282, - VAR_ID = 283, - LABELSTR = 284, - STRINGCONSTANT = 285, - IMPLEMENTATION = 286, - BEGINTOK = 287, - ENDTOK = 288, - DECLARE = 289, - GLOBAL = 290, - CONSTANT = 291, - SECTION = 292, - VOLATILE = 293, - TO = 294, - DOTDOTDOT = 295, - CONST = 296, - INTERNAL = 297, - LINKONCE = 298, - WEAK = 299, + ESINT64VAL = 258, + EUINT64VAL = 259, + SINTVAL = 260, + UINTVAL = 261, + FPVAL = 262, + VOID = 263, + BOOL = 264, + SBYTE = 265, + UBYTE = 266, + SHORT = 267, + USHORT = 268, + INT = 269, + UINT = 270, + LONG = 271, + ULONG = 272, + FLOAT = 273, + DOUBLE = 274, + TYPE = 275, + LABEL = 276, + VAR_ID = 277, + LABELSTR = 278, + STRINGCONSTANT = 279, + IMPLEMENTATION = 280, + ZEROINITIALIZER = 281, + TRUETOK = 282, + FALSETOK = 283, + BEGINTOK = 284, + ENDTOK = 285, + DECLARE = 286, + GLOBAL = 287, + CONSTANT = 288, + SECTION = 289, + VOLATILE = 290, + TO = 291, + DOTDOTDOT = 292, + NULL_TOK = 293, + UNDEF = 294, + CONST = 295, + INTERNAL = 296, + LINKONCE = 297, + WEAK = 298, + APPENDING = 299, DLLIMPORT = 300, DLLEXPORT = 301, EXTERN_WEAK = 302, - APPENDING = 303, - EXTERNAL = 304, - TARGET = 305, - TRIPLE = 306, - ENDIAN = 307, - POINTERSIZE = 308, - LITTLE = 309, - BIG = 310, - ALIGN = 311, - UNINITIALIZED = 312, + OPAQUE = 303, + NOT = 304, + EXTERNAL = 305, + TARGET = 306, + TRIPLE = 307, + ENDIAN = 308, + POINTERSIZE = 309, + LITTLE = 310, + BIG = 311, + ALIGN = 312, DEPLIBS = 313, CALL = 314, TAIL = 315, @@ -132,9 +137,9 @@ BR = 328, SWITCH = 329, INVOKE = 330, - EXCEPT = 331, + UNREACHABLE = 331, UNWIND = 332, - UNREACHABLE = 333, + EXCEPT = 333, ADD = 334, SUB = 335, MUL = 336, @@ -157,112 +162,115 @@ SETNE = 353, ICMP = 354, FCMP = 355, - EQ = 356, - NE = 357, - SLT = 358, - SGT = 359, - SLE = 360, - SGE = 361, - OEQ = 362, - ONE = 363, - OLT = 364, - OGT = 365, - OLE = 366, - OGE = 367, - ORD = 368, - UNO = 369, - UEQ = 370, - UNE = 371, - ULT = 372, - UGT = 373, - ULE = 374, - UGE = 375, - MALLOC = 376, - ALLOCA = 377, - FREE = 378, - LOAD = 379, - STORE = 380, - GETELEMENTPTR = 381, - PHI_TOK = 382, - SELECT = 383, - SHL = 384, - SHR = 385, - ASHR = 386, - LSHR = 387, - VAARG = 388, - EXTRACTELEMENT = 389, - INSERTELEMENT = 390, - SHUFFLEVECTOR = 391, - CAST = 392, - TRUNC = 393, - ZEXT = 394, - SEXT = 395, - FPTRUNC = 396, - FPEXT = 397, - FPTOUI = 398, - FPTOSI = 399, - UITOFP = 400, - SITOFP = 401, - PTRTOINT = 402, - INTTOPTR = 403, - BITCAST = 404 + MALLOC = 356, + ALLOCA = 357, + FREE = 358, + LOAD = 359, + STORE = 360, + GETELEMENTPTR = 361, + PHI_TOK = 362, + SELECT = 363, + SHL = 364, + SHR = 365, + ASHR = 366, + LSHR = 367, + VAARG = 368, + EXTRACTELEMENT = 369, + INSERTELEMENT = 370, + SHUFFLEVECTOR = 371, + VAARG_old = 372, + VANEXT_old = 373, + EQ = 374, + NE = 375, + SLT = 376, + SGT = 377, + SLE = 378, + SGE = 379, + ULT = 380, + UGT = 381, + ULE = 382, + UGE = 383, + OEQ = 384, + ONE = 385, + OLT = 386, + OGT = 387, + OLE = 388, + OGE = 389, + ORD = 390, + UNO = 391, + UEQ = 392, + UNE = 393, + CAST = 394, + TRUNC = 395, + ZEXT = 396, + SEXT = 397, + FPTRUNC = 398, + FPEXT = 399, + FPTOUI = 400, + FPTOSI = 401, + UITOFP = 402, + SITOFP = 403, + PTRTOINT = 404, + INTTOPTR = 405, + BITCAST = 406 }; #endif -#define VOID 258 -#define BOOL 259 -#define SBYTE 260 -#define UBYTE 261 -#define SHORT 262 -#define USHORT 263 -#define INT 264 -#define UINT 265 -#define LONG 266 -#define ULONG 267 -#define FLOAT 268 -#define DOUBLE 269 -#define LABEL 270 -#define OPAQUE 271 -#define ESINT64VAL 272 -#define EUINT64VAL 273 -#define SINTVAL 274 -#define UINTVAL 275 -#define FPVAL 276 -#define NULL_TOK 277 -#define UNDEF 278 -#define ZEROINITIALIZER 279 -#define TRUETOK 280 -#define FALSETOK 281 -#define TYPE 282 -#define VAR_ID 283 -#define LABELSTR 284 -#define STRINGCONSTANT 285 -#define IMPLEMENTATION 286 -#define BEGINTOK 287 -#define ENDTOK 288 -#define DECLARE 289 -#define GLOBAL 290 -#define CONSTANT 291 -#define SECTION 292 -#define VOLATILE 293 -#define TO 294 -#define DOTDOTDOT 295 -#define CONST 296 -#define INTERNAL 297 -#define LINKONCE 298 -#define WEAK 299 +/* Tokens. */ +#define ESINT64VAL 258 +#define EUINT64VAL 259 +#define SINTVAL 260 +#define UINTVAL 261 +#define FPVAL 262 +#define VOID 263 +#define BOOL 264 +#define SBYTE 265 +#define UBYTE 266 +#define SHORT 267 +#define USHORT 268 +#define INT 269 +#define UINT 270 +#define LONG 271 +#define ULONG 272 +#define FLOAT 273 +#define DOUBLE 274 +#define TYPE 275 +#define LABEL 276 +#define VAR_ID 277 +#define LABELSTR 278 +#define STRINGCONSTANT 279 +#define IMPLEMENTATION 280 +#define ZEROINITIALIZER 281 +#define TRUETOK 282 +#define FALSETOK 283 +#define BEGINTOK 284 +#define ENDTOK 285 +#define DECLARE 286 +#define GLOBAL 287 +#define CONSTANT 288 +#define SECTION 289 +#define VOLATILE 290 +#define TO 291 +#define DOTDOTDOT 292 +#define NULL_TOK 293 +#define UNDEF 294 +#define CONST 295 +#define INTERNAL 296 +#define LINKONCE 297 +#define WEAK 298 +#define APPENDING 299 #define DLLIMPORT 300 #define DLLEXPORT 301 #define EXTERN_WEAK 302 -#define APPENDING 303 -#define EXTERNAL 304 -#define TARGET 305 -#define TRIPLE 306 -#define ENDIAN 307 -#define POINTERSIZE 308 -#define LITTLE 309 -#define BIG 310 -#define ALIGN 311 -#define UNINITIALIZED 312 +#define OPAQUE 303 +#define NOT 304 +#define EXTERNAL 305 +#define TARGET 306 +#define TRIPLE 307 +#define ENDIAN 308 +#define POINTERSIZE 309 +#define LITTLE 310 +#define BIG 311 +#define ALIGN 312 #define DEPLIBS 313 #define CALL 314 #define TAIL 315 @@ -281,9 +289,9 @@ #define BR 328 #define SWITCH 329 #define INVOKE 330 -#define EXCEPT 331 +#define UNREACHABLE 331 #define UNWIND 332 -#define UNREACHABLE 333 +#define EXCEPT 333 #define ADD 334 #define SUB 335 #define MUL 336 @@ -306,1013 +314,1515 @@ #define SETNE 353 #define ICMP 354 #define FCMP 355 -#define EQ 356 -#define NE 357 -#define SLT 358 -#define SGT 359 -#define SLE 360 -#define SGE 361 -#define OEQ 362 -#define ONE 363 -#define OLT 364 -#define OGT 365 -#define OLE 366 -#define OGE 367 -#define ORD 368 -#define UNO 369 -#define UEQ 370 -#define UNE 371 -#define ULT 372 -#define UGT 373 -#define ULE 374 -#define UGE 375 -#define MALLOC 376 -#define ALLOCA 377 -#define FREE 378 -#define LOAD 379 -#define STORE 380 -#define GETELEMENTPTR 381 -#define PHI_TOK 382 -#define SELECT 383 -#define SHL 384 -#define SHR 385 -#define ASHR 386 -#define LSHR 387 -#define VAARG 388 -#define EXTRACTELEMENT 389 -#define INSERTELEMENT 390 -#define SHUFFLEVECTOR 391 -#define CAST 392 -#define TRUNC 393 -#define ZEXT 394 -#define SEXT 395 -#define FPTRUNC 396 -#define FPEXT 397 -#define FPTOUI 398 -#define FPTOSI 399 -#define UITOFP 400 -#define SITOFP 401 -#define PTRTOINT 402 -#define INTTOPTR 403 -#define BITCAST 404 +#define MALLOC 356 +#define ALLOCA 357 +#define FREE 358 +#define LOAD 359 +#define STORE 360 +#define GETELEMENTPTR 361 +#define PHI_TOK 362 +#define SELECT 363 +#define SHL 364 +#define SHR 365 +#define ASHR 366 +#define LSHR 367 +#define VAARG 368 +#define EXTRACTELEMENT 369 +#define INSERTELEMENT 370 +#define SHUFFLEVECTOR 371 +#define VAARG_old 372 +#define VANEXT_old 373 +#define EQ 374 +#define NE 375 +#define SLT 376 +#define SGT 377 +#define SLE 378 +#define SGE 379 +#define ULT 380 +#define UGT 381 +#define ULE 382 +#define UGE 383 +#define OEQ 384 +#define ONE 385 +#define OLT 386 +#define OGT 387 +#define OLE 388 +#define OGE 389 +#define ORD 390 +#define UNO 391 +#define UEQ 392 +#define UNE 393 +#define CAST 394 +#define TRUNC 395 +#define ZEXT 396 +#define SEXT 397 +#define FPTRUNC 398 +#define FPEXT 399 +#define FPTOUI 400 +#define FPTOSI 401 +#define UITOFP 402 +#define SITOFP 403 +#define PTRTOINT 404 +#define INTTOPTR 405 +#define BITCAST 406 /* Copy the first part of user declarations. */ -#line 14 "/usr/home/jeffc/llvm/tools/llvm-upgrade/UpgradeParser.y" +#line 14 "/proj/llvm/llvm-1/tools/llvm-upgrade/UpgradeParser.y" #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) +inline bool SignedType::classof(const Type *T) { + if (T->getTypeID() != IntegerTyID) + return false; + return (T == SByteTy || T == SShortTy || T == SIntTy || T == SLongTy ); +} + +SignedType::SignedType(const IntegerType* ITy) + : IntegerType(ITy->getBitWidth()), base_type(ITy) { - Upgradelineno = 1; - CurFilename = infile; - LexInput = ∈ - yydebug = debug; - AddAttributes = addAttrs; - O = &out; +} - if (yyparse()) { - std::cerr << "llvm-upgrade: parse failed.\n"; - out << "llvm-upgrade: parse failed.\n"; - exit(1); - } +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"); } -namespace { // Anonymous namespace to keep our implementation local +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; +} + +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; + TyStack.push_back(Ty); + + // Process the type + switch (Ty->getTypeID()) { + default: assert(0 && "Invalid derived type"); + case Type::IntegerTyID: + break; + case Type::FunctionTyID: { + const FunctionType* FTy = cast<FunctionType>(Ty); + const Type* RetTy = resolveTypeImpl(FTy->getReturnType(), TyStack); + std::vector<const Type*> Types; + FunctionType::ParamAttrsList Attrs; + Attrs.push_back(FTy->getParamAttrs(0)); + for (unsigned i = 0; i < FTy->getNumParams(); ++i) { + Types.push_back(resolveTypeImpl(FTy->getParamType(i), TyStack)); + Attrs.push_back(FTy->getParamAttrs(i+1)); + } + Result = FunctionType::get(RetTy, Types, FTy->isVarArg(), Attrs); + break; + } + case Type::StructTyID: + case Type::PackedStructTyID: { + const StructType *STy = cast<StructType>(Ty); + std::vector<const Type*> FieldTypes; + for (unsigned i = 0; i < STy->getNumElements(); ++i) + FieldTypes.push_back(resolveTypeImpl(STy->getElementType(i), TyStack)); + Result = StructType::get(FieldTypes, STy->isPacked()); + break; + } + case Type::ArrayTyID: { + const ArrayType *ATy = cast<ArrayType>(Ty); + uint64_t NElems = ATy->getNumElements(); + const Type *ElemTy = resolveTypeImpl(ATy->getElementType(), TyStack); + Result = ArrayType::get(ElemTy, NElems); + break; + } + case Type::PointerTyID: { + const PointerType *PTy = cast<PointerType>(Ty); + const Type *ElemTy = resolveTypeImpl(PTy->getElementType(), TyStack); + Result = PointerType::get(ElemTy); + break; + } + case Type::PackedTyID: { + const PackedType *PTy = cast<PackedType>(Ty); + unsigned NElems = PTy->getNumElements(); + const Type *ElemTy = resolveTypeImpl(PTy->getElementType(), TyStack); + Result = PackedType::get(ElemTy, NElems); + break; + } + } + // Done with it, pop it off. + TyStack.pop_back(); + return Result; +} +static inline const Type* resolveType(const Type* Ty) { + if (!Ty) + return 0; + if (const SignedType* STy = dyn_cast<SignedType>(Ty)) + return STy->getBaseType(); + std::vector<const Type*> TyStack; + return resolveTypeImpl(Ty, TyStack); +} -/// 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; } -}; +std::istream* LexInput; +static std::string CurFilename; +// This bool controls whether attributes are ever added to function declarations +// definitions and calls. +static bool AddAttributes = false; -/// 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 Type 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 Type { -public: - static const Type* get(const std::string &newType, TypeIDs oldType); - static const Type* get(const std::string& newType, TypeIDs oldType, - const Type* eTy, const Type* rTy); +static Module *ParserResult; +static bool ObsoleteVarArgs; +static bool NewVarArgs; +static BasicBlock *CurBB; +static GlobalVariable *CurGV; + + + +// This contains info used when building the body of a function. It is +// destroyed when the function is completed. +// +typedef std::vector<Value *> ValueList; // Numbered defs + +typedef std::pair<std::string,const Type*> RenameMapKey; +typedef std::map<RenameMapKey,std::string> RenameMapType; + +static void +ResolveDefinitions(std::map<const Type *,ValueList> &LateResolvers, + std::map<const Type *,ValueList> *FutureLateResolvers = 0); + +static struct PerModuleInfo { + Module *CurrentModule; + std::map<const Type *, ValueList> Values; // Module level numbered definitions + std::map<const Type *,ValueList> LateResolveValues; + std::vector<PATypeHolder> Types; + std::map<ValID, PATypeHolder> LateResolveTypes; + static Module::Endianness Endian; + static Module::PointerSize PointerSize; + RenameMapType RenameMap; + + /// PlaceHolderInfo - When temporary placeholder objects are created, remember + /// how they were referenced and on which line of the input they came from so + /// that we can resolve them later and print error messages as appropriate. + std::map<Value*, std::pair<ValID, int> > PlaceHolderInfo; + + // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward + // references to global values. Global values may be referenced before they + // are defined, and if so, the temporary object that they represent is held + // here. This is used for forward references of GlobalValues. + // + typedef std::map<std::pair<const PointerType *, ValID>, GlobalValue*> + GlobalRefsType; + GlobalRefsType GlobalRefs; + + void ModuleDone() { + // If we could not resolve some functions at function compilation time + // (calls to functions before they are defined), resolve them now... Types + // are resolved when the constant pool has been completely parsed. + // + ResolveDefinitions(LateResolveValues); + + // Check to make sure that all global value forward references have been + // resolved! + // + if (!GlobalRefs.empty()) { + std::string UndefinedReferences = "Unresolved global references exist:\n"; + + for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end(); + I != E; ++I) { + UndefinedReferences += " " + I->first.first->getDescription() + " " + + I->first.second.getName() + "\n"; + } + error(UndefinedReferences); + return; + } - static const Type* get(const std::string& newType, TypeIDs oldType, - const Type *eTy, uint64_t elems); + if (CurrentModule->getDataLayout().empty()) { + std::string dataLayout; + if (Endian != Module::AnyEndianness) + dataLayout.append(Endian == Module::BigEndian ? "E" : "e"); + if (PointerSize != Module::AnyPointerSize) { + if (!dataLayout.empty()) + dataLayout += "-"; + dataLayout.append(PointerSize == Module::Pointer64 ? + "p:64:64" : "p:32:32"); + } + CurrentModule->setDataLayout(dataLayout); + } - static const Type* get(const std::string& newType, TypeIDs oldType, - TypeList* TL); + Values.clear(); // Clear out function local definitions + Types.clear(); + CurrentModule = 0; + } + + // GetForwardRefForGlobal - Check to see if there is a forward reference + // for this global. If so, remove it from the GlobalRefs map and return it. + // If not, just return null. + GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) { + // Check to see if there is a forward reference to this global variable... + // if there is, eliminate it and patch the reference to use the new def'n. + GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID)); + GlobalValue *Ret = 0; + if (I != GlobalRefs.end()) { + Ret = I->second; + GlobalRefs.erase(I); + } + return Ret; + } + void setEndianness(Module::Endianness E) { Endian = E; } + void setPointerSize(Module::PointerSize sz) { PointerSize = sz; } +} CurModule; - static const Type* get(const std::string& newType, const Type* resTy, - TypeList* TL); +Module::Endianness PerModuleInfo::Endian = Module::AnyEndianness; +Module::PointerSize PerModuleInfo::PointerSize = Module::AnyPointerSize; - const Type* resolve() const; - bool operator<(const Type& that) const; +static struct PerFunctionInfo { + Function *CurrentFunction; // Pointer to current function being created - bool sameNewTyAs(const Type* that) const { - return this->newTy == that->newTy; - } + std::map<const Type*, ValueList> Values; // Keep track of #'d definitions + std::map<const Type*, ValueList> LateResolveValues; + bool isDeclare; // Is this function a forward declararation? + GlobalValue::LinkageTypes Linkage;// Linkage for forward declaration. - bool sameOldTyAs(const Type* that) const; + /// BBForwardRefs - When we see forward references to basic blocks, keep + /// track of them here. + std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs; + std::vector<BasicBlock*> NumberedBlocks; + RenameMapType RenameMap; + std::set<Value*> SignedValues; + unsigned NextBBNum; - TypeIDs getElementTy() const { - if (elemTy) { - return elemTy->oldTy; - } - return UnresolvedTy; + inline PerFunctionInfo() { + CurrentFunction = 0; + isDeclare = false; + Linkage = GlobalValue::ExternalLinkage; } - unsigned getUpRefNum() const { - assert(oldTy == UpRefTy && "Can't getUpRefNum on non upreference"); - return atoi(&((getNewTy().c_str())[1])); // skip the slash + inline void FunctionStart(Function *M) { + CurrentFunction = M; + NextBBNum = 0; } - typedef std::vector<const Type*> UpRefStack; - void getSignedness(unsigned &sNum, unsigned &uNum, UpRefStack& stk) const; - std::string makeUniqueName(const std::string& BaseName) const; + void FunctionDone() { + NumberedBlocks.clear(); - const std::string& getNewTy() const { return newTy; } - const Type* getResultType() const { return resultTy; } - const Type* getElementType() const { return elemTy; } + // Any forward referenced blocks left? + if (!BBForwardRefs.empty()) { + error("Undefined reference to label " + + BBForwardRefs.begin()->first->getName()); + return; + } - const Type* getPointerType() const { - return get(newTy + "*", PointerTy, this, (Type*)0); - } + // Resolve all forward references now. + ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues); - 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; + Values.clear(); // Clear out function local definitions + RenameMap.clear(); + SignedValues.clear(); + CurrentFunction = 0; + isDeclare = false; + Linkage = GlobalValue::ExternalLinkage; } +} CurFun; // Info for the current function... - 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(); - } +static bool inFunctionScope() { return CurFun.CurrentFunction != 0; } - bool isAttributeCandidate() const { - return isIntegral() && getBitWidth() < 32; - } - bool isUnresolvedDeep() const; +//===----------------------------------------------------------------------===// +// Code to handle definitions of all the types +//===----------------------------------------------------------------------===// - unsigned getBitWidth() const; +static int InsertValue(Value *V, + std::map<const Type*,ValueList> &ValueTab = CurFun.Values) { + if (V->hasName()) return -1; // Is this a numbered definition? - const Type* getIndexedType(const Value* V) const; + // Yes, insert the value into the value table... + ValueList &List = ValueTab[V->getType()]; + List.push_back(V); + return List.size()-1; +} - unsigned getNumStructElements() const { - return (elements ? elements->size() : 0); +static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) { + switch (D.Type) { + case ValID::NumberVal: // Is it a numbered definition? + // Module constants occupy the lowest numbered slots... + if ((unsigned)D.Num < CurModule.Types.size()) { + return CurModule.Types[(unsigned)D.Num]; + } + break; + case ValID::NameVal: // Is it a named definition? + if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) { + D.destroy(); // Free old strdup'd memory... + return N; + } + break; + default: + error("Internal parser error: Invalid symbol type reference"); + return 0; } - const Type* getElement(unsigned idx) const { - if (elements) - if (idx < elements->size()) - return (*elements)[idx]; - return 0; + // If we reached here, we referenced either a symbol that we don't know about + // or an id number that hasn't been read yet. We may be referencing something + // forward, so just create an entry to be resolved later and get to it... + // + if (DoNotImprovise) return 0; // Do we just want a null to be returned? + + + if (inFunctionScope()) { + if (D.Type == ValID::NameVal) { + error("Reference to an undefined type: '" + D.getName() + "'"); + return 0; + } else { + error("Reference to an undefined type: #" + itostr(D.Num)); + return 0; + } } -private: - Type() - : newTy(), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0), - nelems(0) { + std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D); + if (I != CurModule.LateResolveTypes.end()) + return I->second; + + Type *Typ = OpaqueType::get(); + CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); + return Typ; + } + +// getExistingValue - Look up the value specified by the provided type and +// the provided ValID. If the value exists and has already been defined, return +// it. Otherwise return null. +// +static Value *getExistingValue(const Type *Ty, const ValID &D) { + if (isa<FunctionType>(Ty)) { + error("Functions are not values and must be referenced as pointers"); } - Type(const Type& that); // do not implement - Type& operator=(const Type& that); // do not implement + switch (D.Type) { + case ValID::NumberVal: { // Is it a numbered definition? + unsigned Num = (unsigned)D.Num; + + // Module constants occupy the lowest numbered slots... + std::map<const Type*,ValueList>::iterator VI = CurModule.Values.find(Ty); + if (VI != CurModule.Values.end()) { + if (Num < VI->second.size()) + return VI->second[Num]; + Num -= VI->second.size(); + } - ~Type() { delete elements; } + // Make sure that our type is within bounds + VI = CurFun.Values.find(Ty); + if (VI == CurFun.Values.end()) return 0; - struct ltfunctor - { - bool operator()(const Type* X, const Type* Y) const { - assert(X && "Can't compare null pointer"); - assert(Y && "Can't compare null pointer"); - return *X < *Y; + // Check that the number is within bounds... + if (VI->second.size() <= Num) return 0; + + return VI->second[Num]; + } + + case ValID::NameVal: { // Is it a named definition? + // Get the name out of the ID + std::string Name(D.Name); + Value* V = 0; + RenameMapKey Key = std::make_pair(Name, Ty); + if (inFunctionScope()) { + // See if the name was renamed + RenameMapType::const_iterator I = CurFun.RenameMap.find(Key); + std::string LookupName; + if (I != CurFun.RenameMap.end()) + LookupName = I->second; + else + LookupName = Name; + SymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable(); + V = SymTab.lookup(Ty, LookupName); } - }; + if (!V) { + RenameMapType::const_iterator I = CurModule.RenameMap.find(Key); + std::string LookupName; + if (I != CurModule.RenameMap.end()) + LookupName = I->second; + else + LookupName = Name; + V = CurModule.CurrentModule->getValueSymbolTable().lookup(Ty, LookupName); + } + if (V == 0) + return 0; - typedef std::set<const Type*, ltfunctor> TypeRegMap; - - static const Type* add_new_type(Type* existing); - - std::string newTy; - TypeIDs oldTy; - Type *elemTy; - Type *resultTy; - TypeList *elements; - uint64_t nelems; - static TypeRegMap registry; -public: - typedef std::vector<const Type*> TypeVector; - typedef std::map<std::string,const Type*> TypeMap; - typedef std::map<const Type*,std::string> TypePlaneMap; - typedef std::map<std::string,TypePlaneMap> GlobalsTypeMap; - static TypeVector EnumeratedTypes; - static TypeMap NamedTypes; - static GlobalsTypeMap Globals; -}; + D.destroy(); // Free old strdup'd memory... + return V; + } -Type::TypeRegMap Type::registry; -Type::TypeVector Type::EnumeratedTypes; -Type::TypeMap Type::NamedTypes; -Type::GlobalsTypeMap Type::Globals; + // Check to make sure that "Ty" is an integral type, and that our + // value will fit into the specified type... + case ValID::ConstSIntVal: // Is it a constant pool reference?? |