diff options
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 225 |
1 files changed, 171 insertions, 54 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 432ec151cf8a..a1cdeac2b47f 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -37,6 +37,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/Value.h" #include "llvm/IR/ValueSymbolTable.h" #include "llvm/Support/Casting.h" @@ -47,7 +48,6 @@ #include <algorithm> #include <cassert> #include <cstring> -#include <iterator> #include <vector> using namespace llvm; @@ -59,9 +59,31 @@ static std::string getTypeString(Type *T) { return Tmp.str(); } +static void setContextOpaquePointers(LLLexer &L, LLVMContext &C) { + while (true) { + lltok::Kind K = L.Lex(); + // LLLexer will set the opaque pointers option in LLVMContext if it sees an + // explicit "ptr". + if (K == lltok::star || K == lltok::Error || K == lltok::Eof || + isa_and_nonnull<PointerType>(L.getTyVal())) { + if (K == lltok::star) + C.setOpaquePointers(false); + return; + } + } +} + /// Run: module ::= toplevelentity* bool LLParser::Run(bool UpgradeDebugInfo, DataLayoutCallbackTy DataLayoutCallback) { + // If we haven't decided on whether or not we're using opaque pointers, do a + // quick lex over the tokens to see if we explicitly construct any typed or + // opaque pointer types. + // Don't bail out on an error so we do the same work in the parsing below + // regardless of if --opaque-pointers is set. + if (!Context.hasSetOpaquePointersValue()) + setContextOpaquePointers(OPLex, Context); + // Prime the lexer. Lex.Lex(); @@ -248,7 +270,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) { // remangle intrinsics names as well. for (Function &F : llvm::make_early_inc_range(*M)) { if (auto Remangled = Intrinsic::remangleIntrinsicFunction(&F)) { - F.replaceAllUsesWith(Remangled.getValue()); + F.replaceAllUsesWith(*Remangled); F.eraseFromParent(); } } @@ -1081,6 +1103,45 @@ bool LLParser::parseAliasOrIFunc(const std::string &Name, LocTy NameLoc, return false; } +static bool isSanitizer(lltok::Kind Kind) { + switch (Kind) { + case lltok::kw_no_sanitize_address: + case lltok::kw_no_sanitize_hwaddress: + case lltok::kw_no_sanitize_memtag: + case lltok::kw_sanitize_address_dyninit: + return true; + default: + return false; + } +} + +bool LLParser::parseSanitizer(GlobalVariable *GV) { + using SanitizerMetadata = GlobalValue::SanitizerMetadata; + SanitizerMetadata Meta; + if (GV->hasSanitizerMetadata()) + Meta = GV->getSanitizerMetadata(); + + switch (Lex.getKind()) { + case lltok::kw_no_sanitize_address: + Meta.NoAddress = true; + break; + case lltok::kw_no_sanitize_hwaddress: + Meta.NoHWAddress = true; + break; + case lltok::kw_no_sanitize_memtag: + Meta.NoMemtag = true; + break; + case lltok::kw_sanitize_address_dyninit: + Meta.IsDynInit = true; + break; + default: + return tokError("non-sanitizer token passed to LLParser::parseSanitizer()"); + } + GV->setSanitizerMetadata(Meta); + Lex.Lex(); + return false; +} + /// parseGlobal /// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier /// OptionalVisibility OptionalDLLStorageClass @@ -1168,7 +1229,7 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc, GV->setUnnamedAddr(UnnamedAddr); if (GVal) { - if (!GVal->getType()->isOpaque() && GVal->getValueType() != Ty) + if (GVal->getType() != Ty->getPointerTo(AddrSpace)) return error( TyLoc, "forward reference and definition of global have different types"); @@ -1199,6 +1260,9 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc, } else if (Lex.getKind() == lltok::MetadataVar) { if (parseGlobalObjectMetadataAttachment(*GV)) return true; + } else if (isSanitizer(Lex.getKind())) { + if (parseSanitizer(GV)) + return true; } else { Comdat *C; if (parseOptionalComdat(Name, C)) @@ -1333,6 +1397,20 @@ bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B, B.addDereferenceableOrNullAttr(Bytes); return false; } + case Attribute::UWTable: { + UWTableKind Kind; + if (parseOptionalUWTableKind(Kind)) + return true; + B.addUWTableAttr(Kind); + return false; + } + case Attribute::AllocKind: { + AllocFnKind Kind = AllocFnKind::Unknown; + if (parseAllocKind(Kind)) + return true; + B.addAllocKindAttr(Kind); + return false; + } default: B.addAttribute(Attr); Lex.Lex(); @@ -1996,6 +2074,56 @@ bool LLParser::parseOptionalDerefAttrBytes(lltok::Kind AttrKind, return false; } +bool LLParser::parseOptionalUWTableKind(UWTableKind &Kind) { + Lex.Lex(); + Kind = UWTableKind::Default; + if (!EatIfPresent(lltok::lparen)) + return false; + LocTy KindLoc = Lex.getLoc(); + if (Lex.getKind() == lltok::kw_sync) + Kind = UWTableKind::Sync; + else if (Lex.getKind() == lltok::kw_async) + Kind = UWTableKind::Async; + else + return error(KindLoc, "expected unwind table kind"); + Lex.Lex(); + return parseToken(lltok::rparen, "expected ')'"); +} + +bool LLParser::parseAllocKind(AllocFnKind &Kind) { + Lex.Lex(); + LocTy ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::lparen)) + return error(ParenLoc, "expected '('"); + LocTy KindLoc = Lex.getLoc(); + std::string Arg; + if (parseStringConstant(Arg)) + return error(KindLoc, "expected allockind value"); + for (StringRef A : llvm::split(Arg, ",")) { + if (A == "alloc") { + Kind |= AllocFnKind::Alloc; + } else if (A == "realloc") { + Kind |= AllocFnKind::Realloc; + } else if (A == "free") { + Kind |= AllocFnKind::Free; + } else if (A == "uninitialized") { + Kind |= AllocFnKind::Uninitialized; + } else if (A == "zeroed") { + Kind |= AllocFnKind::Zeroed; + } else if (A == "aligned") { + Kind |= AllocFnKind::Aligned; + } else { + return error(KindLoc, Twine("unknown allockind ") + A); + } + } + ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::rparen)) + return error(ParenLoc, "expected ')'"); + if (Kind == AllocFnKind::Unknown) + return error(KindLoc, "expected allockind value"); + return false; +} + /// parseOptionalCommaAlign /// ::= /// ::= ',' align 4 @@ -3344,24 +3472,8 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) { ID.Kind = ValID::t_Constant; return false; } - case lltok::kw_extractvalue: { - Lex.Lex(); - Constant *Val; - SmallVector<unsigned, 4> Indices; - if (parseToken(lltok::lparen, - "expected '(' in extractvalue constantexpr") || - parseGlobalTypeAndValue(Val) || parseIndexList(Indices) || - parseToken(lltok::rparen, "expected ')' in extractvalue constantexpr")) - return true; - - if (!Val->getType()->isAggregateType()) - return error(ID.Loc, "extractvalue operand must be aggregate type"); - if (!ExtractValueInst::getIndexedType(Val->getType(), Indices)) - return error(ID.Loc, "invalid indices for extractvalue"); - ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices); - ID.Kind = ValID::t_Constant; - return false; - } + case lltok::kw_extractvalue: + return error(ID.Loc, "extractvalue constexprs are no longer supported"); case lltok::kw_insertvalue: { Lex.Lex(); Constant *Val0, *Val1; @@ -3881,11 +3993,11 @@ struct MDAPSIntField : public MDFieldImpl<APSInt> { }; struct MDSignedField : public MDFieldImpl<int64_t> { - int64_t Min; - int64_t Max; + int64_t Min = INT64_MIN; + int64_t Max = INT64_MAX; MDSignedField(int64_t Default = 0) - : ImplTy(Default), Min(INT64_MIN), Max(INT64_MAX) {} + : ImplTy(Default) {} MDSignedField(int64_t Default, int64_t Min, int64_t Max) : ImplTy(Default), Min(Min), Max(Max) {} }; @@ -4144,8 +4256,8 @@ bool LLParser::parseMDField(LocTy Loc, StringRef Name, DIFlagField &Result) { Val = DINode::getFlag(Lex.getStrVal()); if (!Val) - return tokError(Twine("invalid debug info flag flag '") + - Lex.getStrVal() + "'"); + return tokError(Twine("invalid debug info flag '") + Lex.getStrVal() + + "'"); Lex.Lex(); return false; }; @@ -4779,7 +4891,8 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { OPTIONAL(declaration, MDField, ); \ OPTIONAL(retainedNodes, MDField, ); \ OPTIONAL(thrownTypes, MDField, ); \ - OPTIONAL(annotations, MDField, ); + OPTIONAL(annotations, MDField, ); \ + OPTIONAL(targetFuncName, MDStringField, ); PARSE_MD_FIELDS(); #undef VISIT_MD_FIELDS @@ -4798,7 +4911,8 @@ bool LLParser::parseDISubprogram(MDNode *&Result, bool IsDistinct) { (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, type.Val, scopeLine.Val, containingType.Val, virtualIndex.Val, thisAdjustment.Val, flags.Val, SPFlags, unit.Val, templateParams.Val, - declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val)); + declaration.Val, retainedNodes.Val, thrownTypes.Val, annotations.Val, + targetFuncName.Val)); return false; } @@ -4965,7 +5079,7 @@ bool LLParser::parseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) { /// declaration: !4, align: 8) bool LLParser::parseDIGlobalVariable(MDNode *&Result, bool IsDistinct) { #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \ - REQUIRED(name, MDStringField, (/* AllowEmpty */ false)); \ + OPTIONAL(name, MDStringField, (/* AllowEmpty */ false)); \ OPTIONAL(scope, MDField, ); \ OPTIONAL(linkageName, MDStringField, ); \ OPTIONAL(file, MDField, ); \ @@ -5603,20 +5717,19 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) { auto FRVI = ForwardRefVals.find(FunctionName); if (FRVI != ForwardRefVals.end()) { FwdFn = FRVI->second.first; - if (!FwdFn->getType()->isOpaque()) { - if (!FwdFn->getType()->getNonOpaquePointerElementType()->isFunctionTy()) - return error(FRVI->second.second, "invalid forward reference to " - "function as global value!"); - if (FwdFn->getType() != PFT) - return error(FRVI->second.second, - "invalid forward reference to " - "function '" + - FunctionName + - "' with wrong type: " - "expected '" + - getTypeString(PFT) + "' but was '" + - getTypeString(FwdFn->getType()) + "'"); - } + if (!FwdFn->getType()->isOpaque() && + !FwdFn->getType()->getNonOpaquePointerElementType()->isFunctionTy()) + return error(FRVI->second.second, "invalid forward reference to " + "function as global value!"); + if (FwdFn->getType() != PFT) + return error(FRVI->second.second, + "invalid forward reference to " + "function '" + + FunctionName + + "' with wrong type: " + "expected '" + + getTypeString(PFT) + "' but was '" + + getTypeString(FwdFn->getType()) + "'"); ForwardRefVals.erase(FRVI); } else if ((Fn = M->getFunction(FunctionName))) { // Reject redefinitions. @@ -5631,8 +5744,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) { // types agree. auto I = ForwardRefValIDs.find(NumberedVals.size()); if (I != ForwardRefValIDs.end()) { - FwdFn = cast<Function>(I->second.first); - if (!FwdFn->getType()->isOpaque() && FwdFn->getType() != PFT) + FwdFn = I->second.first; + if (FwdFn->getType() != PFT) return error(NameLoc, "type of definition and forward reference of '@" + Twine(NumberedVals.size()) + "' disagree: " @@ -7322,9 +7435,9 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) { PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize( Cmp->getType())); - AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst( - Ptr, Cmp, New, Alignment.getValueOr(DefaultAlignment), SuccessOrdering, - FailureOrdering, SSID); + AtomicCmpXchgInst *CXI = + new AtomicCmpXchgInst(Ptr, Cmp, New, Alignment.value_or(DefaultAlignment), + SuccessOrdering, FailureOrdering, SSID); CXI->setVolatile(isVolatile); CXI->setWeak(isWeak); @@ -7390,10 +7503,12 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { if (Operation == AtomicRMWInst::Xchg) { if (!Val->getType()->isIntegerTy() && - !Val->getType()->isFloatingPointTy()) { - return error(ValLoc, - "atomicrmw " + AtomicRMWInst::getOperationName(Operation) + - " operand must be an integer or floating point type"); + !Val->getType()->isFloatingPointTy() && + !Val->getType()->isPointerTy()) { + return error( + ValLoc, + "atomicrmw " + AtomicRMWInst::getOperationName(Operation) + + " operand must be an integer, floating point, or pointer type"); } } else if (IsFP) { if (!Val->getType()->isFloatingPointTy()) { @@ -7409,7 +7524,9 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { } } - unsigned Size = Val->getType()->getPrimitiveSizeInBits(); + unsigned Size = + PFS.getFunction().getParent()->getDataLayout().getTypeStoreSizeInBits( + Val->getType()); if (Size < 8 || (Size & (Size - 1))) return error(ValLoc, "atomicrmw operand must be power-of-two byte-sized" " integer"); @@ -7418,7 +7535,7 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) { Val->getType())); AtomicRMWInst *RMWI = new AtomicRMWInst(Operation, Ptr, Val, - Alignment.getValueOr(DefaultAlignment), Ordering, SSID); + Alignment.value_or(DefaultAlignment), Ordering, SSID); RMWI->setVolatile(isVolatile); Inst = RMWI; return AteExtraComma ? InstExtraComma : InstNormal; |