aboutsummaryrefslogtreecommitdiff
path: root/lib/AsmParser/llvmAsmParser.cpp.cvs
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-02 07:01:27 +0000
committerChris Lattner <sabre@nondot.org>2009-01-02 07:01:27 +0000
commitdf98617b23315e427cc4fad8ccfdd50d68bec2f9 (patch)
tree7ff121d47bf96432f608d5059916d6b7062e6d36 /lib/AsmParser/llvmAsmParser.cpp.cvs
parentccb6976a69a6e146db049fff8e6338e31c91b6f8 (diff)
Reimplement the old and horrible bison parser for .ll files with a nice
and clean recursive descent parser. This change has a couple of ramifications: 1. The parser code is about 400 lines shorter (in what we maintain, not including what is autogenerated). 2. The code should be significantly faster than the old code because we don't have to work around bison's poor handling of datatypes with ctors/dtors. This also makes the code much more resistant to memory leaks. 3. We now get caret diagnostics from the .ll parser, woo. 4. The actual diagnostics emited from the parser are completely different so a bunch of testcases had to be updated. 5. I now disallow "%ty = type opaque %ty = type i32". There was no good reason to support this, it was just an accident of the old implementation. I have no reason to think that anyone is actually using this. 6. The syntax for sticking a global variable has changed to make it unambiguous. I don't think anyone is depending on this since only clang supports this and it is not solid yet, so I'm not worried about anything breaking. 7. This gets rid of the last use of bison, and along with it the .cvs files. I'll prune this from the makefiles as a subsequent commit. There are a few minor cleanups that can be done after this commit (suggestions welcome!) but this passes dejagnu testing and is ready for its time in the limelight. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61558 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser/llvmAsmParser.cpp.cvs')
-rw-r--r--lib/AsmParser/llvmAsmParser.cpp.cvs7375
1 files changed, 0 insertions, 7375 deletions
diff --git a/lib/AsmParser/llvmAsmParser.cpp.cvs b/lib/AsmParser/llvmAsmParser.cpp.cvs
deleted file mode 100644
index 07a73bcf27..0000000000
--- a/lib/AsmParser/llvmAsmParser.cpp.cvs
+++ /dev/null
@@ -1,7375 +0,0 @@
-/* A Bison parser, made by GNU Bison 2.3. */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
- 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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-/* As a special exception, you may create a larger work that contains
- part or all of the Bison parser skeleton and distribute that work
- under terms of your choice, so long as that work isn't itself a
- parser generator using the skeleton or a modified version thereof
- as a parser skeleton. Alternatively, if you modify or redistribute
- the parser skeleton itself, you may (at your option) remove this
- special exception, which will cause the skeleton and the resulting
- Bison output files to be licensed under the GNU General Public
- License without this special exception.
-
- This special exception was added by the Free Software Foundation in
- version 2.2 of Bison. */
-
-/* C LALR(1) parser skeleton 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
-
-/* Bison version. */
-#define YYBISON_VERSION "2.3"
-
-/* Skeleton name. */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers. */
-#define YYPURE 0
-
-/* Using locations. */
-#define YYLSP_NEEDED 0
-
-/* Substitute the variable and function 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,
- ESAPINTVAL = 260,
- EUAPINTVAL = 261,
- LOCALVAL_ID = 262,
- GLOBALVAL_ID = 263,
- FPVAL = 264,
- VOID = 265,
- INTTYPE = 266,
- FLOAT = 267,
- DOUBLE = 268,
- X86_FP80 = 269,
- FP128 = 270,
- PPC_FP128 = 271,
- LABEL = 272,
- TYPE = 273,
- LOCALVAR = 274,
- GLOBALVAR = 275,
- LABELSTR = 276,
- STRINGCONSTANT = 277,
- ATSTRINGCONSTANT = 278,
- PCTSTRINGCONSTANT = 279,
- ZEROINITIALIZER = 280,
- TRUETOK = 281,
- FALSETOK = 282,
- BEGINTOK = 283,
- ENDTOK = 284,
- DECLARE = 285,
- DEFINE = 286,
- GLOBAL = 287,
- CONSTANT = 288,
- SECTION = 289,
- ALIAS = 290,
- VOLATILE = 291,
- THREAD_LOCAL = 292,
- TO = 293,
- DOTDOTDOT = 294,
- NULL_TOK = 295,
- UNDEF = 296,
- INTERNAL = 297,
- LINKONCE = 298,
- WEAK = 299,
- APPENDING = 300,
- DLLIMPORT = 301,
- DLLEXPORT = 302,
- EXTERN_WEAK = 303,
- COMMON = 304,
- OPAQUE = 305,
- EXTERNAL = 306,
- TARGET = 307,
- TRIPLE = 308,
- ALIGN = 309,
- ADDRSPACE = 310,
- DEPLIBS = 311,
- CALL = 312,
- TAIL = 313,
- ASM_TOK = 314,
- MODULE = 315,
- SIDEEFFECT = 316,
- CC_TOK = 317,
- CCC_TOK = 318,
- FASTCC_TOK = 319,
- COLDCC_TOK = 320,
- X86_STDCALLCC_TOK = 321,
- X86_FASTCALLCC_TOK = 322,
- DATALAYOUT = 323,
- RET = 324,
- BR = 325,
- SWITCH = 326,
- INVOKE = 327,
- UNWIND = 328,
- UNREACHABLE = 329,
- ADD = 330,
- SUB = 331,
- MUL = 332,
- UDIV = 333,
- SDIV = 334,
- FDIV = 335,
- UREM = 336,
- SREM = 337,
- FREM = 338,
- AND = 339,
- OR = 340,
- XOR = 341,
- SHL = 342,
- LSHR = 343,
- ASHR = 344,
- ICMP = 345,
- FCMP = 346,
- VICMP = 347,
- VFCMP = 348,
- EQ = 349,
- NE = 350,
- SLT = 351,
- SGT = 352,
- SLE = 353,
- SGE = 354,
- ULT = 355,
- UGT = 356,
- ULE = 357,
- UGE = 358,
- OEQ = 359,
- ONE = 360,
- OLT = 361,
- OGT = 362,
- OLE = 363,
- OGE = 364,
- ORD = 365,
- UNO = 366,
- UEQ = 367,
- UNE = 368,
- MALLOC = 369,
- ALLOCA = 370,
- FREE = 371,
- LOAD = 372,
- STORE = 373,
- GETELEMENTPTR = 374,
- TRUNC = 375,
- ZEXT = 376,
- SEXT = 377,
- FPTRUNC = 378,
- FPEXT = 379,
- BITCAST = 380,
- UITOFP = 381,
- SITOFP = 382,
- FPTOUI = 383,
- FPTOSI = 384,
- INTTOPTR = 385,
- PTRTOINT = 386,
- PHI_TOK = 387,
- SELECT = 388,
- VAARG = 389,
- EXTRACTELEMENT = 390,
- INSERTELEMENT = 391,
- SHUFFLEVECTOR = 392,
- GETRESULT = 393,
- EXTRACTVALUE = 394,
- INSERTVALUE = 395,
- SIGNEXT = 396,
- ZEROEXT = 397,
- NORETURN = 398,
- INREG = 399,
- SRET = 400,
- NOUNWIND = 401,
- NOALIAS = 402,
- NOCAPTURE = 403,
- BYVAL = 404,
- READNONE = 405,
- READONLY = 406,
- GC = 407,
- OPTSIZE = 408,
- NOINLINE = 409,
- ALWAYSINLINE = 410,
- SSP = 411,
- SSPREQ = 412,
- NEST = 413,
- DEFAULT = 414,
- HIDDEN = 415,
- PROTECTED = 416
- };
-#endif
-/* Tokens. */
-#define ESINT64VAL 258
-#define EUINT64VAL 259
-#define ESAPINTVAL 260
-#define EUAPINTVAL 261
-#define LOCALVAL_ID 262
-#define GLOBALVAL_ID 263
-#define FPVAL 264
-#define VOID 265
-#define INTTYPE 266
-#define FLOAT 267
-#define DOUBLE 268
-#define X86_FP80 269
-#define FP128 270
-#define PPC_FP128 271
-#define LABEL 272
-#define TYPE 273
-#define LOCALVAR 274
-#define GLOBALVAR 275
-#define LABELSTR 276
-#define STRINGCONSTANT 277
-#define ATSTRINGCONSTANT 278
-#define PCTSTRINGCONSTANT 279
-#define ZEROINITIALIZER 280
-#define TRUETOK 281
-#define FALSETOK 282
-#define BEGINTOK 283
-#define ENDTOK 284
-#define DECLARE 285
-#define DEFINE 286
-#define GLOBAL 287
-#define CONSTANT 288
-#define SECTION 289
-#define ALIAS 290
-#define VOLATILE 291
-#define THREAD_LOCAL 292
-#define TO 293
-#define DOTDOTDOT 294
-#define NULL_TOK 295
-#define UNDEF 296
-#define INTERNAL 297
-#define LINKONCE 298
-#define WEAK 299
-#define APPENDING 300
-#define DLLIMPORT 301
-#define DLLEXPORT 302
-#define EXTERN_WEAK 303
-#define COMMON 304
-#define OPAQUE 305
-#define EXTERNAL 306
-#define TARGET 307
-#define TRIPLE 308
-#define ALIGN 309
-#define ADDRSPACE 310
-#define DEPLIBS 311
-#define CALL 312
-#define TAIL 313
-#define ASM_TOK 314
-#define MODULE 315
-#define SIDEEFFECT 316
-#define CC_TOK 317
-#define CCC_TOK 318
-#define FASTCC_TOK 319
-#define COLDCC_TOK 320
-#define X86_STDCALLCC_TOK 321
-#define X86_FASTCALLCC_TOK 322
-#define DATALAYOUT 323
-#define RET 324
-#define BR 325
-#define SWITCH 326
-#define INVOKE 327
-#define UNWIND 328
-#define UNREACHABLE 329
-#define ADD 330
-#define SUB 331
-#define MUL 332
-#define UDIV 333
-#define SDIV 334
-#define FDIV 335
-#define UREM 336
-#define SREM 337
-#define FREM 338
-#define AND 339
-#define OR 340
-#define XOR 341
-#define SHL 342
-#define LSHR 343
-#define ASHR 344
-#define ICMP 345
-#define FCMP 346
-#define VICMP 347
-#define VFCMP 348
-#define EQ 349
-#define NE 350
-#define SLT 351
-#define SGT 352
-#define SLE 353
-#define SGE 354
-#define ULT 355
-#define UGT 356
-#define ULE 357
-#define UGE 358
-#define OEQ 359
-#define ONE 360
-#define OLT 361
-#define OGT 362
-#define OLE 363
-#define OGE 364
-#define ORD 365
-#define UNO 366
-#define UEQ 367
-#define UNE 368
-#define MALLOC 369
-#define ALLOCA 370
-#define FREE 371
-#define LOAD 372
-#define STORE 373
-#define GETELEMENTPTR 374
-#define TRUNC 375
-#define ZEXT 376
-#define SEXT 377
-#define FPTRUNC 378
-#define FPEXT 379
-#define BITCAST 380
-#define UITOFP 381
-#define SITOFP 382
-#define FPTOUI 383
-#define FPTOSI 384
-#define INTTOPTR 385
-#define PTRTOINT 386
-#define PHI_TOK 387
-#define SELECT 388
-#define VAARG 389
-#define EXTRACTELEMENT 390
-#define INSERTELEMENT 391
-#define SHUFFLEVECTOR 392
-#define GETRESULT 393
-#define EXTRACTVALUE 394
-#define INSERTVALUE 395
-#define SIGNEXT 396
-#define ZEROEXT 397
-#define NORETURN 398
-#define INREG 399
-#define SRET 400
-#define NOUNWIND 401
-#define NOALIAS 402
-#define NOCAPTURE 403
-#define BYVAL 404
-#define READNONE 405
-#define READONLY 406
-#define GC 407
-#define OPTSIZE 408
-#define NOINLINE 409
-#define ALWAYSINLINE 410
-#define SSP 411
-#define SSPREQ 412
-#define NEST 413
-#define DEFAULT 414
-#define HIDDEN 415
-#define PROTECTED 416
-
-
-
-
-/* Copy the first part of user declarations. */
-#line 14 "/home/nicholas/llvm-commit/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/ValueSymbolTable.h"
-#include "llvm/AutoUpgrade.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Streams.h"
-#include <algorithm>
-#include <list>
-#include <map>
-#include <utility>
-
-// The following is a gross hack. In order to rid the libAsmParser library of
-// exceptions, we have to have a way of getting the yyparse function to go into
-// an error situation. So, whenever we want an error to occur, the GenerateError
-// function (see bottom of file) sets TriggerError. Then, at the end of each
-// production in the grammer we use CHECK_FOR_ERROR which will invoke YYERROR
-// (a goto) to put YACC in error state. Furthermore, several calls to
-// GenerateError are made from inside productions and they must simulate the
-// previous exception behavior by exiting the production immediately. We have
-// replaced these with the GEN_ERROR macro which calls GeneratError and then
-// immediately invokes YYERROR. This would be so much cleaner if it was a
-// recursive descent parser.
-static bool TriggerError = false;
-#define CHECK_FOR_ERROR { if (TriggerError) { TriggerError = false; YYABORT; } }
-#define GEN_ERROR(msg) { GenerateError(msg); YYERROR; }
-
-int yyerror(const char *ErrorMsg); // Forward declarations to prevent "implicit
-int yylex(); // declaration" of xxx warnings.
-int yyparse();
-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) cerr << X
-#else
-#define UR_OUT(X)
-#endif
-
-#define YYERROR_VERBOSE 1
-
-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(ValueList &LateResolvers, ValueList *FutureLateResolvers=0);
-
-static struct PerModuleInfo {
- Module *CurrentModule;
- ValueList Values; // Module level numbered definitions
- ValueList LateResolveValues;
- std::vector<PATypeHolder> Types;
- std::map<ValID, PATypeHolder> LateResolveTypes;
-
- /// PlaceHolderInfo - When temporary placeholder objects are created, remember
- /// how they were referenced and on which line of the input they came from so
- /// that we can resolve them later and print error messages as appropriate.
- std::map<Value*, std::pair<ValID, int> > PlaceHolderInfo;
-
- // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
- // references to global values. Global values may be referenced before they
- // are defined, and if so, the temporary object that they represent is held
- // here. This is used for forward references of GlobalValues.
- //
- typedef std::map<std::pair<const PointerType *,
- ValID>, GlobalValue*> GlobalRefsType;
- GlobalRefsType GlobalRefs;
-
- void ModuleDone() {
- // If we could not resolve some functions at function compilation time
- // (calls to functions before they are defined), resolve them now... Types
- // are resolved when the constant pool has been completely parsed.
- //
- ResolveDefinitions(LateResolveValues);
- if (TriggerError)
- return;
-
- // 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";
- }
- GenerateError(UndefinedReferences);
- return;
- }
-
- // Look for intrinsic functions and CallInst that need to be upgraded
- for (Module::iterator FI = CurrentModule->begin(),
- FE = CurrentModule->end(); FI != FE; )
- UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
-
- 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;
- I->first.second.destroy();
- GlobalRefs.erase(I);
- }
- return Ret;
- }
-
- bool TypeIsUnresolved(PATypeHolder* PATy) {
- // If it isn't abstract, its resolved
- const Type* Ty = PATy->get();
- if (!Ty->isAbstract())
- return false;
- // Traverse the type looking for abstract types. If it isn't abstract then
- // we don't need to traverse that leg of the type.
- std::vector<const Type*> WorkList, SeenList;
- WorkList.push_back(Ty);
- while (!WorkList.empty()) {
- const Type* Ty = WorkList.back();
- SeenList.push_back(Ty);
- WorkList.pop_back();
- if (const OpaqueType* OpTy = dyn_cast<OpaqueType>(Ty)) {
- // Check to see if this is an unresolved type
- std::map<ValID, PATypeHolder>::iterator I = LateResolveTypes.begin();
- std::map<ValID, PATypeHolder>::iterator E = LateResolveTypes.end();
- for ( ; I != E; ++I) {
- if (I->second.get() == OpTy)
- return true;
- }
- } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(Ty)) {
- const Type* TheTy = SeqTy->getElementType();
- if (TheTy->isAbstract() && TheTy != Ty) {
- std::vector<const Type*>::iterator I = SeenList.begin(),
- E = SeenList.end();
- for ( ; I != E; ++I)
- if (*I == TheTy)
- break;
- if (I == E)
- WorkList.push_back(TheTy);
- }
- } else if (const StructType* StrTy = dyn_cast<StructType>(Ty)) {
- for (unsigned i = 0; i < StrTy->getNumElements(); ++i) {
- const Type* TheTy = StrTy->getElementType(i);
- if (TheTy->isAbstract() && TheTy != Ty) {
- std::vector<const Type*>::iterator I = SeenList.begin(),
- E = SeenList.end();
- for ( ; I != E; ++I)
- if (*I == TheTy)
- break;
- if (I == E)
- WorkList.push_back(TheTy);
- }
- }
- }
- }
- return false;
- }
-} CurModule;
-
-static struct PerFunctionInfo {
- Function *CurrentFunction; // Pointer to current function being created
-
- ValueList Values; // Keep track of #'d definitions
- unsigned NextValNum;
- ValueList LateResolveValues;
- bool isDeclare; // Is this function a forward declararation?
- GlobalValue::LinkageTypes Linkage; // Linkage for forward declaration.
- GlobalValue::VisibilityTypes Visibility;
-
- /// BBForwardRefs - When we see forward references to basic blocks, keep
- /// track of them here.
- std::map<ValID, BasicBlock*> BBForwardRefs;
-
- inline PerFunctionInfo() {
- CurrentFunction = 0;
- isDeclare = false;
- Linkage = GlobalValue::ExternalLinkage;
- Visibility = GlobalValue::DefaultVisibility;
- }
-
- inline void FunctionStart(Function *M) {
- CurrentFunction = M;
- NextValNum = 0;
- }
-
- void FunctionDone() {
- // Any forward referenced blocks left?
- if (!BBForwardRefs.empty()) {
- GenerateError("Undefined reference to label " +
- BBForwardRefs.begin()->second->getName());
- return;
- }
-
- // Resolve all forward references now.
- ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues);
-
- Values.clear(); // Clear out function local definitions
- BBForwardRefs.clear();
- CurrentFunction = 0;
- isDeclare = false;
- Linkage = GlobalValue::ExternalLinkage;
- Visibility = GlobalValue::DefaultVisibility;
- }
-} CurFun; // Info for the current function...
-
-static bool inFunctionScope() { return CurFun.CurrentFunction != 0; }
-
-
-//===----------------------------------------------------------------------===//
-// Code to handle definitions of all the types
-//===----------------------------------------------------------------------===//
-
-/// InsertValue - Insert a value into the value table. If it is named, this
-/// returns -1, otherwise it returns the slot number for the value.
-static int InsertValue(Value *V, ValueList &ValueTab = CurFun.Values) {
- // Things that have names or are void typed don't get slot numbers
- if (V->hasName() || (V->getType() == Type::VoidTy))
- return -1;
-
- // In the case of function values, we have to allow for the forward reference
- // of basic blocks, which are included in the numbering. Consequently, we keep
- // track of the next insertion location with NextValNum. When a BB gets
- // inserted, it could change the size of the CurFun.Values vector.
- if (&ValueTab == &CurFun.Values) {
- if (ValueTab.size() <= CurFun.NextValNum)
- ValueTab.resize(CurFun.NextValNum+1);
- ValueTab[CurFun.NextValNum++] = V;
- return CurFun.NextValNum-1;
- }
- // For all other lists, its okay to just tack it on the back of the vector.
- ValueTab.push_back(V);
- return ValueTab.size()-1;
-}
-
-static const Type *getTypeVal(const ValID &D, bool DoNotImprovise = false) {
- switch (D.Type) {
- case ValID::LocalID: // Is it a numbered definition?
- // Module constants occupy the lowest numbered slots...
- if (D.Num < CurModule.Types.size())
- return CurModule.Types[D.Num];
- break;
- case ValID::LocalName: // Is it a named definition?
- if (const Type *N = CurModule.CurrentModule->getTypeByName(D.getName())) {
- D.destroy(); // Free old strdup'd memory...
- return N;
- }
- break;
- default:
- GenerateError("Internal parser error: Invalid symbol type reference");
- return 0;
- }
-
- // If we reached here, we referenced either a symbol that we don't know about
- // or an id number that hasn't been read yet. We may be referencing something
- // forward, so just create an entry to be resolved later and get to it...
- //
- if (DoNotImprovise) return 0; // Do we just want a null to be returned?
-
-
- if (inFunctionScope()) {
- if (D.Type == ValID::LocalName) {
- GenerateError("Reference to an undefined type: '" + D.getName() + "'");
- return 0;
- } else {
- GenerateError("Reference to an undefined type: #" + utostr(D.Num));
- return 0;
- }
- }
-
- std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D);
- if (I != CurModule.LateResolveTypes.end()) {
- D.destroy();
- return I->second;
- }
-
- Type *Typ = OpaqueType::get();
- CurModule.LateResolveTypes.insert(std::make_pair(D, Typ));
- return Typ;
- }
-
-// getExistingVal - 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 *getExistingVal(const Type *Ty, const ValID &D) {
- if (isa<FunctionType>(Ty)) {
- GenerateError("Functions are not values and "
- "must be referenced as pointers");
- return 0;
- }
-
- switch (D.Type) {
- case ValID::LocalID: { // Is it a numbered definition?
- // Check that the number is within bounds.
- if (D.Num >= CurFun.Values.size())
- return 0;
- Value *Result = CurFun.Values[D.Num];
- if (Ty != Result->getType()) {
- GenerateError("Numbered value (%" + utostr(D.Num) + ") of type '" +
- Result->getType()->getDescription() + "' does not match "
- "expected type, '" + Ty->getDescription() + "'");
- return 0;
- }
- return Result;
- }
- case ValID::GlobalID: { // Is it a numbered definition?
- if (D.Num >= CurModule.Values.size())
- return 0;
- Value *Result = CurModule.Values[D.Num];
- if (Ty != Result->getType()) {
- GenerateError("Numbered value (@" + utostr(D.Num) + ") of type '" +
- Result->getType()->getDescription() + "' does not match "
- "expected type, '" + Ty->getDescription() + "'");
- return 0;
- }
- return Result;
- }
-
- case ValID::LocalName: { // Is it a named definition?
- if (!inFunctionScope())
- return 0;
- ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable();
- Value *N = SymTab.lookup(D.getName());
- if (N == 0)
- return 0;
- if (N->getType() != Ty)
- return 0;
-
- D.destroy(); // Free old strdup'd memory...
- return N;
- }
- case ValID::GlobalName: { // Is it a named definition?
- ValueSymbolTable &SymTab = CurModule.CurrentModule->getValueSymbolTable();
- Value *N = SymTab.lookup(D.getName());
- if (N == 0)
- return 0;
- if (N->getType() != Ty)
- 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 (!isa<IntegerType>(Ty) ||
- !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
- GenerateError("Signed integral constant '" +
- itostr(D.ConstPool64) + "' is invalid for type '" +
- Ty->getDescription() + "'");
- return 0;
- }
- return ConstantInt::get(Ty, D.ConstPool64, true);
-
- case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
- if (isa<IntegerType>(Ty) &&
- ConstantInt::isValueValidForType(Ty, D.UConstPool64))
- return ConstantInt::get(Ty, D.UConstPool64);
-
- if (!isa<IntegerType>(Ty) ||
- !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
- GenerateError("Integral constant '" + utostr(D.UConstPool64) +
- "' is invalid or out of range for type '" +
- Ty->getDescription() + "'");
- return 0;
- }
- // This is really a signed reference. Transmogrify.
- return ConstantInt::get(Ty, D.ConstPool64, true);
-
- case ValID::ConstAPInt: // Is it an unsigned const pool reference?
- if (!isa<IntegerType>(Ty)) {
- GenerateError("Integral constant '" + D.getName() +
- "' is invalid or out of range for type '" +
- Ty->getDescription() + "'");
- return 0;
- }
-
- {
- APSInt Tmp = *D.ConstPoolInt;
- D.destroy();
- Tmp.extOrTrunc(Ty->getPrimitiveSizeInBits());
- return ConstantInt::get(Tmp);
- }
-
- case ValID::ConstFPVal: // Is it a floating point const pool reference?
- if (!Ty->isFloatingPoint() ||
- !ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) {
- GenerateError("FP constant invalid for type");
- return 0;
- }
- // Lexer has no type info, so builds all float and double FP constants
- // as double. Fix this here. Long double does not need this.
- if (&D.ConstPoolFP->getSemantics() == &APFloat::IEEEdouble &&
- Ty==Type::FloatTy) {
- bool ignored;
- D.ConstPoolFP->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
- &ignored);
- }
- {
- ConstantFP *tmp = ConstantFP::get(*D.ConstPoolFP);
- D.destroy();
- return tmp;
- }
-
- case ValID::ConstNullVal: // Is it a null value?
- if (!isa<PointerType>(Ty)) {
- GenerateError("Cannot create a a non pointer null");
- return 0;
- }
- 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) {
- GenerateError("Constant expression type different from required type");
- return 0;
- }
- 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)) {
- GenerateError("Invalid type for asm constraint string");
- return 0;
- }
- 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 getExistingVal, 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) {
- GenerateError("Cannot use a basic block here");
- return 0;
- }
-
- // See if the value has already been defined.
- Value *V = getExistingVal(Ty, ID);
- if (V) return V;
- if (TriggerError) return 0;
-
- if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) {
- GenerateError("Invalid use of a non-first-class type");
- return 0;
- }
-
- // If we reached here, we referenced either a symbol that we don't know about
- // or an id number that hasn't been read yet. We may be referencing something
- // forward, so just create an entry to be resolved later and get to it...
- //
- switch (ID.Type) {
- case ValID::GlobalName:
- case ValID::GlobalID: {
- const PointerType *PTy = dyn_cast<PointerType>(Ty);
- if (!PTy) {
- GenerateError("Invalid type for reference to global" );
- return 0;
- }
- const Type* ElTy = PTy->getElementType();
- if (const FunctionType *FTy = dyn_cast<FunctionType>(ElTy))
- V = Function::Create(FTy, GlobalValue::ExternalLinkage);
- else
- V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "",
- (Module*)0, false, PTy->getAddressSpace());
- break;
- }
- default:
- 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,
- LLLgetLineNo())));
-
- if (inFunctionScope())
- InsertValue(V, CurFun.LateResolveValues);
- else
- InsertValue(V, CurModule.LateResolveValues);
- return V;
-}
-
-/// defineBBVal - This is a definition of a new basic block with the specified
-/// identifier which must be the same as CurFun.NextValNum, if its numeric.
-static BasicBlock *defineBBVal(const ValID &ID) {
- assert(inFunctionScope() && "Can't get basic block at global scope!");
-
- BasicBlock *BB = 0;
-
- // First, see if this was forward referenced
-
- std::map<ValID, BasicBlock*>::iterator BBI = CurFun.BBForwardRefs.find(ID);
- if (BBI != CurFun.BBForwardRefs.end()) {
- BB = BBI->second;
- // 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);
-
- // We're about to erase the entry, save the key so we can clean it up.
- ValID Tmp = BBI->first;
-
- // Erase the forward ref from the map as its no longer "forward"
- CurFun.BBForwardRefs.erase(ID);
-
- // The key has been removed from the map but so we don't want to leave
- // strdup'd memory around so destroy it too.
- Tmp.destroy();
-
- // If its a numbered definition, bump the number and set the BB value.
- if (ID.Type == ValID::LocalID) {
- assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
- InsertValue(BB);
- }
- } else {
- // We haven't seen this BB before and its first mention is a definition.
- // Just create it and return it.
- std::string Name (ID.Type == ValID::LocalName ? ID.getName() : "");
- BB = BasicBlock::Create(Name, CurFun.CurrentFunction);
- if (ID.Type == ValID::LocalID) {
- assert(ID.Num == CurFun.NextValNum && "Invalid new block number");
- InsertValue(BB);
- }
- }
-
- ID.destroy();
- return BB;
-}
-
-/// getBBVal - get an existing BB value or create a forward reference for it.
-///
-static BasicBlock *getBBVal(const ValID &ID) {
- assert(inFunctionScope() && "Can't get basic block at global scope!");
-
- BasicBlock *BB = 0;
-
- std::map<ValID, BasicBlock*>::iterator BBI = CurFun.BBForwardRefs.find(ID);
- if (BBI != CurFun.BBForwardRefs.end()) {
- BB = BBI->second;
- } if (ID.Type == ValID::LocalName) {
- std::string Name = ID.getName();
- Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name);
- if (N) {
- if (N->getType()->getTypeID() == Type::LabelTyID)
- BB = cast<BasicBlock>(N);
- else
- GenerateError("Reference to label '" + Name + "' is actually of type '"+
- N->getType()->getDescription() + "'");
- }
- } else if (ID.Type == ValID::LocalID) {
- if (ID.Num < CurFun.NextValNum && ID.Num < CurFun.Values.size()) {
- if (CurFun.Values[ID.Num]->getType()->getTypeID() == Type::LabelTyID)
- BB = cast<BasicBlock>(CurFun.Values[ID.Num]);
- else
- GenerateError("Reference to label '%" + utostr(ID.Num) +
- "' is actually of type '"+
- CurFun.Values[ID.Num]->getType()->getDescription() + "'");
- }
- } else {