aboutsummaryrefslogtreecommitdiff
path: root/lib/AsmParser/llvmAsmParser.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-02-15 07:22:58 +0000
committerChris Lattner <sabre@nondot.org>2006-02-15 07:22:58 +0000
commit58af2a1c5f084591bbc4c878134f6ffeea215628 (patch)
treedf61d18dde1b92e2f46aefe9afc895a5241f6355 /lib/AsmParser/llvmAsmParser.cpp
parent6599c75cccf24a2910a49be4eeb9085e8cfbdec8 (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.cpp4249
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",