Comments (12)
Is LLVM 13 and LLVM 14 supported now? If not, how can I help?
@suhabe, now LLVM 13.0 is supported; as of llir/llvm version 0.3.5.
Edit: LLVM 14.0 is supported as of llir/llvm version 0.3.6 (see #221).
from llvm.
Diff
diff --git a/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLLexer.cpp b/llvm-project-llvmorg-13.0.0/llvm/lib/AsmParser/LLLexer.cpp
index 427de74..4f72c6f 100644
--- a/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm-project-llvmorg-13.0.0/llvm/lib/AsmParser/LLLexer.cpp
@@ -10,7 +10,7 @@
//
//===----------------------------------------------------------------------===//
-#include "LLLexer.h"
+#include "llvm/AsmParser/LLLexer.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
@@ -543,7 +543,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(triple);
KEYWORD(source_filename);
KEYWORD(unwind);
- KEYWORD(deplibs); // FIXME: Remove in 4.0.
KEYWORD(datalayout);
KEYWORD(volatile);
KEYWORD(atomic);
@@ -609,6 +608,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(x86_regcallcc);
KEYWORD(webkit_jscc);
KEYWORD(swiftcc);
+ KEYWORD(swifttailcc);
KEYWORD(anyregcc);
KEYWORD(preserve_mostcc);
KEYWORD(preserve_allcc);
@@ -643,6 +643,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(convergent);
KEYWORD(dereferenceable);
KEYWORD(dereferenceable_or_null);
+ KEYWORD(elementtype);
KEYWORD(inaccessiblememonly);
KEYWORD(inaccessiblemem_or_argmemonly);
KEYWORD(inlinehint);
@@ -670,6 +671,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(nocf_check);
KEYWORD(noundef);
KEYWORD(nounwind);
+ KEYWORD(nosanitize_coverage);
KEYWORD(null_pointer_is_valid);
KEYWORD(optforfuzzing);
KEYWORD(optnone);
@@ -696,7 +698,9 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(speculative_load_hardening);
KEYWORD(swifterror);
KEYWORD(swiftself);
+ KEYWORD(swiftasync);
KEYWORD(uwtable);
+ KEYWORD(vscale_range);
KEYWORD(willreturn);
KEYWORD(writeonly);
KEYWORD(zeroext);
@@ -713,7 +717,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(any);
KEYWORD(exactmatch);
KEYWORD(largest);
- KEYWORD(noduplicates);
+ KEYWORD(nodeduplicate);
KEYWORD(samesize);
KEYWORD(eq); KEYWORD(ne); KEYWORD(slt); KEYWORD(sgt); KEYWORD(sle);
@@ -751,6 +755,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(flags);
KEYWORD(blockcount);
KEYWORD(linkage);
+ KEYWORD(visibility);
KEYWORD(notEligibleToImport);
KEYWORD(live);
KEYWORD(dsoLocal);
@@ -843,6 +848,7 @@ lltok::Kind LLLexer::LexIdentifier() {
TYPEKEYWORD("x86_mmx", Type::getX86_MMXTy(Context));
TYPEKEYWORD("x86_amx", Type::getX86_AMXTy(Context));
TYPEKEYWORD("token", Type::getTokenTy(Context));
+ TYPEKEYWORD("ptr", PointerType::getUnqual(Context));
#undef TYPEKEYWORD
diff --git a/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLLexer.h b/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLLexer.h
deleted file mode 100644
index c97d978..0000000
--- a/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLLexer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===- LLLexer.h - Lexer for LLVM Assembly Files ----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This class represents the Lexer for .ll files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_ASMPARSER_LLLEXER_H
-#define LLVM_LIB_ASMPARSER_LLLEXER_H
-
-#include "LLToken.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/Support/SMLoc.h"
-#include <string>
-
-namespace llvm {
- class Type;
- class SMDiagnostic;
- class SourceMgr;
- class LLVMContext;
-
- class LLLexer {
- const char *CurPtr;
- StringRef CurBuf;
- SMDiagnostic &ErrorInfo;
- SourceMgr &SM;
- LLVMContext &Context;
-
- // Information about the current token.
- const char *TokStart;
- lltok::Kind CurKind;
- std::string StrVal;
- unsigned UIntVal;
- Type *TyVal;
- APFloat APFloatVal;
- APSInt APSIntVal;
-
- // When false (default), an identifier ending in ':' is a label token.
- // When true, the ':' is treated as a separate token.
- bool IgnoreColonInIdentifiers;
-
- public:
- explicit LLLexer(StringRef StartBuf, SourceMgr &SM, SMDiagnostic &,
- LLVMContext &C);
-
- lltok::Kind Lex() {
- return CurKind = LexToken();
- }
-
- typedef SMLoc LocTy;
- LocTy getLoc() const { return SMLoc::getFromPointer(TokStart); }
- lltok::Kind getKind() const { return CurKind; }
- const std::string &getStrVal() const { return StrVal; }
- Type *getTyVal() const { return TyVal; }
- unsigned getUIntVal() const { return UIntVal; }
- const APSInt &getAPSIntVal() const { return APSIntVal; }
- const APFloat &getAPFloatVal() const { return APFloatVal; }
-
- void setIgnoreColonInIdentifiers(bool val) {
- IgnoreColonInIdentifiers = val;
- }
-
- bool Error(LocTy ErrorLoc, const Twine &Msg) const;
- bool Error(const Twine &Msg) const { return Error(getLoc(), Msg); }
-
- void Warning(LocTy WarningLoc, const Twine &Msg) const;
- void Warning(const Twine &Msg) const { return Warning(getLoc(), Msg); }
-
- private:
- lltok::Kind LexToken();
-
- int getNextChar();
- void SkipLineComment();
- lltok::Kind ReadString(lltok::Kind kind);
- bool ReadVarName();
-
- lltok::Kind LexIdentifier();
- lltok::Kind LexDigitOrNegative();
- lltok::Kind LexPositive();
- lltok::Kind LexAt();
- lltok::Kind LexDollar();
- lltok::Kind LexExclaim();
- lltok::Kind LexPercent();
- lltok::Kind LexUIntID(lltok::Kind Token);
- lltok::Kind LexVar(lltok::Kind Var, lltok::Kind VarID);
- lltok::Kind LexQuote();
- lltok::Kind Lex0x();
- lltok::Kind LexHash();
- lltok::Kind LexCaret();
-
- uint64_t atoull(const char *Buffer, const char *End);
- uint64_t HexIntToVal(const char *Buffer, const char *End);
- void HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]);
- void FP80HexToIntPair(const char *Buffer, const char *End, uint64_t Pair[2]);
- };
-} // end namespace llvm
-
-#endif
diff --git a/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLParser.cpp b/llvm-project-llvmorg-13.0.0/llvm/lib/AsmParser/LLParser.cpp
index 2a3fb8f..799cb03 100644
--- a/llvm-project-llvmorg-12.0.1/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm-project-llvmorg-13.0.0/llvm/lib/AsmParser/LLParser.cpp
@@ -10,13 +10,13 @@
//
//===----------------------------------------------------------------------===//
-#include "LLParser.h"
-#include "LLToken.h"
+#include "llvm/AsmParser/LLParser.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/AsmParser/LLToken.h"
#include "llvm/AsmParser/SlotMapping.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/Argument.h"
@@ -32,6 +32,7 @@
#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/InlineAsm.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
@@ -356,10 +357,6 @@ bool LLParser::parseTopLevelEntities() {
if (parseModuleAsm())
return true;
break;
- case lltok::kw_deplibs:
- if (parseDepLibs())
- return true;
- break;
case lltok::LocalVarID:
if (parseUnnamedType())
return true;
@@ -459,29 +456,6 @@ bool LLParser::parseSourceFileName() {
return false;
}
-/// 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();
- if (parseToken(lltok::equal, "expected '=' after deplibs") ||
- parseToken(lltok::lsquare, "expected '=' after deplibs"))
- return true;
-
- if (EatIfPresent(lltok::rsquare))
- return false;
-
- do {
- std::string Str;
- if (parseStringConstant(Str))
- return true;
- } while (EatIfPresent(lltok::comma));
-
- return parseToken(lltok::rsquare, "expected ']' at end of list");
-}
-
/// parseUnnamedType:
/// ::= LocalVarID '=' 'type' type
bool LLParser::parseUnnamedType() {
@@ -694,8 +668,8 @@ bool LLParser::parseComdat() {
case lltok::kw_largest:
SK = Comdat::Largest;
break;
- case lltok::kw_noduplicates:
- SK = Comdat::NoDuplicates;
+ case lltok::kw_nodeduplicate:
+ SK = Comdat::NoDeduplicate;
break;
case lltok::kw_samesize:
SK = Comdat::SameSize;
@@ -776,6 +750,11 @@ bool LLParser::parseNamedMetadata() {
Lex.getStrVal() == "DIExpression") {
if (parseDIExpression(N, /*IsDistinct=*/false))
return true;
+ // DIArgLists should only appear inline in a function, as they may
+ // contain LocalAsMetadata arguments which require a function context.
+ } else if (Lex.getKind() == lltok::MetadataVar &&
+ Lex.getStrVal() == "DIArgList") {
+ return tokError("found DIArgList outside of function");
} else if (parseToken(lltok::exclaim, "Expected '!' here") ||
parseMDNodeID(N)) {
return true;
@@ -926,6 +905,14 @@ static void maybeSetDSOLocal(bool DSOLocal, GlobalValue &GV) {
GV.setDSOLocal(true);
}
+static std::string typeComparisonErrorMessage(StringRef Message, Type *Ty1,
+ Type *Ty2) {
+ std::string ErrString;
+ raw_string_ostream ErrOS(ErrString);
+ ErrOS << Message << " (" << *Ty1 << " vs " << *Ty2 << ")";
+ return ErrOS.str();
+}
+
/// parseIndirectSymbol:
/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
/// OptionalVisibility OptionalDLLStorageClass
@@ -980,7 +967,7 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
} else {
// The bitcast dest type is not present, it is implied by the dest type.
ValID ID;
- if (parseValID(ID))
+ if (parseValID(ID, /*PFS=*/nullptr))
return true;
if (ID.Kind != ValID::t_Constant)
return error(AliaseeLoc, "invalid aliasee");
@@ -993,23 +980,30 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
return error(AliaseeLoc, "An alias or ifunc must have pointer type");
unsigned AddrSpace = PTy->getAddressSpace();
- if (IsAlias && Ty != PTy->getElementType())
- return error(ExplicitTypeLoc,
- "explicit pointee type doesn't match operand's pointee type");
+ if (IsAlias && !PTy->isOpaqueOrPointeeTypeMatches(Ty)) {
+ return error(
+ ExplicitTypeLoc,
+ typeComparisonErrorMessage(
+ "explicit pointee type doesn't match operand's pointee type", Ty,
+ PTy->getElementType()));
+ }
- if (!IsAlias && !PTy->getElementType()->isFunctionTy())
+ if (!IsAlias && !PTy->getElementType()->isFunctionTy()) {
return error(ExplicitTypeLoc,
"explicit pointee type should be a function type");
+ }
GlobalValue *GVal = nullptr;
// See if the alias was forward referenced, if so, prepare to replace the
// forward reference.
if (!Name.empty()) {
- GVal = M->getNamedValue(Name);
- if (GVal) {
- if (!ForwardRefVals.erase(Name))
- return error(NameLoc, "redefinition of global '@" + Name + "'");
+ auto I = ForwardRefVals.find(Name);
+ if (I != ForwardRefVals.end()) {
+ GVal = I->second.first;
+ ForwardRefVals.erase(Name);
+ } else if (M->getNamedValue(Name)) {
+ return error(NameLoc, "redefinition of global '@" + Name + "'");
}
} else {
auto I = ForwardRefValIDs.find(NumberedVals.size());
@@ -1131,10 +1125,12 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
// See if the global was forward referenced, if so, use the global.
if (!Name.empty()) {
- GVal = M->getNamedValue(Name);
- if (GVal) {
- if (!ForwardRefVals.erase(Name))
- return error(NameLoc, "redefinition of global '@" + Name + "'");
+ auto I = ForwardRefVals.find(Name);
+ if (I != ForwardRefVals.end()) {
+ GVal = I->second.first;
+ ForwardRefVals.erase(I);
+ } else if (M->getNamedValue(Name)) {
+ return error(NameLoc, "redefinition of global '@" + Name + "'");
}
} else {
auto I = ForwardRefValIDs.find(NumberedVals.size());
@@ -1144,22 +1140,9 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
}
}
- GlobalVariable *GV;
- if (!GVal) {
- GV = new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage, nullptr,
- Name, nullptr, GlobalVariable::NotThreadLocal,
- AddrSpace);
- } else {
- if (GVal->getValueType() != Ty)
- return error(
- TyLoc,
- "forward reference and definition of global have different types");
-
- GV = cast<GlobalVariable>(GVal);
-
- // Move the forward-reference to the correct spot in the module.
- M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV);
- }
+ GlobalVariable *GV = new GlobalVariable(
+ *M, Ty, false, GlobalValue::ExternalLinkage, nullptr, Name, nullptr,
+ GlobalVariable::NotThreadLocal, AddrSpace);
if (Name.empty())
NumberedVals.push_back(GV);
@@ -1176,6 +1159,16 @@ bool LLParser::parseGlobal(const std::string &Name, LocTy NameLoc,
GV->setThreadLocalMode(TLM);
GV->setUnnamedAddr(UnnamedAddr);
+ if (GVal) {
+ if (!GVal->getType()->isOpaque() && GVal->getValueType() != Ty)
+ return error(
+ TyLoc,
+ "forward reference and definition of global have different types");
+
+ GVal->replaceAllUsesWith(GV);
+ GVal->eraseFromParent();
+ }
+
// parse attributes on the global.
while (Lex.getKind() == lltok::comma) {
Lex.Lex();
@@ -1250,201 +1243,144 @@ bool LLParser::parseUnnamedAttrGrp() {
return false;
}
+static Attribute::AttrKind tokenToAttribute(lltok::Kind Kind) {
+ switch (Kind) {
+#define GET_ATTR_NAMES
+#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
+ case lltok::kw_##DISPLAY_NAME: \
+ return Attribute::ENUM_NAME;
+#include "llvm/IR/Attributes.inc"
+ default:
+ return Attribute::None;
+ }
+}
+
+bool LLParser::parseEnumAttribute(Attribute::AttrKind Attr, AttrBuilder &B,
+ bool InAttrGroup) {
+ if (Attribute::isTypeAttrKind(Attr))
+ return parseRequiredTypeAttr(B, Lex.getKind(), Attr);
+
+ switch (Attr) {
+ case Attribute::Alignment: {
+ MaybeAlign Alignment;
+ if (InAttrGroup) {
+ uint32_t Value = 0;
+ Lex.Lex();
+ if (parseToken(lltok::equal, "expected '=' here") || parseUInt32(Value))
+ return true;
+ Alignment = Align(Value);
+ } else {
+ if (parseOptionalAlignment(Alignment, true))
+ return true;
+ }
+ B.addAlignmentAttr(Alignment);
+ return false;
+ }
+ case Attribute::StackAlignment: {
+ unsigned Alignment;
+ if (InAttrGroup) {
+ Lex.Lex();
+ if (parseToken(lltok::equal, "expected '=' here") ||
+ parseUInt32(Alignment))
+ return true;
+ } else {
+ if (parseOptionalStackAlignment(Alignment))
+ return true;
+ }
+ B.addStackAlignmentAttr(Alignment);
+ return false;
+ }
+ case Attribute::AllocSize: {
+ unsigned ElemSizeArg;
+ Optional<unsigned> NumElemsArg;
+ if (parseAllocSizeArguments(ElemSizeArg, NumElemsArg))
+ return true;
+ B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
+ return false;
+ }
+ case Attribute::VScaleRange: {
+ unsigned MinValue, MaxValue;
+ if (parseVScaleRangeArguments(MinValue, MaxValue))
+ return true;
+ B.addVScaleRangeAttr(MinValue, MaxValue);
+ return false;
+ }
+ case Attribute::Dereferenceable: {
+ uint64_t Bytes;
+ if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
+ return true;
+ B.addDereferenceableAttr(Bytes);
+ return false;
+ }
+ case Attribute::DereferenceableOrNull: {
+ uint64_t Bytes;
+ if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
+ return true;
+ B.addDereferenceableOrNullAttr(Bytes);
+ return false;
+ }
+ default:
+ B.addAttribute(Attr);
+ Lex.Lex();
+ return false;
+ }
+}
+
/// parseFnAttributeValuePairs
/// ::= <attr> | <attr> '=' <value>
bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
std::vector<unsigned> &FwdRefAttrGrps,
- bool inAttrGrp, LocTy &BuiltinLoc) {
+ bool InAttrGrp, LocTy &BuiltinLoc) {
bool HaveError = false;
B.clear();
while (true) {
lltok::Kind Token = Lex.getKind();
- if (Token == lltok::kw_builtin)
- BuiltinLoc = Lex.getLoc();
- switch (Token) {
- default:
- if (!inAttrGrp) return HaveError;
- return error(Lex.getLoc(), "unterminated attribute group");
- case lltok::rbrace:
- // Finished.
- return false;
+ if (Token == lltok::rbrace)
+ return HaveError; // Finished.
+
+ if (Token == lltok::StringConstant) {
+ if (parseStringAttribute(B))
+ return true;
+ continue;
+ }
- case lltok::AttrGrpID: {
+ if (Token == lltok::AttrGrpID) {
// Allow a function to reference an attribute group:
//
// define void @foo() #1 { ... }
- if (inAttrGrp)
+ 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: {
- if (parseStringAttribute(B))
- return true;
- continue;
- }
-
- // Target-independent attributes:
- case lltok::kw_align: {
- // As a hack, we allow function alignment to be initially parsed as an
- // attribute on a function declaration/definition or added to an attribute
- // group and later moved to the alignment field.
- MaybeAlign Alignment;
- if (inAttrGrp) {
- Lex.Lex();
- uint32_t Value = 0;
- if (parseToken(lltok::equal, "expected '=' here") || parseUInt32(Value))
- return true;
- Alignment = Align(Value);
} else {
- if (parseOptionalAlignment(Alignment))
- return true;
+ // Save the reference to the attribute group. We'll fill it in later.
+ FwdRefAttrGrps.push_back(Lex.getUIntVal());
}
- 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_allocsize: {
- unsigned ElemSizeArg;
- Optional<unsigned> NumElemsArg;
- // inAttrGrp doesn't matter; we only support allocsize(a[, b])
- if (parseAllocSizeArguments(ElemSizeArg, NumElemsArg))
- return true;
- B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
+ Lex.Lex();
continue;
}
- case lltok::kw_alwaysinline: B.addAttribute(Attribute::AlwaysInline); break;
- case lltok::kw_argmemonly: B.addAttribute(Attribute::ArgMemOnly); break;
- case lltok::kw_builtin: B.addAttribute(Attribute::Builtin); break;
- case lltok::kw_cold: B.addAttribute(Attribute::Cold); break;
- case lltok::kw_hot: B.addAttribute(Attribute::Hot); break;
- case lltok::kw_convergent: B.addAttribute(Attribute::Convergent); break;
- case lltok::kw_inaccessiblememonly:
- B.addAttribute(Attribute::InaccessibleMemOnly); break;
- case lltok::kw_inaccessiblemem_or_argmemonly:
- B.addAttribute(Attribute::InaccessibleMemOrArgMemOnly); break;
- case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
- case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
- case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
- case lltok::kw_mustprogress:
- B.addAttribute(Attribute::MustProgress);
- break;
- case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
- case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
- case lltok::kw_nocallback:
- B.addAttribute(Attribute::NoCallback);
- break;
- case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
- case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); 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_nomerge: B.addAttribute(Attribute::NoMerge); break;
- case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
- case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
- case lltok::kw_nosync: B.addAttribute(Attribute::NoSync); break;
- case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break;
- case lltok::kw_noprofile: B.addAttribute(Attribute::NoProfile); break;
- case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
- case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
- case lltok::kw_null_pointer_is_valid:
- B.addAttribute(Attribute::NullPointerIsValid); break;
- case lltok::kw_optforfuzzing:
- B.addAttribute(Attribute::OptForFuzzing); break;
- case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); 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_speculatable: B.addAttribute(Attribute::Speculatable); 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_safestack: B.addAttribute(Attribute::SafeStack); break;
- case lltok::kw_shadowcallstack:
- B.addAttribute(Attribute::ShadowCallStack); break;
- case lltok::kw_sanitize_address:
- B.addAttribute(Attribute::SanitizeAddress); break;
- case lltok::kw_sanitize_hwaddress:
- B.addAttribute(Attribute::SanitizeHWAddress); break;
- case lltok::kw_sanitize_memtag:
- B.addAttribute(Attribute::SanitizeMemTag); break;
- case lltok::kw_sanitize_thread:
- B.addAttribute(Attribute::SanitizeThread); break;
- case lltok::kw_sanitize_memory:
- B.addAttribute(Attribute::SanitizeMemory); break;
- case lltok::kw_speculative_load_hardening:
- B.addAttribute(Attribute::SpeculativeLoadHardening);
- break;
- case lltok::kw_strictfp: B.addAttribute(Attribute::StrictFP); break;
- case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
- case lltok::kw_willreturn: B.addAttribute(Attribute::WillReturn); break;
- case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
- case lltok::kw_preallocated: {
- Type *Ty;
- if (parsePreallocated(Ty))
- return true;
- B.addPreallocatedAttr(Ty);
- 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_dereferenceable:
- case lltok::kw_dereferenceable_or_null:
- case lltok::kw_inalloca:
- case lltok::kw_nest:
- case lltok::kw_noalias:
- case lltok::kw_noundef:
- case lltok::kw_nocapture:
- case lltok::kw_nonnull:
- case lltok::kw_returned:
- case lltok::kw_sret:
- case lltok::kw_swifterror:
- case lltok::kw_swiftself:
- case lltok::kw_immarg:
- case lltok::kw_byref:
- HaveError |=
- error(Lex.getLoc(),
- "invalid use of parameter-only attribute on a function");
- break;
+ SMLoc Loc = Lex.getLoc();
+ if (Token == lltok::kw_builtin)
+ BuiltinLoc = Loc;
+
+ Attribute::AttrKind Attr = tokenToAttribute(Token);
+ if (Attr == Attribute::None) {
+ if (!InAttrGrp)
+ return HaveError;
+ return error(Lex.getLoc(), "unterminated attribute group");
}
- // parsePreallocated() consumes token
- if (Token != lltok::kw_preallocated)
- Lex.Lex();
+ if (parseEnumAttribute(Attr, B, InAttrGrp))
+ return true;
+
+ // As a hack, we allow function alignment to be initially parsed as an
+ // attribute on a function declaration/definition or added to an attribute
+ // group and later moved to the alignment field.
+ if (!Attribute::canUseAsFnAttr(Attr) && Attr != Attribute::Alignment)
+ HaveError |= error(Loc, "this attribute does not apply to functions");
}
}
@@ -1452,37 +1388,40 @@ bool LLParser::parseFnAttributeValuePairs(AttrBuilder &B,
// GlobalValue Reference/Resolution Routines.
//===----------------------------------------------------------------------===//
-static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy,
- const std::string &Name) {
- if (auto *FT = dyn_cast<FunctionType>(PTy->getElementType()))
+static inline GlobalValue *createGlobalFwdRef(Module *M, PointerType *PTy) {
+ // For opaque pointers, the used global type does not matter. We will later
+ // RAUW it with a global/function of the correct type.
+ if (PTy->isOpaque())
+ return new GlobalVariable(*M, Type::getInt8Ty(M->getContext()), false,
+ GlobalValue::ExternalWeakLinkage, nullptr, "",
+ nullptr, GlobalVariable::NotThreadLocal,
+ PTy->getAddressSpace());
+
+ if (auto *FT = dyn_cast<FunctionType>(PTy->getPointerElementType()))
return Function::Create(FT, GlobalValue::ExternalWeakLinkage,
- PTy->getAddressSpace(), Name, M);
+ PTy->getAddressSpace(), "", M);
else
- return new GlobalVariable(*M, PTy->getElementType(), false,
- GlobalValue::ExternalWeakLinkage, nullptr, Name,
+ return new GlobalVariable(*M, PTy->getPointerElementType(), false,
+ GlobalValue::ExternalWeakLinkage, nullptr, "",
nullptr, GlobalVariable::NotThreadLocal,
PTy->getAddressSpace());
}
Value *LLParser::checkValidVariableType(LocTy Loc, const Twine &Name, Type *Ty,
Value *Val, bool IsCall) {
- if (Val->getType() == Ty)
+ Type *ValTy = Val->getType();
+ if (ValTy == Ty)
+ return Val;
+ // For calls, we also allow opaque pointers.
+ if (IsCall && ValTy == PointerType::get(Ty->getContext(),
+ Ty->getPointerAddressSpace()))
return Val;
- // For calls we also accept variables in the program address space.
- Type *SuggestedTy = Ty;
- if (IsCall && isa<PointerType>(Ty)) {
- Type *TyInProgAS = cast<PointerType>(Ty)->getElementType()->getPointerTo(
- M->getDataLayout().getProgramAddressSpace());
- SuggestedTy = TyInProgAS;
- if (Val->getType() == TyInProgAS)
- return Val;
- }
if (Ty->isLabelTy())
error(Loc, "'" + Name + "' is not a basic block");
else
error(Loc, "'" + Name + "' defined with type '" +
getTypeString(Val->getType()) + "' but expected '" +
- getTypeString(SuggestedTy) + "'");
+ getTypeString(Ty) + "'");
return nullptr;
}
@@ -1678,254 +1617,32 @@ bool LLParser::parseStringAttribute(AttrBuilder &B) {
return false;
}
-/// parseOptionalParamAttrs - parse a potentially empty list of parameter
-/// attributes.
-bool LLParser::parseOptionalParamAttrs(AttrBuilder &B) {
+/// Parse a potentially empty list of parameter or return attributes.
+bool LLParser::parseOptionalParamOrReturnAttrs(AttrBuilder &B, bool IsParam) {
bool HaveError = false;
B.clear();
while (true) {
lltok::Kind Token = Lex.getKind();
- switch (Token) {
- default: // End of attributes.
- return HaveError;
- case lltok::StringConstant: {
+ if (Token == lltok::StringConstant) {
if (parseStringAttribute(B))
return true;
continue;
}
- case lltok::kw_align: {
- MaybeAlign Alignment;
- if (parseOptionalAlignment(Alignment, true))
- return true;
- B.addAlignmentAttr(Alignment);
- continue;
- }
- case lltok::kw_byval: {
- Type *Ty;
- if (parseRequiredTypeAttr(Ty, lltok::kw_byval))
- return true;
- B.addByValAttr(Ty);
- continue;
- }
- case lltok::kw_sret: {
- Type *Ty;
- if (parseRequiredTypeAttr(Ty, lltok::kw_sret))
- return true;
- B.addStructRetAttr(Ty);
- continue;
- }
- case lltok::kw_preallocated: {
- Type *Ty;
- if (parsePreallocated(Ty))
- return true;
- B.addPreallocatedAttr(Ty);
- continue;
- }
- case lltok::kw_dereferenceable: {
- uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
- return true;
- B.addDereferenceableAttr(Bytes);
- continue;
- }
- case lltok::kw_dereferenceable_or_null: {
- uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
- return true;
- B.addDereferenceableOrNullAttr(Bytes);
- continue;
- }
- case lltok::kw_byref: {
- Type *Ty;
- if (parseByRef(Ty))
- return true;
- B.addByRefAttr(Ty);
- continue;
- }
- case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break;
- case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
- case lltok::kw_nest: B.addAttribute(Attribute::Nest); break;
- case lltok::kw_noundef:
- B.addAttribute(Attribute::NoUndef);
- break;
- case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
- case lltok::kw_nocapture: B.addAttribute(Attribute::NoCapture); break;
- case lltok::kw_nofree: B.addAttribute(Attribute::NoFree); break;
- case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
- case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break;
- case lltok::kw_readonly: B.addAttribute(Attribute::ReadOnly); break;
- case lltok::kw_returned: B.addAttribute(Attribute::Returned); break;
- case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
- case lltok::kw_swifterror: B.addAttribute(Attribute::SwiftError); break;
- case lltok::kw_swiftself: B.addAttribute(Attribute::SwiftSelf); break;
- case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
- case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
- case lltok::kw_immarg: B.addAttribute(Attribute::ImmArg); break;
-
- case lltok::kw_alignstack:
- case lltok::kw_alwaysinline:
- case lltok::kw_argmemonly:
- case lltok::kw_builtin:
- case lltok::kw_inlinehint:
- case lltok::kw_jumptable:
- case lltok::kw_minsize:
- case lltok::kw_mustprogress:
- case lltok::kw_naked:
- case lltok::kw_nobuiltin:
- case lltok::kw_noduplicate:
- case lltok::kw_noimplicitfloat:
- case lltok::kw_noinline:
- case lltok::kw_nonlazybind:
- case lltok::kw_nomerge:
- case lltok::kw_noprofile:
- case lltok::kw_noredzone:
- case lltok::kw_noreturn:
- case lltok::kw_nocf_check:
- case lltok::kw_nounwind:
- case lltok::kw_optforfuzzing:
- case lltok::kw_optnone:
- case lltok::kw_optsize:
- case lltok::kw_returns_twice:
- case lltok::kw_sanitize_address:
- case lltok::kw_sanitize_hwaddress:
- case lltok::kw_sanitize_memtag:
- case lltok::kw_sanitize_memory:
- case lltok::kw_sanitize_thread:
- case lltok::kw_speculative_load_hardening:
- case lltok::kw_ssp:
- case lltok::kw_sspreq:
- case lltok::kw_sspstrong:
- case lltok::kw_safestack:
- case lltok::kw_shadowcallstack:
- case lltok::kw_strictfp:
- case lltok::kw_uwtable:
- HaveError |=
- error(Lex.getLoc(), "invalid use of function-only attribute");
- break;
- }
- Lex.Lex();
- }
-}
-
-/// parseOptionalReturnAttrs - parse a potentially empty list of return
-/// attributes.
-bool LLParser::parseOptionalReturnAttrs(AttrBuilder &B) {
- bool HaveError = false;
-
- B.clear();
-
- while (true) {
- lltok::Kind Token = Lex.getKind();
- switch (Token) {
- default: // End of attributes.
+ SMLoc Loc = Lex.getLoc();
+ Attribute::AttrKind Attr = tokenToAttribute(Token);
+ if (Attr == Attribute::None)
return HaveError;
- case lltok::StringConstant: {
- if (parseStringAttribute(B))
- return true;
- continue;
- }
- case lltok::kw_dereferenceable: {
- uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable, Bytes))
- return true;
- B.addDereferenceableAttr(Bytes);
- continue;
- }
- case lltok::kw_dereferenceable_or_null: {
- uint64_t Bytes;
- if (parseOptionalDerefAttrBytes(lltok::kw_dereferenceable_or_null, Bytes))
- return true;
- B.addDereferenceableOrNullAttr(Bytes);
- continue;
- }
- case lltok::kw_align: {
- MaybeAlign Alignment;
- if (parseOptionalAlignment(Alignment))
- return true;
- B.addAlignmentAttr(Alignment);
- continue;
- }
- case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
- case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
- case lltok::kw_noundef:
- B.addAttribute(Attribute::NoUndef);
- break;
- case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
- case lltok::kw_signext: B.addAttribute(Attribute::SExt); break;
- case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break;
-
- // error handling.
- case lltok::kw_byval:
- case lltok::kw_inalloca:
- case lltok::kw_nest:
- case lltok::kw_nocapture:
- case lltok::kw_returned:
- case lltok::kw_sret:
- case lltok::kw_swifterror:
- case lltok::kw_swiftself:
- case lltok::kw_immarg:
- case lltok::kw_byref:
- HaveError |=
- error(Lex.getLoc(), "invalid use of parameter-only attribute");
- break;
- case lltok::kw_alignstack:
- case lltok::kw_alwaysinline:
- case lltok::kw_argmemonly:
- case lltok::kw_builtin:
- case lltok::kw_cold:
- case lltok::kw_inlinehint:
- case lltok::kw_jumptable:
- case lltok::kw_minsize:
- case lltok::kw_mustprogress:
- case lltok::kw_naked:
- case lltok::kw_nobuiltin:
- case lltok::kw_noduplicate:
- case lltok::kw_noimplicitfloat:
- case lltok::kw_noinline:
- case lltok::kw_nonlazybind:
- case lltok::kw_nomerge:
- case lltok::kw_noprofile:
- case lltok::kw_noredzone:
- case lltok::kw_noreturn:
- case lltok::kw_nocf_check:
- case lltok::kw_nounwind:
- case lltok::kw_optforfuzzing:
- case lltok::kw_optnone:
- case lltok::kw_optsize:
- case lltok::kw_returns_twice:
- case lltok::kw_sanitize_address:
- case lltok::kw_sanitize_hwaddress:
- case lltok::kw_sanitize_memtag:
- case lltok::kw_sanitize_memory:
- case lltok::kw_sanitize_thread:
- case lltok::kw_speculative_load_hardening:
- case lltok::kw_ssp:
- case lltok::kw_sspreq:
- case lltok::kw_sspstrong:
- case lltok::kw_safestack:
- case lltok::kw_shadowcallstack:
- case lltok::kw_strictfp:
- case lltok::kw_uwtable:
- HaveError |=
- error(Lex.getLoc(), "invalid use of function-only attribute");
- break;
- case lltok::kw_readnone:
- case lltok::kw_readonly:
- HaveError |=
- error(Lex.getLoc(), "invalid use of attribute on return type");
- break;
- case lltok::kw_preallocated:
- HaveError |=
- error(Lex.getLoc(),
- "invalid use of parameter-only/call site-only attribute");
- break;
- }
+ if (parseEnumAttribute(Attr, B, /* InAttrGroup */ false))
+ return true;
- Lex.Lex();
+ if (IsParam && !Attribute::canUseAsParamAttr(Attr))
+ HaveError |= error(Loc, "this attribute does not apply to parameters");
+ if (!IsParam && !Attribute::canUseAsRetAttr(Attr))
+ HaveError |= error(Loc, "this attribute does not apply to return values");
}
}
@@ -2081,6 +1798,7 @@ void LLParser::parseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'preserve_allcc'
/// ::= 'ghccc'
/// ::= 'swiftcc'
+/// ::= 'swifttailcc'
/// ::= 'x86_intrcc'
/// ::= 'hhvmcc'
/// ::= 'hhvm_ccc'
@@ -2131,6 +1849,7 @@ bool LLParser::parseOptionalCallingConv(unsigned &CC) {
case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
case lltok::kw_ghccc: CC = CallingConv::GHC; break;
case lltok::kw_swiftcc: CC = CallingConv::Swift; break;
+ case lltok::kw_swifttailcc: CC = CallingConv::SwiftTail; break;
case lltok::kw_x86_intrcc: CC = CallingConv::X86_INTR; break;
case lltok::kw_hhvmcc: CC = CallingConv::HHVM; break;
case lltok::kw_hhvm_ccc: CC = CallingConv::HHVM_C; break;
@@ -2350,6 +2069,29 @@ bool LLParser::parseAllocSizeArguments(unsigned &BaseSizeArg,
return false;
}
+bool LLParser::parseVScaleRangeArguments(unsigned &MinValue,
+ unsigned &MaxValue) {
+ Lex.Lex();
+
+ auto StartParen = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return error(StartParen, "expected '('");
+
+ if (parseUInt32(MinValue))
+ return true;
+
+ if (EatIfPresent(lltok::comma)) {
+ if (parseUInt32(MaxValue))
+ return true;
+ } else
+ MaxValue = MinValue;
+
+ auto EndParen = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return error(EndParen, "expected ')'");
+ return false;
+}
+
/// parseScopeAndOrdering
/// if isAtomic: ::= SyncScope? AtomicOrdering
/// else: ::=
@@ -2532,6 +2274,26 @@ bool LLParser::parseType(Type *&Result, const Twine &Msg, bool AllowVoid) {
}
}
+ // Handle (explicit) opaque pointer types (not --force-opaque-pointers).
+ //
+ // Type ::= ptr ('addrspace' '(' uint32 ')')?
+ if (Result->isOpaquePointerTy()) {
+ unsigned AddrSpace;
+ if (parseOptionalAddrSpace(AddrSpace))
+ return true;
+ Result = PointerType::get(getContext(), AddrSpace);
+
+ // Give a nice error for 'ptr*'.
+ if (Lex.getKind() == lltok::star)
+ return tokError("ptr* is invalid - use ptr instead");
+
+ // Fall through to parsing the type suffixes only if this 'ptr' is a
+ // function return. Otherwise, return success, implicitly rejecting other
+ // suffixes.
+ if (Lex.getKind() != lltok::lparen)
+ return false;
+ }
+
// parse the type suffixes.
while (true) {
switch (Lex.getKind()) {
@@ -2637,29 +2399,20 @@ bool LLParser::parseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
/// parseRequiredTypeAttr
/// ::= attrname(<ty>)
-bool LLParser::parseRequiredTypeAttr(Type *&Result, lltok::Kind AttrName) {
- Result = nullptr;
- if (!EatIfPresent(AttrName))
+bool LLParser::parseRequiredTypeAttr(AttrBuilder &B, lltok::Kind AttrToken,
+ Attribute::AttrKind AttrKind) {
+ Type *Ty = nullptr;
+ if (!EatIfPresent(AttrToken))
return true;
if (!EatIfPresent(lltok::lparen))
return error(Lex.getLoc(), "expected '('");
- if (parseType(Result))
+ if (parseType(Ty))
return true;
if (!EatIfPresent(lltok::rparen))
return error(Lex.getLoc(), "expected ')'");
- return false;
-}
-/// parsePreallocated
-/// ::= preallocated(<ty>)
-bool LLParser::parsePreallocated(Type *&Result) {
- return parseRequiredTypeAttr(Result, lltok::kw_preallocated);
-}
-
-/// parseByRef
-/// ::= byref(<type>)
-bool LLParser::parseByRef(Type *&Result) {
- return parseRequiredTypeAttr(Result, lltok::kw_byref);
+ B.addTypeAttr(AttrKind, Ty);
+ return false;
}
/// parseOptionalOperandBundles
@@ -3241,7 +2994,7 @@ BasicBlock *LLParser::PerFunctionState::defineBB(const std::string &Name,
/// sanity. PFS is used to convert function-local operands of metadata (since
/// metadata operands are not just parsed here but also converted to values).
/// PFS can be null when we are not parsing metadata values inside a function.
-bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
+bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS, Type *ExpectedTy) {
ID.Loc = Lex.getLoc();
switch (Lex.getKind()) {
default:
@@ -3389,18 +3142,19 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
case lltok::kw_asm: {
// ValID ::= 'asm' SideEffect? AlignStack? IntelDialect? STRINGCONSTANT ','
// STRINGCONSTANT
- bool HasSideEffect, AlignStack, AsmDialect;
+ bool HasSideEffect, AlignStack, AsmDialect, CanThrow;
Lex.Lex();
if (parseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
parseOptionalToken(lltok::kw_alignstack, AlignStack) ||
parseOptionalToken(lltok::kw_inteldialect, AsmDialect) ||
+ parseOptionalToken(lltok::kw_unwind, CanThrow) ||
parseStringConstant(ID.StrVal) ||
parseToken(lltok::comma, "expected comma in inline asm expression") ||
parseToken(lltok::StringConstant, "expected constraint string"))
return true;
ID.StrVal2 = Lex.getStrVal();
- ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack)<<1) |
- (unsigned(AsmDialect)<<2);
+ ID.UIntVal = unsigned(HasSideEffect) | (unsigned(AlignStack) << 1) |
+ (unsigned(AsmDialect) << 2) | (unsigned(CanThrow) << 3);
ID.Kind = ValID::t_InlineAsm;
return false;
}
@@ -3412,10 +3166,10 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
ValID Fn, Label;
if (parseToken(lltok::lparen, "expected '(' in block address expression") ||
- parseValID(Fn) ||
+ parseValID(Fn, PFS) ||
parseToken(lltok::comma,
"expected comma in block address expression") ||
- parseValID(Label) ||
+ parseValID(Label, PFS) ||
parseToken(lltok::rparen, "expected ')' in block address expression"))
return true;
@@ -3450,9 +3204,27 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
std::map<ValID, GlobalValue *>()))
.first->second.insert(std::make_pair(std::move(Label), nullptr))
.first->second;
- if (!FwdRef)
- FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false,
- GlobalValue::InternalLinkage, nullptr, "");
+ if (!FwdRef) {
+ unsigned FwdDeclAS;
+ if (ExpectedTy) {
+ // If we know the type that the blockaddress is being assigned to,
+ // we can use the address space of that type.
+ if (!ExpectedTy->isPointerTy())
+ return error(ID.Loc,
+ "type of blockaddress must be a pointer and not '" +
+ getTypeString(ExpectedTy) + "'");
+ FwdDeclAS = ExpectedTy->getPointerAddressSpace();
+ } else if (PFS) {
+ // Otherwise, we default the address space of the current function.
+ FwdDeclAS = PFS->getFunction().getAddressSpace();
+ } else {
+ llvm_unreachable("Unknown address space for blockaddress");
+ }
+ FwdRef = new GlobalVariable(
+ *M, Type::getInt8Ty(Context), false, GlobalValue::InternalLinkage,
+ nullptr, "", nullptr, GlobalValue::NotThreadLocal, FwdDeclAS);
+ }
+
ID.ConstantVal = FwdRef;
ID.Kind = ValID::t_Constant;
return false;
@@ -3489,7 +3261,7 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
ValID Fn;
- if (parseValID(Fn))
+ if (parseValID(Fn, PFS))
return true;
if (Fn.Kind != ValID::t_GlobalID && Fn.Kind != ValID::t_GlobalName)
@@ -3788,10 +3560,13 @@ bool LLParser::parseValID(ValID &ID, PerFunctionState *PFS) {
Type *BaseType = Elts[0]->getType();
auto *BasePointerType = cast<PointerType>(BaseType->getScalarType());
- if (Ty != BasePointerType->getElementType())
+ if (!BasePointerType->isOpaqueOrPointeeTypeMatches(Ty)) {
return error(
ExplicitTypeLoc,
- "explicit pointee type doesn't match operand's pointee type");
+ typeComparisonErrorMessage(
+ "explicit pointee type doesn't match operand's pointee type",
+ Ty, BasePointerType->getElementType()));
+ }
unsigned GEPWidth =
BaseType->isVectorTy()
@@ -3876,7 +3651,7 @@ bool LLParser::parseGlobalValue(Type *Ty, Constant *&C) {
C = nullptr;
ValID ID;
Value *V = nullptr;
- bool Parsed = parseValID(ID) ||
+ bool Parsed = parseValID(ID, /*PFS=*/nullptr, Ty) ||
convertValIDToValue(Ty, ID, V, nullptr, /*IsCall=*/false);
if (V && !(C = dyn_cast<Constant>(V)))
return error(ID.Loc, "global values must be constants");
@@ -4666,11 +4441,6 @@ bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) {
Metadata *LowerBound = nullptr;
Metadata *UpperBound = nullptr;
Metadata *Stride = nullptr;
- if (count.isMDSignedField())
- Count = ConstantAsMetadata::get(ConstantInt::getSigned(
- Type::getInt64Ty(Context), count.getMDSignedValue()));
- else if (count.isMDField())
- Count = count.getMDFieldValue();
auto convToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * {
if (Bound.isMDSignedField())
@@ -4681,6 +4451,7 @@ bool LLParser::parseDISubrange(MDNode *&Result, bool IsDistinct) {
return nullptr;
};
+ Count = convToMetadata(count);
LowerBound = convToMetadata(lowerBound);
UpperBound = convToMetadata(upperBound);
Stride = convToMetadata(stride);
@@ -5297,6 +5068,36 @@ bool LLParser::parseDIExpression(MDNode *&Result, bool IsDistinct) {
return false;
}
+bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct) {
+ return parseDIArgList(Result, IsDistinct, nullptr);
+}
+/// ParseDIArgList:
+/// ::= !DIArgList(i32 7, i64 %0)
+bool LLParser::parseDIArgList(MDNode *&Result, bool IsDistinct,
+ PerFunctionState *PFS) {
+ assert(PFS && "Expected valid function state");
+ assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+ Lex.Lex();
+
+ if (parseToken(lltok::lparen, "expected '(' here"))
+ return true;
+
+ SmallVector<ValueAsMetadata *, 4> Args;
+ if (Lex.getKind() != lltok::rparen)
+ do {
+ Metadata *MD;
+ if (parseValueAsMetadata(MD, "expected value-as-metadata operand", PFS))
+ return true;
+ Args.push_back(dyn_cast<ValueAsMetadata>(MD));
+ } while (EatIfPresent(lltok::comma));
+
+ if (parseToken(lltok::rparen, "expected ')' here"))
+ return true;
+
+ Result = GET_OR_DISTINCT(DIArgList, (Context, Args));
+ return false;
+}
+
/// parseDIGlobalVariableExpression:
/// ::= !DIGlobalVariableExpression(var: !0, expr: !1)
bool LLParser::parseDIGlobalVariableExpression(MDNode *&Result,
@@ -5407,8 +5208,14 @@ bool LLParser::parseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg,
bool LLParser::parseMetadata(Metadata *&MD, PerFunctionState *PFS) {
if (Lex.getKind() == lltok::MetadataVar) {
MDNode *N;
- if (parseSpecializedMDNode(N))
+ // DIArgLists are a special case, as they are a list of ValueAsMetadata and
+ // so parsing this requires a Function State.
+ if (Lex.getStrVal() == "DIArgList") {
+ if (parseDIArgList(N, false, PFS))
+ return true;
+ } else if (parseSpecializedMDNode(N)) {
return true;
+ }
MD = N;
return false;
}
@@ -5465,9 +5272,9 @@ bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
case ValID::t_InlineAsm: {
if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2))
return error(ID.Loc, "invalid type for inline asm constraint string");
- V = InlineAsm::get(ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1,
- (ID.UIntVal >> 1) & 1,
- (InlineAsm::AsmDialect(ID.UIntVal >> 2)));
+ V = InlineAsm::get(
+ ID.FTy, ID.StrVal, ID.StrVal2, ID.UIntVal & 1, (ID.UIntVal >> 1) & 1,
+ InlineAsm::AsmDialect((ID.UIntVal >> 2) & 1), (ID.UIntVal >> 3) & 1);
return false;
}
case ValID::t_GlobalName:
@@ -5553,7 +5360,9 @@ bool LLParser::convertValIDToValue(Type *Ty, ValID &ID, Value *&V,
return false;
case ValID::t_Constant:
if (ID.ConstantVal->getType() != Ty)
- return error(ID.Loc, "constant expression type mismatch");
+ return error(ID.Loc, "constant expression type mismatch: got type '" +
+ getTypeString(ID.ConstantVal->getType()) +
+ "' but expected '" + getTypeString(Ty) + "'");
V = ID.ConstantVal;
return false;
case ValID::t_ConstantStruct:
@@ -5613,7 +5422,7 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
V = nullptr;
ValID ID;
- return parseValID(ID, PFS) ||
+ return parseValID(ID, PFS, Ty) ||
convertValIDToValue(Ty, ID, V, PFS, /*IsCall=*/false);
}
@@ -5769,24 +5578,27 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
PointerType *PFT = PointerType::get(FT, AddrSpace);
Fn = nullptr;
+ GlobalValue *FwdFn = nullptr;
if (!FunctionName.empty()) {
// If this was a definition of a forward reference, remove the definition
// from the forward reference table and fill in the forward ref.
auto FRVI = ForwardRefVals.find(FunctionName);
if (FRVI != ForwardRefVals.end()) {
- Fn = M->getFunction(FunctionName);
- if (!Fn)
- return error(FRVI->second.second, "invalid forward reference to "
- "function as global value!");
- if (Fn->getType() != PFT)
- return error(FRVI->second.second,
- "invalid forward reference to "
- "function '" +
- FunctionName +
- "' with wrong type: "
- "expected '" +
- getTypeString(PFT) + "' but was '" +
- getTypeString(Fn->getType()) + "'");
+ FwdFn = FRVI->second.first;
+ if (!FwdFn->getType()->isOpaque()) {
+ if (!FwdFn->getType()->getPointerElementType()->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.
@@ -5801,23 +5613,20 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
// types agree.
auto I = ForwardRefValIDs.find(NumberedVals.size());
if (I != ForwardRefValIDs.end()) {
- Fn = cast<Function>(I->second.first);
- if (Fn->getType() != PFT)
+ FwdFn = cast<Function>(I->second.first);
+ if (!FwdFn->getType()->isOpaque() && FwdFn->getType() != PFT)
return error(NameLoc, "type of definition and forward reference of '@" +
Twine(NumberedVals.size()) +
"' disagree: "
"expected '" +
getTypeString(PFT) + "' but was '" +
- getTypeString(Fn->getType()) + "'");
+ getTypeString(FwdFn->getType()) + "'");
ForwardRefValIDs.erase(I);
}
}
- if (!Fn)
- Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace,
- FunctionName, M);
- else // Move the forward-reference to the correct spot in the module.
- M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn);
+ Fn = Function::Create(FT, GlobalValue::ExternalLinkage, AddrSpace,
+ FunctionName, M);
assert(Fn->getAddressSpace() == AddrSpace && "Created function in wrong AS");
@@ -5855,6 +5664,11 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine) {
"redefinition of argument '%" + ArgList[i].Name + "'");
}
+ if (FwdFn) {
+ FwdFn->replaceAllUsesWith(Fn);
+ FwdFn->eraseFromParent();
+ }
+
if (IsDefine)
return false;
@@ -5902,7 +5716,12 @@ bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() {
if (!BB)
return P.error(BBID.Loc, "referenced value is not a basic block");
- GV->replaceAllUsesWith(BlockAddress::get(&F, BB));
+ Value *ResolvedVal = BlockAddress::get(&F, BB);
+ ResolvedVal = P.checkValidVariableType(BBID.Loc, BBID.StrVal, GV->getType(),
+ ResolvedVal, false);
+ if (!ResolvedVal)
+ return true;
+ GV->replaceAllUsesWith(ResolvedVal);
GV->eraseFromParent();
}
@@ -6437,7 +6256,7 @@ bool LLParser::parseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
parseOptionalProgramAddrSpace(InvokeAddrSpace) ||
parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- parseValID(CalleeID) || parseParameterList(ArgList, PFS) ||
+ parseValID(CalleeID, &PFS) || parseParameterList(ArgList, PFS) ||
parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
NoBuiltinLoc) ||
parseOptionalOperandBundles(BundleList, PFS) ||
@@ -6745,7 +6564,7 @@ bool LLParser::parseCallBr(Instruction *&Inst, PerFunctionState &PFS) {
BasicBlock *DefaultDest;
if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- parseValID(CalleeID) || parseParameterList(ArgList, PFS) ||
+ parseValID(CalleeID, &PFS) || parseParameterList(ArgList, PFS) ||
parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
NoBuiltinLoc) ||
parseOptionalOperandBundles(BundleList, PFS) ||
@@ -7172,7 +6991,7 @@ bool LLParser::parseCall(Instruction *&Inst, PerFunctionState &PFS,
if (parseOptionalCallingConv(CC) || parseOptionalReturnAttrs(RetAttrs) ||
parseOptionalProgramAddrSpace(CallAddrSpace) ||
parseType(RetType, RetTypeLoc, true /*void allowed*/) ||
- parseValID(CalleeID) ||
+ parseValID(CalleeID, &PFS) ||
parseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail,
PFS.getFunction().isVarArg()) ||
parseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false, BuiltinLoc) ||
@@ -7366,9 +7185,13 @@ int LLParser::parseLoad(Instruction *&Inst, PerFunctionState &PFS) {
Ordering == AtomicOrdering::AcquireRelease)
return error(Loc, "atomic load cannot use Release ordering");
- if (Ty != cast<PointerType>(Val->getType())->getElementType())
- return error(ExplicitTypeLoc,
- "explicit pointee type doesn't match operand's pointee type");
+ if (!cast<PointerType>(Val->getType())->isOpaqueOrPointeeTypeMatches(Ty)) {
+ return error(
+ ExplicitTypeLoc,
+ typeComparisonErrorMessage(
+ "explicit pointee type doesn't match operand's pointee type", Ty,
+ cast<PointerType>(Val->getType())->getElementType()));
+ }
SmallPtrSet<Type *, 4> Visited;
if (!Alignment && !Ty->isSized(&Visited))
return error(ExplicitTypeLoc, "loading unsized types is not allowed");
@@ -7413,7 +7236,8 @@ int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
return error(PtrLoc, "store operand must be a pointer");
if (!Val->getType()->isFirstClassType())
return error(Loc, "store operand must be a first class value");
- if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
+ if (!cast<PointerType>(Ptr->getType())
+ ->isOpaqueOrPointeeTypeMatches(Val->getType()))
return error(Loc, "stored value and pointer type do not match");
if (isAtomic && !Alignment)
return error(Loc, "atomic store must have explicit non-zero alignment");
@@ -7432,7 +7256,8 @@ int LLParser::parseStore(Instruction *&Inst, PerFunctionState &PFS) {
/// parseCmpXchg
/// ::= 'cmpxchg' 'weak'? 'volatile'? TypeAndValue ',' TypeAndValue ','
-/// TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering
+/// TypeAndValue 'singlethread'? AtomicOrdering AtomicOrdering ','
+/// 'Align'?
int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Ptr, *Cmp, *New; LocTy PtrLoc, CmpLoc, NewLoc;
bool AteExtraComma = false;
@@ -7441,6 +7266,7 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
SyncScope::ID SSID = SyncScope::System;
bool isVolatile = false;
bool isWeak = false;
+ MaybeAlign Alignment;
if (EatIfPresent(lltok::kw_weak))
isWeak = true;
@@ -7454,36 +7280,37 @@ int LLParser::parseCmpXchg(Instruction *&Inst, PerFunctionState &PFS) {
parseToken(lltok::comma, "expected ',' after cmpxchg cmp operand") ||
parseTypeAndValue(New, NewLoc, PFS) ||
parseScopeAndOrdering(true /*Always atomic*/, SSID, SuccessOrdering) ||
- parseOrdering(FailureOrdering))
+ parseOrdering(FailureOrdering) ||
+ parseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
- if (SuccessOrdering == AtomicOrdering::Unordered ||
- FailureOrdering == AtomicOrdering::Unordered)
- return tokError("cmpxchg cannot be unordered");
- if (isStrongerThan(FailureOrdering, SuccessOrdering))
- return tokError("cmpxchg failure argument shall be no stronger than the "
- "success argument");
- if (FailureOrdering == AtomicOrdering::Release ||
- FailureOrdering == AtomicOrdering::AcquireRelease)
- return tokError(
- "cmpxchg failure ordering cannot include release semantics");
+ if (!AtomicCmpXchgInst::isValidSuccessOrdering(SuccessOrdering))
+ return tokError("invalid cmpxchg success ordering");
+ if (!AtomicCmpXchgInst::isValidFailureOrdering(FailureOrdering))
+ return tokError("invalid cmpxchg failure ordering");
if (!Ptr->getType()->isPointerTy())
return error(PtrLoc, "cmpxchg operand must be a pointer");
- if (cast<PointerType>(Ptr->getType())->getElementType() != Cmp->getType())
+ if (!cast<PointerType>(Ptr->getType())
+ ->isOpaqueOrPointeeTypeMatches(Cmp->getType()))
return error(CmpLoc, "compare value and pointer type do not match");
- if (cast<PointerType>(Ptr->getType())->getElementType() != New->getType())
+ if (!cast<PointerType>(Ptr->getType())
+ ->isOpaqueOrPointeeTypeMatches(New->getType()))
return error(NewLoc, "new value and pointer type do not match");
+ if (Cmp->getType() != New->getType())
+ return error(NewLoc, "compare value and new value type do not match");
if (!New->getType()->isFirstClassType())
return error(NewLoc, "cmpxchg operand must be a first class value");
- Align Alignment(
+ const Align DefaultAlignment(
PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize(
Cmp->getType()));
AtomicCmpXchgInst *CXI = new AtomicCmpXchgInst(
- Ptr, Cmp, New, Alignment, SuccessOrdering, FailureOrdering, SSID);
+ Ptr, Cmp, New, Alignment.getValueOr(DefaultAlignment), SuccessOrdering,
+ FailureOrdering, SSID);
CXI->setVolatile(isVolatile);
CXI->setWeak(isWeak);
+
Inst = CXI;
return AteExtraComma ? InstExtraComma : InstNormal;
}
@@ -7499,6 +7326,7 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
bool isVolatile = false;
bool IsFP = false;
AtomicRMWInst::BinOp Operation;
+ MaybeAlign Alignment;
if (EatIfPresent(lltok::kw_volatile))
isVolatile = true;
@@ -7531,14 +7359,16 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
if (parseTypeAndValue(Ptr, PtrLoc, PFS) ||
parseToken(lltok::comma, "expected ',' after atomicrmw address") ||
parseTypeAndValue(Val, ValLoc, PFS) ||
- parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering))
+ parseScopeAndOrdering(true /*Always atomic*/, SSID, Ordering) ||
+ parseOptionalCommaAlign(Alignment, AteExtraComma))
return true;
if (Ordering == AtomicOrdering::Unordered)
return tokError("atomicrmw cannot be unordered");
if (!Ptr->getType()->isPointerTy())
return error(PtrLoc, "atomicrmw operand must be a pointer");
- if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
+ if (!cast<PointerType>(Ptr->getType())
+ ->isOpaqueOrPointeeTypeMatches(Val->getType()))
return error(ValLoc, "atomicrmw value and pointer type do not match");
if (Operation == AtomicRMWInst::Xchg) {
@@ -7566,11 +7396,12 @@ int LLParser::parseAtomicRMW(Instruction *&Inst, PerFunctionState &PFS) {
if (Size < 8 || (Size & (Size - 1)))
return error(ValLoc, "atomicrmw operand must be power-of-two byte-sized"
" integer");
- Align Alignment(
+ const Align DefaultAlignment(
PFS.getFunction().getParent()->getDataLayout().getTypeStoreSize(
Val->getType()));
AtomicRMWInst *RMWI =
- new AtomicRMWInst(Operation, Ptr, Val, Alignment, Ordering, SSID);
+ new AtomicRMWInst(Operation, Ptr, Val,
+ Alignment.getValueOr(DefaultAlignment), Ordering, SSID);
RMWI->setVolatile(isVolatile);
Inst = RMWI;
return AteExtraComma ? InstExtraComma : InstNormal;
@@ -7614,9 +7445,13 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
if (!BasePointerType)
return error(Loc, "base of getelementptr must be a pointer");
- if (Ty != BasePointerType->getElementType())
- return error(ExplicitTypeLoc,
- "explicit pointee type doesn't match operand's pointee type");
+ if (!BasePointerType->isOpaqueOrPointeeTypeMatches(Ty)) {
+ return error(
+ ExplicitTypeLoc,
+ typeComparisonErrorMessage(
+ "explicit pointee type doesn't match operand's pointee type", Ty,
+ BasePointerType->getElementType()));
+ }
SmallVector<Value*, 16> Indices;
bool AteExtraComma = false;
@@ -7832,9 +7667,9 @@ bool LLParser::parseUseListOrderBB() {
ValID Fn, Label;
SmallVector<unsigned, 16> Indexes;
- if (parseValID(Fn) ||
+ if (parseValID(Fn, /*PFS=*/nullptr) ||
parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
- parseValID(Label) ||
+ parseValID(Label, /*PFS=*/nullptr) ||
parseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
parseUseListOrderIndexes(Indexes))
return true;
@@ -8517,7 +8352,8 @@ bool LLParser::parseFunctionSummary(std::string Name, GlobalValue::GUID GUID,
StringRef ModulePath;
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
- /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
+ GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
+ /*NotEligibleToImport=*/false,
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
unsigned InstCount;
std::vector<FunctionSummary::EdgeTy> Calls;
@@ -8593,7 +8429,8 @@ bool LLParser::parseVariableSummary(std::string Name, GlobalValue::GUID GUID,
StringRef ModulePath;
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
- /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
+ GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
+ /*NotEligibleToImport=*/false,
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
GlobalVarSummary::GVarFlags GVarFlags(/*ReadOnly*/ false,
/* WriteOnly */ false,
@@ -8651,7 +8488,8 @@ bool LLParser::parseAliasSummary(std::string Name, GlobalValue::GUID GUID,
StringRef ModulePath;
GlobalValueSummary::GVFlags GVFlags = GlobalValueSummary::GVFlags(
- /*Linkage=*/GlobalValue::ExternalLinkage, /*NotEligibleToImport=*/false,
+ GlobalValue::ExternalLinkage, GlobalValue::DefaultVisibility,
+ /*NotEligibleToImport=*/false,
/*Live=*/false, /*IsLocal=*/false, /*CanAutoHide=*/false);
if (parseToken(lltok::colon, "expected ':' here") ||
parseToken(lltok::lparen, "expected '(' here") ||
@@ -9035,6 +8873,7 @@ bool LLParser::parseOptionalParamAccesses(
return true;
CallsNum += ParamAccess.Calls.size();
assert(VContexts.size() == CallsNum);
+ (void)CallsNum;
Params.emplace_back(std::move(ParamAccess));
} while (EatIfPresent(lltok::comma));
@@ -9339,8 +9178,9 @@ bool LLParser::parseVFuncId(FunctionSummary::VFuncId &VFuncId,
/// GVFlags
/// ::= 'flags' ':' '(' 'linkage' ':' OptionalLinkageAux ','
-/// 'notEligibleToImport' ':' Flag ',' 'live' ':' Flag ','
-/// 'dsoLocal' ':' Flag ',' 'canAutoHide' ':' Flag ')'
+/// 'visibility' ':' Flag 'notEligibleToImport' ':' Flag ','
+/// 'live' ':' Flag ',' 'dsoLocal' ':' Flag ','
+/// 'canAutoHide' ':' Flag ',' ')'
bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
assert(Lex.getKind() == lltok::kw_flags);
Lex.Lex();
@@ -9361,6 +9201,13 @@ bool LLParser::parseGVFlags(GlobalValueSummary::GVFlags &GVFlags) {
assert(HasLinkage && "Linkage not optional in summary entry");
Lex.Lex();
break;
+ case lltok::kw_visibility:
+ Lex.Lex();
+ if (parseToken(lltok::colon, "expected ':'"))
+ return true;
+ parseOptionalVisibility(Flag);
+ GVFlags.Visibility = Flag;
+ break;
case lltok::kw_notEligibleToImport:
Lex.Lex();
if (parseToken(lltok::colon, "expected ':'") || parseFlag(Flag))
from llvm.
Sure~~~
from llvm.
Done!
from llvm.
Diff
Great @dannypsnl! Feel free to create a llvm13 branch if you feel like. The diff can be added as a file on this branch to track progress like last time.
Cheers,
Robin
from llvm.
Is LLVM 13 and LLVM 14 supported now? If not, how can I help?
from llvm.
No, llvm13 is in progress, but #205 (comment) has a hidden difference in syntax changes, after updating grammar, you will back and update this difference(@mewmew maybe that should be recorded in llvm13
branch? So anyone can update it, not only me).
You will modify https://github.com/llir/grammar/blob/master/ll.tm to handle those new syntaxes in llir. Generate command is make gen
, but I already forget how to get ./tools/textmapper
. This is the grammar for the parser generator.
After generating parser by generator, you might need to update https://github.com/llir/llvm/tree/master/ir for Go representation of llir, interface method LLString
is the point.
from llvm.
Is LLVM 13 and LLVM 14 supported now? If not, how can I help?
Hi @suhabe,
Glad to see you take an interest in the project :)
As noticed, @dannypsnl has started work on LLVM 13. For the last few releases of llir/llvm
@dannypsnl has been the one doing the majority of the work. I've mostly updated test cases and helped coordinate a bit.
However, work on LLVM 13 and upwards have been put on hold as both @dannypsnl and I are busy in life. Since this is a hobby project, other life priorities take precedence, as they should :)
If you feel like working on integrating LLVM 13/14 support into llir/llvm
, then you are most welcome to give it a go!
There is a wealth of comments written on how to update llir/llvm
to newer versions. Please take inspiration from the following:
- meta issue detailing how to update
llir/llvm
to a new LLVM release version: see #128
There are four sub-steps:
- Update llir/grammar/ll.tm grammar to LLVM version xx.0: see #101 for an example
- Generate parser of grammar (llir/ll) using Textmapper by @inspirer.
- Add new language constructs of LLVM version xx.0 to llir/llvm/ir: see #106 for an example
- Update test cases to LLVM version xx.0: see #195 and #132 for instance.
Feel free to give it a go!
If you struggle with getting Textmapper up and running, just give me a ping and I'll get you up to speed.
Wish you happy coding and a most wonderful summer ahead :)
Cheers,
Robin
from llvm.
No, llvm13 is in progress, but #205 (comment) has a hidden difference in syntax changes, after updating grammar, you will back and update this difference(@mewmew maybe that should be recorded in llvm13 branch? So anyone can update it, not only me).
@dannypsnl, is the llvm13.diff up to date? If so, it's already tracked in the llvm13 branch :) If not, then feel free to update it based on the <details>
field of the linked comment #205 (comment).
Cheers,
Robin
from llvm.
from llvm.
@dannypsnl thanks for doing the initial work on the LLVM 13.0 release of llir/llvm
! We've now got support for both LLVM 13.0 and LLVM 14.0 in llir/llvm
.
Wish you a happy summer!
Cheers,
Robin
from llvm.
@dannypsnl, could you prepare the v0.3.5 (LLVM 13.0) and v0.3.6 (LLVM 14.0) releases so they show up on https://github.com/llir/llvm/releases? (I've not done that before)
Cheers,
Robin
from llvm.
Related Issues (20)
- `interface{}` -> `any` HOT 7
- ast parse error HOT 10
- `SRet` struct location HOT 3
- How to use Function Pointers? HOT 3
- Wrong function pointer type HOT 1
- indirect br only takes constant addr HOT 1
- Returning void as a value HOT 3
- update llir/llvm to support 14.0 HOT 2
- update llir/llvm to support LLVM 15.0 HOT 7
- How to have two structs referencing eachother HOT 4
- How to convert to exe? HOT 3
- `module.NewTypeDef` has unexpected side effects HOT 17
- Provide working Hello, World example HOT 1
- support llvm 16.0.0 HOT 2
- incorrect cmpxchg signature HOT 4
- How to generate ir for embedded struct? HOT 6
- Convert to string HOT 1
- Hello 10 instead of Hello world. Passing a IntPtr to printf (go - LLIR/LLVM) HOT 3
- malloc and strcpy in LLVM HOT 1
- unable to generate LLVM: structure, external , noundef and ptr HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from llvm.