diff options
Diffstat (limited to 'contrib/llvm/lib/AsmParser')
-rw-r--r-- | contrib/llvm/lib/AsmParser/LLLexer.cpp | 193 | ||||
-rw-r--r-- | contrib/llvm/lib/AsmParser/LLLexer.h | 3 | ||||
-rw-r--r-- | contrib/llvm/lib/AsmParser/LLParser.cpp | 688 | ||||
-rw-r--r-- | contrib/llvm/lib/AsmParser/LLParser.h | 71 | ||||
-rw-r--r-- | contrib/llvm/lib/AsmParser/LLToken.h | 54 | ||||
-rw-r--r-- | contrib/llvm/lib/AsmParser/Parser.cpp | 4 |
6 files changed, 656 insertions, 357 deletions
diff --git a/contrib/llvm/lib/AsmParser/LLLexer.cpp b/contrib/llvm/lib/AsmParser/LLLexer.cpp index a60e4aa..f46383b 100644 --- a/contrib/llvm/lib/AsmParser/LLLexer.cpp +++ b/contrib/llvm/lib/AsmParser/LLLexer.cpp @@ -12,14 +12,15 @@ //===----------------------------------------------------------------------===// #include "LLLexer.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instruction.h" -#include "llvm/LLVMContext.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Assembly/Parser.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include <cctype> @@ -55,22 +56,12 @@ uint64_t LLLexer::atoull(const char *Buffer, const char *End) { return Result; } -static char parseHexChar(char C) { - if (C >= '0' && C <= '9') - return C-'0'; - if (C >= 'A' && C <= 'F') - return C-'A'+10; - if (C >= 'a' && C <= 'f') - return C-'a'+10; - return 0; -} - uint64_t LLLexer::HexIntToVal(const char *Buffer, const char *End) { uint64_t Result = 0; for (; Buffer != End; ++Buffer) { uint64_t OldRes = Result; Result *= 16; - Result += parseHexChar(*Buffer); + Result += hexDigitValue(*Buffer); if (Result < OldRes) { // Uh, oh, overflow detected!!! Error("constant bigger than 64 bits detected!"); @@ -86,12 +77,12 @@ void LLLexer::HexToIntPair(const char *Buffer, const char *End, for (int i=0; i<16; i++, Buffer++) { assert(Buffer != End); Pair[0] *= 16; - Pair[0] += parseHexChar(*Buffer); + Pair[0] += hexDigitValue(*Buffer); } Pair[1] = 0; for (int i=0; i<16 && Buffer != End; i++, Buffer++) { Pair[1] *= 16; - Pair[1] += parseHexChar(*Buffer); + Pair[1] += hexDigitValue(*Buffer); } if (Buffer != End) Error("constant bigger than 128 bits detected!"); @@ -105,12 +96,12 @@ void LLLexer::FP80HexToIntPair(const char *Buffer, const char *End, for (int i=0; i<4 && Buffer != End; i++, Buffer++) { assert(Buffer != End); Pair[1] *= 16; - Pair[1] += parseHexChar(*Buffer); + Pair[1] += hexDigitValue(*Buffer); } Pair[0] = 0; for (int i=0; i<16; i++, Buffer++) { Pair[0] *= 16; - Pair[0] += parseHexChar(*Buffer); + Pair[0] += hexDigitValue(*Buffer); } if (Buffer != End) Error("constant bigger than 128 bits detected!"); @@ -128,8 +119,10 @@ static void UnEscapeLexed(std::string &Str) { if (BIn < EndBuffer-1 && BIn[1] == '\\') { *BOut++ = '\\'; // Two \ becomes one BIn += 2; - } else if (BIn < EndBuffer-2 && isxdigit(BIn[1]) && isxdigit(BIn[2])) { - *BOut = parseHexChar(BIn[1]) * 16 + parseHexChar(BIn[2]); + } else if (BIn < EndBuffer-2 && + isxdigit(static_cast<unsigned char>(BIn[1])) && + isxdigit(static_cast<unsigned char>(BIn[2]))) { + *BOut = hexDigitValue(BIn[1]) * 16 + hexDigitValue(BIn[2]); BIn += 3; // Skip over handled chars ++BOut; } else { @@ -144,7 +137,8 @@ static void UnEscapeLexed(std::string &Str) { /// isLabelChar - Return true for [-a-zA-Z$._0-9]. static bool isLabelChar(char C) { - return isalnum(C) || C == '-' || C == '$' || C == '.' || C == '_'; + return isalnum(static_cast<unsigned char>(C)) || C == '-' || C == '$' || + C == '.' || C == '_'; } @@ -197,7 +191,7 @@ lltok::Kind LLLexer::LexToken() { switch (CurChar) { default: // Handle letters: [a-zA-Z_] - if (isalpha(CurChar) || CurChar == '_') + if (isalpha(static_cast<unsigned char>(CurChar)) || CurChar == '_') return LexIdentifier(); return lltok::Error; @@ -235,6 +229,7 @@ lltok::Kind LLLexer::LexToken() { SkipLineComment(); return LexToken(); case '!': return LexExclaim(); + case '#': return LexHash(); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': @@ -290,8 +285,8 @@ lltok::Kind LLLexer::LexAt() { return lltok::GlobalVar; // Handle GlobalVarID: @[0-9]+ - if (isdigit(CurPtr[0])) { - for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr) + if (isdigit(static_cast<unsigned char>(CurPtr[0]))) { + for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) /*empty*/; uint64_t Val = atoull(TokStart+1, CurPtr); @@ -325,10 +320,12 @@ lltok::Kind LLLexer::ReadString(lltok::Kind kind) { /// ReadVarName - Read the rest of a token containing a variable name. bool LLLexer::ReadVarName() { const char *NameStart = CurPtr; - if (isalpha(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || + if (isalpha(static_cast<unsigned char>(CurPtr[0])) || + CurPtr[0] == '-' || CurPtr[0] == '$' || CurPtr[0] == '.' || CurPtr[0] == '_') { ++CurPtr; - while (isalnum(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || + while (isalnum(static_cast<unsigned char>(CurPtr[0])) || + CurPtr[0] == '-' || CurPtr[0] == '$' || CurPtr[0] == '.' || CurPtr[0] == '_') ++CurPtr; @@ -354,8 +351,8 @@ lltok::Kind LLLexer::LexPercent() { return lltok::LocalVar; // Handle LocalVarID: %[0-9]+ - if (isdigit(CurPtr[0])) { - for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr) + if (isdigit(static_cast<unsigned char>(CurPtr[0]))) { + for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) /*empty*/; uint64_t Val = atoull(TokStart+1, CurPtr); @@ -389,10 +386,12 @@ lltok::Kind LLLexer::LexQuote() { /// ! lltok::Kind LLLexer::LexExclaim() { // Lex a metadata name as a MetadataVar. - if (isalpha(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || + if (isalpha(static_cast<unsigned char>(CurPtr[0])) || + CurPtr[0] == '-' || CurPtr[0] == '$' || CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') { ++CurPtr; - while (isalnum(CurPtr[0]) || CurPtr[0] == '-' || CurPtr[0] == '$' || + while (isalnum(static_cast<unsigned char>(CurPtr[0])) || + CurPtr[0] == '-' || CurPtr[0] == '$' || CurPtr[0] == '.' || CurPtr[0] == '_' || CurPtr[0] == '\\') ++CurPtr; @@ -402,7 +401,25 @@ lltok::Kind LLLexer::LexExclaim() { } return lltok::exclaim; } - + +/// LexHash - Lex all tokens that start with a # character: +/// AttrGrpID ::= #[0-9]+ +lltok::Kind LLLexer::LexHash() { + // Handle AttrGrpID: #[0-9]+ + if (isdigit(static_cast<unsigned char>(CurPtr[0]))) { + for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) + /*empty*/; + + uint64_t Val = atoull(TokStart+1, CurPtr); + if ((unsigned)Val != Val) + Error("invalid value number (too large)!"); + UIntVal = unsigned(Val); + return lltok::AttrGrpID; + } + + return lltok::Error; +} + /// LexIdentifier: Handle several related productions: /// Label [-a-zA-Z$._0-9]+: /// IntegerType i[0-9]+ @@ -415,8 +432,11 @@ lltok::Kind LLLexer::LexIdentifier() { for (; isLabelChar(*CurPtr); ++CurPtr) { // If we decide this is an integer, remember the end of the sequence. - if (!IntEnd && !isdigit(*CurPtr)) IntEnd = CurPtr; - if (!KeywordEnd && !isalnum(*CurPtr) && *CurPtr != '_') KeywordEnd = CurPtr; + if (!IntEnd && !isdigit(static_cast<unsigned char>(*CurPtr))) + IntEnd = CurPtr; + if (!KeywordEnd && !isalnum(static_cast<unsigned char>(*CurPtr)) && + *CurPtr != '_') + KeywordEnd = CurPtr; } // If we stopped due to a colon, this really is a label. @@ -445,9 +465,11 @@ lltok::Kind LLLexer::LexIdentifier() { CurPtr = KeywordEnd; --StartChar; unsigned Len = CurPtr-StartChar; -#define KEYWORD(STR) \ - if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) \ - return lltok::kw_##STR; +#define KEYWORD(STR) \ + do { \ + if (Len == strlen(#STR) && !memcmp(StartChar, #STR, strlen(#STR))) \ + return lltok::kw_##STR; \ + } while (0) KEYWORD(true); KEYWORD(false); KEYWORD(declare); KEYWORD(define); @@ -472,6 +494,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(hidden); KEYWORD(protected); KEYWORD(unnamed_addr); + KEYWORD(externally_initialized); KEYWORD(extern_weak); KEYWORD(external); KEYWORD(thread_local); @@ -486,7 +509,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(target); KEYWORD(triple); KEYWORD(unwind); - KEYWORD(deplibs); + KEYWORD(deplibs); // FIXME: Remove in 4.0. KEYWORD(datalayout); KEYWORD(volatile); KEYWORD(atomic); @@ -498,6 +521,11 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(seq_cst); KEYWORD(singlethread); + KEYWORD(nnan); + KEYWORD(ninf); + KEYWORD(nsz); + KEYWORD(arcp); + KEYWORD(fast); KEYWORD(nuw); KEYWORD(nsw); KEYWORD(exact); @@ -532,33 +560,39 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(cc); KEYWORD(c); - KEYWORD(signext); - KEYWORD(zeroext); + KEYWORD(attributes); + + KEYWORD(alwaysinline); + KEYWORD(byval); + KEYWORD(inlinehint); KEYWORD(inreg); - KEYWORD(sret); - KEYWORD(nounwind); - KEYWORD(noreturn); + KEYWORD(minsize); + KEYWORD(naked); + KEYWORD(nest); KEYWORD(noalias); + KEYWORD(nobuiltin); KEYWORD(nocapture); - KEYWORD(byval); - KEYWORD(nest); + KEYWORD(noduplicate); + KEYWORD(noimplicitfloat); + KEYWORD(noinline); + KEYWORD(nonlazybind); + KEYWORD(noredzone); + KEYWORD(noreturn); + KEYWORD(nounwind); + KEYWORD(optsize); KEYWORD(readnone); KEYWORD(readonly); - KEYWORD(uwtable); KEYWORD(returns_twice); - - KEYWORD(inlinehint); - KEYWORD(noinline); - KEYWORD(alwaysinline); - KEYWORD(optsize); + KEYWORD(signext); + KEYWORD(sret); KEYWORD(ssp); KEYWORD(sspreq); - KEYWORD(noredzone); - KEYWORD(noimplicitfloat); - KEYWORD(naked); - KEYWORD(nonlazybind); - KEYWORD(address_safety); - KEYWORD(minsize); + KEYWORD(sspstrong); + KEYWORD(sanitize_address); + KEYWORD(sanitize_thread); + KEYWORD(sanitize_memory); + KEYWORD(uwtable); + KEYWORD(zeroext); KEYWORD(type); KEYWORD(opaque); @@ -653,7 +687,8 @@ lltok::Kind LLLexer::LexIdentifier() { // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by // the CFE to avoid forcing it to deal with 64-bit numbers. if ((TokStart[0] == 'u' || TokStart[0] == 's') && - TokStart[1] == '0' && TokStart[2] == 'x' && isxdigit(TokStart[3])) { + TokStart[1] == '0' && TokStart[2] == 'x' && + isxdigit(static_cast<unsigned char>(TokStart[3]))) { int len = CurPtr-TokStart-3; uint32_t bits = len * 4; APInt Tmp(bits, StringRef(TokStart+3, len), 16); @@ -693,13 +728,13 @@ lltok::Kind LLLexer::Lex0x() { Kind = 'J'; } - if (!isxdigit(CurPtr[0])) { + if (!isxdigit(static_cast<unsigned char>(CurPtr[0]))) { // Bad token, return it as an error. CurPtr = TokStart+1; return lltok::Error; } - while (isxdigit(CurPtr[0])) + while (isxdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr; if (Kind == 'J') { @@ -716,20 +751,21 @@ lltok::Kind LLLexer::Lex0x() { case 'K': // F80HexFPConstant - x87 long double in hexadecimal format (10 bytes) FP80HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(80, Pair)); + APFloatVal = APFloat(APFloat::x87DoubleExtended, APInt(80, Pair)); return lltok::APFloat; case 'L': // F128HexFPConstant - IEEE 128-bit in hexadecimal format (16 bytes) HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(128, Pair), true); + APFloatVal = APFloat(APFloat::IEEEquad, APInt(128, Pair)); return lltok::APFloat; case 'M': // PPC128HexFPConstant - PowerPC 128-bit in hexadecimal format (16 bytes) HexToIntPair(TokStart+3, CurPtr, Pair); - APFloatVal = APFloat(APInt(128, Pair)); + APFloatVal = APFloat(APFloat::PPCDoubleDouble, APInt(128, Pair)); return lltok::APFloat; case 'H': - APFloatVal = APFloat(APInt(16,HexIntToVal(TokStart+3, CurPtr))); + APFloatVal = APFloat(APFloat::IEEEhalf, + APInt(16,HexIntToVal(TokStart+3, CurPtr))); return lltok::APFloat; } } @@ -744,8 +780,9 @@ lltok::Kind LLLexer::Lex0x() { /// HexFP128Constant 0xL[0-9A-Fa-f]+ /// HexPPC128Constant 0xM[0-9A-Fa-f]+ 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])) { + // If the letter after the negative is not a number, this is probably a label. + if (!isdigit(static_cast<unsigned char>(TokStart[0])) && + !isdigit(static_cast<unsigned char>(CurPtr[0]))) { // Okay, this is not a number after the -, it's probably a label. if (const char *End = isLabelTail(CurPtr)) { StrVal.assign(TokStart, End-1); @@ -759,7 +796,7 @@ lltok::Kind LLLexer::LexDigitOrNegative() { // At this point, it is either a label, int or fp constant. // Skip digits, we have at least one. - for (; isdigit(CurPtr[0]); ++CurPtr) + for (; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) /*empty*/; // Check to see if this really is a label afterall, e.g. "-1:". @@ -796,13 +833,14 @@ lltok::Kind LLLexer::LexDigitOrNegative() { ++CurPtr; // Skip over [0-9]*([eE][-+]?[0-9]+)? - while (isdigit(CurPtr[0])) ++CurPtr; + while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr; if (CurPtr[0] == 'e' || CurPtr[0] == 'E') { - if (isdigit(CurPtr[1]) || - ((CurPtr[1] == '-' || CurPtr[1] == '+') && isdigit(CurPtr[2]))) { + if (isdigit(static_cast<unsigned char>(CurPtr[1])) || + ((CurPtr[1] == '-' || CurPtr[1] == '+') && + isdigit(static_cast<unsigned char>(CurPtr[2])))) { CurPtr += 2; - while (isdigit(CurPtr[0])) ++CurPtr; + while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr; } } @@ -814,11 +852,11 @@ lltok::Kind LLLexer::LexDigitOrNegative() { lltok::Kind LLLexer::LexPositive() { // If the letter after the negative is a number, this is probably not a // label. - if (!isdigit(CurPtr[0])) + if (!isdigit(static_cast<unsigned char>(CurPtr[0]))) return lltok::Error; // Skip digits. - for (++CurPtr; isdigit(CurPtr[0]); ++CurPtr) + for (++CurPtr; isdigit(static_cast<unsigned char>(CurPtr[0])); ++CurPtr) /*empty*/; // At this point, we need a '.'. @@ -830,13 +868,14 @@ lltok::Kind LLLexer::LexPositive() { ++CurPtr; // Skip over [0-9]*([eE][-+]?[0-9]+)? - while (isdigit(CurPtr[0])) ++CurPtr; + while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr; if (CurPtr[0] == 'e' || CurPtr[0] == 'E') { - if (isdigit(CurPtr[1]) || - ((CurPtr[1] == '-' || CurPtr[1] == '+') && isdigit(CurPtr[2]))) { + if (isdigit(static_cast<unsigned char>(CurPtr[1])) || + ((CurPtr[1] == '-' || CurPtr[1] == '+') && + isdigit(static_cast<unsigned char>(CurPtr[2])))) { CurPtr += 2; - while (isdigit(CurPtr[0])) ++CurPtr; + while (isdigit(static_cast<unsigned char>(CurPtr[0]))) ++CurPtr; } } diff --git a/contrib/llvm/lib/AsmParser/LLLexer.h b/contrib/llvm/lib/AsmParser/LLLexer.h index 09aea5b..85703c7 100644 --- a/contrib/llvm/lib/AsmParser/LLLexer.h +++ b/contrib/llvm/lib/AsmParser/LLLexer.h @@ -15,8 +15,8 @@ #define LIB_ASMPARSER_LLLEXER_H #include "LLToken.h" -#include "llvm/ADT/APSInt.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APSInt.h" #include "llvm/Support/SourceMgr.h" #include <string> @@ -81,6 +81,7 @@ namespace llvm { lltok::Kind LexPercent(); lltok::Kind LexQuote(); lltok::Kind Lex0x(); + lltok::Kind LexHash(); uint64_t atoull(const char *Buffer, const char *End); uint64_t HexIntToVal(const char *Buffer, const char *End); diff --git a/contrib/llvm/lib/AsmParser/LLParser.cpp b/contrib/llvm/lib/AsmParser/LLParser.cpp index b24291f..c8da1f8 100644 --- a/contrib/llvm/lib/AsmParser/LLParser.cpp +++ b/contrib/llvm/lib/AsmParser/LLParser.cpp @@ -12,16 +12,16 @@ //===----------------------------------------------------------------------===// #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/Operator.h" -#include "llvm/ValueSymbolTable.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/AutoUpgrade.h" +#include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -52,10 +52,10 @@ bool LLParser::ValidateEndOfModule() { I != E; ++I) { Instruction *Inst = I->first; const std::vector<MDRef> &MDList = I->second; - + for (unsigned i = 0, e = MDList.size(); i != e; ++i) { unsigned SlotNo = MDList[i].MDSlot; - + if (SlotNo >= NumberedMetadata.size() || NumberedMetadata[SlotNo] == 0) return Error(MDList[i].Loc, "use of undefined metadata '!" + Twine(SlotNo) + "'"); @@ -64,8 +64,66 @@ bool LLParser::ValidateEndOfModule() { } ForwardRefInstMetadata.clear(); } - - + + // Handle any function attribute group forward references. + for (std::map<Value*, std::vector<unsigned> >::iterator + I = ForwardRefAttrGroups.begin(), E = ForwardRefAttrGroups.end(); + I != E; ++I) { + Value *V = I->first; + std::vector<unsigned> &Vec = I->second; + AttrBuilder B; + + for (std::vector<unsigned>::iterator VI = Vec.begin(), VE = Vec.end(); + VI != VE; ++VI) + B.merge(NumberedAttrBuilders[*VI]); + + if (Function *Fn = dyn_cast<Function>(V)) { + AttributeSet AS = Fn->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); + AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, + AS.getFnAttributes()); + + FnAttrs.merge(B); + + // If the alignment was parsed as an attribute, move to the alignment + // field. + if (FnAttrs.hasAlignmentAttr()) { + Fn->setAlignment(FnAttrs.getAlignment()); + FnAttrs.removeAttribute(Attribute::Alignment); + } + + AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, + AttributeSet::get(Context, + AttributeSet::FunctionIndex, + FnAttrs)); + Fn->setAttributes(AS); + } else if (CallInst *CI = dyn_cast<CallInst>(V)) { + AttributeSet AS = CI->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); + AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, + AS.getFnAttributes()); + FnAttrs.merge(B); + AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, + AttributeSet::get(Context, + AttributeSet::FunctionIndex, + FnAttrs)); + CI->setAttributes(AS); + } else if (InvokeInst *II = dyn_cast<InvokeInst>(V)) { + AttributeSet AS = II->getAttributes(); + AttrBuilder FnAttrs(AS.getFnAttributes(), AttributeSet::FunctionIndex); + AS = AS.removeAttributes(Context, AttributeSet::FunctionIndex, + AS.getFnAttributes()); + FnAttrs.merge(B); + AS = AS.addAttributes(Context, AttributeSet::FunctionIndex, + AttributeSet::get(Context, + AttributeSet::FunctionIndex, + FnAttrs)); + II->setAttributes(AS); + } else { + llvm_unreachable("invalid object with forward attribute group reference"); + } + } + // If there are entries in ForwardRefBlockAddresses at this point, they are // references after the function was defined. Resolve those now. while (!ForwardRefBlockAddresses.empty()) { @@ -76,19 +134,19 @@ bool LLParser::ValidateEndOfModule() { TheFn = M->getFunction(Fn.StrVal); else if (Fn.UIntVal < NumberedVals.size()) TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]); - + if (TheFn == 0) return Error(Fn.Loc, "unknown function referenced by blockaddress"); - + // Resolve all these references. - if (ResolveForwardRefBlockAddresses(TheFn, + if (ResolveForwardRefBlockAddresses(TheFn, ForwardRefBlockAddresses.begin()->second, 0)) return true; - + ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin()); } - + for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i) if (NumberedTypes[i].second.isValid()) return Error(NumberedTypes[i].second, @@ -123,7 +181,7 @@ bool LLParser::ValidateEndOfModule() { return false; } -bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, +bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, std::vector<std::pair<ValID, GlobalValue*> > &Refs, PerFunctionState *PFS) { // Loop over all the references, resolving them. @@ -141,11 +199,11 @@ bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn, Res = dyn_cast_or_null<BasicBlock>( TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal)); } - + if (Res == 0) return Error(Refs[i].first.Loc, "referenced value is not a basic block"); - + // Get the BlockAddress for this and update references to use it. BlockAddress *BA = BlockAddress::get(TheFn, Res); Refs[i].second->replaceAllUsesWith(BA); @@ -174,7 +232,7 @@ bool LLParser::ParseTopLevelEntities() { case lltok::GlobalID: if (ParseUnnamedGlobal()) return true; break; case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break; case lltok::exclaim: if (ParseStandaloneMetadata()) return true; break; - case lltok::MetadataVar: if (ParseNamedMetadata()) return true; break; + case lltok::MetadataVar:if (ParseNamedMetadata()) return true; break; // The Global variable production with no name can have many different // optional leading prefixes, the production is: @@ -220,6 +278,8 @@ bool LLParser::ParseTopLevelEntities() { case lltok::kw_global: // GlobalType if (ParseGlobal("", SMLoc(), 0, false, 0)) return true; break; + + case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break; } } } @@ -267,6 +327,7 @@ bool LLParser::ParseTargetDefinition() { /// toplevelentity /// ::= 'deplibs' '=' '[' ']' /// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']' +/// FIXME: Remove in 4.0. Currently parse, but ignore. bool LLParser::ParseDepLibs() { assert(Lex.getKind() == lltok::kw_deplibs); Lex.Lex(); @@ -277,14 +338,10 @@ bool LLParser::ParseDepLibs() { if (EatIfPresent(lltok::rsquare)) return false; - std::string Str; - if (ParseStringConstant(Str)) return true; - M->addLibrary(Str); - - while (EatIfPresent(lltok::comma)) { + do { + std::string Str; if (ParseStringConstant(Str)) return true; - M->addLibrary(Str); - } + } while (EatIfPresent(lltok::comma)); return ParseToken(lltok::rsquare, "expected ']' at end of list"); } @@ -302,11 +359,11 @@ bool LLParser::ParseUnnamedType() { if (TypeID >= NumberedTypes.size()) NumberedTypes.resize(TypeID+1); - + Type *Result = 0; if (ParseStructDefinition(TypeLoc, "", NumberedTypes[TypeID], Result)) return true; - + if (!isa<StructType>(Result)) { std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID]; if (Entry.first) @@ -329,11 +386,11 @@ bool LLParser::ParseNamedType() { if (ParseToken(lltok::equal, "expected '=' after name") || ParseToken(lltok::kw_type, "expected 'type' after name")) return true; - + Type *Result = 0; if (ParseStructDefinition(NameLoc, Name, NamedTypes[Name], Result)) return true; - + if (!isa<StructType>(Result)) { std::pair<Type*, LocTy> &Entry = NamedTypes[Name]; if (Entry.first) @@ -341,7 +398,7 @@ bool LLParser::ParseNamedType() { Entry.first = Result; Entry.second = SMLoc(); } - + return false; } @@ -473,7 +530,7 @@ bool LLParser::ParseMDNodeID(MDNode *&Result) { // Otherwise, create MDNode forward reference. MDNode *FwdNode = MDNode::getTemporary(Context, ArrayRef<Value*>()); ForwardRefMDNodes[MID] = std::make_pair(FwdNode, Lex.getLoc()); - + if (NumberedMetadata.size() <= MID) NumberedMetadata.resize(MID+1); NumberedMetadata[MID] = FwdNode; @@ -498,7 +555,7 @@ bool LLParser::ParseNamedMetadata() { do { if (ParseToken(lltok::exclaim, "Expected '!' here")) return true; - + MDNode *N = 0; if (ParseMDNodeID(N)) return true; NMD->addOperand(N); @@ -530,7 +587,7 @@ bool LLParser::ParseStandaloneMetadata() { return true; MDNode *Init = MDNode::get(Context, Elts); - + // See if this was forward referenced, if so, handle it. std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> >::iterator FI = ForwardRefMDNodes.find(MetadataID); @@ -539,7 +596,7 @@ bool LLParser::ParseStandaloneMetadata() { Temp->replaceAllUsesWith(Init); MDNode::deleteTemporary(Temp); ForwardRefMDNodes.erase(FI); - + assert(NumberedMetadata[MetadataID] == Init && "Tracking VH didn't work"); } else { if (MetadataID >= NumberedMetadata.size()) @@ -635,9 +692,11 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, /// ParseGlobal /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal -/// OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const +/// OptionalAddrSpace OptionalUnNammedAddr +/// OptionalExternallyInitialized GlobalType Type Const /// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal -/// OptionalAddrSpace OptionalUnNammedAddr GlobalType Type Const +/// OptionalAddrSpace OptionalUnNammedAddr +/// OptionalExternallyInitialized GlobalType Type Const /// /// Everything through visibility has been parsed already. /// @@ -645,9 +704,10 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility) { unsigned AddrSpace; - bool IsConstant, UnnamedAddr; + bool IsConstant, UnnamedAddr, IsExternallyInitialized; GlobalVariable::ThreadLocalMode TLM; LocTy UnnamedAddrLoc; + LocTy IsExternallyInitializedLoc; LocTy TyLoc; Type *Ty = 0; @@ -655,6 +715,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, ParseOptionalAddrSpace(AddrSpace) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || + ParseOptionalToken(lltok::kw_externally_initialized, + IsExternallyInitialized, + &IsExternallyInitializedLoc) || ParseGlobalType(IsConstant) || ParseType(Ty, TyLoc)) return true; @@ -712,6 +775,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GV->setConstant(IsConstant); GV->setLinkage((GlobalValue::LinkageTypes)Linkage); GV->setVisibility((GlobalValue::VisibilityTypes)Visibility); + GV->setExternallyInitialized(IsExternallyInitialized); GV->setThreadLocalMode(TLM); GV->setUnnamedAddr(UnnamedAddr); @@ -736,6 +800,159 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, return false; } +/// ParseUnnamedAttrGrp +/// ::= 'attributes' AttrGrpID '=' '{' AttrValPair+ '}' +bool LLParser::ParseUnnamedAttrGrp() { + assert(Lex.getKind() == lltok::kw_attributes); + LocTy AttrGrpLoc = Lex.getLoc(); + Lex.Lex(); + + assert(Lex.getKind() == lltok::AttrGrpID); + unsigned VarID = Lex.getUIntVal(); + std::vector<unsigned> unused; + LocTy NoBuiltinLoc; + Lex.Lex(); + + if (ParseToken(lltok::equal, "expected '=' here") || + ParseToken(lltok::lbrace, "expected '{' here") || + ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true, + NoBuiltinLoc) || + ParseToken(lltok::rbrace, "expected end of attribute group")) + return true; + + if (!NumberedAttrBuilders[VarID].hasAttributes()) + return Error(AttrGrpLoc, "attribute group has no attributes"); + + return false; +} + +/// ParseFnAttributeValuePairs +/// ::= <attr> | <attr> '=' <value> +bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, + std::vector<unsigned> &FwdRefAttrGrps, + bool inAttrGrp, LocTy &NoBuiltinLoc) { + bool HaveError = false; + + B.clear(); + + while (true) { + lltok::Kind Token = Lex.getKind(); + if (Token == lltok::kw_nobuiltin) + NoBuiltinLoc = Lex.getLoc(); + switch (Token) { + default: + if (!inAttrGrp) return HaveError; + return Error(Lex.getLoc(), "unterminated attribute group"); + case lltok::rbrace: + // Finished. + return false; + + case lltok::AttrGrpID: { + // Allow a function to reference an attribute group: + // + // define void @foo() #1 { ... } + if (inAttrGrp) + HaveError |= + Error(Lex.getLoc(), + "cannot have an attribute group reference in an attribute group"); + + unsigned AttrGrpNum = Lex.getUIntVal(); + if (inAttrGrp) break; + + // Save the reference to the attribute group. We'll fill it in later. + FwdRefAttrGrps.push_back(AttrGrpNum); + break; + } + // Target-dependent attributes: + case lltok::StringConstant: { + std::string Attr = Lex.getStrVal(); + Lex.Lex(); + std::string Val; + if (EatIfPresent(lltok::equal) && + ParseStringConstant(Val)) + return true; + + B.addAttribute(Attr, Val); + continue; + } + + // Target-independent attributes: + case lltok::kw_align: { + // As a hack, we allow "align 2" on functions as a synonym for "alignstack + // 2". + unsigned Alignment; + if (inAttrGrp) { + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' here") || + ParseUInt32(Alignment)) + return true; + } else { + if (ParseOptionalAlignment(Alignment)) + return true; + } + B.addAlignmentAttr(Alignment); + continue; + } + case lltok::kw_alignstack: { + unsigned Alignment; + if (inAttrGrp) { + Lex.Lex(); + if (ParseToken(lltok::equal, "expected '=' here") || + ParseUInt32(Alignment)) + return true; + } else { + if (ParseOptionalStackAlignment(Alignment)) + return true; + } + B.addStackAlignmentAttr(Alignment); + continue; + } + case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break; + case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break; + case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break; + case lltok::kw_naked: B.addAttribute(Attribute::Naked); break; + case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break; + case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break; + case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break; + case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break; + case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break; + case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break; + case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break; + case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; + case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; + case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break; + case lltok::kw_returns_twice: B.addAttribute(Attribute::ReturnsTwice); break; + case lltok::kw_ssp: B.addAttribute(Attribute::StackProtect); break; + case lltok::kw_sspreq: B.addAttribute(Attribute::StackProtectReq); break; + case lltok::kw_sspstrong: B.addAttribute(Attribute::StackProtectStrong); break; + case lltok::kw_sanitize_address: B.addAttribute(Attribute::SanitizeAddress); break; + case lltok::kw_sanitize_thread: B.addAttribute(Attribute::SanitizeThread); break; + case lltok::kw_sanitize_memory: B.addAttribute(Attribute::SanitizeMemory); break; + case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break; + + // Error handling. + case lltok::kw_inreg: + case lltok::kw_signext: + case lltok::kw_zeroext: + HaveError |= + Error(Lex.getLoc(), + "invalid use of attribute on a function"); + break; + case lltok::kw_byval: + case lltok::kw_nest: + case lltok::kw_noalias: + case lltok::kw_nocapture: + case lltok::kw_sret: + HaveError |= + Error(Lex.getLoc(), + "invalid use of parameter-only attribute on a function"); + break; + } + + Lex.Lex(); + } +} //===----------------------------------------------------------------------===// // GlobalValue Reference/Resolution Routines. @@ -915,11 +1132,8 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &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(AttrBuilder &B, unsigned AttrKind) { - LocTy AttrLoc = Lex.getLoc(); +/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes. +bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { bool HaveError = false; B.clear(); @@ -929,42 +1143,6 @@ bool LLParser::ParseOptionalAttrs(AttrBuilder &B, unsigned AttrKind) { switch (Token) { default: // End of attributes. return HaveError; - case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break; - case lltok::kw_signext: B.addAttribute(Attributes::SExt); break; - case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break; - case lltok::kw_sret: B.addAttribute(Attributes::StructRet); break; - case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break; - case lltok::kw_nocapture: B.addAttribute(Attributes::NoCapture); break; - case lltok::kw_byval: B.addAttribute(Attributes::ByVal); break; - case lltok::kw_nest: B.addAttribute(Attributes::Nest); break; - - case lltok::kw_noreturn: B.addAttribute(Attributes::NoReturn); break; - case lltok::kw_nounwind: B.addAttribute(Attributes::NoUnwind); break; - case lltok::kw_uwtable: B.addAttribute(Attributes::UWTable); break; - case lltok::kw_returns_twice: B.addAttribute(Attributes::ReturnsTwice); break; - case lltok::kw_noinline: B.addAttribute(Attributes::NoInline); break; - case lltok::kw_readnone: B.addAttribute(Attributes::ReadNone); break; - case lltok::kw_readonly: B.addAttribute(Attributes::ReadOnly); break; - case lltok::kw_inlinehint: B.addAttribute(Attributes::InlineHint); break; - case lltok::kw_alwaysinline: B.addAttribute(Attributes::AlwaysInline); break; - case lltok::kw_optsize: B.addAttribute(Attributes::OptimizeForSize); break; - case lltok::kw_ssp: B.addAttribute(Attributes::StackProtect); break; - case lltok::kw_sspreq: B.addAttribute(Attributes::StackProtectReq); break; - case lltok::kw_noredzone: B.addAttribute(Attributes::NoRedZone); break; - case lltok::kw_noimplicitfloat: B.addAttribute(Attributes::NoImplicitFloat); break; - case lltok::kw_naked: B.addAttribute(Attributes::Naked); break; - case lltok::kw_nonlazybind: B.addAttribute(Attributes::NonLazyBind); break; - case lltok::kw_address_safety: B.addAttribute(Attributes::AddressSafety); break; - case lltok::kw_minsize: B.addAttribute(Attributes::MinSize); break; - - case lltok::kw_alignstack: { - unsigned Alignment; - if (ParseOptionalStackAlignment(Alignment)) - return true; - B.addStackAlignmentAttr(Alignment); - continue; - } - case lltok::kw_align: { unsigned Alignment; if (ParseOptionalAlignment(Alignment)) @@ -972,51 +1150,70 @@ bool LLParser::ParseOptionalAttrs(AttrBuilder &B, unsigned AttrKind) { B.addAlignmentAttr(Alignment); continue; } - + case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; + case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; + case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break; + case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; + case lltok::kw_sret: B.addAttribute(Attribute::StructRet); break; + case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; + + case lltok::kw_alignstack: case lltok::kw_nounwind: + case lltok::kw_alwaysinline: case lltok::kw_optsize: + case lltok::kw_inlinehint: case lltok::kw_readnone: + case lltok::kw_minsize: case lltok::kw_readonly: + case lltok::kw_naked: case lltok::kw_returns_twice: + case lltok::kw_nobuiltin: case lltok::kw_sanitize_address: + case lltok::kw_noimplicitfloat: case lltok::kw_sanitize_memory: + case lltok::kw_noinline: case lltok::kw_sanitize_thread: + case lltok::kw_nonlazybind: case lltok::kw_ssp: + case lltok::kw_noredzone: case lltok::kw_sspreq: + case lltok::kw_noreturn: case lltok::kw_uwtable: + HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); + break; } - // Perform some error checking. - switch (Token) { - default: - if (AttrKind == 2) - HaveError |= Error(AttrLoc, "invalid use of attribute on a function"); - break; - case lltok::kw_align: - // As a hack, we allow "align 2" on functions as a synonym for - // "alignstack 2". - break; + Lex.Lex(); + } +} - // Parameter Only: - case lltok::kw_sret: - case lltok::kw_nocapture: - case lltok::kw_byval: - case lltok::kw_nest: - if (AttrKind != 0) - HaveError |= Error(AttrLoc, "invalid use of parameter-only attribute"); +/// ParseOptionalReturnAttrs - Parse a potentially empty list of return attributes. +bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { + bool HaveError = false; + + B.clear(); + + while (1) { + lltok::Kind Token = Lex.getKind(); + switch (Token) { + default: // End of attributes. + return HaveError; + case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; + case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; + case lltok::kw_signext: B.addAttribute(Attribute::SExt); break; + case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; + + // Error handling. + case lltok::kw_sret: case lltok::kw_nocapture: + case lltok::kw_byval: case lltok::kw_nest: + HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute"); break; - // Function Only: - case lltok::kw_noreturn: - case lltok::kw_nounwind: - case lltok::kw_readnone: - case lltok::kw_readonly: - case lltok::kw_noinline: - case lltok::kw_alwaysinline: - case lltok::kw_optsize: - case lltok::kw_ssp: - case lltok::kw_sspreq: - case lltok::kw_noredzone: - case lltok::kw_noimplicitfloat: - case lltok::kw_naked: - case lltok::kw_inlinehint: - case lltok::kw_alignstack: - case lltok::kw_uwtable: - case lltok::kw_nonlazybind: - case lltok::kw_returns_twice: - case lltok::kw_address_safety: - case lltok::kw_minsize: - if (AttrKind != 2) - HaveError |= Error(AttrLoc, "invalid use of function-only attribute"); + case lltok::kw_align: case lltok::kw_noreturn: + case lltok::kw_alignstack: case lltok::kw_nounwind: + case lltok::kw_alwaysinline: case lltok::kw_optsize: + case lltok::kw_inlinehint: case lltok::kw_readnone: + case lltok::kw_minsize: case lltok::kw_readonly: + case lltok::kw_naked: case lltok::kw_returns_twice: + case lltok::kw_nobuiltin: case lltok::kw_sanitize_address: + case lltok::kw_noduplicate: case lltok::kw_sanitize_memory: + case lltok::kw_noimplicitfloat: case lltok::kw_sanitize_thread: + case lltok::kw_noinline: case lltok::kw_ssp: + case lltok::kw_nonlazybind: case lltok::kw_sspreq: + case lltok::kw_noredzone: case lltok::kw_sspstrong: + case lltok::kw_uwtable: + HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute"); break; } @@ -1207,7 +1404,7 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { } /// ParseOptionalCommaAlign -/// ::= +/// ::= /// ::= ',' align 4 /// /// This returns with AteExtraComma set to true if it ate an excess comma at the @@ -1221,7 +1418,7 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment, AteExtraComma = true; return false; } - + if (Lex.getKind() != lltok::kw_align) return Error(Lex.getLoc(), "expected metadata or 'align'"); @@ -1289,7 +1486,7 @@ bool LLParser::ParseOptionalStackAlignment(unsigned &Alignment) { bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices, bool &AteExtraComma) { AteExtraComma = false; - + if (Lex.getKind() != lltok::comma) return TokError("expected ',' as start of index list"); @@ -1345,7 +1542,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { case lltok::LocalVar: { // Type ::= %foo std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()]; - + // If the type hasn't been defined yet, create a forward definition and // remember where that forward def'n was seen (in case it never is defined). if (Entry.first == 0) { @@ -1362,7 +1559,7 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) { if (Lex.getUIntVal() >= NumberedTypes.size()) NumberedTypes.resize(Lex.getUIntVal()+1); std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()]; - + // If the type hasn't been defined yet, create a forward definition and // remember where that forward def'n was seen (in case it never is defined). if (Entry.first == 0) { @@ -1432,6 +1629,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, if (ParseToken(lltok::lparen, "expected '(' in call")) return true; + unsigned AttrIndex = 1; while (Lex.getKind() != lltok::rparen) { // If this isn't the first argument, we need a comma. if (!ArgList.empty() && @@ -1447,10 +1645,11 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, return true; // Otherwise, handle normal operands. - if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS)) + if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS)) return true; - ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(V->getContext(), - ArgAttrs))); + ArgList.push_back(ParamInfo(ArgLoc, V, AttributeSet::get(V->getContext(), + AttrIndex++, + ArgAttrs))); } Lex.Lex(); // Lex the ')'. @@ -1486,7 +1685,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, std::string Name; if (ParseType(ArgTy) || - ParseOptionalAttrs(Attrs, 0)) return true; + ParseOptionalParamAttrs(Attrs)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1499,9 +1698,10 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); + unsigned AttrIndex = 1; ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - Attributes::get(ArgTy->getContext(), - Attrs), Name)); + AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1512,7 +1712,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, // Otherwise must be an argument type. TypeLoc = Lex.getLoc(); - if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true; + if (ParseType(ArgTy) || ParseOptionalParamAttrs(Attrs)) return true; if (ArgTy->isVoidTy()) return Error(TypeLoc, "argument can not have void type"); @@ -1528,7 +1728,8 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, return Error(TypeLoc, "invalid type for function argument"); ArgList.push_back(ArgInfo(TypeLoc, ArgTy, - Attributes::get(ArgTy->getContext(), Attrs), + AttributeSet::get(ArgTy->getContext(), + AttrIndex++, Attrs), Name)); } } @@ -1553,7 +1754,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { 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.hasAttributes()) + if (ArgList[i].Attrs.hasAttributes(i + 1)) return Error(ArgList[i].Loc, "argument attributes invalid in function type"); } @@ -1571,7 +1772,7 @@ bool LLParser::ParseFunctionType(Type *&Result) { bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) { SmallVector<Type*, 8> Elts; if (ParseStructBody(Elts)) return true; - + Result = StructType::get(Context, Elts, Packed); return false; } @@ -1583,20 +1784,20 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, // If the type was already defined, diagnose the redefinition. if (Entry.first && !Entry.second.isValid()) return Error(TypeLoc, "redefinition of type"); - + // If we have opaque, just return without filling in the definition for the // struct. This counts as a definition as far as the .ll file goes. if (EatIfPresent(lltok::kw_opaque)) { // This type is being defined, so clear the location to indicate this. Entry.second = SMLoc(); - + // If this type number has never been uttered, create it. if (Entry.first == 0) Entry.first = StructType::create(Context, Name); ResultTy = Entry.first; return false; } - + // If the type starts with '<', then it is either a packed struct or a vector. bool isPacked = EatIfPresent(lltok::less); @@ -1606,27 +1807,27 @@ bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name, if (Lex.getKind() != lltok::lbrace) { if (Entry.first) return Error(TypeLoc, "forward references to non-struct type"); - + ResultTy = 0; if (isPacked) return ParseArrayVectorType(ResultTy, true); return ParseType(ResultTy); } - + // This type is being defined, so clear the location to indicate this. Entry.second = SMLoc(); - + // If this type number has never been uttered, create it. if (Entry.first == 0) Entry.first = StructType::create(Context, Name); - + StructType *STy = cast<StructType>(Entry.first); - + SmallVector<Type*, 8> Body; if (ParseStructBody(Body) || (isPacked && ParseToken(lltok::greater, "expected '>' in packed struct"))) return true; - + STy->setBody(Body, isPacked); ResultTy = STy; return false; @@ -1699,8 +1900,7 @@ bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) { if ((unsigned)Size != Size) return Error(SizeLoc, "size too large for vector"); if (!VectorType::isValidElementType(EltTy)) - return Error(TypeLoc, - "vector element type must be fp, integer or a pointer to these types"); + return Error(TypeLoc, "invalid vector element type"); Result = VectorType::get(EltTy, unsigned(Size)); } else { if (!ArrayType::isValidElementType(EltTy)) @@ -1757,18 +1957,18 @@ bool LLParser::PerFunctionState::FinishFunction() { FunctionID.Kind = ValID::t_GlobalID; FunctionID.UIntVal = FunctionNumber; } - + std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > >::iterator FRBAI = P.ForwardRefBlockAddresses.find(FunctionID); if (FRBAI != P.ForwardRefBlockAddresses.end()) { // Resolve all these references. if (P.ResolveForwardRefBlockAddresses(&F, FRBAI->second, this)) return true; - + P.ForwardRefBlockAddresses.erase(FRBAI); } } - + if (!ForwardRefVals.empty()) return P.Error(ForwardRefVals.begin()->second.second, "use of undefined value '%" + ForwardRefVals.begin()->first + @@ -2118,7 +2318,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return false; case lltok::kw_asm: { - // ValID ::= 'asm' SideEffect? AlignStack? STRINGCONSTANT ',' STRINGCONSTANT + // ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ',' + // STRINGCONSTANT bool HasSideEffect, AlignStack, AsmDialect; Lex.Lex(); if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) || @@ -2141,19 +2342,19 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ValID Fn, Label; LocTy FnLoc, LabelLoc; - + if (ParseToken(lltok::lparen, "expected '(' in block address expression") || ParseValID(Fn) || ParseToken(lltok::comma, "expected comma in block address expression")|| ParseValID(Label) || ParseToken(lltok::rparen, "expected ')' in block address expression")) return true; - + if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName) return Error(Fn.Loc, "expected function name in blockaddress"); if (Label.Kind != ValID::t_LocalID && Label.Kind != ValID::t_LocalName) return Error(Label.Loc, "expected basic block name in blockaddress"); - + // Make a global variable as a placeholder for this reference. GlobalVariable *FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false, GlobalValue::InternalLinkage, @@ -2163,7 +2364,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ID.Kind = ValID::t_Constant; return false; } - + case lltok::kw_trunc: case lltok::kw_zext: case lltok::kw_sext: @@ -2543,7 +2744,7 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, return (V == 0); case ValID::t_InlineAsm: { PointerType *PTy = dyn_cast<PointerType>(Ty); - FunctionType *FTy = + FunctionType *FTy = PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0; if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2)) return Error(ID.Loc, "invalid type for inline asm constraint string"); @@ -2632,13 +2833,13 @@ bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, "initializer with struct type has wrong # elements"); if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct)) return Error(ID.Loc, "packed'ness of initializer and type don't match"); - + // Verify that the elements are compatible with the structtype. for (unsigned i = 0, e = ID.UIntVal; i != e; ++i) if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i)) return Error(ID.Loc, "element " + Twine(i) + " of struct initializer doesn't match struct element type"); - + V = ConstantStruct::get(ST, makeArrayRef(ID.ConstantStructElts, ID.UIntVal)); } else @@ -2690,7 +2891,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (ParseOptionalLinkage(Linkage) || ParseOptionalVisibility(Visibility) || ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/)) return true; @@ -2748,6 +2949,8 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { SmallVector<ArgInfo, 8> ArgList; bool isVarArg; AttrBuilder FuncAttrs; + std::vector<unsigned> FwdRefAttrGrps; + LocTy NoBuiltinLoc; std::string Section; unsigned Alignment; std::string GC; @@ -2757,7 +2960,8 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (ParseArgumentList(ArgList, isVarArg) || ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, &UnnamedAddrLoc) || - ParseOptionalAttrs(FuncAttrs, 2) || + ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false, + NoBuiltinLoc) || (EatIfPresent(lltok::kw_section) && ParseStringConstant(Section)) || ParseOptionalAlignment(Alignment) || @@ -2765,39 +2969,41 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { ParseStringConstant(GC))) return true; + if (FuncAttrs.contains(Attribute::NoBuiltin)) + return Error(NoBuiltinLoc, "'nobuiltin' attribute not valid on function"); + // If the alignment was parsed as an attribute, move to the alignment field. if (FuncAttrs.hasAlignmentAttr()) { Alignment = FuncAttrs.getAlignment(); - FuncAttrs.removeAttribute(Attributes::Alignment); + FuncAttrs.removeAttribute(Attribute::Alignment); } // Okay, if we got here, the function is syntactically valid. Convert types // and do semantic checks. std::vector<Type*> ParamTypeList; - SmallVector<AttributeWithIndex, 8> Attrs; + SmallVector<AttributeSet, 8> Attrs; if (RetAttrs.hasAttributes()) - Attrs.push_back( - AttributeWithIndex::get(AttrListPtr::ReturnIndex, - Attributes::get(RetType->getContext(), - RetAttrs))); + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::ReturnIndex, + RetAttrs)); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); - if (ArgList[i].Attrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); + Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); + } } if (FuncAttrs.hasAttributes()) - Attrs.push_back( - AttributeWithIndex::get(AttrListPtr::FunctionIndex, - Attributes::get(RetType->getContext(), - FuncAttrs))); + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::FunctionIndex, + FuncAttrs)); - AttrListPtr PAL = AttrListPtr::get(Context, Attrs); + AttributeSet PAL = AttributeSet::get(Context, Attrs); - if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) && - !RetType->isVoidTy()) + if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy()) return Error(RetTypeLoc, "functions with 'sret' argument must return void"); FunctionType *FT = @@ -2818,7 +3024,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { if (Fn->getType() != PFT) return Error(FRVI->second.second, "invalid forward reference to " "function '" + FunctionName + "' with wrong type!"); - + ForwardRefVals.erase(FRVI); } else if ((Fn = M->getFunction(FunctionName))) { // Reject redefinitions. @@ -2858,6 +3064,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Fn->setAlignment(Alignment); Fn->setSection(Section); if (!GC.empty()) Fn->setGC(GC.c_str()); + ForwardRefAttrGroups[Fn] = FwdRefAttrGrps; // Add all of the arguments we parsed to the function. Function::arg_iterator ArgIt = Fn->arg_begin(); @@ -2887,13 +3094,13 @@ bool LLParser::ParseFunctionBody(Function &Fn) { int FunctionNumber = -1; if (!Fn.hasName()) FunctionNumber = NumberedVals.size()-1; - + PerFunctionState PFS(*this, Fn, FunctionNumber); // We need at least one basic block. if (Lex.getKind() == lltok::rbrace) return TokError("function body requires at least one basic block"); - + while (Lex.getKind() != lltok::rbrace) if (ParseBasicBlock(PFS)) return true; @@ -2961,7 +3168,7 @@ bool LLParser::ParseBasicBlock(PerFunctionState &PFS) { // *must* be followed by metadata. if (ParseInstructionMetadata(Inst, &PFS)) return true; - break; + break; } // Set the name on the instruction. @@ -3004,16 +3211,26 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, bool NUW = EatIfPresent(lltok::kw_nuw); bool NSW = EatIfPresent(lltok::kw_nsw); if (!NUW) NUW = EatIfPresent(lltok::kw_nuw); - + if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true; - + if (NUW) cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true); if (NSW) cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true); return false; } case lltok::kw_fadd: case lltok::kw_fsub: - case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2); + case lltok::kw_fmul: + case lltok::kw_fdiv: + case lltok::kw_frem: { + FastMathFlags FMF = EatFastMathFlagsIfPresent(); + int Res = ParseArithmetic(Inst, PFS, KeywordVal, 2); + if (Res != 0) + return Res; + if (FMF.any()) + Inst->setFastMathFlags(FMF); + return 0; + } case lltok::kw_sdiv: case lltok::kw_udiv: @@ -3028,8 +3245,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_urem: case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1); - case lltok::kw_fdiv: - case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2); case lltok::kw_and: case lltok::kw_or: case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal); @@ -3075,7 +3290,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { if (Opc == Instruction::FCmp) { switch (Lex.getKind()) { - default: TokError("expected fcmp predicate (e.g. 'oeq')"); + default: return 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; @@ -3095,7 +3310,7 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) { } } else { switch (Lex.getKind()) { - default: TokError("expected icmp predicate (e.g. 'eq')"); + default: return 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; @@ -3126,12 +3341,12 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, if (ParseType(Ty, true /*void allowed*/)) return true; Type *ResType = PFS.getFunction().getReturnType(); - + if (Ty->isVoidTy()) { if (!ResType->isVoidTy()) return Error(TypeLoc, "value doesn't match function result type '" + getTypeString(ResType) + "'"); - + Inst = ReturnInst::Create(Context); return false; } @@ -3142,7 +3357,7 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB, if (ResType != RV->getType()) return Error(TypeLoc, "value doesn't match function result type '" + getTypeString(ResType) + "'"); - + Inst = ReturnInst::Create(Context, RV); return false; } @@ -3204,7 +3419,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) { ParseToken(lltok::comma, "expected ',' after case value") || ParseTypeAndBasicBlock(DestBB, PFS)) return true; - + if (!SeenCases.insert(Constant)) return Error(CondLoc, "duplicate case value in switch"); if (!isa<ConstantInt>(Constant)) @@ -3232,26 +3447,26 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { ParseToken(lltok::comma, "expected ',' after indirectbr address") || ParseToken(lltok::lsquare, "expected '[' with indirectbr")) return true; - + if (!Address->getType()->isPointerTy()) return Error(AddrLoc, "indirectbr address must have pointer type"); - + // Parse the destination list. SmallVector<BasicBlock*, 16> DestList; - + if (Lex.getKind() != lltok::rsquare) { BasicBlock *DestBB; if (ParseTypeAndBasicBlock(DestBB, PFS)) return true; DestList.push_back(DestBB); - + while (EatIfPresent(lltok::comma)) { if (ParseTypeAndBasicBlock(DestBB, PFS)) return true; DestList.push_back(DestBB); } } - + if (ParseToken(lltok::rsquare, "expected ']' at end of block list")) return true; @@ -3269,6 +3484,8 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); AttrBuilder RetAttrs, FnAttrs; + std::vector<unsigned> FwdRefAttrGrps; + LocTy NoBuiltinLoc; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3277,11 +3494,12 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { BasicBlock *NormalBB, *UnwindBB; if (ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseOptionalAttrs(FnAttrs, 2) || + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, + NoBuiltinLoc) || ParseToken(lltok::kw_to, "expected 'to' in invoke") || ParseTypeAndBasicBlock(NormalBB, PFS) || ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") || @@ -3311,13 +3529,12 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // Set up the Attributes for the function. - SmallVector<AttributeWithIndex, 8> Attrs; + // Set up the Attribute for the function. + SmallVector<AttributeSet, 8> Attrs; if (RetAttrs.hasAttributes()) - Attrs.push_back( - AttributeWithIndex::get(AttrListPtr::ReturnIndex, - Attributes::get(Callee->getContext(), - RetAttrs))); + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::ReturnIndex, + RetAttrs)); SmallVector<Value*, 8> Args; @@ -3337,25 +3554,27 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); + Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); + } } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); if (FnAttrs.hasAttributes()) - Attrs.push_back( - AttributeWithIndex::get(AttrListPtr::FunctionIndex, - Attributes::get(Callee->getContext(), - FnAttrs))); + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::FunctionIndex, + FnAttrs)); - // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Context, Attrs); + // Finish off the Attribute and check them + AttributeSet PAL = AttributeSet::get(Context, Attrs); InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); II->setCallingConv(CC); II->setAttributes(PAL); + ForwardRefAttrGroups[II] = FwdRefAttrGrps; Inst = II; return false; } @@ -3674,6 +3893,8 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, bool isTail) { AttrBuilder RetAttrs, FnAttrs; + std::vector<unsigned> FwdRefAttrGrps; + LocTy NoBuiltinLoc; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3683,11 +3904,12 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) || ParseOptionalCallingConv(CC) || - ParseOptionalAttrs(RetAttrs, 1) || + ParseOptionalReturnAttrs(RetAttrs) || ParseType(RetType, RetTypeLoc, true /*void allowed*/) || ParseValID(CalleeID) || ParseParameterList(ArgList, PFS) || - ParseOptionalAttrs(FnAttrs, 2)) + ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, + NoBuiltinLoc)) return true; // If RetType is a non-function pointer type, then this is the short syntax @@ -3713,13 +3935,12 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, Value *Callee; if (ConvertValIDToValue(PFTy, CalleeID, Callee, &PFS)) return true; - // Set up the Attributes for the function. - SmallVector<AttributeWithIndex, 8> Attrs; + // Set up the Attribute for the function. + SmallVector<AttributeSet, 8> Attrs; if (RetAttrs.hasAttributes()) - Attrs.push_back( - AttributeWithIndex::get(AttrListPtr::ReturnIndex, - Attributes::get(Callee->getContext(), - RetAttrs))); + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::ReturnIndex, + RetAttrs)); SmallVector<Value*, 8> Args; @@ -3739,26 +3960,28 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(ArgList[i].Loc, "argument is not of expected type '" + getTypeString(ExpectedTy) + "'"); Args.push_back(ArgList[i].V); - if (ArgList[i].Attrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs)); + if (ArgList[i].Attrs.hasAttributes(i + 1)) { + AttrBuilder B(ArgList[i].Attrs, i + 1); + Attrs.push_back(AttributeSet::get(RetType->getContext(), i + 1, B)); + } } if (I != E) return Error(CallLoc, "not enough parameters specified for call"); if (FnAttrs.hasAttributes()) - Attrs.push_back( - AttributeWithIndex::get(AttrListPtr::FunctionIndex, - Attributes::get(Callee->getContext(), - FnAttrs))); + Attrs.push_back(AttributeSet::get(RetType->getContext(), + AttributeSet::FunctionIndex, + FnAttrs)); - // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Context, Attrs); + // Finish off the Attribute and check them + AttributeSet PAL = AttributeSet::get(Context, Attrs); CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); CI->setCallingConv(CC); CI->setAttributes(PAL); + ForwardRefAttrGroups[CI] = FwdRefAttrGrps; Inst = CI; return false; } @@ -3798,7 +4021,7 @@ int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) { /// ParseLoad /// ::= 'load' 'volatile'? TypeAndValue (',' 'align' i32)? -/// ::= 'load' 'atomic' 'volatile'? TypeAndValue +/// ::= 'load' 'atomic' 'volatile'? TypeAndValue /// 'singlethread'? AtomicOrdering (',' 'align' i32)? int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) { Value *Val; LocTy Loc; @@ -4034,9 +4257,6 @@ int LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) { Indices.push_back(Val); } - if (Val && Val->getType()->isVectorTy() && Indices.size() != 1) - return Error(EltLoc, "vector getelementptrs must have a single index"); - if (!GetElementPtrInst::getIndexedType(Ptr->getType(), Indices)) return Error(Loc, "invalid getelementptr indices"); Inst = GetElementPtrInst::Create(Ptr, Indices); @@ -4075,7 +4295,7 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndValue(Val1, Loc1, PFS) || ParseIndexList(Indices, AteExtraComma)) return true; - + if (!Val0->getType()->isAggregateType()) return Error(Loc0, "insertvalue operand must be aggregate type"); @@ -4105,7 +4325,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts, Elts.push_back(0); continue; } - + Value *V = 0; if (ParseTypeAndValue(V, PFS)) return true; Elts.push_back(V); diff --git a/contrib/llvm/lib/AsmParser/LLParser.h b/contrib/llvm/lib/AsmParser/LLParser.h index c6bbdb2..1f2879e 100644 --- a/contrib/llvm/lib/AsmParser/LLParser.h +++ b/contrib/llvm/lib/AsmParser/LLParser.h @@ -15,12 +15,13 @@ #define LLVM_ASMPARSER_LLPARSER_H #include "LLLexer.h" -#include "llvm/Attributes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" -#include "llvm/Type.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/Type.h" #include "llvm/Support/ValueHandle.h" #include <map> @@ -55,7 +56,7 @@ namespace llvm { t_ConstantStruct, // Value in ConstantStructElts. t_PackedConstantStruct // Value in ConstantStructElts. } Kind; - + LLLexer::LocTy Loc; unsigned UIntVal; std::string StrVal, StrVal2; @@ -65,23 +66,23 @@ namespace llvm { MDNode *MDNodeVal; MDString *MDStringVal; Constant **ConstantStructElts; - + ValID() : Kind(t_LocalID), APFloatVal(0.0) {} ~ValID() { if (Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) delete [] ConstantStructElts; } - + bool operator<(const ValID &RHS) const { if (Kind == t_LocalID || Kind == t_GlobalID) return UIntVal < RHS.UIntVal; assert((Kind == t_LocalName || Kind == t_GlobalName || - Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && + Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) && "Ordering not defined for this ValID kind yet"); return StrVal < RHS.StrVal; } }; - + class LLParser { public: typedef LLLexer::LocTy LocTy; @@ -89,7 +90,7 @@ namespace llvm { LLVMContext &Context; LLLexer Lex; Module *M; - + // Instruction metadata resolution. Each instruction can have a list of // MDRef info associated with them. // @@ -110,7 +111,7 @@ namespace llvm { // have processed a use of the type but not a definition yet. StringMap<std::pair<Type*, LocTy> > NamedTypes; std::vector<std::pair<Type*, LocTy> > NumberedTypes; - + std::vector<TrackingVH<MDNode> > NumberedMetadata; std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> > ForwardRefMDNodes; @@ -118,14 +119,18 @@ namespace llvm { std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals; std::map<unsigned, std::pair<GlobalValue*, LocTy> > ForwardRefValIDs; std::vector<GlobalValue*> NumberedVals; - + // References to blockaddress. The key is the function ValID, the value is // a list of references to blocks in that function. std::map<ValID, std::vector<std::pair<ValID, GlobalValue*> > > ForwardRefBlockAddresses; - + + // Attribute builder reference information. + std::map<Value*, std::vector<unsigned> > ForwardRefAttrGroups; + std::map<unsigned, AttrBuilder> NumberedAttrBuilders; + public: - LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) : + LLParser(MemoryBuffer *F, SourceMgr &SM, SMDiagnostic &Err, Module *m) : Context(m->getContext()), Lex(F, SM, Err, m->getContext()), M(m) {} bool Run(); @@ -154,6 +159,21 @@ namespace llvm { Lex.Lex(); return true; } + + FastMathFlags EatFastMathFlagsIfPresent() { + FastMathFlags FMF; + while (true) + switch (Lex.getKind()) { + case lltok::kw_fast: FMF.setUnsafeAlgebra(); Lex.Lex(); continue; + case lltok::kw_nnan: FMF.setNoNaNs(); Lex.Lex(); continue; + case lltok::kw_ninf: FMF.setNoInfs(); Lex.Lex(); continue; + case lltok::kw_nsz: FMF.setNoSignedZeros(); Lex.Lex(); continue; + case lltok::kw_arcp: FMF.setAllowReciprocal(); Lex.Lex(); continue; + default: return FMF; + } + return FMF; + } + bool ParseOptionalToken(lltok::Kind T, bool &Present, LocTy *Loc = 0) { if (Lex.getKind() != T) { Present = false; @@ -175,7 +195,8 @@ namespace llvm { bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalAddrSpace(unsigned &AddrSpace); - bool ParseOptionalAttrs(AttrBuilder &Attrs, unsigned AttrKind); + bool ParseOptionalParamAttrs(AttrBuilder &B); + bool ParseOptionalReturnAttrs(AttrBuilder &B); bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage); bool ParseOptionalLinkage(unsigned &Linkage) { bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage); @@ -200,8 +221,8 @@ namespace llvm { bool ParseTopLevelEntities(); bool ValidateEndOfModule(); bool ParseTargetDefinition(); - bool ParseDepLibs(); bool ParseModuleAsm(); + bool ParseDepLibs(); // FIXME: Remove in 4.0. bool ParseUnnamedType(); bool ParseNamedType(); bool ParseDeclare(); @@ -218,6 +239,10 @@ namespace llvm { bool ParseMDString(MDString *&Result); bool ParseMDNodeID(MDNode *&Result); bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo); + bool ParseUnnamedAttrGrp(); + bool ParseFnAttributeValuePairs(AttrBuilder &B, + std::vector<unsigned> &FwdRefAttrGrps, + bool inAttrGrp, LocTy &NoBuiltinLoc); // Type Parsing. bool ParseType(Type *&Result, bool AllowVoid = false); @@ -241,7 +266,7 @@ namespace llvm { std::map<std::string, std::pair<Value*, LocTy> > ForwardRefVals; std::map<unsigned, std::pair<Value*, LocTy> > ForwardRefValIDs; std::vector<Value*> NumberedVals; - + /// FunctionNumber - If this is an unnamed function, this is the slot /// number of it, otherwise it is -1. int FunctionNumber; @@ -308,8 +333,8 @@ namespace llvm { struct ParamInfo { LocTy Loc; Value *V; - Attributes Attrs; - ParamInfo(LocTy loc, Value *v, Attributes attrs) + AttributeSet Attrs; + ParamInfo(LocTy loc, Value *v, AttributeSet attrs) : Loc(loc), V(v), Attrs(attrs) {} }; bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList, @@ -329,9 +354,9 @@ namespace llvm { struct ArgInfo { LocTy Loc; Type *Ty; - Attributes Attrs; + AttributeSet Attrs; std::string Name; - ArgInfo(LocTy L, Type *ty, Attributes Attr, const std::string &N) + ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N) : Loc(L), Ty(ty), Attrs(Attr), Name(N) {} }; bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg); @@ -375,8 +400,8 @@ namespace llvm { int ParseGetElementPtr(Instruction *&I, PerFunctionState &PFS); int ParseExtractValue(Instruction *&I, PerFunctionState &PFS); int ParseInsertValue(Instruction *&I, PerFunctionState &PFS); - - bool ResolveForwardRefBlockAddresses(Function *TheFn, + + bool ResolveForwardRefBlockAddresses(Function *TheFn, std::vector<std::pair<ValID, GlobalValue*> > &Refs, PerFunctionState *PFS); }; diff --git a/contrib/llvm/lib/AsmParser/LLToken.h b/contrib/llvm/lib/AsmParser/LLToken.h index 036686d..cd25ba3 100644 --- a/contrib/llvm/lib/AsmParser/LLToken.h +++ b/contrib/llvm/lib/AsmParser/LLToken.h @@ -30,6 +30,7 @@ namespace lltok { lparen, rparen, // ( ) backslash, // \ (not /) exclaim, // ! + hash, // # kw_x, kw_true, kw_false, @@ -44,6 +45,7 @@ namespace lltok { kw_dllimport, kw_dllexport, kw_common, kw_available_externally, kw_default, kw_hidden, kw_protected, kw_unnamed_addr, + kw_externally_initialized, kw_extern_weak, kw_external, kw_thread_local, kw_localdynamic, kw_initialexec, kw_localexec, @@ -54,12 +56,17 @@ namespace lltok { kw_target, kw_triple, kw_unwind, - kw_deplibs, + kw_deplibs, // FIXME: Remove in 4.0 kw_datalayout, kw_volatile, kw_atomic, kw_unordered, kw_monotonic, kw_acquire, kw_release, kw_acq_rel, kw_seq_cst, kw_singlethread, + kw_nnan, + kw_ninf, + kw_nsz, + kw_arcp, + kw_fast, kw_nuw, kw_nsw, kw_exact, @@ -84,33 +91,39 @@ namespace lltok { kw_ptx_kernel, kw_ptx_device, kw_spir_kernel, kw_spir_func, - kw_signext, - kw_zeroext, + // Attributes: + kw_attributes, + kw_alwaysinline, + kw_sanitize_address, + kw_byval, + kw_inlinehint, kw_inreg, - kw_sret, - kw_nounwind, - kw_noreturn, + kw_minsize, + kw_naked, + kw_nest, kw_noalias, + kw_nobuiltin, kw_nocapture, - kw_byval, - kw_nest, + kw_noduplicate, + kw_noimplicitfloat, + kw_noinline, + kw_nonlazybind, + kw_noredzone, + kw_noreturn, + kw_nounwind, + kw_optsize, kw_readnone, kw_readonly, - kw_uwtable, kw_returns_twice, - - kw_inlinehint, - kw_noinline, - kw_alwaysinline, - kw_optsize, + kw_signext, kw_ssp, kw_sspreq, - kw_noredzone, - kw_noimplicitfloat, - kw_naked, - kw_nonlazybind, - kw_address_safety, - kw_minsize, + kw_sspstrong, + kw_sret, + kw_sanitize_thread, + kw_sanitize_memory, + kw_uwtable, + kw_zeroext, kw_type, kw_opaque, @@ -147,6 +160,7 @@ namespace lltok { // Unsigned Valued tokens (UIntVal). GlobalID, // @42 LocalVarID, // %42 + AttrGrpID, // #42 // String valued tokens (StrVal). LabelStr, // foo: diff --git a/contrib/llvm/lib/AsmParser/Parser.cpp b/contrib/llvm/lib/AsmParser/Parser.cpp index 21b7fd4..bb4f03b 100644 --- a/contrib/llvm/lib/AsmParser/Parser.cpp +++ b/contrib/llvm/lib/AsmParser/Parser.cpp @@ -13,10 +13,10 @@ #include "llvm/Assembly/Parser.h" #include "LLParser.h" -#include "llvm/Module.h" #include "llvm/ADT/OwningPtr.h" -#include "llvm/Support/SourceMgr.h" +#include "llvm/IR/Module.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" #include <cstring> |