diff options
Diffstat (limited to 'lib/AsmParser/llvmAsmParser.cpp')
-rw-r--r-- | lib/AsmParser/llvmAsmParser.cpp | 4590 |
1 files changed, 4590 insertions, 0 deletions
diff --git a/lib/AsmParser/llvmAsmParser.cpp b/lib/AsmParser/llvmAsmParser.cpp new file mode 100644 index 0000000000..cfae201fd4 --- /dev/null +++ b/lib/AsmParser/llvmAsmParser.cpp @@ -0,0 +1,4590 @@ +/* A Bison parser, made by GNU Bison 1.875c. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 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 + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* If NAME_PREFIX is specified substitute the variables and functions + names. */ +#define yyparse llvmAsmparse +#define yylex llvmAsmlex +#define yyerror llvmAsmerror +#define yylval llvmAsmlval +#define yychar llvmAsmchar +#define yydebug llvmAsmdebug +#define yynerrs llvmAsmnerrs + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + 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, + VOLATILE = 289, + TO = 290, + DOTDOTDOT = 291, + NULL_TOK = 292, + UNDEF = 293, + CONST = 294, + INTERNAL = 295, + LINKONCE = 296, + WEAK = 297, + APPENDING = 298, + OPAQUE = 299, + NOT = 300, + EXTERNAL = 301, + TARGET = 302, + TRIPLE = 303, + ENDIAN = 304, + POINTERSIZE = 305, + LITTLE = 306, + BIG = 307, + DEPLIBS = 308, + CALL = 309, + TAIL = 310, + CC_TOK = 311, + CCC_TOK = 312, + FASTCC_TOK = 313, + COLDCC_TOK = 314, + RET = 315, + BR = 316, + SWITCH = 317, + INVOKE = 318, + UNWIND = 319, + UNREACHABLE = 320, + ADD = 321, + SUB = 322, + MUL = 323, + DIV = 324, + REM = 325, + AND = 326, + OR = 327, + XOR = 328, + SETLE = 329, + SETGE = 330, + SETLT = 331, + SETGT = 332, + SETEQ = 333, + SETNE = 334, + MALLOC = 335, + ALLOCA = 336, + FREE = 337, + LOAD = 338, + STORE = 339, + GETELEMENTPTR = 340, + PHI_TOK = 341, + CAST = 342, + SELECT = 343, + SHL = 344, + SHR = 345, + VAARG = 346, + VAARG_old = 347, + VANEXT_old = 348 + }; +#endif +#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 VOLATILE 289 +#define TO 290 +#define DOTDOTDOT 291 +#define NULL_TOK 292 +#define UNDEF 293 +#define CONST 294 +#define INTERNAL 295 +#define LINKONCE 296 +#define WEAK 297 +#define APPENDING 298 +#define OPAQUE 299 +#define NOT 300 +#define EXTERNAL 301 +#define TARGET 302 +#define TRIPLE 303 +#define ENDIAN 304 +#define POINTERSIZE 305 +#define LITTLE 306 +#define BIG 307 +#define DEPLIBS 308 +#define CALL 309 +#define TAIL 310 +#define CC_TOK 311 +#define CCC_TOK 312 +#define FASTCC_TOK 313 +#define COLDCC_TOK 314 +#define RET 315 +#define BR 316 +#define SWITCH 317 +#define INVOKE 318 +#define UNWIND 319 +#define UNREACHABLE 320 +#define ADD 321 +#define SUB 322 +#define MUL 323 +#define DIV 324 +#define REM 325 +#define AND 326 +#define OR 327 +#define XOR 328 +#define SETLE 329 +#define SETGE 330 +#define SETLT 331 +#define SETGT 332 +#define SETEQ 333 +#define SETNE 334 +#define MALLOC 335 +#define ALLOCA 336 +#define FREE 337 +#define LOAD 338 +#define STORE 339 +#define GETELEMENTPTR 340 +#define PHI_TOK 341 +#define CAST 342 +#define SELECT 343 +#define SHL 344 +#define SHR 345 +#define VAARG 346 +#define VAARG_old 347 +#define VANEXT_old 348 + + + + +/* Copy the first part of user declarations. */ +#line 14 "/proj/llvm/build/../llvm/lib/AsmParser/llvmAsmParser.y" + +#include "ParserInternals.h" +#include "llvm/CallingConv.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/SymbolTable.h" +#include "llvm/Support/GetElementPtrTypeIterator.h" +#include "llvm/ADT/STLExtras.h" +#include <algorithm> +#include <iostream> +#include <list> +#include <utility> + +int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit +int yylex(); // declaration" of xxx warnings. +int yyparse(); + +namespace llvm { + std::string CurFilename; +} +using namespace llvm; + +static Module *ParserResult; + +// 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 + +static bool ObsoleteVarArgs; +static bool NewVarArgs; +static BasicBlock* CurBB; + + +// 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 +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; + + /// PlaceHolderInfo - When temporary placeholder objects are created, remember + /// how they were referenced and one 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"; + } + ThrowException(UndefinedReferences); + } + + 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; + } +} CurModule; + +static struct PerFunctionInfo { + Function *CurrentFunction; // Pointer to current function being created + + 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? + + /// 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; + unsigned NextBBNum; + + inline PerFunctionInfo() { + CurrentFunction = 0; + isDeclare = false; + } + + inline void FunctionStart(Function *M) { + CurrentFunction = M; + NextBBNum = 0; + } + + void FunctionDone() { + NumberedBlocks.clear(); + + // Any forward referenced blocks left? + if (!BBForwardRefs.empty()) + ThrowException("Undefined reference to label " + + BBForwardRefs.begin()->first->getName()); + + // Resolve all forward references now. + ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues); + + Values.clear(); // Clear out function local definitions + CurrentFunction = 0; + isDeclare = false; + } +} CurFun; // Info for the current function... + +static bool inFunctionScope() { return CurFun.CurrentFunction != 0; } + + +//===----------------------------------------------------------------------===// +// Code to handle definitions of all the types +//===----------------------------------------------------------------------===// + +static int InsertValue(Value *V, + std::map<const Type*,ValueList> &ValueTab = CurFun.Values) { + if (V->hasName()) return -1; // Is this a numbered definition? + + // Yes, insert the value into the value table... + ValueList &List = ValueTab[V->getType()]; + List.push_back(V); + return List.size()-1; +} + +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: + ThrowException("Internal parser error: Invalid symbol type reference!"); + } + + // 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) + ThrowException("Reference to an undefined type: '" + D.getName() + "'"); + else + ThrowException("Reference to an undefined type: #" + itostr(D.Num)); + } + + 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; + } + +static Value *lookupInSymbolTable(const Type *Ty, const std::string &Name) { + SymbolTable &SymTab = + inFunctionScope() ? CurFun.CurrentFunction->getSymbolTable() : + CurModule.CurrentModule->getSymbolTable(); + return SymTab.lookup(Ty, Name); +} + +// getValNonImprovising - 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 *getValNonImprovising(const Type *Ty, const ValID &D) { + if (isa<FunctionType>(Ty)) + ThrowException("Functions are not values and " + "must be referenced as pointers"); + + 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(); + } + + // Make sure that our type is within bounds + VI = CurFun.Values.find(Ty); + if (VI == CurFun.Values.end()) return 0; + + // 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? + Value *N = lookupInSymbolTable(Ty, std::string(D.Name)); + if (N == 0) return 0; + + D.destroy(); // Free old strdup'd memory... + return N; + } + + // 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?? + if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64)) + ThrowException("Signed integral constant '" + + itostr(D.ConstPool64) + "' is invalid for type '" + + Ty->getDescription() + "'!"); + return ConstantSInt::get(Ty, D.ConstPool64); + + case ValID::ConstUIntVal: // Is it an unsigned const pool reference? + if (!ConstantUInt::isValueValidForType(Ty, D.UConstPool64)) { + if (!ConstantSInt::isValueValidForType(Ty, D.ConstPool64)) { + ThrowException("Integral constant '" + utostr(D.UConstPool64) + + "' is invalid or out of range!"); + } else { // This is really a signed reference. Transmogrify. + return ConstantSInt::get(Ty, D.ConstPool64); + } + } else { + return ConstantUInt::get(Ty, D.UConstPool64); + } + + case ValID::ConstFPVal: // Is it a floating point const pool reference? + if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) + ThrowException("FP constant invalid for type!!"); + return ConstantFP::get(Ty, D.ConstPoolFP); + + case ValID::ConstNullVal: // Is it a null value? + if (!isa<PointerType>(Ty)) + ThrowException("Cannot create a a non pointer null!"); + return ConstantPointerNull::get(cast<PointerType>(Ty)); + + case ValID::ConstUndefVal: // Is it an undef value? + return UndefValue::get(Ty); + + case ValID::ConstantVal: // Fully resolved constant? + if (D.ConstantValue->getType() != Ty) + ThrowException("Constant expression type different from required type!"); + return D.ConstantValue; + + default: + assert(0 && "Unhandled case!"); + return 0; + } // End of switch + + assert(0 && "Unhandled case!"); + return 0; +} + +// getVal - This function is identical to getValNonImprovising, except that if a +// value is not already defined, it "improvises" by creating a placeholder var +// that looks and acts just like the requested variable. When the value is +// defined later, all uses of the placeholder variable are replaced with the +// real thing. +// +static Value *getVal(const Type *Ty, const ValID &ID) { + if (Ty == Type::LabelTy) + ThrowException("Cannot use a basic block here"); + + // See if the value has already been defined. + Value *V = getValNonImprovising(Ty, ID); + if (V) return V; + + if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) + ThrowException("Invalid use of a composite type!"); + + // 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... + // + V = new Argument(Ty); + + // Remember where this forward reference came from. FIXME, shouldn't we try + // to recycle these things?? + CurModule.PlaceHolderInfo.insert(std::make_pair(V, std::make_pair(ID, + llvmAsmlineno))); + + if (inFunctionScope()) + InsertValue(V, CurFun.LateResolveValues); + else + InsertValue(V, CurModule.LateResolveValues); + return V; +} + +/// getBBVal - This is used for two purposes: +/// * If isDefinition is true, a new basic block with the specified ID is being +/// defined. +/// * If isDefinition is true, this is a reference to a basic block, which may +/// or may not be a forward reference. +/// +static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) { + assert(inFunctionScope() && "Can't get basic block at global scope!"); + + std::string Name; + BasicBlock *BB = 0; + switch (ID.Type) { + default: ThrowException("Illegal label reference " + ID.getName()); + case ValID::NumberVal: // Is it a numbered definition? + if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size()) + CurFun.NumberedBlocks.resize(ID.Num+1); + BB = CurFun.NumberedBlocks[ID.Num]; + break; + case ValID::NameVal: // Is it a named definition? + Name = ID.Name; + if (Value *N = CurFun.CurrentFunction-> + getSymbolTable().lookup(Type::LabelTy, Name)) + BB = cast<BasicBlock>(N); + break; + } + + // See if the block has already been defined. + if (BB) { + // If this is the definition of the block, make sure the existing value was + // just a forward reference. If it was a forward reference, there will be + // an entry for it in the PlaceHolderInfo map. + if (isDefinition && !CurFun.BBForwardRefs.erase(BB)) + // The existing value was a definition, not a forward reference. + ThrowException("Redefinition of label " + ID.getName()); + + ID.destroy(); // Free strdup'd memory. + return BB; + } + + // Otherwise this block has not been seen before. + BB = new BasicBlock("", CurFun.CurrentFunction); + if (ID.Type == ValID::NameVal) { + BB->setName(ID.Name); + } else { + CurFun.NumberedBlocks[ID.Num] = BB; + } + + // If this is not a definition, keep track of it so we can use it as a forward + // reference. + if (!isDefinition) { + // Remember where this forward reference came from. + CurFun.BBForwardRefs[BB] = std::make_pair(ID, llvmAsmlineno); + } else { + // The forward declaration could have been inserted anywhere in the + // function: insert it into the correct place now. + CurFun.CurrentFunction->getBasicBlockList().remove(BB); + CurFun.CurrentFunction->getBasicBlockList().push_back(BB); + } + ID.destroy(); + return BB; +} + + +//===----------------------------------------------------------------------===// +// Code to handle forward references in instructions +//===----------------------------------------------------------------------===// +// +// This code handles the late binding needed with statements that reference +// values not defined yet... for example, a forward branch, or the PHI node for +// a loop body. +// +// This keeps a table (CurFun.LateResolveValues) of all such forward references +// and back patchs after we are done. +// + +// ResolveDefinitions - If we could not resolve some defs at parsing +// time (forward branches, phi functions for loops, etc...) resolve the +// defs now... +// +static void +ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers, + std::map<const Type*,ValueList> *FutureLateResolvers) { + // Loop over LateResolveDefs fixing up stuff that couldn't be resolved + for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(), + E = LateResolvers.end(); LRI != E; ++LRI) { + ValueList &List = LRI->second; + while (!List.empty()) { + Value *V = List.back(); + List.pop_back(); + + std::map<Value*, std::pair<ValID, int> >::iterator PHI = + CurModule.PlaceHolderInfo.find(V); + assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!"); + + ValID &DID = PHI->second.first; + + Value *TheRealValue = getValNonImprovising(LRI->first, DID); + if (TheRealValue) { + V->replaceAllUsesWith(TheRealValue); + delete V; + CurModule.PlaceHolderInfo.erase(PHI); + } else if (FutureLateResolvers) { + // Functions have their unresolved items forwarded to the module late + // resolver table + InsertValue(V, *FutureLateResolvers); + } else { + if (DID.Type == ValID::NameVal) + ThrowException("Reference to an invalid definition: '" +DID.getName()+ + "' of type '" + V->getType()->getDescription() + "'", + PHI->second.second); + else + ThrowException("Reference to an invalid definition: #" + + itostr(DID.Num) + " of type '" + + V->getType()->getDescription() + "'", + PHI->second.second); + } + } + } + + LateResolvers.clear(); +} + +// ResolveTypeTo - A brand new type was just declared. This means that (if +// name is not null) things referencing Name can be resolved. Otherwise, things +// refering to the number can be resolved. Do this now. +// +static void ResolveTypeTo(char *Name, const Type *ToTy) { + ValID D; + if (Name) D = ValID::create(Name); + else D = ValID::create((int)CurModule.Types.size()); + + std::map<ValID, PATypeHolder>::iterator I = + CurModule.LateResolveTypes.find(D); + if (I != CurModule.LateResolveTypes.end()) { + ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); + CurModule.LateResolveTypes.erase(I); + } +} + +// setValueName - Set the specified value to the name given. The name may be +// null potentially, in which case this is a noop. The string passed in is +// assumed to be a malloc'd string buffer, and is free'd by this function. +// +static void setValueName(Value *V, char *NameStr) { + if (NameStr) { + std::string Name(NameStr); // Copy string + free(NameStr); // Free old string + + if (V->getType() == Type::VoidTy) + ThrowException("Can't assign name '" + Name+"' to value with void type!"); + + assert(inFunctionScope() && "Must be in function scope!"); + SymbolTable &ST = CurFun.CurrentFunction->getSymbolTable(); + if (ST.lookup(V->getType(), Name)) + ThrowException("Redefinition of value named '" + Name + "' in the '" + + V->getType()->getDescription() + "' type plane!"); + + // Set the name. + V->setName(Name); + } +} + +/// ParseGlobalVariable - Handle parsing of a global. If Initializer is null, +/// this is a declaration, otherwise it is a definition. +static void ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, + bool isConstantGlobal, const Type *Ty, + Constant *Initializer) { + if (isa<FunctionType>(Ty)) + ThrowException("Cannot declare global vars of function type!"); + + const PointerType *PTy = PointerType::get(Ty); + + std::string Name; + if (NameStr) { + Name = NameStr; // Copy string + free(NameStr); // Free old string + } + + // See if this global value was forward referenced. If so, recycle the + // object. + ValID ID; + if (!Name.empty()) { + ID = ValID::create((char*)Name.c_str()); + } else { + ID = ValID::create((int)CurModule.Values[PTy].size()); + } + + if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) { + // Move the global to the end of the list, from whereever it was + // previously inserted. + GlobalVariable *GV = cast<GlobalVariable>(FWGV); + CurModule.CurrentModule->getGlobalList().remove(GV); + CurModule.CurrentModule->getGlobalList().push_back(GV); + GV->setInitializer(Initializer); + GV->setLinkage(Linkage); + GV->setConstant(isConstantGlobal); + InsertValue(GV, CurModule.Values); + return; + } + + // If this global has a name, check to see if there is already a definition + // of this global in the module. If so, merge as appropriate. Note that + // this is really just a hack around problems in the CFE. :( + if (!Name.empty()) { + // We are a simple redefinition of a value, check to see if it is defined + // the same as the old one. + if (GlobalVariable *EGV = + CurModule.CurrentModule->getGlobalVariable(Name, Ty)) { + // We are allowed to redefine a global variable in two circumstances: + // 1. If at least one of the globals is uninitialized or + // 2. If both initializers have the same value. + // + if (!EGV->hasInitializer() || !Initializer || + EGV->getInitializer() == Initializer) { + + // Make sure the existing global version gets the initializer! Make + // sure that it also gets marked const if the new version is. + if (Initializer && !EGV->hasInitializer()) + EGV->setInitializer(Initializer); + if (isConstantGlobal) + EGV->setConstant(true); + EGV->setLinkage(Linkage); + return; + } + + ThrowException("Redefinition of global variable named '" + Name + + "' in the '" + Ty->getDescription() + "' type plane!"); + } + } + + // Otherwise there is no existing GV to use, create one now. + GlobalVariable *GV = + new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, + CurModule.CurrentModule); + InsertValue(GV, CurModule.Values); +} + +// setTypeName - Set the specified type to the name given. The name may be +// null potentially, in which case this is a noop. The string passed in is +// assumed to be a malloc'd string buffer, and is freed by this function. +// +// This function returns true if the type has already been defined, but is +// allowed to be redefined in the specified context. If the name is a new name +// for the type plane, it is inserted and false is returned. +static bool setTypeName(const Type *T, char *NameStr) { + assert(!inFunctionScope() && "Can't give types function-local names!"); + if (NameStr == 0) return false; + + std::string Name(NameStr); // Copy string + free(NameStr); // Free old string + + // We don't allow assigning names to void type + if (T == Type::VoidTy) + ThrowException("Can't assign name '" + Name + "' to the void type!"); + + // Set the type name, checking for conflicts as we do so. + bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, T); + + if (AlreadyExists) { // Inserting a name that is already defined??? + const Type *Existing = CurModule.CurrentModule->getTypeByName(Name); + assert(Existing && "Conflict but no matching type?"); + + // There is only one case where this is allowed: when we are refining an + // opaque type. In this case, Existing will be an opaque type. + if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) { + // We ARE replacing an opaque type! + const_cast<OpaqueType*>(OpTy)->refineAbstractTypeTo(T); + return true; + } + + // Otherwise, this is an attempt to redefine a type. That's okay if + // the redefinition is identical to the original. This will be so if + // Existing and T point to the same Type object. In this one case we + // allow the equivalent redefinition. + if (Existing == T) return true; // Yes, it's equal. + + // Any other kind of (non-equivalent) redefinition is an error. + ThrowException("Redefinition of type named '" + Name + "' in the '" + + T->getDescription() + "' type plane!"); + } + + return false; +} + +//===----------------------------------------------------------------------===// +// Code for handling upreferences in type names... +// + +// TypeContains - Returns true if Ty directly contains E in it. +// +static bool TypeContains(const Type *Ty, const Type *E) { + return std::find(Ty->subtype_begin(), Ty->subtype_end(), + E) != Ty->subtype_end(); +} + +namespace { + struct UpRefRecord { + // NestingLevel - The number of nesting levels that need to be popped before + // this type is resolved. + unsigned NestingLevel; + + // LastContainedTy - This is the type at the current binding level for the + // type. Every time we reduce the nesting level, this gets updated. + const Type *LastContainedTy; + + // UpRefTy - This is the actual opaque type that the upreference is + // represented with. + OpaqueType *UpRefTy; + + UpRefRecord(unsigned NL, OpaqueType *URTy) + : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) {} + }; +} + +// UpRefs - A list of the outstanding upreferences that need to be resolved. +static std::vector<UpRefRecord> UpRefs; + +/// HandleUpRefs - Every time we finish a new layer of types, this function is +/// called. It loops through the UpRefs vector, which is a list of the +/// currently active types. For each type, if the up reference is contained in +/// the newly completed type, we decrement the level count. When the level +/// count reaches zero, the upreferenced type is the type that is passed in: +/// thus we can complete the cycle. +/// +static PATypeHolder HandleUpRefs(const Type *ty) { + if (!ty->isAbstract()) return ty; + PATypeHolder Ty(ty); + UR_OUT("Type '" << Ty->getDescription() << + "' newly formed. Resolving upreferences.\n" << + UpRefs.size() << " upreferences active!\n"); + + // If we find any resolvable upreferences (i.e., those whose NestingLevel goes + // to zero), we resolve them all together before we resolve them to Ty. At + // the end of the loop, if there is anything to resolve to Ty, it will be in + // this variable. + OpaqueType *TypeToResolve = 0; + + for (unsigned i = 0; i != UpRefs.size(); ++i) { + UR_OUT(" UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " + << UpRefs[i].second->getDescription() << ") = " + << (TypeContains(Ty, UpRefs[i].second) ? "true" : "false") << "\n"); + if (TypeContains(Ty, UpRefs[i].LastContainedTy)) { + // Decrement level of upreference + unsigned Level = --UpRefs[i].NestingLevel; + UpRefs[i].LastContainedTy = Ty; + UR_OUT(" Uplevel Ref Level = " << Level << "\n"); + if (Level == 0) { // Upreference should be resolved! + if (!TypeToResolve) { + TypeToResolve = UpRefs[i].UpRefTy; + } else { + UR_OUT(" * Resolving upreference for " + << UpRefs[i].second->getDescription() << "\n"; + std::string OldName = UpRefs[i].UpRefTy->getDescription()); + UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); + UR_OUT(" * Type '" << OldName << "' refined upreference to: " + << (const void*)Ty << ", " << Ty->getDescription() << "\n"); + } + UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list... + --i; // Do not skip the next element... + } + } + } + + if (TypeToResolve) { + UR_OUT(" * Resolving upreference for " + << UpRefs[i].second->getDescription() << "\n"; + std::string OldName = TypeToResolve->getDescription()); + TypeToResolve->refineAbstractTypeTo(Ty); + } + + return Ty; +} + + +// common code from the two 'RunVMAsmParser' functions + static Module * RunParser(Module * M) { + + llvmAsmlineno = 1; // Reset the current line number... + ObsoleteVarArgs = false; + NewVarArgs = false; + + CurModule.CurrentModule = M; + yyparse(); // Parse the file, potentially throwing exception + + Module *Result = ParserResult; + ParserResult = 0; + + //Not all functions use vaarg, so make a second check for ObsoleteVarArgs + { + Function* F; + if ((F = Result->getNamedFunction("llvm.va_start")) + && F->getFunctionType()->getNumParams() == 0) + ObsoleteVarArgs = true; + if((F = Result->getNamedFunction("llvm.va_copy")) + && F->getFunctionType()->getNumParams() == 1) + ObsoleteVarArgs = true; + } + + if (ObsoleteVarArgs && NewVarArgs) + ThrowException("This file is corrupt: it uses both new and old style varargs"); + + if(ObsoleteVarArgs) { + if(Function* F = Result->getNamedFunction("llvm.va_start")) { + if (F->arg_size() != 0) + ThrowException("Obsolete va_start takes 0 argument!"); + + //foo = va_start() + // -> + //bar = alloca typeof(foo) + //va_start(bar) + //foo = load bar + + const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); + const Type* ArgTy = F->getFunctionType()->getReturnType(); + const Type* ArgTyPtr = PointerType::get(ArgTy); + Function* NF = Result->getOrInsertFunction("llvm.va_start", + RetTy, ArgTyPtr, 0); + + while (!F->use_empty()) { + CallInst* CI = cast<CallInst>(F->use_back()); + AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI); + new CallInst(NF, bar, "", CI); + Valu |