aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/AsmParser/LLParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp225
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;