diff options
author | Chris Lattner <sabre@nondot.org> | 2006-02-15 07:22:58 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-02-15 07:22:58 +0000 |
commit | 58af2a1c5f084591bbc4c878134f6ffeea215628 (patch) | |
tree | df61d18dde1b92e2f46aefe9afc895a5241f6355 /lib/AsmParser/llvmAsmParser.cpp | |
parent | 6599c75cccf24a2910a49be4eeb9085e8cfbdec8 (diff) |
Convert this over to work with the new makefiles
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26206 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser/llvmAsmParser.cpp')
-rw-r--r-- | lib/AsmParser/llvmAsmParser.cpp | 4249 |
1 files changed, 0 insertions, 4249 deletions
diff --git a/lib/AsmParser/llvmAsmParser.cpp b/lib/AsmParser/llvmAsmParser.cpp deleted file mode 100644 index f7e57fe878..0000000000 --- a/lib/AsmParser/llvmAsmParser.cpp +++ /dev/null @@ -1,4249 +0,0 @@ - -/* A Bison parser, made from /Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y - by GNU Bison version 1.28 */ - -#define YYBISON 1 /* Identify Bison output. */ - -#define yyparse llvmAsmparse -#define yylex llvmAsmlex -#define yyerror llvmAsmerror -#define yylval llvmAsmlval -#define yychar llvmAsmchar -#define yydebug llvmAsmdebug -#define yynerrs llvmAsmnerrs -#define ESINT64VAL 257 -#define EUINT64VAL 258 -#define SINTVAL 259 -#define UINTVAL 260 -#define FPVAL 261 -#define VOID 262 -#define BOOL 263 -#define SBYTE 264 -#define UBYTE 265 -#define SHORT 266 -#define USHORT 267 -#define INT 268 -#define UINT 269 -#define LONG 270 -#define ULONG 271 -#define FLOAT 272 -#define DOUBLE 273 -#define TYPE 274 -#define LABEL 275 -#define VAR_ID 276 -#define LABELSTR 277 -#define STRINGCONSTANT 278 -#define IMPLEMENTATION 279 -#define ZEROINITIALIZER 280 -#define TRUETOK 281 -#define FALSETOK 282 -#define BEGINTOK 283 -#define ENDTOK 284 -#define DECLARE 285 -#define GLOBAL 286 -#define CONSTANT 287 -#define SECTION 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 ALIGN 308 -#define DEPLIBS 309 -#define CALL 310 -#define TAIL 311 -#define ASM_TOK 312 -#define MODULE 313 -#define SIDEEFFECT 314 -#define CC_TOK 315 -#define CCC_TOK 316 -#define FASTCC_TOK 317 -#define COLDCC_TOK 318 -#define RET 319 -#define BR 320 -#define SWITCH 321 -#define INVOKE 322 -#define UNWIND 323 -#define UNREACHABLE 324 -#define ADD 325 -#define SUB 326 -#define MUL 327 -#define DIV 328 -#define REM 329 -#define AND 330 -#define OR 331 -#define XOR 332 -#define SETLE 333 -#define SETGE 334 -#define SETLT 335 -#define SETGT 336 -#define SETEQ 337 -#define SETNE 338 -#define MALLOC 339 -#define ALLOCA 340 -#define FREE 341 -#define LOAD 342 -#define STORE 343 -#define GETELEMENTPTR 344 -#define PHI_TOK 345 -#define CAST 346 -#define SELECT 347 -#define SHL 348 -#define SHR 349 -#define VAARG 350 -#define EXTRACTELEMENT 351 -#define INSERTELEMENT 352 -#define VAARG_old 353 -#define VANEXT_old 354 - -#line 14 "/Volumes/ProjectsDisk/cvs/llvm/lib/AsmParser/llvmAsmParser.y" - -#include "ParserInternals.h" -#include "llvm/CallingConv.h" -#include "llvm/InlineAsm.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/SymbolTable.h" -#include "llvm/Assembly/AutoUpgrade.h" -#include "llvm/Support/GetElementPtrTypeIterator.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/MathExtras.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; -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 -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); - } - - // Look for intrinsic functions and CallInst that need to be upgraded - for (Module::iterator FI = CurrentModule->begin(),FE = CurrentModule->end(); - FI != FE; ++FI) - UpgradeCallsToIntrinsic(FI); - - 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::ConstZeroVal: // Is it a zero value? - return Constant::getNullValue(Ty); - - case ValID::ConstantVal: // Fully resolved constant? - if (D.ConstantValue->getType() != Ty) - ThrowException("Constant expression type different from required type!"); - return D.ConstantValue; - - case ValID::InlineAsmVal: { // Inline asm expression - const PointerType *PTy = dyn_cast<PointerType>(Ty); - const FunctionType *FTy = - PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0; - if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints)) - ThrowException("Invalid type for asm constraint string!"); - InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints, - D.IAD->HasSideEffects); - D.destroy(); // Free InlineAsmDescriptor. - return IA; - } - 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 GlobalVariable * -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 GV; - } - - // 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 EGV; - } - - 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); - return GV; -} - -// 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, (Type *)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); - Value* foo = new LoadInst(bar, "vastart.fix.2", CI); - CI->replaceAllUsesWith(foo); - CI->getParent()->getInstList().erase(CI); - } - Result->getFunctionList().erase(F); - } - - if(Function* F = Result->getNamedFunction("llvm.va_end")) { - if(F->arg_size() != 1) - ThrowException("Obsolete va_end takes 1 argument!"); - - //vaend foo - // -> - //bar = alloca 1 of typeof(foo) - //vaend bar - const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); - const Type* ArgTy = F->getFunctionType()->getParamType(0); - const Type* ArgTyPtr = PointerType::get(ArgTy); - Function* NF = Result->getOrInsertFunction("llvm.va_end", - RetTy, ArgTyPtr, (Type *)0); - - while (!F->use_empty()) { - CallInst* CI = cast<CallInst>(F->use_back()); - AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); - new StoreInst(CI->getOperand(1), bar, CI); - new CallInst(NF, bar, "", CI); - CI->getParent()->getInstList().erase(CI); - } - Result->getFunctionList().erase(F); - } - - if(Function* F = Result->getNamedFunction("llvm.va_copy")) { - if(F->arg_size() != 1) - ThrowException("Obsolete va_copy takes 1 argument!"); - //foo = vacopy(bar) - // -> - //a = alloca 1 of typeof(foo) - //b = alloca 1 of typeof(foo) - //store bar -> b - //vacopy(a, b) - //foo = load a - - 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_copy", - RetTy, ArgTyPtr, ArgTyPtr, - (Type *)0); - - while (!F->use_empty()) { - CallInst* CI = cast<CallInst>(F->use_back()); - AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", |