diff --git a/include/llvm/Assembly/Parser.h b/include/llvm/Assembly/Parser.h index 904130d67ca..17484aee34e 100644 --- a/include/llvm/Assembly/Parser.h +++ b/include/llvm/Assembly/Parser.h @@ -20,6 +20,7 @@ namespace llvm { class Module; class ParseError; +class raw_ostream; /// This function is the main interface to the LLVM Assembly Parser. It parses /// an ASCII file that (presumably) contains LLVM Assembly code. It returns a @@ -29,7 +30,7 @@ class ParseError; /// @brief Parse LLVM Assembly from a file Module *ParseAssemblyFile( const std::string &Filename, ///< The name of the file to parse - ParseError* Error = 0 ///< If not null, an object to return errors in. + ParseError &Error ///< If not null, an object to return errors in. ); /// The function is a secondary interface to the LLVM Assembly Parser. It parses @@ -39,9 +40,9 @@ Module *ParseAssemblyFile( /// run the verifier after parsing the file to check that it is okay. /// @brief Parse LLVM Assembly from a string Module *ParseAssemblyString( - const char * AsmString, ///< The string containing assembly - Module * M, ///< A module to add the assembly too. - ParseError* Error = 0 ///< If not null, an object to return errors in. + const char *AsmString, ///< The string containing assembly + Module *M, ///< A module to add the assembly too. + ParseError &Error ///< If not null, an object to return errors in. ); //===------------------------------------------------------------------------=== @@ -58,6 +59,8 @@ public: ParseError() : Filename("unknown"), Message("none"), LineNo(0), ColumnNo(0) {} ParseError(const ParseError &E); + void setFilename(const std::string &F) { Filename = F; } + // getMessage - Return the message passed in at construction time plus extra // information extracted from the options used to parse with... // @@ -71,8 +74,12 @@ public: return Filename; } - void setError(const std::string &filename, const std::string &message, - int LineNo = -1, int ColNo = -1); + void setError(const std::string &message, int lineNo = -1, int ColNo = -1, + const std::string &FileContents = "") { + Message = message; + LineNo = lineNo; ColumnNo = ColNo; + LineContents = FileContents; + } // getErrorLocation - Return the line and column number of the error in the // input source file. The source filename can be derived from the @@ -82,13 +89,16 @@ public: inline void getErrorLocation(int &Line, int &Column) const { Line = LineNo; Column = ColumnNo; } + + void PrintError(const char *ProgName, raw_ostream &S); private : std::string Filename; std::string Message; int LineNo, ColumnNo; // -1 if not relevant + std::string LineContents; - ParseError &operator=(const ParseError &E); // objects by reference + void operator=(const ParseError &E); // DO NOT IMPLEMENT }; } // End llvm namespace diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index b8f497a5e90..da5b1584687 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -12,16 +12,36 @@ //===----------------------------------------------------------------------===// #include "LLLexer.h" -#include "ParserInternals.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instruction.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MathExtras.h" - -#include -#include "llvmAsmParser.h" - +#include "llvm/Support/raw_ostream.h" +#include "llvm/Assembly/Parser.h" #include using namespace llvm; +bool LLLexer::Error(LocTy ErrorLoc, const std::string &Msg) const { + // Scan backward to find the start of the line. + const char *LineStart = ErrorLoc; + while (LineStart != CurBuf->getBufferStart() && + LineStart[-1] != '\n' && LineStart[-1] != '\r') + --LineStart; + // Get the end of the line. + const char *LineEnd = ErrorLoc; + while (LineEnd != CurBuf->getBufferEnd() && + LineEnd[0] != '\n' && LineEnd[0] != '\r') + ++LineEnd; + + unsigned LineNo = 1; + for (const char *FP = CurBuf->getBufferStart(); FP != ErrorLoc; ++FP) + if (*FP == '\n') ++LineNo; + + std::string LineContents(LineStart, LineEnd); + ErrorInfo.setError(Msg, LineNo, ErrorLoc-LineStart, LineContents); + return true; +} + //===----------------------------------------------------------------------===// // Helper functions. //===----------------------------------------------------------------------===// @@ -30,21 +50,21 @@ using namespace llvm; // long representation... this does not have to do input error checking, // because we know that the input will be matched by a suitable regex... // -static uint64_t atoull(const char *Buffer, const char *End) { +uint64_t LLLexer::atoull(const char *Buffer, const char *End) { uint64_t Result = 0; for (; Buffer != End; Buffer++) { uint64_t OldRes = Result; Result *= 10; Result += *Buffer-'0'; if (Result < OldRes) { // Uh, oh, overflow detected!!! - GenerateError("constant bigger than 64 bits detected!"); + Error("constant bigger than 64 bits detected!"); return 0; } } return Result; } -static uint64_t HexIntToVal(const char *Buffer, const char *End) { +uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) { uint64_t Result = 0; for (; Buffer != End; ++Buffer) { uint64_t OldRes = Result; @@ -58,21 +78,15 @@ static uint64_t HexIntToVal(const char *Buffer, const char *End) { Result += C-'a'+10; if (Result < OldRes) { // Uh, oh, overflow detected!!! - GenerateError("constant bigger than 64 bits detected!"); + Error("constant bigger than 64 bits detected!"); return 0; } } return Result; } -// HexToFP - Convert the ascii string in hexadecimal format to the floating -// point representation of it. -// -static double HexToFP(const char *Buffer, const char *End) { - return BitsToDouble(HexIntToVal(Buffer, End)); // Cast Hex constant to double -} - -static void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]){ +void LLLexer::HexToIntPair(const char *Buffer, const char *End, + uint64_t Pair[2]) { Pair[0] = 0; for (int i=0; i<16; i++, Buffer++) { assert(Buffer != End); @@ -97,7 +111,7 @@ static void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]){ Pair[1] += C-'a'+10; } if (Buffer != End) - GenerateError("constant bigger than 128 bits detected!"); + Error("constant bigger than 128 bits detected!"); } // UnEscapeLexed - Run through the specified buffer and change \xx codes to the @@ -149,11 +163,8 @@ static const char *isLabelTail(const char *CurPtr) { // Lexer definition. //===----------------------------------------------------------------------===// -// FIXME: REMOVE THIS. -#define YYEOF 0 -#define YYERROR -2 - -LLLexer::LLLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) { +LLLexer::LLLexer(MemoryBuffer *StartBuf, ParseError &Err) + : CurBuf(StartBuf), ErrorInfo(Err), APFloatVal(0.0) { CurPtr = CurBuf->getBufferStart(); } @@ -174,34 +185,22 @@ int LLLexer::getNextChar() { // Otherwise, return end of file. --CurPtr; // Another call to lex will return EOF again. return EOF; - case '\n': - case '\r': - // Handle the newline character by ignoring it and incrementing the line - // count. However, be careful about 'dos style' files with \n\r in them. - // Only treat a \n\r or \r\n as a single line. - if ((*CurPtr == '\n' || (*CurPtr == '\r')) && - *CurPtr != CurChar) - ++CurPtr; // Eat the two char newline sequence. - - ++CurLineNo; - return '\n'; } } -int LLLexer::LexToken() { +lltok::Kind LLLexer::LexToken() { TokStart = CurPtr; int CurChar = getNextChar(); - switch (CurChar) { default: // Handle letters: [a-zA-Z_] if (isalpha(CurChar) || CurChar == '_') return LexIdentifier(); - return CurChar; - case EOF: return YYEOF; + return lltok::Error; + case EOF: return lltok::Eof; case 0: case ' ': case '\t': @@ -216,21 +215,21 @@ int LLLexer::LexToken() { case '.': if (const char *Ptr = isLabelTail(CurPtr)) { CurPtr = Ptr; - llvmAsmlval.StrVal = new std::string(TokStart, CurPtr-1); - return LABELSTR; + StrVal.assign(TokStart, CurPtr-1); + return lltok::LabelStr; } if (CurPtr[0] == '.' && CurPtr[1] == '.') { CurPtr += 2; - return DOTDOTDOT; + return lltok::dotdotdot; } - return '.'; + return lltok::Error; case '$': if (const char *Ptr = isLabelTail(CurPtr)) { CurPtr = Ptr; - llvmAsmlval.StrVal = new std::string(TokStart, CurPtr-1); - return LABELSTR; + StrVal.assign(TokStart, CurPtr-1); + return lltok::LabelStr; } - return '$'; + return lltok::Error; case ';': SkipLineComment(); return LexToken(); @@ -238,6 +237,18 @@ int LLLexer::LexToken() { case '5': case '6': case '7': case '8': case '9': case '-': return LexDigitOrNegative(); + case '=': return lltok::equal; + case '[': return lltok::lsquare; + case ']': return lltok::rsquare; + case '{': return lltok::lbrace; + case '}': return lltok::rbrace; + case '<': return lltok::less; + case '>': return lltok::greater; + case '(': return lltok::lparen; + case ')': return lltok::rparen; + case ',': return lltok::comma; + case '*': return lltok::star; + case '\\': return lltok::backslash; } } @@ -249,10 +260,10 @@ void LLLexer::SkipLineComment() { } /// LexAt - Lex all tokens that start with an @ character: -/// AtStringConstant @\"[^\"]*\" -/// GlobalVarName @[-a-zA-Z$._][-a-zA-Z$._0-9]* -/// GlobalVarID @[0-9]+ -int LLLexer::LexAt() { +/// GlobalVar @\"[^\"]*\" +/// GlobalVar @[-a-zA-Z$._][-a-zA-Z$._0-9]* +/// GlobalVarID @[0-9]+ +lltok::Kind LLLexer::LexAt() { // Handle AtStringConstant: @\"[^\"]*\" if (CurPtr[0] == '"') { ++CurPtr; @@ -261,13 +272,13 @@ int LLLexer::LexAt() { int CurChar = getNextChar(); if (CurChar == EOF) { - GenerateError("End of file in global variable name"); - return YYERROR; + Error("end of file in global variable name"); + return lltok::Error; } if (CurChar == '"') { - llvmAsmlval.StrVal = new std::string(TokStart+2, CurPtr-1); - UnEscapeLexed(*llvmAsmlval.StrVal); - return ATSTRINGCONSTANT; + StrVal.assign(TokStart+2, CurPtr-1); + UnEscapeLexed(StrVal); + return lltok::GlobalVar; } } } @@ -280,8 +291,8 @@ int LLLexer::LexAt() { CurPtr[0] == '.' || CurPtr[0] == '_') ++CurPtr; - llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr); // Skip @ - return GLOBALVAR; + StrVal.assign(TokStart+1, CurPtr); // Skip @ + return lltok::GlobalVar; } // Handle GlobalVarID: @[0-9]+ @@ -291,21 +302,21 @@ int LLLexer::LexAt() { uint64_t Val = atoull(TokStart+1, CurPtr); if ((unsigned)Val != Val) - GenerateError("Invalid value number (too large)!"); - llvmAsmlval.UIntVal = unsigned(Val); - return GLOBALVAL_ID; + Error("invalid value number (too large)!"); + UIntVal = unsigned(Val); + return lltok::GlobalID; } - return '@'; + return lltok::Error; } /// LexPercent - Lex all tokens that start with a % character: -/// PctStringConstant %\"[^\"]*\" -/// LocalVarName %[-a-zA-Z$._][-a-zA-Z$._0-9]* -/// LocalVarID %[0-9]+ -int LLLexer::LexPercent() { - // Handle PctStringConstant: %\"[^\"]*\" +/// LocalVar ::= %\"[^\"]*\" +/// LocalVar ::= %[-a-zA-Z$._][-a-zA-Z$._0-9]* +/// LocalVarID ::= %[0-9]+ +lltok::Kind LLLexer::LexPercent() { + // Handle LocalVarName: %\"[^\"]*\" if (CurPtr[0] == '"') { ++CurPtr; @@ -313,13 +324,13 @@ int LLLexer::LexPercent() { int CurChar = getNextChar(); if (CurChar == EOF) { - GenerateError("End of file in local variable name"); - return YYERROR; + Error("end of file in string constant"); + return lltok::Error; } if (CurChar == '"') { - llvmAsmlval.StrVal = new std::string(TokStart+2, CurPtr-1); - UnEscapeLexed(*llvmAsmlval.StrVal); - return PCTSTRINGCONSTANT; + StrVal.assign(TokStart+2, CurPtr-1); + UnEscapeLexed(StrVal); + return lltok::LocalVar; } } } @@ -332,8 +343,8 @@ int LLLexer::LexPercent() { CurPtr[0] == '.' || CurPtr[0] == '_') ++CurPtr; - llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr); // Skip % - return LOCALVAR; + StrVal.assign(TokStart+1, CurPtr); // Skip % + return lltok::LocalVar; } // Handle LocalVarID: %[0-9]+ @@ -343,38 +354,38 @@ int LLLexer::LexPercent() { uint64_t Val = atoull(TokStart+1, CurPtr); if ((unsigned)Val != Val) - GenerateError("Invalid value number (too large)!"); - llvmAsmlval.UIntVal = unsigned(Val); - return LOCALVAL_ID; + Error("invalid value number (too large)!"); + UIntVal = unsigned(Val); + return lltok::LocalVarID; } - return '%'; + return lltok::Error; } /// LexQuote - Lex all tokens that start with a " character: /// QuoteLabel "[^"]+": /// StringConstant "[^"]*" -int LLLexer::LexQuote() { +lltok::Kind LLLexer::LexQuote() { while (1) { int CurChar = getNextChar(); if (CurChar == EOF) { - GenerateError("End of file in quoted string"); - return YYERROR; + Error("end of file in quoted string"); + return lltok::Error; } if (CurChar != '"') continue; if (CurPtr[0] != ':') { - llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr-1); - UnEscapeLexed(*llvmAsmlval.StrVal); - return STRINGCONSTANT; + StrVal.assign(TokStart+1, CurPtr-1); + UnEscapeLexed(StrVal); + return lltok::StringConstant; } ++CurPtr; - llvmAsmlval.StrVal = new std::string(TokStart+1, CurPtr-2); - UnEscapeLexed(*llvmAsmlval.StrVal); - return LABELSTR; + StrVal.assign(TokStart+1, CurPtr-2); + UnEscapeLexed(StrVal); + return lltok::LabelStr; } } @@ -395,7 +406,7 @@ static bool JustWhitespaceNewLine(const char *&Ptr) { /// IntegerType i[0-9]+ /// Keyword sdiv, float, ... /// HexIntConstant [us]0x[0-9A-Fa-f]+ -int LLLexer::LexIdentifier() { +lltok::Kind LLLexer::LexIdentifier() { const char *StartChar = CurPtr; const char *IntEnd = CurPtr[-1] == 'i' ? 0 : StartChar; const char *KeywordEnd = 0; @@ -408,8 +419,8 @@ int LLLexer::LexIdentifier() { // If we stopped due to a colon, this really is a label. if (*CurPtr == ':') { - llvmAsmlval.StrVal = new std::string(StartChar-1, CurPtr++); - return LABELSTR; + StrVal.assign(StartChar-1, CurPtr++); + return lltok::LabelStr; } // Otherwise, this wasn't a label. If this was valid as an integer type, @@ -420,12 +431,11 @@ int LLLexer::LexIdentifier() { uint64_t NumBits = atoull(StartChar, CurPtr); if (NumBits < IntegerType::MIN_INT_BITS || NumBits > IntegerType::MAX_INT_BITS) { - GenerateError("Bitwidth for integer type out of range!"); - return YYERROR; + Error("bitwidth for integer type out of range!"); + return lltok::Error; } - const Type* Ty = IntegerType::get(NumBits); - llvmAsmlval.PrimType = Ty; - return INTTYPE; + TyVal = IntegerType::get(NumBits); + return lltok::Type; } // Otherwise, this was a letter sequence. See which keyword this is. @@ -433,112 +443,96 @@ int LLLexer::LexIdentifier() { CurPtr = KeywordEnd; --StartChar; unsigned Len = CurPtr-StartChar; -#define KEYWORD(STR, TOK) \ - if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) return TOK; +#define KEYWORD(STR) \ + if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) \ + return lltok::kw_##STR; - KEYWORD("begin", BEGINTOK); - KEYWORD("end", ENDTOK); - KEYWORD("true", TRUETOK); - KEYWORD("false", FALSETOK); - KEYWORD("declare", DECLARE); - KEYWORD("define", DEFINE); - KEYWORD("global", GLOBAL); - KEYWORD("constant", CONSTANT); + KEYWORD(begin); KEYWORD(end); + KEYWORD(true); KEYWORD(false); + KEYWORD(declare); KEYWORD(define); + KEYWORD(global); KEYWORD(constant); - KEYWORD("internal", INTERNAL); - KEYWORD("linkonce", LINKONCE); - KEYWORD("weak", WEAK); - KEYWORD("appending", APPENDING); - KEYWORD("dllimport", DLLIMPORT); - KEYWORD("dllexport", DLLEXPORT); - KEYWORD("common", COMMON); - KEYWORD("default", DEFAULT); - KEYWORD("hidden", HIDDEN); - KEYWORD("protected", PROTECTED); - KEYWORD("extern_weak", EXTERN_WEAK); - KEYWORD("external", EXTERNAL); - KEYWORD("thread_local", THREAD_LOCAL); - KEYWORD("zeroinitializer", ZEROINITIALIZER); - KEYWORD("undef", UNDEF); - KEYWORD("null", NULL_TOK); - KEYWORD("to", TO); - KEYWORD("tail", TAIL); - KEYWORD("target", TARGET); - KEYWORD("triple", TRIPLE); - KEYWORD("deplibs", DEPLIBS); - KEYWORD("datalayout", DATALAYOUT); - KEYWORD("volatile", VOLATILE); - KEYWORD("align", ALIGN); - KEYWORD("addrspace", ADDRSPACE); - KEYWORD("section", SECTION); - KEYWORD("alias", ALIAS); - KEYWORD("module", MODULE); - KEYWORD("asm", ASM_TOK); - KEYWORD("sideeffect", SIDEEFFECT); - KEYWORD("gc", GC); + KEYWORD(internal); + KEYWORD(linkonce); + KEYWORD(weak); + KEYWORD(appending); + KEYWORD(dllimport); + KEYWORD(dllexport); + KEYWORD(common); + KEYWORD(default); + KEYWORD(hidden); + KEYWORD(protected); + KEYWORD(extern_weak); + KEYWORD(external); + KEYWORD(thread_local); + KEYWORD(zeroinitializer); + KEYWORD(undef); + KEYWORD(null); + KEYWORD(to); + KEYWORD(tail); + KEYWORD(target); + KEYWORD(triple); + KEYWORD(deplibs); + KEYWORD(datalayout); + KEYWORD(volatile); + KEYWORD(align); + KEYWORD(addrspace); + KEYWORD(section); + KEYWORD(alias); + KEYWORD(module); + KEYWORD(asm); + KEYWORD(sideeffect); + KEYWORD(gc); - KEYWORD("cc", CC_TOK); - KEYWORD("ccc", CCC_TOK); - KEYWORD("fastcc", FASTCC_TOK); - KEYWORD("coldcc", COLDCC_TOK); - KEYWORD("x86_stdcallcc", X86_STDCALLCC_TOK); - KEYWORD("x86_fastcallcc", X86_FASTCALLCC_TOK); + KEYWORD(ccc); + KEYWORD(fastcc); + KEYWORD(coldcc); + KEYWORD(x86_stdcallcc); + KEYWORD(x86_fastcallcc); + KEYWORD(cc); + KEYWORD(c); - KEYWORD("signext", SIGNEXT); - KEYWORD("zeroext", ZEROEXT); - KEYWORD("inreg", INREG); - KEYWORD("sret", SRET); - KEYWORD("nounwind", NOUNWIND); - KEYWORD("noreturn", NORETURN); - KEYWORD("noalias", NOALIAS); - KEYWORD("nocapture", NOCAPTURE); - KEYWORD("byval", BYVAL); - KEYWORD("nest", NEST); - KEYWORD("readnone", READNONE); - KEYWORD("readonly", READONLY); + KEYWORD(signext); + KEYWORD(zeroext); + KEYWORD(inreg); + KEYWORD(sret); + KEYWORD(nounwind); + KEYWORD(noreturn); + KEYWORD(noalias); + KEYWORD(nocapture); + KEYWORD(byval); + KEYWORD(nest); + KEYWORD(readnone); + KEYWORD(readonly); - KEYWORD("noinline", NOINLINE); - KEYWORD("alwaysinline", ALWAYSINLINE); - KEYWORD("optsize", OPTSIZE); - KEYWORD("ssp", SSP); - KEYWORD("sspreq", SSPREQ); + KEYWORD(noinline); + KEYWORD(alwaysinline); + KEYWORD(optsize); + KEYWORD(ssp); + KEYWORD(sspreq); - KEYWORD("type", TYPE); - KEYWORD("opaque", OPAQUE); + KEYWORD(type); + KEYWORD(opaque); - KEYWORD("eq" , EQ); - KEYWORD("ne" , NE); - KEYWORD("slt", SLT); - KEYWORD("sgt", SGT); - KEYWORD("sle", SLE); - KEYWORD("sge", SGE); - KEYWORD("ult", ULT); - KEYWORD("ugt", UGT); - KEYWORD("ule", ULE); - KEYWORD("uge", UGE); - KEYWORD("oeq", OEQ); - KEYWORD("one", ONE); - KEYWORD("olt", OLT); - KEYWORD("ogt", OGT); - KEYWORD("ole", OLE); - KEYWORD("oge", OGE); - KEYWORD("ord", ORD); - KEYWORD("uno", UNO); - KEYWORD("ueq", UEQ); - KEYWORD("une", UNE); + KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle); + KEYWORD(sge); KEYWORD(ult); KEYWORD(ugt); KEYWORD(ule); KEYWORD(uge); + KEYWORD(oeq); KEYWORD(one); KEYWORD(olt); KEYWORD(ogt); KEYWORD(ole); + KEYWORD(oge); KEYWORD(ord); KEYWORD(uno); KEYWORD(ueq); KEYWORD(une); + + KEYWORD(x); #undef KEYWORD // Keywords for types. -#define TYPEKEYWORD(STR, LLVMTY, TOK) \ +#define TYPEKEYWORD(STR, LLVMTY) \ if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) { \ - llvmAsmlval.PrimType = LLVMTY; return TOK; } - TYPEKEYWORD("void", Type::VoidTy, VOID); - TYPEKEYWORD("float", Type::FloatTy, FLOAT); - TYPEKEYWORD("double", Type::DoubleTy, DOUBLE); - TYPEKEYWORD("x86_fp80", Type::X86_FP80Ty, X86_FP80); - TYPEKEYWORD("fp128", Type::FP128Ty, FP128); - TYPEKEYWORD("ppc_fp128", Type::PPC_FP128Ty, PPC_FP128); - TYPEKEYWORD("label", Type::LabelTy, LABEL); + TyVal = LLVMTY; return lltok::Type; } + TYPEKEYWORD("void", Type::VoidTy); + TYPEKEYWORD("float", Type::FloatTy); + TYPEKEYWORD("double", Type::DoubleTy); + TYPEKEYWORD("x86_fp80", Type::X86_FP80Ty); + TYPEKEYWORD("fp128", Type::FP128Ty); + TYPEKEYWORD("ppc_fp128", Type::PPC_FP128Ty); + TYPEKEYWORD("label", Type::LabelTy); #undef TYPEKEYWORD // Handle special forms for autoupgrading. Drop these in LLVM 3.0. This is @@ -546,74 +540,62 @@ int LLLexer::LexIdentifier() { if (Len == 4 && !memcmp(StartChar, "sext", 4)) { // Scan CurPtr ahead, seeing if there is just whitespace before the newline. if (JustWhitespaceNewLine(CurPtr)) - return SIGNEXT; + return lltok::kw_signext; } else if (Len == 4 && !memcmp(StartChar, "zext", 4)) { // Scan CurPtr ahead, seeing if there is just whitespace before the newline. if (JustWhitespaceNewLine(CurPtr)) - return ZEROEXT; + return lltok::kw_zeroext; } // Keywords for instructions. -#define INSTKEYWORD(STR, type, Enum, TOK) \ - if (Len == strlen(STR) && !memcmp(StartChar, STR, strlen(STR))) { \ - llvmAsmlval.type = Instruction::Enum; return TOK; } +#define INSTKEYWORD(STR, Enum) \ + if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) { \ + UIntVal = Instruction::Enum; return lltok::kw_##STR; } - INSTKEYWORD("add", BinaryOpVal, Add, ADD); - INSTKEYWORD("sub", BinaryOpVal, Sub, SUB); - INSTKEYWORD("mul", BinaryOpVal, Mul, MUL); - INSTKEYWORD("udiv", BinaryOpVal, UDiv, UDIV); - INSTKEYWORD("sdiv", BinaryOpVal, SDiv, SDIV); - INSTKEYWORD("fdiv", BinaryOpVal, FDiv, FDIV); - INSTKEYWORD("urem", BinaryOpVal, URem, UREM); - INSTKEYWORD("srem", BinaryOpVal, SRem, SREM); - INSTKEYWORD("frem", BinaryOpVal, FRem, FREM); - INSTKEYWORD("shl", BinaryOpVal, Shl, SHL); - INSTKEYWORD("lshr", BinaryOpVal, LShr, LSHR); - INSTKEYWORD("ashr", BinaryOpVal, AShr, ASHR); - INSTKEYWORD("and", BinaryOpVal, And, AND); - INSTKEYWORD("or", BinaryOpVal, Or , OR ); - INSTKEYWORD("xor", BinaryOpVal, Xor, XOR); - INSTKEYWORD("icmp", OtherOpVal, ICmp, ICMP); - INSTKEYWORD("fcmp", OtherOpVal, FCmp, FCMP); - INSTKEYWORD("vicmp", OtherOpVal, VICmp, VICMP); - INSTKEYWORD("vfcmp", OtherOpVal, VFCmp, VFCMP); + INSTKEYWORD(add, Add); INSTKEYWORD(sub, Sub); INSTKEYWORD(mul, Mul); + INSTKEYWORD(udiv, UDiv); INSTKEYWORD(sdiv, SDiv); INSTKEYWORD(fdiv, FDiv); + INSTKEYWORD(urem, URem); INSTKEYWORD(srem, SRem); INSTKEYWORD(frem, FRem); + INSTKEYWORD(shl, Shl); INSTKEYWORD(lshr, LShr); INSTKEYWORD(ashr, AShr); + INSTKEYWORD(and, And); INSTKEYWORD(or, Or); INSTKEYWORD(xor, Xor); + INSTKEYWORD(icmp, ICmp); INSTKEYWORD(fcmp, FCmp); + INSTKEYWORD(vicmp, VICmp); INSTKEYWORD(vfcmp, VFCmp); - INSTKEYWORD("phi", OtherOpVal, PHI, PHI_TOK); - INSTKEYWORD("call", OtherOpVal, Call, CALL); - INSTKEYWORD("trunc", CastOpVal, Trunc, TRUNC); - INSTKEYWORD("zext", CastOpVal, ZExt, ZEXT); - INSTKEYWORD("sext", CastOpVal, SExt, SEXT); - INSTKEYWORD("fptrunc", CastOpVal, FPTrunc, FPTRUNC); - INSTKEYWORD("fpext", CastOpVal, FPExt, FPEXT); - INSTKEYWORD("uitofp", CastOpVal, UIToFP, UITOFP); - INSTKEYWORD("sitofp", CastOpVal, SIToFP, SITOFP); - INSTKEYWORD("fptoui", CastOpVal, FPToUI, FPTOUI); - INSTKEYWORD("fptosi", CastOpVal, FPToSI, FPTOSI); - INSTKEYWORD("inttoptr", CastOpVal, IntToPtr, INTTOPTR); - INSTKEYWORD("ptrtoint", CastOpVal, PtrToInt, PTRTOINT); - INSTKEYWORD("bitcast", CastOpVal, BitCast, BITCAST); - INSTKEYWORD("select", OtherOpVal, Select, SELECT); - INSTKEYWORD("va_arg", OtherOpVal, VAArg , VAARG); - INSTKEYWORD("ret", TermOpVal, Ret, RET); - INSTKEYWORD("br", TermOpVal, Br, BR); - INSTKEYWORD("switch", TermOpVal, Switch, SWITCH); - INSTKEYWORD("invoke", TermOpVal, Invoke, INVOKE); - INSTKEYWORD("unwind", TermOpVal, Unwind, UNWIND); - INSTKEYWORD("unreachable", TermOpVal, Unreachable, UNREACHABLE); + INSTKEYWORD(phi, PHI); + INSTKEYWORD(call, Call); + INSTKEYWORD(trunc, Trunc); + INSTKEYWORD(zext, ZExt); + INSTKEYWORD(sext, SExt); + INSTKEYWORD(fptrunc, FPTrunc); + INSTKEYWORD(fpext, FPExt); + INSTKEYWORD(uitofp, UIToFP); + INSTKEYWORD(sitofp, SIToFP); + INSTKEYWORD(fptoui, FPToUI); + INSTKEYWORD(fptosi, FPToSI); + INSTKEYWORD(inttoptr, IntToPtr); + INSTKEYWORD(ptrtoint, PtrToInt); + INSTKEYWORD(bitcast, BitCast); + INSTKEYWORD(select, Select); + INSTKEYWORD(va_arg, VAArg); + INSTKEYWORD(ret, Ret); + INSTKEYWORD(br, Br); + INSTKEYWORD(switch, Switch); + INSTKEYWORD(invoke, Invoke); + INSTKEYWORD(unwind, Unwind); + INSTKEYWORD(unreachable, Unreachable); - INSTKEYWORD("malloc", MemOpVal, Malloc, MALLOC); - INSTKEYWORD("alloca", MemOpVal, Alloca, ALLOCA); - INSTKEYWORD("free", MemOpVal, Free, FREE); - INSTKEYWORD("load", MemOpVal, Load, LOAD); - INSTKEYWORD("store", MemOpVal, Store, STORE); - INSTKEYWORD("getelementptr", MemOpVal, GetElementPtr, GETELEMENTPTR); + INSTKEYWORD(malloc, Malloc); + INSTKEYWORD(alloca, Alloca); + INSTKEYWORD(free, Free); + INSTKEYWORD(load, Load); + INSTKEYWORD(store, Store); + INSTKEYWORD(getelementptr, GetElementPtr); - INSTKEYWORD("extractelement", OtherOpVal, ExtractElement, EXTRACTELEMENT); - INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT); - INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR); - INSTKEYWORD("getresult", OtherOpVal, ExtractValue, GETRESULT); - INSTKEYWORD("extractvalue", OtherOpVal, ExtractValue, EXTRACTVALUE); - INSTKEYWORD("insertvalue", OtherOpVal, InsertValue, INSERTVALUE); + INSTKEYWORD(extractelement, ExtractElement); + INSTKEYWORD(insertelement, InsertElement); + INSTKEYWORD(shufflevector, ShuffleVector); + INSTKEYWORD(getresult, ExtractValue); + INSTKEYWORD(extractvalue, ExtractValue); + INSTKEYWORD(insertvalue, InsertValue); #undef INSTKEYWORD // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by @@ -626,35 +608,27 @@ int LLLexer::LexIdentifier() { uint32_t activeBits = Tmp.getActiveBits(); if (activeBits > 0 && activeBits < bits) Tmp.trunc(activeBits); - if (Tmp.getBitWidth() > 64) { - llvmAsmlval.APIntVal = new APInt(Tmp); - return TokStart[0] == 's' ? ESAPINTVAL : EUAPINTVAL; - } else if (TokStart[0] == 's') { - llvmAsmlval.SInt64Val = Tmp.getSExtValue(); - return ESINT64VAL; - } else { - llvmAsmlval.UInt64Val = Tmp.getZExtValue(); - return EUINT64VAL; - } + APSIntVal = APSInt(Tmp, TokStart[0] == 'u'); + return lltok::APSInt; } // If this is "cc1234", return this as just "cc". if (TokStart[0] == 'c' && TokStart[1] == 'c') { CurPtr = TokStart+2; - return CC_TOK; + return lltok::kw_cc; } // If this starts with "call", return it as CALL. This is to support old // broken .ll files. FIXME: remove this with LLVM 3.0. if (CurPtr-TokStart > 4 && !memcmp(TokStart, "call", 4)) { CurPtr = TokStart+4; - llvmAsmlval.OtherOpVal = Instruction::Call; - return CALL; + UIntVal = Instruction::Call; + return lltok::kw_call; } - // Finally, if this isn't known, return just a single character. + // Finally, if this isn't known, return an error. CurPtr = TokStart+1; - return TokStart[0]; + return lltok::Error; } @@ -664,7 +638,7 @@ int LLLexer::LexIdentifier() { /// HexFP80Constant 0xK[0-9A-Fa-f]+ /// HexFP128Constant 0xL[0-9A-Fa-f]+ /// HexPPC128Constant 0xM[0-9A-Fa-f]+ -int LLLexer::Lex0x() { +lltok::Kind LLLexer::Lex0x() { CurPtr = TokStart + 2; char Kind; @@ -675,9 +649,9 @@ int LLLexer::Lex0x() { } if (!isxdigit(CurPtr[0])) { - // Bad token, return it as just zero. + // Bad token, return it as an error. CurPtr = TokStart+1; - return '0'; + return lltok::Error; } while (isxdigit(CurPtr[0])) @@ -687,8 +661,8 @@ int LLLexer::Lex0x() { // HexFPConstant - Floating point constant represented in IEEE format as a // hexadecimal number for when exponential notation is not precise enough. // Float and double only. - llvmAsmlval.FPVal = new APFloat(HexToFP(TokStart+2, CurPtr)); - return FPVAL; + APFloatVal = APFloat(BitsToDouble(HexIntToVal(TokStart+2, CurPtr))); + return lltok::APFloat; } uint64_t Pair[2]; @@ -697,16 +671,16 @@ int LLLexer::Lex0x() { default: assert(0 && "Unknown kind!"); case 'K': // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes) - llvmAsmlval.FPVal = new APFloat(APInt(80, 2, Pair)); - return FPVAL; + APFloatVal = APFloat(APInt(80, 2, Pair)); + return lltok::APFloat; case 'L': // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes) - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair), true); - return FPVAL; + APFloatVal = APFloat(APInt(128, 2, Pair), true); + return lltok::APFloat; case 'M': // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes) - llvmAsmlval.FPVal = new APFloat(APInt(128, 2, Pair)); - return FPVAL; + APFloatVal = APFloat(APInt(128, 2, Pair)); + return lltok::APFloat; } } @@ -719,17 +693,17 @@ int LLLexer::Lex0x() { /// HexFP80Constant 0xK[0-9A-Fa-f]+ /// HexFP128Constant 0xL[0-9A-Fa-f]+ /// HexPPC128Constant 0xM[0-9A-Fa-f]+ -int LLLexer::LexDigitOrNegative() { +lltok::Kind LLLexer::LexDigitOrNegative() { // If the letter after the negative is a number, this is probably a label. if (!isdigit(TokStart[0]) && !isdigit(CurPtr[0])) { // Okay, this is not a number after the -, it's probably a label. if (const char *End = isLabelTail(CurPtr)) { - llvmAsmlval.StrVal = new std::string(TokStart, End-1); + StrVal.assign(TokStart, End-1); CurPtr = End; - return LABELSTR; + return lltok::LabelStr; } - return CurPtr[-1]; + return lltok::Error; } // At this point, it is either a label, int or fp constant. @@ -741,9 +715,9 @@ int LLLexer::LexDigitOrNegative() { // Check to see if this really is a label afterall, e.g. "-1:". if (isLabelChar(CurPtr[0]) || CurPtr[0] == ':') { if (const char *End = isLabelTail(CurPtr)) { - llvmAsmlval.StrVal = new std::string(TokStart, End-1); + StrVal.assign(TokStart, End-1); CurPtr = End; - return LABELSTR; + return lltok::LabelStr; } } @@ -759,25 +733,14 @@ int LLLexer::LexDigitOrNegative() { uint32_t minBits = Tmp.getMinSignedBits(); if (minBits > 0 && minBits < numBits) Tmp.trunc(minBits); - if (Tmp.getBitWidth() > 64) { - llvmAsmlval.APIntVal = new APInt(Tmp); - return ESAPINTVAL; - } else { - llvmAsmlval.SInt64Val = Tmp.getSExtValue(); - return ESINT64VAL; - } + APSIntVal = APSInt(Tmp, false); } else { uint32_t activeBits = Tmp.getActiveBits(); if (activeBits > 0 && activeBits < numBits) Tmp.trunc(activeBits); - if (Tmp.getBitWidth() > 64) { - llvmAsmlval.APIntVal = new APInt(Tmp); - return EUAPINTVAL; - } else { - llvmAsmlval.UInt64Val = Tmp.getZExtValue(); - return EUINT64VAL; - } + APSIntVal = APSInt(Tmp, true); } + return lltok::APSInt; } ++CurPtr; @@ -793,16 +756,16 @@ int LLLexer::LexDigitOrNegative() { } } - llvmAsmlval.FPVal = new APFloat(atof(TokStart)); - return FPVAL; + APFloatVal = APFloat(atof(TokStart)); + return lltok::APFloat; } /// FPConstant [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)? -int LLLexer::LexPositive() { +lltok::Kind LLLexer::LexPositive() { // If the letter after the negative is a number, this is probably not a // label. if (!isdigit(CurPtr[0])) - return CurPtr[-1]; + return lltok::Error; // Skip digits. for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr) @@ -811,7 +774,7 @@ int LLLexer::LexPositive() { // At this point, we need a '.'. if (CurPtr[0] != '.') { CurPtr = TokStart+1; - return TokStart[0]; + return lltok::Error; } ++CurPtr; @@ -827,31 +790,6 @@ int LLLexer::LexPositive() { } } - llvmAsmlval.FPVal = new APFloat(atof(TokStart)); - return FPVAL; -} - - -//===----------------------------------------------------------------------===// -// Define the interface to this file. -//===----------------------------------------------------------------------===// - -static LLLexer *TheLexer; - -void InitLLLexer(llvm::MemoryBuffer *MB) { - assert(TheLexer == 0 && "LL Lexer isn't reentrant yet"); - TheLexer = new LLLexer(MB); -} - -int llvmAsmlex() { - return TheLexer->LexToken(); -} -const char *LLLgetTokenStart() { return TheLexer->getTokStart(); } -unsigned LLLgetTokenLength() { return TheLexer->getTokLength(); } -std::string LLLgetFilename() { return TheLexer->getFilename(); } -unsigned LLLgetLineNo() { return TheLexer->getLineNo(); } - -void FreeLexer() { - delete TheLexer; - TheLexer = 0; + APFloatVal = APFloat(atof(TokStart)); + return lltok::APFloat; } diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h index 8b44b14cb74..45001815e75 100644 --- a/lib/AsmParser/LLLexer.h +++ b/lib/AsmParser/LLLexer.h @@ -14,43 +14,72 @@ #ifndef LIB_ASMPARSER_LLLEXER_H #define LIB_ASMPARSER_LLLEXER_H +#include "LLToken.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/APFloat.h" + #include #include #include namespace llvm { class MemoryBuffer; + class Type; + class ParseError; class LLLexer { const char *CurPtr; - unsigned CurLineNo; MemoryBuffer *CurBuf; - + ParseError &ErrorInfo; + + // Information about the current token. const char *TokStart; + lltok::Kind CurKind; + std::string StrVal; + unsigned UIntVal; + const Type *TyVal; + APFloat APFloatVal; + APSInt APSIntVal; std::string TheError; public: - explicit LLLexer(MemoryBuffer *StartBuf); + explicit LLLexer(MemoryBuffer *StartBuf, ParseError &); ~LLLexer() {} - const char *getTokStart() const { return TokStart; } - unsigned getTokLength() const { return CurPtr-TokStart; } - unsigned getLineNo() const { return CurLineNo; } + lltok::Kind Lex() { + return CurKind = LexToken(); + } + + typedef const char* LocTy; + LocTy getLoc() const { return TokStart; } + lltok::Kind getKind() const { return CurKind; } + const std::string getStrVal() const { return StrVal; } + const Type *getTyVal() const { return TyVal; } + unsigned getUIntVal() const { return UIntVal; } + const APSInt &getAPSIntVal() const { return APSIntVal; } + const APFloat &getAPFloatVal() const { return APFloatVal; } + + + bool Error(LocTy L, const std::string &Msg) const; + bool Error(const std::string &Msg) const { return Error(CurPtr, Msg); } std::string getFilename() const; - int LexToken(); - - const std::string getError() const { return TheError; } - + private: + lltok::Kind LexToken(); + int getNextChar(); void SkipLineComment(); - int LexIdentifier(); - int LexDigitOrNegative(); - int LexPositive(); - int LexAt(); - int LexPercent(); - int LexQuote(); - int Lex0x(); + lltok::Kind LexIdentifier(); + lltok::Kind LexDigitOrNegative(); + lltok::Kind LexPositive(); + lltok::Kind LexAt(); + lltok::Kind LexPercent(); + lltok::Kind LexQuote(); + lltok::Kind Lex0x(); + + uint64_t atoull(const char *Buffer, const char *End); + uint64_t HexIntToVal(const char *Buffer, const char *End); + void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]); }; } // end namespace llvm diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp new file mode 100644 index 00000000000..eefdc6c239d --- /dev/null +++ b/lib/AsmParser/LLParser.cpp @@ -0,0 +1,3158 @@ +//===-- LLParser.cpp - Parser Class ---------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the parser class for .ll files. +// +//===----------------------------------------------------------------------===// + +#include "LLParser.h" +#include "llvm/AutoUpgrade.h" +#include "llvm/CallingConv.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/InlineAsm.h" +#include "llvm/Instructions.h" +#include "llvm/Module.h" +#include "llvm/ValueSymbolTable.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +// ValID - Represents a reference of a definition of some sort with no type. +// There are several cases where we have to parse the value but where the type +// can depend on later context. This may either +// be a numeric reference or a symbolic (%var) reference. This is just a +// discriminated union. +// +// Note that I can't implement this class in a straight forward manner with +// constructors and stuff because it goes in a union. +// +namespace llvm { + struct ValID { + enum { + t_LocalID, t_GlobalID, // ID in UIntVal. + t_LocalName, t_GlobalName, // Name in StrVal. + t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal. + t_Null, t_Undef, t_Zero, // No value. + t_Constant, // Value in ConstantVal. + t_InlineAsm // Value in StrVal/StrVal2/UIntVal. + } Kind; + + LLParser::LocTy Loc; + unsigned UIntVal; + std::string StrVal, StrVal2; + APSInt APSIntVal; + APFloat APFloatVal; + Constant *ConstantVal; + ValID() : APFloatVal(0.0) {} + }; +} + +/// Parse: module ::= toplevelentity* +Module *LLParser::Run() { + M = new Module(Lex.getFilename()); + + if (ParseTopLevelEntities() || + ValidateEndOfModule()) { + delete M; + return 0; + } + + return M; +} + +/// ValidateEndOfModule - Do final validity and sanity checks at the end of the +/// module. +bool LLParser::ValidateEndOfModule() { + if (!ForwardRefTypes.empty()) + return Error(ForwardRefTypes.begin()->second.second, + "use of undefined type named '" + + ForwardRefTypes.begin()->first + "'"); + if (!ForwardRefTypeIDs.empty()) + return Error(ForwardRefTypeIDs.begin()->second.second, + "use of undefined type '%" + + utostr(ForwardRefTypeIDs.begin()->first) + "'"); + + if (!ForwardRefVals.empty()) + return Error(ForwardRefVals.begin()->second.second, + "use of undefined value '@" + ForwardRefVals.begin()->first + + "'"); + + if (!ForwardRefValIDs.empty()) + return Error(ForwardRefValIDs.begin()->second.second, + "use of undefined value '@" + + utostr(ForwardRefValIDs.begin()->first) + "'"); + + // Look for intrinsic functions and CallInst that need to be upgraded + for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ) + UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove + + return false; +} + +//===----------------------------------------------------------------------===// +// Top-Level Entities +//===----------------------------------------------------------------------===// + +bool LLParser::ParseTopLevelEntities() { + Lex.Lex(); + while (1) { + switch (Lex.getKind()) { + default: return TokError("expected top-level entity"); + case lltok::Eof: return false; + //case lltok::kw_define: + case lltok::kw_declare: if (ParseDeclare()) return true; break; + case lltok::kw_define: if (ParseDefine()) return true; break; + case lltok::kw_module: if (ParseModuleAsm()) return true; break; + case lltok::kw_target: if (ParseTargetDefinition()) return true; break; + case lltok::kw_deplibs: if (ParseDepLibs()) return true; break; + case lltok::kw_type: if (ParseUnnamedType()) return true; break; + case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0 + case lltok::LocalVar: if (ParseNamedType()) return true; break; + case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break; + + // The Global variable production with no name can have many different + // optional leading prefixes, the production is: + // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal + // OptionalAddrSpace ('constant'|'global') ... + case lltok::kw_internal: // OptionalLinkage + case lltok::kw_weak: // OptionalLinkage + case lltok::kw_linkonce: // OptionalLinkage + case lltok::kw_appending: // OptionalLinkage + case lltok::kw_dllexport: // OptionalLinkage + case lltok::kw_common: // OptionalLinkage + case lltok::kw_dllimport: // OptionalLinkage + case lltok::kw_extern_weak: // OptionalLinkage + case lltok::kw_external: { // OptionalLinkage + unsigned Linkage, Visibility; + if (ParseOptionalLinkage(Linkage) || + ParseOptionalVisibility(Visibility) || + ParseGlobal("", 0, Linkage, true, Visibility)) + return true; + break; + } + case lltok::kw_default: // OptionalVisibility + case lltok::kw_hidden: // OptionalVisibility + case lltok::kw_protected: { // OptionalVisibility + unsigned Visibility; + if (ParseOptionalVisibility(Visibility) || + ParseGlobal("", 0, 0, false, Visibility)) + return true; + break; + } + + case lltok::kw_thread_local: // OptionalThreadLocal + case lltok::kw_addrspace: // OptionalAddrSpace + case lltok::kw_constant: // GlobalType + case lltok::kw_global: // GlobalType + if (ParseGlobal("", 0, 0, false, 0)) return true; + break; + } + } +} + + +/// toplevelentity +/// ::= 'module' 'asm' STRINGCONSTANT +bool LLParser::ParseModuleAsm() { + assert(Lex.getKind() == lltok::kw_module); + Lex.Lex(); + + if (ParseToken(lltok::kw_asm, "expected 'module asm'")) return true; + + if (Lex.getKind() != lltok::StringConstant) + return TokError("expected 'module asm \"foo\"'"); + + const std::string &AsmSoFar = M->getModuleInlineAsm(); + if (AsmSoFar.empty()) + M->setModuleInlineAsm(Lex.getStrVal()); + else + M->setModuleInlineAsm(AsmSoFar+"\n"+Lex.getStrVal()); + Lex.Lex(); + return false; +} + +/// toplevelentity +/// ::= 'target' 'triple' '=' STRINGCONSTANT +/// ::= 'target' 'datalayout' '=' STRINGCONSTANT +bool LLParser::ParseTargetDefinition() { + assert(Lex.getKind() == lltok::kw_target); + switch (Lex.Lex()) { + default: return TokError("unknown target property"); + case lltok::kw_triple: + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' after target triple")) + return true; + if (Lex.getKind() != lltok::StringConstant) + return TokError("expected string after target triple '='"); + M->setTargetTriple(Lex.getStrVal()); + Lex.Lex(); + return false; + case lltok::kw_datalayout: + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' after target datalayout")) + return true; + if (Lex.getKind() != lltok::StringConstant) + return TokError("expected string after target datalayout '='"); + M->setDataLayout(Lex.getStrVal()); + Lex.Lex(); + return false; + } +} + +/// toplevelentity +/// ::= 'deplibs' '=' '[' ']' +/// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']' +bool LLParser::ParseDepLibs() { + assert(Lex.getKind() == lltok::kw_deplibs); + if (Lex.Lex() != lltok::equal) + return TokError("expected '=' after deplibs"); + + if (Lex.Lex() != lltok::lsquare) + return TokError("expected '=' after deplibs"); + + if (Lex.Lex() == lltok::rsquare) { + Lex.Lex(); + return false; + } + + if (Lex.getKind() != lltok::StringConstant) + return TokError("expected string in deplib list"); + + M->addLibrary(Lex.getStrVal()); + + while (Lex.Lex() == lltok::comma) { + if (Lex.Lex() != lltok::StringConstant) + return TokError("expected string in deplibs list"); + M->addLibrary(Lex.getStrVal()); + } + + if (Lex.getKind() != lltok::rsquare) + return TokError("expected ']' at end of list"); + Lex.Lex(); + return false; +} + +/// toplevelentity +/// ::= 'type' type +bool LLParser::ParseUnnamedType() { + assert(Lex.getKind() == lltok::kw_type); + LocTy TypeLoc = Lex.getLoc(); + Lex.Lex(); // eat kw_type + + PATypeHolder Ty(Type::VoidTy); + if (ParseType(Ty)) return true; + + unsigned TypeID = NumberedTypes.size(); + + // We don't allow assigning names to void type + if (Ty == Type::VoidTy) + return Error(TypeLoc, "can't assign name to the void type"); + + // See if this type was previously referenced. + std::map >::iterator + FI = ForwardRefTypeIDs.find(TypeID); + if (FI != ForwardRefTypeIDs.end()) { + cast(FI->second.first.get())->refineAbstractTypeTo(Ty); + Ty = FI->second.first.get(); + ForwardRefTypeIDs.erase(FI); + } + + NumberedTypes.push_back(Ty); + + return false; +} + +/// toplevelentity +/// ::= LocalVar '=' 'type' type +bool LLParser::ParseNamedType() { + std::string Name = Lex.getStrVal(); + LocTy NameLoc = Lex.getLoc(); + + if (Lex.Lex() != lltok::equal) + return TokError("expected '=' after name"); + if (Lex.Lex() != lltok::kw_type) + return TokError("expected 'type' after name"); + Lex.Lex(); // consume 'type'. + + PATypeHolder Ty(Type::VoidTy); + if (ParseType(Ty)) return true; + + // We don't allow assigning names to void type + if (Ty == Type::VoidTy) + return Error(NameLoc, "can't assign name '" + Name + "' to the void type"); + + // Set the type name, checking for conflicts as we do so. + bool AlreadyExists = M->addTypeName(Name, Ty); + if (!AlreadyExists) return false; + + // See if this type is a forward reference. We need to eagerly resolve + // types to allow recursive type redefinitions below. + std::map >::iterator + FI = ForwardRefTypes.find(Name); + if (FI != ForwardRefTypes.end()) { + cast(FI->second.first.get())->refineAbstractTypeTo(Ty); + Ty = FI->second.first.get(); + ForwardRefTypes.erase(FI); + } + + // Inserting a name that is already defined, get the existing name. + const Type *Existing = M->getTypeByName(Name); + assert(Existing && "Conflict but no matching type?!"); + + // Otherwise, this is an attempt to redefine a type. That's okay if + // the redefinition is identical to the original. + // FIXME: REMOVE REDEFINITIONS IN LLVM 3.0 + if (Existing == Ty) return false; + + // Any other kind of (non-equivalent) redefinition is an error. + return Error(NameLoc, "redefinition of type named '" + Name + "' of type '" + + Ty->getDescription() + "'"); +} + + +/// toplevelentity +/// ::= 'declare' FunctionHeader +bool LLParser::ParseDeclare() { + assert(Lex.getKind() == lltok::kw_declare); + Lex.Lex(); + + Function *F; + return ParseFunctionHeader(F, false); +} + +/// toplevelentity +/// ::= 'define' FunctionHeader '{' ... +bool LLParser::ParseDefine() { + assert(Lex.getKind() == lltok::kw_define); + Lex.Lex(); + + Function *F; + if (ParseFunctionHeader(F, true)) return true; + + return ParseFunctionBody(*F); +} + +bool LLParser::ParseGlobalType(bool &IsConstant) { + if (Lex.getKind() == lltok::kw_constant) + IsConstant = true; + else if (Lex.getKind() == lltok::kw_global) + IsConstant = false; + else + return TokError("expected 'global' or 'constant'"); + Lex.Lex(); + return false; +} + +/// ParseNamedGlobal: +/// GlobalVar '=' OptionalVisibility ALIAS ... +/// GlobalVar '=' OptionalLinkage OptionalVisibility ... -> global variable +bool LLParser::ParseNamedGlobal() { + assert(Lex.getKind() == lltok::GlobalVar); + LocTy NameLoc = Lex.getLoc(); + std::string Name = Lex.getStrVal(); + Lex.Lex(); + + bool HasLinkage; + unsigned Linkage, Visibility; + if (ParseToken(lltok::equal, "expected '=' in global variable") || + ParseOptionalLinkage(Linkage, HasLinkage) || + ParseOptionalVisibility(Visibility)) + return true; + + if (HasLinkage || Lex.getKind() != lltok::kw_alias) + return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility); + return ParseAlias(Name, NameLoc, Visibility); +} + +/// ParseAlias: +/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee +/// Aliasee +/// ::= TypeAndValue | 'bitcast' '(' TypeAndValue 'to' Type ')' +/// +/// Everything through visibility has already been parsed. +/// +bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, + unsigned Visibility) { + assert(Lex.getKind() == lltok::kw_alias); + Lex.Lex(); + unsigned Linkage; + LocTy LinkageLoc = Lex.getLoc(); + if (ParseOptionalLinkage(Linkage)) + return true; + + if (Linkage != GlobalValue::ExternalLinkage && + Linkage != GlobalValue::WeakLinkage && + Linkage != GlobalValue::InternalLinkage) + return Error(LinkageLoc, "invalid linkage type for alias"); + + Constant *Aliasee; + LocTy AliaseeLoc = Lex.getLoc(); + if (Lex.getKind() != lltok::kw_bitcast) { + if (ParseGlobalTypeAndValue(Aliasee)) return true; + } else { + // The bitcast dest type is not present, it is implied by the dest type. + ValID ID; + if (ParseValID(ID)) return true; + if (ID.Kind != ValID::t_Constant) + return Error(AliaseeLoc, "invalid aliasee"); + Aliasee = ID.ConstantVal; + } + + if (!isa(Aliasee->getType())) + return Error(AliaseeLoc, "alias must have pointer type"); + + // Okay, create the alias but do not insert it into the module yet. + GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), + (GlobalValue::LinkageTypes)Linkage, Name, + Aliasee); + GA->setVisibility((GlobalValue::VisibilityTypes)Visibility); + + // See if this value already exists in the symbol table. If so, it is either + // a redefinition or a definition of a forward reference. + if (GlobalValue *Val = + cast_or_null(M->getValueSymbolTable().lookup(Name))) { + // See if this was a redefinition. If so, there is no entry in + // ForwardRefVals. + std::map >::iterator + I = ForwardRefVals.find(Name); + if (I == ForwardRefVals.end()) + return Error(NameLoc, "redefinition of global named '@" + Name + "'"); + + // Otherwise, this was a definition of forward ref. Verify that types + // agree. + if (Val->getType() != GA->getType()) + return Error(NameLoc, + "forward reference and definition of alias have different types"); + + // If they agree, just RAUW the old value with the alias and remove the + // forward ref info. + Val->replaceAllUsesWith(GA); + Val->eraseFromParent(); + ForwardRefVals.erase(I); + } + + // Insert into the module, we know its name won't collide now. + M->getAliasList().push_back(GA); + assert(GA->getNameStr() == Name && "Should not be a name conflict!"); + + return false; +} + +/// ParseGlobal +/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal +/// OptionalAddrSpace GlobalType Type Const +/// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal +/// OptionalAddrSpace GlobalType Type Const +/// +/// Everything through visibility has been parsed already. +/// +bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, + unsigned Linkage, bool HasLinkage, + unsigned Visibility) { + unsigned AddrSpace; + bool ThreadLocal, IsConstant; + LocTy TyLoc; + + PATypeHolder Ty(Type::VoidTy); + if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) || + ParseOptionalAddrSpace(AddrSpace) || + ParseGlobalType(IsConstant) || + ParseType(Ty, TyLoc)) + return true; + + // If the linkage is specified and is external, then no initializer is + // present. + Constant *Init = 0; + if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage && + Linkage != GlobalValue::ExternalWeakLinkage && + Linkage != GlobalValue::ExternalLinkage)) { + if (ParseGlobalValue(Ty, Init)) + return true; + } + + if (isa(Ty) || Ty == Type::LabelTy) + return Error(TyLoc, "invald type for global variable"); + + GlobalVariable *GV = 0; + + // See if the global was forward referenced, if so, use the global. + if (!Name.empty() && (GV = M->getGlobalVariable(Name, true))) { + if (!ForwardRefVals.erase(Name)) + return Error(NameLoc, "redefinition of global '@" + Name + "'"); + } else { + std::map >::iterator + I = ForwardRefValIDs.find(NumberedVals.size()); + if (I != ForwardRefValIDs.end()) { + GV = cast(I->second.first); + ForwardRefValIDs.erase(I); + } + } + + if (GV == 0) { + GV = new GlobalVariable(Ty, false, GlobalValue::ExternalLinkage, 0, Name, + M, false, AddrSpace); + } else { + if (GV->getType()->getElementType() != Ty) + return Error(TyLoc, + "forward reference and definition of global have different types"); + + // Move the forward-reference to the correct spot in the module. + M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV); + } + + if (Name.empty()) + NumberedVals.push_back(GV); + + // Set the parsed properties on the global. + if (Init) + GV->setInitializer(Init); + GV->setConstant(IsConstant); + GV->setLinkage((GlobalValue::LinkageTypes)Linkage); + GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); + GV->setThreadLocal(ThreadLocal); + + // Parse attributes on the global. + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); + + if (Lex.getKind() == lltok::kw_section) { + Lex.Lex(); + GV->setSection(Lex.getStrVal()); + if (ParseToken(lltok::StringConstant, "expected global section string")) + return true; + } else if (Lex.getKind() == lltok::kw_align) { + unsigned Alignment; + if (ParseOptionalAlignment(Alignment)) return true; + GV->setAlignment(Alignment); + } else { + TokError("unknown global variable property!"); + } + } + + return false; +} + + +//===----------------------------------------------------------------------===// +// GlobalValue Reference/Resolution Routines. +//===----------------------------------------------------------------------===// + +/// GetGlobalVal - Get a value with the specified name or ID, creating a +/// forward reference record if needed. This can return null if the value +/// exists but does not have the right type. +GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty, + LocTy Loc) { + const PointerType *PTy = dyn_cast(Ty); + if (PTy == 0) { + Error(Loc, "global variable reference must have pointer type"); + return 0; + } + + // Look this name up in the normal function symbol table. + GlobalValue *Val = + cast_or_null(M->getValueSymbolTable().lookup(Name)); + + // If this is a forward reference for the value, see if we already created a + // forward ref record. + if (Val == 0) { + std::map >::iterator + I = ForwardRefVals.find(Name); + if (I != ForwardRefVals.end()) + Val = I->second.first; + } + + // If we have the value in the symbol table or fwd-ref table, return it. + if (Val) { + if (Val->getType() == Ty) return Val; + Error(Loc, "'@" + Name + "' defined with type '" + + Val->getType()->getDescription() + "'"); + return 0; + } + + // Otherwise, create a new forward reference for this value and remember it. + GlobalValue *FwdVal; + if (const FunctionType *FT = dyn_cast(PTy->getElementType())) + FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); + else + FwdVal = new GlobalVariable(PTy->getElementType(), false, + GlobalValue::ExternalWeakLinkage, 0, Name, M); + + ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); + return FwdVal; +} + +GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) { + const PointerType *PTy = dyn_cast(Ty); + if (PTy == 0) { + Error(Loc, "global variable reference must have pointer type"); + return 0; + } + + GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0; + + // If this is a forward reference for the value, see if we already created a + // forward ref record. + if (Val == 0) { + std::map >::iterator + I = ForwardRefValIDs.find(ID); + if (I != ForwardRefValIDs.end()) + Val = I->second.first; + } + + // If we have the value in the symbol table or fwd-ref table, return it. + if (Val) { + if (Val->getType() == Ty) return Val; + Error(Loc, "'@" + utostr(ID) + "' defined with type '" + + Val->getType()->getDescription() + "'"); + return 0; + } + + // Otherwise, create a new forward reference for this value and remember it. + GlobalValue *FwdVal; + if (const FunctionType *FT = dyn_cast(PTy->getElementType())) + FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M); + else + FwdVal = new GlobalVariable(PTy->getElementType(), false, + GlobalValue::ExternalWeakLinkage, 0, "", M); + + ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); + return FwdVal; +} + + +//===----------------------------------------------------------------------===// +// Helper Routines. +//===----------------------------------------------------------------------===// + +/// ParseToken - If the current token has the specified kind, eat it and return +/// success. Otherwise, emit the specified error and return failure. +bool LLParser::ParseToken(lltok::Kind T, const char *ErrMsg) { + if (Lex.getKind() != T) + return TokError(ErrMsg); + Lex.Lex(); + return false; +} + +bool LLParser::ParseUnsigned(unsigned &Val) { + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected integer"); + uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(0xFFFFFFFFULL+1); + if (Val64 != unsigned(Val64)) + return TokError("expected 32-bit integer (too large)"); + Val = Val64; + Lex.Lex(); + return false; +} + + +/// ParseOptionalAddrSpace +/// := /*empty*/ +/// := 'addrspace' '(' uint32 ')' +bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { + AddrSpace = 0; + bool HasAddrSpace; + ParseOptionalToken(lltok::kw_addrspace, HasAddrSpace); + if (!HasAddrSpace) + return false; + + return ParseToken(lltok::lparen, "expected '(' in address space") || + ParseUnsigned(AddrSpace) || + ParseToken(lltok::rparen, "expected ')' in address space"); +} + +/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind +/// indicates what kind of attribute list this is: 0: function arg, 1: result, +/// 2: function attr. +bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { + Attrs = Attribute::None; + LocTy AttrLoc = Lex.getLoc(); + + while (1) { + switch (Lex.getKind()) { + case lltok::kw_sext: + case lltok::kw_zext: + // Treat these as signext/zeroext unless they are function attrs. + // FIXME: REMOVE THIS IN LLVM 3.0 + if (AttrKind != 2) { + if (Lex.getKind() == lltok::kw_sext) + Attrs |= Attribute::SExt; + else + Attrs |= Attribute::ZExt; + break; + } + // FALL THROUGH. + default: // End of attributes. + if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly)) + return Error(AttrLoc, "invalid use of function-only attribute"); + + if (AttrKind != 0 && (Attrs & Attribute::ParameterOnly)) + return Error(AttrLoc, "invalid use of parameter-only attribute"); + + return false; + case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break; + case lltok::kw_signext: Attrs |= Attribute::SExt; break; + case lltok::kw_inreg: Attrs |= Attribute::InReg; break; + case lltok::kw_sret: Attrs |= Attribute::StructRet; break; + case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break; + case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break; + case lltok::kw_byval: Attrs |= Attribute::ByVal; break; + case lltok::kw_nest: Attrs |= Attribute::Nest; break; + + case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; + case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; + case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; + case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; + case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; + case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break; + case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break; + case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break; + case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break; + + + case lltok::kw_align: { + unsigned Alignment; + if (ParseOptionalAlignment(Alignment)) + return true; + Attrs |= Attribute::constructAlignmentFromInt(Alignment); + continue; + } + } + Lex.Lex(); + } +} + +/// ParseOptionalLinkage +/// ::= /*empty*/ +/// ::= 'internal' +/// ::= 'weak' +/// ::= 'linkonce' +/// ::= 'appending' +/// ::= 'dllexport' +/// ::= 'common' +/// ::= 'dllimport' +/// ::= 'extern_weak' +/// ::= 'external' +bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) { + HasLinkage = false; + switch (Lex.getKind()) { + default: Res = GlobalValue::ExternalLinkage; return false; + case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break; + case lltok::kw_weak: Res = GlobalValue::WeakLinkage; break; + case lltok::kw_linkonce: Res = GlobalValue::LinkOnceLinkage; break; + case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break; + case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break; + case lltok::kw_common: Res = GlobalValue::CommonLinkage; break; + case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break; + case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break; + case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break; + } + Lex.Lex(); + HasLinkage = true; + return false; +} + +/// ParseOptionalVisibility +/// ::= /*empty*/ +/// ::= 'default' +/// ::= 'hidden' +/// ::= 'protected' +/// +bool LLParser::ParseOptionalVisibility(unsigned &Res) { + switch (Lex.getKind()) { + default: Res = GlobalValue::DefaultVisibility; return false; + case lltok::kw_default: Res = GlobalValue::DefaultVisibility; break; + case lltok::kw_hidden: Res = GlobalValue::HiddenVisibility; break; + case lltok::kw_protected: Res = GlobalValue::ProtectedVisibility; break; + } + Lex.Lex(); + return false; +} + +/// ParseOptionalCallingConv +/// ::= /*empty*/ +/// ::= 'ccc' +/// ::= 'fastcc' +/// ::= 'coldcc' +/// ::= 'x86_stdcallcc' +/// ::= 'x86_fastcallcc' +/// ::= 'cc' UINT +/// +bool LLParser::ParseOptionalCallingConv(unsigned &CC) { + switch (Lex.getKind()) { + default: CC = CallingConv::C; return false; + case lltok::kw_ccc: CC = CallingConv::C; break; + case lltok::kw_fastcc: CC = CallingConv::Fast; break; + case lltok::kw_coldcc: CC = CallingConv::Cold; break; + case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break; + case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break; + case lltok::kw_cc: Lex.Lex(); return ParseUnsigned(CC); + } + Lex.Lex(); + return false; +} + +/// ParseOptionalAlignment +/// ::= /* empty */ +/// ::= 'align' 4 +bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { + Alignment = 0; + bool HasAlignment; + if (ParseOptionalToken(lltok::kw_align, HasAlignment)) return true; + + return HasAlignment && ParseUnsigned(Alignment); +} + +/// ParseOptionalCommaAlignment +/// ::= /* empty */ +/// ::= ',' 'align' 4 +bool LLParser::ParseOptionalCommaAlignment(unsigned &Alignment) { + Alignment = 0; + bool HasComma; + ParseOptionalToken(lltok::comma, HasComma); + if (!HasComma) + return false; + + return ParseToken(lltok::kw_align, "expected 'align'") || + ParseUnsigned(Alignment); +} + +/// ParseIndexList +/// ::= (',' uint32)+ +bool LLParser::ParseIndexList(SmallVectorImpl &Indices) { + if (Lex.getKind() != lltok::comma) + return TokError("expected ',' as start of index list"); + + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); + unsigned Idx; + if (ParseUnsigned(Idx)) return true; + Indices.push_back(Idx); + } + + return false; +} + +//===----------------------------------------------------------------------===// +// Type Parsing. +//===----------------------------------------------------------------------===// + +/// ParseType - Parse and resolve a full type. +bool LLParser::ParseType(PATypeHolder &Result) { + if (ParseTypeRec(Result)) return true; + + // Verify no unresolved uprefs. + if (!UpRefs.empty()) + return Error(UpRefs.back().Loc, "invalid unresolved type up reference"); + // GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); + + return false; +} + +/// 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 up-referenced type is the type that is passed in: +/// thus we can complete the cycle. +/// +PATypeHolder LLParser::HandleUpRefs(const Type *ty) { + // If Ty isn't abstract, or if there are no up-references in it, then there is + // nothing to resolve here. + if (!ty->isAbstract() || UpRefs.empty()) return ty; + + PATypeHolder Ty(ty); +#if 0 + errs() << "Type '" << Ty->getDescription() + << "' newly formed. Resolving upreferences.\n" + << UpRefs.size() << " upreferences active!\n"; +#endif + + // 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) { + // Determine if 'Ty' directly contains this up-references 'LastContainedTy'. + bool ContainsType = + std::find(Ty->subtype_begin(), Ty->subtype_end(), + UpRefs[i].LastContainedTy) != Ty->subtype_end(); + +#if 0 + errs() << " UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " + << UpRefs[i].LastContainedTy->getDescription() << ") = " + << (ContainsType ? "true" : "false") + << " level=" << UpRefs[i].NestingLevel << "\n"; +#endif + if (!ContainsType) + continue; + + // Decrement level of upreference + unsigned Level = --UpRefs[i].NestingLevel; + UpRefs[i].LastContainedTy = Ty; + + // If the Up-reference has a non-zero level, it shouldn't be resolved yet. + if (Level != 0) + continue; + +#if 0 + errs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n"; +#endif + if (!TypeToResolve) + TypeToResolve = UpRefs[i].UpRefTy; + else + UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); + UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list. + --i; // Do not skip the next element. + } + + if (TypeToResolve) + TypeToResolve->refineAbstractTypeTo(Ty); + + return Ty; +} + + +/// ParseTypeRec - The recursive function used to process the internal +/// implementation details of types. +bool LLParser::ParseTypeRec(PATypeHolder &Result) { + switch (Lex.getKind()) { + default: + return TokError("expected type"); + case lltok::Type: + // TypeRec ::= 'float' | 'void' (etc) + Result = Lex.getTyVal(); + Lex.Lex(); + break; + case lltok::kw_opaque: + // TypeRec ::= 'opaque' + Result = OpaqueType::get(); + Lex.Lex(); + break; + case lltok::lbrace: + // TypeRec ::= '{' ... '}' + if (ParseStructType(Result, false)) + return true; + break; + case lltok::lsquare: + // TypeRec ::= '[' ... ']' + Lex.Lex(); // eat the lsquare. + if (ParseArrayVectorType(Result, false)) + return true; + break; + case lltok::less: // Either vector or packed struct. + // TypeRec ::= '<' ... '>' + if (Lex.Lex() == lltok::lbrace) { + if (ParseStructType(Result, true)) + return true; + if (Lex.getKind() != lltok::greater) + return TokError("expected '>' at end of packed struct"); + Lex.Lex(); + } else if (ParseArrayVectorType(Result, true)) + return true; + break; + case lltok::LocalVar: + case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0 + // TypeRec ::= %foo + if (const Type *T = M->getTypeByName(Lex.getStrVal())) { + Result = T; + } else { + Result = OpaqueType::get(); + ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(), + std::make_pair(Result, + Lex.getLoc()))); + M->addTypeName(Lex.getStrVal(), Result.get()); + } + Lex.Lex(); + break; + + case lltok::LocalVarID: + // TypeRec ::= %4 + if (Lex.getUIntVal() < NumberedTypes.size()) + Result = NumberedTypes[Lex.getUIntVal()]; + else { + std::map >::iterator + I = ForwardRefTypeIDs.find(Lex.getUIntVal()); + if (I != ForwardRefTypeIDs.end()) + Result = I->second.first; + else { + Result = OpaqueType::get(); + ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(), + std::make_pair(Result, + Lex.getLoc()))); + } + } + Lex.Lex(); + break; + case lltok::backslash: { + // TypeRec ::= '\' 4 + unsigned Val; + Lex.Lex(); + if (ParseUnsigned(Val)) return true; + OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder. + UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT)); + Result = OT; + break; + } + } + + // Parse the type suffixes. + while (1) { + switch (Lex.getKind()) { + // End of type. + default: return false; + + // TypeRec ::= TypeRec '*' + case lltok::star: + if (Result.get() == Type::LabelTy) + return TokError("basic block pointers are invalid"); + Result = HandleUpRefs(PointerType::getUnqual(Result.get())); + Lex.Lex(); + break; + + // TypeRec ::= TypeRec 'addrspace' '(' uint32 ')' '*' + case lltok::kw_addrspace: { + if (Result.get() == Type::LabelTy) + return TokError("basic block pointers are invalid"); + unsigned AddrSpace; + if (ParseOptionalAddrSpace(AddrSpace) || + ParseToken(lltok::star, "expected '*' in address space")) + return true; + + Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace)); + break; + } + + /// Types '(' ArgTypeListI ')' OptFuncAttrs + case lltok::lparen: + if (ParseFunctionType(Result)) + return true; + break; + } + } +} + +/// ParseParameterList +/// ::= '(' ')' +/// ::= '(' Arg (',' Arg)* ')' +/// Arg +/// ::= Type OptionalAttributes Value OptionalAttributes +bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, + PerFunctionState &PFS) { + if (ParseToken(lltok::lparen, "expected '(' in call")) + return true; + + while (Lex.getKind() != lltok::rparen) { + // If this isn't the first argument, we need a comma. + if (!ArgList.empty() && + ParseToken(lltok::comma, "expected ',' in argument list")) + return true; + + // Parse the argument. + LocTy ArgLoc; + PATypeHolder ArgTy(Type::VoidTy); + unsigned ArgAttrs1, ArgAttrs2; + Value *V; + if (ParseType(ArgTy, ArgLoc) || + ParseOptionalAttrs(ArgAttrs1, 0) || + ParseValue(ArgTy, V, PFS) || + // FIXME: Should not allow attributes after the argument, remove this in + // LLVM 3.0. + ParseOptionalAttrs(ArgAttrs2, 0)) + return true; + ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2)); + } + + Lex.Lex(); // Lex the ')'. + return false; +} + + + +/// ParseArgumentList +/// ::= '(' ArgTypeListI ')' +/// ArgTypeListI +/// ::= /*empty*/ +/// ::= '...' +/// ::= ArgTypeList ',' '...' +/// ::= ArgType (',' ArgType)* +bool LLParser::ParseArgumentList(std::vector &ArgList, + bool &isVarArg) { + isVarArg = false; + assert(Lex.getKind() == lltok::lparen); + Lex.Lex(); // eat the (. + + if (Lex.getKind() == lltok::rparen) { + // empty + } else if (Lex.getKind() == lltok::dotdotdot) { + isVarArg = true; + Lex.Lex(); + } else { + LocTy TypeLoc = Lex.getLoc(); + PATypeHolder ArgTy(Type::VoidTy); + + if (ParseTypeRec(ArgTy)) return true; + + if (!ArgTy->isFirstClassType() && !isa(ArgTy)) + return Error(TypeLoc, "invalid type for function argument"); + + unsigned Attrs; + if (ParseOptionalAttrs(Attrs, 0)) return true; + + std::string Name; + if (Lex.getKind() == lltok::LocalVar || + Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0 + Name = Lex.getStrVal(); + Lex.Lex(); + } + + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); // eat the comma. + + // Handle ... at end of arg list. + if (Lex.getKind() == lltok::dotdotdot) { + isVarArg = true; + Lex.Lex(); + break; + } + + // Otherwise must be an argument type. + TypeLoc = Lex.getLoc(); + if (ParseTypeRec(ArgTy)) return true; + if (!ArgTy->isFirstClassType() && !isa(ArgTy)) + return Error(TypeLoc, "invalid type for function argument"); + + if (ParseOptionalAttrs(Attrs, 0)) return true; + + if (Lex.getKind() == lltok::LocalVar || + Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0 + Name = Lex.getStrVal(); + Lex.Lex(); + } else { + Name = ""; + } + + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + } + } + + if (Lex.getKind() != lltok::rparen) + return TokError("expected ')' at end of function argument list"); + Lex.Lex(); + return false; +} + +/// ParseFunctionType +/// ::= Type ArgumentList OptionalAttrs +bool LLParser::ParseFunctionType(PATypeHolder &Result) { + assert(Lex.getKind() == lltok::lparen); + + std::vector ArgList; + bool isVarArg; + unsigned Attrs; + if (ParseArgumentList(ArgList, isVarArg) || + // FIXME: Allow, but ignore attributes on function types! + // FIXME: Remove in LLVM 3.0 + ParseOptionalAttrs(Attrs, 2)) + return true; + + // Reject names on the arguments lists. + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { + if (!ArgList[i].Name.empty()) + return Error(ArgList[i].Loc, "argument name invalid in function type"); + if (!ArgList[i].Attrs != 0) { + // Allow but ignore attributes on function types; this permits + // auto-upgrade. + // FIXME: REJECT ATTRIBUTES ON FUNCTION TYPES in LLVM 3.0 + } + } + + std::vector ArgListTy; + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) + ArgListTy.push_back(ArgList[i].Type); + + Result = HandleUpRefs(FunctionType::get(Result.get(), ArgListTy, isVarArg)); + return false; +} + +/// ParseStructType: Handles packed and unpacked types. parsed elsewhere. +/// TypeRec +/// ::= '{' '}' +/// ::= '{' TypeRec (',' TypeRec)* '}' +/// ::= '<' '{' '}' '>' +/// ::= '<' '{' TypeRec (',' TypeRec)* '}' '>' +bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) { + assert(Lex.getKind() == lltok::lbrace); + Lex.Lex(); // Consume the '{' + + if (Lex.getKind() == lltok::rbrace) { + Result = StructType::get(std::vector(), Packed); + Lex.Lex(); + return false; + } + + std::vector ParamsList; + if (ParseTypeRec(Result)) return true; + ParamsList.push_back(Result); + + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); // eat the comma. + + if (ParseTypeRec(Result)) return true; + ParamsList.push_back(Result); + } + + if (Lex.getKind() != lltok::rbrace) + return TokError("expected '}' at end of struct"); + Lex.Lex(); // Consume the '}' + + std::vector ParamsListTy; + for (unsigned i = 0, e = ParamsList.size(); i != e; ++i) + ParamsListTy.push_back(ParamsList[i].get()); + Result = HandleUpRefs(StructType::get(ParamsListTy, Packed)); + return false; +} + +/// ParseArrayVectorType - Parse an array or vector type, assuming the first +/// token has already been consumed. +/// TypeRec +/// ::= '[' APSINTVAL 'x' Types ']' +/// ::= '<' APSINTVAL 'x' Types '>' +bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) { + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() || + Lex.getAPSIntVal().getBitWidth() > 64) + return TokError("expected number in address space"); + + LocTy SizeLoc = Lex.getLoc(); + uint64_t Size = Lex.getAPSIntVal().getZExtValue(); + if (Lex.Lex() != lltok::kw_x) + return TokError("expected 'x' after element count"); + Lex.Lex(); // eat the 'x'. + + LocTy TypeLoc = Lex.getLoc(); + PATypeHolder EltTy(Type::VoidTy); + if (ParseTypeRec(EltTy)) return true; + + if (Lex.getKind() != (isVector ? lltok::greater : lltok::rsquare)) + return TokError("expected end of sequential type"); + Lex.Lex(); + + if (isVector) { + if ((unsigned)Size != Size) + return Error(SizeLoc, "size too large for vector"); + if (!EltTy->isFloatingPoint() && !EltTy->isInteger()) + return Error(TypeLoc, "vector element type must be fp or integer"); + Result = VectorType::get(EltTy, unsigned(Size)); + } else { + if (!EltTy->isFirstClassType() && !isa(EltTy)) + return Error(TypeLoc, "invalid array element type"); + Result = HandleUpRefs(ArrayType::get(EltTy, Size)); + } + return false; +} + +//===----------------------------------------------------------------------===// +// Function Semantic Analysis. +//===----------------------------------------------------------------------===// + +LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f) + : P(p), F(f) { + + // Insert unnamed arguments into the NumberedVals list. + for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); + AI != E; ++AI) + if (!AI->hasName()) + NumberedVals.push_back(AI); +} + +LLParser::PerFunctionState::~PerFunctionState() { + // If there were any forward referenced non-basicblock values, delete them. + for (std::map >::iterator + I = ForwardRefVals.begin(), E = ForwardRefVals.end(); I != E; ++I) + if (!isa(I->second.first)) { + I->second.first->replaceAllUsesWith(UndefValue::get(I->second.first + ->getType())); + delete I->second.first; + I->second.first = 0; + } + + for (std::map >::iterator + I = ForwardRefValIDs.begin(), E = ForwardRefValIDs.end(); I != E; ++I) + if (!isa(I->second.first)) { + I->second.first->replaceAllUsesWith(UndefValue::get(I->second.first + ->getType())); + delete I->second.first; + I->second.first = 0; + } +} + +bool LLParser::PerFunctionState::VerifyFunctionComplete() { + if (!ForwardRefVals.empty()) + return P.Error(ForwardRefVals.begin()->second.second, + "use of undefined value '%" + ForwardRefVals.begin()->first + + "'"); + if (!ForwardRefValIDs.empty()) + return P.Error(ForwardRefValIDs.begin()->second.second, + "use of undefined value '%" + + utostr(ForwardRefValIDs.begin()->first) + "'"); + return false; +} + + +/// GetVal - Get a value with the specified name or ID, creating a +/// forward reference record if needed. This can return null if the value +/// exists but does not have the right type. +Value *LLParser::PerFunctionState::GetVal(const std::string &Name, + const Type *Ty, LocTy Loc) { + // Look this name up in the normal function symbol table. + Value *Val = F.getValueSymbolTable().lookup(Name); + + // If this is a forward reference for the value, see if we already created a + // forward ref record. + if (Val == 0) { + std::map >::iterator + I = ForwardRefVals.find(Name); + if (I != ForwardRefVals.end()) + Val = I->second.first; + } + + // If we have the value in the symbol table or fwd-ref table, return it. + if (Val) { + if (Val->getType() == Ty) return Val; + if (Ty == Type::LabelTy) + P.Error(Loc, "'%" + Name + "' is not a basic block"); + else + P.Error(Loc, "'%" + Name + "' defined with type '" + + Val->getType()->getDescription() + "'"); + return 0; + } + + // Don't make placeholders with invalid type. + if (!Ty->isFirstClassType() && !isa(Ty) && Ty != Type::LabelTy) { + P.Error(Loc, "invalid use of a non-first-class type"); + return 0; + } + + // Otherwise, create a new forward reference for this value and remember it. + Value *FwdVal; + if (Ty == Type::LabelTy) + FwdVal = BasicBlock::Create(Name, &F); + else + FwdVal = new Argument(Ty, Name); + + ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); + return FwdVal; +} + +Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty, + LocTy Loc) { + // Look this name up in the normal function symbol table. + Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0; + + // If this is a forward reference for the value, see if we already created a + // forward ref record. + if (Val == 0) { + std::map >::iterator + I = ForwardRefValIDs.find(ID); + if (I != ForwardRefValIDs.end()) + Val = I->second.first; + } + + // If we have the value in the symbol table or fwd-ref table, return it. + if (Val) { + if (Val->getType() == Ty) return Val; + if (Ty == Type::LabelTy) + P.Error(Loc, "'%" + utostr(ID) + "' is not a basic block"); + else + P.Error(Loc, "'%" + utostr(ID) + "' defined with type '" + + Val->getType()->getDescription() + "'"); + return 0; + } + + if (!Ty->isFirstClassType() && !isa(Ty) && Ty != Type::LabelTy) { + P.Error(Loc, "invalid use of a non-first-class type"); + return 0; + } + + // Otherwise, create a new forward reference for this value and remember it. + Value *FwdVal; + if (Ty == Type::LabelTy) + FwdVal = BasicBlock::Create("", &F); + else + FwdVal = new Argument(Ty); + + ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); + return FwdVal; +} + +/// SetInstName - After an instruction is parsed and inserted into its +/// basic block, this installs its name. +bool LLParser::PerFunctionState::SetInstName(int NameID, + const std::string &NameStr, + LocTy NameLoc, Instruction *Inst) { + // If this instruction has void type, it cannot have a name or ID specified. + if (Inst->getType() == Type::VoidTy) { + if (NameID != -1 || !NameStr.empty()) + return P.Error(NameLoc, "instructions returning void cannot have a name"); + return false; + } + + // If this was a numbered instruction, verify that the instruction is the + // expected value and resolve any forward references. + if (NameStr.empty()) { + // If neither a name nor an ID was specified, just use the next ID. + if (NameID == -1) + NameID = NumberedVals.size(); + + if (unsigned(NameID) != NumberedVals.size()) + return P.Error(NameLoc, "instruction expected to be numbered '%" + + utostr(NumberedVals.size()) + "'"); + + std::map >::iterator FI = + ForwardRefValIDs.find(NameID); + if (FI != ForwardRefValIDs.end()) { + if (FI->second.first->getType() != Inst->getType()) + return P.Error(NameLoc, "instruction forward referenced with type '" + + FI->second.first->getType()->getDescription() + "'"); + FI->second.first->replaceAllUsesWith(Inst); + ForwardRefValIDs.erase(FI); + } + + NumberedVals.push_back(Inst); + return false; + } + + // Otherwise, the instruction had a name. Resolve forward refs and set it. + std::map >::iterator + FI = ForwardRefVals.find(NameStr); + if (FI != ForwardRefVals.end()) { + if (FI->second.first->getType() != Inst->getType()) + return P.Error(NameLoc, "instruction forward referenced with type '" + + FI->second.first->getType()->getDescription() + "'"); + FI->second.first->replaceAllUsesWith(Inst); + ForwardRefVals.erase(FI); + } + + // Set the name on the instruction. + Inst->setName(NameStr); + + if (Inst->getNameStr() != NameStr) + return P.Error(NameLoc, "multiple definition of local value named '" + + NameStr + "'"); + return false; +} + +/// GetBB - Get a basic block with the specified name or ID, creating a +/// forward reference record if needed. +BasicBlock *LLParser::PerFunctionState::GetBB(const std::string &Name, + LocTy Loc) { + return cast_or_null(GetVal(Name, Type::LabelTy, Loc)); +} + +BasicBlock *LLParser::PerFunctionState::GetBB(unsigned ID, LocTy Loc) { + return cast_or_null(GetVal(ID, Type::LabelTy, Loc)); +} + +/// DefineBB - Define the specified basic block, which is either named or +/// unnamed. If there is an error, this returns null otherwise it returns +/// the block being defined. +BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name, + LocTy Loc) { + BasicBlock *BB; + if (Name.empty()) + BB = GetBB(NumberedVals.size(), Loc); + else + BB = GetBB(Name, Loc); + if (BB == 0) return 0; // Already diagnosed error. + + // Move the block to the end of the function. Forward ref'd blocks are + // inserted wherever they happen to be referenced. + F.getBasicBlockList().splice(F.end(), F.getBasicBlockList(), BB); + + // Remove the block from forward ref sets. + if (Name.empty()) { + ForwardRefValIDs.erase(NumberedVals.size()); + NumberedVals.push_back(BB); + } else { + // BB forward references are already in the function symbol table. + ForwardRefVals.erase(Name); + } + + return BB; +} + +//===----------------------------------------------------------------------===// +// Constants. +//===----------------------------------------------------------------------===// + +/// ParseValID - Parse an abstract value that doesn't necessarily have a +/// type implied. For example, if we parse "4" we don't know what integer type +/// it has. The value will later be combined with its type and checked for +/// sanity. +bool LLParser::ParseValID(ValID &ID) { + ID.Loc = Lex.getLoc(); + switch (Lex.getKind()) { + default: return TokError("expected value token"); + case lltok::GlobalID: // @42 + ID.UIntVal = Lex.getUIntVal(); + ID.Kind = ValID::t_GlobalID; + break; + case lltok::GlobalVar: // @foo + ID.StrVal = Lex.getStrVal(); + ID.Kind = ValID::t_GlobalName; + break; + case lltok::LocalVarID: // %42 + ID.UIntVal = Lex.getUIntVal(); + ID.Kind = ValID::t_LocalID; + break; + case lltok::LocalVar: // %foo + case lltok::StringConstant: // "foo" - FIXME: REMOVE IN LLVM 3.0 + ID.StrVal = Lex.getStrVal(); + ID.Kind = ValID::t_LocalName; + break; + case lltok::APSInt: + ID.APSIntVal = Lex.getAPSIntVal(); + ID.Kind = ValID::t_APSInt; + break; + case lltok::APFloat: + ID.APFloatVal = Lex.getAPFloatVal(); + ID.Kind = ValID::t_APFloat; + break; + case lltok::kw_true: + ID.ConstantVal = ConstantInt::getTrue(); + ID.Kind = ValID::t_Constant; + break; + case lltok::kw_false: + ID.ConstantVal = ConstantInt::getFalse(); + ID.Kind = ValID::t_Constant; + break; + case lltok::kw_null: ID.Kind = ValID::t_Null; break; + case lltok::kw_undef: ID.Kind = ValID::t_Undef; break; + case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break; + + case lltok::lbrace: { + // ValID ::= '{' ConstVector '}' + Lex.Lex(); + SmallVector Elts; + if (ParseGlobalValueVector(Elts) || + ParseToken(lltok::rbrace, "expected end of struct constant")) + return true; + + ID.ConstantVal = ConstantStruct::get(&Elts[0], Elts.size(), false); + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::less: { + // ValID ::= '<' ConstVector '>' --> Vector. + // ValID ::= '<' '{' ConstVector '}' '>' --> Packed Struct. + Lex.Lex(); + bool isPackedStruct; + ParseOptionalToken(lltok::lbrace, isPackedStruct); + + SmallVector Elts; + LocTy FirstEltLoc = Lex.getLoc(); + if (ParseGlobalValueVector(Elts) || + (isPackedStruct && + ParseToken(lltok::rbrace, "expected end of packed struct")) || + ParseToken(lltok::greater, "expected end of constant")) + return true; + + if (isPackedStruct) { + ID.ConstantVal = ConstantStruct::get(&Elts[0], Elts.size(), true); + ID.Kind = ValID::t_Constant; + return false; + } + + if (Elts.empty()) + return Error(ID.Loc, "constant vector must not be empty"); + + if (!Elts[0]->getType()->isInteger() && + !Elts[0]->getType()->isFloatingPoint()) + return Error(FirstEltLoc, + "vector elements must have integer or floating point type"); + + // Verify that all the vector elements have the same type. + for (unsigned i = 1, e = Elts.size(); i != e; ++i) + if (Elts[i]->getType() != Elts[0]->getType()) + return Error(FirstEltLoc, + "vector element #" + utostr(i) + + " is not of type '" + Elts[0]->getType()->getDescription()); + + ID.ConstantVal = ConstantVector::get(&Elts[0], Elts.size()); + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::lsquare: { // Array Constant + Lex.Lex(); + SmallVector Elts; + LocTy FirstEltLoc = Lex.getLoc(); + if (ParseGlobalValueVector(Elts) || + ParseToken(lltok::rsquare, "expected end of array constant")) + return true; + + // Handle empty element. + if (Elts.empty()) { + // Use undef instead of an array because it's inconvenient to determine + // the element type at this point, there being no elements to examine. + ID.Kind = ValID::t_Undef; + return false; + } + + if (!Elts[0]->getType()->isFirstClassType()) + return Error(FirstEltLoc, "invalid array element type: " + + Elts[0]->getType()->getDescription()); + + ArrayType *ATy = ArrayType::get(Elts[0]->getType(), Elts.size()); + + // Verify all elements are correct type! + for (unsigned i = i, e = Elts.size() ; i != e; ++i) { + if (Elts[i]->getType() != Elts[0]->getType()) + return Error(FirstEltLoc, + "array element #" + utostr(i) + + " is not of type '" +Elts[0]->getType()->getDescription()); + } + + ID.ConstantVal = ConstantArray::get(ATy, &Elts[0], Elts.size()); + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::kw_c: // c "foo" + Lex.Lex(); + ID.ConstantVal = ConstantArray::get(Lex.getStrVal(), false); + if (ParseToken(lltok::StringConstant, "expected string")) return true; + ID.Kind = ValID::t_Constant; + return false; + + case lltok::kw_asm: { + // ValID ::= 'asm' SideEffect? STRINGCONSTANT ',' STRINGCONSTANT + bool HasSideEffect; + Lex.Lex(); + if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) || + ParseToken(lltok::StringConstant, "expected asm string")) + return true; + ID.StrVal = Lex.getStrVal(); + + if (ParseToken(lltok::comma, "expected comma in inline asm expression") || + ParseToken(lltok::StringConstant, "expected constraint string")) + return true; + ID.StrVal2 = Lex.getStrVal(); + ID.UIntVal = HasSideEffect; + ID.Kind = ValID::t_InlineAsm; + return false; + } + + case lltok::kw_trunc: + case lltok::kw_zext: + case lltok::kw_sext: + case lltok::kw_fptrunc: + case lltok::kw_fpext: + case lltok::kw_bitcast: + case lltok::kw_uitofp: + case lltok::kw_sitofp: + case lltok::kw_fptoui: + case lltok::kw_fptosi: + case lltok::kw_inttoptr: + case lltok::kw_ptrtoint: { + unsigned Opc = Lex.getUIntVal(); + PATypeHolder DestTy(Type::VoidTy); + Constant *SrcVal; + Lex.Lex(); + if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") || + ParseGlobalTypeAndValue(SrcVal) || + ParseToken(lltok::kw_to, "expected 'to' int constantexpr cast") || + ParseType(DestTy) || + ParseToken(lltok::rparen, "expected ')' at end of constantexpr cast")) + return true; + if (!CastInst::castIsValid((Instruction::CastOps)Opc, SrcVal, DestTy)) + return Error(ID.Loc, "invalid cast opcode for cast from '" + + SrcVal->getType()->getDescription() + "' to '" + + DestTy->getDescription() + "'"); + ID.ConstantVal = ConstantExpr::getCast((Instruction::CastOps)Opc, SrcVal, + DestTy); + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::kw_extractvalue: { + Lex.Lex(); + Constant *Val; + SmallVector Indices; + if (ParseToken(lltok::lparen, "expected '(' in extractvalue constantexpr")|| + ParseGlobalTypeAndValue(Val) || + ParseIndexList(Indices) || + ParseToken(lltok::rparen, "expected ')' in extractvalue constantexpr")) + return true; + if (!isa(Val->getType()) && !isa(Val->getType())) + return Error(ID.Loc, "extractvalue operand must be array or struct"); + if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(), + Indices.end())) + return Error(ID.Loc, "invalid indices for extractvalue"); + ID.ConstantVal = ConstantExpr::getExtractValue(Val, + &Indices[0], Indices.size()); + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::kw_insertvalue: { + Lex.Lex(); + Constant *Val0, *Val1; + SmallVector Indices; + if (ParseToken(lltok::lparen, "expected '(' in insertvalue constantexpr")|| + ParseGlobalTypeAndValue(Val0) || + ParseToken(lltok::comma, "expected comma in insertvalue constantexpr")|| + ParseGlobalTypeAndValue(Val1) || + ParseIndexList(Indices) || + ParseToken(lltok::rparen, "expected ')' in insertvalue constantexpr")) + return true; + if (!isa(Val0->getType()) && !isa(Val0->getType())) + return Error(ID.Loc, "extractvalue operand must be array or struct"); + if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(), + Indices.end())) + return Error(ID.Loc, "invalid indices for insertvalue"); + ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, + &Indices[0], Indices.size()); + ID.Kind = ValID::t_Constant; + return false; + } + case lltok::kw_icmp: + case lltok::kw_fcmp: + case lltok::kw_vicmp: + case lltok::kw_vfcmp: { + unsigned PredVal, Opc = Lex.getUIntVal(); + Constant *Val0, *Val1; + Lex.Lex(); + if (ParseCmpPredicate(PredVal, Opc) || + ParseToken(lltok::lparen, "expected '(' in compare constantexpr") || + ParseGlobalTypeAndValue(Val0) || + ParseToken(lltok::comma, "expected comma in compare constantexpr") || + ParseGlobalTypeAndValue(Val1) || + ParseToken(lltok::rparen, "expected ')' in compare constantexpr")) + return true; + + if (Val0->getType() != Val1->getType()) + return Error(ID.Loc, "compare operands must have the same type"); + + CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal; + + if (Opc == Instruction::FCmp) { + if (!Val0->getType()->isFPOrFPVector()) + return Error(ID.Loc, "fcmp requires floating point operands"); + ID.ConstantVal = ConstantExpr::getFCmp(Pred, Val0, Val1); + } else if (Opc == Instruction::ICmp) { + if (!Val0->getType()->isIntOrIntVector() && + !isa(Val0->getType())) + return Error(ID.Loc, "icmp requires pointer or integer operands"); + ID.ConstantVal = ConstantExpr::getICmp(Pred, Val0, Val1); + } else if (Opc == Instruction::VFCmp) { + // FIXME: REMOVE VFCMP Support + ID.ConstantVal = ConstantExpr::getVFCmp(Pred, Val0, Val1); + } else if (Opc == Instruction::VICmp) { + // FIXME: REMOVE VFCMP Support + ID.ConstantVal = ConstantExpr::getVICmp(Pred, Val0, Val1); + } + ID.Kind = ValID::t_Constant; + return false; + } + + // Binary Operators. + case lltok::kw_add: + case lltok::kw_sub: + case lltok::kw_mul: + case lltok::kw_udiv: + case lltok::kw_sdiv: + case lltok::kw_fdiv: + case lltok::kw_urem: + case lltok::kw_srem: + case lltok::kw_frem: { + unsigned Opc = Lex.getUIntVal(); + Constant *Val0, *Val1; + Lex.Lex(); + if (ParseToken(lltok::lparen, "expected '(' in binary constantexpr") || + ParseGlobalTypeAndValue(Val0) || + ParseToken(lltok::comma, "expected comma in binary constantexpr") || + ParseGlobalTypeAndValue(Val1) || + ParseToken(lltok::rparen, "expected ')' in binary constantexpr")) + return true; + if (Val0->getType() != Val1->getType()) + return Error(ID.Loc, "operands of constexpr must have same type"); + if (!Val0->getType()->isIntOrIntVector() && + !Val0->getType()->isFPOrFPVector()) + return Error(ID.Loc,"constexpr requires integer, fp, or vector operands"); + ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1); + ID.Kind = ValID::t_Constant; + return false; + } + + // Logical Operations + case lltok::kw_shl: + case lltok::kw_lshr: + case lltok::kw_ashr: + case lltok::kw_and: + case lltok::kw_or: + case lltok::kw_xor: { + unsigned Opc = Lex.getUIntVal(); + Constant *Val0, *Val1; + Lex.Lex(); + if (ParseToken(lltok::lparen, "expected '(' in logical constantexpr") || + ParseGlobalTypeAndValue(Val0) || + ParseToken(lltok::comma, "expected comma in logical constantexpr") || + ParseGlobalTypeAndValue(Val1) || + ParseToken(lltok::rparen, "expected ')' in logical constantexpr")) + return true; + if (Val0->getType() != Val1->getType()) + return Error(ID.Loc, "operands of constexpr must have same type"); + if (!Val0->getType()->isIntOrIntVector()) + return Error(ID.Loc, + "constexpr requires integer or integer vector operands"); + ID.ConstantVal = ConstantExpr::get(Opc, Val0, Val1); + ID.Kind = ValID::t_Constant; + return false; + } + + case lltok::kw_getelementptr: + case lltok::kw_shufflevector: + case lltok::kw_insertelement: + case lltok::kw_extractelement: + case lltok::kw_select: { + unsigned Opc = Lex.getUIntVal(); + SmallVector Elts; + Lex.Lex(); + if (ParseToken(lltok::lparen, "expected '(' in constantexpr") || + ParseGlobalValueVector(Elts) || + ParseToken(lltok::rparen, "expected ')' in constantexpr")) + return true; + + if (Opc == Instruction::GetElementPtr) { + if (Elts.size() == 0 || !isa(Elts[0]->getType())) + return Error(ID.Loc, "getelementptr requires pointer operand"); + + if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(), + (Value**)&Elts[1], Elts.size()-1)) + return Error(ID.Loc, "invalid indices for getelementptr"); + ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0], + &Elts[1], Elts.size()-1); + } else if (Opc == Instruction::Select) { + if (Elts.size() != 3) + return Error(ID.Loc, "expected three operands to select"); + if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1], + Elts[2])) + return Error(ID.Loc, Reason); + ID.ConstantVal = ConstantExpr::getSelect(Elts[0], Elts[1], Elts[2]); + } else if (Opc == Instruction::ShuffleVector) { + if (Elts.size() != 3) + return Error(ID.Loc, "expected three operands to shufflevector"); + if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2])) + return Error(ID.Loc, "invalid operands to shufflevector"); + ID.ConstantVal = ConstantExpr::getShuffleVector(Elts[0], Elts[1],Elts[2]); + } else if (Opc == Instruction::ExtractElement) { + if (Elts.size() != 2) + return Error(ID.Loc, "expected two operands to extractelement"); + if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1])) + return Error(ID.Loc, "invalid extractelement operands"); + ID.ConstantVal = ConstantExpr::getExtractElement(Elts[0], Elts[1]); + } else { + assert(Opc == Instruction::InsertElement && "Unknown opcode"); + if (Elts.size() != 3) + return Error(ID.Loc, "expected three operands to insertelement"); + if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2])) + return Error(ID.Loc, "invalid insertelement operands"); + ID.ConstantVal = ConstantExpr::getInsertElement(Elts[0], Elts[1],Elts[2]); + } + + ID.Kind = ValID::t_Constant; + return false; + } + } + + Lex.Lex(); + return false; +} + +/// ParseGlobalValue - Parse a global value with the specified type. +bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&V) { + V = 0; + ValID ID; + if (ParseValID(ID) || + ConvertGlobalValIDToValue(Ty, ID, V)) + return true; + return false; +} + +/// ConvertGlobalValIDToValue - Apply a type to a ValID to get a fully resolved +/// constant. +bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, + Constant *&V) { + if (isa(Ty)) + return Error(ID.Loc, "functions are not values, refer to them as pointers"); + + switch (ID.Kind) { + default: assert(0 && "Unknown ValID!"); + case ValID::t_LocalID: + case ValID::t_LocalName: + return Error(ID.Loc, "invalid use of function-local name"); + case ValID::t_InlineAsm: + return Error(ID.Loc, "inline asm can only be an operand of call/invoke"); + case ValID::t_GlobalName: + V = GetGlobalVal(ID.StrVal, Ty, ID.Loc); + return V == 0; + case ValID::t_GlobalID: + V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc); + return V == 0; + case ValID::t_APSInt: + if (!isa(Ty)) + return Error(ID.Loc, "integer constant must have integer type"); + ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits()); + V = ConstantInt::get(ID.APSIntVal); + return false; + case ValID::t_APFloat: + if (!Ty->isFloatingPoint() || + !ConstantFP::isValueValidForType(Ty, ID.APFloatVal)) + return Error(ID.Loc, "floating point constant invalid for type"); + + // The 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 (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble && + Ty == Type::FloatTy) { + bool Ignored; + ID.APFloatVal.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, + &Ignored); + } + V = ConstantFP::get(ID.APFloatVal); + return false; + case ValID::t_Null: + if (!isa(Ty)) + return Error(ID.Loc, "null must be a pointer type"); + V = ConstantPointerNull::get(cast(Ty)); + return false; + case ValID::t_Undef: + V = UndefValue::get(Ty); + return false; + case ValID::t_Zero: + if (!Ty->isFirstClassType()) + return Error(ID.Loc, "invalid type for null constant"); + V = Constant::getNullValue(Ty); + return false; + case ValID::t_Constant: + if (ID.ConstantVal->getType() != Ty) + return Error(ID.Loc, "constant expression type mismatch"); + V = ID.ConstantVal; + return false; + } +} + +bool LLParser::ParseGlobalTypeAndValue(Constant *&V) { + PATypeHolder Type(Type::VoidTy); + return ParseType(Type) || + ParseGlobalValue(Type, V); +} + +bool LLParser::ParseGlobalValueVector(SmallVectorImpl &Elts) { + // Empty list. + if (Lex.getKind() == lltok::rbrace || + Lex.getKind() == lltok::rsquare || + Lex.getKind() == lltok::greater || + Lex.getKind() == lltok::rparen) + return false; + + Constant *C; + if (ParseGlobalTypeAndValue(C)) return true; + Elts.push_back(C); + + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); + if (ParseGlobalTypeAndValue(C)) return true; + Elts.push_back(C); + } + + return false; +} + + +//===----------------------------------------------------------------------===// +// Function Parsing. +//===----------------------------------------------------------------------===// + +bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, + PerFunctionState &PFS) { + if (ID.Kind == ValID::t_LocalID) + V = PFS.GetVal(ID.UIntVal, Ty, ID.Loc); + else if (ID.Kind == ValID::t_LocalName) + V = PFS.GetVal(ID.StrVal, Ty, ID.Loc); + else if (ID.Kind == ValID::ValID::t_InlineAsm) { + const PointerType *PTy = dyn_cast(Ty); + const FunctionType *FTy = + PTy ? dyn_cast(PTy->getElementType()) : 0; + if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2)) + return Error(ID.Loc, "invalid type for inline asm constraint string"); + V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal); + return false; + } else { + Constant *C; + if (ConvertGlobalValIDToValue(Ty, ID, C)) return true; + V = C; + return false; + } + + return V == 0; +} + +bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) { + V = 0; + ValID ID; + if (ParseValID(ID) || + ConvertValIDToValue(Ty, ID, V, PFS)) + return true; + return false; +} + +bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) { + PATypeHolder T(Type::VoidTy); + if (ParseType(T)) return true; + return ParseValue(T, V, PFS); +} + +/// FunctionHeader +/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs +/// Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection +/// OptionalAlign OptGC +bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { + // Parse the linkage. + LocTy LinkageLoc = Lex.getLoc(); + unsigned Linkage; + + unsigned Visibility, CC, RetAttrs; + PATypeHolder RetType(Type::VoidTy); + LocTy RetTypeLoc = Lex.getLoc(); + if (ParseOptionalLinkage(Linkage) || + ParseOptionalVisibility(Visibility) || + ParseOptionalCallingConv(CC) || + ParseOptionalAttrs(RetAttrs, 1) || + ParseType(RetType, RetTypeLoc)) + return true; + + // Verify that the linkage is ok. + switch ((GlobalValue::LinkageTypes)Linkage) { + case GlobalValue::ExternalLinkage: + break; // always ok. + case GlobalValue::DLLImportLinkage: + case GlobalValue::ExternalWeakLinkage: + if (isDefine) + return Error(LinkageLoc, "invalid linkage for function definition"); + break; + case GlobalValue::InternalLinkage: + case GlobalValue::LinkOnceLinkage: + case GlobalValue::WeakLinkage: + case GlobalValue::DLLExportLinkage: + if (!isDefine) + return Error(LinkageLoc, "invalid linkage for function declaration"); + break; + case GlobalValue::AppendingLinkage: + case GlobalValue::GhostLinkage: + case GlobalValue::CommonLinkage: + return Error(LinkageLoc, "invalid function linkage type"); + } + + if (!FunctionType::isValidReturnType(RetType)) + return Error(RetTypeLoc, "invalid function return type"); + + if (Lex.getKind() != lltok::GlobalVar) + return TokError("expected function name"); + + LocTy NameLoc = Lex.getLoc(); + std::string FunctionName = Lex.getStrVal(); + + if (Lex.Lex() != lltok::lparen) + return TokError("expected '(' in function argument list"); + + std::vector ArgList; + bool isVarArg; + if (ParseArgumentList(ArgList, isVarArg)) return true; + + unsigned FuncAttrs; + if (ParseOptionalAttrs(FuncAttrs, 2)) return true; + + // Section string. + std::string Section; + if (Lex.getKind() == lltok::kw_section) { + if (Lex.Lex() != lltok::StringConstant) + return TokError("expected section name"); + Section = Lex.getStrVal(); + Lex.Lex(); + } + + unsigned Alignment; + if (ParseOptionalAlignment(Alignment)) return true; + + // If the alignment was parsed as an attribute, move to the alignment field. + if (FuncAttrs & Attribute::Alignment) { + Alignment = Attribute::getAlignmentFromAttrs(FuncAttrs); + FuncAttrs &= ~Attribute::Alignment; + } + + // Optional GC setting. + std::string GC; + if (Lex.getKind() == lltok::kw_gc) { + if (Lex.Lex() != lltok::StringConstant) + return TokError("expected gc name"); + GC = Lex.getStrVal(); + Lex.Lex(); + } + + // Okay, if we got here, the function is syntactically valid. Convert types + // and do semantic checks. + std::vector ParamTypeList; + SmallVector Attrs; + // FIXME : In 3.0, stop accepting zext, sext and inreg as optional function + // attributes. + unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg; + if (FuncAttrs & ObsoleteFuncAttrs) { + RetAttrs |= FuncAttrs & ObsoleteFuncAttrs; + FuncAttrs &= ~ObsoleteFuncAttrs; + } + + if (RetAttrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { + ParamTypeList.push_back(ArgList[i].Type); + if (ArgList[i].Attrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + } + + if (FuncAttrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs)); + + AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + + const FunctionType *FT = FunctionType::get(RetType, ParamTypeList, isVarArg); + const PointerType *PFT = PointerType::getUnqual(FT); + + Fn = 0; + if (!FunctionName.empty()) { + // If this was a definition of a forward reference, remove the definition + // from the forward reference table and fill in the forward ref. + std::map >::iterator FRVI = + ForwardRefVals.find(FunctionName); + if (FRVI != ForwardRefVals.end()) { + Fn = M->getFunction(FunctionName); + ForwardRefVals.erase(FRVI); + } else if ((Fn = M->getFunction(FunctionName))) { + // If this function already exists in the symbol table, then it is + // multiply defined. We accept a few cases for old backwards compat. + // FIXME: Remove this stuff for LLVM 3.0. + if (Fn->getType() != PFT || Fn->getAttributes() != PAL || + (!Fn->isDeclaration() && isDefine)) { + // If the redefinition has different type or different attributes, + // reject it. If both have bodies, reject it. + return Error(NameLoc, "invalid redefinition of function '" + + FunctionName + "'"); + } else if (Fn->isDeclaration()) { + // Make sure to strip off any argument names so we can't get conflicts. + for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); + AI != AE; ++AI) + AI->setName(""); + } + } + + } else if (FunctionName.empty()) { + // If this is a definition of a forward referenced function, make sure the + // types agree. + std::map >::iterator I + = ForwardRefValIDs.find(NumberedVals.size()); + if (I != ForwardRefValIDs.end()) { + Fn = cast(I->second.first); + if (Fn->getType() != PFT) + return Error(NameLoc, "type of definition and forward reference of '@" + + utostr(NumberedVals.size()) +"' disagree"); + ForwardRefValIDs.erase(I); + } + } + + if (Fn == 0) + Fn = Function::Create(FT, GlobalValue::ExternalLinkage, FunctionName, M); + else // Move the forward-reference to the correct spot in the module. + M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn); + + if (FunctionName.empty()) + NumberedVals.push_back(Fn); + + Fn->setLinkage((GlobalValue::LinkageTypes)Linkage); + Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility); + Fn->setCallingConv(CC); + Fn->setAttributes(PAL); + Fn->setAlignment(Alignment); + Fn->setSection(Section); + if (!GC.empty()) Fn->setGC(GC.c_str()); + + // Add all of the arguments we parsed to the function. + Function::arg_iterator ArgIt = Fn->arg_begin(); + for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) { + // If the argument has a name, insert it into the argument symbol table. + if (ArgList[i].Name.empty()) continue; + + // Set the name, if it conflicted, it will be auto-renamed. + ArgIt->setName(ArgList[i].Name); + + if (ArgIt->getNameStr() != ArgList[i].Name) + return Error(ArgList[i].Loc, "redefinition of argument '%" + + ArgList[i].Name + "'"); + } + + return false; +} + + +/// ParseFunctionBody +/// ::= '{' BasicBlock+ '}' +/// ::= 'begin' BasicBlock+ 'end' // FIXME: remove in LLVM 3.0 +/// +bool LLParser::ParseFunctionBody(Function &Fn) { + if (Lex.getKind() != lltok::lbrace && Lex.getKind() != lltok::kw_begin) + return TokError("expected '{' in function body"); + Lex.Lex(); // eat the {. + + PerFunctionState PFS(*this, Fn); + + while (Lex.getKind() != lltok::rbrace && Lex.getKind() != lltok::kw_end) + if (ParseBasicBlock(PFS)) return true; + + // Eat the }. + Lex.Lex(); + + // Verify function is ok. + return PFS.VerifyFunctionComplete(); +} + +/// ParseBasicBlock +/// ::= LabelStr? Instruction* +bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { + // If this basic block starts out with a name, remember it. + std::string Name; + LocTy NameLoc = Lex.getLoc(); + if (Lex.getKind() == lltok::LabelStr) { + Name = Lex.getStrVal(); + Lex.Lex(); + } + + BasicBlock *BB = PFS.DefineBB(Name, NameLoc); + if (BB == 0) return true; + + std::string NameStr; + + // Parse the instructions in this block until we get a terminator. + Instruction *Inst; + do { + // This instruction may have three possibilities for a name: a) none + // specified, b) name specified "%foo =", c) number specified: "%4 =". + LocTy NameLoc = Lex.getLoc(); + int NameID = -1; + NameStr = ""; + + if (Lex.getKind() == lltok::LocalVarID) { + NameID = Lex.getUIntVal(); + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' after instruction id")) + return true; + } else if (Lex.getKind() == lltok::LocalVar || + // FIXME: REMOVE IN LLVM 3.0 + Lex.getKind() == lltok::StringConstant) { + NameStr = Lex.getStrVal(); + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' after instruction name")) + return true; + } + + if (ParseInstruction(Inst, BB, PFS)) return true; + + BB->getInstList().push_back(Inst); + + // Set the name on the instruction. + if (PFS.SetInstName(NameID, NameStr, NameLoc, Inst)) return true; + } while (!isa(Inst)); + + return false; +} + +//===----------------------------------------------------------------------===// +// Instruction Parsing. +//===----------------------------------------------------------------------===// + +/// ParseInstruction - Parse one of the many different instructions. +/// +bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, + PerFunctionState &PFS) { + lltok::Kind Token = Lex.getKind(); + if (Token == lltok::Eof) + return TokError("found end of file when expecting more instructions"); + LocTy Loc = Lex.getLoc(); + Lex.Lex(); // Eat the keyword. + + switch (Token) { + default: return Error(Loc, "expected instruction opcode"); + // Terminator Instructions. + case lltok::kw_unwind: Inst = new UnwindInst(); return false; + case lltok::kw_unreachable: Inst = new UnreachableInst(); return false; + case lltok::kw_ret: return ParseRet(Inst, BB, PFS); + case lltok::kw_br: return ParseBr(Inst, PFS); + case lltok::kw_switch: return ParseSwitch(Inst, PFS); + case lltok::kw_invoke: return ParseInvoke(Inst, PFS); + // Binary Operators. + case lltok::kw_add: + case lltok::kw_sub: + case lltok::kw_mul: + case lltok::kw_udiv: + case lltok::kw_sdiv: + case lltok::kw_fdiv: + case lltok::kw_urem: + case lltok::kw_srem: + case lltok::kw_frem: return ParseArithmetic(Inst, PFS, Lex.getUIntVal()); + case lltok::kw_shl: + case lltok::kw_lshr: + case lltok::kw_ashr: + case lltok::kw_and: + case lltok::kw_or: + case lltok::kw_xor: return ParseLogical(Inst, PFS, Lex.getUIntVal()); + case lltok::kw_icmp: + case lltok::kw_fcmp: + case lltok::kw_vicmp: + case lltok::kw_vfcmp: return ParseCompare(Inst, PFS, Lex.getUIntVal()); + // Casts. + case lltok::kw_trunc: + case lltok::kw_zext: + case lltok::kw_sext: + case lltok::kw_fptrunc: + case lltok::kw_fpext: + case lltok::kw_bitcast: + case lltok::kw_uitofp: + case lltok::kw_sitofp: + case lltok::kw_fptoui: + case lltok::kw_fptosi: + case lltok::kw_inttoptr: + case lltok::kw_ptrtoint: return ParseCast(Inst, PFS, Lex.getUIntVal()); + // Other. + case lltok::kw_select: return ParseSelect(Inst, PFS); + case lltok::kw_va_arg: return ParseVAArg(Inst, PFS); + case lltok::kw_extractelement: return ParseExtractElement(Inst, PFS); + case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS); + case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS); + case lltok::kw_phi: return ParsePHI(Inst, PFS); + case lltok::kw_call: return ParseCall(Inst, PFS, false); + case lltok::kw_tail: return ParseCall(Inst, PFS, true); + // Memory. + case lltok::kw_alloca: + case lltok::kw_malloc: return ParseAlloc(Inst, PFS, Lex.getUIntVal()); + case lltok::kw_free: return ParseFree(Inst, PFS); + case lltok::kw_load: return ParseLoad(Inst, PFS, false); + case lltok::kw_store: return ParseStore(Inst, PFS, false); + case lltok::kw_volatile: + if (Lex.getKind() == lltok::kw_load) { + Lex.Lex(); + return ParseLoad(Inst, PFS, true); + } else if (Lex.getKind() == lltok::kw_store) { + Lex.Lex(); + return ParseStore(Inst, PFS, true); + } else { + return TokError("expected 'load' or 'store'"); + } + case lltok::kw_getresult: return ParseGetResult(Inst, PFS); + case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS); + case lltok::kw_extractvalue: return ParseExtractValue(Inst, PFS); + case lltok::kw_insertvalue: return ParseInsertValue(Inst, PFS); + } +} + +/// ParseCmpPredicate - Parse an integer or fp predicate, based on Kind. +bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { + // FIXME: REMOVE vicmp/vfcmp! + if (Opc == Instruction::FCmp || Opc == Instruction::VFCmp) { + switch (Lex.getKind()) { + default: TokError("expected fcmp predicate (e.g. 'oeq')"); + case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break; + case lltok::kw_one: P = CmpInst::FCMP_ONE; break; + case lltok::kw_olt: P = CmpInst::FCMP_OLT; break; + case lltok::kw_ogt: P = CmpInst::FCMP_OGT; break; + case lltok::kw_ole: P = CmpInst::FCMP_OLE; break; + case lltok::kw_oge: P = CmpInst::FCMP_OGE; break; + case lltok::kw_ord: P = CmpInst::FCMP_ORD; break; + case lltok::kw_uno: P = CmpInst::FCMP_UNO; break; + case lltok::kw_ueq: P = CmpInst::FCMP_UEQ; break; + case lltok::kw_une: P = CmpInst::FCMP_UNE; break; + case lltok::kw_ult: P = CmpInst::FCMP_ULT; break; + case lltok::kw_ugt: P = CmpInst::FCMP_UGT; break; + case lltok::kw_ule: P = CmpInst::FCMP_ULE; break; + case lltok::kw_uge: P = CmpInst::FCMP_UGE; break; + case lltok::kw_true: P = CmpInst::FCMP_TRUE; break; + case lltok::kw_false: P = CmpInst::FCMP_FALSE; break; + } + } else { + switch (Lex.getKind()) { + default: TokError("expected icmp predicate (e.g. 'eq')"); + case lltok::kw_eq: P = CmpInst::ICMP_EQ; break; + case lltok::kw_ne: P = CmpInst::ICMP_NE; break; + case lltok::kw_slt: P = CmpInst::ICMP_SLT; break; + case lltok::kw_sgt: P = CmpInst::ICMP_SGT; break; + case lltok::kw_sle: P = CmpInst::ICMP_SLE; break; + case lltok::kw_sge: P = CmpInst::ICMP_SGE; break; + case lltok::kw_ult: P = CmpInst::ICMP_ULT; break; + case lltok::kw_ugt: P = CmpInst::ICMP_UGT; break; + case lltok::kw_ule: P = CmpInst::ICMP_ULE; break; + case lltok::kw_uge: P = CmpInst::ICMP_UGE; break; + } + } + Lex.Lex(); + return false; +} + +//===----------------------------------------------------------------------===// +// Terminator Instructions. +//===----------------------------------------------------------------------===// + +/// ParseRet - Parse a return instruction. +/// ::= 'ret' void +/// ::= 'ret' TypeAndValue +/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ [[obsolete: LLVM 3.0]] +bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, + PerFunctionState &PFS) { + PATypeHolder Ty(Type::VoidTy); + if (ParseType(Ty)) return true; + + if (Ty == Type::VoidTy) { + Inst = ReturnInst::Create(); + return false; + } + + Value *RV; + if (ParseValue(Ty, RV, PFS)) return true; + + // The normal case is one return value. + if (Lex.getKind() == lltok::comma) { + // FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use + // of 'ret {i32,i32} {i32 1, i32 2}' + SmallVector RVs; + RVs.push_back(RV); + + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); // Eat the comma. + if (ParseTypeAndValue(RV, PFS)) return true; + RVs.push_back(RV); + } + + RV = UndefValue::get(PFS.getFunction().getReturnType()); + for (unsigned i = 0, e = RVs.size(); i != e; ++i) { + Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv"); + BB->getInstList().push_back(I); + RV = I; + } + } + Inst = ReturnInst::Create(RV); + return false; +} + + +/// ParseBr +/// ::= 'br' TypeAndValue +/// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue +bool LLParser::ParseBr(Instruction *&Inst, PerFunctionState &PFS) { + LocTy Loc, Loc2; + Value *Op0, *Op1, *Op2; + if (ParseTypeAndValue(Op0, Loc, PFS)) return true; + + if (BasicBlock *BB = dyn_cast(Op0)) { + Inst = BranchInst::Create(BB); + return false; + } + + if (Op0->getType() != Type::Int1Ty) + return Error(Loc, "branch condition must have 'i1' type"); + + if (ParseToken(lltok::comma, "expected ',' after branch condition") || + ParseTypeAndValue(Op1, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after true destination") || + ParseTypeAndValue(Op2, Loc2, PFS)) + return true; + + if (!isa(Op1)) + return Error(Loc, "true destination of branch must be a basic block"); + + if (!isa(Op2)) + return Error(Loc2, "true destination of branch must be a basic block"); + + Inst = BranchInst::Create(cast(Op1), cast(Op2), Op0); + return false; +} + +/// ParseSwitch +/// Instruction +/// ::= 'switch' TypeAndValue ',' TypeAndValue '[' JumpTable ']' +/// JumpTable +/// ::= (TypeAndValue ',' TypeAndValue)* +bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) { + LocTy CondLoc, BBLoc; + Value *Cond, *DefaultBB; + if (ParseTypeAndValue(Cond, CondLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after switch condition") || + ParseTypeAndValue(DefaultBB, BBLoc, PFS) || + ParseToken(lltok::lsquare, "expected '[' with switch table")) + return true; + + if (!isa(Cond->getType())) + return Error(CondLoc, "switch condition must have integer type"); + if (!isa(DefaultBB)) + return Error(BBLoc, "default destination must be a basic block"); + + // Parse the jump table pairs. + SmallPtrSet SeenCases; + SmallVector, 32> Table; + while (Lex.getKind() != lltok::rsquare) { + Value *Constant, *DestBB; + + if (ParseTypeAndValue(Constant, CondLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after case value") || + ParseTypeAndValue(DestBB, BBLoc, PFS)) + return true; + + if (!SeenCases.insert(Constant)) + return Error(CondLoc, "duplicate case value in switch"); + if (!isa(Constant)) + return Error(CondLoc, "case value is not a constant integer"); + if (!isa(DestBB)) + return Error(BBLoc, "case destination is not a basic block"); + + Table.push_back(std::make_pair(cast(Constant), + cast(DestBB))); + } + + Lex.Lex(); // Eat the ']'. + + SwitchInst *SI = SwitchInst::Create(Cond, cast(DefaultBB), + Table.size()); + for (unsigned i = 0, e = Table.size(); i != e; ++i) + SI->addCase(Table[i].first, Table[i].second); + Inst = SI; + return false; +} + +/// ParseInvoke +/// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList +/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue +bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { + LocTy CallLoc = Lex.getLoc(); + unsigned CC, RetAttrs, FnAttrs; + PATypeHolder RetType(Type::VoidTy); + LocTy RetTypeLoc; + ValID CalleeID; + SmallVector ArgList; + + Value *NormalBB, *UnwindBB; + if (ParseOptionalCallingConv(CC) || + ParseOptionalAttrs(RetAttrs, 1) || + ParseType(RetType, RetTypeLoc) || + ParseValID(CalleeID) || + ParseParameterList(ArgList, PFS) || + ParseOptionalAttrs(FnAttrs, 2) || + ParseToken(lltok::kw_to, "expected 'to' in invoke") || + ParseTypeAndValue(NormalBB, PFS) || + ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || + ParseTypeAndValue(UnwindBB, PFS)) + return true; + + if (!isa(NormalBB)) + return Error(CallLoc, "normal destination is not a basic block"); + if (!isa(UnwindBB)) + return Error(CallLoc, "unwind destination is not a basic block"); + + // If RetType is a non-function pointer type, then this is the short syntax + // for the call, which means that RetType is just the return type. Infer the + // rest of the function argument types from the arguments that are present. + const PointerType *PFTy = 0; + const FunctionType *Ty = 0; + if (!(PFTy = dyn_cast(RetType)) || + !(Ty = dyn_cast(PFTy->getElementType()))) { + // Pull out the types of all of the arguments... + std::vector ParamTypes; + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) + ParamTypes.push_back(ArgList[i].V->getType()); + + if (!FunctionType::isValidReturnType(RetType)) + return Error(RetTypeLoc, "Invalid result type for LLVM function"); + + Ty = FunctionType::get(RetType, ParamTypes, false); + PFTy = PointerType::getUnqual(Ty); + } + + // Look up the callee. + Value *Callee; + if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true; + + // FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional + // function attributes. + unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg; + if (FnAttrs & ObsoleteFuncAttrs) { + RetAttrs |= FnAttrs & ObsoleteFuncAttrs; + FnAttrs &= ~ObsoleteFuncAttrs; + } + + // Set up the Attributes for the function. + SmallVector Attrs; + if (RetAttrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + + SmallVector Args; + + // Loop through FunctionType's arguments and ensure they are specified + // correctly. Also, gather any parameter attributes. + FunctionType::param_iterator I = Ty->param_begin(); + FunctionType::param_iterator E = Ty->param_end(); + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { + const Type *ExpectedTy = 0; + if (I != E) { + ExpectedTy = *I++; + } else if (!Ty->isVarArg()) { + return Error(ArgList[i].Loc, "too many arguments specified"); + } + + if (ExpectedTy && ExpectedTy != ArgList[i].V->getType()) + return Error(ArgList[i].Loc, "argument is not of expected type '" + + ExpectedTy->getDescription() + "'"); + Args.push_back(ArgList[i].V); + if (ArgList[i].Attrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + } + + if (I != E) + return Error(CallLoc, "not enough parameters specified for call"); + + if (FnAttrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); + + // Finish off the Attributes and check them + AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + + InvokeInst *II = InvokeInst::Create(Callee, cast(NormalBB), + cast(UnwindBB), + Args.begin(), Args.end()); + II->setCallingConv(CC); + II->setAttributes(PAL); + Inst = II; + return false; +} + + + +//===----------------------------------------------------------------------===// +// Binary Operators. +//===----------------------------------------------------------------------===// + +/// ParseArithmetic +/// ::= ArithmeticOps TypeAndValue ',' Value { +bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, + unsigned Opc) { + LocTy Loc; Value *LHS, *RHS; + if (ParseTypeAndValue(LHS, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' in arithmetic operation") || + ParseValue(LHS->getType(), RHS, PFS)) + return true; + + if (!isa(LHS->getType()) && !LHS->getType()->isFloatingPoint() && + !isa(LHS->getType())) + return Error(Loc, "instruction requires integer, fp, or vector operands"); + + Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); + return false; +} + +/// ParseLogical +/// ::= ArithmeticOps TypeAndValue ',' Value { +bool LLParser::ParseLogical(Instruction *&Inst, PerFunctionState &PFS, + unsigned Opc) { + LocTy Loc; Value *LHS, *RHS; + if (ParseTypeAndValue(LHS, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' in logical operation") || + ParseValue(LHS->getType(), RHS, PFS)) + return true; + + if (!LHS->getType()->isIntOrIntVector()) + return Error(Loc,"instruction requires integer or integer vector operands"); + + Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); + return false; +} + + +/// ParseCompare +/// ::= 'icmp' IPredicates TypeAndValue ',' Value +/// ::= 'fcmp' FPredicates TypeAndValue ',' Value +/// ::= 'vicmp' IPredicates TypeAndValue ',' Value +/// ::= 'vfcmp' FPredicates TypeAndValue ',' Value +bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS, + unsigned Opc) { + // Parse the integer/fp comparison predicate. + LocTy Loc; + unsigned Pred; + Value *LHS, *RHS; + if (ParseCmpPredicate(Pred, Opc) || + ParseTypeAndValue(LHS, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after compare value") || + ParseValue(LHS->getType(), RHS, PFS)) + return true; + + if (Opc == Instruction::FCmp) { + if (!LHS->getType()->isFPOrFPVector()) + return Error(Loc, "fcmp requires floating point operands"); + Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS); + } else if (Opc == Instruction::ICmp) { + if (!LHS->getType()->isIntOrIntVector() && + !isa(LHS->getType())) + return Error(Loc, "icmp requires integer operands"); + Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS); + } else if (Opc == Instruction::VFCmp) { + Inst = new VFCmpInst(CmpInst::Predicate(Pred), LHS, RHS); + } else if (Opc == Instruction::VICmp) { + Inst = new VICmpInst(CmpInst::Predicate(Pred), LHS, RHS); + } + return false; +} + +//===----------------------------------------------------------------------===// +// Other Instructions. +//===----------------------------------------------------------------------===// + + +/// ParseCast +/// ::= CastOpc TypeAndValue 'to' Type +bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS, + unsigned Opc) { + LocTy Loc; Value *Op; + PATypeHolder DestTy(Type::VoidTy); + if (ParseTypeAndValue(Op, Loc, PFS) || + ParseToken(lltok::kw_to, "expected 'to' after cast value") || + ParseType(DestTy)) + return true; + + if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy)) + return Error(Loc, "invalid cast opcode for cast from '" + + Op->getType()->getDescription() + "' to '" + + DestTy->getDescription() + "'"); + Inst = CastInst::Create((Instruction::CastOps)Opc, Op, DestTy); + return false; +} + +/// ParseSelect +/// ::= 'select' TypeAndValue ',' TypeAndValue ',' TypeAndValue +bool LLParser::ParseSelect(Instruction *&Inst, PerFunctionState &PFS) { + LocTy Loc; + Value *Op0, *Op1, *Op2; + if (ParseTypeAndValue(Op0, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after select condition") || + ParseTypeAndValue(Op1, PFS) || + ParseToken(lltok::comma, "expected ',' after select value") || + ParseTypeAndValue(Op2, PFS)) + return true; + + if (const char *Reason = SelectInst::areInvalidOperands(Op0, Op1, Op2)) + return Error(Loc, Reason); + + Inst = SelectInst::Create(Op0, Op1, Op2); + return false; +} + +/// ParseVAArg +/// ::= 'vaarg' TypeAndValue ',' Type +bool LLParser::ParseVAArg(Instruction *&Inst, PerFunctionState &PFS) { + Value *Op; + PATypeHolder EltTy(Type::VoidTy); + if (ParseTypeAndValue(Op, PFS) || + ParseToken(lltok::comma, "expected ',' after vaarg operand") || + ParseType(EltTy)) + return true; + + Inst = new VAArgInst(Op, EltTy); + return false; +} + +/// ParseExtractElement +/// ::= 'extractelement' TypeAndValue ',' TypeAndValue +bool LLParser::ParseExtractElement(Instruction *&Inst, PerFunctionState &PFS) { + LocTy Loc; + Value *Op0, *Op1; + if (ParseTypeAndValue(Op0, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after extract value") || + ParseTypeAndValue(Op1, PFS)) + return true; + + if (!ExtractElementInst::isValidOperands(Op0, Op1)) + return Error(Loc, "invalid extractelement operands"); + + Inst = new ExtractElementInst(Op0, Op1); + return false; +} + +/// ParseInsertElement +/// ::= 'insertelement' TypeAndValue ',' TypeAndValue ',' TypeAndValue +bool LLParser::ParseInsertElement(Instruction *&Inst, PerFunctionState &PFS) { + LocTy Loc; + Value *Op0, *Op1, *Op2; + if (ParseTypeAndValue(Op0, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after insertelement value") || + ParseTypeAndValue(Op1, PFS) || + ParseToken(lltok::comma, "expected ',' after insertelement value") || + ParseTypeAndValue(Op2, PFS)) + return true; + + if (!InsertElementInst::isValidOperands(Op0, Op1, Op2)) + return Error(Loc, "invalid extractelement operands"); + + Inst = InsertElementInst::Create(Op0, Op1, Op2); + return false; +} + +/// ParseShuffleVector +/// ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue +bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) { + LocTy Loc; + Value *Op0, *Op1, *Op2; + if (ParseTypeAndValue(Op0, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after shuffle mask") || + ParseTypeAndValue(Op1, PFS) || + ParseToken(lltok::comma, "expected ',' after shuffle value") || + ParseTypeAndValue(Op2, PFS)) + return true; + + if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2)) + return Error(Loc, "invalid extractelement operands"); + + Inst = new ShuffleVectorInst(Op0, Op1, Op2); + return false; +} + +/// ParsePHI +/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Valueß ']')* +bool LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { + PATypeHolder Ty(Type::VoidTy); + Value *Op0, *Op1; + LocTy TypeLoc = Lex.getLoc(); + + if (ParseType(Ty) || + ParseToken(lltok::lsquare, "expected '[' in phi value list") || + ParseValue(Ty, Op0, PFS) || + ParseToken(lltok::comma, "expected ',' after insertelement value") || + ParseValue(Type::LabelTy, Op1, PFS) || + ParseToken(lltok::rsquare, "expected ']' in phi value list")) + return true; + + SmallVector, 16> PHIVals; + while (1) { + PHIVals.push_back(std::make_pair(Op0, cast(Op1))); + + if (Lex.getKind() != lltok::comma) + break; + + if (ParseToken(lltok::comma, 0) || + ParseToken(lltok::lsquare, "expected '[' in phi value list") || + ParseValue(Ty, Op0, PFS) || + ParseToken(lltok::comma, "expected ',' after insertelement value") || + ParseValue(Type::LabelTy, Op1, PFS) || + ParseToken(lltok::rsquare, "expected ']' in phi value list")) + return true; + } + + if (!Ty->isFirstClassType()) + return Error(TypeLoc, "phi node must have first class type"); + + PHINode *PN = PHINode::Create(Ty); + PN->reserveOperandSpace(PHIVals.size()); + for (unsigned i = 0, e = PHIVals.size(); i != e; ++i) + PN->addIncoming(PHIVals[i].first, PHIVals[i].second); + Inst = PN; + return false; +} + +/// ParseCall +/// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value +/// ParameterList OptionalAttrs +bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, + bool isTail) { + unsigned CC, RetAttrs, FnAttrs; + PATypeHolder RetType(Type::VoidTy); + LocTy RetTypeLoc; + ValID CalleeID; + SmallVector ArgList; + LocTy CallLoc = Lex.getLoc(); + + if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) || + ParseOptionalCallingConv(CC) || + ParseOptionalAttrs(RetAttrs, 1) || + ParseType(RetType, RetTypeLoc) || + ParseValID(CalleeID) || + ParseParameterList(ArgList, PFS) || + ParseOptionalAttrs(FnAttrs, 2)) + return true; + + // If RetType is a non-function pointer type, then this is the short syntax + // for the call, which means that RetType is just the return type. Infer the + // rest of the function argument types from the arguments that are present. + const PointerType *PFTy = 0; + const FunctionType *Ty = 0; + if (!(PFTy = dyn_cast(RetType)) || + !(Ty = dyn_cast(PFTy->getElementType()))) { + // Pull out the types of all of the arguments... + std::vector ParamTypes; + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) + ParamTypes.push_back(ArgList[i].V->getType()); + + if (!FunctionType::isValidReturnType(RetType)) + return Error(RetTypeLoc, "Invalid result type for LLVM function"); + + Ty = FunctionType::get(RetType, ParamTypes, false); + PFTy = PointerType::getUnqual(Ty); + } + + // Look up the callee. + Value *Callee; + if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true; + + // Check for call to invalid intrinsic to avoid crashing later. + if (Function *F = dyn_cast(Callee)) { + if (F->hasName() && F->getNameLen() >= 5 && + !strncmp(F->getValueName()->getKeyData(), "llvm.", 5) && + !F->getIntrinsicID(true)) + return Error(CallLoc, "Call to invalid LLVM intrinsic function '" + + F->getNameStr() + "'"); + } + + // FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional + // function attributes. + unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg; + if (FnAttrs & ObsoleteFuncAttrs) { + RetAttrs |= FnAttrs & ObsoleteFuncAttrs; + FnAttrs &= ~ObsoleteFuncAttrs; + } + + // Set up the Attributes for the function. + SmallVector Attrs; + if (RetAttrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + + SmallVector Args; + + // Loop through FunctionType's arguments and ensure they are specified + // correctly. Also, gather any parameter attributes. + FunctionType::param_iterator I = Ty->param_begin(); + FunctionType::param_iterator E = Ty->param_end(); + for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { + const Type *ExpectedTy = 0; + if (I != E) { + ExpectedTy = *I++; + } else if (!Ty->isVarArg()) { + return Error(ArgList[i].Loc, "too many arguments specified"); + } + + if (ExpectedTy && ExpectedTy != ArgList[i].V->getType()) + return Error(ArgList[i].Loc, "argument is not of expected type '" + + ExpectedTy->getDescription() + "'"); + Args.push_back(ArgList[i].V); + if (ArgList[i].Attrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + } + + if (I != E) + return Error(CallLoc, "not enough parameters specified for call"); + + if (FnAttrs != Attribute::None) + Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); + + // Finish off the Attributes and check them + AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); + + CallInst *CI = CallInst::Create(Callee, Args.begin(), Args.end()); + CI->setTailCall(isTail); + CI->setCallingConv(CC); + CI->setAttributes(PAL); + Inst = CI; + return false; +} + +//===----------------------------------------------------------------------===// +// Memory Instructions. +//===----------------------------------------------------------------------===// + +/// ParseAlloc +/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalAlignment)? +/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalAlignment)? +bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS, + unsigned Opc) { + PATypeHolder Ty(Type::VoidTy); + Value *Size = 0; + LocTy SizeLoc = 0; + unsigned Alignment = 0; + bool HasComma; + if (ParseType(Ty) || + ParseOptionalToken(lltok::comma, HasComma)) + return true; + + if (HasComma) { + if (Lex.getKind() == lltok::kw_align) { + if (ParseOptionalAlignment(Alignment)) return true; + } else { + if (ParseTypeAndValue(Size, SizeLoc, PFS)) return true; + if (ParseOptionalCommaAlignment(Alignment)) + return true; + } + } + + if (Size && Size->getType() != Type::Int32Ty) + return Error(SizeLoc, "element count must be i32"); + + if (Opc == Instruction::Malloc) + Inst = new MallocInst(Ty, Size, Alignment); + else + Inst = new AllocaInst(Ty, Size, Alignment); + return false; +} + +/// ParseFree +/// ::= 'free' TypeAndValue +bool LLParser::ParseFree(Instruction *&Inst, PerFunctionState &PFS) { + Value *Val; LocTy Loc; + if (ParseTypeAndValue(Val, Loc, PFS)) return true; + if (!isa(Val->getType())) + return Error(Loc, "operand to free must be a pointer"); + Inst = new FreeInst(Val); + return false; +} + +/// ParseLoad +/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' uint)? +bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS, + bool isVolatile) { + Value *Val; LocTy Loc; + unsigned Alignment; + if (ParseTypeAndValue(Val, Loc, PFS) || + ParseOptionalCommaAlignment(Alignment)) + return true; + + if (!isa(Val->getType()) || + !cast(Val->getType())->getElementType()->isFirstClassType()) + return Error(Loc, "load operand must be a pointer to a first class type"); + + Inst = new LoadInst(Val, "", isVolatile, Alignment); + return false; +} + +/// ParseStore +/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' uint)? +bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS, + bool isVolatile) { + Value *Val, *Ptr; LocTy Loc, PtrLoc; + unsigned Alignment; + if (ParseTypeAndValue(Val, Loc, PFS) || + ParseToken(lltok::comma, "expected ',' after store operand") || + ParseTypeAndValue(Ptr, PtrLoc, PFS) || + ParseOptionalCommaAlignment(Alignment)) + return true; + + if (!isa(Ptr->getType())) + return Error(PtrLoc, "store operand must be a pointer"); + if (!Val->getType()->isFirstClassType()) + return Error(Loc, "store operand must be a first class value"); + if (cast(Ptr->getType())->getElementType() != Val->getType()) + return Error(Loc, "stored value and pointer type do not match"); + + Inst = new StoreInst(Val, Ptr, isVolatile, Alignment); + return false; +} + +/// ParseGetResult +/// ::= 'getresult' TypeAndValue ',' uint +/// FIXME: Remove support for getresult in LLVM 3.0 +bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) { + Value *Val; LocTy ValLoc, EltLoc; + unsigned Element; + if (ParseTypeAndValue(Val, ValLoc, PFS) || + ParseToken(lltok::comma, "expected ',' after getresult operand") || + ParseUnsigned(Element, EltLoc)) + return true; + + if (!isa(Val->getType()) && !isa(Val->getType())) + return Error(ValLoc, "getresult inst requires an aggregate operand"); + if (!ExtractValueInst::getIndexedType(Val->getType(), Element)) + return Error(EltLoc, "invalid getresult index for value"); + Inst = ExtractValueInst::Create(Val, Element); + return false; +} + +/// ParseGetElementPtr +/// ::= 'getelementptr' TypeAndValue (',' TypeAndValue)* +bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { + Value *Ptr, *Val; LocTy Loc, EltLoc; + if (ParseTypeAndValue(Ptr, Loc, PFS)) + return true; + + if (!isa(Ptr->getType())) + return Error(Loc, "base of getelementptr must be a pointer"); + + SmallVector Indices; + while (Lex.getKind() == lltok::comma) { + Lex.Lex(); + if (ParseTypeAndValue(Val, EltLoc, PFS)) + return true; + if (!isa(Val->getType())) + return Error(EltLoc, "getelementptr index must be an integer"); + Indices.push_back(Val); + } + + if (!GetElementPtrInst::getIndexedType(Ptr->getType(), + Indices.begin(), Indices.end())) + return Error(Loc, "invalid getelementptr indices"); + Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end()); + return false; +} + +/// ParseExtractValue +/// ::= 'extractvalue' TypeAndValue (',' uint32)+ +bool LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) { + Value *Val; LocTy Loc; + SmallVector Indices; + if (ParseTypeAndValue(Val, Loc, PFS) || + ParseIndexList(Indices)) + return true; + + if (!isa(Val->getType()) && !isa(Val->getType())) + return Error(Loc, "extractvalue operand must be array or struct"); + + if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(), + Indices.end())) + return Error(Loc, "invalid indices for extractvalue"); + Inst = ExtractValueInst::Create(Val, Indices.begin(), Indices.end()); + return false; +} + +/// ParseInsertValue +/// ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+ +bool LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { + Value *Val0, *Val1; LocTy Loc0, Loc1; + SmallVector Indices; + if (ParseTypeAndValue(Val0, Loc0, PFS) || + ParseToken(lltok::comma, "expected comma after insertvalue operand") || + ParseTypeAndValue(Val1, Loc1, PFS) || + ParseIndexList(Indices)) + return true; + + if (!isa(Val0->getType()) && !isa(Val0->getType())) + return Error(Loc0, "extractvalue operand must be array or struct"); + + if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(), + Indices.end())) + return Error(Loc0, "invalid indices for insertvalue"); + Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end()); + return false; +} diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h new file mode 100644 index 00000000000..1ea19793795 --- /dev/null +++ b/lib/AsmParser/LLParser.h @@ -0,0 +1,266 @@ +//===-- LLParser.h - Parser Class -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the parser class for .ll files. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ASMPARSER_LLPARSER_H +#define LLVM_ASMPARSER_LLPARSER_H + +#include "LLLexer.h" +#include "llvm/Type.h" +#include + +namespace llvm { + class Module; + class OpaqueType; + class Function; + class Value; + class BasicBlock; + class Instruction; + class Constant; + class GlobalValue; + struct ValID; + + class LLParser { + public: + typedef LLLexer::LocTy LocTy; + private: + + LLLexer Lex; + Module *M; + + // Type resolution handling data structures. + std::map > ForwardRefTypes; + std::map > ForwardRefTypeIDs; + std::vector NumberedTypes; + + struct UpRefRecord { + /// Loc - This is the location of the upref. + LocTy Loc; + + /// 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(LocTy L, unsigned NL, OpaqueType *URTy) + : Loc(L), NestingLevel(NL), LastContainedTy((Type*)URTy), + UpRefTy(URTy) {} + }; + std::vector UpRefs; + + // Global Value reference information. + std::map > ForwardRefVals; + std::map > ForwardRefValIDs; + std::vector NumberedVals; + public: + LLParser(MemoryBuffer *F, ParseError &Err) : Lex(F, Err), M(0) {} + Module *Run(); + + private: + + bool Error(LocTy L, const std::string &Msg) const { + return Lex.Error(L, Msg); + } + bool TokError(const std::string &Msg) const { + return Error(Lex.getLoc(), Msg); + } + + /// GetGlobalVal - Get a value with the specified name or ID, creating a + /// forward reference record if needed. This can return null if the value + /// exists but does not have the right type. + GlobalValue *GetGlobalVal(const std::string &N, const Type *Ty, LocTy Loc); + GlobalValue *GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc); + + // Helper Routines. + bool ParseToken(lltok::Kind T, const char *ErrMsg); + bool ParseOptionalToken(lltok::Kind T, bool &Present) { + if (Lex.getKind() != T) { + Present = false; + } else { + Lex.Lex(); + Present = true; + } + return false; + } + bool ParseUnsigned(unsigned &Val); + bool ParseUnsigned(unsigned &Val, LocTy &Loc) { + Loc = Lex.getLoc(); + return ParseUnsigned(Val); + } + bool ParseOptionalAddrSpace(unsigned &AddrSpace); + bool ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind); + bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage); + bool ParseOptionalLinkage(unsigned &Linkage) { + bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage); + } + bool ParseOptionalVisibility(unsigned &Visibility); + bool ParseOptionalCallingConv(unsigned &CC); + bool ParseOptionalAlignment(unsigned &Alignment); + bool ParseOptionalCommaAlignment(unsigned &Alignment); + bool ParseIndexList(SmallVectorImpl &Indices); + + // Top-Level Entities + bool ParseTopLevelEntities(); + bool ValidateEndOfModule(); + bool ParseTargetDefinition(); + bool ParseDepLibs(); + bool ParseModuleAsm(); + bool ParseUnnamedType(); + bool ParseNamedType(); + bool ParseDeclare(); + bool ParseDefine(); + + bool ParseGlobalType(bool &IsConstant); + bool ParseNamedGlobal(); + bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage, + bool HasLinkage, unsigned Visibility); + bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility); + + // Type Parsing. + bool ParseType(PATypeHolder &Result); + bool ParseType(PATypeHolder &Result, LocTy &Loc) { + Loc = Lex.getLoc(); + return ParseType(Result); + } + bool ParseTypeRec(PATypeHolder &H); + bool ParseStructType(PATypeHolder &H, bool Packed); + bool ParseArrayVectorType(PATypeHolder &H, bool isVector); + bool ParseFunctionType(PATypeHolder &Result); + PATypeHolder HandleUpRefs(const Type *Ty); + + // Constants. + bool ParseValID(ValID &ID); + bool ConvertGlobalValIDToValue(const Type *Ty, ValID &ID, Constant *&V); + bool ParseGlobalValue(const Type *Ty, Constant *&V); + bool ParseGlobalTypeAndValue(Constant *&V); + bool ParseGlobalValueVector(SmallVectorImpl &Elts); + + + // Function Semantic Analysis. + class PerFunctionState { + LLParser &P; + Function &F; + std::map > ForwardRefVals; + std::map > ForwardRefValIDs; + std::vector NumberedVals; + public: + PerFunctionState(LLParser &p, Function &f); + ~PerFunctionState(); + + Function &getFunction() const { return F; } + + bool VerifyFunctionComplete(); + + /// GetVal - Get a value with the specified name or ID, creating a + /// forward reference record if needed. This can return null if the value + /// exists but does not have the right type. + Value *GetVal(const std::string &Name, const Type *Ty, LocTy Loc); + Value *GetVal(unsigned ID, const Type *Ty, LocTy Loc); + + /// SetInstName - After an instruction is parsed and inserted into its + /// basic block, this installs its name. + bool SetInstName(int NameID, const std::string &NameStr, LocTy NameLoc, + Instruction *Inst); + + /// GetBB - Get a basic block with the specified name or ID, creating a + /// forward reference record if needed. This can return null if the value + /// is not a BasicBlock. + BasicBlock *GetBB(const std::string &Name, LocTy Loc); + BasicBlock *GetBB(unsigned ID, LocTy Loc); + + /// DefineBB - Define the specified basic block, which is either named or + /// unnamed. If there is an error, this returns null otherwise it returns + /// the block being defined. + BasicBlock *DefineBB(const std::string &Name, LocTy Loc); + }; + + bool ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V, + PerFunctionState &PFS); + + bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS); + bool ParseValue(const Type *Ty, Value *&V, LocTy &Loc, + PerFunctionState &PFS) { + Loc = Lex.getLoc(); + return ParseValue(Ty, V, PFS); + } + + bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS); + bool ParseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) { + Loc = Lex.getLoc(); + return ParseTypeAndValue(V, PFS); + } + + struct ParamInfo { + LocTy Loc; + Value *V; + unsigned Attrs; + ParamInfo(LocTy loc, Value *v, unsigned attrs) + : Loc(loc), V(v), Attrs(attrs) {} + }; + bool ParseParameterList(SmallVectorImpl &ArgList, + PerFunctionState &PFS); + + // Function Parsing. + struct ArgInfo { + LocTy Loc; + PATypeHolder Type; + unsigned Attrs; + std::string Name; + ArgInfo(LocTy L, PATypeHolder Ty, unsigned Attr, const std::string &N) + : Loc(L), Type(Ty), Attrs(Attr), Name(N) {} + }; + bool ParseArgumentList(std::vector &ArgList, + bool &isVarArg); + bool ParseFunctionHeader(Function *&Fn, bool isDefine); + bool ParseFunctionBody(Function &Fn); + bool ParseBasicBlock(PerFunctionState &PFS); + + // Instruction Parsing. + bool ParseInstruction(Instruction *&Inst, BasicBlock *BB, + PerFunctionState &PFS); + bool ParseCmpPredicate(unsigned &Pred, unsigned Opc); + + bool ParseRet(Instruction *&Inst, BasicBlock *BB, PerFunctionState &PFS); + bool ParseBr(Instruction *&Inst, PerFunctionState &PFS); + bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); + bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); + + bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc); + bool ParseLogical(Instruction *&I, PerFunctionState &PFS, unsigned Opc); + bool ParseCompare(Instruction *&I, PerFunctionState &PFS, unsigned Opc); + bool ParseCast(Instruction *&I, PerFunctionState &PFS, unsigned Opc); + bool ParseSelect(Instruction *&I, PerFunctionState &PFS); + bool ParseVAArg(Instruction *&I, PerFunctionState &PFS); + bool ParseExtractElement(Instruction *&I, PerFunctionState &PFS); + bool ParseInsertElement(Instruction *&I, PerFunctionState &PFS); + bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS); + bool ParsePHI(Instruction *&I, PerFunctionState &PFS); + bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail); + bool ParseAlloc(Instruction *&I, PerFunctionState &PFS, unsigned Opc); + bool ParseFree(Instruction *&I, PerFunctionState &PFS); + bool ParseLoad(Instruction *&I, PerFunctionState &PFS, bool isVolatile); + bool ParseStore(Instruction *&I, PerFunctionState &PFS, bool isVolatile); + bool ParseGetResult(Instruction *&I, PerFunctionState &PFS); + bool ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS); + bool ParseExtractValue(Instruction *&I, PerFunctionState &PFS); + bool ParseInsertValue(Instruction *&I, PerFunctionState &PFS); + }; +} // End llvm namespace + +#endif diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h new file mode 100644 index 00000000000..78286005b8b --- /dev/null +++ b/lib/AsmParser/LLToken.h @@ -0,0 +1,126 @@ +//===- LLToken.h - Token Codes for LLVM Assembly Files ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the enums for the .ll lexer. +// +//===----------------------------------------------------------------------===// + +#ifndef LIBS_ASMPARSER_LLTOKEN_H +#define LIBS_ASMPARSER_LLTOKEN_H + +namespace llvm { +namespace lltok { + enum Kind { + // Markers + Eof, Error, + + // Tokens with no info. + dotdotdot, // ... + equal, comma, // = , + star, // * + lsquare, rsquare, // [ ] + lbrace, rbrace, // { } + less, greater, // < > + lparen, rparen, // ( ) + backslash, // \ / + + kw_x, + kw_begin, kw_end, + kw_true, kw_false, + kw_declare, kw_define, + kw_global, kw_constant, + + kw_internal, kw_linkonce, kw_weak, kw_appending, kw_dllimport, + kw_dllexport, kw_common, kw_default, kw_hidden, kw_protected, + kw_extern_weak, + kw_external, kw_thread_local, + kw_zeroinitializer, + kw_undef, kw_null, + kw_to, + kw_tail, + kw_target, + kw_triple, + kw_deplibs, + kw_datalayout, + kw_volatile, + kw_align, + kw_addrspace, + kw_section, + kw_alias, + kw_module, + kw_asm, + kw_sideeffect, + kw_gc, + kw_c, + + kw_cc, kw_ccc, kw_fastcc, kw_coldcc, kw_x86_stdcallcc, kw_x86_fastcallcc, + + kw_signext, + kw_zeroext, + kw_inreg, + kw_sret, + kw_nounwind, + kw_noreturn, + kw_noalias, + kw_nocapture, + kw_byval, + kw_nest, + kw_readnone, + kw_readonly, + + kw_noinline, + kw_alwaysinline, + kw_optsize, + kw_ssp, + kw_sspreq, + + kw_type, + kw_opaque, + + kw_eq, kw_ne, kw_slt, kw_sgt, kw_sle, kw_sge, kw_ult, kw_ugt, kw_ule, + kw_uge, kw_oeq, kw_one, kw_olt, kw_ogt, kw_ole, kw_oge, kw_ord, kw_uno, + kw_ueq, kw_une, + + // Instruction Opcodes (Opcode in UIntVal). + kw_add, kw_sub, kw_mul, kw_udiv, kw_sdiv, kw_fdiv, + kw_urem, kw_srem, kw_frem, kw_shl, kw_lshr, kw_ashr, + kw_and, kw_or, kw_xor, kw_icmp, kw_fcmp, kw_vicmp, kw_vfcmp, + + kw_phi, kw_call, + kw_trunc, kw_zext, kw_sext, kw_fptrunc, kw_fpext, kw_uitofp, kw_sitofp, + kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast, + kw_select, kw_va_arg, + + kw_ret, kw_br, kw_switch, kw_invoke, kw_unwind, kw_unreachable, + + kw_malloc, kw_alloca, kw_free, kw_load, kw_store, kw_getelementptr, + + kw_extractelement, kw_insertelement, kw_shufflevector, kw_getresult, + kw_extractvalue, kw_insertvalue, + + // Unsigned Valued tokens (UIntVal). + GlobalID, // @42 + LocalVarID, // %42 + + // String valued tokens (StrVal). + LabelStr, // foo: + GlobalVar, // @foo @"foo" + LocalVar, // %foo %"foo" + StringConstant, // "foo" + + // Type valued tokens (TyVal). + Type, + + APFloat, // APFloatVal + APSInt, // APSInt + }; +} // end namespace lltok +} // end namespace llvm + +#endif diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp index 0005e11737b..36c9712b9d5 100644 --- a/lib/AsmParser/Parser.cpp +++ b/lib/AsmParser/Parser.cpp @@ -1,4 +1,4 @@ -//===- Parser.cpp - Main dispatch module for the Parser library -------------=== +//===- Parser.cpp - Main dispatch module for the Parser library -----------===// // // The LLVM Compiler Infrastructure // @@ -9,39 +9,40 @@ // // This library implements the functionality defined in llvm/assembly/parser.h // -//===------------------------------------------------------------------------=== +//===----------------------------------------------------------------------===// -#include "ParserInternals.h" +#include "llvm/Assembly/Parser.h" +#include "LLParser.h" #include "llvm/Module.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" #include using namespace llvm; - -ParseError* TheParseError = 0; /// FIXME: Not threading friendly - -Module *llvm::ParseAssemblyFile(const std::string &Filename, ParseError* Err) { +Module *llvm::ParseAssemblyFile(const std::string &Filename, ParseError &Err) { + Err.setFilename(Filename); + std::string ErrorStr; MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrorStr); if (F == 0) { - if (Err) - Err->setError(Filename, "Could not open input file '" + Filename + "'"); + Err.setError("Could not open input file '" + Filename + "'"); return 0; } - TheParseError = Err; - Module *Result = RunVMAsmParser(F); + Module *Result = LLParser(F, Err).Run(); delete F; return Result; } +// FIXME: M is ignored?? Module *llvm::ParseAssemblyString(const char *AsmString, Module *M, - ParseError *Err) { - TheParseError = Err; + ParseError &Err) { + Err.setFilename(""); + MemoryBuffer *F = MemoryBuffer::getMemBuffer(AsmString, AsmString+strlen(AsmString), ""); - Module *Result = RunVMAsmParser(F); + Module *Result = LLParser(F, Err).Run(); delete F; return Result; } @@ -51,40 +52,28 @@ Module *llvm::ParseAssemblyString(const char *AsmString, Module *M, // ParseError Class //===------------------------------------------------------------------------=== - -void ParseError::setError(const std::string &filename, - const std::string &message, - int lineNo, int colNo) { - Filename = filename; - Message = message; - LineNo = lineNo; - colNo = colNo; -} - -ParseError::ParseError(const ParseError &E) - : Filename(E.Filename), Message(E.Message) { - LineNo = E.LineNo; - ColumnNo = E.ColumnNo; -} - -// Includes info from options -const std::string ParseError::getMessage() const { - std::string Result; - char Buffer[10]; - +void ParseError::PrintError(const char *ProgName, raw_ostream &S) { + errs() << ProgName << ": "; if (Filename == "-") - Result += ""; + errs() << ""; else - Result += Filename; - + errs() << Filename; + if (LineNo != -1) { - sprintf(Buffer, "%d", LineNo); - Result += std::string(":") + Buffer; - if (ColumnNo != -1) { - sprintf(Buffer, "%d", ColumnNo); - Result += std::string(",") + Buffer; - } + errs() << ':' << LineNo; + if (ColumnNo != -1) + errs() << ':' << (ColumnNo+1); + } + + errs() << ": " << Message << '\n'; + + if (LineNo != -1 && ColumnNo != -1) { + errs() << LineContents << '\n'; + + // Print out spaces/tabs before the caret. + for (unsigned i = 0; i != unsigned(ColumnNo); ++i) + errs() << (LineContents[i] == '\t' ? '\t' : ' '); + errs() << "^\n"; } - - return Result + ": " + Message; } + diff --git a/lib/AsmParser/ParserInternals.h b/lib/AsmParser/ParserInternals.h deleted file mode 100644 index 8af27c77c33..00000000000 --- a/lib/AsmParser/ParserInternals.h +++ /dev/null @@ -1,260 +0,0 @@ -//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This header file defines the various variables that are shared among the -// different components of the parser... -// -//===----------------------------------------------------------------------===// - -#ifndef PARSER_INTERNALS_H -#define PARSER_INTERNALS_H - -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Attributes.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Assembly/Parser.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/APFloat.h" -#include "llvm/ADT/APSInt.h" -namespace llvm { class MemoryBuffer; } - -// Global variables exported from the lexer... - -extern llvm::ParseError* TheParseError; /// FIXME: Not threading friendly - -// functions exported from the lexer -void InitLLLexer(llvm::MemoryBuffer *MB); -const char *LLLgetTokenStart(); -unsigned LLLgetTokenLength(); -std::string LLLgetFilename(); -unsigned LLLgetLineNo(); -void FreeLexer(); - -namespace llvm { -class Module; - -// RunVMAsmParser - Parse a buffer and return Module -Module *RunVMAsmParser(llvm::MemoryBuffer *MB); - -// GenerateError - Wrapper around the ParseException class that automatically -// fills in file line number and column number and options info. -// -// This also helps me because I keep typing 'throw new ParseException' instead -// of just 'throw ParseException'... sigh... -// -extern void GenerateError(const std::string &message, int LineNo = -1); - -/// InlineAsmDescriptor - This is a simple class that holds info about inline -/// asm blocks, for use by ValID. -struct InlineAsmDescriptor { - std::string AsmString, Constraints; - bool HasSideEffects; - - InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE) - : AsmString(as), Constraints(c), HasSideEffects(HSE) {} -}; - - -// ValID - Represents a reference of a definition of some sort. This may either -// be a numeric reference or a symbolic (%var) reference. This is just a -// discriminated union. -// -// Note that I can't implement this class in a straight forward manner with -// constructors and stuff because it goes in a union. -// -struct ValID { - enum { - LocalID, GlobalID, LocalName, GlobalName, - ConstSIntVal, ConstUIntVal, ConstAPInt, ConstFPVal, ConstNullVal, - ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal - } Type; - - union { - unsigned Num; // If it's a numeric reference like %1234 - std::string *Name; // If it's a named reference. Memory must be deleted. - int64_t ConstPool64; // Constant pool reference. This is the value - uint64_t UConstPool64; // Unsigned constant pool reference. - APSInt *ConstPoolInt; // Large Integer constant pool reference - APFloat *ConstPoolFP; // Floating point constant pool reference - Constant *ConstantValue; // Fully resolved constant for ConstantVal case. - InlineAsmDescriptor *IAD; - }; - - static ValID createLocalID(unsigned Num) { - ValID D; D.Type = LocalID; D.Num = Num; return D; - } - static ValID createGlobalID(unsigned Num) { - ValID D; D.Type = GlobalID; D.Num = Num; return D; - } - static ValID createLocalName(const std::string &Name) { - ValID D; D.Type = LocalName; D.Name = new std::string(Name); return D; - } - static ValID createGlobalName(const std::string &Name) { - ValID D; D.Type = GlobalName; D.Name = new std::string(Name); return D; - } - - static ValID create(int64_t Val) { - ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; return D; - } - - static ValID create(uint64_t Val) { - ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D; - } - - static ValID create(APFloat *Val) { - ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D; - } - - static ValID create(const APInt &Val, bool isSigned) { - ValID D; D.Type = ConstAPInt; - D.ConstPoolInt = new APSInt(Val, !isSigned); - return D; - } - - - static ValID createNull() { - ValID D; D.Type = ConstNullVal; return D; - } - - static ValID createUndef() { - ValID D; D.Type = ConstUndefVal; return D; - } - - static ValID createZeroInit() { - ValID D; D.Type = ConstZeroVal; return D; - } - - static ValID create(Constant *Val) { - ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D; - } - - static ValID createInlineAsm(const std::string &AsmString, - const std::string &Constraints, - bool HasSideEffects) { - ValID D; - D.Type = InlineAsmVal; - D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects); - return D; - } - - inline void destroy() const { - if (Type == LocalName || Type == GlobalName) - delete Name; // Free this strdup'd memory. - else if (Type == InlineAsmVal) - delete IAD; - else if (Type == ConstAPInt) - delete ConstPoolInt; - else if (Type == ConstFPVal) - delete ConstPoolFP; - } - - inline ValID copy() const { - ValID Result = *this; - if (Type == ConstAPInt) - Result.ConstPoolInt = new APSInt(*ConstPoolInt); - - if (Type != LocalName && Type != GlobalName) return Result; - Result.Name = new std::string(*Name); - return Result; - } - - inline std::string getName() const { - switch (Type) { - case LocalID : return '%' + utostr(Num); - case GlobalID : return '@' + utostr(Num); - case LocalName : return *Name; - case GlobalName : return *Name; - case ConstAPInt : return ConstPoolInt->toString(10); - case ConstFPVal : return ftostr(*ConstPoolFP); - case ConstNullVal : return "null"; - case ConstUndefVal : return "undef"; - case ConstZeroVal : return "zeroinitializer"; - case ConstUIntVal : - case ConstSIntVal : return std::string("%") + itostr(ConstPool64); - case ConstantVal: - if (ConstantValue == ConstantInt::getTrue()) return "true"; - if (ConstantValue == ConstantInt::getFalse()) return "false"; - return ""; - default: - assert(0 && "Unknown value!"); - abort(); - return ""; - } - } - - bool operator<(const ValID &V) const { - if (Type != V.Type) return Type < V.Type; - switch (Type) { - case LocalID: - case GlobalID: return Num < V.Num; - case LocalName: - case GlobalName: return *Name < *V.Name; - case ConstSIntVal: return ConstPool64 < V.ConstPool64; - case ConstUIntVal: return UConstPool64 < V.UConstPool64; - case ConstAPInt: return ConstPoolInt->ult(*V.ConstPoolInt); - case ConstFPVal: return ConstPoolFP->compare(*V.ConstPoolFP) == - APFloat::cmpLessThan; - case ConstNullVal: return false; - case ConstUndefVal: return false; - case ConstZeroVal: return false; - case ConstantVal: return ConstantValue < V.ConstantValue; - default: assert(0 && "Unknown value type!"); return false; - } - } - - bool operator==(const ValID &V) const { - if (Type != V.Type) return false; - - switch (Type) { - default: assert(0 && "Unknown value type!"); - case LocalID: - case GlobalID: return Num == V.Num; - case LocalName: - case GlobalName: return *Name == *(V.Name); - case ConstSIntVal: return ConstPool64 == V.ConstPool64; - case ConstUIntVal: return UConstPool64 == V.UConstPool64; - case ConstAPInt: return *ConstPoolInt == *V.ConstPoolInt; - case ConstFPVal: return ConstPoolFP->compare(*V.ConstPoolFP) == - APFloat::cmpEqual; - case ConstantVal: return ConstantValue == V.ConstantValue; - case ConstNullVal: return true; - case ConstUndefVal: return true; - case ConstZeroVal: return true; - } - } -}; - -struct TypeWithAttrs { - llvm::PATypeHolder *Ty; - Attributes Attrs; -}; - -typedef std::vector TypeWithAttrsList; - -struct ArgListEntry { - Attributes Attrs; - llvm::PATypeHolder *Ty; - std::string *Name; -}; - -typedef std::vector ArgListType; - -struct ParamListEntry { - Value *Val; - Attributes Attrs; -}; - -typedef std::vector ParamList; - - -} // End llvm namespace - -#endif diff --git a/lib/AsmParser/llvmAsmParser.cpp.cvs b/lib/AsmParser/llvmAsmParser.cpp.cvs deleted file mode 100644 index 07a73bcf274..00000000000 --- 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 -#include -#include -#include - -// 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 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 Types; - std::map 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 > PlaceHolderInfo; - - // GlobalRefs - This maintains a mapping between '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, 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 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(Ty)) { - // Check to see if this is an unresolved type - std::map::iterator I = LateResolveTypes.begin(); - std::map::iterator E = LateResolveTypes.end(); - for ( ; I != E; ++I) { - if (I->second.get() == OpTy) - return true; - } - } else if (const SequentialType* SeqTy = dyn_cast(Ty)) { - const Type* TheTy = SeqTy->getElementType(); - if (TheTy->isAbstract() && TheTy != Ty) { - std::vector::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(Ty)) { - for (unsigned i = 0; i < StrTy->getNumElements(); ++i) { - const Type* TheTy = StrTy->getElementType(i); - if (TheTy->isAbstract() && TheTy != Ty) { - std::vector::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 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::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(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(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(Ty) && - ConstantInt::isValueValidForType(Ty, D.UConstPool64)) - return ConstantInt::get(Ty, D.UConstPool64); - - if (!isa(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(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(Ty)) { - GenerateError("Cannot create a a non pointer null"); - return 0; - } - return ConstantPointerNull::get(cast(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(Ty); - const FunctionType *FTy = - PTy ? dyn_cast(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(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(Ty); - if (!PTy) { - GenerateError("Invalid type for reference to global" ); - return 0; - } - const Type* ElTy = PTy->getElementType(); - if (const FunctionType *FTy = dyn_cast(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::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::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(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(CurFun.Values[ID.Num]); - else - GenerateError("Reference to label '%" + utostr(ID.Num) + - "' is actually of type '"+ - CurFun.Values[ID.Num]->getType()->getDescription() + "'"); - } - } else { - GenerateError("Illegal label reference " + ID.getName()); - return 0; - } - - // If its already been defined, return it now. - if (BB) { - ID.destroy(); // Free strdup'd memory. - return BB; - } - - // Otherwise, this block has not been seen before, create it. - std::string Name; - if (ID.Type == ValID::LocalName) - Name = ID.getName(); - BB = BasicBlock::Create(Name, CurFun.CurrentFunction); - - // Insert it in the forward refs map. - CurFun.BBForwardRefs[ID] = BB; - - 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(ValueList &LateResolvers, ValueList *FutureLateResolvers) { - // Loop over LateResolveDefs fixing up stuff that couldn't be resolved - while (!LateResolvers.empty()) { - Value *V = LateResolvers.back(); - LateResolvers.pop_back(); - - std::map >::iterator PHI = - CurModule.PlaceHolderInfo.find(V); - assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!"); - - ValID &DID = PHI->second.first; - - Value *TheRealValue = getExistingVal(V->getType(), DID); - if (TriggerError) - return; - 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::LocalName || DID.Type == ValID::GlobalName) { - GenerateError("Reference to an invalid definition: '" +DID.getName()+ - "' of type '" + V->getType()->getDescription() + "'", - PHI->second.second); - return; - } else { - GenerateError("Reference to an invalid definition: #" + - itostr(DID.Num) + " of type '" + - V->getType()->getDescription() + "'", - PHI->second.second); - return; - } - } - } - 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(std::string *Name, const Type *ToTy) { - ValID D; - if (Name) - D = ValID::createLocalName(*Name); - else - D = ValID::createLocalID(CurModule.Types.size()); - - std::map::iterator I = - CurModule.LateResolveTypes.find(D); - if (I != CurModule.LateResolveTypes.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); - I->first.destroy(); - CurModule.LateResolveTypes.erase(I); - } - D.destroy(); -} - -// 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, std::string *NameStr) { - if (!NameStr) return; - std::string Name(*NameStr); // Copy string - delete NameStr; // Free old string - - if (V->getType() == Type::VoidTy) { - GenerateError("Can't assign name '" + Name+"' to value with void type"); - return; - } - - assert(inFunctionScope() && "Must be in function scope!"); - ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable(); - if (ST.lookup(Name)) { - GenerateError("Redefinition of value '" + Name + "' of type '" + - V->getType()->getDescription() + "'"); - return; - } - - // 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(std::string *NameStr, - GlobalValue::LinkageTypes Linkage, - GlobalValue::VisibilityTypes Visibility, - bool isConstantGlobal, const Type *Ty, - Constant *Initializer, bool IsThreadLocal, - unsigned AddressSpace = 0) { - if (isa(Ty)) { - GenerateError("Cannot declare global vars of function type"); - return 0; - } - if (Ty == Type::LabelTy) { - GenerateError("Cannot declare global vars of label type"); - return 0; - } - - const PointerType *PTy = PointerType::get(Ty, AddressSpace); - - std::string Name; - if (NameStr) { - Name = *NameStr; // Copy string - delete NameStr; // Free old string - } - - // See if this global value was forward referenced. If so, recycle the - // object. - ValID ID; - if (!Name.empty()) { - ID = ValID::createGlobalName(Name); - } else { - ID = ValID::createGlobalID(CurModule.Values.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(FWGV); - CurModule.CurrentModule->getGlobalList().remove(GV); - CurModule.CurrentModule->getGlobalList().push_back(GV); - GV->setInitializer(Initializer); - GV->setLinkage(Linkage); - GV->setVisibility(Visibility); - GV->setConstant(isConstantGlobal); - GV->setThreadLocal(IsThreadLocal); - InsertValue(GV, CurModule.Values); - ID.destroy(); - return GV; - } - - ID.destroy(); - - // If this global has a name - if (!Name.empty()) { - // if the global we're parsing has an initializer (is a definition) and - // has external linkage. - if (Initializer && Linkage != GlobalValue::InternalLinkage) - // If there is already a global with external linkage with this name - if (CurModule.CurrentModule->getGlobalVariable(Name, false)) { - // If we allow this GVar to get created, it will be renamed in the - // symbol table because it conflicts with an existing GVar. We can't - // allow redefinition of GVars whose linking indicates that their name - // must stay the same. Issue the error. - GenerateError("Redefinition of global variable named '" + Name + - "' of type '" + Ty->getDescription() + "'"); - return 0; - } - } - - // Otherwise there is no existing GV to use, create one now. - GlobalVariable *GV = - new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, - CurModule.CurrentModule, IsThreadLocal, AddressSpace); - GV->setVisibility(Visibility); - 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, std::string *NameStr) { - assert(!inFunctionScope() && "Can't give types function-local names!"); - if (NameStr == 0) return false; - - std::string Name(*NameStr); // Copy string - delete NameStr; // Free old string - - // We don't allow assigning names to void type - if (T == Type::VoidTy) { - GenerateError("Can't assign name '" + Name + "' to the void type"); - return false; - } - - // 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(Existing)) { - // We ARE replacing an opaque type! - const_cast(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. - GenerateError("Redefinition of type named '" + Name + "' of type '" + - T->getDescription() + "'"); - } - - 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 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 isn't abstract, or if there are no up-references in it, then there is - // nothing to resolve here. - if (!ty->isAbstract() || UpRefs.empty()) 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; -} - -//===----------------------------------------------------------------------===// -// RunVMAsmParser - Define an interface to this parser -//===----------------------------------------------------------------------===// -// -static Module* RunParser(Module * M); - -Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { - InitLLLexer(MB); - Module *M = RunParser(new Module(LLLgetFilename())); - FreeLexer(); - return M; -} - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 986 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" -{ - llvm::Module *ModuleVal; - llvm::Function *FunctionVal; - llvm::BasicBlock *BasicBlockVal; - llvm::TerminatorInst *TermInstVal; - llvm::Instruction *InstVal; - llvm::Constant *ConstVal; - - const llvm::Type *PrimType; - std::list *TypeList; - llvm::PATypeHolder *TypeVal; - llvm::Value *ValueVal; - std::vector *ValueList; - std::vector *ConstantList; - llvm::ArgListType *ArgList; - llvm::TypeWithAttrs TypeWithAttrs; - llvm::TypeWithAttrsList *TypeWithAttrsList; - llvm::ParamList *ParamList; - - // Represent the RHS of PHI node - std::list > *PHIList; - std::vector > *JumpTable; - std::vector *ConstVector; - - llvm::GlobalValue::LinkageTypes Linkage; - llvm::GlobalValue::VisibilityTypes Visibility; - llvm::Attributes Attributes; - llvm::APInt *APIntVal; - int64_t SInt64Val; - uint64_t UInt64Val; - int SIntVal; - unsigned UIntVal; - llvm::APFloat *FPVal; - bool BoolVal; - - std::string *StrVal; // This memory must be deleted - llvm::ValID ValIDVal; - - llvm::Instruction::BinaryOps BinaryOpVal; - llvm::Instruction::TermOps TermOpVal; - llvm::Instruction::MemoryOps MemOpVal; - llvm::Instruction::CastOps CastOpVal; - llvm::Instruction::OtherOps OtherOpVal; - llvm::ICmpInst::Predicate IPredicate; - llvm::FCmpInst::Predicate FPredicate; -} -/* Line 187 of yacc.c. */ -#line 1446 "llvmAsmParser.tab.c" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 216 of yacc.c. */ -#line 1459 "llvmAsmParser.tab.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 44 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 2372 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 176 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 87 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 352 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 712 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 416 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 162, 163, 166, 2, 165, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 171, 164, 172, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 168, 167, 170, 2, 2, 2, 2, 2, 175, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 169, 2, 2, 173, 2, 174, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 11, 13, 15, 17, - 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, - 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, - 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, - 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, - 99, 101, 103, 105, 107, 109, 111, 113, 115, 117, - 118, 123, 124, 127, 128, 131, 133, 135, 137, 138, - 141, 143, 145, 147, 149, 151, 153, 155, 157, 159, - 160, 162, 164, 166, 167, 169, 171, 172, 174, 176, - 178, 180, 181, 183, 185, 186, 188, 190, 192, 194, - 196, 199, 201, 203, 205, 207, 209, 211, 213, 215, - 217, 219, 222, 223, 226, 228, 230, 232, 234, 235, - 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, - 258, 260, 262, 263, 266, 267, 270, 271, 274, 275, - 279, 282, 283, 285, 286, 290, 292, 295, 297, 299, - 301, 303, 305, 307, 309, 311, 313, 317, 319, 322, - 328, 334, 340, 346, 350, 353, 359, 364, 367, 369, - 371, 373, 377, 379, 383, 385, 386, 388, 392, 397, - 401, 405, 410, 415, 419, 426, 432, 435, 438, 441, - 444, 447, 450, 453, 456, 459, 462, 465, 468, 475, - 481, 490, 497, 504, 512, 520, 528, 536, 543, 552, - 561, 567, 575, 579, 581, 583, 585, 587, 588, 591, - 598, 600, 601, 603, 606, 607, 611, 612, 616, 620, - 624, 628, 629, 638, 639, 649, 650, 660, 666, 669, - 673, 675, 679, 683, 687, 691, 693, 694, 700, 704, - 706, 710, 712, 713, 725, 727, 729, 734, 736, 738, - 741, 745, 746, 748, 750, 752, 754, 756, 758, 760, - 762, 764, 766, 768, 772, 776, 779, 782, 786, 789, - 795, 800, 802, 808, 810, 812, 814, 816, 818, 820, - 823, 825, 829, 832, 835, 839, 843, 846, 847, 849, - 852, 855, 859, 869, 879, 888, 904, 906, 908, 915, - 921, 924, 927, 934, 942, 947, 952, 959, 966, 967, - 968, 972, 975, 979, 982, 984, 990, 996, 1003, 1010, - 1017, 1024, 1029, 1036, 1041, 1046, 1053, 1060, 1063, 1073, - 1075, 1077, 1078, 1082, 1089, 1093, 1100, 1103, 1109, 1117, - 1123, 1128, 1133 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 223, 0, -1, 75, -1, 76, -1, 77, -1, 78, - -1, 79, -1, 80, -1, 81, -1, 82, -1, 83, - -1, 87, -1, 88, -1, 89, -1, 84, -1, 85, - -1, 86, -1, 120, -1, 121, -1, 122, -1, 123, - -1, 124, -1, 125, -1, 126, -1, 127, -1, 128, - -1, 129, -1, 130, -1, 131, -1, 94, -1, 95, - -1, 96, -1, 97, -1, 98, -1, 99, -1, 100, - -1, 101, -1, 102, -1, 103, -1, 104, -1, 105, - -1, 106, -1, 107, -1, 108, -1, 109, -1, 110, - -1, 111, -1, 112, -1, 113, -1, 100, -1, 101, - -1, 102, -1, 103, -1, 26, -1, 27, -1, 19, - -1, 22, -1, 24, -1, 182, -1, -1, 55, 162, - 4, 163, -1, -1, 182, 164, -1, -1, 7, 164, - -1, 20, -1, 23, -1, 189, -1, -1, 187, 164, - -1, 42, -1, 44, -1, 43, -1, 45, -1, 47, - -1, 49, -1, 46, -1, 48, -1, 51, -1, -1, - 159, -1, 160, -1, 161, -1, -1, 46, -1, 48, - -1, -1, 42, -1, 43, -1, 44, -1, 47, -1, - -1, 44, -1, 42, -1, -1, 63, -1, 64, -1, - 65, -1, 66, -1, 67, -1, 62, 4, -1, 142, - -1, 121, -1, 141, -1, 122, -1, 144, -1, 145, - -1, 147, -1, 148, -1, 149, -1, 158, -1, 54, - 4, -1, -1, 198, 197, -1, 144, -1, 142, -1, - 141, -1, 147, -1, -1, 200, 199, -1, 143, -1, - 146, -1, 144, -1, 142, -1, 141, -1, 150, -1, - 151, -1, 154, -1, 155, -1, 153, -1, 156, -1, - 157, -1, -1, 202, 201, -1, -1, 152, 22, -1, - -1, 54, 4, -1, -1, 165, 54, 4, -1, 34, - 22, -1, -1, 206, -1, -1, 165, 209, 208, -1, - 206, -1, 54, 4, -1, 11, -1, 12, -1, 13, - -1, 16, -1, 15, -1, 14, -1, 17, -1, 50, - -1, 210, -1, 211, 184, 166, -1, 245, -1, 167, - 4, -1, 211, 162, 215, 163, 202, -1, 10, 162, - 215, 163, 202, -1, 168, 4, 169, 211, 170, -1, - 171, 4, 169, 211, 172, -1, 173, 216, 174, -1, - 173, 174, -1, 171, 173, 216, 174, 172, -1, 171, - 173, 174, 172, -1, 211, 198, -1, 211, -1, 10, - -1, 212, -1, 214, 165, 212, -1, 214, -1, 214, - 165, 39, -1, 39, -1, -1, 211, -1, 216, 165, - 211, -1, 211, 168, 219, 170, -1, 211, 168, 170, - -1, 211, 175, 22, -1, 211, 171, 219, 172, -1, - 211, 173, 219, 174, -1, 211, 173, 174, -1, 211, - 171, 173, 219, 174, 172, -1, 211, 171, 173, 174, - 172, -1, 211, 40, -1, 211, 41, -1, 211, 245, - -1, 211, 218, -1, 211, 25, -1, 211, 3, -1, - 211, 5, -1, 211, 4, -1, 211, 6, -1, 211, - 26, -1, 211, 27, -1, 211, 9, -1, 179, 162, - 217, 38, 211, 163, -1, 119, 162, 217, 257, 163, - -1, 133, 162, 217, 165, 217, 165, 217, 163, -1, - 177, 162, 217, 165, 217, 163, -1, 178, 162, 217, - 165, 217, 163, -1, 90, 180, 162, 217, 165, 217, - 163, -1, 91, 181, 162, 217, 165, 217, 163, -1, - 92, 180, 162, 217, 165, 217, 163, -1, 93, 181, - 162, 217, 165, 217, 163, -1, 135, 162, 217, 165, - 217, 163, -1, 136, 162, 217, 165, 217, 165, 217, - 163, -1, 137, 162, 217, 165, 217, 165, 217, 163, - -1, 139, 162, 217, 258, 163, -1, 140, 162, 217, - 165, 217, 258, 163, -1, 219, 165, 217, -1, 217, - -1, 32, -1, 33, -1, 37, -1, -1, 213, 245, - -1, 125, 162, 222, 38, 211, 163, -1, 224, -1, - -1, 225, -1, 224, 225, -1, -1, 31, 226, 241, - -1, -1, 30, 227, 242, -1, 60, 59, 231, -1, - 185, 18, 211, -1, 185, 18, 10, -1, -1, 188, - 192, 221, 220, 217, 184, 228, 208, -1, -1, 188, - 190, 192, 221, 220, 217, 184, 229, 208, -1, -1, - 188, 191, 192, 221, 220, 211, 184, 230, 208, -1, - 188, 192, 35, 195, 222, -1, 52, 232, -1, 56, - 164, 233, -1, 22, -1, 53, 164, 22, -1, 68, - 164, 22, -1, 168, 234, 170, -1, 234, 165, 22, - -1, 22, -1, -1, 235, 165, 211, 198, 183, -1, - 211, 198, 183, -1, 235, -1, 235, 165, 39, -1, - 39, -1, -1, 196, 200, 213, 187, 162, 236, 163, - 202, 207, 204, 203, -1, 28, -1, 173, -1, 194, - 192, 237, 238, -1, 29, -1, 174, -1, 249, 240, - -1, 193, 192, 237, -1, -1, 61, -1, 3, -1, - 4, -1, 5, -1, 6, -1, 9, -1, 26, -1, - 27, -1, 40, -1, 41, -1, 25, -1, 171, 219, - 172, -1, 168, 219, 170, -1, 168, 170, -1, 175, - 22, -1, 173, 219, 174, -1, 173, 174, -1, 171, - 173, 219, 174, 172, -1, 171, 173, 174, 172, -1, - 218, -1, 59, 243, 22, 165, 22, -1, 7, -1, - 8, -1, 182, -1, 187, -1, 245, -1, 244, -1, - 211, 246, -1, 247, -1, 248, 165, 247, -1, 249, - 250, -1, 239, 250, -1, 251, 185, 252, -1, 251, - 186, 252, -1, 251, 254, -1, -1, 21, -1, 69, - 248, -1, 69, 10, -1, 70, 17, 246, -1, 70, - 11, 246, 165, 17, 246, 165, 17, 246, -1, 71, - 11, 246, 165, 17, 246, 168, 253, 170, -1, 71, - 11, 246, 165, 17, 246, 168, 170, -1, 72, 196, - 200, 213, 246, 162, 256, 163, 202, 38, 17, 246, - 73, 17, 246, -1, 73, -1, 74, -1, 253, 11, - 244, 165, 17, 246, -1, 11, 244, 165, 17, 246, - -1, 185, 260, -1, 186, 260, -1, 211, 168, 246, - 165, 246, 170, -1, 255, 165, 168, 246, 165, 246, - 170, -1, 211, 198, 246, 198, -1, 17, 198, 246, - 198, -1, 256, 165, 211, 198, 246, 198, -1, 256, - 165, 17, 198, 246, 198, -1, -1, -1, 257, 165, - 247, -1, 165, 4, -1, 258, 165, 4, -1, 58, - 57, -1, 57, -1, 177, 211, 246, 165, 246, -1, - 178, 211, 246, 165, 246, -1, 90, 180, 211, 246, - 165, 246, -1, 91, 181, 211, 246, 165, 246, -1, - 92, 180, 211, 246, 165, 246, -1, 93, 181, 211, - 246, 165, 246, -1, 179, 247, 38, 211, -1, 133, - 247, 165, 247, 165, 247, -1, 134, 247, 165, 211, - -1, 135, 247, 165, 247, -1, 136, 247, 165, 247, - 165, 247, -1, 137, 247, 165, 247, 165, 247, -1, - 132, 255, -1, 259, 196, 200, 213, 246, 162, 256, - 163, 202, -1, 262, -1, 36, -1, -1, 114, 211, - 205, -1, 114, 211, 165, 11, 246, 205, -1, 115, - 211, 205, -1, 115, 211, 165, 11, 246, 205, -1, - 116, 247, -1, 261, 117, 211, 246, 205, -1, 261, - 118, 247, 165, 211, 246, 205, -1, 138, 211, 246, - 165, 4, -1, 119, 211, 246, 257, -1, 139, 211, - 246, 258, -1, 140, 211, 246, 165, 211, 246, 258, - -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, - 1152, 1153, 1153, 1153, 1153, 1153, 1153, 1154, 1154, 1154, - 1154, 1154, 1154, 1155, 1155, 1155, 1155, 1155, 1155, 1158, - 1158, 1159, 1159, 1160, 1160, 1161, 1161, 1162, 1162, 1166, - 1166, 1167, 1167, 1168, 1168, 1169, 1169, 1170, 1170, 1171, - 1171, 1172, 1172, 1173, 1174, 1177, 1177, 1177, 1178, 1178, - 1180, 1181, 1185, 1189, 1194, 1200, 1200, 1202, 1203, 1208, - 1214, 1215, 1216, 1217, 1218, 1219, 1223, 1224, 1225, 1229, - 1230, 1231, 1232, 1236, 1237, 1238, 1242, 1243, 1244, 1245, - 1246, 1250, 1251, 1252, 1255, 1256, 1257, 1258, 1259, 1260, - 1261, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, - 1277, 1278, 1282, 1283, 1288, 1289, 1290, 1291, 1294, 1295, - 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, - 1311, 1312, 1315, 1316, 1322, 1323, 1330, 1331, 1339, 1340, - 1351, 1359, 1360, 1365, 1366, 1367, 1372, 1387, 1387, 1387, - 1387, 1387, 1387, 1387, 1390, 1394, 1398, 1405, 1410, 1418, - 1453, 1484, 1489, 1499, 1509, 1513, 1523, 1530, 1539, 1546, - 1551, 1556, 1563, 1564, 1571, 1578, 1586, 1592, 1604, 1632, - 1648, 1675, 1703, 1729, 1749, 1775, 1795, 1807, 1814, 1880, - 1890, 1900, 1911, 1924, 1935, 1949, 1956, 1963, 1981, 1993, - 2014, 2022, 2028, 2039, 2044, 2049, 2054, 2059, 2065, 2071, - 2077, 2085, 2096, 2100, 2108, 2108, 2111, 2111, 2114, 2126, - 2147, 2152, 2160, 2161, 2165, 2165, 2169, 2169, 2172, 2175, - 2199, 2211, 2210, 2222, 2221, 2231, 2230, 2241, 2281, 2284, - 2290, 2300, 2304, 2309, 2311, 2316, 2321, 2330, 2340, 2351, - 2355, 2364, 2373, 2378, 2527, 2527, 2529, 2538, 2538, 2540, - 2545, 2557, 2561, 2566, 2570, 2574, 2579, 2584, 2588, 2592, - 2596, 2600, 2604, 2608, 2630, 2652, 2658, 2671, 2683, 2688, - 2700, 2706, 2710, 2720, 2724, 2728, 2733, 2740, 2740, 2746, - 2755, 2760, 2765, 2769, 2778, 2787, 2800, 2809, 2813, 2821, - 2841, 2845, 2850, 2861, 2880, 2889, 2993, 2997, 3004, 3015, - 3028, 3037, 3050, 3061, 3071, 3082, 3090, 3100, 3107, 3110, - 3111, 3119, 3125, 3134, 3138, 3143, 3159, 3176, 3188, 3200, - 3214, 3228, 3240, 3261, 3268, 3274, 3280, 3286, 3301, 3411, - 3416, 3420, 3427, 3434, 3444, 3451, 3461, 3469, 3483, 3500, - 3514, 3529, 3544 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "ESINT64VAL", "EUINT64VAL", "ESAPINTVAL", - "EUAPINTVAL", "LOCALVAL_ID", "GLOBALVAL_ID", "FPVAL", "VOID", "INTTYPE", - "FLOAT", "DOUBLE", "X86_FP80", "FP128", "PPC_FP128", "LABEL", "TYPE", - "LOCALVAR", "GLOBALVAR", "LABELSTR", "STRINGCONSTANT", - "ATSTRINGCONSTANT", "PCTSTRINGCONSTANT", "ZEROINITIALIZER", "TRUETOK", - "FALSETOK", "BEGINTOK", "ENDTOK", "DECLARE", "DEFINE", "GLOBAL", - "CONSTANT", "SECTION", "ALIAS", "VOLATILE", "THREAD_LOCAL", "TO", - "DOTDOTDOT", "NULL_TOK", "UNDEF", "INTERNAL", "LINKONCE", "WEAK", - "APPENDING", "DLLIMPORT", "DLLEXPORT", "EXTERN_WEAK", "COMMON", "OPAQUE", - "EXTERNAL", "TARGET", "TRIPLE", "ALIGN", "ADDRSPACE", "DEPLIBS", "CALL", - "TAIL", "ASM_TOK", "MODULE", "SIDEEFFECT", "CC_TOK", "CCC_TOK", - "FASTCC_TOK", "COLDCC_TOK", "X86_STDCALLCC_TOK", "X86_FASTCALLCC_TOK", - "DATALAYOUT", "RET", "BR", "SWITCH", "INVOKE", "UNWIND", "UNREACHABLE", - "ADD", "SUB", "MUL", "UDIV", "SDIV", "FDIV", "UREM", "SREM", "FREM", - "AND", "OR", "XOR", "SHL", "LSHR", "ASHR", "ICMP", "FCMP", "VICMP", - "VFCMP", "EQ", "NE", "SLT", "SGT", "SLE", "SGE", "ULT", "UGT", "ULE", - "UGE", "OEQ", "ONE", "OLT", "OGT", "OLE", "OGE", "ORD", "UNO", "UEQ", - "UNE", "MALLOC", "ALLOCA", "FREE", "LOAD", "STORE", "GETELEMENTPTR", - "TRUNC", "ZEXT", "SEXT", "FPTRUNC", "FPEXT", "BITCAST", "UITOFP", - "SITOFP", "FPTOUI", "FPTOSI", "INTTOPTR", "PTRTOINT", "PHI_TOK", - "SELECT", "VAARG", "EXTRACTELEMENT", "INSERTELEMENT", "SHUFFLEVECTOR", - "GETRESULT", "EXTRACTVALUE", "INSERTVALUE", "SIGNEXT", "ZEROEXT", - "NORETURN", "INREG", "SRET", "NOUNWIND", "NOALIAS", "NOCAPTURE", "BYVAL", - "READNONE", "READONLY", "GC", "OPTSIZE", "NOINLINE", "ALWAYSINLINE", - "SSP", "SSPREQ", "NEST", "DEFAULT", "HIDDEN", "PROTECTED", "'('", "')'", - "'='", "','", "'*'", "'\\\\'", "'['", "'x'", "']'", "'<'", "'>'", "'{'", - "'}'", "'c'", "$accept", "ArithmeticOps", "LogicalOps", "CastOps", - "IPredicates", "FPredicates", "LocalName", "OptLocalName", - "OptAddrSpace", "OptLocalAssign", "LocalNumber", "GlobalName", - "OptGlobalAssign", "GlobalAssign", "GVInternalLinkage", - "GVExternalLinkage", "GVVisibilityStyle", "FunctionDeclareLinkage", - "FunctionDefineLinkage", "AliasLinkage", "OptCallingConv", "Attribute", - "OptAttributes", "RetAttr", "OptRetAttrs", "FuncAttr", "OptFuncAttrs", - "OptGC", "OptAlign", "OptCAlign", "SectionString", "OptSection", - "GlobalVarAttributes", "GlobalVarAttribute", "PrimType", "Types", - "ArgType", "ResultTypes", "ArgTypeList", "ArgTypeListI", "TypeListI", - "ConstVal", "ConstExpr", "ConstVector", "GlobalType", "ThreadLocal", - "AliaseeRef", "Module", "DefinitionList", "Definition", "@1", "@2", "@3", - "@4", "@5", "AsmBlock", "TargetDefinition", "LibrariesDefinition", - "LibList", "ArgListH", "ArgList", "FunctionHeaderH", "BEGIN", - "FunctionHeader", "END", "Function", "FunctionProto", "OptSideEffect", - "ConstValueRef", "SymbolicValueRef", "ValueRef", "ResolvedVal", - "ReturnedVal", "BasicBlockList", "BasicBlock", "InstructionList", - "BBTerminatorInst", "JumpTable", "Inst", "PHIList", "ParamList", - "IndexList", "ConstantIndexList", "OptTailCall", "InstVal", - "OptVolatile", "MemoryInst", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 40, 41, 61, 44, 42, 92, 91, 120, - 93, 60, 62, 123, 125, 99 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 176, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 178, 178, 178, 178, 178, 178, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, - 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 182, 182, 182, 183, 183, - 184, 184, 185, 185, 186, 187, 187, 188, 188, 189, - 190, 190, 190, 190, 190, 190, 191, 191, 191, 192, - 192, 192, 192, 193, 193, 193, 194, 194, 194, 194, - 194, 195, 195, 195, 196, 196, 196, 196, 196, 196, - 196, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 198, 198, 199, 199, 199, 199, 200, 200, - 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, - 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, - 206, 207, 207, 208, 208, 209, 209, 210, 210, 210, - 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, - 211, 211, 211, 211, 211, 211, 211, 212, 213, 213, - 214, 214, 215, 215, 215, 215, 216, 216, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 218, 218, - 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, - 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, - 223, 223, 224, 224, 226, 225, 227, 225, 225, 225, - 225, 228, 225, 229, 225, 230, 225, 225, 225, 225, - 231, 232, 232, 233, 234, 234, 234, 235, 235, 236, - 236, 236, 236, 237, 238, 238, 239, 240, 240, 241, - 242, 243, 243, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, - 244, 244, 244, 245, 245, 245, 245, 246, 246, 247, - 248, 248, 249, 249, 250, 250, 251, 251, 251, 252, - 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, - 254, 254, 255, 255, 256, 256, 256, 256, 256, 257, - 257, 258, 258, 259, 259, 260, 260, 260, 260, 260, - 260, 260, 260, 260, 260, 260, 260, 260, 260, 260, - 261, 261, 262, 262, 262, 262, 262, 262, 262, 262, - 262, 262, 262 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 4, 0, 2, 0, 2, 1, 1, 1, 0, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, - 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 0, 2, 1, 1, 1, 1, 0, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 2, 0, 2, 0, 2, 0, 3, - 2, 0, 1, 0, 3, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 1, 2, 5, - 5, 5, 5, 3, 2, 5, 4, 2, 1, 1, - 1, 3, 1, 3, 1, 0, 1, 3, 4, 3, - 3, 4, 4, 3, 6, 5, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 6, 5, - 8, 6, 6, 7, 7, 7, 7, 6, 8, 8, - 5, 7, 3, 1, 1, 1, 1, 0, 2, 6, - 1, 0, 1, 2, 0, 3, 0, 3, 3, 3, - 3, 0, 8, 0, 9, 0, 9, 5, 2, 3, - 1, 3, 3, 3, 3, 1, 0, 5, 3, 1, - 3, 1, 0, 11, 1, 1, 4, 1, 1, 2, - 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 3, 2, 2, 3, 2, 5, - 4, 1, 5, 1, 1, 1, 1, 1, 1, 2, - 1, 3, 2, 2, 3, 3, 2, 0, 1, 2, - 2, 3, 9, 9, 8, 15, 1, 1, 6, 5, - 2, 2, 6, 7, 4, 4, 6, 6, 0, 0, - 3, 2, 3, 2, 1, 5, 5, 6, 6, 6, - 6, 4, 6, 4, 4, 6, 6, 2, 9, 1, - 1, 0, 3, 6, 3, 6, 2, 5, 7, 5, - 4, 4, 7 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 68, 55, 65, 56, 66, 57, 226, 224, 0, 0, - 0, 0, 0, 0, 79, 67, 0, 68, 222, 83, - 86, 0, 0, 238, 0, 0, 62, 0, 69, 70, - 72, 71, 73, 76, 74, 77, 75, 78, 80, 81, - 82, 79, 79, 217, 1, 223, 84, 85, 79, 227, - 87, 88, 89, 90, 79, 297, 225, 297, 0, 0, - 246, 239, 240, 228, 283, 284, 230, 147, 148, 149, - 152, 151, 150, 153, 154, 0, 0, 0, 0, 285, - 286, 155, 229, 157, 217, 217, 91, 216, 0, 94, - 94, 298, 293, 63, 257, 258, 259, 292, 241, 242, - 245, 0, 175, 158, 0, 0, 0, 0, 164, 176, - 0, 0, 175, 0, 0, 0, 93, 92, 0, 214, - 215, 0, 0, 95, 96, 97, 98, 99, 118, 260, - 0, 0, 341, 341, 296, 0, 243, 174, 112, 170, - 172, 0, 0, 0, 0, 0, 0, 163, 0, 0, - 156, 0, 0, 169, 0, 168, 0, 237, 61, 61, - 100, 0, 254, 255, 256, 64, 340, 324, 0, 0, - 0, 0, 94, 306, 307, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 14, 15, 16, 11, 12, 13, - 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 294, 94, 310, 0, 339, 295, 311, 244, - 167, 0, 132, 61, 61, 166, 0, 177, 0, 132, - 61, 61, 0, 218, 191, 193, 192, 194, 197, 190, - 195, 196, 186, 187, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 189, 188, 231, 116, 115, 114, 117, 119, - 0, 323, 300, 61, 290, 299, 0, 0, 0, 118, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 0, 53, 54, 49, 50, 51, 52, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, - 138, 138, 346, 61, 61, 337, 0, 0, 0, 0, - 0, 61, 61, 61, 61, 61, 0, 118, 0, 0, - 0, 102, 104, 103, 101, 105, 106, 107, 108, 109, - 110, 113, 173, 171, 160, 161, 162, 165, 60, 159, - 233, 235, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 179, 213, 0, 0, 0, 183, - 0, 180, 0, 0, 0, 143, 0, 263, 264, 265, - 266, 267, 272, 268, 269, 270, 271, 261, 0, 0, - 0, 0, 281, 288, 287, 289, 0, 0, 301, 0, - 0, 61, 61, 61, 61, 0, 342, 0, 344, 319, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 61, 0, 111, 124, 123, 120, - 122, 121, 125, 126, 129, 127, 128, 130, 131, 133, - 143, 143, 0, 0, 0, 0, 0, 319, 0, 0, - 0, 0, 0, 0, 0, 178, 164, 176, 0, 181, - 182, 0, 0, 0, 0, 232, 252, 262, 0, 275, - 0, 0, 0, 278, 0, 276, 291, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 350, 0, 0, - 0, 333, 334, 0, 0, 0, 0, 351, 0, 0, - 0, 331, 0, 138, 0, 234, 236, 61, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, - 185, 0, 0, 0, 0, 0, 0, 145, 143, 251, - 112, 249, 0, 0, 274, 164, 0, 273, 277, 0, - 0, 0, 0, 0, 0, 0, 138, 139, 138, 0, - 0, 0, 0, 0, 0, 349, 321, 0, 61, 325, - 326, 0, 0, 347, 61, 219, 0, 0, 0, 0, - 199, 0, 0, 0, 0, 210, 0, 184, 0, 0, - 61, 140, 146, 144, 59, 0, 132, 0, 280, 0, - 0, 0, 318, 327, 328, 329, 330, 343, 345, 320, - 0, 0, 332, 335, 336, 322, 0, 318, 138, 0, - 0, 0, 0, 0, 207, 0, 0, 0, 201, 202, - 198, 58, 248, 250, 112, 141, 282, 279, 0, 0, - 112, 112, 0, 312, 0, 352, 0, 348, 203, 204, - 205, 206, 0, 0, 0, 211, 59, 142, 136, 0, - 0, 304, 0, 0, 0, 132, 0, 313, 132, 200, - 208, 209, 247, 0, 134, 302, 0, 0, 303, 102, - 104, 112, 112, 0, 112, 112, 338, 137, 0, 253, - 0, 0, 315, 314, 0, 0, 0, 135, 0, 0, - 0, 112, 112, 309, 0, 0, 317, 316, 308, 0, - 0, 305 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 269, 270, 271, 300, 317, 79, 632, 113, 12, - 133, 80, 14, 15, 41, 42, 43, 48, 54, 118, - 128, 351, 230, 279, 161, 449, 354, 689, 674, 416, - 537, 658, 475, 538, 81, 158, 139, 156, 140, 141, - 110, 375, 402, 376, 121, 88, 157, 16, 17, 18, - 20, 19, 385, 450, 451, 63, 23, 61, 101, 541, - 542, 129, 164, 55, 96, 56, 49, 478, 403, 83, - 405, 284, 285, 57, 92, 93, 222, 662, 134, 325, - 642, 497, 507, 223, 224, 225, 226 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -611 -static const yytype_int16 yypact[] = -{ - 828, -611, -611, -611, -611, -611, -611, -611, -5, -90, - 68, -25, 113, -20, -9, -611, 153, 1107, -611, 173, - 15, 36, 48, -611, -3, 196, -611, 1950, -611, -611, - -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, - -611, 137, 137, 190, -611, -611, -611, -611, 137, -611, - -611, -611, -611, -611, 137, 203, -611, 3, 212, 215, - 229, -611, -611, -611, -611, -611, 83, -611, -611, -611, - -611, -611, -611, -611, -611, 252, 268, 7, 87, -611, - -611, -611, 73, -611, 238, 238, 186, -611, 22, 200, - 200, -611, -611, 42, -611, -611, -611, -611, -611, -611, - -611, 8, 1765, -611, 110, 121, 573, 83, -611, 73, - -114, 138, 1765, 142, 22, 22, -611, -611, 1368, -611, - -611, 1991, 298, -611, -611, -611, -611, -611, -611, -611, - -16, 168, 2181, 2181, -611, 311, -611, -611, 73, -611, - 169, 174, 1991, 1991, 164, -95, 1991, -611, 334, 178, - -611, 1991, 1991, 83, 182, 73, 287, -611, 1319, 293, - -611, 1680, -611, -611, -611, -611, -611, -611, 295, 2032, - 119, 339, 200, -611, -611, -611, -611, -611, -611, -611, - -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, - 465, 412, 465, 412, 1991, 1991, 1991, 1991, -611, -611, - -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, - 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, 1991, - 1991, 1991, -611, 200, -611, -33, -611, -611, -611, -611, - 271, 1818, -611, -8, -39, -611, 181, 73, 191, -611, - 293, -2, 1368, -611, -611, -611, -611, -611, -611, -611, - -611, -611, -611, -611, 465, 412, 465, 412, 193, 195, - 199, 201, 202, 205, 206, 1721, 2061, 659, 336, 210, - 211, 213, -611, -611, -611, -611, -611, -611, -611, -611, - 187, -611, 83, 973, -611, 197, 1492, 1492, 1492, -611, - -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, - 1991, -611, -611, -611, -611, -611, -611, -611, -611, -611, - -611, -611, -611, -611, -611, -611, -611, 1991, 1991, 1991, - 1, 17, -611, 973, -30, 214, 216, 218, 220, 221, - 224, 973, 973, 973, 973, 973, 322, -611, 1991, 1991, - 361, -611, -611, -611, -611, -611, -611, -611, -611, -611, - -611, -611, -611, -611, 657, -611, -611, -611, -611, 657, - -611, 142, 338, 226, 228, 232, 233, 1991, 1991, 1991, - 1991, 1991, 1991, 1991, -611, -611, 41, 743, 32, -611, - -83, -611, 1991, 1991, 1991, 236, 240, -611, -611, -611, - -611, -611, -611, -611, -611, -611, -611, 313, 1859, 2117, - 1023, 355, -611, -611, -611, -611, 1991, 243, -611, 245, - 1680, 973, 973, 973, 973, 33, -611, 35, -611, -611, - 1492, 235, 1991, 1991, 1991, 1991, 1991, 256, 257, 258, - 265, 267, 1991, 1680, 973, 269, -611, -611, -611, -611, - -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, - 236, 236, 1991, 1991, 1991, 1991, 1991, -611, 270, 272, - 275, 276, 257, 284, 1991, -611, 219, 1146, -69, -611, - -611, 286, 288, 340, 11, -611, 1891, -611, 383, -611, - 44, 1195, 43, -611, -53, -611, -611, 400, 416, 1492, - 289, 291, 296, 297, 1492, 432, 1492, 301, 306, 1492, - 307, 73, -611, 308, 309, 448, 456, 312, 1991, 1492, - 1492, 73, 1492, 314, 1991, -611, -611, -14, 315, 316, - 319, 320, 78, 1991, 1991, 1991, 1991, 94, 1991, -611, - -611, 304, 1991, 1991, 1991, 441, 474, -611, 236, -611, - 73, 321, 324, 329, -611, 325, -52, -611, -611, 1492, - 1492, 345, 1492, 1492, 1492, 1492, 314, -611, 314, 1991, - 1492, 331, 1991, 1991, 1991, -611, -611, 494, 973, -611, - -611, 365, 447, -611, 973, -611, 1991, 1991, 1991, 1991, - -611, 367, 371, 370, 375, -611, 257, -611, 378, 379, - 126, -611, -611, -611, 198, 1932, -611, 521, -611, 372, - 380, 381, 2158, -611, -611, -611, -611, -611, -611, -611, - 377, 1492, -611, -611, -611, -611, 257, 2158, 314, 385, - 387, 388, 389, 1991, -611, 1991, 1991, 122, -611, -611, - -611, -611, -611, -611, 73, 127, -611, -611, 536, 2, - 74, 73, 136, -611, 401, 312, 140, -611, -611, -611, - -611, -611, 407, 409, 410, -611, 198, -611, 523, 1492, - 1630, -611, 4, 816, 816, -611, 2199, -611, -611, -611, - -611, -611, -611, 571, 430, -611, 437, 1630, -611, 442, - 443, -611, -611, 349, 74, 73, 657, -611, 584, -611, - 592, 449, 271, 271, 595, 816, 816, -611, 1492, 599, - 1492, -611, -611, -611, 1492, 544, 271, 271, -611, 601, - 1492, -611 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -611, 183, 185, 189, -166, -110, 0, -36, -116, 528, - -611, 6, -611, -611, -611, -611, 27, -611, -611, -611, - -145, -611, -526, -611, -260, -611, -237, -611, -611, -314, - -13, -611, -420, -611, -611, -26, 393, -157, -611, 514, - 522, 75, -153, -258, 209, 246, 390, -611, -611, 610, - -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, - -611, 539, -611, -611, -611, -611, -611, -611, -610, -85, - 223, -193, -611, -611, 574, -611, 497, -611, -611, -611, - 16, 184, -452, -611, 505, -611, -611 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -222 -static const yytype_int16 yytable[] = -{ - 11, 82, 359, 322, 280, 272, 13, 418, 378, 380, - 527, 105, 162, 660, 594, 677, 111, 11, 326, 327, - 328, 329, 330, 13, 91, 111, 318, 289, 336, 410, - 515, 516, 94, 29, 30, 31, 32, 33, 34, 35, - 36, 111, 37, 274, 494, 535, 496, 111, 21, 131, - 676, 146, 109, 111, 119, 120, 111, 50, 51, 52, - 147, 1, 53, 22, 3, 536, 5, 691, 84, 85, - 146, 243, 111, 273, 24, 89, 138, 433, 337, 236, - 109, 90, 464, 319, 338, 339, 138, 495, 363, 495, - 365, 470, 155, 11, 64, 65, 464, 107, 67, 68, - 69, 70, 71, 72, 73, 531, 1, 2, 656, 3, - 4, 5, 464, 464, 663, 664, 233, 234, 593, 468, - 237, 548, 599, 112, 360, 361, 241, 25, 111, -153, - 286, 27, 112, 356, 627, 155, 287, 74, 420, 26, - 480, 482, 484, 283, 28, 364, 435, 366, 112, 575, - 38, 39, 40, 44, 112, 692, 693, 163, 695, 696, - 112, 535, 355, 112, 645, 60, 415, -61, 320, 321, - 283, 323, 661, 135, 678, 706, 707, 95, 136, 112, - 106, 111, 417, -61, 324, 283, 283, 283, 283, 283, - 331, 332, 333, 334, 335, 283, 159, 464, 404, 573, - 58, 404, 404, 404, 469, 138, 464, 2, 464, 464, - 4, 465, 59, 486, 544, 547, 155, 1, 62, 46, - 3, 47, 5, 546, 91, 86, 240, 87, 116, 500, - 117, 502, 503, 504, 98, 112, -153, 99, 404, -61, - -153, 580, 607, 559, 608, 102, 404, 404, 404, 404, - 404, 100, 340, 489, 75, 76, 103, 585, 77, 567, - 78, 108, 122, 123, 124, 125, 126, 127, 437, 438, - 439, 440, 104, 441, 411, 87, 512, 442, 443, 142, - 444, 445, 446, 447, 448, 655, 386, 567, 112, 630, - 143, 412, 413, 414, 64, 65, 38, 39, 40, 665, - 148, 666, 160, 668, 647, 666, 1, 2, 150, 3, - 4, 5, 434, 283, 272, 219, 219, 220, 220, 341, - 342, 221, 221, 151, 152, 340, 404, 404, 404, 404, - 114, 115, 165, 229, 231, 404, 235, 232, 238, 343, - 344, 239, 345, 346, 242, 347, 348, 349, 111, 404, - 288, 467, 281, 357, 358, 367, 350, 368, 381, 635, - 432, 369, 406, 370, 371, 436, 609, 372, 373, 612, - 613, 614, 382, 383, 477, 384, 452, 485, 534, 421, - 283, 422, 273, 423, 155, 424, 425, 694, 453, 426, - 454, 530, 341, 342, 455, 456, 283, 501, 283, 283, - 283, 474, 476, 499, 404, 543, 511, 155, 487, 404, - 488, 404, 343, 344, 404, 345, 346, 549, 347, 348, - 349, 505, 506, 508, 404, 404, 517, 404, 683, 350, - 509, 686, 510, 550, 514, 523, 557, 524, 301, 302, - 525, 526, 457, 458, 459, 460, 461, 462, 463, 528, - 540, 532, 565, 533, 552, 467, 553, 471, 472, 473, - 566, 554, 555, 591, 404, 404, 559, 404, 404, 404, - 404, 560, 562, 563, 564, 404, 587, 567, 592, 572, - 576, 577, 568, 404, 578, 579, 595, 596, 574, 404, - 437, 438, 439, 440, 597, 441, 611, 598, 615, 442, - 443, 495, 444, 445, 446, 447, 448, 602, 590, 407, - 408, 409, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, 404, 617, 518, 519, - 520, 521, 623, 283, 624, 625, 283, 283, 283, 529, - 626, 628, 629, 636, 637, 638, 419, 643, 648, 639, - 649, 650, 651, 659, 427, 428, 429, 430, 431, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 634, - 669, 667, 670, 671, 404, 687, 641, 673, 404, 404, - 64, 65, 688, 107, 67, 68, 69, 70, 71, 72, - 73, 641, 1, 2, 631, 3, 4, 5, 581, 582, - 583, 584, 690, 586, -18, -19, 697, 588, 589, 698, - 404, 404, 700, 404, 699, 404, 704, 709, 710, 404, - 672, 132, 657, 74, 353, 404, 149, 45, 145, 130, - 227, 97, 362, 646, 490, 491, 492, 493, 228, 0, - 685, 522, 0, 498, 0, 0, 0, 0, 0, 0, - 0, 619, 620, 621, 622, 0, 631, 513, 0, 0, - 0, 0, 0, 0, 0, 0, 64, 65, 0, 107, - 67, 68, 69, 70, 71, 72, 73, 0, 1, 2, - 0, 3, 4, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 652, 0, - 653, 654, 0, 0, 0, 0, 0, 0, 0, 74, - 0, 0, 551, 0, 0, 0, 0, 556, 0, 558, - 0, 0, 561, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 569, 570, 0, 571, 0, 0, 0, 0, - 75, 76, 0, 0, 77, 0, 78, 144, 0, 0, - 64, 65, 0, 107, 67, 68, 69, 70, 71, 72, - 73, 0, 1, 2, 0, 3, 4, 5, 0, 0, - 0, 0, 600, 601, 0, 603, 604, 605, 606, 0, - 0, 0, 0, 610, 0, 0, 0, 0, 0, 0, - 0, 616, 0, 74, 0, 0, 0, 618, 437, 438, - 439, 440, 0, 441, 0, 0, 0, 442, 443, 0, - 444, 445, 446, 447, 448, 0, 0, 0, 0, 387, - 388, 389, 390, 64, 65, 391, 75, 76, -221, 0, - 77, 0, 78, 379, 644, 1, 2, 0, 3, 4, - 5, 392, 393, 394, 0, 0, -63, 1, 2, 0, - 3, 4, 5, 0, 0, 0, 395, 396, 6, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 340, 0, 0, 0, 0, 397, 0, 0, 0, 0, - 8, 0, 675, 0, 9, 0, 681, 682, 10, 0, - 0, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 254, 255, 256, 257, - 75, 76, 0, 0, 77, 0, 78, 466, 701, 702, - 0, 703, 0, 705, 0, 0, 0, 708, 0, 0, - 0, 0, 0, 711, 0, 258, 198, 679, 680, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 0, 259, - 0, 260, 261, 262, 0, 263, 264, 343, 344, 0, - 345, 346, 0, 347, 348, 349, 0, 0, 0, 0, - 0, 0, 0, 0, 350, 0, 387, 388, 389, 390, - 64, 65, 391, 0, 398, 0, 0, 399, 0, 400, - 0, 401, 1, 2, 0, 3, 4, 5, 392, 393, - 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 395, 396, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 111, 0, - 64, 65, 397, 107, 67, 68, 69, 70, 71, 72, - 73, 0, 1, 2, 0, 3, 4, 5, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 254, 255, 256, 257, 0, 0, 0, - 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 258, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 0, 259, -220, 260, 261, - 262, 0, 263, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -63, 1, 2, 0, 3, - 4, 5, 0, 0, 0, 112, 0, 6, 7, 0, - 0, 398, 0, 0, 399, 0, 400, 0, 401, 244, - 245, 246, 247, 64, 65, 248, 0, 0, 0, 8, - 0, 0, 0, 9, 0, 1, 2, 10, 3, 4, - 5, 249, 250, 251, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 252, 253, 0, 0, - 75, 76, 0, 0, 77, 0, 78, 483, 0, 0, - 0, 111, 64, 65, 0, 107, 67, 68, 69, 70, - 71, 72, 73, 0, 1, 2, 0, 3, 4, 5, - 0, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 254, 255, 256, 257, - 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 258, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 0, 259, - 0, 260, 261, 262, 0, 263, 264, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, - 0, 0, -61, 0, 265, 0, 0, 266, 0, 267, - 0, 268, 244, 245, 246, 247, 64, 65, 248, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, - 0, 3, 4, 5, 249, 250, 251, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, - 253, 0, 75, 76, 0, 0, 77, 0, 78, 545, - 0, 0, 0, 0, 111, 64, 65, 0, 153, 67, - 68, 69, 70, 71, 72, 73, 0, 1, 2, 0, - 3, 4, 5, 0, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 254, - 255, 256, 257, 0, 0, 0, 0, 0, 74, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 258, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 0, 259, 0, 260, 261, 262, 0, 263, 264, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 112, 0, 0, 0, 0, 0, 265, 0, 0, - 266, 0, 267, 154, 268, 387, 388, 389, 390, 64, - 65, 391, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 0, 3, 4, 5, 392, 393, 394, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 395, 396, 0, 75, 76, 0, 0, 77, - 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 397, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 254, 255, 256, 257, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 258, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 0, 259, 0, 260, 261, 262, - 0, 263, 264, 387, 388, 389, 390, 0, 0, 391, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 392, 393, 394, 0, 0, - 398, 0, 0, 399, 0, 400, 0, 401, 0, 0, - 395, 396, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64, 65, 397, - 153, 67, 68, 69, 70, 71, 72, 73, 0, 1, - 2, 0, 3, 4, 5, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 254, 255, 256, 257, 0, 0, 0, 0, 64, 65, - 74, 107, 67, 68, 69, 70, 71, 72, 73, 0, - 1, 2, 0, 3, 4, 5, 0, 0, 0, 258, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 0, 259, 0, 260, 261, 262, 0, 263, - 264, 74, 64, 65, 0, 107, 67, 68, 69, 70, - 71, 72, 73, 0, 1, 2, 0, 3, 4, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, - 0, 399, 0, 400, 137, 401, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, - 0, 275, 276, 0, 277, 64, 65, 278, 107, 67, - 68, 69, 70, 71, 72, 73, 0, 1, 2, 0, - 3, 4, 5, 0, 0, 0, 0, 75, 76, 0, - 0, 77, 0, 78, 0, 0, 0, 352, 0, 0, - 0, 0, 0, 0, 0, 0, 64, 65, 74, 107, - 67, 68, 69, 70, 71, 72, 73, 0, 1, 2, - 0, 3, 4, 5, 0, 0, 0, 0, 75, 76, - 0, 374, 77, 0, 78, 0, 0, 0, 64, 65, - 0, 107, 67, 68, 69, 70, 71, 72, 73, 74, - 1, 2, 0, 3, 4, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 539, 0, 75, 76, 0, 0, 77, 0, 78, 64, - 65, 74, 107, 67, 68, 69, 70, 71, 72, 73, - 0, 1, 2, 0, 3, 4, 5, 64, 65, 0, - 66, 67, 68, 69, 70, 71, 72, 73, 0, 1, - 2, 633, 3, 4, 5, 0, 0, 0, 0, 0, - 0, 0, 74, 0, 0, 75, 76, 0, 0, 77, - 0, 78, 0, 0, 0, 0, 0, 0, 64, 65, - 74, 107, 67, 68, 69, 70, 71, 72, 73, 0, - 1, 2, 0, 3, 4, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 76, 0, 479, - 77, 0, 78, 0, 0, 0, 0, 0, 0, 64, - 65, 74, 282, 67, 68, 69, 70, 71, 72, 73, - 0, 1, 2, 0, 3, 4, 5, 0, 75, 76, - 0, 0, 77, 0, 78, 0, 0, 0, 64, 65, - 0, 107, 67, 68, 69, 70, 71, 72, 73, 0, - 1, 2, 74, 3, 4, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, - 76, 0, 0, 77, 0, 78, 0, 0, 0, 0, - 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, - 0, 77, 0, 78, 64, 65, 0, 107, 67, 68, - 69, 70, 71, 72, 73, 0, 1, 2, 0, 3, - 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 75, 76, - 0, 0, 77, 0, 78, 64, 65, 74, 107, 67, - 68, 69, 70, 71, 72, 640, 0, 1, 2, 0, - 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, - 76, 0, 0, 77, 0, 78, 64, 65, 74, 107, - 67, 68, 69, 70, 71, 72, 684, 166, 1, 2, - 0, 3, 4, 5, 0, 0, 0, 0, 75, 76, - 0, 0, 77, 0, 377, 0, 0, 0, 167, 168, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 75, 76, 0, 0, 77, 0, - 481, 0, 0, 0, 0, 194, 195, 196, 0, 0, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 0, 0, 0, 75, 76, 0, 0, 77, - 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 75, 76, 0, 0, - 77, 0, 78 -}; - -static const yytype_int16 yycheck[] = -{ - 0, 27, 239, 196, 161, 158, 0, 321, 266, 267, - 462, 4, 28, 11, 540, 11, 55, 17, 211, 212, - 213, 214, 215, 17, 21, 55, 192, 172, 221, 289, - 450, 451, 29, 42, 43, 44, 45, 46, 47, 48, - 49, 55, 51, 159, 11, 34, 11, 55, 53, 7, - 660, 165, 78, 55, 32, 33, 55, 42, 43, 44, - 174, 19, 47, 68, 22, 54, 24, 677, 41, 42, - 165, 156, 55, 158, 164, 48, 102, 337, 223, 174, - 106, 54, 165, 193, 117, 118, 112, 54, 254, 54, - 256, 174, 118, 93, 7, 8, 165, 10, 11, 12, - 13, 14, 15, 16, 17, 174, 19, 20, 634, 22, - 23, 24, 165, 165, 640, 641, 142, 143, 538, 377, - 146, 174, 174, 162, 240, 241, 152, 59, 55, 55, - 11, 18, 162, 172, 586, 161, 17, 50, 168, 164, - 398, 399, 400, 169, 164, 255, 339, 257, 162, 163, - 159, 160, 161, 0, 162, 681, 682, 173, 684, 685, - 162, 34, 170, 162, 616, 168, 165, 166, 194, 195, - 196, 197, 170, 165, 170, 701, 702, 174, 170, 162, - 173, 55, 165, 166, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 121, 165, 283, 513, - 164, 286, 287, 288, 172, 231, 165, 20, 165, 165, - 23, 170, 164, 406, 170, 172, 242, 19, 22, 46, - 22, 48, 24, 481, 21, 35, 151, 37, 42, 422, - 44, 424, 425, 426, 22, 162, 162, 22, 323, 166, - 166, 163, 556, 165, 558, 162, 331, 332, 333, 334, - 335, 22, 54, 410, 167, 168, 4, 163, 171, 165, - 173, 174, 62, 63, 64, 65, 66, 67, 141, 142, - 143, 144, 4, 146, 300, 37, 433, 150, 151, 169, - 153, 154, 155, 156, 157, 163, 280, 165, 162, 163, - 169, 317, 318, 319, 7, 8, 159, 160, 161, 163, - 162, 165, 4, 163, 618, 165, 19, 20, 166, 22, - 23, 24, 338, 339, 467, 132, 133, 132, 133, 121, - 122, 132, 133, 114, 115, 54, 411, 412, 413, 414, - 84, 85, 164, 22, 165, 420, 172, 163, 4, 141, - 142, 163, 144, 145, 162, 147, 148, 149, 55, 434, - 11, 377, 57, 172, 163, 162, 158, 162, 22, 596, - 38, 162, 165, 162, 162, 4, 559, 162, 162, 562, - 563, 564, 162, 162, 61, 162, 38, 22, 38, 165, - 406, 165, 467, 165, 410, 165, 165, 38, 162, 165, - 162, 172, 121, 122, 162, 162, 422, 423, 424, 425, - 426, 165, 162, 168, 489, 22, 432, 433, 165, 494, - 165, 496, 141, 142, 499, 144, 145, 17, 147, 148, - 149, 165, 165, 165, 509, 510, 452, 512, 665, 158, - 165, 668, 165, 17, 165, 165, 4, 165, 26, 27, - 165, 165, 367, 368, 369, 370, 371, 372, 373, 165, - 476, 165, 4, 165, 165, 481, 165, 382, 383, 384, - 4, 165, 165, 22, 549, 550, 165, 552, 553, 554, - 555, 165, 165, 165, 165, 560, 172, 165, 4, 165, - 165, 165, 508, 568, 165, 165, 165, 163, 514, 574, - 141, 142, 143, 144, 165, 146, 165, 172, 4, 150, - 151, 54, 153, 154, 155, 156, 157, 162, 534, 286, - 287, 288, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 611, 162, 453, 454, - 455, 456, 165, 559, 163, 165, 562, 563, 564, 464, - 165, 163, 163, 22, 172, 165, 323, 170, 163, 168, - 163, 163, 163, 17, 331, 332, 333, 334, 335, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 595, - 163, 170, 163, 163, 659, 4, 602, 54, 663, 664, - 7, 8, 152, 10, 11, 12, 13, 14, 15, 16, - 17, 617, 19, 20, 594, 22, 23, 24, 523, 524, - 525, 526, 165, 528, 162, 162, 22, 532, 533, 17, - 695, 696, 17, 698, 165, 700, 17, 73, 17, 704, - 656, 93, 635, 50, 231, 710, 112, 17, 106, 90, - 133, 57, 242, 617, 411, 412, 413, 414, 133, -1, - 666, 457, -1, 420, -1, -1, -1, -1, -1, -1, - -1, 576, 577, 578, 579, -1, 656, 434, -1, -1, - -1, -1, -1, -1, -1, -1, 7, 8, -1, 10, - 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, - -1, 22, 23, 24, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 623, -1, - 625, 626, -1, -1, -1, -1, -1, -1, -1, 50, - -1, -1, 489, -1, -1, -1, -1, 494, -1, 496, - -1, -1, 499, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 509, 510, -1, 512, -1, -1, -1, -1, - 167, 168, -1, -1, 171, -1, 173, 174, -1, -1, - 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, - 17, -1, 19, 20, -1, 22, 23, 24, -1, -1, - -1, -1, 549, 550, -1, 552, 553, 554, 555, -1, - -1, -1, -1, 560, -1, -1, -1, -1, -1, -1, - -1, 568, -1, 50, -1, -1, -1, 574, 141, 142, - 143, 144, -1, 146, -1, -1, -1, 150, 151, -1, - 153, 154, 155, 156, 157, -1, -1, -1, -1, 3, - 4, 5, 6, 7, 8, 9, 167, 168, 0, -1, - 171, -1, 173, 174, 611, 19, 20, -1, 22, 23, - 24, 25, 26, 27, -1, -1, 18, 19, 20, -1, - 22, 23, 24, -1, -1, -1, 40, 41, 30, 31, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 54, -1, -1, -1, -1, 59, -1, -1, -1, -1, - 52, -1, 659, -1, 56, -1, 663, 664, 60, -1, - -1, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 167, 168, -1, -1, 171, -1, 173, 174, 695, 696, - -1, 698, -1, 700, -1, -1, -1, 704, -1, -1, - -1, -1, -1, 710, -1, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, -1, 133, - -1, 135, 136, 137, -1, 139, 140, 141, 142, -1, - 144, 145, -1, 147, 148, 149, -1, -1, -1, -1, - -1, -1, -1, -1, 158, -1, 3, 4, 5, 6, - 7, 8, 9, -1, 168, -1, -1, 171, -1, 173, - -1, 175, 19, 20, -1, 22, 23, 24, 25, 26, - 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 40, 41, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 55, -1, - 7, 8, 59, 10, 11, 12, 13, 14, 15, 16, - 17, -1, 19, 20, -1, 22, 23, 24, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, -1, -1, -1, - -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, -1, 133, 0, 135, 136, - 137, -1, 139, 140, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 18, 19, 20, -1, 22, - 23, 24, -1, -1, -1, 162, -1, 30, 31, -1, - -1, 168, -1, -1, 171, -1, 173, -1, 175, 3, - 4, 5, 6, 7, 8, 9, -1, -1, -1, 52, - -1, -1, -1, 56, -1, 19, 20, 60, 22, 23, - 24, 25, 26, 27, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 40, 41, -1, -1, - 167, 168, -1, -1, 171, -1, 173, 174, -1, -1, - -1, 55, 7, 8, -1, 10, 11, 12, 13, 14, - 15, 16, 17, -1, 19, 20, -1, 22, 23, 24, - -1, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, -1, 133, - -1, 135, 136, 137, -1, 139, 140, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 162, -1, - -1, -1, 166, -1, 168, -1, -1, 171, -1, 173, - -1, 175, 3, 4, 5, 6, 7, 8, 9, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, - -1, 22, 23, 24, 25, 26, 27, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 167, 168, -1, -1, 171, -1, 173, 174, - -1, -1, -1, -1, 55, 7, 8, -1, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, -1, -1, -1, -1, -1, 50, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, -1, 133, -1, 135, 136, 137, -1, 139, 140, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 162, -1, -1, -1, -1, -1, 168, -1, -1, - 171, -1, 173, 125, 175, 3, 4, 5, 6, 7, - 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 19, 20, -1, 22, 23, 24, 25, 26, 27, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 40, 41, -1, 167, 168, -1, -1, 171, - -1, 173, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 59, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, -1, 133, -1, 135, 136, 137, - -1, 139, 140, 3, 4, 5, 6, -1, -1, 9, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 25, 26, 27, -1, -1, - 168, -1, -1, 171, -1, 173, -1, 175, -1, -1, - 40, 41, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 7, 8, 59, - 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, - 20, -1, 22, 23, 24, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, -1, -1, -1, -1, 7, 8, - 50, 10, 11, 12, 13, 14, 15, 16, 17, -1, - 19, 20, -1, 22, 23, 24, -1, -1, -1, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, -1, 133, -1, 135, 136, 137, -1, 139, - 140, 50, 7, 8, -1, 10, 11, 12, 13, 14, - 15, 16, 17, -1, 19, 20, -1, 22, 23, 24, - -1, -1, -1, -1, -1, -1, -1, -1, 168, -1, - -1, 171, -1, 173, 39, 175, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, - -1, 141, 142, -1, 144, 7, 8, 147, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, -1, -1, -1, -1, 167, 168, -1, - -1, 171, -1, 173, -1, -1, -1, 39, -1, -1, - -1, -1, -1, -1, -1, -1, 7, 8, 50, 10, - 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, - -1, 22, 23, 24, -1, -1, -1, -1, 167, 168, - -1, 170, 171, -1, 173, -1, -1, -1, 7, 8, - -1, 10, 11, 12, 13, 14, 15, 16, 17, 50, - 19, 20, -1, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 39, -1, 167, 168, -1, -1, 171, -1, 173, 7, - 8, 50, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, -1, 22, 23, 24, 7, 8, -1, - 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, - 20, 39, 22, 23, 24, -1, -1, -1, -1, -1, - -1, -1, 50, -1, -1, 167, 168, -1, -1, 171, - -1, 173, -1, -1, -1, -1, -1, -1, 7, 8, - 50, 10, 11, 12, 13, 14, 15, 16, 17, -1, - 19, 20, -1, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 167, 168, -1, 170, - 171, -1, 173, -1, -1, -1, -1, -1, -1, 7, - 8, 50, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, -1, 22, 23, 24, -1, 167, 168, - -1, -1, 171, -1, 173, -1, -1, -1, 7, 8, - -1, 10, 11, 12, 13, 14, 15, 16, 17, -1, - 19, 20, 50, 22, 23, 24, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 167, - 168, -1, -1, 171, -1, 173, -1, -1, -1, -1, - -1, 50, -1, -1, -1, -1, -1, 167, 168, -1, - -1, 171, -1, 173, 7, 8, -1, 10, 11, 12, - 13, 14, 15, 16, 17, -1, 19, 20, -1, 22, - 23, 24, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 167, 168, - -1, -1, 171, -1, 173, 7, 8, 50, 10, 11, - 12, 13, 14, 15, 16, 17, -1, 19, 20, -1, - 22, 23, 24, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 167, - 168, -1, -1, 171, -1, 173, 7, 8, 50, 10, - 11, 12, 13, 14, 15, 16, 17, 36, 19, 20, - -1, 22, 23, 24, -1, -1, -1, -1, 167, 168, - -1, -1, 171, -1, 173, -1, -1, -1, 57, 58, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 50, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 167, 168, -1, -1, 171, -1, - 173, -1, -1, -1, -1, 114, 115, 116, -1, -1, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, -1, -1, -1, 167, 168, -1, -1, 171, - -1, 173, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 167, 168, -1, -1, - 171, -1, 173 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 19, 20, 22, 23, 24, 30, 31, 52, 56, - 60, 182, 185, 187, 188, 189, 223, 224, 225, 227, - 226, 53, 68, 232, 164, 59, 164, 18, 164, 42, - 43, 44, 45, 46, 47, 48, 49, 51, 159, 160, - 161, 190, 191, 192, 0, 225, 46, 48, 193, 242, - 42, 43, 44, 47, 194, 239, 241, 249, 164, 164, - 168, 233, 22, 231, 7, 8, 10, 11, 12, 13, - 14, 15, 16, 17, 50, 167, 168, 171, 173, 182, - 187, 210, 211, 245, 192, 192, 35, 37, 221, 192, - 192, 21, 250, 251, 29, 174, 240, 250, 22, 22, - 22, 234, 162, 4, 4, 4, 173, 10, 174, 211, - 216, 55, 162, 184, 221, 221, 42, 44, 195, 32, - 33, 220, 62, 63, 64, 65, 66, 67, 196, 237, - 237, 7, 185, 186, 254, 165, 170, 39, 211, 212, - 214, 215, 169, 169, 174, 216, 165, 174, 162, 215, - 166, 220, 220, 10, 125, 211, 213, 222, 211, 217, - 4, 200, 28, 173, 238, 164, 36, 57, 58, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 114, 115, 116, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 177, - 178, 179, 252, 259, 260, 261, 262, 252, 260, 22, - 198, 165, 163, 211, 211, 172, 174, 211, 4, 163, - 217, 211, 162, 245, 3, 4, 5, 6, 9, 25, - 26, 27, 40, 41, 90, 91, 92, 93, 119, 133, - 135, 136, 137, 139, 140, 168, 171, 173, 175, 177, - 178, 179, 218, 245, 184, 141, 142, 144, 147, 199, - 213, 57, 10, 211, 247, 248, 11, 17, 11, 196, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 180, 26, 27, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 181, 180, 181, - 211, 211, 247, 211, 211, 255, 247, 247, 247, 247, - 247, 211, 211, 211, 211, 211, 247, 196, 117, 118, - 54, 121, 122, 141, 142, 144, 145, 147, 148, 149, - 158, 197, 39, 212, 202, 170, 172, 172, 163, 202, - 184, 184, 222, 180, 181, 180, 181, 162, 162, 162, - 162, 162, 162, 162, 170, 217, 219, 173, 219, 174, - 219, 22, 162, 162, 162, 228, 187, 3, 4, 5, - 6, 9, 25, 26, 27, 40, 41, 59, 168, 171, - 173, 175, 218, 244, 245, 246, 165, 246, 246, 246, - 200, 211, 211, 211, 211, 165, 205, 165, 205, 246, - 168, 165, 165, 165, 165, 165, 165, 246, 246, 246, - 246, 246, 38, 200, 211, 247, 4, 141, 142, 143, - 144, 146, 150, 151, 153, 154, 155, 156, 157, 201, - 229, 230, 38, 162, 162, 162, 162, 217, 217, 217, - 217, 217, 217, 217, 165, 170, 174, 211, 219, 172, - 174, 217, 217, 217, 165, 208, 162, 61, 243, 170, - 219, 173, 219, 174, 219, 22, 247, 165, 165, 213, - 246, 246, 246, 246, 11, 54, 11, 257, 246, 168, - 247, 211, 247, 247, 247, 165, 165, 258, 165, 165, - 165, 211, 213, 246, 165, 208, 208, 211, 217, 217, - 217, 217, 257, 165, 165, 165, 165, 258, 165, 217, - 172, 174, 165, 165, 38, 34, 54, 206, 209, 39, - 211, 235, 236, 22, 170, 174, 219, 172, 174, 17, - 17, 246, 165, 165, 165, 165, 246, 4, 246, 165, - 165, 246, 165, 165, 165, 4, 4, 165, 211, 246, - 246, 246, 165, 205, 211, 163, 165, 165, 165, 165, - 163, 217, 217, 217, 217, 163, 217, 172, 217, 217, - 211, 22, 4, 208, 198, 165, 163, 165, 172, 174, - 246, 246, 162, 246, 246, 246, 246, 205, 205, 247, - 246, 165, 247, 247, 247, 4, 246, 162, 246, 217, - 217, 217, 217, 165, 163, 165, 165, 258, 163, 163, - 163, 182, 183, 39, 211, 202, 22, 172, 165, 168, - 17, 211, 256, 170, 246, 258, 256, 205, 163, 163, - 163, 163, 217, 217, 217, 163, 198, 206, 207, 17, - 11, 170, 253, 198, 198, 163, 165, 170, 163, 163, - 163, 163, 183, 54, 204, 246, 244, 11, 170, 121, - 122, 246, 246, 202, 17, 211, 202, 4, 152, 203, - 165, 244, 198, 198, 38, 198, 198, 22, 17, 165, - 17, 246, 246, 246, 17, 246, 198, 198, 246, 73, - 17, 246 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 29: -#line 1158 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_EQ; ;} - break; - - case 30: -#line 1158 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_NE; ;} - break; - - case 31: -#line 1159 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_SLT; ;} - break; - - case 32: -#line 1159 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_SGT; ;} - break; - - case 33: -#line 1160 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_SLE; ;} - break; - - case 34: -#line 1160 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_SGE; ;} - break; - - case 35: -#line 1161 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_ULT; ;} - break; - - case 36: -#line 1161 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_UGT; ;} - break; - - case 37: -#line 1162 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_ULE; ;} - break; - - case 38: -#line 1162 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.IPredicate) = ICmpInst::ICMP_UGE; ;} - break; - - case 39: -#line 1166 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_OEQ; ;} - break; - - case 40: -#line 1166 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_ONE; ;} - break; - - case 41: -#line 1167 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_OLT; ;} - break; - - case 42: -#line 1167 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_OGT; ;} - break; - - case 43: -#line 1168 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_OLE; ;} - break; - - case 44: -#line 1168 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_OGE; ;} - break; - - case 45: -#line 1169 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_ORD; ;} - break; - - case 46: -#line 1169 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_UNO; ;} - break; - - case 47: -#line 1170 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_UEQ; ;} - break; - - case 48: -#line 1170 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_UNE; ;} - break; - - case 49: -#line 1171 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_ULT; ;} - break; - - case 50: -#line 1171 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_UGT; ;} - break; - - case 51: -#line 1172 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_ULE; ;} - break; - - case 52: -#line 1172 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_UGE; ;} - break; - - case 53: -#line 1173 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_TRUE; ;} - break; - - case 54: -#line 1174 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.FPredicate) = FCmpInst::FCMP_FALSE; ;} - break; - - case 59: -#line 1178 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.StrVal) = 0; ;} - break; - - case 60: -#line 1180 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal)=(yyvsp[(3) - (4)].UInt64Val); ;} - break; - - case 61: -#line 1181 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal)=0; ;} - break; - - case 62: -#line 1185 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.StrVal) = (yyvsp[(1) - (2)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 63: -#line 1189 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.StrVal) = 0; - CHECK_FOR_ERROR - ;} - break; - - case 64: -#line 1194 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.UIntVal) = (yyvsp[(1) - (2)].UIntVal); - CHECK_FOR_ERROR -;} - break; - - case 68: -#line 1203 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.StrVal) = 0; - CHECK_FOR_ERROR - ;} - break; - - case 69: -#line 1208 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.StrVal) = (yyvsp[(1) - (2)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 70: -#line 1214 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} - break; - - case 71: -#line 1215 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} - break; - - case 72: -#line 1216 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} - break; - - case 73: -#line 1217 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::AppendingLinkage; ;} - break; - - case 74: -#line 1218 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} - break; - - case 75: -#line 1219 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::CommonLinkage; ;} - break; - - case 76: -#line 1223 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} - break; - - case 77: -#line 1224 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} - break; - - case 78: -#line 1225 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} - break; - - case 79: -#line 1229 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Visibility) = GlobalValue::DefaultVisibility; ;} - break; - - case 80: -#line 1230 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Visibility) = GlobalValue::DefaultVisibility; ;} - break; - - case 81: -#line 1231 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Visibility) = GlobalValue::HiddenVisibility; ;} - break; - - case 82: -#line 1232 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Visibility) = GlobalValue::ProtectedVisibility; ;} - break; - - case 83: -#line 1236 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} - break; - - case 84: -#line 1237 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::DLLImportLinkage; ;} - break; - - case 85: -#line 1238 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::ExternalWeakLinkage; ;} - break; - - case 86: -#line 1242 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} - break; - - case 87: -#line 1243 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} - break; - - case 88: -#line 1244 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::LinkOnceLinkage; ;} - break; - - case 89: -#line 1245 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} - break; - - case 90: -#line 1246 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::DLLExportLinkage; ;} - break; - - case 91: -#line 1250 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::ExternalLinkage; ;} - break; - - case 92: -#line 1251 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::WeakLinkage; ;} - break; - - case 93: -#line 1252 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Linkage) = GlobalValue::InternalLinkage; ;} - break; - - case 94: -#line 1255 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = CallingConv::C; ;} - break; - - case 95: -#line 1256 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = CallingConv::C; ;} - break; - - case 96: -#line 1257 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = CallingConv::Fast; ;} - break; - - case 97: -#line 1258 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = CallingConv::Cold; ;} - break; - - case 98: -#line 1259 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = CallingConv::X86_StdCall; ;} - break; - - case 99: -#line 1260 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = CallingConv::X86_FastCall; ;} - break; - - case 100: -#line 1261 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((unsigned)(yyvsp[(2) - (2)].UInt64Val) != (yyvsp[(2) - (2)].UInt64Val)) - GEN_ERROR("Calling conv too large"); - (yyval.UIntVal) = (yyvsp[(2) - (2)].UInt64Val); - CHECK_FOR_ERROR - ;} - break; - - case 101: -#line 1268 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ZExt; ;} - break; - - case 102: -#line 1269 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ZExt; ;} - break; - - case 103: -#line 1270 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::SExt; ;} - break; - - case 104: -#line 1271 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::SExt; ;} - break; - - case 105: -#line 1272 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::InReg; ;} - break; - - case 106: -#line 1273 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::StructRet; ;} - break; - - case 107: -#line 1274 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::NoAlias; ;} - break; - - case 108: -#line 1275 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::NoCapture; ;} - break; - - case 109: -#line 1276 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ByVal; ;} - break; - - case 110: -#line 1277 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::Nest; ;} - break; - - case 111: -#line 1278 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = - Attribute::constructAlignmentFromInt((yyvsp[(2) - (2)].UInt64Val)); ;} - break; - - case 112: -#line 1282 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::None; ;} - break; - - case 113: -#line 1283 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.Attributes) = (yyvsp[(1) - (2)].Attributes) | (yyvsp[(2) - (2)].Attributes); - ;} - break; - - case 114: -#line 1288 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::InReg; ;} - break; - - case 115: -#line 1289 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ZExt; ;} - break; - - case 116: -#line 1290 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::SExt; ;} - break; - - case 117: -#line 1291 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::NoAlias; ;} - break; - - case 118: -#line 1294 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::None; ;} - break; - - case 119: -#line 1295 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.Attributes) = (yyvsp[(1) - (2)].Attributes) | (yyvsp[(2) - (2)].Attributes); - ;} - break; - - case 120: -#line 1301 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::NoReturn; ;} - break; - - case 121: -#line 1302 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::NoUnwind; ;} - break; - - case 122: -#line 1303 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::InReg; ;} - break; - - case 123: -#line 1304 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ZExt; ;} - break; - - case 124: -#line 1305 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::SExt; ;} - break; - - case 125: -#line 1306 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ReadNone; ;} - break; - - case 126: -#line 1307 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::ReadOnly; ;} - break; - - case 127: -#line 1308 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::NoInline; ;} - break; - - case 128: -#line 1309 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::AlwaysInline; ;} - break; - - case 129: -#line 1310 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::OptimizeForSize; ;} - break; - - case 130: -#line 1311 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::StackProtect; ;} - break; - - case 131: -#line 1312 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::StackProtectReq; ;} - break; - - case 132: -#line 1315 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.Attributes) = Attribute::None; ;} - break; - - case 133: -#line 1316 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.Attributes) = (yyvsp[(1) - (2)].Attributes) | (yyvsp[(2) - (2)].Attributes); - ;} - break; - - case 134: -#line 1322 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.StrVal) = 0; ;} - break; - - case 135: -#line 1323 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.StrVal) = (yyvsp[(2) - (2)].StrVal); - ;} - break; - - case 136: -#line 1330 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = 0; ;} - break; - - case 137: -#line 1331 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.UIntVal) = (yyvsp[(2) - (2)].UInt64Val); - if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) - GEN_ERROR("Alignment must be a power of two"); - if ((yyval.UIntVal) > 0x40000000) - GEN_ERROR("Alignment too large"); - CHECK_FOR_ERROR -;} - break; - - case 138: -#line 1339 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.UIntVal) = 0; ;} - break; - - case 139: -#line 1340 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.UIntVal) = (yyvsp[(3) - (3)].UInt64Val); - if ((yyval.UIntVal) != 0 && !isPowerOf2_32((yyval.UIntVal))) - GEN_ERROR("Alignment must be a power of two"); - if ((yyval.UIntVal) > 0x40000000) - GEN_ERROR("Alignment too large"); - CHECK_FOR_ERROR -;} - break; - - case 140: -#line 1351 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - for (unsigned i = 0, e = (yyvsp[(2) - (2)].StrVal)->length(); i != e; ++i) - if ((*(yyvsp[(2) - (2)].StrVal))[i] == '"' || (*(yyvsp[(2) - (2)].StrVal))[i] == '\\') - GEN_ERROR("Invalid character in section name"); - (yyval.StrVal) = (yyvsp[(2) - (2)].StrVal); - CHECK_FOR_ERROR -;} - break; - - case 141: -#line 1359 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.StrVal) = 0; ;} - break; - - case 142: -#line 1360 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.StrVal) = (yyvsp[(1) - (1)].StrVal); ;} - break; - - case 143: -#line 1365 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - {;} - break; - - case 144: -#line 1366 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - {;} - break; - - case 145: -#line 1367 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurGV->setSection(*(yyvsp[(1) - (1)].StrVal)); - delete (yyvsp[(1) - (1)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 146: -#line 1372 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(2) - (2)].UInt64Val) != 0 && !isPowerOf2_32((yyvsp[(2) - (2)].UInt64Val))) - GEN_ERROR("Alignment must be a power of two"); - if ((yyvsp[(2) - (2)].UInt64Val) > 0x40000000) - GEN_ERROR("Alignment too large"); - CurGV->setAlignment((yyvsp[(2) - (2)].UInt64Val)); - CHECK_FOR_ERROR - ;} - break; - - case 154: -#line 1390 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeVal) = new PATypeHolder(OpaqueType::get()); - CHECK_FOR_ERROR - ;} - break; - - case 155: -#line 1394 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeVal) = new PATypeHolder((yyvsp[(1) - (1)].PrimType)); - CHECK_FOR_ERROR - ;} - break; - - case 156: -#line 1398 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Pointer type? - if (*(yyvsp[(1) - (3)].TypeVal) == Type::LabelTy) - GEN_ERROR("Cannot form a pointer to a basic block"); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(PointerType::get(*(yyvsp[(1) - (3)].TypeVal), (yyvsp[(2) - (3)].UIntVal)))); - delete (yyvsp[(1) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 157: -#line 1405 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Named types are also simple types... - const Type* tmp = getTypeVal((yyvsp[(1) - (1)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.TypeVal) = new PATypeHolder(tmp); - ;} - break; - - case 158: -#line 1410 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Type UpReference - if ((yyvsp[(2) - (2)].UInt64Val) > (uint64_t)~0U) GEN_ERROR("Value out of range"); - OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder - UpRefs.push_back(UpRefRecord((unsigned)(yyvsp[(2) - (2)].UInt64Val), OT)); // Add to vector... - (yyval.TypeVal) = new PATypeHolder(OT); - UR_OUT("New Upreference!\n"); - CHECK_FOR_ERROR - ;} - break; - - case 159: -#line 1418 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - const Type *RetTy = *(yyvsp[(1) - (5)].TypeVal); - if (!FunctionType::isValidReturnType(RetTy)) - GEN_ERROR("Invalid result type for LLVM function"); - - std::vector Params; - TypeWithAttrsList::iterator I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin(), E = (yyvsp[(3) - (5)].TypeWithAttrsList)->end(); - for (; I != E; ++I ) { - const Type *Ty = I->Ty->get(); - Params.push_back(Ty); - } - - bool isVarArg = Params.size() && Params.back() == Type::VoidTy; - if (isVarArg) Params.pop_back(); - - for (unsigned i = 0; i != Params.size(); ++i) - if (!(Params[i]->isFirstClassType() || isa(Params[i]))) - GEN_ERROR("Function arguments must be value types!"); - - CHECK_FOR_ERROR - - FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); - delete (yyvsp[(1) - (5)].TypeVal); // Delete the return type handle - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(FT)); - - // Delete the argument list - for (I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin() ; I != E; ++I ) { - delete I->Ty; - } - delete (yyvsp[(3) - (5)].TypeWithAttrsList); - - CHECK_FOR_ERROR - ;} - break; - - case 160: -#line 1453 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - std::vector Params; - TypeWithAttrsList::iterator I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin(), E = (yyvsp[(3) - (5)].TypeWithAttrsList)->end(); - for ( ; I != E; ++I ) { - const Type* Ty = I->Ty->get(); - Params.push_back(Ty); - } - - bool isVarArg = Params.size() && Params.back() == Type::VoidTy; - if (isVarArg) Params.pop_back(); - - for (unsigned i = 0; i != Params.size(); ++i) - if (!(Params[i]->isFirstClassType() || isa(Params[i]))) - GEN_ERROR("Function arguments must be value types!"); - - CHECK_FOR_ERROR - - FunctionType *FT = FunctionType::get((yyvsp[(1) - (5)].PrimType), Params, isVarArg); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(FT)); - - // Delete the argument list - for (I = (yyvsp[(3) - (5)].TypeWithAttrsList)->begin() ; I != E; ++I ) { - delete I->Ty; - } - delete (yyvsp[(3) - (5)].TypeWithAttrsList); - - CHECK_FOR_ERROR - ;} - break; - - case 161: -#line 1484 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Sized array type? - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(ArrayType::get(*(yyvsp[(4) - (5)].TypeVal), (yyvsp[(2) - (5)].UInt64Val)))); - delete (yyvsp[(4) - (5)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 162: -#line 1489 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Vector type? - const llvm::Type* ElemTy = (yyvsp[(4) - (5)].TypeVal)->get(); - if ((unsigned)(yyvsp[(2) - (5)].UInt64Val) != (yyvsp[(2) - (5)].UInt64Val)) - GEN_ERROR("Unsigned result not equal to signed result"); - if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger()) - GEN_ERROR("Element type of a VectorType must be primitive"); - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(VectorType::get(*(yyvsp[(4) - (5)].TypeVal), (unsigned)(yyvsp[(2) - (5)].UInt64Val)))); - delete (yyvsp[(4) - (5)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 163: -#line 1499 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Structure type? - std::vector Elements; - for (std::list::iterator I = (yyvsp[(2) - (3)].TypeList)->begin(), - E = (yyvsp[(2) - (3)].TypeList)->end(); I != E; ++I) - Elements.push_back(*I); - - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); - delete (yyvsp[(2) - (3)].TypeList); - CHECK_FOR_ERROR - ;} - break; - - case 164: -#line 1509 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Empty structure type? - (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector())); - CHECK_FOR_ERROR - ;} - break; - - case 165: -#line 1513 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - std::vector Elements; - for (std::list::iterator I = (yyvsp[(3) - (5)].TypeList)->begin(), - E = (yyvsp[(3) - (5)].TypeList)->end(); I != E; ++I) - Elements.push_back(*I); - - (yyval.TypeVal) = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true))); - delete (yyvsp[(3) - (5)].TypeList); - CHECK_FOR_ERROR - ;} - break; - - case 166: -#line 1523 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Empty structure type? - (yyval.TypeVal) = new PATypeHolder(StructType::get(std::vector(), true)); - CHECK_FOR_ERROR - ;} - break; - - case 167: -#line 1530 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - (yyval.TypeWithAttrs).Ty = (yyvsp[(1) - (2)].TypeVal); - (yyval.TypeWithAttrs).Attrs = Attribute::None; - ;} - break; - - case 168: -#line 1539 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (1)].TypeVal))->getDescription()); - if (!(*(yyvsp[(1) - (1)].TypeVal))->isFirstClassType() && !isa((yyvsp[(1) - (1)].TypeVal)->get())) - GEN_ERROR("LLVM functions cannot return aggregate types"); - (yyval.TypeVal) = (yyvsp[(1) - (1)].TypeVal); - ;} - break; - - case 169: -#line 1546 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeVal) = new PATypeHolder(Type::VoidTy); - ;} - break; - - case 170: -#line 1551 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); - (yyval.TypeWithAttrsList)->push_back((yyvsp[(1) - (1)].TypeWithAttrs)); - CHECK_FOR_ERROR - ;} - break; - - case 171: -#line 1556 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - ((yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList))->push_back((yyvsp[(3) - (3)].TypeWithAttrs)); - CHECK_FOR_ERROR - ;} - break; - - case 173: -#line 1564 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeWithAttrsList)=(yyvsp[(1) - (3)].TypeWithAttrsList); - TypeWithAttrs TWA; TWA.Attrs = Attribute::None; - TWA.Ty = new PATypeHolder(Type::VoidTy); - (yyval.TypeWithAttrsList)->push_back(TWA); - CHECK_FOR_ERROR - ;} - break; - - case 174: -#line 1571 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeWithAttrsList) = new TypeWithAttrsList; - TypeWithAttrs TWA; TWA.Attrs = Attribute::None; - TWA.Ty = new PATypeHolder(Type::VoidTy); - (yyval.TypeWithAttrsList)->push_back(TWA); - CHECK_FOR_ERROR - ;} - break; - - case 175: -#line 1578 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeWithAttrsList) = new TypeWithAttrsList(); - CHECK_FOR_ERROR - ;} - break; - - case 176: -#line 1586 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TypeList) = new std::list(); - (yyval.TypeList)->push_back(*(yyvsp[(1) - (1)].TypeVal)); - delete (yyvsp[(1) - (1)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 177: -#line 1592 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - ((yyval.TypeList)=(yyvsp[(1) - (3)].TypeList))->push_back(*(yyvsp[(3) - (3)].TypeVal)); - delete (yyvsp[(3) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 178: -#line 1604 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Nonempty unsized arr - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); - const ArrayType *ATy = dyn_cast((yyvsp[(1) - (4)].TypeVal)->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*(yyvsp[(1) - (4)].TypeVal))->getDescription() + "'"); - const Type *ETy = ATy->getElementType(); - uint64_t NumElements = ATy->getNumElements(); - - // Verify that we have the correct size... - if (NumElements != uint64_t(-1) && NumElements != (yyvsp[(3) - (4)].ConstVector)->size()) - GEN_ERROR("Type mismatch: constant sized array initialized with " + - utostr((yyvsp[(3) - (4)].ConstVector)->size()) + " arguments, but has size of " + - utostr(NumElements) + ""); - - // Verify all elements are correct type! - for (unsigned i = 0; i < (yyvsp[(3) - (4)].ConstVector)->size(); i++) { - if (ETy != (*(yyvsp[(3) - (4)].ConstVector))[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*(yyvsp[(3) - (4)].ConstVector))[i]->getType()->getDescription() + "'."); - } - - (yyval.ConstVal) = ConstantArray::get(ATy, *(yyvsp[(3) - (4)].ConstVector)); - delete (yyvsp[(1) - (4)].TypeVal); delete (yyvsp[(3) - (4)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 179: -#line 1632 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); - const ArrayType *ATy = dyn_cast((yyvsp[(1) - (3)].TypeVal)->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*(yyvsp[(1) - (3)].TypeVal))->getDescription() + "'"); - - uint64_t NumElements = ATy->getNumElements(); - if (NumElements != uint64_t(-1) && NumElements != 0) - GEN_ERROR("Type mismatch: constant sized array initialized with 0" - " arguments, but has size of " + utostr(NumElements) +""); - (yyval.ConstVal) = ConstantArray::get(ATy, std::vector()); - delete (yyvsp[(1) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 180: -#line 1648 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); - const ArrayType *ATy = dyn_cast((yyvsp[(1) - (3)].TypeVal)->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*(yyvsp[(1) - (3)].TypeVal))->getDescription() + "'"); - - uint64_t NumElements = ATy->getNumElements(); - const Type *ETy = ATy->getElementType(); - if (NumElements != uint64_t(-1) && NumElements != (yyvsp[(3) - (3)].StrVal)->length()) - GEN_ERROR("Can't build string constant of size " + - utostr((yyvsp[(3) - (3)].StrVal)->length()) + - " when array has size " + utostr(NumElements) + ""); - std::vector Vals; - if (ETy == Type::Int8Ty) { - for (uint64_t i = 0; i < (yyvsp[(3) - (3)].StrVal)->length(); ++i) - Vals.push_back(ConstantInt::get(ETy, (*(yyvsp[(3) - (3)].StrVal))[i])); - } else { - delete (yyvsp[(3) - (3)].StrVal); - GEN_ERROR("Cannot build string arrays of non byte sized elements"); - } - delete (yyvsp[(3) - (3)].StrVal); - (yyval.ConstVal) = ConstantArray::get(ATy, Vals); - delete (yyvsp[(1) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 181: -#line 1675 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Nonempty unsized arr - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); - const VectorType *PTy = dyn_cast((yyvsp[(1) - (4)].TypeVal)->get()); - if (PTy == 0) - GEN_ERROR("Cannot make packed constant with type: '" + - (*(yyvsp[(1) - (4)].TypeVal))->getDescription() + "'"); - const Type *ETy = PTy->getElementType(); - unsigned NumElements = PTy->getNumElements(); - - // Verify that we have the correct size... - if (NumElements != unsigned(-1) && NumElements != (unsigned)(yyvsp[(3) - (4)].ConstVector)->size()) - GEN_ERROR("Type mismatch: constant sized packed initialized with " + - utostr((yyvsp[(3) - (4)].ConstVector)->size()) + " arguments, but has size of " + - utostr(NumElements) + ""); - - // Verify all elements are correct type! - for (unsigned i = 0; i < (yyvsp[(3) - (4)].ConstVector)->size(); i++) { - if (ETy != (*(yyvsp[(3) - (4)].ConstVector))[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*(yyvsp[(3) - (4)].ConstVector))[i]->getType()->getDescription() + "'."); - } - - (yyval.ConstVal) = ConstantVector::get(PTy, *(yyvsp[(3) - (4)].ConstVector)); - delete (yyvsp[(1) - (4)].TypeVal); delete (yyvsp[(3) - (4)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 182: -#line 1703 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const StructType *STy = dyn_cast((yyvsp[(1) - (4)].TypeVal)->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*(yyvsp[(1) - (4)].TypeVal))->getDescription() + "'"); - - if ((yyvsp[(3) - (4)].ConstVector)->size() != STy->getNumContainedTypes()) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that constants are compatible with the type initializer! - for (unsigned i = 0, e = (yyvsp[(3) - (4)].ConstVector)->size(); i != e; ++i) - if ((*(yyvsp[(3) - (4)].ConstVector))[i]->getType() != STy->getElementType(i)) - GEN_ERROR("Expected type '" + - STy->getElementType(i)->getDescription() + - "' for element #" + utostr(i) + - " of structure initializer"); - - // Check to ensure that Type is not packed - if (STy->isPacked()) - GEN_ERROR("Unpacked Initializer to vector type '" + - STy->getDescription() + "'"); - - (yyval.ConstVal) = ConstantStruct::get(STy, *(yyvsp[(3) - (4)].ConstVector)); - delete (yyvsp[(1) - (4)].TypeVal); delete (yyvsp[(3) - (4)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 183: -#line 1729 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); - const StructType *STy = dyn_cast((yyvsp[(1) - (3)].TypeVal)->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*(yyvsp[(1) - (3)].TypeVal))->getDescription() + "'"); - - if (STy->getNumContainedTypes() != 0) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that Type is not packed - if (STy->isPacked()) - GEN_ERROR("Unpacked Initializer to vector type '" + - STy->getDescription() + "'"); - - (yyval.ConstVal) = ConstantStruct::get(STy, std::vector()); - delete (yyvsp[(1) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 184: -#line 1749 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const StructType *STy = dyn_cast((yyvsp[(1) - (6)].TypeVal)->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*(yyvsp[(1) - (6)].TypeVal))->getDescription() + "'"); - - if ((yyvsp[(4) - (6)].ConstVector)->size() != STy->getNumContainedTypes()) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that constants are compatible with the type initializer! - for (unsigned i = 0, e = (yyvsp[(4) - (6)].ConstVector)->size(); i != e; ++i) - if ((*(yyvsp[(4) - (6)].ConstVector))[i]->getType() != STy->getElementType(i)) - GEN_ERROR("Expected type '" + - STy->getElementType(i)->getDescription() + - "' for element #" + utostr(i) + - " of structure initializer"); - - // Check to ensure that Type is packed - if (!STy->isPacked()) - GEN_ERROR("Vector initializer to non-vector type '" + - STy->getDescription() + "'"); - - (yyval.ConstVal) = ConstantStruct::get(STy, *(yyvsp[(4) - (6)].ConstVector)); - delete (yyvsp[(1) - (6)].TypeVal); delete (yyvsp[(4) - (6)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 185: -#line 1775 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (5)].TypeVal))->getDescription()); - const StructType *STy = dyn_cast((yyvsp[(1) - (5)].TypeVal)->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*(yyvsp[(1) - (5)].TypeVal))->getDescription() + "'"); - - if (STy->getNumContainedTypes() != 0) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that Type is packed - if (!STy->isPacked()) - GEN_ERROR("Vector initializer to non-vector type '" + - STy->getDescription() + "'"); - - (yyval.ConstVal) = ConstantStruct::get(STy, std::vector()); - delete (yyvsp[(1) - (5)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 186: -#line 1795 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - const PointerType *PTy = dyn_cast((yyvsp[(1) - (2)].TypeVal)->get()); - if (PTy == 0) - GEN_ERROR("Cannot make null pointer constant with type: '" + - (*(yyvsp[(1) - (2)].TypeVal))->getDescription() + "'"); - - (yyval.ConstVal) = ConstantPointerNull::get(PTy); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 187: -#line 1807 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - (yyval.ConstVal) = UndefValue::get((yyvsp[(1) - (2)].TypeVal)->get()); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 188: -#line 1814 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - const PointerType *Ty = dyn_cast((yyvsp[(1) - (2)].TypeVal)->get()); - if (Ty == 0) - GEN_ERROR("Global const reference must be a pointer type " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - - // ConstExprs can exist in the body of a function, thus creating - // GlobalValues whenever they refer to a variable. Because we are in - // the context of a function, getExistingVal will search the functions - // symbol table instead of the module symbol table for the global symbol, - // which throws things all off. To get around this, we just tell - // getExistingVal that we are at global scope here. - // - Function *SavedCurFn = CurFun.CurrentFunction; - CurFun.CurrentFunction = 0; - - Value *V = getExistingVal(Ty, (yyvsp[(2) - (2)].ValIDVal)); - CHECK_FOR_ERROR - - CurFun.CurrentFunction = SavedCurFn; - - // If this is an initializer for a constant pointer, which is referencing a - // (currently) undefined variable, create a stub now that shall be replaced - // in the future with the right type of variable. - // - if (V == 0) { - assert(isa(Ty) && "Globals may only be used as pointers!"); - const PointerType *PT = cast(Ty); - - // First check to see if the forward references value is already created! - PerModuleInfo::GlobalRefsType::iterator I = - CurModule.GlobalRefs.find(std::make_pair(PT, (yyvsp[(2) - (2)].ValIDVal))); - - if (I != CurModule.GlobalRefs.end()) { - V = I->second; // Placeholder already exists, use it... - (yyvsp[(2) - (2)].ValIDVal).destroy(); - } else { - std::string Name; - if ((yyvsp[(2) - (2)].ValIDVal).Type == ValID::GlobalName) - Name = (yyvsp[(2) - (2)].ValIDVal).getName(); - else if ((yyvsp[(2) - (2)].ValIDVal).Type != ValID::GlobalID) - GEN_ERROR("Invalid reference to global"); - - // Create the forward referenced global. - GlobalValue *GV; - if (const FunctionType *FTy = - dyn_cast(PT->getElementType())) { - GV = Function::Create(FTy, GlobalValue::ExternalWeakLinkage, Name, - CurModule.CurrentModule); - } else { - GV = new GlobalVariable(PT->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, - Name, CurModule.CurrentModule); - } - - // Keep track of the fact that we have a forward ref to recycle it - CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, (yyvsp[(2) - (2)].ValIDVal)), GV)); - V = GV; - } - } - - (yyval.ConstVal) = cast(V); - delete (yyvsp[(1) - (2)].TypeVal); // Free the type handle - CHECK_FOR_ERROR - ;} - break; - - case 189: -#line 1880 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - if ((yyvsp[(1) - (2)].TypeVal)->get() != (yyvsp[(2) - (2)].ConstVal)->getType()) - GEN_ERROR("Mismatched types for constant expression: " + - (*(yyvsp[(1) - (2)].TypeVal))->getDescription() + " and " + (yyvsp[(2) - (2)].ConstVal)->getType()->getDescription()); - (yyval.ConstVal) = (yyvsp[(2) - (2)].ConstVal); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 190: -#line 1890 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - const Type *Ty = (yyvsp[(1) - (2)].TypeVal)->get(); - if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) - GEN_ERROR("Cannot create a null initialized value of this type"); - (yyval.ConstVal) = Constant::getNullValue(Ty); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 191: -#line 1900 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // integral constants - if (IntegerType *IT = dyn_cast((yyvsp[(1) - (2)].TypeVal)->get())) { - if (!ConstantInt::isValueValidForType(IT, (yyvsp[(2) - (2)].SInt64Val))) - GEN_ERROR("Constant value doesn't fit in type"); - (yyval.ConstVal) = ConstantInt::get(IT, (yyvsp[(2) - (2)].SInt64Val), true); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 192: -#line 1911 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // arbitrary precision integer constants - if (IntegerType *IT = dyn_cast((yyvsp[(1) - (2)].TypeVal)->get())) { - if ((yyvsp[(2) - (2)].APIntVal)->getBitWidth() > IT->getBitWidth()) - GEN_ERROR("Constant value does not fit in type"); - (yyvsp[(2) - (2)].APIntVal)->sextOrTrunc(IT->getBitWidth()); - (yyval.ConstVal) = ConstantInt::get(*(yyvsp[(2) - (2)].APIntVal)); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete (yyvsp[(1) - (2)].TypeVal); - delete (yyvsp[(2) - (2)].APIntVal); - CHECK_FOR_ERROR - ;} - break; - - case 193: -#line 1924 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // integral constants - if (IntegerType *IT = dyn_cast((yyvsp[(1) - (2)].TypeVal)->get())) { - if (!ConstantInt::isValueValidForType(IT, (yyvsp[(2) - (2)].UInt64Val))) - GEN_ERROR("Constant value doesn't fit in type"); - (yyval.ConstVal) = ConstantInt::get(IT, (yyvsp[(2) - (2)].UInt64Val), false); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 194: -#line 1935 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // arbitrary precision integer constants - if (IntegerType *IT = dyn_cast((yyvsp[(1) - (2)].TypeVal)->get())) { - if ((yyvsp[(2) - (2)].APIntVal)->getBitWidth() > IT->getBitWidth()) - GEN_ERROR("Constant value does not fit in type"); - (yyvsp[(2) - (2)].APIntVal)->zextOrTrunc(IT->getBitWidth()); - (yyval.ConstVal) = ConstantInt::get(*(yyvsp[(2) - (2)].APIntVal)); - } else { - GEN_ERROR("integer constant must have integer type"); - } - - delete (yyvsp[(2) - (2)].APIntVal); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 195: -#line 1949 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Boolean constants - if ((yyvsp[(1) - (2)].TypeVal)->get() != Type::Int1Ty) - GEN_ERROR("Constant true must have type i1"); - (yyval.ConstVal) = ConstantInt::getTrue(); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 196: -#line 1956 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Boolean constants - if ((yyvsp[(1) - (2)].TypeVal)->get() != Type::Int1Ty) - GEN_ERROR("Constant false must have type i1"); - (yyval.ConstVal) = ConstantInt::getFalse(); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 197: -#line 1963 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Floating point constants - if (!ConstantFP::isValueValidForType((yyvsp[(1) - (2)].TypeVal)->get(), *(yyvsp[(2) - (2)].FPVal))) - GEN_ERROR("Floating point constant invalid for type"); - - // Lexer has no type info, so builds all float and double FP constants - // as double. Fix this here. Long double is done right. - if (&(yyvsp[(2) - (2)].FPVal)->getSemantics()==&APFloat::IEEEdouble && (yyvsp[(1) - (2)].TypeVal)->get()==Type::FloatTy) { - bool ignored; - (yyvsp[(2) - (2)].FPVal)->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, - &ignored); - } - (yyval.ConstVal) = ConstantFP::get(*(yyvsp[(2) - (2)].FPVal)); - delete (yyvsp[(1) - (2)].TypeVal); - delete (yyvsp[(2) - (2)].FPVal); - CHECK_FOR_ERROR - ;} - break; - - case 198: -#line 1981 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(5) - (6)].TypeVal))->getDescription()); - Constant *Val = (yyvsp[(3) - (6)].ConstVal); - const Type *DestTy = (yyvsp[(5) - (6)].TypeVal)->get(); - if (!CastInst::castIsValid((yyvsp[(1) - (6)].CastOpVal), (yyvsp[(3) - (6)].ConstVal), DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - (yyval.ConstVal) = ConstantExpr::getCast((yyvsp[(1) - (6)].CastOpVal), (yyvsp[(3) - (6)].ConstVal), DestTy); - delete (yyvsp[(5) - (6)].TypeVal); - ;} - break; - - case 199: -#line 1993 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!isa((yyvsp[(3) - (5)].ConstVal)->getType())) - GEN_ERROR("GetElementPtr requires a pointer operand"); - - const Type *IdxTy = - GetElementPtrInst::getIndexedType((yyvsp[(3) - (5)].ConstVal)->getType(), (yyvsp[(4) - (5)].ValueList)->begin(), (yyvsp[(4) - (5)].ValueList)->end()); - if (!IdxTy) - GEN_ERROR("Index list invalid for constant getelementptr"); - - SmallVector IdxVec; - for (unsigned i = 0, e = (yyvsp[(4) - (5)].ValueList)->size(); i != e; ++i) - if (Constant *C = dyn_cast((*(yyvsp[(4) - (5)].ValueList))[i])) - IdxVec.push_back(C); - else - GEN_ERROR("Indices to constant getelementptr must be constants"); - - delete (yyvsp[(4) - (5)].ValueList); - - (yyval.ConstVal) = ConstantExpr::getGetElementPtr((yyvsp[(3) - (5)].ConstVal), &IdxVec[0], IdxVec.size()); - CHECK_FOR_ERROR - ;} - break; - - case 200: -#line 2014 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(3) - (8)].ConstVal)->getType() != Type::Int1Ty) - GEN_ERROR("Select condition must be of boolean type"); - if ((yyvsp[(5) - (8)].ConstVal)->getType() != (yyvsp[(7) - (8)].ConstVal)->getType()) - GEN_ERROR("Select operand types must match"); - (yyval.ConstVal) = ConstantExpr::getSelect((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 201: -#line 2022 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(3) - (6)].ConstVal)->getType() != (yyvsp[(5) - (6)].ConstVal)->getType()) - GEN_ERROR("Binary operator types must match"); - CHECK_FOR_ERROR; - (yyval.ConstVal) = ConstantExpr::get((yyvsp[(1) - (6)].BinaryOpVal), (yyvsp[(3) - (6)].ConstVal), (yyvsp[(5) - (6)].ConstVal)); - ;} - break; - - case 202: -#line 2028 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(3) - (6)].ConstVal)->getType() != (yyvsp[(5) - (6)].ConstVal)->getType()) - GEN_ERROR("Logical operator types must match"); - if (!(yyvsp[(3) - (6)].ConstVal)->getType()->isInteger()) { - if (!isa((yyvsp[(3) - (6)].ConstVal)->getType()) || - !cast((yyvsp[(3) - (6)].ConstVal)->getType())->getElementType()->isInteger()) - GEN_ERROR("Logical operator requires integral operands"); - } - (yyval.ConstVal) = ConstantExpr::get((yyvsp[(1) - (6)].BinaryOpVal), (yyvsp[(3) - (6)].ConstVal), (yyvsp[(5) - (6)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 203: -#line 2039 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) - GEN_ERROR("icmp operand types must match"); - (yyval.ConstVal) = ConstantExpr::getICmp((yyvsp[(2) - (7)].IPredicate), (yyvsp[(4) - (7)].ConstVal), (yyvsp[(6) - (7)].ConstVal)); - ;} - break; - - case 204: -#line 2044 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) - GEN_ERROR("fcmp operand types must match"); - (yyval.ConstVal) = ConstantExpr::getFCmp((yyvsp[(2) - (7)].FPredicate), (yyvsp[(4) - (7)].ConstVal), (yyvsp[(6) - (7)].ConstVal)); - ;} - break; - - case 205: -#line 2049 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) - GEN_ERROR("vicmp operand types must match"); - (yyval.ConstVal) = ConstantExpr::getVICmp((yyvsp[(2) - (7)].IPredicate), (yyvsp[(4) - (7)].ConstVal), (yyvsp[(6) - (7)].ConstVal)); - ;} - break; - - case 206: -#line 2054 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(4) - (7)].ConstVal)->getType() != (yyvsp[(6) - (7)].ConstVal)->getType()) - GEN_ERROR("vfcmp operand types must match"); - (yyval.ConstVal) = ConstantExpr::getVFCmp((yyvsp[(2) - (7)].FPredicate), (yyvsp[(4) - (7)].ConstVal), (yyvsp[(6) - (7)].ConstVal)); - ;} - break; - - case 207: -#line 2059 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!ExtractElementInst::isValidOperands((yyvsp[(3) - (6)].ConstVal), (yyvsp[(5) - (6)].ConstVal))) - GEN_ERROR("Invalid extractelement operands"); - (yyval.ConstVal) = ConstantExpr::getExtractElement((yyvsp[(3) - (6)].ConstVal), (yyvsp[(5) - (6)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 208: -#line 2065 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!InsertElementInst::isValidOperands((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal))) - GEN_ERROR("Invalid insertelement operands"); - (yyval.ConstVal) = ConstantExpr::getInsertElement((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 209: -#line 2071 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!ShuffleVectorInst::isValidOperands((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal))) - GEN_ERROR("Invalid shufflevector operands"); - (yyval.ConstVal) = ConstantExpr::getShuffleVector((yyvsp[(3) - (8)].ConstVal), (yyvsp[(5) - (8)].ConstVal), (yyvsp[(7) - (8)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 210: -#line 2077 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!isa((yyvsp[(3) - (5)].ConstVal)->getType()) && !isa((yyvsp[(3) - (5)].ConstVal)->getType())) - GEN_ERROR("ExtractValue requires an aggregate operand"); - - (yyval.ConstVal) = ConstantExpr::getExtractValue((yyvsp[(3) - (5)].ConstVal), &(*(yyvsp[(4) - (5)].ConstantList))[0], (yyvsp[(4) - (5)].ConstantList)->size()); - delete (yyvsp[(4) - (5)].ConstantList); - CHECK_FOR_ERROR - ;} - break; - - case 211: -#line 2085 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!isa((yyvsp[(3) - (7)].ConstVal)->getType()) && !isa((yyvsp[(3) - (7)].ConstVal)->getType())) - GEN_ERROR("InsertValue requires an aggregate operand"); - - (yyval.ConstVal) = ConstantExpr::getInsertValue((yyvsp[(3) - (7)].ConstVal), (yyvsp[(5) - (7)].ConstVal), &(*(yyvsp[(6) - (7)].ConstantList))[0], (yyvsp[(6) - (7)].ConstantList)->size()); - delete (yyvsp[(6) - (7)].ConstantList); - CHECK_FOR_ERROR - ;} - break; - - case 212: -#line 2096 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - ((yyval.ConstVector) = (yyvsp[(1) - (3)].ConstVector))->push_back((yyvsp[(3) - (3)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 213: -#line 2100 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ConstVector) = new std::vector(); - (yyval.ConstVector)->push_back((yyvsp[(1) - (1)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 214: -#line 2108 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.BoolVal) = false; ;} - break; - - case 215: -#line 2108 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.BoolVal) = true; ;} - break; - - case 216: -#line 2111 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.BoolVal) = true; ;} - break; - - case 217: -#line 2111 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.BoolVal) = false; ;} - break; - - case 218: -#line 2114 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const Type* VTy = (yyvsp[(1) - (2)].TypeVal)->get(); - Value *V = getVal(VTy, (yyvsp[(2) - (2)].ValIDVal)); - CHECK_FOR_ERROR - GlobalValue* Aliasee = dyn_cast(V); - if (!Aliasee) - GEN_ERROR("Aliases can be created only to global values"); - - (yyval.ConstVal) = Aliasee; - CHECK_FOR_ERROR - delete (yyvsp[(1) - (2)].TypeVal); - ;} - break; - - case 219: -#line 2126 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - Constant *Val = (yyvsp[(3) - (6)].ConstVal); - const Type *DestTy = (yyvsp[(5) - (6)].TypeVal)->get(); - if (!CastInst::castIsValid((yyvsp[(1) - (6)].CastOpVal), (yyvsp[(3) - (6)].ConstVal), DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - - (yyval.ConstVal) = ConstantExpr::getCast((yyvsp[(1) - (6)].CastOpVal), (yyvsp[(3) - (6)].ConstVal), DestTy); - CHECK_FOR_ERROR - delete (yyvsp[(5) - (6)].TypeVal); - ;} - break; - - case 220: -#line 2147 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ModuleVal) = ParserResult = CurModule.CurrentModule; - CurModule.ModuleDone(); - CHECK_FOR_ERROR; - ;} - break; - - case 221: -#line 2152 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ModuleVal) = ParserResult = CurModule.CurrentModule; - CurModule.ModuleDone(); - CHECK_FOR_ERROR; - ;} - break; - - case 224: -#line 2165 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { CurFun.isDeclare = false; ;} - break; - - case 225: -#line 2165 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurFun.FunctionDone(); - CHECK_FOR_ERROR - ;} - break; - - case 226: -#line 2169 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { CurFun.isDeclare = true; ;} - break; - - case 227: -#line 2169 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - ;} - break; - - case 228: -#line 2172 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - ;} - break; - - case 229: -#line 2175 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (3)].TypeVal))->getDescription()); - // Eagerly resolve types. This is not an optimization, this is a - // requirement that is due to the fact that we could have this: - // - // %list = type { %list * } - // %list = type { %list * } ; repeated type decl - // - // If types are not resolved eagerly, then the two types will not be - // determined to be the same type! - // - ResolveTypeTo((yyvsp[(1) - (3)].StrVal), *(yyvsp[(3) - (3)].TypeVal)); - - if (!setTypeName(*(yyvsp[(3) - (3)].TypeVal), (yyvsp[(1) - (3)].StrVal)) && !(yyvsp[(1) - (3)].StrVal)) { - CHECK_FOR_ERROR - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back(*(yyvsp[(3) - (3)].TypeVal)); - } - - delete (yyvsp[(3) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 230: -#line 2199 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - ResolveTypeTo((yyvsp[(1) - (3)].StrVal), (yyvsp[(3) - (3)].PrimType)); - - if (!setTypeName((yyvsp[(3) - (3)].PrimType), (yyvsp[(1) - (3)].StrVal)) && !(yyvsp[(1) - (3)].StrVal)) { - CHECK_FOR_ERROR - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back((yyvsp[(3) - (3)].PrimType)); - } - CHECK_FOR_ERROR - ;} - break; - - case 231: -#line 2211 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - /* "Externally Visible" Linkage */ - if ((yyvsp[(5) - (6)].ConstVal) == 0) - GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable((yyvsp[(1) - (6)].StrVal), GlobalValue::ExternalLinkage, - (yyvsp[(2) - (6)].Visibility), (yyvsp[(4) - (6)].BoolVal), (yyvsp[(5) - (6)].ConstVal)->getType(), (yyvsp[(5) - (6)].ConstVal), (yyvsp[(3) - (6)].BoolVal), (yyvsp[(6) - (6)].UIntVal)); - CHECK_FOR_ERROR - ;} - break; - - case 232: -#line 2218 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurGV = 0; - ;} - break; - - case 233: -#line 2222 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if ((yyvsp[(6) - (7)].ConstVal) == 0) - GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable((yyvsp[(1) - (7)].StrVal), (yyvsp[(2) - (7)].Linkage), (yyvsp[(3) - (7)].Visibility), (yyvsp[(5) - (7)].BoolVal), (yyvsp[(6) - (7)].ConstVal)->getType(), (yyvsp[(6) - (7)].ConstVal), (yyvsp[(4) - (7)].BoolVal), (yyvsp[(7) - (7)].UIntVal)); - CHECK_FOR_ERROR - ;} - break; - - case 234: -#line 2227 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurGV = 0; - ;} - break; - - case 235: -#line 2231 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(6) - (7)].TypeVal))->getDescription()); - CurGV = ParseGlobalVariable((yyvsp[(1) - (7)].StrVal), (yyvsp[(2) - (7)].Linkage), (yyvsp[(3) - (7)].Visibility), (yyvsp[(5) - (7)].BoolVal), *(yyvsp[(6) - (7)].TypeVal), 0, (yyvsp[(4) - (7)].BoolVal), (yyvsp[(7) - (7)].UIntVal)); - CHECK_FOR_ERROR - delete (yyvsp[(6) - (7)].TypeVal); - ;} - break; - - case 236: -#line 2237 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurGV = 0; - CHECK_FOR_ERROR - ;} - break; - - case 237: -#line 2241 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - std::string Name; - if ((yyvsp[(1) - (5)].StrVal)) { - Name = *(yyvsp[(1) - (5)].StrVal); - delete (yyvsp[(1) - (5)].StrVal); - } - if (Name.empty()) - GEN_ERROR("Alias name cannot be empty"); - - Constant* Aliasee = (yyvsp[(5) - (5)].ConstVal); - if (Aliasee == 0) - GEN_ERROR(std::string("Invalid aliasee for alias: ") + Name); - - GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), (yyvsp[(4) - (5)].Linkage), Name, Aliasee, - CurModule.CurrentModule); - GA->setVisibility((yyvsp[(2) - (5)].Visibility)); - InsertValue(GA, CurModule.Values); - - - // If there was a forward reference of this alias, resolve it now. - - ValID ID; - if (!Name.empty()) - ID = ValID::createGlobalName(Name); - else - ID = ValID::createGlobalID(CurModule.Values.size()-1); - - if (GlobalValue *FWGV = - CurModule.GetForwardRefForGlobal(GA->getType(), ID)) { - // Replace uses of the fwdref with the actual alias. - FWGV->replaceAllUsesWith(GA); - if (GlobalVariable *GV = dyn_cast(FWGV)) - GV->eraseFromParent(); - else - cast(FWGV)->eraseFromParent(); - } - ID.destroy(); - - CHECK_FOR_ERROR - ;} - break; - - case 238: -#line 2281 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - ;} - break; - - case 239: -#line 2284 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - ;} - break; - - case 240: -#line 2290 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); - if (AsmSoFar.empty()) - CurModule.CurrentModule->setModuleInlineAsm(*(yyvsp[(1) - (1)].StrVal)); - else - CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+*(yyvsp[(1) - (1)].StrVal)); - delete (yyvsp[(1) - (1)].StrVal); - CHECK_FOR_ERROR -;} - break; - - case 241: -#line 2300 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurModule.CurrentModule->setTargetTriple(*(yyvsp[(3) - (3)].StrVal)); - delete (yyvsp[(3) - (3)].StrVal); - ;} - break; - - case 242: -#line 2304 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurModule.CurrentModule->setDataLayout(*(yyvsp[(3) - (3)].StrVal)); - delete (yyvsp[(3) - (3)].StrVal); - ;} - break; - - case 244: -#line 2311 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurModule.CurrentModule->addLibrary(*(yyvsp[(3) - (3)].StrVal)); - delete (yyvsp[(3) - (3)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 245: -#line 2316 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurModule.CurrentModule->addLibrary(*(yyvsp[(1) - (1)].StrVal)); - delete (yyvsp[(1) - (1)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 246: -#line 2321 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - ;} - break; - - case 247: -#line 2330 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); - if (!(*(yyvsp[(3) - (5)].TypeVal))->isFirstClassType()) - GEN_ERROR("Argument types must be first-class"); - ArgListEntry E; E.Attrs = (yyvsp[(4) - (5)].Attributes); E.Ty = (yyvsp[(3) - (5)].TypeVal); E.Name = (yyvsp[(5) - (5)].StrVal); - (yyval.ArgList) = (yyvsp[(1) - (5)].ArgList); - (yyvsp[(1) - (5)].ArgList)->push_back(E); - CHECK_FOR_ERROR - ;} - break; - - case 248: -#line 2340 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (3)].TypeVal))->getDescription()); - if (!(*(yyvsp[(1) - (3)].TypeVal))->isFirstClassType()) - GEN_ERROR("Argument types must be first-class"); - ArgListEntry E; E.Attrs = (yyvsp[(2) - (3)].Attributes); E.Ty = (yyvsp[(1) - (3)].TypeVal); E.Name = (yyvsp[(3) - (3)].StrVal); - (yyval.ArgList) = new ArgListType; - (yyval.ArgList)->push_back(E); - CHECK_FOR_ERROR - ;} - break; - - case 249: -#line 2351 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ArgList) = (yyvsp[(1) - (1)].ArgList); - CHECK_FOR_ERROR - ;} - break; - - case 250: -#line 2355 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ArgList) = (yyvsp[(1) - (3)].ArgList); - struct ArgListEntry E; - E.Ty = new PATypeHolder(Type::VoidTy); - E.Name = 0; - E.Attrs = Attribute::None; - (yyval.ArgList)->push_back(E); - CHECK_FOR_ERROR - ;} - break; - - case 251: -#line 2364 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ArgList) = new ArgListType; - struct ArgListEntry E; - E.Ty = new PATypeHolder(Type::VoidTy); - E.Name = 0; - E.Attrs = Attribute::None; - (yyval.ArgList)->push_back(E); - CHECK_FOR_ERROR - ;} - break; - - case 252: -#line 2373 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ArgList) = 0; - CHECK_FOR_ERROR - ;} - break; - - case 253: -#line 2379 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - std::string FunctionName(*(yyvsp[(4) - (11)].StrVal)); - delete (yyvsp[(4) - (11)].StrVal); // Free strdup'd memory! - - // Check the function result for abstractness if this is a define. We should - // have no abstract types at this point - if (!CurFun.isDeclare && CurModule.TypeIsUnresolved((yyvsp[(3) - (11)].TypeVal))) - GEN_ERROR("Reference to abstract result: "+ (yyvsp[(3) - (11)].TypeVal)->get()->getDescription()); - - if (!FunctionType::isValidReturnType(*(yyvsp[(3) - (11)].TypeVal))) - GEN_ERROR("Invalid result type for LLVM function"); - - std::vector ParamTypeList; - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = (yyvsp[(2) - (11)].Attributes); - if ((yyvsp[(8) - (11)].Attributes) != Attribute::None) { - if ((yyvsp[(8) - (11)].Attributes) & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - (yyvsp[(8) - (11)].Attributes) = (yyvsp[(8) - (11)].Attributes) ^ Attribute::ZExt; - } - if ((yyvsp[(8) - (11)].Attributes) & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - (yyvsp[(8) - (11)].Attributes) = (yyvsp[(8) - (11)].Attributes) ^ Attribute::SExt; - } - if ((yyvsp[(8) - (11)].Attributes) & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - (yyvsp[(8) - (11)].Attributes) = (yyvsp[(8) - (11)].Attributes) ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - if ((yyvsp[(6) - (11)].ArgList)) { // If there are arguments... - unsigned index = 1; - for (ArgListType::iterator I = (yyvsp[(6) - (11)].ArgList)->begin(); I != (yyvsp[(6) - (11)].ArgList)->end(); ++I, ++index) { - const Type* Ty = I->Ty->get(); - if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty)) - GEN_ERROR("Reference to abstract argument: " + Ty->getDescription()); - ParamTypeList.push_back(Ty); - if (Ty != Type::VoidTy && I->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, I->Attrs)); - } - } - if ((yyvsp[(8) - (11)].Attributes) != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, (yyvsp[(8) - (11)].Attributes))); - - bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; - if (isVarArg) ParamTypeList.pop_back(); - - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - FunctionType *FT = FunctionType::get(*(yyvsp[(3) - (11)].TypeVal), ParamTypeList, isVarArg); - const PointerType *PFT = PointerType::getUnqual(FT); - delete (yyvsp[(3) - (11)].TypeVal); - - ValID ID; - if (!FunctionName.empty()) { - ID = ValID::createGlobalName((char*)FunctionName.c_str()); - } else { - ID = ValID::createGlobalID(CurModule.Values.size()); - } - - Function *Fn = 0; - // See if this function was forward referenced. If so, recycle the object. - if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) { - // Move the function to the end of the list, from whereever it was - // previously inserted. - Fn = cast(FWRef); - assert(Fn->getAttributes().isEmpty() && - "Forward reference has parameter attributes!"); - CurModule.CurrentModule->getFunctionList().remove(Fn); - CurModule.CurrentModule->getFunctionList().push_back(Fn); - } else if (!FunctionName.empty() && // Merge with an earlier prototype? - (Fn = CurModule.CurrentModule->getFunction(FunctionName))) { - if (Fn->getFunctionType() != FT ) { - // The existing function doesn't have the same type. This is an overload - // error. - GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); - } else if (Fn->getAttributes() != PAL) { - // The existing function doesn't have the same parameter attributes. - // This is an overload error. - GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); - } else if (!CurFun.isDeclare && !Fn->isDeclaration()) { - // Neither the existing or the current function is a declaration and they - // have the same name and same type. Clearly this is a redefinition. - GEN_ERROR("Redefinition of function '" + FunctionName + "'"); - } else if (Fn->isDeclaration()) { - // Make sure to strip off any argument names so we can't get conflicts. - for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); - AI != AE; ++AI) - AI->setName(""); - } - } else { // Not already defined? - Fn = Function::Create(FT, GlobalValue::ExternalWeakLinkage, FunctionName, - CurModule.CurrentModule); - InsertValue(Fn, CurModule.Values); - } - - ID.destroy(); - CurFun.FunctionStart(Fn); - - if (CurFun.isDeclare) { - // If we have declaration, always overwrite linkage. This will allow us to - // correctly handle cases, when pointer to function is passed as argument to - // another function. - Fn->setLinkage(CurFun.Linkage); - Fn->setVisibility(CurFun.Visibility); - } - Fn->setCallingConv((yyvsp[(1) - (11)].UIntVal)); - Fn->setAttributes(PAL); - Fn->setAlignment((yyvsp[(10) - (11)].UIntVal)); - if ((yyvsp[(9) - (11)].StrVal)) { - Fn->setSection(*(yyvsp[(9) - (11)].StrVal)); - delete (yyvsp[(9) - (11)].StrVal); - } - if ((yyvsp[(11) - (11)].StrVal)) { - Fn->setGC((yyvsp[(11) - (11)].StrVal)->c_str()); - delete (yyvsp[(11) - (11)].StrVal); - } - - // Add all of the arguments we parsed to the function... - if ((yyvsp[(6) - (11)].ArgList)) { // Is null if empty... - if (isVarArg) { // Nuke the last entry - assert((yyvsp[(6) - (11)].ArgList)->back().Ty->get() == Type::VoidTy && (yyvsp[(6) - (11)].ArgList)->back().Name == 0 && - "Not a varargs marker!"); - delete (yyvsp[(6) - (11)].ArgList)->back().Ty; - (yyvsp[(6) - (11)].ArgList)->pop_back(); // Delete the last entry - } - Function::arg_iterator ArgIt = Fn->arg_begin(); - Function::arg_iterator ArgEnd = Fn->arg_end(); - unsigned Idx = 1; - for (ArgListType::iterator I = (yyvsp[(6) - (11)].ArgList)->begin(); - I != (yyvsp[(6) - (11)].ArgList)->end() && ArgIt != ArgEnd; ++I, ++ArgIt) { - delete I->Ty; // Delete the typeholder... - setValueName(ArgIt, I->Name); // Insert arg into symtab... - CHECK_FOR_ERROR - InsertValue(ArgIt); - Idx++; - } - - delete (yyvsp[(6) - (11)].ArgList); // We're now done with the argument list - } - CHECK_FOR_ERROR -;} - break; - - case 256: -#line 2529 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.FunctionVal) = CurFun.CurrentFunction; - - // Make sure that we keep track of the linkage type even if there was a - // previous "declare". - (yyval.FunctionVal)->setLinkage((yyvsp[(1) - (4)].Linkage)); - (yyval.FunctionVal)->setVisibility((yyvsp[(2) - (4)].Visibility)); -;} - break; - - case 259: -#line 2540 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); - CHECK_FOR_ERROR -;} - break; - - case 260: -#line 2545 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CurFun.CurrentFunction->setLinkage((yyvsp[(1) - (3)].Linkage)); - CurFun.CurrentFunction->setVisibility((yyvsp[(2) - (3)].Visibility)); - (yyval.FunctionVal) = CurFun.CurrentFunction; - CurFun.FunctionDone(); - CHECK_FOR_ERROR - ;} - break; - - case 261: -#line 2557 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.BoolVal) = false; - CHECK_FOR_ERROR - ;} - break; - - case 262: -#line 2561 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.BoolVal) = true; - CHECK_FOR_ERROR - ;} - break; - - case 263: -#line 2566 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // A reference to a direct constant - (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].SInt64Val)); - CHECK_FOR_ERROR - ;} - break; - - case 264: -#line 2570 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].UInt64Val)); - CHECK_FOR_ERROR - ;} - break; - - case 265: -#line 2574 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // arbitrary precision integer constants - (yyval.ValIDVal) = ValID::create(*(yyvsp[(1) - (1)].APIntVal), true); - delete (yyvsp[(1) - (1)].APIntVal); - CHECK_FOR_ERROR - ;} - break; - - case 266: -#line 2579 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // arbitrary precision integer constants - (yyval.ValIDVal) = ValID::create(*(yyvsp[(1) - (1)].APIntVal), false); - delete (yyvsp[(1) - (1)].APIntVal); - CHECK_FOR_ERROR - ;} - break; - - case 267: -#line 2584 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Perhaps it's an FP constant? - (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].FPVal)); - CHECK_FOR_ERROR - ;} - break; - - case 268: -#line 2588 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::create(ConstantInt::getTrue()); - CHECK_FOR_ERROR - ;} - break; - - case 269: -#line 2592 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::create(ConstantInt::getFalse()); - CHECK_FOR_ERROR - ;} - break; - - case 270: -#line 2596 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::createNull(); - CHECK_FOR_ERROR - ;} - break; - - case 271: -#line 2600 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::createUndef(); - CHECK_FOR_ERROR - ;} - break; - - case 272: -#line 2604 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // A vector zero constant. - (yyval.ValIDVal) = ValID::createZeroInit(); - CHECK_FOR_ERROR - ;} - break; - - case 273: -#line 2608 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Nonempty unsized packed vector - const Type *ETy = (*(yyvsp[(2) - (3)].ConstVector))[0]->getType(); - unsigned NumElements = (yyvsp[(2) - (3)].ConstVector)->size(); - - if (!ETy->isInteger() && !ETy->isFloatingPoint()) - GEN_ERROR("Invalid vector element type: " + ETy->getDescription()); - - VectorType* pt = VectorType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt)); - - // Verify all elements are correct type! - for (unsigned i = 0; i < (yyvsp[(2) - (3)].ConstVector)->size(); i++) { - if (ETy != (*(yyvsp[(2) - (3)].ConstVector))[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '" + - (*(yyvsp[(2) - (3)].ConstVector))[i]->getType()->getDescription() + "'."); - } - - (yyval.ValIDVal) = ValID::create(ConstantVector::get(pt, *(yyvsp[(2) - (3)].ConstVector))); - delete PTy; delete (yyvsp[(2) - (3)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 274: -#line 2630 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Nonempty unsized arr - const Type *ETy = (*(yyvsp[(2) - (3)].ConstVector))[0]->getType(); - uint64_t NumElements = (yyvsp[(2) - (3)].ConstVector)->size(); - - if (!ETy->isFirstClassType()) - GEN_ERROR("Invalid array element type: " + ETy->getDescription()); - - ArrayType *ATy = ArrayType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy)); - - // Verify all elements are correct type! - for (unsigned i = 0; i < (yyvsp[(2) - (3)].ConstVector)->size(); i++) { - if (ETy != (*(yyvsp[(2) - (3)].ConstVector))[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*(yyvsp[(2) - (3)].ConstVector))[i]->getType()->getDescription() + "'."); - } - - (yyval.ValIDVal) = ValID::create(ConstantArray::get(ATy, *(yyvsp[(2) - (3)].ConstVector))); - delete PTy; delete (yyvsp[(2) - (3)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 275: -#line 2652 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // Use undef instead of an array because it's inconvenient to determine - // the element type at this point, there being no elements to examine. - (yyval.ValIDVal) = ValID::createUndef(); - CHECK_FOR_ERROR - ;} - break; - - case 276: -#line 2658 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - uint64_t NumElements = (yyvsp[(2) - (2)].StrVal)->length(); - const Type *ETy = Type::Int8Ty; - - ArrayType *ATy = ArrayType::get(ETy, NumElements); - - std::vector Vals; - for (unsigned i = 0; i < (yyvsp[(2) - (2)].StrVal)->length(); ++i) - Vals.push_back(ConstantInt::get(ETy, (*(yyvsp[(2) - (2)].StrVal))[i])); - delete (yyvsp[(2) - (2)].StrVal); - (yyval.ValIDVal) = ValID::create(ConstantArray::get(ATy, Vals)); - CHECK_FOR_ERROR - ;} - break; - - case 277: -#line 2671 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - std::vector Elements((yyvsp[(2) - (3)].ConstVector)->size()); - for (unsigned i = 0, e = (yyvsp[(2) - (3)].ConstVector)->size(); i != e; ++i) - Elements[i] = (*(yyvsp[(2) - (3)].ConstVector))[i]->getType(); - - const StructType *STy = StructType::get(Elements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); - - (yyval.ValIDVal) = ValID::create(ConstantStruct::get(STy, *(yyvsp[(2) - (3)].ConstVector))); - delete PTy; delete (yyvsp[(2) - (3)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 278: -#line 2683 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const StructType *STy = StructType::get(std::vector()); - (yyval.ValIDVal) = ValID::create(ConstantStruct::get(STy, std::vector())); - CHECK_FOR_ERROR - ;} - break; - - case 279: -#line 2688 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - std::vector Elements((yyvsp[(3) - (5)].ConstVector)->size()); - for (unsigned i = 0, e = (yyvsp[(3) - (5)].ConstVector)->size(); i != e; ++i) - Elements[i] = (*(yyvsp[(3) - (5)].ConstVector))[i]->getType(); - - const StructType *STy = StructType::get(Elements, /*isPacked=*/true); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); - - (yyval.ValIDVal) = ValID::create(ConstantStruct::get(STy, *(yyvsp[(3) - (5)].ConstVector))); - delete PTy; delete (yyvsp[(3) - (5)].ConstVector); - CHECK_FOR_ERROR - ;} - break; - - case 280: -#line 2700 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const StructType *STy = StructType::get(std::vector(), - /*isPacked=*/true); - (yyval.ValIDVal) = ValID::create(ConstantStruct::get(STy, std::vector())); - CHECK_FOR_ERROR - ;} - break; - - case 281: -#line 2706 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::create((yyvsp[(1) - (1)].ConstVal)); - CHECK_FOR_ERROR - ;} - break; - - case 282: -#line 2710 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::createInlineAsm(*(yyvsp[(3) - (5)].StrVal), *(yyvsp[(5) - (5)].StrVal), (yyvsp[(2) - (5)].BoolVal)); - delete (yyvsp[(3) - (5)].StrVal); - delete (yyvsp[(5) - (5)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 283: -#line 2720 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Is it an integer reference...? - (yyval.ValIDVal) = ValID::createLocalID((yyvsp[(1) - (1)].UIntVal)); - CHECK_FOR_ERROR - ;} - break; - - case 284: -#line 2724 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValIDVal) = ValID::createGlobalID((yyvsp[(1) - (1)].UIntVal)); - CHECK_FOR_ERROR - ;} - break; - - case 285: -#line 2728 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Is it a named reference...? - (yyval.ValIDVal) = ValID::createLocalName(*(yyvsp[(1) - (1)].StrVal)); - delete (yyvsp[(1) - (1)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 286: -#line 2733 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Is it a named reference...? - (yyval.ValIDVal) = ValID::createGlobalName(*(yyvsp[(1) - (1)].StrVal)); - delete (yyvsp[(1) - (1)].StrVal); - CHECK_FOR_ERROR - ;} - break; - - case 289: -#line 2746 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (2)].TypeVal))->getDescription()); - (yyval.ValueVal) = getVal(*(yyvsp[(1) - (2)].TypeVal), (yyvsp[(2) - (2)].ValIDVal)); - delete (yyvsp[(1) - (2)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 290: -#line 2755 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValueList) = new std::vector(); - (yyval.ValueList)->push_back((yyvsp[(1) - (1)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 291: -#line 2760 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - ((yyval.ValueList)=(yyvsp[(1) - (3)].ValueList))->push_back((yyvsp[(3) - (3)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 292: -#line 2765 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); - CHECK_FOR_ERROR - ;} - break; - - case 293: -#line 2769 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Do not allow functions with 0 basic blocks - (yyval.FunctionVal) = (yyvsp[(1) - (2)].FunctionVal); - CHECK_FOR_ERROR - ;} - break; - - case 294: -#line 2778 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - setValueName((yyvsp[(3) - (3)].TermInstVal), (yyvsp[(2) - (3)].StrVal)); - CHECK_FOR_ERROR - InsertValue((yyvsp[(3) - (3)].TermInstVal)); - (yyvsp[(1) - (3)].BasicBlockVal)->getInstList().push_back((yyvsp[(3) - (3)].TermInstVal)); - (yyval.BasicBlockVal) = (yyvsp[(1) - (3)].BasicBlockVal); - CHECK_FOR_ERROR - ;} - break; - - case 295: -#line 2787 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - int ValNum = InsertValue((yyvsp[(3) - (3)].TermInstVal)); - if (ValNum != (int)(yyvsp[(2) - (3)].UIntVal)) - GEN_ERROR("Result value number %" + utostr((yyvsp[(2) - (3)].UIntVal)) + - " is incorrect, expected %" + utostr((unsigned)ValNum)); - - (yyvsp[(1) - (3)].BasicBlockVal)->getInstList().push_back((yyvsp[(3) - (3)].TermInstVal)); - (yyval.BasicBlockVal) = (yyvsp[(1) - (3)].BasicBlockVal); - CHECK_FOR_ERROR -;} - break; - - case 296: -#line 2800 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (CastInst *CI1 = dyn_cast((yyvsp[(2) - (2)].InstVal))) - if (CastInst *CI2 = dyn_cast(CI1->getOperand(0))) - if (CI2->getParent() == 0) - (yyvsp[(1) - (2)].BasicBlockVal)->getInstList().push_back(CI2); - (yyvsp[(1) - (2)].BasicBlockVal)->getInstList().push_back((yyvsp[(2) - (2)].InstVal)); - (yyval.BasicBlockVal) = (yyvsp[(1) - (2)].BasicBlockVal); - CHECK_FOR_ERROR - ;} - break; - - case 297: -#line 2809 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Empty space between instruction lists - (yyval.BasicBlockVal) = defineBBVal(ValID::createLocalID(CurFun.NextValNum)); - CHECK_FOR_ERROR - ;} - break; - - case 298: -#line 2813 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Labelled (named) basic block - (yyval.BasicBlockVal) = defineBBVal(ValID::createLocalName(*(yyvsp[(1) - (1)].StrVal))); - delete (yyvsp[(1) - (1)].StrVal); - CHECK_FOR_ERROR - - ;} - break; - - case 299: -#line 2821 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Return with a result... - ValueList &VL = *(yyvsp[(2) - (2)].ValueList); - assert(!VL.empty() && "Invalid ret operands!"); - const Type *ReturnType = CurFun.CurrentFunction->getReturnType(); - if (VL.size() > 1 || - (isa(ReturnType) && - (VL.empty() || VL[0]->getType() != ReturnType))) { - Value *RV = UndefValue::get(ReturnType); - for (unsigned i = 0, e = VL.size(); i != e; ++i) { - Instruction *I = InsertValueInst::Create(RV, VL[i], i, "mrv"); - ((yyvsp[(-1) - (2)].BasicBlockVal))->getInstList().push_back(I); - RV = I; - } - (yyval.TermInstVal) = ReturnInst::Create(RV); - } else { - (yyval.TermInstVal) = ReturnInst::Create(VL[0]); - } - delete (yyvsp[(2) - (2)].ValueList); - CHECK_FOR_ERROR - ;} - break; - - case 300: -#line 2841 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Return with no result... - (yyval.TermInstVal) = ReturnInst::Create(); - CHECK_FOR_ERROR - ;} - break; - - case 301: -#line 2845 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Unconditional Branch... - BasicBlock* tmpBB = getBBVal((yyvsp[(3) - (3)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.TermInstVal) = BranchInst::Create(tmpBB); - ;} - break; - - case 302: -#line 2850 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (cast((yyvsp[(2) - (9)].PrimType))->getBitWidth() != 1) - GEN_ERROR("Branch condition must have type i1"); - BasicBlock* tmpBBA = getBBVal((yyvsp[(6) - (9)].ValIDVal)); - CHECK_FOR_ERROR - BasicBlock* tmpBBB = getBBVal((yyvsp[(9) - (9)].ValIDVal)); - CHECK_FOR_ERROR - Value* tmpVal = getVal(Type::Int1Ty, (yyvsp[(3) - (9)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.TermInstVal) = BranchInst::Create(tmpBBA, tmpBBB, tmpVal); - ;} - break; - - case 303: -#line 2861 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - Value* tmpVal = getVal((yyvsp[(2) - (9)].PrimType), (yyvsp[(3) - (9)].ValIDVal)); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal((yyvsp[(6) - (9)].ValIDVal)); - CHECK_FOR_ERROR - SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, (yyvsp[(8) - (9)].JumpTable)->size()); - (yyval.TermInstVal) = S; - - std::vector >::iterator I = (yyvsp[(8) - (9)].JumpTable)->begin(), - E = (yyvsp[(8) - (9)].JumpTable)->end(); - for (; I != E; ++I) { - if (ConstantInt *CI = dyn_cast(I->first)) - S->addCase(CI, I->second); - else - GEN_ERROR("Switch case is constant, but not a simple integer"); - } - delete (yyvsp[(8) - (9)].JumpTable); - CHECK_FOR_ERROR - ;} - break; - - case 304: -#line 2880 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - Value* tmpVal = getVal((yyvsp[(2) - (8)].PrimType), (yyvsp[(3) - (8)].ValIDVal)); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal((yyvsp[(6) - (8)].ValIDVal)); - CHECK_FOR_ERROR - SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, 0); - (yyval.TermInstVal) = S; - CHECK_FOR_ERROR - ;} - break; - - case 305: -#line 2890 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - - // Handle the short syntax - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast((yyvsp[(4) - (15)].TypeVal)->get())) || - !(Ty = dyn_cast(PFTy->getElementType()))) { - // Pull out the types of all of the arguments... - std::vector ParamTypes; - ParamList::iterator I = (yyvsp[(7) - (15)].ParamList)->begin(), E = (yyvsp[(7) - (15)].ParamList)->end(); - for (; I != E; ++I) { - const Type *Ty = I->Val->getType(); - if (Ty == Type::VoidTy) - GEN_ERROR("Short call syntax cannot be used with varargs"); - ParamTypes.push_back(Ty); - } - - if (!FunctionType::isValidReturnType(*(yyvsp[(4) - (15)].TypeVal))) - GEN_ERROR("Invalid result type for LLVM function"); - - Ty = FunctionType::get((yyvsp[(4) - (15)].TypeVal)->get(), ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); - } - - delete (yyvsp[(4) - (15)].TypeVal); - - Value *V = getVal(PFTy, (yyvsp[(5) - (15)].ValIDVal)); // Get the function we're calling... - CHECK_FOR_ERROR - BasicBlock *Normal = getBBVal((yyvsp[(12) - (15)].ValIDVal)); - CHECK_FOR_ERROR - BasicBlock *Except = getBBVal((yyvsp[(15) - (15)].ValIDVal)); - CHECK_FOR_ERROR - - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = (yyvsp[(3) - (15)].Attributes); - if ((yyvsp[(9) - (15)].Attributes) != Attribute::None) { - if ((yyvsp[(9) - (15)].Attributes) & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - (yyvsp[(9) - (15)].Attributes) = (yyvsp[(9) - (15)].Attributes) ^ Attribute::ZExt; - } - if ((yyvsp[(9) - (15)].Attributes) & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - (yyvsp[(9) - (15)].Attributes) = (yyvsp[(9) - (15)].Attributes) ^ Attribute::SExt; - } - if ((yyvsp[(9) - (15)].Attributes) & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - (yyvsp[(9) - (15)].Attributes) = (yyvsp[(9) - (15)].Attributes) ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - - // Check the arguments - ValueList Args; - if ((yyvsp[(7) - (15)].ParamList)->empty()) { // Has no arguments? - // Make sure no arguments is a good thing! - if (Ty->getNumParams() != 0) - GEN_ERROR("No arguments passed to a function that " - "expects arguments"); - } else { // Has arguments? - // Loop through FunctionType's arguments and ensure they are specified - // correctly! - FunctionType::param_iterator I = Ty->param_begin(); - FunctionType::param_iterator E = Ty->param_end(); - ParamList::iterator ArgI = (yyvsp[(7) - (15)].ParamList)->begin(), ArgE = (yyvsp[(7) - (15)].ParamList)->end(); - unsigned index = 1; - - for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { - if (ArgI->Val->getType() != *I) - GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + - (*I)->getDescription() + "'"); - Args.push_back(ArgI->Val); - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - - if (Ty->isVarArg()) { - if (I == E) - for (; ArgI != ArgE; ++ArgI, ++index) { - Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - } else if (I != E || ArgI != ArgE) - GEN_ERROR("Invalid number of parameters detected"); - } - if ((yyvsp[(9) - (15)].Attributes) != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, (yyvsp[(9) - (15)].Attributes))); - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - // Create the InvokeInst - InvokeInst *II = InvokeInst::Create(V, Normal, Except, - Args.begin(), Args.end()); - II->setCallingConv((yyvsp[(2) - (15)].UIntVal)); - II->setAttributes(PAL); - (yyval.TermInstVal) = II; - delete (yyvsp[(7) - (15)].ParamList); - CHECK_FOR_ERROR - ;} - break; - - case 306: -#line 2993 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TermInstVal) = new UnwindInst(); - CHECK_FOR_ERROR - ;} - break; - - case 307: -#line 2997 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.TermInstVal) = new UnreachableInst(); - CHECK_FOR_ERROR - ;} - break; - - case 308: -#line 3004 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.JumpTable) = (yyvsp[(1) - (6)].JumpTable); - Constant *V = cast(getExistingVal((yyvsp[(2) - (6)].PrimType), (yyvsp[(3) - (6)].ValIDVal))); - CHECK_FOR_ERROR - if (V == 0) - GEN_ERROR("May only switch on a constant pool value"); - - BasicBlock* tmpBB = getBBVal((yyvsp[(6) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.JumpTable)->push_back(std::make_pair(V, tmpBB)); - ;} - break; - - case 309: -#line 3015 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.JumpTable) = new std::vector >(); - Constant *V = cast(getExistingVal((yyvsp[(1) - (5)].PrimType), (yyvsp[(2) - (5)].ValIDVal))); - CHECK_FOR_ERROR - - if (V == 0) - GEN_ERROR("May only switch on a constant pool value"); - - BasicBlock* tmpBB = getBBVal((yyvsp[(5) - (5)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.JumpTable)->push_back(std::make_pair(V, tmpBB)); - ;} - break; - - case 310: -#line 3028 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // Is this definition named?? if so, assign the name... - setValueName((yyvsp[(2) - (2)].InstVal), (yyvsp[(1) - (2)].StrVal)); - CHECK_FOR_ERROR - InsertValue((yyvsp[(2) - (2)].InstVal)); - (yyval.InstVal) = (yyvsp[(2) - (2)].InstVal); - CHECK_FOR_ERROR - ;} - break; - - case 311: -#line 3037 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - CHECK_FOR_ERROR - int ValNum = InsertValue((yyvsp[(2) - (2)].InstVal)); - - if (ValNum != (int)(yyvsp[(1) - (2)].UIntVal)) - GEN_ERROR("Result value number %" + utostr((yyvsp[(1) - (2)].UIntVal)) + - " is incorrect, expected %" + utostr((unsigned)ValNum)); - - (yyval.InstVal) = (yyvsp[(2) - (2)].InstVal); - CHECK_FOR_ERROR - ;} - break; - - case 312: -#line 3050 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { // Used for PHI nodes - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (6)].TypeVal))->getDescription()); - (yyval.PHIList) = new std::list >(); - Value* tmpVal = getVal(*(yyvsp[(1) - (6)].TypeVal), (yyvsp[(3) - (6)].ValIDVal)); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal((yyvsp[(5) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.PHIList)->push_back(std::make_pair(tmpVal, tmpBB)); - delete (yyvsp[(1) - (6)].TypeVal); - ;} - break; - - case 313: -#line 3061 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.PHIList) = (yyvsp[(1) - (7)].PHIList); - Value* tmpVal = getVal((yyvsp[(1) - (7)].PHIList)->front().first->getType(), (yyvsp[(4) - (7)].ValIDVal)); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal((yyvsp[(6) - (7)].ValIDVal)); - CHECK_FOR_ERROR - (yyvsp[(1) - (7)].PHIList)->push_back(std::make_pair(tmpVal, tmpBB)); - ;} - break; - - case 314: -#line 3071 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(1) - (4)].TypeVal))->getDescription()); - // Used for call and invoke instructions - (yyval.ParamList) = new ParamList(); - ParamListEntry E; E.Attrs = (yyvsp[(2) - (4)].Attributes) | (yyvsp[(4) - (4)].Attributes); E.Val = getVal((yyvsp[(1) - (4)].TypeVal)->get(), (yyvsp[(3) - (4)].ValIDVal)); - (yyval.ParamList)->push_back(E); - delete (yyvsp[(1) - (4)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 315: -#line 3082 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - // Labels are only valid in ASMs - (yyval.ParamList) = new ParamList(); - ParamListEntry E; E.Attrs = (yyvsp[(2) - (4)].Attributes) | (yyvsp[(4) - (4)].Attributes); E.Val = getBBVal((yyvsp[(3) - (4)].ValIDVal)); - (yyval.ParamList)->push_back(E); - CHECK_FOR_ERROR - ;} - break; - - case 316: -#line 3090 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); - (yyval.ParamList) = (yyvsp[(1) - (6)].ParamList); - ParamListEntry E; E.Attrs = (yyvsp[(4) - (6)].Attributes) | (yyvsp[(6) - (6)].Attributes); E.Val = getVal((yyvsp[(3) - (6)].TypeVal)->get(), (yyvsp[(5) - (6)].ValIDVal)); - (yyval.ParamList)->push_back(E); - delete (yyvsp[(3) - (6)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 317: -#line 3100 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - (yyval.ParamList) = (yyvsp[(1) - (6)].ParamList); - ParamListEntry E; E.Attrs = (yyvsp[(4) - (6)].Attributes) | (yyvsp[(6) - (6)].Attributes); E.Val = getBBVal((yyvsp[(5) - (6)].ValIDVal)); - (yyval.ParamList)->push_back(E); - CHECK_FOR_ERROR - ;} - break; - - case 318: -#line 3107 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.ParamList) = new ParamList(); ;} - break; - - case 319: -#line 3110 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { (yyval.ValueList) = new std::vector(); ;} - break; - - case 320: -#line 3111 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ValueList) = (yyvsp[(1) - (3)].ValueList); - (yyval.ValueList)->push_back((yyvsp[(3) - (3)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 321: -#line 3119 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ConstantList) = new std::vector(); - if ((unsigned)(yyvsp[(2) - (2)].UInt64Val) != (yyvsp[(2) - (2)].UInt64Val)) - GEN_ERROR("Index " + utostr((yyvsp[(2) - (2)].UInt64Val)) + " is not valid for insertvalue or extractvalue."); - (yyval.ConstantList)->push_back((yyvsp[(2) - (2)].UInt64Val)); - ;} - break; - - case 322: -#line 3125 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.ConstantList) = (yyvsp[(1) - (3)].ConstantList); - if ((unsigned)(yyvsp[(3) - (3)].UInt64Val) != (yyvsp[(3) - (3)].UInt64Val)) - GEN_ERROR("Index " + utostr((yyvsp[(3) - (3)].UInt64Val)) + " is not valid for insertvalue or extractvalue."); - (yyval.ConstantList)->push_back((yyvsp[(3) - (3)].UInt64Val)); - CHECK_FOR_ERROR - ;} - break; - - case 323: -#line 3134 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.BoolVal) = true; - CHECK_FOR_ERROR - ;} - break; - - case 324: -#line 3138 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.BoolVal) = false; - CHECK_FOR_ERROR - ;} - break; - - case 325: -#line 3143 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); - if (!(*(yyvsp[(2) - (5)].TypeVal))->isInteger() && !(*(yyvsp[(2) - (5)].TypeVal))->isFloatingPoint() && - !isa((*(yyvsp[(2) - (5)].TypeVal)).get())) - GEN_ERROR( - "Arithmetic operator requires integer, FP, or packed operands"); - Value* val1 = getVal(*(yyvsp[(2) - (5)].TypeVal), (yyvsp[(3) - (5)].ValIDVal)); - CHECK_FOR_ERROR - Value* val2 = getVal(*(yyvsp[(2) - (5)].TypeVal), (yyvsp[(5) - (5)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = BinaryOperator::Create((yyvsp[(1) - (5)].BinaryOpVal), val1, val2); - if ((yyval.InstVal) == 0) - GEN_ERROR("binary operator returned null"); - delete (yyvsp[(2) - (5)].TypeVal); - ;} - break; - - case 326: -#line 3159 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); - if (!(*(yyvsp[(2) - (5)].TypeVal))->isInteger()) { - if (!isa((yyvsp[(2) - (5)].TypeVal)->get()) || - !cast((yyvsp[(2) - (5)].TypeVal)->get())->getElementType()->isInteger()) - GEN_ERROR("Logical operator requires integral operands"); - } - Value* tmpVal1 = getVal(*(yyvsp[(2) - (5)].TypeVal), (yyvsp[(3) - (5)].ValIDVal)); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[(2) - (5)].TypeVal), (yyvsp[(5) - (5)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = BinaryOperator::Create((yyvsp[(1) - (5)].BinaryOpVal), tmpVal1, tmpVal2); - if ((yyval.InstVal) == 0) - GEN_ERROR("binary operator returned null"); - delete (yyvsp[(2) - (5)].TypeVal); - ;} - break; - - case 327: -#line 3176 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); - Value* tmpVal1 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(4) - (6)].ValIDVal)); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(6) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = CmpInst::Create((yyvsp[(1) - (6)].OtherOpVal), (yyvsp[(2) - (6)].IPredicate), tmpVal1, tmpVal2); - if ((yyval.InstVal) == 0) - GEN_ERROR("icmp operator returned null"); - delete (yyvsp[(3) - (6)].TypeVal); - ;} - break; - - case 328: -#line 3188 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); - Value* tmpVal1 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(4) - (6)].ValIDVal)); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(6) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = CmpInst::Create((yyvsp[(1) - (6)].OtherOpVal), (yyvsp[(2) - (6)].FPredicate), tmpVal1, tmpVal2); - if ((yyval.InstVal) == 0) - GEN_ERROR("fcmp operator returned null"); - delete (yyvsp[(3) - (6)].TypeVal); - ;} - break; - - case 329: -#line 3200 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); - if (!isa((*(yyvsp[(3) - (6)].TypeVal)).get())) - GEN_ERROR("Scalar types not supported by vicmp instruction"); - Value* tmpVal1 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(4) - (6)].ValIDVal)); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(6) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = CmpInst::Create((yyvsp[(1) - (6)].OtherOpVal), (yyvsp[(2) - (6)].IPredicate), tmpVal1, tmpVal2); - if ((yyval.InstVal) == 0) - GEN_ERROR("vicmp operator returned null"); - delete (yyvsp[(3) - (6)].TypeVal); - ;} - break; - - case 330: -#line 3214 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (6)].TypeVal))->getDescription()); - if (!isa((*(yyvsp[(3) - (6)].TypeVal)).get())) - GEN_ERROR("Scalar types not supported by vfcmp instruction"); - Value* tmpVal1 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(4) - (6)].ValIDVal)); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*(yyvsp[(3) - (6)].TypeVal), (yyvsp[(6) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = CmpInst::Create((yyvsp[(1) - (6)].OtherOpVal), (yyvsp[(2) - (6)].FPredicate), tmpVal1, tmpVal2); - if ((yyval.InstVal) == 0) - GEN_ERROR("vfcmp operator returned null"); - delete (yyvsp[(3) - (6)].TypeVal); - ;} - break; - - case 331: -#line 3228 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(4) - (4)].TypeVal))->getDescription()); - Value* Val = (yyvsp[(2) - (4)].ValueVal); - const Type* DestTy = (yyvsp[(4) - (4)].TypeVal)->get(); - if (!CastInst::castIsValid((yyvsp[(1) - (4)].CastOpVal), Val, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - (yyval.InstVal) = CastInst::Create((yyvsp[(1) - (4)].CastOpVal), Val, DestTy); - delete (yyvsp[(4) - (4)].TypeVal); - ;} - break; - - case 332: -#line 3240 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (isa((yyvsp[(2) - (6)].ValueVal)->getType())) { - // vector select - if (!isa((yyvsp[(4) - (6)].ValueVal)->getType()) - || !isa((yyvsp[(6) - (6)].ValueVal)->getType()) ) - GEN_ERROR("vector select value types must be vector types"); - const VectorType* cond_type = cast((yyvsp[(2) - (6)].ValueVal)->getType()); - const VectorType* select_type = cast((yyvsp[(4) - (6)].ValueVal)->getType()); - if (cond_type->getElementType() != Type::Int1Ty) - GEN_ERROR("vector select condition element type must be boolean"); - if (cond_type->getNumElements() != select_type->getNumElements()) - GEN_ERROR("vector select number of elements must be the same"); - } else { - if ((yyvsp[(2) - (6)].ValueVal)->getType() != Type::Int1Ty) - GEN_ERROR("select condition must be boolean"); - } - if ((yyvsp[(4) - (6)].ValueVal)->getType() != (yyvsp[(6) - (6)].ValueVal)->getType()) - GEN_ERROR("select value types must match"); - (yyval.InstVal) = SelectInst::Create((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 333: -#line 3261 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(4) - (4)].TypeVal))->getDescription()); - (yyval.InstVal) = new VAArgInst((yyvsp[(2) - (4)].ValueVal), *(yyvsp[(4) - (4)].TypeVal)); - delete (yyvsp[(4) - (4)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 334: -#line 3268 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!ExtractElementInst::isValidOperands((yyvsp[(2) - (4)].ValueVal), (yyvsp[(4) - (4)].ValueVal))) - GEN_ERROR("Invalid extractelement operands"); - (yyval.InstVal) = new ExtractElementInst((yyvsp[(2) - (4)].ValueVal), (yyvsp[(4) - (4)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 335: -#line 3274 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!InsertElementInst::isValidOperands((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal))) - GEN_ERROR("Invalid insertelement operands"); - (yyval.InstVal) = InsertElementInst::Create((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 336: -#line 3280 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!ShuffleVectorInst::isValidOperands((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal))) - GEN_ERROR("Invalid shufflevector operands"); - (yyval.InstVal) = new ShuffleVectorInst((yyvsp[(2) - (6)].ValueVal), (yyvsp[(4) - (6)].ValueVal), (yyvsp[(6) - (6)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 337: -#line 3286 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - const Type *Ty = (yyvsp[(2) - (2)].PHIList)->front().first->getType(); - if (!Ty->isFirstClassType()) - GEN_ERROR("PHI node operands must be of first class type"); - (yyval.InstVal) = PHINode::Create(Ty); - ((PHINode*)(yyval.InstVal))->reserveOperandSpace((yyvsp[(2) - (2)].PHIList)->size()); - while ((yyvsp[(2) - (2)].PHIList)->begin() != (yyvsp[(2) - (2)].PHIList)->end()) { - if ((yyvsp[(2) - (2)].PHIList)->front().first->getType() != Ty) - GEN_ERROR("All elements of a PHI node must be of the same type"); - cast((yyval.InstVal))->addIncoming((yyvsp[(2) - (2)].PHIList)->front().first, (yyvsp[(2) - (2)].PHIList)->front().second); - (yyvsp[(2) - (2)].PHIList)->pop_front(); - } - delete (yyvsp[(2) - (2)].PHIList); // Free the list... - CHECK_FOR_ERROR - ;} - break; - - case 338: -#line 3302 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - - // Handle the short syntax - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast((yyvsp[(4) - (9)].TypeVal)->get())) || - !(Ty = dyn_cast(PFTy->getElementType()))) { - // Pull out the types of all of the arguments... - std::vector ParamTypes; - ParamList::iterator I = (yyvsp[(7) - (9)].ParamList)->begin(), E = (yyvsp[(7) - (9)].ParamList)->end(); - for (; I != E; ++I) { - const Type *Ty = I->Val->getType(); - if (Ty == Type::VoidTy) - GEN_ERROR("Short call syntax cannot be used with varargs"); - ParamTypes.push_back(Ty); - } - - if (!FunctionType::isValidReturnType(*(yyvsp[(4) - (9)].TypeVal))) - GEN_ERROR("Invalid result type for LLVM function"); - - Ty = FunctionType::get((yyvsp[(4) - (9)].TypeVal)->get(), ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); - } - - Value *V = getVal(PFTy, (yyvsp[(5) - (9)].ValIDVal)); // Get the function we're calling... - CHECK_FOR_ERROR - - // Check for call to invalid intrinsic to avoid crashing later. - if (Function *theF = dyn_cast(V)) { - if (theF->hasName() && (theF->getValueName()->getKeyLength() >= 5) && - (0 == strncmp(theF->getValueName()->getKeyData(), "llvm.", 5)) && - !theF->getIntrinsicID(true)) - GEN_ERROR("Call to invalid LLVM intrinsic function '" + - theF->getName() + "'"); - } - - // Set up the Attributes for the function - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = (yyvsp[(3) - (9)].Attributes); - if ((yyvsp[(9) - (9)].Attributes) != Attribute::None) { - if ((yyvsp[(9) - (9)].Attributes) & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - (yyvsp[(9) - (9)].Attributes) = (yyvsp[(9) - (9)].Attributes) ^ Attribute::ZExt; - } - if ((yyvsp[(9) - (9)].Attributes) & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - (yyvsp[(9) - (9)].Attributes) = (yyvsp[(9) - (9)].Attributes) ^ Attribute::SExt; - } - if ((yyvsp[(9) - (9)].Attributes) & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - (yyvsp[(9) - (9)].Attributes) = (yyvsp[(9) - (9)].Attributes) ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - - // Check the arguments - ValueList Args; - if ((yyvsp[(7) - (9)].ParamList)->empty()) { // Has no arguments? - // Make sure no arguments is a good thing! - if (Ty->getNumParams() != 0) - GEN_ERROR("No arguments passed to a function that " - "expects arguments"); - } else { // Has arguments? - // Loop through FunctionType's arguments and ensure they are specified - // correctly. Also, gather any parameter attributes. - FunctionType::param_iterator I = Ty->param_begin(); - FunctionType::param_iterator E = Ty->param_end(); - ParamList::iterator ArgI = (yyvsp[(7) - (9)].ParamList)->begin(), ArgE = (yyvsp[(7) - (9)].ParamList)->end(); - unsigned index = 1; - - for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { - if (ArgI->Val->getType() != *I) - GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + - (*I)->getDescription() + "'"); - Args.push_back(ArgI->Val); - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - if (Ty->isVarArg()) { - if (I == E) - for (; ArgI != ArgE; ++ArgI, ++index) { - Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - } else if (I != E || ArgI != ArgE) - GEN_ERROR("Invalid number of parameters detected"); - } - if ((yyvsp[(9) - (9)].Attributes) != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, (yyvsp[(9) - (9)].Attributes))); - - // Finish off the Attributes and check them - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - // Create the call node - CallInst *CI = CallInst::Create(V, Args.begin(), Args.end()); - CI->setTailCall((yyvsp[(1) - (9)].BoolVal)); - CI->setCallingConv((yyvsp[(2) - (9)].UIntVal)); - CI->setAttributes(PAL); - (yyval.InstVal) = CI; - delete (yyvsp[(7) - (9)].ParamList); - delete (yyvsp[(4) - (9)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 339: -#line 3411 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.InstVal) = (yyvsp[(1) - (1)].InstVal); - CHECK_FOR_ERROR - ;} - break; - - case 340: -#line 3416 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.BoolVal) = true; - CHECK_FOR_ERROR - ;} - break; - - case 341: -#line 3420 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - (yyval.BoolVal) = false; - CHECK_FOR_ERROR - ;} - break; - - case 342: -#line 3427 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (3)].TypeVal))->getDescription()); - (yyval.InstVal) = new MallocInst(*(yyvsp[(2) - (3)].TypeVal), 0, (yyvsp[(3) - (3)].UIntVal)); - delete (yyvsp[(2) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 343: -#line 3434 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (6)].TypeVal))->getDescription()); - if ((yyvsp[(4) - (6)].PrimType) != Type::Int32Ty) - GEN_ERROR("Malloc array size is not a 32-bit integer!"); - Value* tmpVal = getVal((yyvsp[(4) - (6)].PrimType), (yyvsp[(5) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = new MallocInst(*(yyvsp[(2) - (6)].TypeVal), tmpVal, (yyvsp[(6) - (6)].UIntVal)); - delete (yyvsp[(2) - (6)].TypeVal); - ;} - break; - - case 344: -#line 3444 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (3)].TypeVal))->getDescription()); - (yyval.InstVal) = new AllocaInst(*(yyvsp[(2) - (3)].TypeVal), 0, (yyvsp[(3) - (3)].UIntVal)); - delete (yyvsp[(2) - (3)].TypeVal); - CHECK_FOR_ERROR - ;} - break; - - case 345: -#line 3451 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (6)].TypeVal))->getDescription()); - if ((yyvsp[(4) - (6)].PrimType) != Type::Int32Ty) - GEN_ERROR("Alloca array size is not a 32-bit integer!"); - Value* tmpVal = getVal((yyvsp[(4) - (6)].PrimType), (yyvsp[(5) - (6)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = new AllocaInst(*(yyvsp[(2) - (6)].TypeVal), tmpVal, (yyvsp[(6) - (6)].UIntVal)); - delete (yyvsp[(2) - (6)].TypeVal); - ;} - break; - - case 346: -#line 3461 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!isa((yyvsp[(2) - (2)].ValueVal)->getType())) - GEN_ERROR("Trying to free nonpointer type " + - (yyvsp[(2) - (2)].ValueVal)->getType()->getDescription() + ""); - (yyval.InstVal) = new FreeInst((yyvsp[(2) - (2)].ValueVal)); - CHECK_FOR_ERROR - ;} - break; - - case 347: -#line 3469 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); - if (!isa((yyvsp[(3) - (5)].TypeVal)->get())) - GEN_ERROR("Can't load from nonpointer type: " + - (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); - if (!cast((yyvsp[(3) - (5)].TypeVal)->get())->getElementType()->isFirstClassType()) - GEN_ERROR("Can't load from pointer of non-first-class type: " + - (*(yyvsp[(3) - (5)].TypeVal))->getDescription()); - Value* tmpVal = getVal(*(yyvsp[(3) - (5)].TypeVal), (yyvsp[(4) - (5)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = new LoadInst(tmpVal, "", (yyvsp[(1) - (5)].BoolVal), (yyvsp[(5) - (5)].UIntVal)); - delete (yyvsp[(3) - (5)].TypeVal); - ;} - break; - - case 348: -#line 3483 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(5) - (7)].TypeVal))->getDescription()); - const PointerType *PT = dyn_cast((yyvsp[(5) - (7)].TypeVal)->get()); - if (!PT) - GEN_ERROR("Can't store to a nonpointer type: " + - (*(yyvsp[(5) - (7)].TypeVal))->getDescription()); - const Type *ElTy = PT->getElementType(); - if (ElTy != (yyvsp[(3) - (7)].ValueVal)->getType()) - GEN_ERROR("Can't store '" + (yyvsp[(3) - (7)].ValueVal)->getType()->getDescription() + - "' into space of type '" + ElTy->getDescription() + "'"); - - Value* tmpVal = getVal(*(yyvsp[(5) - (7)].TypeVal), (yyvsp[(6) - (7)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = new StoreInst((yyvsp[(3) - (7)].ValueVal), tmpVal, (yyvsp[(1) - (7)].BoolVal), (yyvsp[(7) - (7)].UIntVal)); - delete (yyvsp[(5) - (7)].TypeVal); - ;} - break; - - case 349: -#line 3500 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (5)].TypeVal))->getDescription()); - if (!isa((yyvsp[(2) - (5)].TypeVal)->get()) && !isa((yyvsp[(2) - (5)].TypeVal)->get())) - GEN_ERROR("getresult insn requires an aggregate operand"); - if (!ExtractValueInst::getIndexedType(*(yyvsp[(2) - (5)].TypeVal), (yyvsp[(5) - (5)].UInt64Val))) - GEN_ERROR("Invalid getresult index for type '" + - (*(yyvsp[(2) - (5)].TypeVal))->getDescription()+ "'"); - - Value *tmpVal = getVal(*(yyvsp[(2) - (5)].TypeVal), (yyvsp[(3) - (5)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = ExtractValueInst::Create(tmpVal, (yyvsp[(5) - (5)].UInt64Val)); - delete (yyvsp[(2) - (5)].TypeVal); - ;} - break; - - case 350: -#line 3514 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (4)].TypeVal))->getDescription()); - if (!isa((yyvsp[(2) - (4)].TypeVal)->get())) - GEN_ERROR("getelementptr insn requires pointer operand"); - - if (!GetElementPtrInst::getIndexedType(*(yyvsp[(2) - (4)].TypeVal), (yyvsp[(4) - (4)].ValueList)->begin(), (yyvsp[(4) - (4)].ValueList)->end())) - GEN_ERROR("Invalid getelementptr indices for type '" + - (*(yyvsp[(2) - (4)].TypeVal))->getDescription()+ "'"); - Value* tmpVal = getVal(*(yyvsp[(2) - (4)].TypeVal), (yyvsp[(3) - (4)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = GetElementPtrInst::Create(tmpVal, (yyvsp[(4) - (4)].ValueList)->begin(), (yyvsp[(4) - (4)].ValueList)->end()); - delete (yyvsp[(2) - (4)].TypeVal); - delete (yyvsp[(4) - (4)].ValueList); - ;} - break; - - case 351: -#line 3529 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (4)].TypeVal))->getDescription()); - if (!isa((yyvsp[(2) - (4)].TypeVal)->get()) && !isa((yyvsp[(2) - (4)].TypeVal)->get())) - GEN_ERROR("extractvalue insn requires an aggregate operand"); - - if (!ExtractValueInst::getIndexedType(*(yyvsp[(2) - (4)].TypeVal), (yyvsp[(4) - (4)].ConstantList)->begin(), (yyvsp[(4) - (4)].ConstantList)->end())) - GEN_ERROR("Invalid extractvalue indices for type '" + - (*(yyvsp[(2) - (4)].TypeVal))->getDescription()+ "'"); - Value* tmpVal = getVal(*(yyvsp[(2) - (4)].TypeVal), (yyvsp[(3) - (4)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = ExtractValueInst::Create(tmpVal, (yyvsp[(4) - (4)].ConstantList)->begin(), (yyvsp[(4) - (4)].ConstantList)->end()); - delete (yyvsp[(2) - (4)].TypeVal); - delete (yyvsp[(4) - (4)].ConstantList); - ;} - break; - - case 352: -#line 3544 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*(yyvsp[(2) - (7)].TypeVal))->getDescription()); - if (!isa((yyvsp[(2) - (7)].TypeVal)->get()) && !isa((yyvsp[(2) - (7)].TypeVal)->get())) - GEN_ERROR("extractvalue insn requires an aggregate operand"); - - if (ExtractValueInst::getIndexedType(*(yyvsp[(2) - (7)].TypeVal), (yyvsp[(7) - (7)].ConstantList)->begin(), (yyvsp[(7) - (7)].ConstantList)->end()) != (yyvsp[(5) - (7)].TypeVal)->get()) - GEN_ERROR("Invalid insertvalue indices for type '" + - (*(yyvsp[(2) - (7)].TypeVal))->getDescription()+ "'"); - Value* aggVal = getVal(*(yyvsp[(2) - (7)].TypeVal), (yyvsp[(3) - (7)].ValIDVal)); - Value* tmpVal = getVal(*(yyvsp[(5) - (7)].TypeVal), (yyvsp[(6) - (7)].ValIDVal)); - CHECK_FOR_ERROR - (yyval.InstVal) = InsertValueInst::Create(aggVal, tmpVal, (yyvsp[(7) - (7)].ConstantList)->begin(), (yyvsp[(7) - (7)].ConstantList)->end()); - delete (yyvsp[(2) - (7)].TypeVal); - delete (yyvsp[(5) - (7)].TypeVal); - delete (yyvsp[(7) - (7)].ConstantList); - ;} - break; - - -/* Line 1267 of yacc.c. */ -#line 7087 "llvmAsmParser.tab.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -#line 3563 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" - - -// common code from the two 'RunVMAsmParser' functions -static Module* RunParser(Module * M) { - CurModule.CurrentModule = M; - // Check to make sure the parser succeeded - if (yyparse()) { - if (ParserResult) - delete ParserResult; - return 0; - } - - // Emit an error if there are any unresolved types left. - if (!CurModule.LateResolveTypes.empty()) { - const ValID &DID = CurModule.LateResolveTypes.begin()->first; - if (DID.Type == ValID::LocalName) { - GenerateError("Undefined type remains at eof: '"+DID.getName() + "'"); - } else { - GenerateError("Undefined type remains at eof: #" + itostr(DID.Num)); - } - if (ParserResult) - delete ParserResult; - return 0; - } - - // Emit an error if there are any unresolved values left. - if (!CurModule.LateResolveValues.empty()) { - Value *V = CurModule.LateResolveValues.back(); - std::map >::iterator I = - CurModule.PlaceHolderInfo.find(V); - - if (I != CurModule.PlaceHolderInfo.end()) { - ValID &DID = I->second.first; - if (DID.Type == ValID::LocalName) { - GenerateError("Undefined value remains at eof: "+DID.getName() + "'"); - } else { - GenerateError("Undefined value remains at eof: #" + itostr(DID.Num)); - } - if (ParserResult) - delete ParserResult; - return 0; - } - } - - // Check to make sure that parsing produced a result - if (!ParserResult) - return 0; - - // Reset ParserResult variable while saving its value for the result. - Module *Result = ParserResult; - ParserResult = 0; - - return Result; -} - -void llvm::GenerateError(const std::string &message, int LineNo) { - if (LineNo == -1) LineNo = LLLgetLineNo(); - // TODO: column number in exception - if (TheParseError) - TheParseError->setError(LLLgetFilename(), message, LineNo); - TriggerError = 1; -} - -int yyerror(const char *ErrorMsg) { - std::string where = LLLgetFilename() + ":" + utostr(LLLgetLineNo()) + ": "; - std::string errMsg = where + "error: " + std::string(ErrorMsg); - if (yychar != YYEMPTY && yychar != 0) { - errMsg += " while reading token: '"; - errMsg += std::string(LLLgetTokenStart(), - LLLgetTokenStart()+LLLgetTokenLength()) + "'"; - } - GenerateError(errMsg); - return 0; -} - diff --git a/lib/AsmParser/llvmAsmParser.h.cvs b/lib/AsmParser/llvmAsmParser.h.cvs deleted file mode 100644 index 9df712ef595..00000000000 --- a/lib/AsmParser/llvmAsmParser.h.cvs +++ /dev/null @@ -1,426 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface 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. */ - -/* 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 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 986 "/home/nicholas/llvm-commit/lib/AsmParser/llvmAsmParser.y" -{ - llvm::Module *ModuleVal; - llvm::Function *FunctionVal; - llvm::BasicBlock *BasicBlockVal; - llvm::TerminatorInst *TermInstVal; - llvm::Instruction *InstVal; - llvm::Constant *ConstVal; - - const llvm::Type *PrimType; - std::list *TypeList; - llvm::PATypeHolder *TypeVal; - llvm::Value *ValueVal; - std::vector *ValueList; - std::vector *ConstantList; - llvm::ArgListType *ArgList; - llvm::TypeWithAttrs TypeWithAttrs; - llvm::TypeWithAttrsList *TypeWithAttrsList; - llvm::ParamList *ParamList; - - // Represent the RHS of PHI node - std::list > *PHIList; - std::vector > *JumpTable; - std::vector *ConstVector; - - llvm::GlobalValue::LinkageTypes Linkage; - llvm::GlobalValue::VisibilityTypes Visibility; - llvm::Attributes Attributes; - llvm::APInt *APIntVal; - int64_t SInt64Val; - uint64_t UInt64Val; - int SIntVal; - unsigned UIntVal; - llvm::APFloat *FPVal; - bool BoolVal; - - std::string *StrVal; // This memory must be deleted - llvm::ValID ValIDVal; - - llvm::Instruction::BinaryOps BinaryOpVal; - llvm::Instruction::TermOps TermOpVal; - llvm::Instruction::MemoryOps MemOpVal; - llvm::Instruction::CastOps CastOpVal; - llvm::Instruction::OtherOps OtherOpVal; - llvm::ICmpInst::Predicate IPredicate; - llvm::FCmpInst::Predicate FPredicate; -} -/* Line 1489 of yacc.c. */ -#line 419 "llvmAsmParser.tab.h" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE llvmAsmlval; - diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y deleted file mode 100644 index 7028ea3fe0d..00000000000 --- a/lib/AsmParser/llvmAsmParser.y +++ /dev/null @@ -1,3636 +0,0 @@ -//===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the bison parser for LLVM assembly languages files. -// -//===----------------------------------------------------------------------===// - -%{ -#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 -#include -#include -#include - -// 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 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 Types; - std::map 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 > PlaceHolderInfo; - - // GlobalRefs - This maintains a mapping between '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, 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 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(Ty)) { - // Check to see if this is an unresolved type - std::map::iterator I = LateResolveTypes.begin(); - std::map::iterator E = LateResolveTypes.end(); - for ( ; I != E; ++I) { - if (I->second.get() == OpTy) - return true; - } - } else if (const SequentialType* SeqTy = dyn_cast(Ty)) { - const Type* TheTy = SeqTy->getElementType(); - if (TheTy->isAbstract() && TheTy != Ty) { - std::vector::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(Ty)) { - for (unsigned i = 0; i < StrTy->getNumElements(); ++i) { - const Type* TheTy = StrTy->getElementType(i); - if (TheTy->isAbstract() && TheTy != Ty) { - std::vector::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 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::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(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(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(Ty) && - ConstantInt::isValueValidForType(Ty, D.UConstPool64)) - return ConstantInt::get(Ty, D.UConstPool64); - - if (!isa(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(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(Ty)) { - GenerateError("Cannot create a a non pointer null"); - return 0; - } - return ConstantPointerNull::get(cast(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(Ty); - const FunctionType *FTy = - PTy ? dyn_cast(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(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(Ty); - if (!PTy) { - GenerateError("Invalid type for reference to global" ); - return 0; - } - const Type* ElTy = PTy->getElementType(); - if (const FunctionType *FTy = dyn_cast(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::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::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(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(CurFun.Values[ID.Num]); - else - GenerateError("Reference to label '%" + utostr(ID.Num) + - "' is actually of type '"+ - CurFun.Values[ID.Num]->getType()->getDescription() + "'"); - } - } else { - GenerateError("Illegal label reference " + ID.getName()); - return 0; - } - - // If its already been defined, return it now. - if (BB) { - ID.destroy(); // Free strdup'd memory. - return BB; - } - - // Otherwise, this block has not been seen before, create it. - std::string Name; - if (ID.Type == ValID::LocalName) - Name = ID.getName(); - BB = BasicBlock::Create(Name, CurFun.CurrentFunction); - - // Insert it in the forward refs map. - CurFun.BBForwardRefs[ID] = BB; - - 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(ValueList &LateResolvers, ValueList *FutureLateResolvers) { - // Loop over LateResolveDefs fixing up stuff that couldn't be resolved - while (!LateResolvers.empty()) { - Value *V = LateResolvers.back(); - LateResolvers.pop_back(); - - std::map >::iterator PHI = - CurModule.PlaceHolderInfo.find(V); - assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!"); - - ValID &DID = PHI->second.first; - - Value *TheRealValue = getExistingVal(V->getType(), DID); - if (TriggerError) - return; - 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::LocalName || DID.Type == ValID::GlobalName) { - GenerateError("Reference to an invalid definition: '" +DID.getName()+ - "' of type '" + V->getType()->getDescription() + "'", - PHI->second.second); - return; - } else { - GenerateError("Reference to an invalid definition: #" + - itostr(DID.Num) + " of type '" + - V->getType()->getDescription() + "'", - PHI->second.second); - return; - } - } - } - 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(std::string *Name, const Type *ToTy) { - ValID D; - if (Name) - D = ValID::createLocalName(*Name); - else - D = ValID::createLocalID(CurModule.Types.size()); - - std::map::iterator I = - CurModule.LateResolveTypes.find(D); - if (I != CurModule.LateResolveTypes.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); - I->first.destroy(); - CurModule.LateResolveTypes.erase(I); - } - D.destroy(); -} - -// 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, std::string *NameStr) { - if (!NameStr) return; - std::string Name(*NameStr); // Copy string - delete NameStr; // Free old string - - if (V->getType() == Type::VoidTy) { - GenerateError("Can't assign name '" + Name+"' to value with void type"); - return; - } - - assert(inFunctionScope() && "Must be in function scope!"); - ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable(); - if (ST.lookup(Name)) { - GenerateError("Redefinition of value '" + Name + "' of type '" + - V->getType()->getDescription() + "'"); - return; - } - - // 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(std::string *NameStr, - GlobalValue::LinkageTypes Linkage, - GlobalValue::VisibilityTypes Visibility, - bool isConstantGlobal, const Type *Ty, - Constant *Initializer, bool IsThreadLocal, - unsigned AddressSpace = 0) { - if (isa(Ty)) { - GenerateError("Cannot declare global vars of function type"); - return 0; - } - if (Ty == Type::LabelTy) { - GenerateError("Cannot declare global vars of label type"); - return 0; - } - - const PointerType *PTy = PointerType::get(Ty, AddressSpace); - - std::string Name; - if (NameStr) { - Name = *NameStr; // Copy string - delete NameStr; // Free old string - } - - // See if this global value was forward referenced. If so, recycle the - // object. - ValID ID; - if (!Name.empty()) { - ID = ValID::createGlobalName(Name); - } else { - ID = ValID::createGlobalID(CurModule.Values.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(FWGV); - CurModule.CurrentModule->getGlobalList().remove(GV); - CurModule.CurrentModule->getGlobalList().push_back(GV); - GV->setInitializer(Initializer); - GV->setLinkage(Linkage); - GV->setVisibility(Visibility); - GV->setConstant(isConstantGlobal); - GV->setThreadLocal(IsThreadLocal); - InsertValue(GV, CurModule.Values); - ID.destroy(); - return GV; - } - - ID.destroy(); - - // If this global has a name - if (!Name.empty()) { - // if the global we're parsing has an initializer (is a definition) and - // has external linkage. - if (Initializer && Linkage != GlobalValue::InternalLinkage) - // If there is already a global with external linkage with this name - if (CurModule.CurrentModule->getGlobalVariable(Name, false)) { - // If we allow this GVar to get created, it will be renamed in the - // symbol table because it conflicts with an existing GVar. We can't - // allow redefinition of GVars whose linking indicates that their name - // must stay the same. Issue the error. - GenerateError("Redefinition of global variable named '" + Name + - "' of type '" + Ty->getDescription() + "'"); - return 0; - } - } - - // Otherwise there is no existing GV to use, create one now. - GlobalVariable *GV = - new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, - CurModule.CurrentModule, IsThreadLocal, AddressSpace); - GV->setVisibility(Visibility); - 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, std::string *NameStr) { - assert(!inFunctionScope() && "Can't give types function-local names!"); - if (NameStr == 0) return false; - - std::string Name(*NameStr); // Copy string - delete NameStr; // Free old string - - // We don't allow assigning names to void type - if (T == Type::VoidTy) { - GenerateError("Can't assign name '" + Name + "' to the void type"); - return false; - } - - // 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(Existing)) { - // We ARE replacing an opaque type! - const_cast(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. - GenerateError("Redefinition of type named '" + Name + "' of type '" + - T->getDescription() + "'"); - } - - 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 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 isn't abstract, or if there are no up-references in it, then there is - // nothing to resolve here. - if (!ty->isAbstract() || UpRefs.empty()) 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; -} - -//===----------------------------------------------------------------------===// -// RunVMAsmParser - Define an interface to this parser -//===----------------------------------------------------------------------===// -// -static Module* RunParser(Module * M); - -Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { - InitLLLexer(MB); - Module *M = RunParser(new Module(LLLgetFilename())); - FreeLexer(); - return M; -} - -%} - -%union { - llvm::Module *ModuleVal; - llvm::Function *FunctionVal; - llvm::BasicBlock *BasicBlockVal; - llvm::TerminatorInst *TermInstVal; - llvm::Instruction *InstVal; - llvm::Constant *ConstVal; - - const llvm::Type *PrimType; - std::list *TypeList; - llvm::PATypeHolder *TypeVal; - llvm::Value *ValueVal; - std::vector *ValueList; - std::vector *ConstantList; - llvm::ArgListType *ArgList; - llvm::TypeWithAttrs TypeWithAttrs; - llvm::TypeWithAttrsList *TypeWithAttrsList; - llvm::ParamList *ParamList; - - // Represent the RHS of PHI node - std::list > *PHIList; - std::vector > *JumpTable; - std::vector *ConstVector; - - llvm::GlobalValue::LinkageTypes Linkage; - llvm::GlobalValue::VisibilityTypes Visibility; - llvm::Attributes Attributes; - llvm::APInt *APIntVal; - int64_t SInt64Val; - uint64_t UInt64Val; - int SIntVal; - unsigned UIntVal; - llvm::APFloat *FPVal; - bool BoolVal; - - std::string *StrVal; // This memory must be deleted - llvm::ValID ValIDVal; - - llvm::Instruction::BinaryOps BinaryOpVal; - llvm::Instruction::TermOps TermOpVal; - llvm::Instruction::MemoryOps MemOpVal; - llvm::Instruction::CastOps CastOpVal; - llvm::Instruction::OtherOps OtherOpVal; - llvm::ICmpInst::Predicate IPredicate; - llvm::FCmpInst::Predicate FPredicate; -} - -%type Module -%type Function FunctionProto FunctionHeader BasicBlockList -%type BasicBlock InstructionList -%type BBTerminatorInst -%type Inst InstVal MemoryInst -%type ConstVal ConstExpr AliaseeRef -%type ConstVector -%type ArgList ArgListH -%type PHIList -%type ParamList // For call param lists & GEP indices -%type IndexList // For GEP indices -%type ConstantIndexList // For insertvalue/extractvalue indices -%type TypeListI -%type ArgTypeList ArgTypeListI -%type ArgType -%type JumpTable -%type GlobalType // GLOBAL or CONSTANT? -%type ThreadLocal // 'thread_local' or not -%type OptVolatile // 'volatile' or not -%type OptTailCall // TAIL CALL or plain CALL. -%type OptSideEffect // 'sideeffect' or not. -%type GVInternalLinkage GVExternalLinkage -%type FunctionDefineLinkage FunctionDeclareLinkage -%type AliasLinkage -%type GVVisibilityStyle - -// ValueRef - Unresolved reference to a definition or BB -%type ValueRef ConstValueRef SymbolicValueRef -%type ResolvedVal // pair -%type ReturnedVal -// Tokens and types for handling constant integer values -// -// ESINT64VAL - A negative number within long long range -%token ESINT64VAL - -// EUINT64VAL - A positive number within uns. long long range -%token EUINT64VAL - -// ESAPINTVAL - A negative number with arbitrary precision -%token ESAPINTVAL - -// EUAPINTVAL - A positive number with arbitrary precision -%token EUAPINTVAL - -%token LOCALVAL_ID GLOBALVAL_ID // %123 @123 -%token FPVAL // Float or Double constant - -// Built in types... -%type Types ResultTypes -%type PrimType // Classifications -%token VOID INTTYPE -%token FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL -%token TYPE - - -%token LOCALVAR GLOBALVAR LABELSTR -%token STRINGCONSTANT ATSTRINGCONSTANT PCTSTRINGCONSTANT -%type LocalName OptLocalName OptLocalAssign -%type GlobalName OptGlobalAssign GlobalAssign -%type OptSection SectionString OptGC - -%type OptAlign OptCAlign OptAddrSpace - -%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK -%token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL -%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING -%token DLLIMPORT DLLEXPORT EXTERN_WEAK COMMON -%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE -%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT -%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK -%token DATALAYOUT -%type OptCallingConv LocalNumber -%type OptAttributes Attribute -%type OptFuncAttrs FuncAttr -%type OptRetAttrs RetAttr - -// Basic Block Terminating Operators -%token RET BR SWITCH INVOKE UNWIND UNREACHABLE - -// Binary Operators -%type ArithmeticOps LogicalOps // Binops Subcatagories -%token ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR -%token SHL LSHR ASHR - -%token ICMP FCMP VICMP VFCMP -%type IPredicates -%type FPredicates -%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE -%token OEQ ONE OLT OGT OLE OGE ORD UNO UEQ UNE - -// Memory Instructions -%token MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR - -// Cast Operators -%type CastOps -%token TRUNC ZEXT SEXT FPTRUNC FPEXT BITCAST -%token UITOFP SITOFP FPTOUI FPTOSI INTTOPTR PTRTOINT - -// Other Operators -%token PHI_TOK SELECT VAARG -%token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR -%token GETRESULT -%token EXTRACTVALUE INSERTVALUE - -// Function Attributes -%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS NOCAPTURE BYVAL -%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ NEST - -// Visibility Styles -%token DEFAULT HIDDEN PROTECTED - -%start Module -%% - - -// Operations that are notably excluded from this list include: -// RET, BR, & SWITCH because they end basic blocks and are treated specially. -// -ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM; -LogicalOps : SHL | LSHR | ASHR | AND | OR | XOR; -CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST | - UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT; - -IPredicates - : EQ { $$ = ICmpInst::ICMP_EQ; } | NE { $$ = ICmpInst::ICMP_NE; } - | SLT { $$ = ICmpInst::ICMP_SLT; } | SGT { $$ = ICmpInst::ICMP_SGT; } - | SLE { $$ = ICmpInst::ICMP_SLE; } | SGE { $$ = ICmpInst::ICMP_SGE; } - | ULT { $$ = ICmpInst::ICMP_ULT; } | UGT { $$ = ICmpInst::ICMP_UGT; } - | ULE { $$ = ICmpInst::ICMP_ULE; } | UGE { $$ = ICmpInst::ICMP_UGE; } - ; - -FPredicates - : OEQ { $$ = FCmpInst::FCMP_OEQ; } | ONE { $$ = FCmpInst::FCMP_ONE; } - | OLT { $$ = FCmpInst::FCMP_OLT; } | OGT { $$ = FCmpInst::FCMP_OGT; } - | OLE { $$ = FCmpInst::FCMP_OLE; } | OGE { $$ = FCmpInst::FCMP_OGE; } - | ORD { $$ = FCmpInst::FCMP_ORD; } | UNO { $$ = FCmpInst::FCMP_UNO; } - | UEQ { $$ = FCmpInst::FCMP_UEQ; } | UNE { $$ = FCmpInst::FCMP_UNE; } - | ULT { $$ = FCmpInst::FCMP_ULT; } | UGT { $$ = FCmpInst::FCMP_UGT; } - | ULE { $$ = FCmpInst::FCMP_ULE; } | UGE { $$ = FCmpInst::FCMP_UGE; } - | TRUETOK { $$ = FCmpInst::FCMP_TRUE; } - | FALSETOK { $$ = FCmpInst::FCMP_FALSE; } - ; - -LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ; -OptLocalName : LocalName | /*empty*/ { $$ = 0; }; - -OptAddrSpace : ADDRSPACE '(' EUINT64VAL ')' { $$=$3; } - | /*empty*/ { $$=0; }; - -/// OptLocalAssign - Value producing statements have an optional assignment -/// component. -OptLocalAssign : LocalName '=' { - $$ = $1; - CHECK_FOR_ERROR - } - | /*empty*/ { - $$ = 0; - CHECK_FOR_ERROR - }; - -LocalNumber : LOCALVAL_ID '=' { - $$ = $1; - CHECK_FOR_ERROR -}; - - -GlobalName : GLOBALVAR | ATSTRINGCONSTANT ; - -OptGlobalAssign : GlobalAssign - | /*empty*/ { - $$ = 0; - CHECK_FOR_ERROR - }; - -GlobalAssign : GlobalName '=' { - $$ = $1; - CHECK_FOR_ERROR - }; - -GVInternalLinkage - : INTERNAL { $$ = GlobalValue::InternalLinkage; } - | WEAK { $$ = GlobalValue::WeakLinkage; } - | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } - | APPENDING { $$ = GlobalValue::AppendingLinkage; } - | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } - | COMMON { $$ = GlobalValue::CommonLinkage; } - ; - -GVExternalLinkage - : DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } - | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } - | EXTERNAL { $$ = GlobalValue::ExternalLinkage; } - ; - -GVVisibilityStyle - : /*empty*/ { $$ = GlobalValue::DefaultVisibility; } - | DEFAULT { $$ = GlobalValue::DefaultVisibility; } - | HIDDEN { $$ = GlobalValue::HiddenVisibility; } - | PROTECTED { $$ = GlobalValue::ProtectedVisibility; } - ; - -FunctionDeclareLinkage - : /*empty*/ { $$ = GlobalValue::ExternalLinkage; } - | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } - | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } - ; - -FunctionDefineLinkage - : /*empty*/ { $$ = GlobalValue::ExternalLinkage; } - | INTERNAL { $$ = GlobalValue::InternalLinkage; } - | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } - | WEAK { $$ = GlobalValue::WeakLinkage; } - | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } - ; - -AliasLinkage - : /*empty*/ { $$ = GlobalValue::ExternalLinkage; } - | WEAK { $$ = GlobalValue::WeakLinkage; } - | INTERNAL { $$ = GlobalValue::InternalLinkage; } - ; - -OptCallingConv : /*empty*/ { $$ = CallingConv::C; } | - CCC_TOK { $$ = CallingConv::C; } | - FASTCC_TOK { $$ = CallingConv::Fast; } | - COLDCC_TOK { $$ = CallingConv::Cold; } | - X86_STDCALLCC_TOK { $$ = CallingConv::X86_StdCall; } | - X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } | - CC_TOK EUINT64VAL { - if ((unsigned)$2 != $2) - GEN_ERROR("Calling conv too large"); - $$ = $2; - CHECK_FOR_ERROR - }; - -Attribute : ZEROEXT { $$ = Attribute::ZExt; } - | ZEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | SEXT { $$ = Attribute::SExt; } - | INREG { $$ = Attribute::InReg; } - | SRET { $$ = Attribute::StructRet; } - | NOALIAS { $$ = Attribute::NoAlias; } - | NOCAPTURE { $$ = Attribute::NoCapture; } - | BYVAL { $$ = Attribute::ByVal; } - | NEST { $$ = Attribute::Nest; } - | ALIGN EUINT64VAL { $$ = - Attribute::constructAlignmentFromInt($2); } - ; - -OptAttributes : /* empty */ { $$ = Attribute::None; } - | OptAttributes Attribute { - $$ = $1 | $2; - } - ; - -RetAttr : INREG { $$ = Attribute::InReg; } - | ZEROEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | NOALIAS { $$ = Attribute::NoAlias; } - ; - -OptRetAttrs : /* empty */ { $$ = Attribute::None; } - | OptRetAttrs RetAttr { - $$ = $1 | $2; - } - ; - - -FuncAttr : NORETURN { $$ = Attribute::NoReturn; } - | NOUNWIND { $$ = Attribute::NoUnwind; } - | INREG { $$ = Attribute::InReg; } - | ZEROEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | READNONE { $$ = Attribute::ReadNone; } - | READONLY { $$ = Attribute::ReadOnly; } - | NOINLINE { $$ = Attribute::NoInline; } - | ALWAYSINLINE { $$ = Attribute::AlwaysInline; } - | OPTSIZE { $$ = Attribute::OptimizeForSize; } - | SSP { $$ = Attribute::StackProtect; } - | SSPREQ { $$ = Attribute::StackProtectReq; } - ; - -OptFuncAttrs : /* empty */ { $$ = Attribute::None; } - | OptFuncAttrs FuncAttr { - $$ = $1 | $2; - } - ; - - -OptGC : /* empty */ { $$ = 0; } - | GC STRINGCONSTANT { - $$ = $2; - } - ; - -// OptAlign/OptCAlign - An optional alignment, and an optional alignment with -// a comma before it. -OptAlign : /*empty*/ { $$ = 0; } | - ALIGN EUINT64VAL { - $$ = $2; - if ($$ != 0 && !isPowerOf2_32($$)) - GEN_ERROR("Alignment must be a power of two"); - if ($$ > 0x40000000) - GEN_ERROR("Alignment too large"); - CHECK_FOR_ERROR -}; -OptCAlign : /*empty*/ { $$ = 0; } | - ',' ALIGN EUINT64VAL { - $$ = $3; - if ($$ != 0 && !isPowerOf2_32($$)) - GEN_ERROR("Alignment must be a power of two"); - if ($$ > 0x40000000) - GEN_ERROR("Alignment too large"); - CHECK_FOR_ERROR -}; - - - -SectionString : SECTION STRINGCONSTANT { - for (unsigned i = 0, e = $2->length(); i != e; ++i) - if ((*$2)[i] == '"' || (*$2)[i] == '\\') - GEN_ERROR("Invalid character in section name"); - $$ = $2; - CHECK_FOR_ERROR -}; - -OptSection : /*empty*/ { $$ = 0; } | - SectionString { $$ = $1; }; - -// GlobalVarAttributes - Used to pass the attributes string on a global. CurGV -// is set to be the global we are processing. -// -GlobalVarAttributes : /* empty */ {} | - ',' GlobalVarAttribute GlobalVarAttributes {}; -GlobalVarAttribute : SectionString { - CurGV->setSection(*$1); - delete $1; - CHECK_FOR_ERROR - } - | ALIGN EUINT64VAL { - if ($2 != 0 && !isPowerOf2_32($2)) - GEN_ERROR("Alignment must be a power of two"); - if ($2 > 0x40000000) - GEN_ERROR("Alignment too large"); - CurGV->setAlignment($2); - CHECK_FOR_ERROR - }; - -//===----------------------------------------------------------------------===// -// Types includes all predefined types... except void, because it can only be -// used in specific contexts (function returning void for example). - -// Derived types are added later... -// -PrimType : INTTYPE | FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80 | LABEL ; - -Types - : OPAQUE { - $$ = new PATypeHolder(OpaqueType::get()); - CHECK_FOR_ERROR - } - | PrimType { - $$ = new PATypeHolder($1); - CHECK_FOR_ERROR - } - | Types OptAddrSpace '*' { // Pointer type? - if (*$1 == Type::LabelTy) - GEN_ERROR("Cannot form a pointer to a basic block"); - $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $2))); - delete $1; - CHECK_FOR_ERROR - } - | SymbolicValueRef { // Named types are also simple types... - const Type* tmp = getTypeVal($1); - CHECK_FOR_ERROR - $$ = new PATypeHolder(tmp); - } - | '\\' EUINT64VAL { // Type UpReference - if ($2 > (uint64_t)~0U) GEN_ERROR("Value out of range"); - OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder - UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector... - $$ = new PATypeHolder(OT); - UR_OUT("New Upreference!\n"); - CHECK_FOR_ERROR - } - | Types '(' ArgTypeListI ')' OptFuncAttrs { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - const Type *RetTy = *$1; - if (!FunctionType::isValidReturnType(RetTy)) - GEN_ERROR("Invalid result type for LLVM function"); - - std::vector Params; - TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); - for (; I != E; ++I ) { - const Type *Ty = I->Ty->get(); - Params.push_back(Ty); - } - - bool isVarArg = Params.size() && Params.back() == Type::VoidTy; - if (isVarArg) Params.pop_back(); - - for (unsigned i = 0; i != Params.size(); ++i) - if (!(Params[i]->isFirstClassType() || isa(Params[i]))) - GEN_ERROR("Function arguments must be value types!"); - - CHECK_FOR_ERROR - - FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); - delete $1; // Delete the return type handle - $$ = new PATypeHolder(HandleUpRefs(FT)); - - // Delete the argument list - for (I = $3->begin() ; I != E; ++I ) { - delete I->Ty; - } - delete $3; - - CHECK_FOR_ERROR - } - | VOID '(' ArgTypeListI ')' OptFuncAttrs { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - std::vector Params; - TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); - for ( ; I != E; ++I ) { - const Type* Ty = I->Ty->get(); - Params.push_back(Ty); - } - - bool isVarArg = Params.size() && Params.back() == Type::VoidTy; - if (isVarArg) Params.pop_back(); - - for (unsigned i = 0; i != Params.size(); ++i) - if (!(Params[i]->isFirstClassType() || isa(Params[i]))) - GEN_ERROR("Function arguments must be value types!"); - - CHECK_FOR_ERROR - - FunctionType *FT = FunctionType::get($1, Params, isVarArg); - $$ = new PATypeHolder(HandleUpRefs(FT)); - - // Delete the argument list - for (I = $3->begin() ; I != E; ++I ) { - delete I->Ty; - } - delete $3; - - CHECK_FOR_ERROR - } - - | '[' EUINT64VAL 'x' Types ']' { // Sized array type? - $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, $2))); - delete $4; - CHECK_FOR_ERROR - } - | '<' EUINT64VAL 'x' Types '>' { // Vector type? - const llvm::Type* ElemTy = $4->get(); - if ((unsigned)$2 != $2) - GEN_ERROR("Unsigned result not equal to signed result"); - if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger()) - GEN_ERROR("Element type of a VectorType must be primitive"); - $$ = new PATypeHolder(HandleUpRefs(VectorType::get(*$4, (unsigned)$2))); - delete $4; - CHECK_FOR_ERROR - } - | '{' TypeListI '}' { // Structure type? - std::vector Elements; - for (std::list::iterator I = $2->begin(), - E = $2->end(); I != E; ++I) - Elements.push_back(*I); - - $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); - delete $2; - CHECK_FOR_ERROR - } - | '{' '}' { // Empty structure type? - $$ = new PATypeHolder(StructType::get(std::vector())); - CHECK_FOR_ERROR - } - | '<' '{' TypeListI '}' '>' { - std::vector Elements; - for (std::list::iterator I = $3->begin(), - E = $3->end(); I != E; ++I) - Elements.push_back(*I); - - $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true))); - delete $3; - CHECK_FOR_ERROR - } - | '<' '{' '}' '>' { // Empty structure type? - $$ = new PATypeHolder(StructType::get(std::vector(), true)); - CHECK_FOR_ERROR - } - ; - -ArgType - : Types OptAttributes { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - $$.Ty = $1; - $$.Attrs = Attribute::None; - } - ; - -ResultTypes - : Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if (!(*$1)->isFirstClassType() && !isa($1->get())) - GEN_ERROR("LLVM functions cannot return aggregate types"); - $$ = $1; - } - | VOID { - $$ = new PATypeHolder(Type::VoidTy); - } - ; - -ArgTypeList : ArgType { - $$ = new TypeWithAttrsList(); - $$->push_back($1); - CHECK_FOR_ERROR - } - | ArgTypeList ',' ArgType { - ($$=$1)->push_back($3); - CHECK_FOR_ERROR - } - ; - -ArgTypeListI - : ArgTypeList - | ArgTypeList ',' DOTDOTDOT { - $$=$1; - TypeWithAttrs TWA; TWA.Attrs = Attribute::None; - TWA.Ty = new PATypeHolder(Type::VoidTy); - $$->push_back(TWA); - CHECK_FOR_ERROR - } - | DOTDOTDOT { - $$ = new TypeWithAttrsList; - TypeWithAttrs TWA; TWA.Attrs = Attribute::None; - TWA.Ty = new PATypeHolder(Type::VoidTy); - $$->push_back(TWA); - CHECK_FOR_ERROR - } - | /*empty*/ { - $$ = new TypeWithAttrsList(); - CHECK_FOR_ERROR - }; - -// TypeList - Used for struct declarations and as a basis for function type -// declaration type lists -// -TypeListI : Types { - $$ = new std::list(); - $$->push_back(*$1); - delete $1; - CHECK_FOR_ERROR - } - | TypeListI ',' Types { - ($$=$1)->push_back(*$3); - delete $3; - CHECK_FOR_ERROR - }; - -// ConstVal - The various declarations that go into the constant pool. This -// production is used ONLY to represent constants that show up AFTER a 'const', -// 'constant' or 'global' token at global scope. Constants that can be inlined -// into other expressions (such as integers and constexprs) are handled by the -// ResolvedVal, ValueRef and ConstValueRef productions. -// -ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const ArrayType *ATy = dyn_cast($1->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'"); - const Type *ETy = ATy->getElementType(); - uint64_t NumElements = ATy->getNumElements(); - - // Verify that we have the correct size... - if (NumElements != uint64_t(-1) && NumElements != $3->size()) - GEN_ERROR("Type mismatch: constant sized array initialized with " + - utostr($3->size()) + " arguments, but has size of " + - utostr(NumElements) + ""); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $3->size(); i++) { - if (ETy != (*$3)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*$3)[i]->getType()->getDescription() + "'."); - } - - $$ = ConstantArray::get(ATy, *$3); - delete $1; delete $3; - CHECK_FOR_ERROR - } - | Types '[' ']' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const ArrayType *ATy = dyn_cast($1->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'"); - - uint64_t NumElements = ATy->getNumElements(); - if (NumElements != uint64_t(-1) && NumElements != 0) - GEN_ERROR("Type mismatch: constant sized array initialized with 0" - " arguments, but has size of " + utostr(NumElements) +""); - $$ = ConstantArray::get(ATy, std::vector()); - delete $1; - CHECK_FOR_ERROR - } - | Types 'c' STRINGCONSTANT { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const ArrayType *ATy = dyn_cast($1->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'"); - - uint64_t NumElements = ATy->getNumElements(); - const Type *ETy = ATy->getElementType(); - if (NumElements != uint64_t(-1) && NumElements != $3->length()) - GEN_ERROR("Can't build string constant of size " + - utostr($3->length()) + - " when array has size " + utostr(NumElements) + ""); - std::vector Vals; - if (ETy == Type::Int8Ty) { - for (uint64_t i = 0; i < $3->length(); ++i) - Vals.push_back(ConstantInt::get(ETy, (*$3)[i])); - } else { - delete $3; - GEN_ERROR("Cannot build string arrays of non byte sized elements"); - } - delete $3; - $$ = ConstantArray::get(ATy, Vals); - delete $1; - CHECK_FOR_ERROR - } - | Types '<' ConstVector '>' { // Nonempty unsized arr - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const VectorType *PTy = dyn_cast($1->get()); - if (PTy == 0) - GEN_ERROR("Cannot make packed constant with type: '" + - (*$1)->getDescription() + "'"); - const Type *ETy = PTy->getElementType(); - unsigned NumElements = PTy->getNumElements(); - - // Verify that we have the correct size... - if (NumElements != unsigned(-1) && NumElements != (unsigned)$3->size()) - GEN_ERROR("Type mismatch: constant sized packed initialized with " + - utostr($3->size()) + " arguments, but has size of " + - utostr(NumElements) + ""); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $3->size(); i++) { - if (ETy != (*$3)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*$3)[i]->getType()->getDescription() + "'."); - } - - $$ = ConstantVector::get(PTy, *$3); - delete $1; delete $3; - CHECK_FOR_ERROR - } - | Types '{' ConstVector '}' { - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if ($3->size() != STy->getNumContainedTypes()) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that constants are compatible with the type initializer! - for (unsigned i = 0, e = $3->size(); i != e; ++i) - if ((*$3)[i]->getType() != STy->getElementType(i)) - GEN_ERROR("Expected type '" + - STy->getElementType(i)->getDescription() + - "' for element #" + utostr(i) + - " of structure initializer"); - - // Check to ensure that Type is not packed - if (STy->isPacked()) - GEN_ERROR("Unpacked Initializer to vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, *$3); - delete $1; delete $3; - CHECK_FOR_ERROR - } - | Types '{' '}' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if (STy->getNumContainedTypes() != 0) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that Type is not packed - if (STy->isPacked()) - GEN_ERROR("Unpacked Initializer to vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, std::vector()); - delete $1; - CHECK_FOR_ERROR - } - | Types '<' '{' ConstVector '}' '>' { - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if ($4->size() != STy->getNumContainedTypes()) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that constants are compatible with the type initializer! - for (unsigned i = 0, e = $4->size(); i != e; ++i) - if ((*$4)[i]->getType() != STy->getElementType(i)) - GEN_ERROR("Expected type '" + - STy->getElementType(i)->getDescription() + - "' for element #" + utostr(i) + - " of structure initializer"); - - // Check to ensure that Type is packed - if (!STy->isPacked()) - GEN_ERROR("Vector initializer to non-vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, *$4); - delete $1; delete $4; - CHECK_FOR_ERROR - } - | Types '<' '{' '}' '>' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if (STy->getNumContainedTypes() != 0) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that Type is packed - if (!STy->isPacked()) - GEN_ERROR("Vector initializer to non-vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, std::vector()); - delete $1; - CHECK_FOR_ERROR - } - | Types NULL_TOK { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const PointerType *PTy = dyn_cast($1->get()); - if (PTy == 0) - GEN_ERROR("Cannot make null pointer constant with type: '" + - (*$1)->getDescription() + "'"); - - $$ = ConstantPointerNull::get(PTy); - delete $1; - CHECK_FOR_ERROR - } - | Types UNDEF { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - $$ = UndefValue::get($1->get()); - delete $1; - CHECK_FOR_ERROR - } - | Types SymbolicValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const PointerType *Ty = dyn_cast($1->get()); - if (Ty == 0) - GEN_ERROR("Global const reference must be a pointer type " + (*$1)->getDescription()); - - // ConstExprs can exist in the body of a function, thus creating - // GlobalValues whenever they refer to a variable. Because we are in - // the context of a function, getExistingVal will search the functions - // symbol table instead of the module symbol table for the global symbol, - // which throws things all off. To get around this, we just tell - // getExistingVal that we are at global scope here. - // - Function *SavedCurFn = CurFun.CurrentFunction; - CurFun.CurrentFunction = 0; - - Value *V = getExistingVal(Ty, $2); - CHECK_FOR_ERROR - - CurFun.CurrentFunction = SavedCurFn; - - // If this is an initializer for a constant pointer, which is referencing a - // (currently) undefined variable, create a stub now that shall be replaced - // in the future with the right type of variable. - // - if (V == 0) { - assert(isa(Ty) && "Globals may only be used as pointers!"); - const PointerType *PT = cast(Ty); - - // First check to see if the forward references value is already created! - PerModuleInfo::GlobalRefsType::iterator I = - CurModule.GlobalRefs.find(std::make_pair(PT, $2)); - - if (I != CurModule.GlobalRefs.end()) { - V = I->second; // Placeholder already exists, use it... - $2.destroy(); - } else { - std::string Name; - if ($2.Type == ValID::GlobalName) - Name = $2.getName(); - else if ($2.Type != ValID::GlobalID) - GEN_ERROR("Invalid reference to global"); - - // Create the forward referenced global. - GlobalValue *GV; - if (const FunctionType *FTy = - dyn_cast(PT->getElementType())) { - GV = Function::Create(FTy, GlobalValue::ExternalWeakLinkage, Name, - CurModule.CurrentModule); - } else { - GV = new GlobalVariable(PT->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, - Name, CurModule.CurrentModule); - } - - // Keep track of the fact that we have a forward ref to recycle it - CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV)); - V = GV; - } - } - - $$ = cast(V); - delete $1; // Free the type handle - CHECK_FOR_ERROR - } - | Types ConstExpr { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if ($1->get() != $2->getType()) - GEN_ERROR("Mismatched types for constant expression: " + - (*$1)->getDescription() + " and " + $2->getType()->getDescription()); - $$ = $2; - delete $1; - CHECK_FOR_ERROR - } - | Types ZEROINITIALIZER { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const Type *Ty = $1->get(); - if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) - GEN_ERROR("Cannot create a null initialized value of this type"); - $$ = Constant::getNullValue(Ty); - delete $1; - CHECK_FOR_ERROR - } - | Types ESINT64VAL { // integral constants - if (IntegerType *IT = dyn_cast($1->get())) { - if (!ConstantInt::isValueValidForType(IT, $2)) - GEN_ERROR("Constant value doesn't fit in type"); - $$ = ConstantInt::get(IT, $2, true); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete $1; - CHECK_FOR_ERROR - } - | Types ESAPINTVAL { // arbitrary precision integer constants - if (IntegerType *IT = dyn_cast($1->get())) { - if ($2->getBitWidth() > IT->getBitWidth()) - GEN_ERROR("Constant value does not fit in type"); - $2->sextOrTrunc(IT->getBitWidth()); - $$ = ConstantInt::get(*$2); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete $1; - delete $2; - CHECK_FOR_ERROR - } - | Types EUINT64VAL { // integral constants - if (IntegerType *IT = dyn_cast($1->get())) { - if (!ConstantInt::isValueValidForType(IT, $2)) - GEN_ERROR("Constant value doesn't fit in type"); - $$ = ConstantInt::get(IT, $2, false); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete $1; - CHECK_FOR_ERROR - } - | Types EUAPINTVAL { // arbitrary precision integer constants - if (IntegerType *IT = dyn_cast($1->get())) { - if ($2->getBitWidth() > IT->getBitWidth()) - GEN_ERROR("Constant value does not fit in type"); - $2->zextOrTrunc(IT->getBitWidth()); - $$ = ConstantInt::get(*$2); - } else { - GEN_ERROR("integer constant must have integer type"); - } - - delete $2; - delete $1; - CHECK_FOR_ERROR - } - | Types TRUETOK { // Boolean constants - if ($1->get() != Type::Int1Ty) - GEN_ERROR("Constant true must have type i1"); - $$ = ConstantInt::getTrue(); - delete $1; - CHECK_FOR_ERROR - } - | Types FALSETOK { // Boolean constants - if ($1->get() != Type::Int1Ty) - GEN_ERROR("Constant false must have type i1"); - $$ = ConstantInt::getFalse(); - delete $1; - CHECK_FOR_ERROR - } - | Types FPVAL { // Floating point constants - if (!ConstantFP::isValueValidForType($1->get(), *$2)) - GEN_ERROR("Floating point constant invalid for type"); - - // Lexer has no type info, so builds all float and double FP constants - // as double. Fix this here. Long double is done right. - if (&$2->getSemantics()==&APFloat::IEEEdouble && $1->get()==Type::FloatTy) { - bool ignored; - $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, - &ignored); - } - $$ = ConstantFP::get(*$2); - delete $1; - delete $2; - CHECK_FOR_ERROR - }; - - -ConstExpr: CastOps '(' ConstVal TO Types ')' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); - Constant *Val = $3; - const Type *DestTy = $5->get(); - if (!CastInst::castIsValid($1, $3, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - $$ = ConstantExpr::getCast($1, $3, DestTy); - delete $5; - } - | GETELEMENTPTR '(' ConstVal IndexList ')' { - if (!isa($3->getType())) - GEN_ERROR("GetElementPtr requires a pointer operand"); - - const Type *IdxTy = - GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end()); - if (!IdxTy) - GEN_ERROR("Index list invalid for constant getelementptr"); - - SmallVector IdxVec; - for (unsigned i = 0, e = $4->size(); i != e; ++i) - if (Constant *C = dyn_cast((*$4)[i])) - IdxVec.push_back(C); - else - GEN_ERROR("Indices to constant getelementptr must be constants"); - - delete $4; - - $$ = ConstantExpr::getGetElementPtr($3, &IdxVec[0], IdxVec.size()); - CHECK_FOR_ERROR - } - | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { - if ($3->getType() != Type::Int1Ty) - GEN_ERROR("Select condition must be of boolean type"); - if ($5->getType() != $7->getType()) - GEN_ERROR("Select operand types must match"); - $$ = ConstantExpr::getSelect($3, $5, $7); - CHECK_FOR_ERROR - } - | ArithmeticOps '(' ConstVal ',' ConstVal ')' { - if ($3->getType() != $5->getType()) - GEN_ERROR("Binary operator types must match"); - CHECK_FOR_ERROR; - $$ = ConstantExpr::get($1, $3, $5); - } - | LogicalOps '(' ConstVal ',' ConstVal ')' { - if ($3->getType() != $5->getType()) - GEN_ERROR("Logical operator types must match"); - if (!$3->getType()->isInteger()) { - if (!isa($3->getType()) || - !cast($3->getType())->getElementType()->isInteger()) - GEN_ERROR("Logical operator requires integral operands"); - } - $$ = ConstantExpr::get($1, $3, $5); - CHECK_FOR_ERROR - } - | ICMP IPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("icmp operand types must match"); - $$ = ConstantExpr::getICmp($2, $4, $6); - } - | FCMP FPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("fcmp operand types must match"); - $$ = ConstantExpr::getFCmp($2, $4, $6); - } - | VICMP IPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("vicmp operand types must match"); - $$ = ConstantExpr::getVICmp($2, $4, $6); - } - | VFCMP FPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("vfcmp operand types must match"); - $$ = ConstantExpr::getVFCmp($2, $4, $6); - } - | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { - if (!ExtractElementInst::isValidOperands($3, $5)) - GEN_ERROR("Invalid extractelement operands"); - $$ = ConstantExpr::getExtractElement($3, $5); - CHECK_FOR_ERROR - } - | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' { - if (!InsertElementInst::isValidOperands($3, $5, $7)) - GEN_ERROR("Invalid insertelement operands"); - $$ = ConstantExpr::getInsertElement($3, $5, $7); - CHECK_FOR_ERROR - } - | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' { - if (!ShuffleVectorInst::isValidOperands($3, $5, $7)) - GEN_ERROR("Invalid shufflevector operands"); - $$ = ConstantExpr::getShuffleVector($3, $5, $7); - CHECK_FOR_ERROR - } - | EXTRACTVALUE '(' ConstVal ConstantIndexList ')' { - if (!isa($3->getType()) && !isa($3->getType())) - GEN_ERROR("ExtractValue requires an aggregate operand"); - - $$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size()); - delete $4; - CHECK_FOR_ERROR - } - | INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' { - if (!isa($3->getType()) && !isa($3->getType())) - GEN_ERROR("InsertValue requires an aggregate operand"); - - $$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size()); - delete $6; - CHECK_FOR_ERROR - }; - - -// ConstVector - A list of comma separated constants. -ConstVector : ConstVector ',' ConstVal { - ($$ = $1)->push_back($3); - CHECK_FOR_ERROR - } - | ConstVal { - $$ = new std::vector(); - $$->push_back($1); - CHECK_FOR_ERROR - }; - - -// GlobalType - Match either GLOBAL or CONSTANT for global declarations... -GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }; - -// ThreadLocal -ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; }; - -// AliaseeRef - Match either GlobalValue or bitcast to GlobalValue. -AliaseeRef : ResultTypes SymbolicValueRef { - const Type* VTy = $1->get(); - Value *V = getVal(VTy, $2); - CHECK_FOR_ERROR - GlobalValue* Aliasee = dyn_cast(V); - if (!Aliasee) - GEN_ERROR("Aliases can be created only to global values"); - - $$ = Aliasee; - CHECK_FOR_ERROR - delete $1; - } - | BITCAST '(' AliaseeRef TO Types ')' { - Constant *Val = $3; - const Type *DestTy = $5->get(); - if (!CastInst::castIsValid($1, $3, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - - $$ = ConstantExpr::getCast($1, $3, DestTy); - CHECK_FOR_ERROR - delete $5; - }; - -//===----------------------------------------------------------------------===// -// Rules to match Modules -//===----------------------------------------------------------------------===// - -// Module rule: Capture the result of parsing the whole file into a result -// variable... -// -Module - : DefinitionList { - $$ = ParserResult = CurModule.CurrentModule; - CurModule.ModuleDone(); - CHECK_FOR_ERROR; - } - | /*empty*/ { - $$ = ParserResult = CurModule.CurrentModule; - CurModule.ModuleDone(); - CHECK_FOR_ERROR; - } - ; - -DefinitionList - : Definition - | DefinitionList Definition - ; - -Definition - : DEFINE { CurFun.isDeclare = false; } Function { - CurFun.FunctionDone(); - CHECK_FOR_ERROR - } - | DECLARE { CurFun.isDeclare = true; } FunctionProto { - CHECK_FOR_ERROR - } - | MODULE ASM_TOK AsmBlock { - CHECK_FOR_ERROR - } - | OptLocalAssign TYPE Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - // Eagerly resolve types. This is not an optimization, this is a - // requirement that is due to the fact that we could have this: - // - // %list = type { %list * } - // %list = type { %list * } ; repeated type decl - // - // If types are not resolved eagerly, then the two types will not be - // determined to be the same type! - // - ResolveTypeTo($1, *$3); - - if (!setTypeName(*$3, $1) && !$1) { - CHECK_FOR_ERROR - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back(*$3); - } - - delete $3; - CHECK_FOR_ERROR - } - | OptLocalAssign TYPE VOID { - ResolveTypeTo($1, $3); - - if (!setTypeName($3, $1) && !$1) { - CHECK_FOR_ERROR - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back($3); - } - CHECK_FOR_ERROR - } - | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal - OptAddrSpace { - /* "Externally Visible" Linkage */ - if ($5 == 0) - GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, - $2, $4, $5->getType(), $5, $3, $6); - CHECK_FOR_ERROR - } GlobalVarAttributes { - CurGV = 0; - } - | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType - ConstVal OptAddrSpace { - if ($6 == 0) - GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7); - CHECK_FOR_ERROR - } GlobalVarAttributes { - CurGV = 0; - } - | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType - Types OptAddrSpace { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription()); - CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4, $7); - CHECK_FOR_ERROR - delete $6; - } GlobalVarAttributes { - CurGV = 0; - CHECK_FOR_ERROR - } - | OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage AliaseeRef { - std::string Name; - if ($1) { - Name = *$1; - delete $1; - } - if (Name.empty()) - GEN_ERROR("Alias name cannot be empty"); - - Constant* Aliasee = $5; - if (Aliasee == 0) - GEN_ERROR(std::string("Invalid aliasee for alias: ") + Name); - - GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), $4, Name, Aliasee, - CurModule.CurrentModule); - GA->setVisibility($2); - InsertValue(GA, CurModule.Values); - - - // If there was a forward reference of this alias, resolve it now. - - ValID ID; - if (!Name.empty()) - ID = ValID::createGlobalName(Name); - else - ID = ValID::createGlobalID(CurModule.Values.size()-1); - - if (GlobalValue *FWGV = - CurModule.GetForwardRefForGlobal(GA->getType(), ID)) { - // Replace uses of the fwdref with the actual alias. - FWGV->replaceAllUsesWith(GA); - if (GlobalVariable *GV = dyn_cast(FWGV)) - GV->eraseFromParent(); - else - cast(FWGV)->eraseFromParent(); - } - ID.destroy(); - - CHECK_FOR_ERROR - } - | TARGET TargetDefinition { - CHECK_FOR_ERROR - } - | DEPLIBS '=' LibrariesDefinition { - CHECK_FOR_ERROR - } - ; - - -AsmBlock : STRINGCONSTANT { - const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); - if (AsmSoFar.empty()) - CurModule.CurrentModule->setModuleInlineAsm(*$1); - else - CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+*$1); - delete $1; - CHECK_FOR_ERROR -}; - -TargetDefinition : TRIPLE '=' STRINGCONSTANT { - CurModule.CurrentModule->setTargetTriple(*$3); - delete $3; - } - | DATALAYOUT '=' STRINGCONSTANT { - CurModule.CurrentModule->setDataLayout(*$3); - delete $3; - }; - -LibrariesDefinition : '[' LibList ']'; - -LibList : LibList ',' STRINGCONSTANT { - CurModule.CurrentModule->addLibrary(*$3); - delete $3; - CHECK_FOR_ERROR - } - | STRINGCONSTANT { - CurModule.CurrentModule->addLibrary(*$1); - delete $1; - CHECK_FOR_ERROR - } - | /* empty: end of list */ { - CHECK_FOR_ERROR - } - ; - -//===----------------------------------------------------------------------===// -// Rules to match Function Headers -//===----------------------------------------------------------------------===// - -ArgListH : ArgListH ',' Types OptAttributes OptLocalName { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!(*$3)->isFirstClassType()) - GEN_ERROR("Argument types must be first-class"); - ArgListEntry E; E.Attrs = $4; E.Ty = $3; E.Name = $5; - $$ = $1; - $1->push_back(E); - CHECK_FOR_ERROR - } - | Types OptAttributes OptLocalName { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if (!(*$1)->isFirstClassType()) - GEN_ERROR("Argument types must be first-class"); - ArgListEntry E; E.Attrs = $2; E.Ty = $1; E.Name = $3; - $$ = new ArgListType; - $$->push_back(E); - CHECK_FOR_ERROR - }; - -ArgList : ArgListH { - $$ = $1; - CHECK_FOR_ERROR - } - | ArgListH ',' DOTDOTDOT { - $$ = $1; - struct ArgListEntry E; - E.Ty = new PATypeHolder(Type::VoidTy); - E.Name = 0; - E.Attrs = Attribute::None; - $$->push_back(E); - CHECK_FOR_ERROR - } - | DOTDOTDOT { - $$ = new ArgListType; - struct ArgListEntry E; - E.Ty = new PATypeHolder(Type::VoidTy); - E.Name = 0; - E.Attrs = Attribute::None; - $$->push_back(E); - CHECK_FOR_ERROR - } - | /* empty */ { - $$ = 0; - CHECK_FOR_ERROR - }; - -FunctionHeaderH : OptCallingConv OptRetAttrs ResultTypes GlobalName '(' ArgList ')' - OptFuncAttrs OptSection OptAlign OptGC { - std::string FunctionName(*$4); - delete $4; // Free strdup'd memory! - - // Check the function result for abstractness if this is a define. We should - // have no abstract types at this point - if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($3)) - GEN_ERROR("Reference to abstract result: "+ $3->get()->getDescription()); - - if (!FunctionType::isValidReturnType(*$3)) - GEN_ERROR("Invalid result type for LLVM function"); - - std::vector ParamTypeList; - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = $2; - if ($8 != Attribute::None) { - if ($8 & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - $8 = $8 ^ Attribute::ZExt; - } - if ($8 & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - $8 = $8 ^ Attribute::SExt; - } - if ($8 & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - $8 = $8 ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - if ($6) { // If there are arguments... - unsigned index = 1; - for (ArgListType::iterator I = $6->begin(); I != $6->end(); ++I, ++index) { - const Type* Ty = I->Ty->get(); - if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty)) - GEN_ERROR("Reference to abstract argument: " + Ty->getDescription()); - ParamTypeList.push_back(Ty); - if (Ty != Type::VoidTy && I->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, I->Attrs)); - } - } - if ($8 != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, $8)); - - bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; - if (isVarArg) ParamTypeList.pop_back(); - - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - FunctionType *FT = FunctionType::get(*$3, ParamTypeList, isVarArg); - const PointerType *PFT = PointerType::getUnqual(FT); - delete $3; - - ValID ID; - if (!FunctionName.empty()) { - ID = ValID::createGlobalName((char*)FunctionName.c_str()); - } else { - ID = ValID::createGlobalID(CurModule.Values.size()); - } - - Function *Fn = 0; - // See if this function was forward referenced. If so, recycle the object. - if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) { - // Move the function to the end of the list, from whereever it was - // previously inserted. - Fn = cast(FWRef); - assert(Fn->getAttributes().isEmpty() && - "Forward reference has parameter attributes!"); - CurModule.CurrentModule->getFunctionList().remove(Fn); - CurModule.CurrentModule->getFunctionList().push_back(Fn); - } else if (!FunctionName.empty() && // Merge with an earlier prototype? - (Fn = CurModule.CurrentModule->getFunction(FunctionName))) { - if (Fn->getFunctionType() != FT ) { - // The existing function doesn't have the same type. This is an overload - // error. - GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); - } else if (Fn->getAttributes() != PAL) { - // The existing function doesn't have the same parameter attributes. - // This is an overload error. - GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); - } else if (!CurFun.isDeclare && !Fn->isDeclaration()) { - // Neither the existing or the current function is a declaration and they - // have the same name and same type. Clearly this is a redefinition. - GEN_ERROR("Redefinition of function '" + FunctionName + "'"); - } else if (Fn->isDeclaration()) { - // Make sure to strip off any argument names so we can't get conflicts. - for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); - AI != AE; ++AI) - AI->setName(""); - } - } else { // Not already defined? - Fn = Function::Create(FT, GlobalValue::ExternalWeakLinkage, FunctionName, - CurModule.CurrentModule); - InsertValue(Fn, CurModule.Values); - } - - ID.destroy(); - CurFun.FunctionStart(Fn); - - if (CurFun.isDeclare) { - // If we have declaration, always overwrite linkage. This will allow us to - // correctly handle cases, when pointer to function is passed as argument to - // another function. - Fn->setLinkage(CurFun.Linkage); - Fn->setVisibility(CurFun.Visibility); - } - Fn->setCallingConv($1); - Fn->setAttributes(PAL); - Fn->setAlignment($10); - if ($9) { - Fn->setSection(*$9); - delete $9; - } - if ($11) { - Fn->setGC($11->c_str()); - delete $11; - } - - // Add all of the arguments we parsed to the function... - if ($6) { // Is null if empty... - if (isVarArg) { // Nuke the last entry - assert($6->back().Ty->get() == Type::VoidTy && $6->back().Name == 0 && - "Not a varargs marker!"); - delete $6->back().Ty; - $6->pop_back(); // Delete the last entry - } - Function::arg_iterator ArgIt = Fn->arg_begin(); - Function::arg_iterator ArgEnd = Fn->arg_end(); - unsigned Idx = 1; - for (ArgListType::iterator I = $6->begin(); - I != $6->end() && ArgIt != ArgEnd; ++I, ++ArgIt) { - delete I->Ty; // Delete the typeholder... - setValueName(ArgIt, I->Name); // Insert arg into symtab... - CHECK_FOR_ERROR - InsertValue(ArgIt); - Idx++; - } - - delete $6; // We're now done with the argument list - } - CHECK_FOR_ERROR -}; - -BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function - -FunctionHeader : FunctionDefineLinkage GVVisibilityStyle FunctionHeaderH BEGIN { - $$ = CurFun.CurrentFunction; - - // Make sure that we keep track of the linkage type even if there was a - // previous "declare". - $$->setLinkage($1); - $$->setVisibility($2); -}; - -END : ENDTOK | '}'; // Allow end of '}' to end a function - -Function : BasicBlockList END { - $$ = $1; - CHECK_FOR_ERROR -}; - -FunctionProto : FunctionDeclareLinkage GVVisibilityStyle FunctionHeaderH { - CurFun.CurrentFunction->setLinkage($1); - CurFun.CurrentFunction->setVisibility($2); - $$ = CurFun.CurrentFunction; - CurFun.FunctionDone(); - CHECK_FOR_ERROR - }; - -//===----------------------------------------------------------------------===// -// Rules to match Basic Blocks -//===----------------------------------------------------------------------===// - -OptSideEffect : /* empty */ { - $$ = false; - CHECK_FOR_ERROR - } - | SIDEEFFECT { - $$ = true; - CHECK_FOR_ERROR - }; - -ConstValueRef : ESINT64VAL { // A reference to a direct constant - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | EUINT64VAL { - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | ESAPINTVAL { // arbitrary precision integer constants - $$ = ValID::create(*$1, true); - delete $1; - CHECK_FOR_ERROR - } - | EUAPINTVAL { // arbitrary precision integer constants - $$ = ValID::create(*$1, false); - delete $1; - CHECK_FOR_ERROR - } - | FPVAL { // Perhaps it's an FP constant? - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | TRUETOK { - $$ = ValID::create(ConstantInt::getTrue()); - CHECK_FOR_ERROR - } - | FALSETOK { - $$ = ValID::create(ConstantInt::getFalse()); - CHECK_FOR_ERROR - } - | NULL_TOK { - $$ = ValID::createNull(); - CHECK_FOR_ERROR - } - | UNDEF { - $$ = ValID::createUndef(); - CHECK_FOR_ERROR - } - | ZEROINITIALIZER { // A vector zero constant. - $$ = ValID::createZeroInit(); - CHECK_FOR_ERROR - } - | '<' ConstVector '>' { // Nonempty unsized packed vector - const Type *ETy = (*$2)[0]->getType(); - unsigned NumElements = $2->size(); - - if (!ETy->isInteger() && !ETy->isFloatingPoint()) - GEN_ERROR("Invalid vector element type: " + ETy->getDescription()); - - VectorType* pt = VectorType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt)); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $2->size(); i++) { - if (ETy != (*$2)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '" + - (*$2)[i]->getType()->getDescription() + "'."); - } - - $$ = ValID::create(ConstantVector::get(pt, *$2)); - delete PTy; delete $2; - CHECK_FOR_ERROR - } - | '[' ConstVector ']' { // Nonempty unsized arr - const Type *ETy = (*$2)[0]->getType(); - uint64_t NumElements = $2->size(); - - if (!ETy->isFirstClassType()) - GEN_ERROR("Invalid array element type: " + ETy->getDescription()); - - ArrayType *ATy = ArrayType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy)); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $2->size(); i++) { - if (ETy != (*$2)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*$2)[i]->getType()->getDescription() + "'."); - } - - $$ = ValID::create(ConstantArray::get(ATy, *$2)); - delete PTy; delete $2; - CHECK_FOR_ERROR - } - | '[' ']' { - // Use undef instead of an array because it's inconvenient to determine - // the element type at this point, there being no elements to examine. - $$ = ValID::createUndef(); - CHECK_FOR_ERROR - } - | 'c' STRINGCONSTANT { - uint64_t NumElements = $2->length(); - const Type *ETy = Type::Int8Ty; - - ArrayType *ATy = ArrayType::get(ETy, NumElements); - - std::vector Vals; - for (unsigned i = 0; i < $2->length(); ++i) - Vals.push_back(ConstantInt::get(ETy, (*$2)[i])); - delete $2; - $$ = ValID::create(ConstantArray::get(ATy, Vals)); - CHECK_FOR_ERROR - } - | '{' ConstVector '}' { - std::vector Elements($2->size()); - for (unsigned i = 0, e = $2->size(); i != e; ++i) - Elements[i] = (*$2)[i]->getType(); - - const StructType *STy = StructType::get(Elements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); - - $$ = ValID::create(ConstantStruct::get(STy, *$2)); - delete PTy; delete $2; - CHECK_FOR_ERROR - } - | '{' '}' { - const StructType *STy = StructType::get(std::vector()); - $$ = ValID::create(ConstantStruct::get(STy, std::vector())); - CHECK_FOR_ERROR - } - | '<' '{' ConstVector '}' '>' { - std::vector Elements($3->size()); - for (unsigned i = 0, e = $3->size(); i != e; ++i) - Elements[i] = (*$3)[i]->getType(); - - const StructType *STy = StructType::get(Elements, /*isPacked=*/true); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); - - $$ = ValID::create(ConstantStruct::get(STy, *$3)); - delete PTy; delete $3; - CHECK_FOR_ERROR - } - | '<' '{' '}' '>' { - const StructType *STy = StructType::get(std::vector(), - /*isPacked=*/true); - $$ = ValID::create(ConstantStruct::get(STy, std::vector())); - CHECK_FOR_ERROR - } - | ConstExpr { - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT { - $$ = ValID::createInlineAsm(*$3, *$5, $2); - delete $3; - delete $5; - CHECK_FOR_ERROR - }; - -// SymbolicValueRef - Reference to one of two ways of symbolically refering to -// another value. -// -SymbolicValueRef : LOCALVAL_ID { // Is it an integer reference...? - $$ = ValID::createLocalID($1); - CHECK_FOR_ERROR - } - | GLOBALVAL_ID { - $$ = ValID::createGlobalID($1); - CHECK_FOR_ERROR - } - | LocalName { // Is it a named reference...? - $$ = ValID::createLocalName(*$1); - delete $1; - CHECK_FOR_ERROR - } - | GlobalName { // Is it a named reference...? - $$ = ValID::createGlobalName(*$1); - delete $1; - CHECK_FOR_ERROR - }; - -// ValueRef - A reference to a definition... either constant or symbolic -ValueRef : SymbolicValueRef | ConstValueRef; - - -// ResolvedVal - a pair. This is used only in cases where the -// type immediately preceeds the value reference, and allows complex constant -// pool references (for things like: 'ret [2 x int] [ int 12, int 42]') -ResolvedVal : Types ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - $$ = getVal(*$1, $2); - delete $1; - CHECK_FOR_ERROR - } - ; - -ReturnedVal : ResolvedVal { - $$ = new std::vector(); - $$->push_back($1); - CHECK_FOR_ERROR - } - | ReturnedVal ',' ResolvedVal { - ($$=$1)->push_back($3); - CHECK_FOR_ERROR - }; - -BasicBlockList : BasicBlockList BasicBlock { - $$ = $1; - CHECK_FOR_ERROR - } - | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks - $$ = $1; - CHECK_FOR_ERROR - }; - - -// Basic blocks are terminated by branching instructions: -// br, br/cc, switch, ret -// -BasicBlock : InstructionList OptLocalAssign BBTerminatorInst { - setValueName($3, $2); - CHECK_FOR_ERROR - InsertValue($3); - $1->getInstList().push_back($3); - $$ = $1; - CHECK_FOR_ERROR - }; - -BasicBlock : InstructionList LocalNumber BBTerminatorInst { - CHECK_FOR_ERROR - int ValNum = InsertValue($3); - if (ValNum != (int)$2) - GEN_ERROR("Result value number %" + utostr($2) + - " is incorrect, expected %" + utostr((unsigned)ValNum)); - - $1->getInstList().push_back($3); - $$ = $1; - CHECK_FOR_ERROR -}; - - -InstructionList : InstructionList Inst { - if (CastInst *CI1 = dyn_cast($2)) - if (CastInst *CI2 = dyn_cast(CI1->getOperand(0))) - if (CI2->getParent() == 0) - $1->getInstList().push_back(CI2); - $1->getInstList().push_back($2); - $$ = $1; - CHECK_FOR_ERROR - } - | /* empty */ { // Empty space between instruction lists - $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum)); - CHECK_FOR_ERROR - } - | LABELSTR { // Labelled (named) basic block - $$ = defineBBVal(ValID::createLocalName(*$1)); - delete $1; - CHECK_FOR_ERROR - - }; - -BBTerminatorInst : - RET ReturnedVal { // Return with a result... - ValueList &VL = *$2; - assert(!VL.empty() && "Invalid ret operands!"); - const Type *ReturnType = CurFun.CurrentFunction->getReturnType(); - if (VL.size() > 1 || - (isa(ReturnType) && - (VL.empty() || VL[0]->getType() != ReturnType))) { - Value *RV = UndefValue::get(ReturnType); - for (unsigned i = 0, e = VL.size(); i != e; ++i) { - Instruction *I = InsertValueInst::Create(RV, VL[i], i, "mrv"); - ($-1)->getInstList().push_back(I); - RV = I; - } - $$ = ReturnInst::Create(RV); - } else { - $$ = ReturnInst::Create(VL[0]); - } - delete $2; - CHECK_FOR_ERROR - } - | RET VOID { // Return with no result... - $$ = ReturnInst::Create(); - CHECK_FOR_ERROR - } - | BR LABEL ValueRef { // Unconditional Branch... - BasicBlock* tmpBB = getBBVal($3); - CHECK_FOR_ERROR - $$ = BranchInst::Create(tmpBB); - } // Conditional Branch... - | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { - if (cast($2)->getBitWidth() != 1) - GEN_ERROR("Branch condition must have type i1"); - BasicBlock* tmpBBA = getBBVal($6); - CHECK_FOR_ERROR - BasicBlock* tmpBBB = getBBVal($9); - CHECK_FOR_ERROR - Value* tmpVal = getVal(Type::Int1Ty, $3); - CHECK_FOR_ERROR - $$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal); - } - | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' JumpTable ']' { - Value* tmpVal = getVal($2, $3); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, $8->size()); - $$ = S; - - std::vector >::iterator I = $8->begin(), - E = $8->end(); - for (; I != E; ++I) { - if (ConstantInt *CI = dyn_cast(I->first)) - S->addCase(CI, I->second); - else - GEN_ERROR("Switch case is constant, but not a simple integer"); - } - delete $8; - CHECK_FOR_ERROR - } - | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' ']' { - Value* tmpVal = getVal($2, $3); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, 0); - $$ = S; - CHECK_FOR_ERROR - } - | INVOKE OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')' - OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef { - - // Handle the short syntax - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast($4->get())) || - !(Ty = dyn_cast(PFTy->getElementType()))) { - // Pull out the types of all of the arguments... - std::vector ParamTypes; - ParamList::iterator I = $7->begin(), E = $7->end(); - for (; I != E; ++I) { - const Type *Ty = I->Val->getType(); - if (Ty == Type::VoidTy) - GEN_ERROR("Short call syntax cannot be used with varargs"); - ParamTypes.push_back(Ty); - } - - if (!FunctionType::isValidReturnType(*$4)) - GEN_ERROR("Invalid result type for LLVM function"); - - Ty = FunctionType::get($4->get(), ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); - } - - delete $4; - - Value *V = getVal(PFTy, $5); // Get the function we're calling... - CHECK_FOR_ERROR - BasicBlock *Normal = getBBVal($12); - CHECK_FOR_ERROR - BasicBlock *Except = getBBVal($15); - CHECK_FOR_ERROR - - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = $3; - if ($9 != Attribute::None) { - if ($9 & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - $9 = $9 ^ Attribute::ZExt; - } - if ($9 & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - $9 = $9 ^ Attribute::SExt; - } - if ($9 & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - $9 = $9 ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - - // Check the arguments - ValueList Args; - if ($7->empty()) { // Has no arguments? - // Make sure no arguments is a good thing! - if (Ty->getNumParams() != 0) - GEN_ERROR("No arguments passed to a function that " - "expects arguments"); - } else { // Has arguments? - // Loop through FunctionType's arguments and ensure they are specified - // correctly! - FunctionType::param_iterator I = Ty->param_begin(); - FunctionType::param_iterator E = Ty->param_end(); - ParamList::iterator ArgI = $7->begin(), ArgE = $7->end(); - unsigned index = 1; - - for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { - if (ArgI->Val->getType() != *I) - GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + - (*I)->getDescription() + "'"); - Args.push_back(ArgI->Val); - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - - if (Ty->isVarArg()) { - if (I == E) - for (; ArgI != ArgE; ++ArgI, ++index) { - Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - } else if (I != E || ArgI != ArgE) - GEN_ERROR("Invalid number of parameters detected"); - } - if ($9 != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, $9)); - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - // Create the InvokeInst - InvokeInst *II = InvokeInst::Create(V, Normal, Except, - Args.begin(), Args.end()); - II->setCallingConv($2); - II->setAttributes(PAL); - $$ = II; - delete $7; - CHECK_FOR_ERROR - } - | UNWIND { - $$ = new UnwindInst(); - CHECK_FOR_ERROR - } - | UNREACHABLE { - $$ = new UnreachableInst(); - CHECK_FOR_ERROR - }; - - - -JumpTable : JumpTable INTTYPE ConstValueRef ',' LABEL ValueRef { - $$ = $1; - Constant *V = cast(getExistingVal($2, $3)); - CHECK_FOR_ERROR - if (V == 0) - GEN_ERROR("May only switch on a constant pool value"); - - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - $$->push_back(std::make_pair(V, tmpBB)); - } - | INTTYPE ConstValueRef ',' LABEL ValueRef { - $$ = new std::vector >(); - Constant *V = cast(getExistingVal($1, $2)); - CHECK_FOR_ERROR - - if (V == 0) - GEN_ERROR("May only switch on a constant pool value"); - - BasicBlock* tmpBB = getBBVal($5); - CHECK_FOR_ERROR - $$->push_back(std::make_pair(V, tmpBB)); - }; - -Inst : OptLocalAssign InstVal { - // Is this definition named?? if so, assign the name... - setValueName($2, $1); - CHECK_FOR_ERROR - InsertValue($2); - $$ = $2; - CHECK_FOR_ERROR - }; - -Inst : LocalNumber InstVal { - CHECK_FOR_ERROR - int ValNum = InsertValue($2); - - if (ValNum != (int)$1) - GEN_ERROR("Result value number %" + utostr($1) + - " is incorrect, expected %" + utostr((unsigned)ValNum)); - - $$ = $2; - CHECK_FOR_ERROR - }; - - -PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - $$ = new std::list >(); - Value* tmpVal = getVal(*$1, $3); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($5); - CHECK_FOR_ERROR - $$->push_back(std::make_pair(tmpVal, tmpBB)); - delete $1; - } - | PHIList ',' '[' ValueRef ',' ValueRef ']' { - $$ = $1; - Value* tmpVal = getVal($1->front().first->getType(), $4); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - $1->push_back(std::make_pair(tmpVal, tmpBB)); - }; - - -ParamList : Types OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - // Used for call and invoke instructions - $$ = new ParamList(); - ParamListEntry E; E.Attrs = $2 | $4; E.Val = getVal($1->get(), $3); - $$->push_back(E); - delete $1; - CHECK_FOR_ERROR - } - | LABEL OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - // Labels are only valid in ASMs - $$ = new ParamList(); - ParamListEntry E; E.Attrs = $2 | $4; E.Val = getBBVal($3); - $$->push_back(E); - CHECK_FOR_ERROR - } - | ParamList ',' Types OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - $$ = $1; - ParamListEntry E; E.Attrs = $4 | $6; E.Val = getVal($3->get(), $5); - $$->push_back(E); - delete $3; - CHECK_FOR_ERROR - } - | ParamList ',' LABEL OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - $$ = $1; - ParamListEntry E; E.Attrs = $4 | $6; E.Val = getBBVal($5); - $$->push_back(E); - CHECK_FOR_ERROR - } - | /*empty*/ { $$ = new ParamList(); }; - -IndexList // Used for gep instructions and constant expressions - : /*empty*/ { $$ = new std::vector(); } - | IndexList ',' ResolvedVal { - $$ = $1; - $$->push_back($3); - CHECK_FOR_ERROR - } - ; - -ConstantIndexList // Used for insertvalue and extractvalue instructions - : ',' EUINT64VAL { - $$ = new std::vector(); - if ((unsigned)$2 != $2) - GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue."); - $$->push_back($2); - } - | ConstantIndexList ',' EUINT64VAL { - $$ = $1; - if ((unsigned)$3 != $3) - GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue."); - $$->push_back($3); - CHECK_FOR_ERROR - } - ; - -OptTailCall : TAIL CALL { - $$ = true; - CHECK_FOR_ERROR - } - | CALL { - $$ = false; - CHECK_FOR_ERROR - }; - -InstVal : ArithmeticOps Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() && - !isa((*$2).get())) - GEN_ERROR( - "Arithmetic operator requires integer, FP, or packed operands"); - Value* val1 = getVal(*$2, $3); - CHECK_FOR_ERROR - Value* val2 = getVal(*$2, $5); - CHECK_FOR_ERROR - $$ = BinaryOperator::Create($1, val1, val2); - if ($$ == 0) - GEN_ERROR("binary operator returned null"); - delete $2; - } - | LogicalOps Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!(*$2)->isInteger()) { - if (!isa($2->get()) || - !cast($2->get())->getElementType()->isInteger()) - GEN_ERROR("Logical operator requires integral operands"); - } - Value* tmpVal1 = getVal(*$2, $3); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$2, $5); - CHECK_FOR_ERROR - $$ = BinaryOperator::Create($1, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("binary operator returned null"); - delete $2; - } - | ICMP IPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("icmp operator returned null"); - delete $3; - } - | FCMP FPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("fcmp operator returned null"); - delete $3; - } - | VICMP IPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!isa((*$3).get())) - GEN_ERROR("Scalar types not supported by vicmp instruction"); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("vicmp operator returned null"); - delete $3; - } - | VFCMP FPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!isa((*$3).get())) - GEN_ERROR("Scalar types not supported by vfcmp instruction"); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("vfcmp operator returned null"); - delete $3; - } - | CastOps ResolvedVal TO Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription()); - Value* Val = $2; - const Type* DestTy = $4->get(); - if (!CastInst::castIsValid($1, Val, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - $$ = CastInst::Create($1, Val, DestTy); - delete $4; - } - | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { - if (isa($2->getType())) { - // vector select - if (!isa($4->getType()) - || !isa($6->getType()) ) - GEN_ERROR("vector select value types must be vector types"); - const VectorType* cond_type = cast($2->getType()); - const VectorType* select_type = cast($4->getType()); - if (cond_type->getElementType() != Type::Int1Ty) - GEN_ERROR("vector select condition element type must be boolean"); - if (cond_type->getNumElements() != select_type->getNumElements()) - GEN_ERROR("vector select number of elements must be the same"); - } else { - if ($2->getType() != Type::Int1Ty) - GEN_ERROR("select condition must be boolean"); - } - if ($4->getType() != $6->getType()) - GEN_ERROR("select value types must match"); - $$ = SelectInst::Create($2, $4, $6); - CHECK_FOR_ERROR - } - | VAARG ResolvedVal ',' Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription()); - $$ = new VAArgInst($2, *$4); - delete $4; - CHECK_FOR_ERROR - } - | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { - if (!ExtractElementInst::isValidOperands($2, $4)) - GEN_ERROR("Invalid extractelement operands"); - $$ = new ExtractElementInst($2, $4); - CHECK_FOR_ERROR - } - | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { - if (!InsertElementInst::isValidOperands($2, $4, $6)) - GEN_ERROR("Invalid insertelement operands"); - $$ = InsertElementInst::Create($2, $4, $6); - CHECK_FOR_ERROR - } - | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal { - if (!ShuffleVectorInst::isValidOperands($2, $4, $6)) - GEN_ERROR("Invalid shufflevector operands"); - $$ = new ShuffleVectorInst($2, $4, $6); - CHECK_FOR_ERROR - } - | PHI_TOK PHIList { - const Type *Ty = $2->front().first->getType(); - if (!Ty->isFirstClassType()) - GEN_ERROR("PHI node operands must be of first class type"); - $$ = PHINode::Create(Ty); - ((PHINode*)$$)->reserveOperandSpace($2->size()); - while ($2->begin() != $2->end()) { - if ($2->front().first->getType() != Ty) - GEN_ERROR("All elements of a PHI node must be of the same type"); - cast($$)->addIncoming($2->front().first, $2->front().second); - $2->pop_front(); - } - delete $2; // Free the list... - CHECK_FOR_ERROR - } - | OptTailCall OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')' - OptFuncAttrs { - - // Handle the short syntax - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast($4->get())) || - !(Ty = dyn_cast(PFTy->getElementType()))) { - // Pull out the types of all of the arguments... - std::vector ParamTypes; - ParamList::iterator I = $7->begin(), E = $7->end(); - for (; I != E; ++I) { - const Type *Ty = I->Val->getType(); - if (Ty == Type::VoidTy) - GEN_ERROR("Short call syntax cannot be used with varargs"); - ParamTypes.push_back(Ty); - } - - if (!FunctionType::isValidReturnType(*$4)) - GEN_ERROR("Invalid result type for LLVM function"); - - Ty = FunctionType::get($4->get(), ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); - } - - Value *V = getVal(PFTy, $5); // Get the function we're calling... - CHECK_FOR_ERROR - - // Check for call to invalid intrinsic to avoid crashing later. - if (Function *theF = dyn_cast(V)) { - if (theF->hasName() && (theF->getValueName()->getKeyLength() >= 5) && - (0 == strncmp(theF->getValueName()->getKeyData(), "llvm.", 5)) && - !theF->getIntrinsicID(true)) - GEN_ERROR("Call to invalid LLVM intrinsic function '" + - theF->getName() + "'"); - } - - // Set up the Attributes for the function - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = $3; - if ($9 != Attribute::None) { - if ($9 & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - $9 = $9 ^ Attribute::ZExt; - } - if ($9 & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - $9 = $9 ^ Attribute::SExt; - } - if ($9 & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - $9 = $9 ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - - // Check the arguments - ValueList Args; - if ($7->empty()) { // Has no arguments? - // Make sure no arguments is a good thing! - if (Ty->getNumParams() != 0) - GEN_ERROR("No arguments passed to a function that " - "expects arguments"); - } else { // Has arguments? - // Loop through FunctionType's arguments and ensure they are specified - // correctly. Also, gather any parameter attributes. - FunctionType::param_iterator I = Ty->param_begin(); - FunctionType::param_iterator E = Ty->param_end(); - ParamList::iterator ArgI = $7->begin(), ArgE = $7->end(); - unsigned index = 1; - - for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { - if (ArgI->Val->getType() != *I) - GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + - (*I)->getDescription() + "'"); - Args.push_back(ArgI->Val); - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - if (Ty->isVarArg()) { - if (I == E) - for (; ArgI != ArgE; ++ArgI, ++index) { - Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - } else if (I != E || ArgI != ArgE) - GEN_ERROR("Invalid number of parameters detected"); - } - if ($9 != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, $9)); - - // Finish off the Attributes and check them - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - // Create the call node - CallInst *CI = CallInst::Create(V, Args.begin(), Args.end()); - CI->setTailCall($1); - CI->setCallingConv($2); - CI->setAttributes(PAL); - $$ = CI; - delete $7; - delete $4; - CHECK_FOR_ERROR - } - | MemoryInst { - $$ = $1; - CHECK_FOR_ERROR - }; - -OptVolatile : VOLATILE { - $$ = true; - CHECK_FOR_ERROR - } - | /* empty */ { - $$ = false; - CHECK_FOR_ERROR - }; - - - -MemoryInst : MALLOC Types OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - $$ = new MallocInst(*$2, 0, $3); - delete $2; - CHECK_FOR_ERROR - } - | MALLOC Types ',' INTTYPE ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if ($4 != Type::Int32Ty) - GEN_ERROR("Malloc array size is not a 32-bit integer!"); - Value* tmpVal = getVal($4, $5); - CHECK_FOR_ERROR - $$ = new MallocInst(*$2, tmpVal, $6); - delete $2; - } - | ALLOCA Types OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - $$ = new AllocaInst(*$2, 0, $3); - delete $2; - CHECK_FOR_ERROR - } - | ALLOCA Types ',' INTTYPE ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if ($4 != Type::Int32Ty) - GEN_ERROR("Alloca array size is not a 32-bit integer!"); - Value* tmpVal = getVal($4, $5); - CHECK_FOR_ERROR - $$ = new AllocaInst(*$2, tmpVal, $6); - delete $2; - } - | FREE ResolvedVal { - if (!isa($2->getType())) - GEN_ERROR("Trying to free nonpointer type " + - $2->getType()->getDescription() + ""); - $$ = new FreeInst($2); - CHECK_FOR_ERROR - } - - | OptVolatile LOAD Types ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!isa($3->get())) - GEN_ERROR("Can't load from nonpointer type: " + - (*$3)->getDescription()); - if (!cast($3->get())->getElementType()->isFirstClassType()) - GEN_ERROR("Can't load from pointer of non-first-class type: " + - (*$3)->getDescription()); - Value* tmpVal = getVal(*$3, $4); - CHECK_FOR_ERROR - $$ = new LoadInst(tmpVal, "", $1, $5); - delete $3; - } - | OptVolatile STORE ResolvedVal ',' Types ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); - const PointerType *PT = dyn_cast($5->get()); - if (!PT) - GEN_ERROR("Can't store to a nonpointer type: " + - (*$5)->getDescription()); - const Type *ElTy = PT->getElementType(); - if (ElTy != $3->getType()) - GEN_ERROR("Can't store '" + $3->getType()->getDescription() + - "' into space of type '" + ElTy->getDescription() + "'"); - - Value* tmpVal = getVal(*$5, $6); - CHECK_FOR_ERROR - $$ = new StoreInst($3, tmpVal, $1, $7); - delete $5; - } - | GETRESULT Types ValueRef ',' EUINT64VAL { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get()) && !isa($2->get())) - GEN_ERROR("getresult insn requires an aggregate operand"); - if (!ExtractValueInst::getIndexedType(*$2, $5)) - GEN_ERROR("Invalid getresult index for type '" + - (*$2)->getDescription()+ "'"); - - Value *tmpVal = getVal(*$2, $3); - CHECK_FOR_ERROR - $$ = ExtractValueInst::Create(tmpVal, $5); - delete $2; - } - | GETELEMENTPTR Types ValueRef IndexList { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get())) - GEN_ERROR("getelementptr insn requires pointer operand"); - - if (!GetElementPtrInst::getIndexedType(*$2, $4->begin(), $4->end())) - GEN_ERROR("Invalid getelementptr indices for type '" + - (*$2)->getDescription()+ "'"); - Value* tmpVal = getVal(*$2, $3); - CHECK_FOR_ERROR - $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end()); - delete $2; - delete $4; - } - | EXTRACTVALUE Types ValueRef ConstantIndexList { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get()) && !isa($2->get())) - GEN_ERROR("extractvalue insn requires an aggregate operand"); - - if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end())) - GEN_ERROR("Invalid extractvalue indices for type '" + - (*$2)->getDescription()+ "'"); - Value* tmpVal = getVal(*$2, $3); - CHECK_FOR_ERROR - $$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end()); - delete $2; - delete $4; - } - | INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get()) && !isa($2->get())) - GEN_ERROR("extractvalue insn requires an aggregate operand"); - - if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get()) - GEN_ERROR("Invalid insertvalue indices for type '" + - (*$2)->getDescription()+ "'"); - Value* aggVal = getVal(*$2, $3); - Value* tmpVal = getVal(*$5, $6); - CHECK_FOR_ERROR - $$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end()); - delete $2; - delete $5; - delete $7; - }; - - -%% - -// common code from the two 'RunVMAsmParser' functions -static Module* RunParser(Module * M) { - CurModule.CurrentModule = M; - // Check to make sure the parser succeeded - if (yyparse()) { - if (ParserResult) - delete ParserResult; - return 0; - } - - // Emit an error if there are any unresolved types left. - if (!CurModule.LateResolveTypes.empty()) { - const ValID &DID = CurModule.LateResolveTypes.begin()->first; - if (DID.Type == ValID::LocalName) { - GenerateError("Undefined type remains at eof: '"+DID.getName() + "'"); - } else { - GenerateError("Undefined type remains at eof: #" + itostr(DID.Num)); - } - if (ParserResult) - delete ParserResult; - return 0; - } - - // Emit an error if there are any unresolved values left. - if (!CurModule.LateResolveValues.empty()) { - Value *V = CurModule.LateResolveValues.back(); - std::map >::iterator I = - CurModule.PlaceHolderInfo.find(V); - - if (I != CurModule.PlaceHolderInfo.end()) { - ValID &DID = I->second.first; - if (DID.Type == ValID::LocalName) { - GenerateError("Undefined value remains at eof: "+DID.getName() + "'"); - } else { - GenerateError("Undefined value remains at eof: #" + itostr(DID.Num)); - } - if (ParserResult) - delete ParserResult; - return 0; - } - } - - // Check to make sure that parsing produced a result - if (!ParserResult) - return 0; - - // Reset ParserResult variable while saving its value for the result. - Module *Result = ParserResult; - ParserResult = 0; - - return Result; -} - -void llvm::GenerateError(const std::string &message, int LineNo) { - if (LineNo == -1) LineNo = LLLgetLineNo(); - // TODO: column number in exception - if (TheParseError) - TheParseError->setError(LLLgetFilename(), message, LineNo); - TriggerError = 1; -} - -int yyerror(const char *ErrorMsg) { - std::string where = LLLgetFilename() + ":" + utostr(LLLgetLineNo()) + ": "; - std::string errMsg = where + "error: " + std::string(ErrorMsg); - if (yychar != YYEMPTY && yychar != 0) { - errMsg += " while reading token: '"; - errMsg += std::string(LLLgetTokenStart(), - LLLgetTokenStart()+LLLgetTokenLength()) + "'"; - } - GenerateError(errMsg); - return 0; -} diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs deleted file mode 100644 index 7028ea3fe0d..00000000000 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ /dev/null @@ -1,3636 +0,0 @@ -//===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the bison parser for LLVM assembly languages files. -// -//===----------------------------------------------------------------------===// - -%{ -#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 -#include -#include -#include - -// 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 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 Types; - std::map 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 > PlaceHolderInfo; - - // GlobalRefs - This maintains a mapping between '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, 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 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(Ty)) { - // Check to see if this is an unresolved type - std::map::iterator I = LateResolveTypes.begin(); - std::map::iterator E = LateResolveTypes.end(); - for ( ; I != E; ++I) { - if (I->second.get() == OpTy) - return true; - } - } else if (const SequentialType* SeqTy = dyn_cast(Ty)) { - const Type* TheTy = SeqTy->getElementType(); - if (TheTy->isAbstract() && TheTy != Ty) { - std::vector::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(Ty)) { - for (unsigned i = 0; i < StrTy->getNumElements(); ++i) { - const Type* TheTy = StrTy->getElementType(i); - if (TheTy->isAbstract() && TheTy != Ty) { - std::vector::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 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::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(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(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(Ty) && - ConstantInt::isValueValidForType(Ty, D.UConstPool64)) - return ConstantInt::get(Ty, D.UConstPool64); - - if (!isa(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(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(Ty)) { - GenerateError("Cannot create a a non pointer null"); - return 0; - } - return ConstantPointerNull::get(cast(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(Ty); - const FunctionType *FTy = - PTy ? dyn_cast(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(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(Ty); - if (!PTy) { - GenerateError("Invalid type for reference to global" ); - return 0; - } - const Type* ElTy = PTy->getElementType(); - if (const FunctionType *FTy = dyn_cast(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::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::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(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(CurFun.Values[ID.Num]); - else - GenerateError("Reference to label '%" + utostr(ID.Num) + - "' is actually of type '"+ - CurFun.Values[ID.Num]->getType()->getDescription() + "'"); - } - } else { - GenerateError("Illegal label reference " + ID.getName()); - return 0; - } - - // If its already been defined, return it now. - if (BB) { - ID.destroy(); // Free strdup'd memory. - return BB; - } - - // Otherwise, this block has not been seen before, create it. - std::string Name; - if (ID.Type == ValID::LocalName) - Name = ID.getName(); - BB = BasicBlock::Create(Name, CurFun.CurrentFunction); - - // Insert it in the forward refs map. - CurFun.BBForwardRefs[ID] = BB; - - 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(ValueList &LateResolvers, ValueList *FutureLateResolvers) { - // Loop over LateResolveDefs fixing up stuff that couldn't be resolved - while (!LateResolvers.empty()) { - Value *V = LateResolvers.back(); - LateResolvers.pop_back(); - - std::map >::iterator PHI = - CurModule.PlaceHolderInfo.find(V); - assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error!"); - - ValID &DID = PHI->second.first; - - Value *TheRealValue = getExistingVal(V->getType(), DID); - if (TriggerError) - return; - 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::LocalName || DID.Type == ValID::GlobalName) { - GenerateError("Reference to an invalid definition: '" +DID.getName()+ - "' of type '" + V->getType()->getDescription() + "'", - PHI->second.second); - return; - } else { - GenerateError("Reference to an invalid definition: #" + - itostr(DID.Num) + " of type '" + - V->getType()->getDescription() + "'", - PHI->second.second); - return; - } - } - } - 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(std::string *Name, const Type *ToTy) { - ValID D; - if (Name) - D = ValID::createLocalName(*Name); - else - D = ValID::createLocalID(CurModule.Types.size()); - - std::map::iterator I = - CurModule.LateResolveTypes.find(D); - if (I != CurModule.LateResolveTypes.end()) { - ((DerivedType*)I->second.get())->refineAbstractTypeTo(ToTy); - I->first.destroy(); - CurModule.LateResolveTypes.erase(I); - } - D.destroy(); -} - -// 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, std::string *NameStr) { - if (!NameStr) return; - std::string Name(*NameStr); // Copy string - delete NameStr; // Free old string - - if (V->getType() == Type::VoidTy) { - GenerateError("Can't assign name '" + Name+"' to value with void type"); - return; - } - - assert(inFunctionScope() && "Must be in function scope!"); - ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable(); - if (ST.lookup(Name)) { - GenerateError("Redefinition of value '" + Name + "' of type '" + - V->getType()->getDescription() + "'"); - return; - } - - // 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(std::string *NameStr, - GlobalValue::LinkageTypes Linkage, - GlobalValue::VisibilityTypes Visibility, - bool isConstantGlobal, const Type *Ty, - Constant *Initializer, bool IsThreadLocal, - unsigned AddressSpace = 0) { - if (isa(Ty)) { - GenerateError("Cannot declare global vars of function type"); - return 0; - } - if (Ty == Type::LabelTy) { - GenerateError("Cannot declare global vars of label type"); - return 0; - } - - const PointerType *PTy = PointerType::get(Ty, AddressSpace); - - std::string Name; - if (NameStr) { - Name = *NameStr; // Copy string - delete NameStr; // Free old string - } - - // See if this global value was forward referenced. If so, recycle the - // object. - ValID ID; - if (!Name.empty()) { - ID = ValID::createGlobalName(Name); - } else { - ID = ValID::createGlobalID(CurModule.Values.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(FWGV); - CurModule.CurrentModule->getGlobalList().remove(GV); - CurModule.CurrentModule->getGlobalList().push_back(GV); - GV->setInitializer(Initializer); - GV->setLinkage(Linkage); - GV->setVisibility(Visibility); - GV->setConstant(isConstantGlobal); - GV->setThreadLocal(IsThreadLocal); - InsertValue(GV, CurModule.Values); - ID.destroy(); - return GV; - } - - ID.destroy(); - - // If this global has a name - if (!Name.empty()) { - // if the global we're parsing has an initializer (is a definition) and - // has external linkage. - if (Initializer && Linkage != GlobalValue::InternalLinkage) - // If there is already a global with external linkage with this name - if (CurModule.CurrentModule->getGlobalVariable(Name, false)) { - // If we allow this GVar to get created, it will be renamed in the - // symbol table because it conflicts with an existing GVar. We can't - // allow redefinition of GVars whose linking indicates that their name - // must stay the same. Issue the error. - GenerateError("Redefinition of global variable named '" + Name + - "' of type '" + Ty->getDescription() + "'"); - return 0; - } - } - - // Otherwise there is no existing GV to use, create one now. - GlobalVariable *GV = - new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, - CurModule.CurrentModule, IsThreadLocal, AddressSpace); - GV->setVisibility(Visibility); - 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, std::string *NameStr) { - assert(!inFunctionScope() && "Can't give types function-local names!"); - if (NameStr == 0) return false; - - std::string Name(*NameStr); // Copy string - delete NameStr; // Free old string - - // We don't allow assigning names to void type - if (T == Type::VoidTy) { - GenerateError("Can't assign name '" + Name + "' to the void type"); - return false; - } - - // 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(Existing)) { - // We ARE replacing an opaque type! - const_cast(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. - GenerateError("Redefinition of type named '" + Name + "' of type '" + - T->getDescription() + "'"); - } - - 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 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 isn't abstract, or if there are no up-references in it, then there is - // nothing to resolve here. - if (!ty->isAbstract() || UpRefs.empty()) 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; -} - -//===----------------------------------------------------------------------===// -// RunVMAsmParser - Define an interface to this parser -//===----------------------------------------------------------------------===// -// -static Module* RunParser(Module * M); - -Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { - InitLLLexer(MB); - Module *M = RunParser(new Module(LLLgetFilename())); - FreeLexer(); - return M; -} - -%} - -%union { - llvm::Module *ModuleVal; - llvm::Function *FunctionVal; - llvm::BasicBlock *BasicBlockVal; - llvm::TerminatorInst *TermInstVal; - llvm::Instruction *InstVal; - llvm::Constant *ConstVal; - - const llvm::Type *PrimType; - std::list *TypeList; - llvm::PATypeHolder *TypeVal; - llvm::Value *ValueVal; - std::vector *ValueList; - std::vector *ConstantList; - llvm::ArgListType *ArgList; - llvm::TypeWithAttrs TypeWithAttrs; - llvm::TypeWithAttrsList *TypeWithAttrsList; - llvm::ParamList *ParamList; - - // Represent the RHS of PHI node - std::list > *PHIList; - std::vector > *JumpTable; - std::vector *ConstVector; - - llvm::GlobalValue::LinkageTypes Linkage; - llvm::GlobalValue::VisibilityTypes Visibility; - llvm::Attributes Attributes; - llvm::APInt *APIntVal; - int64_t SInt64Val; - uint64_t UInt64Val; - int SIntVal; - unsigned UIntVal; - llvm::APFloat *FPVal; - bool BoolVal; - - std::string *StrVal; // This memory must be deleted - llvm::ValID ValIDVal; - - llvm::Instruction::BinaryOps BinaryOpVal; - llvm::Instruction::TermOps TermOpVal; - llvm::Instruction::MemoryOps MemOpVal; - llvm::Instruction::CastOps CastOpVal; - llvm::Instruction::OtherOps OtherOpVal; - llvm::ICmpInst::Predicate IPredicate; - llvm::FCmpInst::Predicate FPredicate; -} - -%type Module -%type Function FunctionProto FunctionHeader BasicBlockList -%type BasicBlock InstructionList -%type BBTerminatorInst -%type Inst InstVal MemoryInst -%type ConstVal ConstExpr AliaseeRef -%type ConstVector -%type ArgList ArgListH -%type PHIList -%type ParamList // For call param lists & GEP indices -%type IndexList // For GEP indices -%type ConstantIndexList // For insertvalue/extractvalue indices -%type TypeListI -%type ArgTypeList ArgTypeListI -%type ArgType -%type JumpTable -%type GlobalType // GLOBAL or CONSTANT? -%type ThreadLocal // 'thread_local' or not -%type OptVolatile // 'volatile' or not -%type OptTailCall // TAIL CALL or plain CALL. -%type OptSideEffect // 'sideeffect' or not. -%type GVInternalLinkage GVExternalLinkage -%type FunctionDefineLinkage FunctionDeclareLinkage -%type AliasLinkage -%type GVVisibilityStyle - -// ValueRef - Unresolved reference to a definition or BB -%type ValueRef ConstValueRef SymbolicValueRef -%type ResolvedVal // pair -%type ReturnedVal -// Tokens and types for handling constant integer values -// -// ESINT64VAL - A negative number within long long range -%token ESINT64VAL - -// EUINT64VAL - A positive number within uns. long long range -%token EUINT64VAL - -// ESAPINTVAL - A negative number with arbitrary precision -%token ESAPINTVAL - -// EUAPINTVAL - A positive number with arbitrary precision -%token EUAPINTVAL - -%token LOCALVAL_ID GLOBALVAL_ID // %123 @123 -%token FPVAL // Float or Double constant - -// Built in types... -%type Types ResultTypes -%type PrimType // Classifications -%token VOID INTTYPE -%token FLOAT DOUBLE X86_FP80 FP128 PPC_FP128 LABEL -%token TYPE - - -%token LOCALVAR GLOBALVAR LABELSTR -%token STRINGCONSTANT ATSTRINGCONSTANT PCTSTRINGCONSTANT -%type LocalName OptLocalName OptLocalAssign -%type GlobalName OptGlobalAssign GlobalAssign -%type OptSection SectionString OptGC - -%type OptAlign OptCAlign OptAddrSpace - -%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK -%token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL -%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING -%token DLLIMPORT DLLEXPORT EXTERN_WEAK COMMON -%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE -%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT -%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK -%token DATALAYOUT -%type OptCallingConv LocalNumber -%type OptAttributes Attribute -%type OptFuncAttrs FuncAttr -%type OptRetAttrs RetAttr - -// Basic Block Terminating Operators -%token RET BR SWITCH INVOKE UNWIND UNREACHABLE - -// Binary Operators -%type ArithmeticOps LogicalOps // Binops Subcatagories -%token ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR -%token SHL LSHR ASHR - -%token ICMP FCMP VICMP VFCMP -%type IPredicates -%type FPredicates -%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE -%token OEQ ONE OLT OGT OLE OGE ORD UNO UEQ UNE - -// Memory Instructions -%token MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR - -// Cast Operators -%type CastOps -%token TRUNC ZEXT SEXT FPTRUNC FPEXT BITCAST -%token UITOFP SITOFP FPTOUI FPTOSI INTTOPTR PTRTOINT - -// Other Operators -%token PHI_TOK SELECT VAARG -%token EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR -%token GETRESULT -%token EXTRACTVALUE INSERTVALUE - -// Function Attributes -%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS NOCAPTURE BYVAL -%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE SSP SSPREQ NEST - -// Visibility Styles -%token DEFAULT HIDDEN PROTECTED - -%start Module -%% - - -// Operations that are notably excluded from this list include: -// RET, BR, & SWITCH because they end basic blocks and are treated specially. -// -ArithmeticOps: ADD | SUB | MUL | UDIV | SDIV | FDIV | UREM | SREM | FREM; -LogicalOps : SHL | LSHR | ASHR | AND | OR | XOR; -CastOps : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | BITCAST | - UITOFP | SITOFP | FPTOUI | FPTOSI | INTTOPTR | PTRTOINT; - -IPredicates - : EQ { $$ = ICmpInst::ICMP_EQ; } | NE { $$ = ICmpInst::ICMP_NE; } - | SLT { $$ = ICmpInst::ICMP_SLT; } | SGT { $$ = ICmpInst::ICMP_SGT; } - | SLE { $$ = ICmpInst::ICMP_SLE; } | SGE { $$ = ICmpInst::ICMP_SGE; } - | ULT { $$ = ICmpInst::ICMP_ULT; } | UGT { $$ = ICmpInst::ICMP_UGT; } - | ULE { $$ = ICmpInst::ICMP_ULE; } | UGE { $$ = ICmpInst::ICMP_UGE; } - ; - -FPredicates - : OEQ { $$ = FCmpInst::FCMP_OEQ; } | ONE { $$ = FCmpInst::FCMP_ONE; } - | OLT { $$ = FCmpInst::FCMP_OLT; } | OGT { $$ = FCmpInst::FCMP_OGT; } - | OLE { $$ = FCmpInst::FCMP_OLE; } | OGE { $$ = FCmpInst::FCMP_OGE; } - | ORD { $$ = FCmpInst::FCMP_ORD; } | UNO { $$ = FCmpInst::FCMP_UNO; } - | UEQ { $$ = FCmpInst::FCMP_UEQ; } | UNE { $$ = FCmpInst::FCMP_UNE; } - | ULT { $$ = FCmpInst::FCMP_ULT; } | UGT { $$ = FCmpInst::FCMP_UGT; } - | ULE { $$ = FCmpInst::FCMP_ULE; } | UGE { $$ = FCmpInst::FCMP_UGE; } - | TRUETOK { $$ = FCmpInst::FCMP_TRUE; } - | FALSETOK { $$ = FCmpInst::FCMP_FALSE; } - ; - -LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ; -OptLocalName : LocalName | /*empty*/ { $$ = 0; }; - -OptAddrSpace : ADDRSPACE '(' EUINT64VAL ')' { $$=$3; } - | /*empty*/ { $$=0; }; - -/// OptLocalAssign - Value producing statements have an optional assignment -/// component. -OptLocalAssign : LocalName '=' { - $$ = $1; - CHECK_FOR_ERROR - } - | /*empty*/ { - $$ = 0; - CHECK_FOR_ERROR - }; - -LocalNumber : LOCALVAL_ID '=' { - $$ = $1; - CHECK_FOR_ERROR -}; - - -GlobalName : GLOBALVAR | ATSTRINGCONSTANT ; - -OptGlobalAssign : GlobalAssign - | /*empty*/ { - $$ = 0; - CHECK_FOR_ERROR - }; - -GlobalAssign : GlobalName '=' { - $$ = $1; - CHECK_FOR_ERROR - }; - -GVInternalLinkage - : INTERNAL { $$ = GlobalValue::InternalLinkage; } - | WEAK { $$ = GlobalValue::WeakLinkage; } - | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } - | APPENDING { $$ = GlobalValue::AppendingLinkage; } - | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } - | COMMON { $$ = GlobalValue::CommonLinkage; } - ; - -GVExternalLinkage - : DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } - | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } - | EXTERNAL { $$ = GlobalValue::ExternalLinkage; } - ; - -GVVisibilityStyle - : /*empty*/ { $$ = GlobalValue::DefaultVisibility; } - | DEFAULT { $$ = GlobalValue::DefaultVisibility; } - | HIDDEN { $$ = GlobalValue::HiddenVisibility; } - | PROTECTED { $$ = GlobalValue::ProtectedVisibility; } - ; - -FunctionDeclareLinkage - : /*empty*/ { $$ = GlobalValue::ExternalLinkage; } - | DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } - | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } - ; - -FunctionDefineLinkage - : /*empty*/ { $$ = GlobalValue::ExternalLinkage; } - | INTERNAL { $$ = GlobalValue::InternalLinkage; } - | LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } - | WEAK { $$ = GlobalValue::WeakLinkage; } - | DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } - ; - -AliasLinkage - : /*empty*/ { $$ = GlobalValue::ExternalLinkage; } - | WEAK { $$ = GlobalValue::WeakLinkage; } - | INTERNAL { $$ = GlobalValue::InternalLinkage; } - ; - -OptCallingConv : /*empty*/ { $$ = CallingConv::C; } | - CCC_TOK { $$ = CallingConv::C; } | - FASTCC_TOK { $$ = CallingConv::Fast; } | - COLDCC_TOK { $$ = CallingConv::Cold; } | - X86_STDCALLCC_TOK { $$ = CallingConv::X86_StdCall; } | - X86_FASTCALLCC_TOK { $$ = CallingConv::X86_FastCall; } | - CC_TOK EUINT64VAL { - if ((unsigned)$2 != $2) - GEN_ERROR("Calling conv too large"); - $$ = $2; - CHECK_FOR_ERROR - }; - -Attribute : ZEROEXT { $$ = Attribute::ZExt; } - | ZEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | SEXT { $$ = Attribute::SExt; } - | INREG { $$ = Attribute::InReg; } - | SRET { $$ = Attribute::StructRet; } - | NOALIAS { $$ = Attribute::NoAlias; } - | NOCAPTURE { $$ = Attribute::NoCapture; } - | BYVAL { $$ = Attribute::ByVal; } - | NEST { $$ = Attribute::Nest; } - | ALIGN EUINT64VAL { $$ = - Attribute::constructAlignmentFromInt($2); } - ; - -OptAttributes : /* empty */ { $$ = Attribute::None; } - | OptAttributes Attribute { - $$ = $1 | $2; - } - ; - -RetAttr : INREG { $$ = Attribute::InReg; } - | ZEROEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | NOALIAS { $$ = Attribute::NoAlias; } - ; - -OptRetAttrs : /* empty */ { $$ = Attribute::None; } - | OptRetAttrs RetAttr { - $$ = $1 | $2; - } - ; - - -FuncAttr : NORETURN { $$ = Attribute::NoReturn; } - | NOUNWIND { $$ = Attribute::NoUnwind; } - | INREG { $$ = Attribute::InReg; } - | ZEROEXT { $$ = Attribute::ZExt; } - | SIGNEXT { $$ = Attribute::SExt; } - | READNONE { $$ = Attribute::ReadNone; } - | READONLY { $$ = Attribute::ReadOnly; } - | NOINLINE { $$ = Attribute::NoInline; } - | ALWAYSINLINE { $$ = Attribute::AlwaysInline; } - | OPTSIZE { $$ = Attribute::OptimizeForSize; } - | SSP { $$ = Attribute::StackProtect; } - | SSPREQ { $$ = Attribute::StackProtectReq; } - ; - -OptFuncAttrs : /* empty */ { $$ = Attribute::None; } - | OptFuncAttrs FuncAttr { - $$ = $1 | $2; - } - ; - - -OptGC : /* empty */ { $$ = 0; } - | GC STRINGCONSTANT { - $$ = $2; - } - ; - -// OptAlign/OptCAlign - An optional alignment, and an optional alignment with -// a comma before it. -OptAlign : /*empty*/ { $$ = 0; } | - ALIGN EUINT64VAL { - $$ = $2; - if ($$ != 0 && !isPowerOf2_32($$)) - GEN_ERROR("Alignment must be a power of two"); - if ($$ > 0x40000000) - GEN_ERROR("Alignment too large"); - CHECK_FOR_ERROR -}; -OptCAlign : /*empty*/ { $$ = 0; } | - ',' ALIGN EUINT64VAL { - $$ = $3; - if ($$ != 0 && !isPowerOf2_32($$)) - GEN_ERROR("Alignment must be a power of two"); - if ($$ > 0x40000000) - GEN_ERROR("Alignment too large"); - CHECK_FOR_ERROR -}; - - - -SectionString : SECTION STRINGCONSTANT { - for (unsigned i = 0, e = $2->length(); i != e; ++i) - if ((*$2)[i] == '"' || (*$2)[i] == '\\') - GEN_ERROR("Invalid character in section name"); - $$ = $2; - CHECK_FOR_ERROR -}; - -OptSection : /*empty*/ { $$ = 0; } | - SectionString { $$ = $1; }; - -// GlobalVarAttributes - Used to pass the attributes string on a global. CurGV -// is set to be the global we are processing. -// -GlobalVarAttributes : /* empty */ {} | - ',' GlobalVarAttribute GlobalVarAttributes {}; -GlobalVarAttribute : SectionString { - CurGV->setSection(*$1); - delete $1; - CHECK_FOR_ERROR - } - | ALIGN EUINT64VAL { - if ($2 != 0 && !isPowerOf2_32($2)) - GEN_ERROR("Alignment must be a power of two"); - if ($2 > 0x40000000) - GEN_ERROR("Alignment too large"); - CurGV->setAlignment($2); - CHECK_FOR_ERROR - }; - -//===----------------------------------------------------------------------===// -// Types includes all predefined types... except void, because it can only be -// used in specific contexts (function returning void for example). - -// Derived types are added later... -// -PrimType : INTTYPE | FLOAT | DOUBLE | PPC_FP128 | FP128 | X86_FP80 | LABEL ; - -Types - : OPAQUE { - $$ = new PATypeHolder(OpaqueType::get()); - CHECK_FOR_ERROR - } - | PrimType { - $$ = new PATypeHolder($1); - CHECK_FOR_ERROR - } - | Types OptAddrSpace '*' { // Pointer type? - if (*$1 == Type::LabelTy) - GEN_ERROR("Cannot form a pointer to a basic block"); - $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $2))); - delete $1; - CHECK_FOR_ERROR - } - | SymbolicValueRef { // Named types are also simple types... - const Type* tmp = getTypeVal($1); - CHECK_FOR_ERROR - $$ = new PATypeHolder(tmp); - } - | '\\' EUINT64VAL { // Type UpReference - if ($2 > (uint64_t)~0U) GEN_ERROR("Value out of range"); - OpaqueType *OT = OpaqueType::get(); // Use temporary placeholder - UpRefs.push_back(UpRefRecord((unsigned)$2, OT)); // Add to vector... - $$ = new PATypeHolder(OT); - UR_OUT("New Upreference!\n"); - CHECK_FOR_ERROR - } - | Types '(' ArgTypeListI ')' OptFuncAttrs { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - const Type *RetTy = *$1; - if (!FunctionType::isValidReturnType(RetTy)) - GEN_ERROR("Invalid result type for LLVM function"); - - std::vector Params; - TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); - for (; I != E; ++I ) { - const Type *Ty = I->Ty->get(); - Params.push_back(Ty); - } - - bool isVarArg = Params.size() && Params.back() == Type::VoidTy; - if (isVarArg) Params.pop_back(); - - for (unsigned i = 0; i != Params.size(); ++i) - if (!(Params[i]->isFirstClassType() || isa(Params[i]))) - GEN_ERROR("Function arguments must be value types!"); - - CHECK_FOR_ERROR - - FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg); - delete $1; // Delete the return type handle - $$ = new PATypeHolder(HandleUpRefs(FT)); - - // Delete the argument list - for (I = $3->begin() ; I != E; ++I ) { - delete I->Ty; - } - delete $3; - - CHECK_FOR_ERROR - } - | VOID '(' ArgTypeListI ')' OptFuncAttrs { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - std::vector Params; - TypeWithAttrsList::iterator I = $3->begin(), E = $3->end(); - for ( ; I != E; ++I ) { - const Type* Ty = I->Ty->get(); - Params.push_back(Ty); - } - - bool isVarArg = Params.size() && Params.back() == Type::VoidTy; - if (isVarArg) Params.pop_back(); - - for (unsigned i = 0; i != Params.size(); ++i) - if (!(Params[i]->isFirstClassType() || isa(Params[i]))) - GEN_ERROR("Function arguments must be value types!"); - - CHECK_FOR_ERROR - - FunctionType *FT = FunctionType::get($1, Params, isVarArg); - $$ = new PATypeHolder(HandleUpRefs(FT)); - - // Delete the argument list - for (I = $3->begin() ; I != E; ++I ) { - delete I->Ty; - } - delete $3; - - CHECK_FOR_ERROR - } - - | '[' EUINT64VAL 'x' Types ']' { // Sized array type? - $$ = new PATypeHolder(HandleUpRefs(ArrayType::get(*$4, $2))); - delete $4; - CHECK_FOR_ERROR - } - | '<' EUINT64VAL 'x' Types '>' { // Vector type? - const llvm::Type* ElemTy = $4->get(); - if ((unsigned)$2 != $2) - GEN_ERROR("Unsigned result not equal to signed result"); - if (!ElemTy->isFloatingPoint() && !ElemTy->isInteger()) - GEN_ERROR("Element type of a VectorType must be primitive"); - $$ = new PATypeHolder(HandleUpRefs(VectorType::get(*$4, (unsigned)$2))); - delete $4; - CHECK_FOR_ERROR - } - | '{' TypeListI '}' { // Structure type? - std::vector Elements; - for (std::list::iterator I = $2->begin(), - E = $2->end(); I != E; ++I) - Elements.push_back(*I); - - $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements))); - delete $2; - CHECK_FOR_ERROR - } - | '{' '}' { // Empty structure type? - $$ = new PATypeHolder(StructType::get(std::vector())); - CHECK_FOR_ERROR - } - | '<' '{' TypeListI '}' '>' { - std::vector Elements; - for (std::list::iterator I = $3->begin(), - E = $3->end(); I != E; ++I) - Elements.push_back(*I); - - $$ = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true))); - delete $3; - CHECK_FOR_ERROR - } - | '<' '{' '}' '>' { // Empty structure type? - $$ = new PATypeHolder(StructType::get(std::vector(), true)); - CHECK_FOR_ERROR - } - ; - -ArgType - : Types OptAttributes { - // Allow but ignore attributes on function types; this permits auto-upgrade. - // FIXME: remove in LLVM 3.0. - $$.Ty = $1; - $$.Attrs = Attribute::None; - } - ; - -ResultTypes - : Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if (!(*$1)->isFirstClassType() && !isa($1->get())) - GEN_ERROR("LLVM functions cannot return aggregate types"); - $$ = $1; - } - | VOID { - $$ = new PATypeHolder(Type::VoidTy); - } - ; - -ArgTypeList : ArgType { - $$ = new TypeWithAttrsList(); - $$->push_back($1); - CHECK_FOR_ERROR - } - | ArgTypeList ',' ArgType { - ($$=$1)->push_back($3); - CHECK_FOR_ERROR - } - ; - -ArgTypeListI - : ArgTypeList - | ArgTypeList ',' DOTDOTDOT { - $$=$1; - TypeWithAttrs TWA; TWA.Attrs = Attribute::None; - TWA.Ty = new PATypeHolder(Type::VoidTy); - $$->push_back(TWA); - CHECK_FOR_ERROR - } - | DOTDOTDOT { - $$ = new TypeWithAttrsList; - TypeWithAttrs TWA; TWA.Attrs = Attribute::None; - TWA.Ty = new PATypeHolder(Type::VoidTy); - $$->push_back(TWA); - CHECK_FOR_ERROR - } - | /*empty*/ { - $$ = new TypeWithAttrsList(); - CHECK_FOR_ERROR - }; - -// TypeList - Used for struct declarations and as a basis for function type -// declaration type lists -// -TypeListI : Types { - $$ = new std::list(); - $$->push_back(*$1); - delete $1; - CHECK_FOR_ERROR - } - | TypeListI ',' Types { - ($$=$1)->push_back(*$3); - delete $3; - CHECK_FOR_ERROR - }; - -// ConstVal - The various declarations that go into the constant pool. This -// production is used ONLY to represent constants that show up AFTER a 'const', -// 'constant' or 'global' token at global scope. Constants that can be inlined -// into other expressions (such as integers and constexprs) are handled by the -// ResolvedVal, ValueRef and ConstValueRef productions. -// -ConstVal: Types '[' ConstVector ']' { // Nonempty unsized arr - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const ArrayType *ATy = dyn_cast($1->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'"); - const Type *ETy = ATy->getElementType(); - uint64_t NumElements = ATy->getNumElements(); - - // Verify that we have the correct size... - if (NumElements != uint64_t(-1) && NumElements != $3->size()) - GEN_ERROR("Type mismatch: constant sized array initialized with " + - utostr($3->size()) + " arguments, but has size of " + - utostr(NumElements) + ""); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $3->size(); i++) { - if (ETy != (*$3)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*$3)[i]->getType()->getDescription() + "'."); - } - - $$ = ConstantArray::get(ATy, *$3); - delete $1; delete $3; - CHECK_FOR_ERROR - } - | Types '[' ']' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const ArrayType *ATy = dyn_cast($1->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'"); - - uint64_t NumElements = ATy->getNumElements(); - if (NumElements != uint64_t(-1) && NumElements != 0) - GEN_ERROR("Type mismatch: constant sized array initialized with 0" - " arguments, but has size of " + utostr(NumElements) +""); - $$ = ConstantArray::get(ATy, std::vector()); - delete $1; - CHECK_FOR_ERROR - } - | Types 'c' STRINGCONSTANT { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const ArrayType *ATy = dyn_cast($1->get()); - if (ATy == 0) - GEN_ERROR("Cannot make array constant with type: '" + - (*$1)->getDescription() + "'"); - - uint64_t NumElements = ATy->getNumElements(); - const Type *ETy = ATy->getElementType(); - if (NumElements != uint64_t(-1) && NumElements != $3->length()) - GEN_ERROR("Can't build string constant of size " + - utostr($3->length()) + - " when array has size " + utostr(NumElements) + ""); - std::vector Vals; - if (ETy == Type::Int8Ty) { - for (uint64_t i = 0; i < $3->length(); ++i) - Vals.push_back(ConstantInt::get(ETy, (*$3)[i])); - } else { - delete $3; - GEN_ERROR("Cannot build string arrays of non byte sized elements"); - } - delete $3; - $$ = ConstantArray::get(ATy, Vals); - delete $1; - CHECK_FOR_ERROR - } - | Types '<' ConstVector '>' { // Nonempty unsized arr - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const VectorType *PTy = dyn_cast($1->get()); - if (PTy == 0) - GEN_ERROR("Cannot make packed constant with type: '" + - (*$1)->getDescription() + "'"); - const Type *ETy = PTy->getElementType(); - unsigned NumElements = PTy->getNumElements(); - - // Verify that we have the correct size... - if (NumElements != unsigned(-1) && NumElements != (unsigned)$3->size()) - GEN_ERROR("Type mismatch: constant sized packed initialized with " + - utostr($3->size()) + " arguments, but has size of " + - utostr(NumElements) + ""); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $3->size(); i++) { - if (ETy != (*$3)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*$3)[i]->getType()->getDescription() + "'."); - } - - $$ = ConstantVector::get(PTy, *$3); - delete $1; delete $3; - CHECK_FOR_ERROR - } - | Types '{' ConstVector '}' { - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if ($3->size() != STy->getNumContainedTypes()) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that constants are compatible with the type initializer! - for (unsigned i = 0, e = $3->size(); i != e; ++i) - if ((*$3)[i]->getType() != STy->getElementType(i)) - GEN_ERROR("Expected type '" + - STy->getElementType(i)->getDescription() + - "' for element #" + utostr(i) + - " of structure initializer"); - - // Check to ensure that Type is not packed - if (STy->isPacked()) - GEN_ERROR("Unpacked Initializer to vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, *$3); - delete $1; delete $3; - CHECK_FOR_ERROR - } - | Types '{' '}' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if (STy->getNumContainedTypes() != 0) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that Type is not packed - if (STy->isPacked()) - GEN_ERROR("Unpacked Initializer to vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, std::vector()); - delete $1; - CHECK_FOR_ERROR - } - | Types '<' '{' ConstVector '}' '>' { - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if ($4->size() != STy->getNumContainedTypes()) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that constants are compatible with the type initializer! - for (unsigned i = 0, e = $4->size(); i != e; ++i) - if ((*$4)[i]->getType() != STy->getElementType(i)) - GEN_ERROR("Expected type '" + - STy->getElementType(i)->getDescription() + - "' for element #" + utostr(i) + - " of structure initializer"); - - // Check to ensure that Type is packed - if (!STy->isPacked()) - GEN_ERROR("Vector initializer to non-vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, *$4); - delete $1; delete $4; - CHECK_FOR_ERROR - } - | Types '<' '{' '}' '>' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const StructType *STy = dyn_cast($1->get()); - if (STy == 0) - GEN_ERROR("Cannot make struct constant with type: '" + - (*$1)->getDescription() + "'"); - - if (STy->getNumContainedTypes() != 0) - GEN_ERROR("Illegal number of initializers for structure type"); - - // Check to ensure that Type is packed - if (!STy->isPacked()) - GEN_ERROR("Vector initializer to non-vector type '" + - STy->getDescription() + "'"); - - $$ = ConstantStruct::get(STy, std::vector()); - delete $1; - CHECK_FOR_ERROR - } - | Types NULL_TOK { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const PointerType *PTy = dyn_cast($1->get()); - if (PTy == 0) - GEN_ERROR("Cannot make null pointer constant with type: '" + - (*$1)->getDescription() + "'"); - - $$ = ConstantPointerNull::get(PTy); - delete $1; - CHECK_FOR_ERROR - } - | Types UNDEF { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - $$ = UndefValue::get($1->get()); - delete $1; - CHECK_FOR_ERROR - } - | Types SymbolicValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const PointerType *Ty = dyn_cast($1->get()); - if (Ty == 0) - GEN_ERROR("Global const reference must be a pointer type " + (*$1)->getDescription()); - - // ConstExprs can exist in the body of a function, thus creating - // GlobalValues whenever they refer to a variable. Because we are in - // the context of a function, getExistingVal will search the functions - // symbol table instead of the module symbol table for the global symbol, - // which throws things all off. To get around this, we just tell - // getExistingVal that we are at global scope here. - // - Function *SavedCurFn = CurFun.CurrentFunction; - CurFun.CurrentFunction = 0; - - Value *V = getExistingVal(Ty, $2); - CHECK_FOR_ERROR - - CurFun.CurrentFunction = SavedCurFn; - - // If this is an initializer for a constant pointer, which is referencing a - // (currently) undefined variable, create a stub now that shall be replaced - // in the future with the right type of variable. - // - if (V == 0) { - assert(isa(Ty) && "Globals may only be used as pointers!"); - const PointerType *PT = cast(Ty); - - // First check to see if the forward references value is already created! - PerModuleInfo::GlobalRefsType::iterator I = - CurModule.GlobalRefs.find(std::make_pair(PT, $2)); - - if (I != CurModule.GlobalRefs.end()) { - V = I->second; // Placeholder already exists, use it... - $2.destroy(); - } else { - std::string Name; - if ($2.Type == ValID::GlobalName) - Name = $2.getName(); - else if ($2.Type != ValID::GlobalID) - GEN_ERROR("Invalid reference to global"); - - // Create the forward referenced global. - GlobalValue *GV; - if (const FunctionType *FTy = - dyn_cast(PT->getElementType())) { - GV = Function::Create(FTy, GlobalValue::ExternalWeakLinkage, Name, - CurModule.CurrentModule); - } else { - GV = new GlobalVariable(PT->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, - Name, CurModule.CurrentModule); - } - - // Keep track of the fact that we have a forward ref to recycle it - CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV)); - V = GV; - } - } - - $$ = cast(V); - delete $1; // Free the type handle - CHECK_FOR_ERROR - } - | Types ConstExpr { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if ($1->get() != $2->getType()) - GEN_ERROR("Mismatched types for constant expression: " + - (*$1)->getDescription() + " and " + $2->getType()->getDescription()); - $$ = $2; - delete $1; - CHECK_FOR_ERROR - } - | Types ZEROINITIALIZER { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - const Type *Ty = $1->get(); - if (isa(Ty) || Ty == Type::LabelTy || isa(Ty)) - GEN_ERROR("Cannot create a null initialized value of this type"); - $$ = Constant::getNullValue(Ty); - delete $1; - CHECK_FOR_ERROR - } - | Types ESINT64VAL { // integral constants - if (IntegerType *IT = dyn_cast($1->get())) { - if (!ConstantInt::isValueValidForType(IT, $2)) - GEN_ERROR("Constant value doesn't fit in type"); - $$ = ConstantInt::get(IT, $2, true); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete $1; - CHECK_FOR_ERROR - } - | Types ESAPINTVAL { // arbitrary precision integer constants - if (IntegerType *IT = dyn_cast($1->get())) { - if ($2->getBitWidth() > IT->getBitWidth()) - GEN_ERROR("Constant value does not fit in type"); - $2->sextOrTrunc(IT->getBitWidth()); - $$ = ConstantInt::get(*$2); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete $1; - delete $2; - CHECK_FOR_ERROR - } - | Types EUINT64VAL { // integral constants - if (IntegerType *IT = dyn_cast($1->get())) { - if (!ConstantInt::isValueValidForType(IT, $2)) - GEN_ERROR("Constant value doesn't fit in type"); - $$ = ConstantInt::get(IT, $2, false); - } else { - GEN_ERROR("integer constant must have integer type"); - } - delete $1; - CHECK_FOR_ERROR - } - | Types EUAPINTVAL { // arbitrary precision integer constants - if (IntegerType *IT = dyn_cast($1->get())) { - if ($2->getBitWidth() > IT->getBitWidth()) - GEN_ERROR("Constant value does not fit in type"); - $2->zextOrTrunc(IT->getBitWidth()); - $$ = ConstantInt::get(*$2); - } else { - GEN_ERROR("integer constant must have integer type"); - } - - delete $2; - delete $1; - CHECK_FOR_ERROR - } - | Types TRUETOK { // Boolean constants - if ($1->get() != Type::Int1Ty) - GEN_ERROR("Constant true must have type i1"); - $$ = ConstantInt::getTrue(); - delete $1; - CHECK_FOR_ERROR - } - | Types FALSETOK { // Boolean constants - if ($1->get() != Type::Int1Ty) - GEN_ERROR("Constant false must have type i1"); - $$ = ConstantInt::getFalse(); - delete $1; - CHECK_FOR_ERROR - } - | Types FPVAL { // Floating point constants - if (!ConstantFP::isValueValidForType($1->get(), *$2)) - GEN_ERROR("Floating point constant invalid for type"); - - // Lexer has no type info, so builds all float and double FP constants - // as double. Fix this here. Long double is done right. - if (&$2->getSemantics()==&APFloat::IEEEdouble && $1->get()==Type::FloatTy) { - bool ignored; - $2->convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, - &ignored); - } - $$ = ConstantFP::get(*$2); - delete $1; - delete $2; - CHECK_FOR_ERROR - }; - - -ConstExpr: CastOps '(' ConstVal TO Types ')' { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); - Constant *Val = $3; - const Type *DestTy = $5->get(); - if (!CastInst::castIsValid($1, $3, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - $$ = ConstantExpr::getCast($1, $3, DestTy); - delete $5; - } - | GETELEMENTPTR '(' ConstVal IndexList ')' { - if (!isa($3->getType())) - GEN_ERROR("GetElementPtr requires a pointer operand"); - - const Type *IdxTy = - GetElementPtrInst::getIndexedType($3->getType(), $4->begin(), $4->end()); - if (!IdxTy) - GEN_ERROR("Index list invalid for constant getelementptr"); - - SmallVector IdxVec; - for (unsigned i = 0, e = $4->size(); i != e; ++i) - if (Constant *C = dyn_cast((*$4)[i])) - IdxVec.push_back(C); - else - GEN_ERROR("Indices to constant getelementptr must be constants"); - - delete $4; - - $$ = ConstantExpr::getGetElementPtr($3, &IdxVec[0], IdxVec.size()); - CHECK_FOR_ERROR - } - | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { - if ($3->getType() != Type::Int1Ty) - GEN_ERROR("Select condition must be of boolean type"); - if ($5->getType() != $7->getType()) - GEN_ERROR("Select operand types must match"); - $$ = ConstantExpr::getSelect($3, $5, $7); - CHECK_FOR_ERROR - } - | ArithmeticOps '(' ConstVal ',' ConstVal ')' { - if ($3->getType() != $5->getType()) - GEN_ERROR("Binary operator types must match"); - CHECK_FOR_ERROR; - $$ = ConstantExpr::get($1, $3, $5); - } - | LogicalOps '(' ConstVal ',' ConstVal ')' { - if ($3->getType() != $5->getType()) - GEN_ERROR("Logical operator types must match"); - if (!$3->getType()->isInteger()) { - if (!isa($3->getType()) || - !cast($3->getType())->getElementType()->isInteger()) - GEN_ERROR("Logical operator requires integral operands"); - } - $$ = ConstantExpr::get($1, $3, $5); - CHECK_FOR_ERROR - } - | ICMP IPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("icmp operand types must match"); - $$ = ConstantExpr::getICmp($2, $4, $6); - } - | FCMP FPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("fcmp operand types must match"); - $$ = ConstantExpr::getFCmp($2, $4, $6); - } - | VICMP IPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("vicmp operand types must match"); - $$ = ConstantExpr::getVICmp($2, $4, $6); - } - | VFCMP FPredicates '(' ConstVal ',' ConstVal ')' { - if ($4->getType() != $6->getType()) - GEN_ERROR("vfcmp operand types must match"); - $$ = ConstantExpr::getVFCmp($2, $4, $6); - } - | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { - if (!ExtractElementInst::isValidOperands($3, $5)) - GEN_ERROR("Invalid extractelement operands"); - $$ = ConstantExpr::getExtractElement($3, $5); - CHECK_FOR_ERROR - } - | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' { - if (!InsertElementInst::isValidOperands($3, $5, $7)) - GEN_ERROR("Invalid insertelement operands"); - $$ = ConstantExpr::getInsertElement($3, $5, $7); - CHECK_FOR_ERROR - } - | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' { - if (!ShuffleVectorInst::isValidOperands($3, $5, $7)) - GEN_ERROR("Invalid shufflevector operands"); - $$ = ConstantExpr::getShuffleVector($3, $5, $7); - CHECK_FOR_ERROR - } - | EXTRACTVALUE '(' ConstVal ConstantIndexList ')' { - if (!isa($3->getType()) && !isa($3->getType())) - GEN_ERROR("ExtractValue requires an aggregate operand"); - - $$ = ConstantExpr::getExtractValue($3, &(*$4)[0], $4->size()); - delete $4; - CHECK_FOR_ERROR - } - | INSERTVALUE '(' ConstVal ',' ConstVal ConstantIndexList ')' { - if (!isa($3->getType()) && !isa($3->getType())) - GEN_ERROR("InsertValue requires an aggregate operand"); - - $$ = ConstantExpr::getInsertValue($3, $5, &(*$6)[0], $6->size()); - delete $6; - CHECK_FOR_ERROR - }; - - -// ConstVector - A list of comma separated constants. -ConstVector : ConstVector ',' ConstVal { - ($$ = $1)->push_back($3); - CHECK_FOR_ERROR - } - | ConstVal { - $$ = new std::vector(); - $$->push_back($1); - CHECK_FOR_ERROR - }; - - -// GlobalType - Match either GLOBAL or CONSTANT for global declarations... -GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }; - -// ThreadLocal -ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; }; - -// AliaseeRef - Match either GlobalValue or bitcast to GlobalValue. -AliaseeRef : ResultTypes SymbolicValueRef { - const Type* VTy = $1->get(); - Value *V = getVal(VTy, $2); - CHECK_FOR_ERROR - GlobalValue* Aliasee = dyn_cast(V); - if (!Aliasee) - GEN_ERROR("Aliases can be created only to global values"); - - $$ = Aliasee; - CHECK_FOR_ERROR - delete $1; - } - | BITCAST '(' AliaseeRef TO Types ')' { - Constant *Val = $3; - const Type *DestTy = $5->get(); - if (!CastInst::castIsValid($1, $3, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - - $$ = ConstantExpr::getCast($1, $3, DestTy); - CHECK_FOR_ERROR - delete $5; - }; - -//===----------------------------------------------------------------------===// -// Rules to match Modules -//===----------------------------------------------------------------------===// - -// Module rule: Capture the result of parsing the whole file into a result -// variable... -// -Module - : DefinitionList { - $$ = ParserResult = CurModule.CurrentModule; - CurModule.ModuleDone(); - CHECK_FOR_ERROR; - } - | /*empty*/ { - $$ = ParserResult = CurModule.CurrentModule; - CurModule.ModuleDone(); - CHECK_FOR_ERROR; - } - ; - -DefinitionList - : Definition - | DefinitionList Definition - ; - -Definition - : DEFINE { CurFun.isDeclare = false; } Function { - CurFun.FunctionDone(); - CHECK_FOR_ERROR - } - | DECLARE { CurFun.isDeclare = true; } FunctionProto { - CHECK_FOR_ERROR - } - | MODULE ASM_TOK AsmBlock { - CHECK_FOR_ERROR - } - | OptLocalAssign TYPE Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - // Eagerly resolve types. This is not an optimization, this is a - // requirement that is due to the fact that we could have this: - // - // %list = type { %list * } - // %list = type { %list * } ; repeated type decl - // - // If types are not resolved eagerly, then the two types will not be - // determined to be the same type! - // - ResolveTypeTo($1, *$3); - - if (!setTypeName(*$3, $1) && !$1) { - CHECK_FOR_ERROR - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back(*$3); - } - - delete $3; - CHECK_FOR_ERROR - } - | OptLocalAssign TYPE VOID { - ResolveTypeTo($1, $3); - - if (!setTypeName($3, $1) && !$1) { - CHECK_FOR_ERROR - // If this is a named type that is not a redefinition, add it to the slot - // table. - CurModule.Types.push_back($3); - } - CHECK_FOR_ERROR - } - | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal - OptAddrSpace { - /* "Externally Visible" Linkage */ - if ($5 == 0) - GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, - $2, $4, $5->getType(), $5, $3, $6); - CHECK_FOR_ERROR - } GlobalVarAttributes { - CurGV = 0; - } - | OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType - ConstVal OptAddrSpace { - if ($6 == 0) - GEN_ERROR("Global value initializer is not a constant"); - CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7); - CHECK_FOR_ERROR - } GlobalVarAttributes { - CurGV = 0; - } - | OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType - Types OptAddrSpace { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription()); - CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4, $7); - CHECK_FOR_ERROR - delete $6; - } GlobalVarAttributes { - CurGV = 0; - CHECK_FOR_ERROR - } - | OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage AliaseeRef { - std::string Name; - if ($1) { - Name = *$1; - delete $1; - } - if (Name.empty()) - GEN_ERROR("Alias name cannot be empty"); - - Constant* Aliasee = $5; - if (Aliasee == 0) - GEN_ERROR(std::string("Invalid aliasee for alias: ") + Name); - - GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), $4, Name, Aliasee, - CurModule.CurrentModule); - GA->setVisibility($2); - InsertValue(GA, CurModule.Values); - - - // If there was a forward reference of this alias, resolve it now. - - ValID ID; - if (!Name.empty()) - ID = ValID::createGlobalName(Name); - else - ID = ValID::createGlobalID(CurModule.Values.size()-1); - - if (GlobalValue *FWGV = - CurModule.GetForwardRefForGlobal(GA->getType(), ID)) { - // Replace uses of the fwdref with the actual alias. - FWGV->replaceAllUsesWith(GA); - if (GlobalVariable *GV = dyn_cast(FWGV)) - GV->eraseFromParent(); - else - cast(FWGV)->eraseFromParent(); - } - ID.destroy(); - - CHECK_FOR_ERROR - } - | TARGET TargetDefinition { - CHECK_FOR_ERROR - } - | DEPLIBS '=' LibrariesDefinition { - CHECK_FOR_ERROR - } - ; - - -AsmBlock : STRINGCONSTANT { - const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); - if (AsmSoFar.empty()) - CurModule.CurrentModule->setModuleInlineAsm(*$1); - else - CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+*$1); - delete $1; - CHECK_FOR_ERROR -}; - -TargetDefinition : TRIPLE '=' STRINGCONSTANT { - CurModule.CurrentModule->setTargetTriple(*$3); - delete $3; - } - | DATALAYOUT '=' STRINGCONSTANT { - CurModule.CurrentModule->setDataLayout(*$3); - delete $3; - }; - -LibrariesDefinition : '[' LibList ']'; - -LibList : LibList ',' STRINGCONSTANT { - CurModule.CurrentModule->addLibrary(*$3); - delete $3; - CHECK_FOR_ERROR - } - | STRINGCONSTANT { - CurModule.CurrentModule->addLibrary(*$1); - delete $1; - CHECK_FOR_ERROR - } - | /* empty: end of list */ { - CHECK_FOR_ERROR - } - ; - -//===----------------------------------------------------------------------===// -// Rules to match Function Headers -//===----------------------------------------------------------------------===// - -ArgListH : ArgListH ',' Types OptAttributes OptLocalName { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!(*$3)->isFirstClassType()) - GEN_ERROR("Argument types must be first-class"); - ArgListEntry E; E.Attrs = $4; E.Ty = $3; E.Name = $5; - $$ = $1; - $1->push_back(E); - CHECK_FOR_ERROR - } - | Types OptAttributes OptLocalName { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - if (!(*$1)->isFirstClassType()) - GEN_ERROR("Argument types must be first-class"); - ArgListEntry E; E.Attrs = $2; E.Ty = $1; E.Name = $3; - $$ = new ArgListType; - $$->push_back(E); - CHECK_FOR_ERROR - }; - -ArgList : ArgListH { - $$ = $1; - CHECK_FOR_ERROR - } - | ArgListH ',' DOTDOTDOT { - $$ = $1; - struct ArgListEntry E; - E.Ty = new PATypeHolder(Type::VoidTy); - E.Name = 0; - E.Attrs = Attribute::None; - $$->push_back(E); - CHECK_FOR_ERROR - } - | DOTDOTDOT { - $$ = new ArgListType; - struct ArgListEntry E; - E.Ty = new PATypeHolder(Type::VoidTy); - E.Name = 0; - E.Attrs = Attribute::None; - $$->push_back(E); - CHECK_FOR_ERROR - } - | /* empty */ { - $$ = 0; - CHECK_FOR_ERROR - }; - -FunctionHeaderH : OptCallingConv OptRetAttrs ResultTypes GlobalName '(' ArgList ')' - OptFuncAttrs OptSection OptAlign OptGC { - std::string FunctionName(*$4); - delete $4; // Free strdup'd memory! - - // Check the function result for abstractness if this is a define. We should - // have no abstract types at this point - if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($3)) - GEN_ERROR("Reference to abstract result: "+ $3->get()->getDescription()); - - if (!FunctionType::isValidReturnType(*$3)) - GEN_ERROR("Invalid result type for LLVM function"); - - std::vector ParamTypeList; - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = $2; - if ($8 != Attribute::None) { - if ($8 & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - $8 = $8 ^ Attribute::ZExt; - } - if ($8 & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - $8 = $8 ^ Attribute::SExt; - } - if ($8 & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - $8 = $8 ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - if ($6) { // If there are arguments... - unsigned index = 1; - for (ArgListType::iterator I = $6->begin(); I != $6->end(); ++I, ++index) { - const Type* Ty = I->Ty->get(); - if (!CurFun.isDeclare && CurModule.TypeIsUnresolved(I->Ty)) - GEN_ERROR("Reference to abstract argument: " + Ty->getDescription()); - ParamTypeList.push_back(Ty); - if (Ty != Type::VoidTy && I->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, I->Attrs)); - } - } - if ($8 != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, $8)); - - bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy; - if (isVarArg) ParamTypeList.pop_back(); - - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - FunctionType *FT = FunctionType::get(*$3, ParamTypeList, isVarArg); - const PointerType *PFT = PointerType::getUnqual(FT); - delete $3; - - ValID ID; - if (!FunctionName.empty()) { - ID = ValID::createGlobalName((char*)FunctionName.c_str()); - } else { - ID = ValID::createGlobalID(CurModule.Values.size()); - } - - Function *Fn = 0; - // See if this function was forward referenced. If so, recycle the object. - if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) { - // Move the function to the end of the list, from whereever it was - // previously inserted. - Fn = cast(FWRef); - assert(Fn->getAttributes().isEmpty() && - "Forward reference has parameter attributes!"); - CurModule.CurrentModule->getFunctionList().remove(Fn); - CurModule.CurrentModule->getFunctionList().push_back(Fn); - } else if (!FunctionName.empty() && // Merge with an earlier prototype? - (Fn = CurModule.CurrentModule->getFunction(FunctionName))) { - if (Fn->getFunctionType() != FT ) { - // The existing function doesn't have the same type. This is an overload - // error. - GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); - } else if (Fn->getAttributes() != PAL) { - // The existing function doesn't have the same parameter attributes. - // This is an overload error. - GEN_ERROR("Overload of function '" + FunctionName + "' not permitted."); - } else if (!CurFun.isDeclare && !Fn->isDeclaration()) { - // Neither the existing or the current function is a declaration and they - // have the same name and same type. Clearly this is a redefinition. - GEN_ERROR("Redefinition of function '" + FunctionName + "'"); - } else if (Fn->isDeclaration()) { - // Make sure to strip off any argument names so we can't get conflicts. - for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); - AI != AE; ++AI) - AI->setName(""); - } - } else { // Not already defined? - Fn = Function::Create(FT, GlobalValue::ExternalWeakLinkage, FunctionName, - CurModule.CurrentModule); - InsertValue(Fn, CurModule.Values); - } - - ID.destroy(); - CurFun.FunctionStart(Fn); - - if (CurFun.isDeclare) { - // If we have declaration, always overwrite linkage. This will allow us to - // correctly handle cases, when pointer to function is passed as argument to - // another function. - Fn->setLinkage(CurFun.Linkage); - Fn->setVisibility(CurFun.Visibility); - } - Fn->setCallingConv($1); - Fn->setAttributes(PAL); - Fn->setAlignment($10); - if ($9) { - Fn->setSection(*$9); - delete $9; - } - if ($11) { - Fn->setGC($11->c_str()); - delete $11; - } - - // Add all of the arguments we parsed to the function... - if ($6) { // Is null if empty... - if (isVarArg) { // Nuke the last entry - assert($6->back().Ty->get() == Type::VoidTy && $6->back().Name == 0 && - "Not a varargs marker!"); - delete $6->back().Ty; - $6->pop_back(); // Delete the last entry - } - Function::arg_iterator ArgIt = Fn->arg_begin(); - Function::arg_iterator ArgEnd = Fn->arg_end(); - unsigned Idx = 1; - for (ArgListType::iterator I = $6->begin(); - I != $6->end() && ArgIt != ArgEnd; ++I, ++ArgIt) { - delete I->Ty; // Delete the typeholder... - setValueName(ArgIt, I->Name); // Insert arg into symtab... - CHECK_FOR_ERROR - InsertValue(ArgIt); - Idx++; - } - - delete $6; // We're now done with the argument list - } - CHECK_FOR_ERROR -}; - -BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function - -FunctionHeader : FunctionDefineLinkage GVVisibilityStyle FunctionHeaderH BEGIN { - $$ = CurFun.CurrentFunction; - - // Make sure that we keep track of the linkage type even if there was a - // previous "declare". - $$->setLinkage($1); - $$->setVisibility($2); -}; - -END : ENDTOK | '}'; // Allow end of '}' to end a function - -Function : BasicBlockList END { - $$ = $1; - CHECK_FOR_ERROR -}; - -FunctionProto : FunctionDeclareLinkage GVVisibilityStyle FunctionHeaderH { - CurFun.CurrentFunction->setLinkage($1); - CurFun.CurrentFunction->setVisibility($2); - $$ = CurFun.CurrentFunction; - CurFun.FunctionDone(); - CHECK_FOR_ERROR - }; - -//===----------------------------------------------------------------------===// -// Rules to match Basic Blocks -//===----------------------------------------------------------------------===// - -OptSideEffect : /* empty */ { - $$ = false; - CHECK_FOR_ERROR - } - | SIDEEFFECT { - $$ = true; - CHECK_FOR_ERROR - }; - -ConstValueRef : ESINT64VAL { // A reference to a direct constant - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | EUINT64VAL { - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | ESAPINTVAL { // arbitrary precision integer constants - $$ = ValID::create(*$1, true); - delete $1; - CHECK_FOR_ERROR - } - | EUAPINTVAL { // arbitrary precision integer constants - $$ = ValID::create(*$1, false); - delete $1; - CHECK_FOR_ERROR - } - | FPVAL { // Perhaps it's an FP constant? - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | TRUETOK { - $$ = ValID::create(ConstantInt::getTrue()); - CHECK_FOR_ERROR - } - | FALSETOK { - $$ = ValID::create(ConstantInt::getFalse()); - CHECK_FOR_ERROR - } - | NULL_TOK { - $$ = ValID::createNull(); - CHECK_FOR_ERROR - } - | UNDEF { - $$ = ValID::createUndef(); - CHECK_FOR_ERROR - } - | ZEROINITIALIZER { // A vector zero constant. - $$ = ValID::createZeroInit(); - CHECK_FOR_ERROR - } - | '<' ConstVector '>' { // Nonempty unsized packed vector - const Type *ETy = (*$2)[0]->getType(); - unsigned NumElements = $2->size(); - - if (!ETy->isInteger() && !ETy->isFloatingPoint()) - GEN_ERROR("Invalid vector element type: " + ETy->getDescription()); - - VectorType* pt = VectorType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt)); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $2->size(); i++) { - if (ETy != (*$2)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '" + - (*$2)[i]->getType()->getDescription() + "'."); - } - - $$ = ValID::create(ConstantVector::get(pt, *$2)); - delete PTy; delete $2; - CHECK_FOR_ERROR - } - | '[' ConstVector ']' { // Nonempty unsized arr - const Type *ETy = (*$2)[0]->getType(); - uint64_t NumElements = $2->size(); - - if (!ETy->isFirstClassType()) - GEN_ERROR("Invalid array element type: " + ETy->getDescription()); - - ArrayType *ATy = ArrayType::get(ETy, NumElements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(ATy)); - - // Verify all elements are correct type! - for (unsigned i = 0; i < $2->size(); i++) { - if (ETy != (*$2)[i]->getType()) - GEN_ERROR("Element #" + utostr(i) + " is not of type '" + - ETy->getDescription() +"' as required!\nIt is of type '"+ - (*$2)[i]->getType()->getDescription() + "'."); - } - - $$ = ValID::create(ConstantArray::get(ATy, *$2)); - delete PTy; delete $2; - CHECK_FOR_ERROR - } - | '[' ']' { - // Use undef instead of an array because it's inconvenient to determine - // the element type at this point, there being no elements to examine. - $$ = ValID::createUndef(); - CHECK_FOR_ERROR - } - | 'c' STRINGCONSTANT { - uint64_t NumElements = $2->length(); - const Type *ETy = Type::Int8Ty; - - ArrayType *ATy = ArrayType::get(ETy, NumElements); - - std::vector Vals; - for (unsigned i = 0; i < $2->length(); ++i) - Vals.push_back(ConstantInt::get(ETy, (*$2)[i])); - delete $2; - $$ = ValID::create(ConstantArray::get(ATy, Vals)); - CHECK_FOR_ERROR - } - | '{' ConstVector '}' { - std::vector Elements($2->size()); - for (unsigned i = 0, e = $2->size(); i != e; ++i) - Elements[i] = (*$2)[i]->getType(); - - const StructType *STy = StructType::get(Elements); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); - - $$ = ValID::create(ConstantStruct::get(STy, *$2)); - delete PTy; delete $2; - CHECK_FOR_ERROR - } - | '{' '}' { - const StructType *STy = StructType::get(std::vector()); - $$ = ValID::create(ConstantStruct::get(STy, std::vector())); - CHECK_FOR_ERROR - } - | '<' '{' ConstVector '}' '>' { - std::vector Elements($3->size()); - for (unsigned i = 0, e = $3->size(); i != e; ++i) - Elements[i] = (*$3)[i]->getType(); - - const StructType *STy = StructType::get(Elements, /*isPacked=*/true); - PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(STy)); - - $$ = ValID::create(ConstantStruct::get(STy, *$3)); - delete PTy; delete $3; - CHECK_FOR_ERROR - } - | '<' '{' '}' '>' { - const StructType *STy = StructType::get(std::vector(), - /*isPacked=*/true); - $$ = ValID::create(ConstantStruct::get(STy, std::vector())); - CHECK_FOR_ERROR - } - | ConstExpr { - $$ = ValID::create($1); - CHECK_FOR_ERROR - } - | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT { - $$ = ValID::createInlineAsm(*$3, *$5, $2); - delete $3; - delete $5; - CHECK_FOR_ERROR - }; - -// SymbolicValueRef - Reference to one of two ways of symbolically refering to -// another value. -// -SymbolicValueRef : LOCALVAL_ID { // Is it an integer reference...? - $$ = ValID::createLocalID($1); - CHECK_FOR_ERROR - } - | GLOBALVAL_ID { - $$ = ValID::createGlobalID($1); - CHECK_FOR_ERROR - } - | LocalName { // Is it a named reference...? - $$ = ValID::createLocalName(*$1); - delete $1; - CHECK_FOR_ERROR - } - | GlobalName { // Is it a named reference...? - $$ = ValID::createGlobalName(*$1); - delete $1; - CHECK_FOR_ERROR - }; - -// ValueRef - A reference to a definition... either constant or symbolic -ValueRef : SymbolicValueRef | ConstValueRef; - - -// ResolvedVal - a pair. This is used only in cases where the -// type immediately preceeds the value reference, and allows complex constant -// pool references (for things like: 'ret [2 x int] [ int 12, int 42]') -ResolvedVal : Types ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - $$ = getVal(*$1, $2); - delete $1; - CHECK_FOR_ERROR - } - ; - -ReturnedVal : ResolvedVal { - $$ = new std::vector(); - $$->push_back($1); - CHECK_FOR_ERROR - } - | ReturnedVal ',' ResolvedVal { - ($$=$1)->push_back($3); - CHECK_FOR_ERROR - }; - -BasicBlockList : BasicBlockList BasicBlock { - $$ = $1; - CHECK_FOR_ERROR - } - | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks - $$ = $1; - CHECK_FOR_ERROR - }; - - -// Basic blocks are terminated by branching instructions: -// br, br/cc, switch, ret -// -BasicBlock : InstructionList OptLocalAssign BBTerminatorInst { - setValueName($3, $2); - CHECK_FOR_ERROR - InsertValue($3); - $1->getInstList().push_back($3); - $$ = $1; - CHECK_FOR_ERROR - }; - -BasicBlock : InstructionList LocalNumber BBTerminatorInst { - CHECK_FOR_ERROR - int ValNum = InsertValue($3); - if (ValNum != (int)$2) - GEN_ERROR("Result value number %" + utostr($2) + - " is incorrect, expected %" + utostr((unsigned)ValNum)); - - $1->getInstList().push_back($3); - $$ = $1; - CHECK_FOR_ERROR -}; - - -InstructionList : InstructionList Inst { - if (CastInst *CI1 = dyn_cast($2)) - if (CastInst *CI2 = dyn_cast(CI1->getOperand(0))) - if (CI2->getParent() == 0) - $1->getInstList().push_back(CI2); - $1->getInstList().push_back($2); - $$ = $1; - CHECK_FOR_ERROR - } - | /* empty */ { // Empty space between instruction lists - $$ = defineBBVal(ValID::createLocalID(CurFun.NextValNum)); - CHECK_FOR_ERROR - } - | LABELSTR { // Labelled (named) basic block - $$ = defineBBVal(ValID::createLocalName(*$1)); - delete $1; - CHECK_FOR_ERROR - - }; - -BBTerminatorInst : - RET ReturnedVal { // Return with a result... - ValueList &VL = *$2; - assert(!VL.empty() && "Invalid ret operands!"); - const Type *ReturnType = CurFun.CurrentFunction->getReturnType(); - if (VL.size() > 1 || - (isa(ReturnType) && - (VL.empty() || VL[0]->getType() != ReturnType))) { - Value *RV = UndefValue::get(ReturnType); - for (unsigned i = 0, e = VL.size(); i != e; ++i) { - Instruction *I = InsertValueInst::Create(RV, VL[i], i, "mrv"); - ($-1)->getInstList().push_back(I); - RV = I; - } - $$ = ReturnInst::Create(RV); - } else { - $$ = ReturnInst::Create(VL[0]); - } - delete $2; - CHECK_FOR_ERROR - } - | RET VOID { // Return with no result... - $$ = ReturnInst::Create(); - CHECK_FOR_ERROR - } - | BR LABEL ValueRef { // Unconditional Branch... - BasicBlock* tmpBB = getBBVal($3); - CHECK_FOR_ERROR - $$ = BranchInst::Create(tmpBB); - } // Conditional Branch... - | BR INTTYPE ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { - if (cast($2)->getBitWidth() != 1) - GEN_ERROR("Branch condition must have type i1"); - BasicBlock* tmpBBA = getBBVal($6); - CHECK_FOR_ERROR - BasicBlock* tmpBBB = getBBVal($9); - CHECK_FOR_ERROR - Value* tmpVal = getVal(Type::Int1Ty, $3); - CHECK_FOR_ERROR - $$ = BranchInst::Create(tmpBBA, tmpBBB, tmpVal); - } - | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' JumpTable ']' { - Value* tmpVal = getVal($2, $3); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, $8->size()); - $$ = S; - - std::vector >::iterator I = $8->begin(), - E = $8->end(); - for (; I != E; ++I) { - if (ConstantInt *CI = dyn_cast(I->first)) - S->addCase(CI, I->second); - else - GEN_ERROR("Switch case is constant, but not a simple integer"); - } - delete $8; - CHECK_FOR_ERROR - } - | SWITCH INTTYPE ValueRef ',' LABEL ValueRef '[' ']' { - Value* tmpVal = getVal($2, $3); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - SwitchInst *S = SwitchInst::Create(tmpVal, tmpBB, 0); - $$ = S; - CHECK_FOR_ERROR - } - | INVOKE OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')' - OptFuncAttrs TO LABEL ValueRef UNWIND LABEL ValueRef { - - // Handle the short syntax - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast($4->get())) || - !(Ty = dyn_cast(PFTy->getElementType()))) { - // Pull out the types of all of the arguments... - std::vector ParamTypes; - ParamList::iterator I = $7->begin(), E = $7->end(); - for (; I != E; ++I) { - const Type *Ty = I->Val->getType(); - if (Ty == Type::VoidTy) - GEN_ERROR("Short call syntax cannot be used with varargs"); - ParamTypes.push_back(Ty); - } - - if (!FunctionType::isValidReturnType(*$4)) - GEN_ERROR("Invalid result type for LLVM function"); - - Ty = FunctionType::get($4->get(), ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); - } - - delete $4; - - Value *V = getVal(PFTy, $5); // Get the function we're calling... - CHECK_FOR_ERROR - BasicBlock *Normal = getBBVal($12); - CHECK_FOR_ERROR - BasicBlock *Except = getBBVal($15); - CHECK_FOR_ERROR - - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = $3; - if ($9 != Attribute::None) { - if ($9 & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - $9 = $9 ^ Attribute::ZExt; - } - if ($9 & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - $9 = $9 ^ Attribute::SExt; - } - if ($9 & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - $9 = $9 ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - - // Check the arguments - ValueList Args; - if ($7->empty()) { // Has no arguments? - // Make sure no arguments is a good thing! - if (Ty->getNumParams() != 0) - GEN_ERROR("No arguments passed to a function that " - "expects arguments"); - } else { // Has arguments? - // Loop through FunctionType's arguments and ensure they are specified - // correctly! - FunctionType::param_iterator I = Ty->param_begin(); - FunctionType::param_iterator E = Ty->param_end(); - ParamList::iterator ArgI = $7->begin(), ArgE = $7->end(); - unsigned index = 1; - - for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { - if (ArgI->Val->getType() != *I) - GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + - (*I)->getDescription() + "'"); - Args.push_back(ArgI->Val); - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - - if (Ty->isVarArg()) { - if (I == E) - for (; ArgI != ArgE; ++ArgI, ++index) { - Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - } else if (I != E || ArgI != ArgE) - GEN_ERROR("Invalid number of parameters detected"); - } - if ($9 != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, $9)); - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - // Create the InvokeInst - InvokeInst *II = InvokeInst::Create(V, Normal, Except, - Args.begin(), Args.end()); - II->setCallingConv($2); - II->setAttributes(PAL); - $$ = II; - delete $7; - CHECK_FOR_ERROR - } - | UNWIND { - $$ = new UnwindInst(); - CHECK_FOR_ERROR - } - | UNREACHABLE { - $$ = new UnreachableInst(); - CHECK_FOR_ERROR - }; - - - -JumpTable : JumpTable INTTYPE ConstValueRef ',' LABEL ValueRef { - $$ = $1; - Constant *V = cast(getExistingVal($2, $3)); - CHECK_FOR_ERROR - if (V == 0) - GEN_ERROR("May only switch on a constant pool value"); - - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - $$->push_back(std::make_pair(V, tmpBB)); - } - | INTTYPE ConstValueRef ',' LABEL ValueRef { - $$ = new std::vector >(); - Constant *V = cast(getExistingVal($1, $2)); - CHECK_FOR_ERROR - - if (V == 0) - GEN_ERROR("May only switch on a constant pool value"); - - BasicBlock* tmpBB = getBBVal($5); - CHECK_FOR_ERROR - $$->push_back(std::make_pair(V, tmpBB)); - }; - -Inst : OptLocalAssign InstVal { - // Is this definition named?? if so, assign the name... - setValueName($2, $1); - CHECK_FOR_ERROR - InsertValue($2); - $$ = $2; - CHECK_FOR_ERROR - }; - -Inst : LocalNumber InstVal { - CHECK_FOR_ERROR - int ValNum = InsertValue($2); - - if (ValNum != (int)$1) - GEN_ERROR("Result value number %" + utostr($1) + - " is incorrect, expected %" + utostr((unsigned)ValNum)); - - $$ = $2; - CHECK_FOR_ERROR - }; - - -PHIList : Types '[' ValueRef ',' ValueRef ']' { // Used for PHI nodes - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - $$ = new std::list >(); - Value* tmpVal = getVal(*$1, $3); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($5); - CHECK_FOR_ERROR - $$->push_back(std::make_pair(tmpVal, tmpBB)); - delete $1; - } - | PHIList ',' '[' ValueRef ',' ValueRef ']' { - $$ = $1; - Value* tmpVal = getVal($1->front().first->getType(), $4); - CHECK_FOR_ERROR - BasicBlock* tmpBB = getBBVal($6); - CHECK_FOR_ERROR - $1->push_back(std::make_pair(tmpVal, tmpBB)); - }; - - -ParamList : Types OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription()); - // Used for call and invoke instructions - $$ = new ParamList(); - ParamListEntry E; E.Attrs = $2 | $4; E.Val = getVal($1->get(), $3); - $$->push_back(E); - delete $1; - CHECK_FOR_ERROR - } - | LABEL OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - // Labels are only valid in ASMs - $$ = new ParamList(); - ParamListEntry E; E.Attrs = $2 | $4; E.Val = getBBVal($3); - $$->push_back(E); - CHECK_FOR_ERROR - } - | ParamList ',' Types OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - $$ = $1; - ParamListEntry E; E.Attrs = $4 | $6; E.Val = getVal($3->get(), $5); - $$->push_back(E); - delete $3; - CHECK_FOR_ERROR - } - | ParamList ',' LABEL OptAttributes ValueRef OptAttributes { - // FIXME: Remove trailing OptAttributes in LLVM 3.0, it was a mistake in 2.0 - $$ = $1; - ParamListEntry E; E.Attrs = $4 | $6; E.Val = getBBVal($5); - $$->push_back(E); - CHECK_FOR_ERROR - } - | /*empty*/ { $$ = new ParamList(); }; - -IndexList // Used for gep instructions and constant expressions - : /*empty*/ { $$ = new std::vector(); } - | IndexList ',' ResolvedVal { - $$ = $1; - $$->push_back($3); - CHECK_FOR_ERROR - } - ; - -ConstantIndexList // Used for insertvalue and extractvalue instructions - : ',' EUINT64VAL { - $$ = new std::vector(); - if ((unsigned)$2 != $2) - GEN_ERROR("Index " + utostr($2) + " is not valid for insertvalue or extractvalue."); - $$->push_back($2); - } - | ConstantIndexList ',' EUINT64VAL { - $$ = $1; - if ((unsigned)$3 != $3) - GEN_ERROR("Index " + utostr($3) + " is not valid for insertvalue or extractvalue."); - $$->push_back($3); - CHECK_FOR_ERROR - } - ; - -OptTailCall : TAIL CALL { - $$ = true; - CHECK_FOR_ERROR - } - | CALL { - $$ = false; - CHECK_FOR_ERROR - }; - -InstVal : ArithmeticOps Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!(*$2)->isInteger() && !(*$2)->isFloatingPoint() && - !isa((*$2).get())) - GEN_ERROR( - "Arithmetic operator requires integer, FP, or packed operands"); - Value* val1 = getVal(*$2, $3); - CHECK_FOR_ERROR - Value* val2 = getVal(*$2, $5); - CHECK_FOR_ERROR - $$ = BinaryOperator::Create($1, val1, val2); - if ($$ == 0) - GEN_ERROR("binary operator returned null"); - delete $2; - } - | LogicalOps Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!(*$2)->isInteger()) { - if (!isa($2->get()) || - !cast($2->get())->getElementType()->isInteger()) - GEN_ERROR("Logical operator requires integral operands"); - } - Value* tmpVal1 = getVal(*$2, $3); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$2, $5); - CHECK_FOR_ERROR - $$ = BinaryOperator::Create($1, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("binary operator returned null"); - delete $2; - } - | ICMP IPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("icmp operator returned null"); - delete $3; - } - | FCMP FPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("fcmp operator returned null"); - delete $3; - } - | VICMP IPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!isa((*$3).get())) - GEN_ERROR("Scalar types not supported by vicmp instruction"); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("vicmp operator returned null"); - delete $3; - } - | VFCMP FPredicates Types ValueRef ',' ValueRef { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!isa((*$3).get())) - GEN_ERROR("Scalar types not supported by vfcmp instruction"); - Value* tmpVal1 = getVal(*$3, $4); - CHECK_FOR_ERROR - Value* tmpVal2 = getVal(*$3, $6); - CHECK_FOR_ERROR - $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2); - if ($$ == 0) - GEN_ERROR("vfcmp operator returned null"); - delete $3; - } - | CastOps ResolvedVal TO Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription()); - Value* Val = $2; - const Type* DestTy = $4->get(); - if (!CastInst::castIsValid($1, Val, DestTy)) - GEN_ERROR("invalid cast opcode for cast from '" + - Val->getType()->getDescription() + "' to '" + - DestTy->getDescription() + "'"); - $$ = CastInst::Create($1, Val, DestTy); - delete $4; - } - | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { - if (isa($2->getType())) { - // vector select - if (!isa($4->getType()) - || !isa($6->getType()) ) - GEN_ERROR("vector select value types must be vector types"); - const VectorType* cond_type = cast($2->getType()); - const VectorType* select_type = cast($4->getType()); - if (cond_type->getElementType() != Type::Int1Ty) - GEN_ERROR("vector select condition element type must be boolean"); - if (cond_type->getNumElements() != select_type->getNumElements()) - GEN_ERROR("vector select number of elements must be the same"); - } else { - if ($2->getType() != Type::Int1Ty) - GEN_ERROR("select condition must be boolean"); - } - if ($4->getType() != $6->getType()) - GEN_ERROR("select value types must match"); - $$ = SelectInst::Create($2, $4, $6); - CHECK_FOR_ERROR - } - | VAARG ResolvedVal ',' Types { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription()); - $$ = new VAArgInst($2, *$4); - delete $4; - CHECK_FOR_ERROR - } - | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { - if (!ExtractElementInst::isValidOperands($2, $4)) - GEN_ERROR("Invalid extractelement operands"); - $$ = new ExtractElementInst($2, $4); - CHECK_FOR_ERROR - } - | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { - if (!InsertElementInst::isValidOperands($2, $4, $6)) - GEN_ERROR("Invalid insertelement operands"); - $$ = InsertElementInst::Create($2, $4, $6); - CHECK_FOR_ERROR - } - | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal { - if (!ShuffleVectorInst::isValidOperands($2, $4, $6)) - GEN_ERROR("Invalid shufflevector operands"); - $$ = new ShuffleVectorInst($2, $4, $6); - CHECK_FOR_ERROR - } - | PHI_TOK PHIList { - const Type *Ty = $2->front().first->getType(); - if (!Ty->isFirstClassType()) - GEN_ERROR("PHI node operands must be of first class type"); - $$ = PHINode::Create(Ty); - ((PHINode*)$$)->reserveOperandSpace($2->size()); - while ($2->begin() != $2->end()) { - if ($2->front().first->getType() != Ty) - GEN_ERROR("All elements of a PHI node must be of the same type"); - cast($$)->addIncoming($2->front().first, $2->front().second); - $2->pop_front(); - } - delete $2; // Free the list... - CHECK_FOR_ERROR - } - | OptTailCall OptCallingConv OptRetAttrs ResultTypes ValueRef '(' ParamList ')' - OptFuncAttrs { - - // Handle the short syntax - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - if (!(PFTy = dyn_cast($4->get())) || - !(Ty = dyn_cast(PFTy->getElementType()))) { - // Pull out the types of all of the arguments... - std::vector ParamTypes; - ParamList::iterator I = $7->begin(), E = $7->end(); - for (; I != E; ++I) { - const Type *Ty = I->Val->getType(); - if (Ty == Type::VoidTy) - GEN_ERROR("Short call syntax cannot be used with varargs"); - ParamTypes.push_back(Ty); - } - - if (!FunctionType::isValidReturnType(*$4)) - GEN_ERROR("Invalid result type for LLVM function"); - - Ty = FunctionType::get($4->get(), ParamTypes, false); - PFTy = PointerType::getUnqual(Ty); - } - - Value *V = getVal(PFTy, $5); // Get the function we're calling... - CHECK_FOR_ERROR - - // Check for call to invalid intrinsic to avoid crashing later. - if (Function *theF = dyn_cast(V)) { - if (theF->hasName() && (theF->getValueName()->getKeyLength() >= 5) && - (0 == strncmp(theF->getValueName()->getKeyData(), "llvm.", 5)) && - !theF->getIntrinsicID(true)) - GEN_ERROR("Call to invalid LLVM intrinsic function '" + - theF->getName() + "'"); - } - - // Set up the Attributes for the function - SmallVector Attrs; - //FIXME : In 3.0, stop accepting zext, sext and inreg as optional function - //attributes. - Attributes RetAttrs = $3; - if ($9 != Attribute::None) { - if ($9 & Attribute::ZExt) { - RetAttrs = RetAttrs | Attribute::ZExt; - $9 = $9 ^ Attribute::ZExt; - } - if ($9 & Attribute::SExt) { - RetAttrs = RetAttrs | Attribute::SExt; - $9 = $9 ^ Attribute::SExt; - } - if ($9 & Attribute::InReg) { - RetAttrs = RetAttrs | Attribute::InReg; - $9 = $9 ^ Attribute::InReg; - } - } - if (RetAttrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); - - // Check the arguments - ValueList Args; - if ($7->empty()) { // Has no arguments? - // Make sure no arguments is a good thing! - if (Ty->getNumParams() != 0) - GEN_ERROR("No arguments passed to a function that " - "expects arguments"); - } else { // Has arguments? - // Loop through FunctionType's arguments and ensure they are specified - // correctly. Also, gather any parameter attributes. - FunctionType::param_iterator I = Ty->param_begin(); - FunctionType::param_iterator E = Ty->param_end(); - ParamList::iterator ArgI = $7->begin(), ArgE = $7->end(); - unsigned index = 1; - - for (; ArgI != ArgE && I != E; ++ArgI, ++I, ++index) { - if (ArgI->Val->getType() != *I) - GEN_ERROR("Parameter " + ArgI->Val->getName()+ " is not of type '" + - (*I)->getDescription() + "'"); - Args.push_back(ArgI->Val); - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - if (Ty->isVarArg()) { - if (I == E) - for (; ArgI != ArgE; ++ArgI, ++index) { - Args.push_back(ArgI->Val); // push the remaining varargs - if (ArgI->Attrs != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(index, ArgI->Attrs)); - } - } else if (I != E || ArgI != ArgE) - GEN_ERROR("Invalid number of parameters detected"); - } - if ($9 != Attribute::None) - Attrs.push_back(AttributeWithIndex::get(~0, $9)); - - // Finish off the Attributes and check them - AttrListPtr PAL; - if (!Attrs.empty()) - PAL = AttrListPtr::get(Attrs.begin(), Attrs.end()); - - // Create the call node - CallInst *CI = CallInst::Create(V, Args.begin(), Args.end()); - CI->setTailCall($1); - CI->setCallingConv($2); - CI->setAttributes(PAL); - $$ = CI; - delete $7; - delete $4; - CHECK_FOR_ERROR - } - | MemoryInst { - $$ = $1; - CHECK_FOR_ERROR - }; - -OptVolatile : VOLATILE { - $$ = true; - CHECK_FOR_ERROR - } - | /* empty */ { - $$ = false; - CHECK_FOR_ERROR - }; - - - -MemoryInst : MALLOC Types OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - $$ = new MallocInst(*$2, 0, $3); - delete $2; - CHECK_FOR_ERROR - } - | MALLOC Types ',' INTTYPE ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if ($4 != Type::Int32Ty) - GEN_ERROR("Malloc array size is not a 32-bit integer!"); - Value* tmpVal = getVal($4, $5); - CHECK_FOR_ERROR - $$ = new MallocInst(*$2, tmpVal, $6); - delete $2; - } - | ALLOCA Types OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - $$ = new AllocaInst(*$2, 0, $3); - delete $2; - CHECK_FOR_ERROR - } - | ALLOCA Types ',' INTTYPE ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if ($4 != Type::Int32Ty) - GEN_ERROR("Alloca array size is not a 32-bit integer!"); - Value* tmpVal = getVal($4, $5); - CHECK_FOR_ERROR - $$ = new AllocaInst(*$2, tmpVal, $6); - delete $2; - } - | FREE ResolvedVal { - if (!isa($2->getType())) - GEN_ERROR("Trying to free nonpointer type " + - $2->getType()->getDescription() + ""); - $$ = new FreeInst($2); - CHECK_FOR_ERROR - } - - | OptVolatile LOAD Types ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription()); - if (!isa($3->get())) - GEN_ERROR("Can't load from nonpointer type: " + - (*$3)->getDescription()); - if (!cast($3->get())->getElementType()->isFirstClassType()) - GEN_ERROR("Can't load from pointer of non-first-class type: " + - (*$3)->getDescription()); - Value* tmpVal = getVal(*$3, $4); - CHECK_FOR_ERROR - $$ = new LoadInst(tmpVal, "", $1, $5); - delete $3; - } - | OptVolatile STORE ResolvedVal ',' Types ValueRef OptCAlign { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$5)->getDescription()); - const PointerType *PT = dyn_cast($5->get()); - if (!PT) - GEN_ERROR("Can't store to a nonpointer type: " + - (*$5)->getDescription()); - const Type *ElTy = PT->getElementType(); - if (ElTy != $3->getType()) - GEN_ERROR("Can't store '" + $3->getType()->getDescription() + - "' into space of type '" + ElTy->getDescription() + "'"); - - Value* tmpVal = getVal(*$5, $6); - CHECK_FOR_ERROR - $$ = new StoreInst($3, tmpVal, $1, $7); - delete $5; - } - | GETRESULT Types ValueRef ',' EUINT64VAL { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get()) && !isa($2->get())) - GEN_ERROR("getresult insn requires an aggregate operand"); - if (!ExtractValueInst::getIndexedType(*$2, $5)) - GEN_ERROR("Invalid getresult index for type '" + - (*$2)->getDescription()+ "'"); - - Value *tmpVal = getVal(*$2, $3); - CHECK_FOR_ERROR - $$ = ExtractValueInst::Create(tmpVal, $5); - delete $2; - } - | GETELEMENTPTR Types ValueRef IndexList { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get())) - GEN_ERROR("getelementptr insn requires pointer operand"); - - if (!GetElementPtrInst::getIndexedType(*$2, $4->begin(), $4->end())) - GEN_ERROR("Invalid getelementptr indices for type '" + - (*$2)->getDescription()+ "'"); - Value* tmpVal = getVal(*$2, $3); - CHECK_FOR_ERROR - $$ = GetElementPtrInst::Create(tmpVal, $4->begin(), $4->end()); - delete $2; - delete $4; - } - | EXTRACTVALUE Types ValueRef ConstantIndexList { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get()) && !isa($2->get())) - GEN_ERROR("extractvalue insn requires an aggregate operand"); - - if (!ExtractValueInst::getIndexedType(*$2, $4->begin(), $4->end())) - GEN_ERROR("Invalid extractvalue indices for type '" + - (*$2)->getDescription()+ "'"); - Value* tmpVal = getVal(*$2, $3); - CHECK_FOR_ERROR - $$ = ExtractValueInst::Create(tmpVal, $4->begin(), $4->end()); - delete $2; - delete $4; - } - | INSERTVALUE Types ValueRef ',' Types ValueRef ConstantIndexList { - if (!UpRefs.empty()) - GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription()); - if (!isa($2->get()) && !isa($2->get())) - GEN_ERROR("extractvalue insn requires an aggregate operand"); - - if (ExtractValueInst::getIndexedType(*$2, $7->begin(), $7->end()) != $5->get()) - GEN_ERROR("Invalid insertvalue indices for type '" + - (*$2)->getDescription()+ "'"); - Value* aggVal = getVal(*$2, $3); - Value* tmpVal = getVal(*$5, $6); - CHECK_FOR_ERROR - $$ = InsertValueInst::Create(aggVal, tmpVal, $7->begin(), $7->end()); - delete $2; - delete $5; - delete $7; - }; - - -%% - -// common code from the two 'RunVMAsmParser' functions -static Module* RunParser(Module * M) { - CurModule.CurrentModule = M; - // Check to make sure the parser succeeded - if (yyparse()) { - if (ParserResult) - delete ParserResult; - return 0; - } - - // Emit an error if there are any unresolved types left. - if (!CurModule.LateResolveTypes.empty()) { - const ValID &DID = CurModule.LateResolveTypes.begin()->first; - if (DID.Type == ValID::LocalName) { - GenerateError("Undefined type remains at eof: '"+DID.getName() + "'"); - } else { - GenerateError("Undefined type remains at eof: #" + itostr(DID.Num)); - } - if (ParserResult) - delete ParserResult; - return 0; - } - - // Emit an error if there are any unresolved values left. - if (!CurModule.LateResolveValues.empty()) { - Value *V = CurModule.LateResolveValues.back(); - std::map >::iterator I = - CurModule.PlaceHolderInfo.find(V); - - if (I != CurModule.PlaceHolderInfo.end()) { - ValID &DID = I->second.first; - if (DID.Type == ValID::LocalName) { - GenerateError("Undefined value remains at eof: "+DID.getName() + "'"); - } else { - GenerateError("Undefined value remains at eof: #" + itostr(DID.Num)); - } - if (ParserResult) - delete ParserResult; - return 0; - } - } - - // Check to make sure that parsing produced a result - if (!ParserResult) - return 0; - - // Reset ParserResult variable while saving its value for the result. - Module *Result = ParserResult; - ParserResult = 0; - - return Result; -} - -void llvm::GenerateError(const std::string &message, int LineNo) { - if (LineNo == -1) LineNo = LLLgetLineNo(); - // TODO: column number in exception - if (TheParseError) - TheParseError->setError(LLLgetFilename(), message, LineNo); - TriggerError = 1; -} - -int yyerror(const char *ErrorMsg) { - std::string where = LLLgetFilename() + ":" + utostr(LLLgetLineNo()) + ": "; - std::string errMsg = where + "error: " + std::string(ErrorMsg); - if (yychar != YYEMPTY && yychar != 0) { - errMsg += " while reading token: '"; - errMsg += std::string(LLLgetTokenStart(), - LLLgetTokenStart()+LLLgetTokenLength()) + "'"; - } - GenerateError(errMsg); - return 0; -} diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 41929faed50..cd4c6921d2e 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1188,6 +1188,8 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { PrintVisibility(GV->getVisibility(), Out); if (GV->isThreadLocal()) Out << "thread_local "; + if (unsigned AddressSpace = GV->getType()->getAddressSpace()) + Out << "addrspace(" << AddressSpace << ") "; Out << (GV->isConstant() ? "constant " : "global "); printType(GV->getType()->getElementType()); @@ -1195,9 +1197,6 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { Out << ' '; writeOperand(GV->getInitializer(), false); } - - if (unsigned AddressSpace = GV->getType()->getAddressSpace()) - Out << " addrspace(" << AddressSpace << ") "; if (GV->hasSection()) Out << ", section \"" << GV->getSection() << '"'; diff --git a/test/Assembler/2002-07-25-ParserAssertionFailure.ll b/test/Assembler/2002-07-25-ParserAssertionFailure.ll index e1fa9346be5..29c7c02ff85 100644 --- a/test/Assembler/2002-07-25-ParserAssertionFailure.ll +++ b/test/Assembler/2002-07-25-ParserAssertionFailure.ll @@ -1,6 +1,6 @@ ; Make sure we don't get an assertion failure, even though this is a parse ; error -; RUN: not llvm-as %s -o /dev/null -f |& grep {No arguments} +; RUN: not llvm-as %s -o /dev/null -f |& grep {'@foo' defined with} %ty = type void (i32) diff --git a/test/Assembler/2003-04-15-ConstantInitAssertion.ll b/test/Assembler/2003-04-15-ConstantInitAssertion.ll index 66b80de348b..e0121688dc3 100644 --- a/test/Assembler/2003-04-15-ConstantInitAssertion.ll +++ b/test/Assembler/2003-04-15-ConstantInitAssertion.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as < %s >/dev/null |& grep {Expected type 'i32' for element #0} +; RUN: not llvm-as < %s >/dev/null |& grep {constant expression type mismatch} ; Test the case of a misformed constant initializer ; This should cause an assembler error, not an assertion failure! constant { i32 } { float 1.0 } diff --git a/test/Assembler/2003-05-21-MalformedShiftCrash.ll b/test/Assembler/2003-05-21-MalformedShiftCrash.ll index d573403a13e..c661f7c0771 100644 --- a/test/Assembler/2003-05-21-MalformedShiftCrash.ll +++ b/test/Assembler/2003-05-21-MalformedShiftCrash.ll @@ -1,4 +1,4 @@ ; Found by inspection of the code -; RUN: not llvm-as < %s > /dev/null |& grep {Logical operator requires integral} +; RUN: not llvm-as < %s > /dev/null |& grep {constexpr requires integer or integer vector operands} global i32 ashr (float 1.0, float 2.0) diff --git a/test/Assembler/2003-05-21-MalformedStructCrash.ll b/test/Assembler/2003-05-21-MalformedStructCrash.ll index bf930350ef0..1efb57704ec 100644 --- a/test/Assembler/2003-05-21-MalformedStructCrash.ll +++ b/test/Assembler/2003-05-21-MalformedStructCrash.ll @@ -1,4 +1,4 @@ ; Found by inspection of the code -; RUN: not llvm-as < %s > /dev/null |& grep {Illegal number of init} +; RUN: not llvm-as < %s > /dev/null |& grep {constant expression type mismatch} global {} { i32 7, float 1.0, i32 7, i32 8 } diff --git a/test/Assembler/2003-11-24-SymbolTableCrash.ll b/test/Assembler/2003-11-24-SymbolTableCrash.ll index 4b2cbdcc037..041b0d94c41 100644 --- a/test/Assembler/2003-11-24-SymbolTableCrash.ll +++ b/test/Assembler/2003-11-24-SymbolTableCrash.ll @@ -1,5 +1,4 @@ -; RUN: not llvm-as < %s |& not grep Asserti -; RUN: not llvm-as < %s |& grep Redefinition +; RUN: not llvm-as < %s |& grep {multiple definition} define void @test() { %tmp.1 = add i32 0, 1 diff --git a/test/Assembler/2003-12-30-TypeMapInvalidMemory.ll b/test/Assembler/2003-12-30-TypeMapInvalidMemory.ll index db39490d5a4..bdb4d546854 100644 --- a/test/Assembler/2003-12-30-TypeMapInvalidMemory.ll +++ b/test/Assembler/2003-12-30-TypeMapInvalidMemory.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as %s -o /dev/null -f |& grep {Undefined type remains} +; RUN: not llvm-as %s -o /dev/null -f |& grep {use of undefined type named 'struct.D_Scope'} ; END. @d_reduction_0_dparser_gram = global { diff --git a/test/Assembler/2004-03-30-UnclosedFunctionCrash.ll b/test/Assembler/2004-03-30-UnclosedFunctionCrash.ll index 62a713871bf..775b7558f3c 100644 --- a/test/Assembler/2004-03-30-UnclosedFunctionCrash.ll +++ b/test/Assembler/2004-03-30-UnclosedFunctionCrash.ll @@ -1,3 +1,3 @@ -; RUN: not llvm-as %s |& grep error +; RUN: not llvm-as %s |& grep {found end of file when expecting more instructions} -void %foo() { +define void @foo() { diff --git a/test/Assembler/2004-11-28-InvalidTypeCrash.ll b/test/Assembler/2004-11-28-InvalidTypeCrash.ll index 5f800774fa3..6f264393a59 100644 --- a/test/Assembler/2004-11-28-InvalidTypeCrash.ll +++ b/test/Assembler/2004-11-28-InvalidTypeCrash.ll @@ -1,5 +1,4 @@ ; Test for PR463. This program is erroneous, but should not crash llvm-as. -; RUN: not llvm-as %s -o /dev/null -f |& \ -; RUN: grep {Cannot create a null initialized value of this type} +; RUN: not llvm-as %s -o /dev/null -f |& grep {invalid type for null constant} @.FOO = internal global %struct.none zeroinitializer diff --git a/test/Assembler/2006-09-28-CrashOnInvalid.ll b/test/Assembler/2006-09-28-CrashOnInvalid.ll index f77ea5c427e..a203c6ad034 100644 --- a/test/Assembler/2006-09-28-CrashOnInvalid.ll +++ b/test/Assembler/2006-09-28-CrashOnInvalid.ll @@ -1,6 +1,6 @@ ; Test for PR902. This program is erroneous, but should not crash llvm-as. ; This tests that a simple error is caught and processed correctly. -; RUN: not llvm-as < %s >/dev/null |& grep {FP constant invalid for type} +; RUN: not llvm-as < %s >/dev/null |& grep {floating point constant invalid for type} define void @test() { add i32 1, 2.0 diff --git a/test/Assembler/2007-01-02-Undefined-Arg-Type.ll b/test/Assembler/2007-01-02-Undefined-Arg-Type.ll index 9521b43897c..1962ae70c03 100644 --- a/test/Assembler/2007-01-02-Undefined-Arg-Type.ll +++ b/test/Assembler/2007-01-02-Undefined-Arg-Type.ll @@ -1,5 +1,5 @@ ; The assembler should catch an undefined argument type . -; RUN: not llvm-as %s -o /dev/null -f |& grep {Reference to abstract argument} +; RUN: not llvm-as %s -o /dev/null -f |& grep {use of undefined type named 'typedef.bc_struct'} ; %typedef.bc_struct = type opaque diff --git a/test/Assembler/2007-03-18-InvalidNumberedVar.ll b/test/Assembler/2007-03-18-InvalidNumberedVar.ll index 8e821132d8a..12bac61124e 100644 --- a/test/Assembler/2007-03-18-InvalidNumberedVar.ll +++ b/test/Assembler/2007-03-18-InvalidNumberedVar.ll @@ -1,5 +1,5 @@ ; PR 1258 -; RUN: not llvm-as < %s >/dev/null -f |& grep {Numbered.*does not match} +; RUN: not llvm-as < %s >/dev/null -f |& grep {'%0' defined with type 'i1'} define i32 @test1(i32 %a, i32 %b) { entry: diff --git a/test/Assembler/2007-08-06-AliasInvalid.ll b/test/Assembler/2007-08-06-AliasInvalid.ll index b54acec1c94..94095982468 100644 --- a/test/Assembler/2007-08-06-AliasInvalid.ll +++ b/test/Assembler/2007-08-06-AliasInvalid.ll @@ -1,7 +1,9 @@ -; RUN: not llvm-as < %s > /dev/null |& grep {Invalid type for reference to global} +; RUN: not llvm-as < %s > /dev/null |& grep {expected top-level entity} ; PR1577 -@anInt = global i32 1 alias i32 @anAlias +@anInt = global i32 1 +alias i32 @anAlias + define i32 @main() { ret i32 0 } diff --git a/test/Assembler/2007-12-11-AddressSpaces.ll b/test/Assembler/2007-12-11-AddressSpaces.ll index 16d01307f3a..0eb4a797306 100644 --- a/test/Assembler/2007-12-11-AddressSpaces.ll +++ b/test/Assembler/2007-12-11-AddressSpaces.ll @@ -5,9 +5,9 @@ ; RUN: llvm-as < %s | llvm-dis | grep {addrspace(22)} | count 5 %struct.mystruct = type { i32, i32 addrspace(33)*, i32, i32 addrspace(33)* } -@input = weak global %struct.mystruct zeroinitializer addrspace(42) ; <%struct.mystruct addrspace(42)*> [#uses=1] -@output = global %struct.mystruct zeroinitializer addrspace(66) ; <%struct.mystruct addrspace(66)*> [#uses=1] -@y = external global i32 addrspace(11)* addrspace(22)* addrspace(33) ; [#uses=1] +@input = weak addrspace(42) global %struct.mystruct zeroinitializer ; <%struct.mystruct addrspace(42)*> [#uses=1] +@output = addrspace(66) global %struct.mystruct zeroinitializer ; <%struct.mystruct addrspace(66)*> [#uses=1] +@y = external addrspace(33) global i32 addrspace(11)* addrspace(22)* ; [#uses=1] define void @foo() { entry: diff --git a/test/Assembler/2008-02-18-IntPointerCrash.ll b/test/Assembler/2008-02-18-IntPointerCrash.ll index 69632ae85cd..5a661ad9b99 100644 --- a/test/Assembler/2008-02-18-IntPointerCrash.ll +++ b/test/Assembler/2008-02-18-IntPointerCrash.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as %s |& grep {is invalid or} +; RUN: not llvm-as %s |& grep {integer constant must have integer type} ; PR2060 define i8* @foo() { diff --git a/test/Feature/globalredefinition3.ll b/test/Feature/globalredefinition3.ll index bbac2e985aa..0183e5a04f9 100644 --- a/test/Feature/globalredefinition3.ll +++ b/test/Feature/globalredefinition3.ll @@ -1,6 +1,4 @@ -; RUN: not llvm-as %s -o /dev/null -f |& grep \ -; RUN: "Redefinition of global variable named 'B'" -; END. +; RUN: not llvm-as %s -o /dev/null -f |& grep {redefinition of global '@B'} @B = global i32 7 @B = global i32 7 diff --git a/test/Feature/opaquetypes.ll b/test/Feature/opaquetypes.ll index 2ca58a7922b..6539c1a6e1c 100644 --- a/test/Feature/opaquetypes.ll +++ b/test/Feature/opaquetypes.ll @@ -7,7 +7,6 @@ ; %SQ1 = type { i32 } -%ITy = type opaque %SQ2 = type { %ITy } %ITy = type i32 @@ -22,7 +21,6 @@ type %BBB %Composite = type { %0, %1 } ; Test simple opaque type resolution... -%intty = type opaque %intty = type i32 ; Perform a simple forward reference... diff --git a/test/Integer/opaquetypes_bt.ll b/test/Integer/opaquetypes_bt.ll index a1ba799c2c2..5771342c97a 100644 --- a/test/Integer/opaquetypes_bt.ll +++ b/test/Integer/opaquetypes_bt.ll @@ -7,7 +7,6 @@ ; %SQ1 = type { i31 } -%ITy = type opaque %SQ2 = type { %ITy } %ITy = type i31 @@ -22,7 +21,6 @@ type %BBB %Composite = type { %0, %1 } ; Test simple opaque type resolution... -%i31ty = type opaque %i31ty = type i31 ; Perform a simple forward reference... diff --git a/test/Linker/2008-06-26-AddressSpace.ll b/test/Linker/2008-06-26-AddressSpace.ll index ee475094f34..7f2110628e0 100644 --- a/test/Linker/2008-06-26-AddressSpace.ll +++ b/test/Linker/2008-06-26-AddressSpace.ll @@ -6,4 +6,4 @@ ; RUN: llvm-link %t.foo1.bc %t.foo2.bc | llvm-dis | grep {addrspace(2)} ; rdar://6038021 -@G = global i32 256 addrspace(2) +@G = addrspace(2) global i32 256 diff --git a/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll b/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll index fd9d0885f27..735a84d6fcb 100644 --- a/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll +++ b/test/Transforms/GlobalOpt/2008-07-17-addrspace.ll @@ -6,8 +6,8 @@ ; Check that the new global values still have their address space ; RUN: cat %t | grep global.*addrspace -@struct = internal global { i32, i32 } zeroinitializer addrspace(1) -@array = internal global [ 2 x i32 ] zeroinitializer addrspace(1) +@struct = internal addrspace(1) global { i32, i32 } zeroinitializer +@array = internal addrspace(1) global [ 2 x i32 ] zeroinitializer define i32 @foo() { %A = load i32 addrspace(1) * getelementptr ({ i32, i32 } addrspace(1) * @struct, i32 0, i32 0) diff --git a/test/Verifier/2002-11-05-GetelementptrPointers.ll b/test/Verifier/2002-11-05-GetelementptrPointers.ll index e37a0ffd324..1f71387ab3a 100644 --- a/test/Verifier/2002-11-05-GetelementptrPointers.ll +++ b/test/Verifier/2002-11-05-GetelementptrPointers.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as < %s |& grep {Invalid getelementptr indices} +; RUN: not llvm-as < %s |& grep {invalid getelementptr indices} ; This testcase is invalid because we are indexing into a pointer that is ; contained WITHIN a structure. diff --git a/test/Verifier/2005-03-21-UndefinedTypeReference.ll b/test/Verifier/2005-03-21-UndefinedTypeReference.ll index 19a9826ea52..5299397ab06 100644 --- a/test/Verifier/2005-03-21-UndefinedTypeReference.ll +++ b/test/Verifier/2005-03-21-UndefinedTypeReference.ll @@ -1,4 +1,4 @@ -; RUN: not llvm-as < %s |& grep {Reference to an undefined type} +; RUN: not llvm-as < %s |& grep {use of undefined type named 'InvalidType'} define void @test() { malloc %InvalidType diff --git a/test/Verifier/2006-10-15-AddrLabel.ll b/test/Verifier/2006-10-15-AddrLabel.ll index e2c0e603c33..73b69024c77 100644 --- a/test/Verifier/2006-10-15-AddrLabel.ll +++ b/test/Verifier/2006-10-15-AddrLabel.ll @@ -1,5 +1,4 @@ -; RUN: not llvm-as < %s > /dev/null |& \ -; RUN: grep {Cannot form a pointer to a basic block} +; RUN: not llvm-as < %s > /dev/null |& grep {basic block pointers are invalid} define i32 @main() { %foo = call i8* %llvm.stacksave() diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index 19f9685677c..d050b59ed77 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" #include #include using namespace llvm; @@ -80,8 +81,8 @@ Module *llvm::ParseInputFile(const std::string &Filename) { Result = ParseBitcodeFile(Buffer.get()); ParseError Err; - if (!Result && !(Result = ParseAssemblyFile(Filename, &Err))) { - std::cerr << "bugpoint: " << Err.getMessage() << "\n"; + if (!Result && !(Result = ParseAssemblyFile(Filename, Err))) { + Err.PrintError("bugpoint", errs()); Result = 0; } diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index d9fa1fa7f40..72e32972d2c 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -23,6 +23,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Streams.h" #include "llvm/Support/SystemUtils.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/System/Signals.h" #include #include @@ -59,9 +60,9 @@ int main(int argc, char **argv) { try { // Parse the file now... ParseError Err; - std::auto_ptr M(ParseAssemblyFile(InputFilename,&Err)); + std::auto_ptr M(ParseAssemblyFile(InputFilename, Err)); if (M.get() == 0) { - cerr << argv[0] << ": " << Err.getMessage() << "\n"; + Err.PrintError(argv[0], errs()); return 1; }