aboutsummaryrefslogtreecommitdiffstats
path: root/lib/AsmParser
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLLexer.cpp18
-rw-r--r--lib/AsmParser/LLLexer.h10
-rw-r--r--lib/AsmParser/LLParser.cpp472
-rw-r--r--lib/AsmParser/LLParser.h46
-rw-r--r--lib/AsmParser/LLToken.h12
-rw-r--r--lib/AsmParser/Parser.cpp44
6 files changed, 416 insertions, 186 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 1e5bcdd..6523bce 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -161,14 +161,10 @@ static const char *isLabelTail(const char *CurPtr) {
// Lexer definition.
//===----------------------------------------------------------------------===//
-LLLexer::LLLexer(MemoryBuffer *StartBuf, SourceMgr &sm, SMDiagnostic &Err,
+LLLexer::LLLexer(StringRef StartBuf, SourceMgr &sm, SMDiagnostic &Err,
LLVMContext &C)
: CurBuf(StartBuf), ErrorInfo(Err), SM(sm), Context(C), APFloatVal(0.0) {
- CurPtr = CurBuf->getBufferStart();
-}
-
-std::string LLLexer::getFilename() const {
- return CurBuf->getBufferIdentifier();
+ CurPtr = CurBuf.begin();
}
int LLLexer::getNextChar() {
@@ -178,7 +174,7 @@ int LLLexer::getNextChar() {
case 0:
// A nul character in the stream is either the end of the current buffer or
// a random nul in the file. Disambiguate that here.
- if (CurPtr-1 != CurBuf->getBufferEnd())
+ if (CurPtr-1 != CurBuf.end())
return 0; // Just whitespace.
// Otherwise, return end of file.
@@ -516,8 +512,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(private);
KEYWORD(internal);
- KEYWORD(linker_private); // NOTE: deprecated, for parser compatibility
- KEYWORD(linker_private_weak); // NOTE: deprecated, for parser compatibility
KEYWORD(available_externally);
KEYWORD(linkonce);
KEYWORD(linkonce_odr);
@@ -586,6 +580,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(x86_stdcallcc);
KEYWORD(x86_fastcallcc);
KEYWORD(x86_thiscallcc);
+ KEYWORD(x86_vectorcallcc);
KEYWORD(arm_apcscc);
KEYWORD(arm_aapcscc);
KEYWORD(arm_aapcs_vfpcc);
@@ -612,6 +607,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(byval);
KEYWORD(inalloca);
KEYWORD(cold);
+ KEYWORD(dereferenceable);
KEYWORD(inlinehint);
KEYWORD(inreg);
KEYWORD(jumptable);
@@ -669,6 +665,10 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(x);
KEYWORD(blockaddress);
+ // Use-list order directives.
+ KEYWORD(uselistorder);
+ KEYWORD(uselistorder_bb);
+
KEYWORD(personality);
KEYWORD(cleanup);
KEYWORD(catch);
diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h
index d42de57..219827f 100644
--- a/lib/AsmParser/LLLexer.h
+++ b/lib/AsmParser/LLLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LIB_ASMPARSER_LLLEXER_H
-#define LIB_ASMPARSER_LLLEXER_H
+#ifndef LLVM_LIB_ASMPARSER_LLLEXER_H
+#define LLVM_LIB_ASMPARSER_LLLEXER_H
#include "LLToken.h"
#include "llvm/ADT/APFloat.h"
@@ -28,7 +28,7 @@ namespace llvm {
class LLLexer {
const char *CurPtr;
- MemoryBuffer *CurBuf;
+ StringRef CurBuf;
SMDiagnostic &ErrorInfo;
SourceMgr &SM;
LLVMContext &Context;
@@ -43,7 +43,7 @@ namespace llvm {
APSInt APSIntVal;
public:
- explicit LLLexer(MemoryBuffer *StartBuf, SourceMgr &SM, SMDiagnostic &,
+ explicit LLLexer(StringRef StartBuf, SourceMgr &SM, SMDiagnostic &,
LLVMContext &C);
~LLLexer() {}
@@ -67,8 +67,6 @@ namespace llvm {
void Warning(LocTy WarningLoc, const Twine &Msg) const;
void Warning(const Twine &Msg) const { return Warning(getLoc(), Msg); }
- std::string getFilename() const;
-
private:
lltok::Kind LexToken();
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index be55ac6..2c835f9 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -24,6 +24,7 @@
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -129,28 +130,11 @@ bool LLParser::ValidateEndOfModule() {
}
}
- // If there are entries in ForwardRefBlockAddresses at this point, they are
- // references after the function was defined. Resolve those now.
- while (!ForwardRefBlockAddresses.empty()) {
- // Okay, we are referencing an already-parsed function, resolve them now.
- Function *TheFn = nullptr;
- const ValID &Fn = ForwardRefBlockAddresses.begin()->first;
- if (Fn.Kind == ValID::t_GlobalName)
- TheFn = M->getFunction(Fn.StrVal);
- else if (Fn.UIntVal < NumberedVals.size())
- TheFn = dyn_cast<Function>(NumberedVals[Fn.UIntVal]);
-
- if (!TheFn)
- return Error(Fn.Loc, "unknown function referenced by blockaddress");
-
- // Resolve all these references.
- if (ResolveForwardRefBlockAddresses(TheFn,
- ForwardRefBlockAddresses.begin()->second,
- nullptr))
- return true;
-
- ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
- }
+ // If there are entries in ForwardRefBlockAddresses at this point, the
+ // function was never defined.
+ if (!ForwardRefBlockAddresses.empty())
+ return Error(ForwardRefBlockAddresses.begin()->first.Loc,
+ "expected function name in blockaddress");
for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
if (NumberedTypes[i].second.isValid())
@@ -193,38 +177,6 @@ bool LLParser::ValidateEndOfModule() {
return false;
}
-bool LLParser::ResolveForwardRefBlockAddresses(Function *TheFn,
- std::vector<std::pair<ValID, GlobalValue*> > &Refs,
- PerFunctionState *PFS) {
- // Loop over all the references, resolving them.
- for (unsigned i = 0, e = Refs.size(); i != e; ++i) {
- BasicBlock *Res;
- if (PFS) {
- if (Refs[i].first.Kind == ValID::t_LocalName)
- Res = PFS->GetBB(Refs[i].first.StrVal, Refs[i].first.Loc);
- else
- Res = PFS->GetBB(Refs[i].first.UIntVal, Refs[i].first.Loc);
- } else if (Refs[i].first.Kind == ValID::t_LocalID) {
- return Error(Refs[i].first.Loc,
- "cannot take address of numeric label after the function is defined");
- } else {
- Res = dyn_cast_or_null<BasicBlock>(
- TheFn->getValueSymbolTable().lookup(Refs[i].first.StrVal));
- }
-
- if (!Res)
- 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);
- Refs[i].second->eraseFromParent();
- }
- return false;
-}
-
-
//===----------------------------------------------------------------------===//
// Top-Level Entities
//===----------------------------------------------------------------------===//
@@ -254,8 +206,6 @@ bool LLParser::ParseTopLevelEntities() {
// ('constant'|'global') ...
case lltok::kw_private: // OptionalLinkage
case lltok::kw_internal: // OptionalLinkage
- case lltok::kw_linker_private: // Obsolete OptionalLinkage
- case lltok::kw_linker_private_weak: // Obsolete OptionalLinkage
case lltok::kw_weak: // OptionalLinkage
case lltok::kw_weak_odr: // OptionalLinkage
case lltok::kw_linkonce: // OptionalLinkage
@@ -289,6 +239,9 @@ bool LLParser::ParseTopLevelEntities() {
}
case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break;
+ case lltok::kw_uselistorder: if (ParseUseListOrder()) return true; break;
+ case lltok::kw_uselistorder_bb:
+ if (ParseUseListOrderBB()) return true; break;
}
}
}
@@ -483,10 +436,10 @@ bool LLParser::ParseUnnamedGlobal() {
parseOptionalUnnamedAddr(UnnamedAddr))
return true;
- if (HasLinkage || Lex.getKind() != lltok::kw_alias)
+ if (Lex.getKind() != lltok::kw_alias)
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
DLLStorageClass, TLM, UnnamedAddr);
- return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
+ return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM,
UnnamedAddr);
}
@@ -512,10 +465,11 @@ bool LLParser::ParseNamedGlobal() {
parseOptionalUnnamedAddr(UnnamedAddr))
return true;
- if (HasLinkage || Lex.getKind() != lltok::kw_alias)
+ if (Lex.getKind() != lltok::kw_alias)
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
DLLStorageClass, TLM, UnnamedAddr);
- return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass, TLM,
+
+ return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM,
UnnamedAddr);
}
@@ -693,33 +647,29 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
}
/// ParseAlias:
-/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass
-/// OptionalThreadLocal OptionalUnNammedAddr 'alias'
-/// OptionalLinkage Aliasee
+/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
+/// OptionalDLLStorageClass OptionalThreadLocal
+/// OptionalUnNammedAddr 'alias' Aliasee
///
/// Aliasee
/// ::= TypeAndValue
///
/// Everything through OptionalUnNammedAddr has already been parsed.
///
-bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
+bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
unsigned Visibility, unsigned DLLStorageClass,
GlobalVariable::ThreadLocalMode TLM,
bool UnnamedAddr) {
assert(Lex.getKind() == lltok::kw_alias);
Lex.Lex();
- LocTy LinkageLoc = Lex.getLoc();
- unsigned L;
- if (ParseOptionalLinkage(L))
- return true;
GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
if(!GlobalAlias::isValidLinkage(Linkage))
- return Error(LinkageLoc, "invalid linkage type for alias");
+ return Error(NameLoc, "invalid linkage type for alias");
if (!isValidVisibilityForLinkage(Visibility, L))
- return Error(LinkageLoc,
+ return Error(NameLoc,
"symbol with local linkage must have default visibility");
Constant *Aliasee;
@@ -1052,6 +1002,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
"invalid use of attribute on a function");
break;
case lltok::kw_byval:
+ case lltok::kw_dereferenceable:
case lltok::kw_inalloca:
case lltok::kw_nest:
case lltok::kw_noalias:
@@ -1212,6 +1163,16 @@ bool LLParser::ParseUInt32(unsigned &Val) {
return false;
}
+/// ParseUInt64
+/// ::= uint64
+bool LLParser::ParseUInt64(uint64_t &Val) {
+ if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
+ return TokError("expected integer");
+ Val = Lex.getAPSIntVal().getLimitedValue();
+ Lex.Lex();
+ return false;
+}
+
/// ParseTLSModel
/// := 'localdynamic'
/// := 'initialexec'
@@ -1284,6 +1245,13 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
continue;
}
case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break;
+ case lltok::kw_dereferenceable: {
+ uint64_t Bytes;
+ if (ParseOptionalDereferenceableBytes(Bytes))
+ return true;
+ B.addDereferenceableAttr(Bytes);
+ 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;
@@ -1341,6 +1309,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
switch (Token) {
default: // End of attributes.
return HaveError;
+ case lltok::kw_dereferenceable: {
+ uint64_t Bytes;
+ if (ParseOptionalDereferenceableBytes(Bytes))
+ return true;
+ B.addDereferenceableAttr(Bytes);
+ continue;
+ }
case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break;
case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break;
case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break;
@@ -1409,10 +1384,6 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
/// ::= 'common'
/// ::= 'extern_weak'
/// ::= 'external'
-///
-/// Deprecated Values:
-/// ::= 'linker_private'
-/// ::= 'linker_private_weak'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
HasLinkage = false;
switch (Lex.getKind()) {
@@ -1430,15 +1401,6 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
-
- case lltok::kw_linker_private:
- case lltok::kw_linker_private_weak:
- Lex.Warning("'" + Lex.getStrVal() + "' is deprecated, treating as"
- " PrivateLinkage");
- Lex.Lex();
- // treat linker_private and linker_private_weak as PrivateLinkage
- Res = GlobalValue::PrivateLinkage;
- return false;
}
Lex.Lex();
HasLinkage = true;
@@ -1486,6 +1448,7 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'x86_stdcallcc'
/// ::= 'x86_fastcallcc'
/// ::= 'x86_thiscallcc'
+/// ::= 'x86_vectorcallcc'
/// ::= 'arm_apcscc'
/// ::= 'arm_aapcscc'
/// ::= 'arm_aapcs_vfpcc'
@@ -1502,7 +1465,7 @@ bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) {
/// ::= 'preserve_allcc'
/// ::= 'cc' UINT
///
-bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
+bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
switch (Lex.getKind()) {
default: CC = CallingConv::C; return false;
case lltok::kw_ccc: CC = CallingConv::C; break;
@@ -1511,6 +1474,7 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break;
case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
case lltok::kw_x86_thiscallcc: CC = CallingConv::X86_ThisCall; break;
+ case lltok::kw_x86_vectorcallcc:CC = CallingConv::X86_VectorCall; break;
case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
@@ -1527,12 +1491,8 @@ bool LLParser::ParseOptionalCallingConv(CallingConv::ID &CC) {
case lltok::kw_preserve_mostcc:CC = CallingConv::PreserveMost; break;
case lltok::kw_preserve_allcc: CC = CallingConv::PreserveAll; break;
case lltok::kw_cc: {
- unsigned ArbitraryCC;
Lex.Lex();
- if (ParseUInt32(ArbitraryCC))
- return true;
- CC = static_cast<CallingConv::ID>(ArbitraryCC);
- return false;
+ return ParseUInt32(CC);
}
}
@@ -1606,6 +1566,26 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
return false;
}
+/// ParseOptionalDereferenceableBytes
+/// ::= /* empty */
+/// ::= 'dereferenceable' '(' 4 ')'
+bool LLParser::ParseOptionalDereferenceableBytes(uint64_t &Bytes) {
+ Bytes = 0;
+ if (!EatIfPresent(lltok::kw_dereferenceable))
+ return false;
+ LocTy ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::lparen))
+ return Error(ParenLoc, "expected '('");
+ LocTy DerefLoc = Lex.getLoc();
+ if (ParseUInt64(Bytes)) return true;
+ ParenLoc = Lex.getLoc();
+ if (!EatIfPresent(lltok::rparen))
+ return Error(ParenLoc, "expected ')'");
+ if (!Bytes)
+ return Error(DerefLoc, "dereferenceable bytes must be non-zero");
+ return false;
+}
+
/// ParseOptionalCommaAlign
/// ::=
/// ::= ',' align 4
@@ -1837,7 +1817,8 @@ bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
/// Arg
/// ::= Type OptionalAttributes Value OptionalAttributes
bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
- PerFunctionState &PFS) {
+ PerFunctionState &PFS, bool IsMustTailCall,
+ bool InVarArgsFunc) {
if (ParseToken(lltok::lparen, "expected '(' in call"))
return true;
@@ -1848,6 +1829,17 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
ParseToken(lltok::comma, "expected ',' in argument list"))
return true;
+ // Parse an ellipsis if this is a musttail call in a variadic function.
+ if (Lex.getKind() == lltok::dotdotdot) {
+ const char *Msg = "unexpected ellipsis in argument list for ";
+ if (!IsMustTailCall)
+ return TokError(Twine(Msg) + "non-musttail call");
+ if (!InVarArgsFunc)
+ return TokError(Twine(Msg) + "musttail call in non-varargs function");
+ Lex.Lex(); // Lex the '...', it is purely for readability.
+ return ParseToken(lltok::rparen, "expected ')' at end of argument list");
+ }
+
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = nullptr;
@@ -1864,6 +1856,10 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
ArgAttrs)));
}
+ if (IsMustTailCall && InVarArgsFunc)
+ return TokError("expected '...' at end of argument list for musttail call "
+ "in varargs function");
+
Lex.Lex(); // Lex the ')'.
return false;
}
@@ -2159,28 +2155,6 @@ LLParser::PerFunctionState::~PerFunctionState() {
}
bool LLParser::PerFunctionState::FinishFunction() {
- // Check to see if someone took the address of labels in this block.
- if (!P.ForwardRefBlockAddresses.empty()) {
- ValID FunctionID;
- if (!F.getName().empty()) {
- FunctionID.Kind = ValID::t_GlobalName;
- FunctionID.StrVal = F.getName();
- } else {
- 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 +
@@ -2222,7 +2196,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
}
// Don't make placeholders with invalid type.
- if (!Ty->isFirstClassType() && !Ty->isLabelTy()) {
+ if (!Ty->isFirstClassType()) {
P.Error(Loc, "invalid use of a non-first-class type");
return nullptr;
}
@@ -2263,7 +2237,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
return nullptr;
}
- if (!Ty->isFirstClassType() && !Ty->isLabelTy()) {
+ if (!Ty->isFirstClassType()) {
P.Error(Loc, "invalid use of a non-first-class type");
return nullptr;
}
@@ -2566,12 +2540,56 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
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,
- nullptr, "");
- ForwardRefBlockAddresses[Fn].push_back(std::make_pair(Label, FwdRef));
- ID.ConstantVal = FwdRef;
+ // Try to find the function (but skip it if it's forward-referenced).
+ GlobalValue *GV = nullptr;
+ if (Fn.Kind == ValID::t_GlobalID) {
+ if (Fn.UIntVal < NumberedVals.size())
+ GV = NumberedVals[Fn.UIntVal];
+ } else if (!ForwardRefVals.count(Fn.StrVal)) {
+ GV = M->getNamedValue(Fn.StrVal);
+ }
+ Function *F = nullptr;
+ if (GV) {
+ // Confirm that it's actually a function with a definition.
+ if (!isa<Function>(GV))
+ return Error(Fn.Loc, "expected function name in blockaddress");
+ F = cast<Function>(GV);
+ if (F->isDeclaration())
+ return Error(Fn.Loc, "cannot take blockaddress inside a declaration");
+ }
+
+ if (!F) {
+ // Make a global variable as a placeholder for this reference.
+ GlobalValue *&FwdRef = ForwardRefBlockAddresses[Fn][Label];
+ if (!FwdRef)
+ FwdRef = new GlobalVariable(*M, Type::getInt8Ty(Context), false,
+ GlobalValue::InternalLinkage, nullptr, "");
+ ID.ConstantVal = FwdRef;
+ ID.Kind = ValID::t_Constant;
+ return false;
+ }
+
+ // We found the function; now find the basic block. Don't use PFS, since we
+ // might be inside a constant expression.
+ BasicBlock *BB;
+ if (BlockAddressPFS && F == &BlockAddressPFS->getFunction()) {
+ if (Label.Kind == ValID::t_LocalID)
+ BB = BlockAddressPFS->GetBB(Label.UIntVal, Label.Loc);
+ else
+ BB = BlockAddressPFS->GetBB(Label.StrVal, Label.Loc);
+ if (!BB)
+ return Error(Label.Loc, "referenced value is not a basic block");
+ } else {
+ if (Label.Kind == ValID::t_LocalID)
+ return Error(Label.Loc, "cannot take address of numeric label after "
+ "the function is defined");
+ BB = dyn_cast_or_null<BasicBlock>(
+ F->getValueSymbolTable().lookup(Label.StrVal));
+ if (!BB)
+ return Error(Label.Loc, "referenced value is not a basic block");
+ }
+
+ ID.ConstantVal = BlockAddress::get(F, BB);
ID.Kind = ValID::t_Constant;
return false;
}
@@ -2886,7 +2904,7 @@ bool LLParser::parseOptionalComdat(Comdat *&C) {
/// ParseGlobalValueVector
/// ::= /*empty*/
/// ::= TypeAndValue (',' TypeAndValue)*
-bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
+bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) {
// Empty list.
if (Lex.getKind() == lltok::rbrace ||
Lex.getKind() == lltok::rsquare ||
@@ -3111,7 +3129,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
unsigned Visibility;
unsigned DLLStorageClass;
AttrBuilder RetAttrs;
- CallingConv::ID CC;
+ unsigned CC;
Type *RetType = nullptr;
LocTy RetTypeLoc = Lex.getLoc();
if (ParseOptionalLinkage(Linkage) ||
@@ -3314,13 +3332,63 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
ArgList[i].Name + "'");
}
+ if (isDefine)
+ return false;
+
+ // Check the declaration has no block address forward references.
+ ValID ID;
+ if (FunctionName.empty()) {
+ ID.Kind = ValID::t_GlobalID;
+ ID.UIntVal = NumberedVals.size() - 1;
+ } else {
+ ID.Kind = ValID::t_GlobalName;
+ ID.StrVal = FunctionName;
+ }
+ auto Blocks = ForwardRefBlockAddresses.find(ID);
+ if (Blocks != ForwardRefBlockAddresses.end())
+ return Error(Blocks->first.Loc,
+ "cannot take blockaddress inside a declaration");
return false;
}
+bool LLParser::PerFunctionState::resolveForwardRefBlockAddresses() {
+ ValID ID;
+ if (FunctionNumber == -1) {
+ ID.Kind = ValID::t_GlobalName;
+ ID.StrVal = F.getName();
+ } else {
+ ID.Kind = ValID::t_GlobalID;
+ ID.UIntVal = FunctionNumber;
+ }
+
+ auto Blocks = P.ForwardRefBlockAddresses.find(ID);
+ if (Blocks == P.ForwardRefBlockAddresses.end())
+ return false;
+
+ for (const auto &I : Blocks->second) {
+ const ValID &BBID = I.first;
+ GlobalValue *GV = I.second;
+
+ assert((BBID.Kind == ValID::t_LocalID || BBID.Kind == ValID::t_LocalName) &&
+ "Expected local id or name");
+ BasicBlock *BB;
+ if (BBID.Kind == ValID::t_LocalName)
+ BB = GetBB(BBID.StrVal, BBID.Loc);
+ else
+ BB = GetBB(BBID.UIntVal, BBID.Loc);
+ if (!BB)
+ return P.Error(BBID.Loc, "referenced value is not a basic block");
+
+ GV->replaceAllUsesWith(BlockAddress::get(&F, BB));
+ GV->eraseFromParent();
+ }
+
+ P.ForwardRefBlockAddresses.erase(Blocks);
+ return false;
+}
/// ParseFunctionBody
-/// ::= '{' BasicBlock+ '}'
-///
+/// ::= '{' BasicBlock+ UseListOrderDirective* '}'
bool LLParser::ParseFunctionBody(Function &Fn) {
if (Lex.getKind() != lltok::lbrace)
return TokError("expected '{' in function body");
@@ -3331,13 +3399,24 @@ bool LLParser::ParseFunctionBody(Function &Fn) {
PerFunctionState PFS(*this, Fn, FunctionNumber);
+ // Resolve block addresses and allow basic blocks to be forward-declared
+ // within this function.
+ if (PFS.resolveForwardRefBlockAddresses())
+ return true;
+ SaveAndRestore<PerFunctionState *> ScopeExit(BlockAddressPFS, &PFS);
+
// We need at least one basic block.
- if (Lex.getKind() == lltok::rbrace)
+ if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::kw_uselistorder)
return TokError("function body requires at least one basic block");
- while (Lex.getKind() != lltok::rbrace)
+ while (Lex.getKind() != lltok::rbrace &&
+ Lex.getKind() != lltok::kw_uselistorder)
if (ParseBasicBlock(PFS)) return true;
+ while (Lex.getKind() != lltok::rbrace)
+ if (ParseUseListOrder(&PFS))
+ return true;
+
// Eat the }.
Lex.Lex();
@@ -3656,7 +3735,7 @@ bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
ParseTypeAndBasicBlock(DestBB, PFS))
return true;
- if (!SeenCases.insert(Constant))
+ if (!SeenCases.insert(Constant).second)
return Error(CondLoc, "duplicate case value in switch");
if (!isa<ConstantInt>(Constant))
return Error(CondLoc, "case value is not a constant integer");
@@ -3722,7 +3801,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
LocTy NoBuiltinLoc;
- CallingConv::ID CC;
+ unsigned CC;
Type *RetType = nullptr;
LocTy RetTypeLoc;
ValID CalleeID;
@@ -4136,7 +4215,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
LocTy BuiltinLoc;
- CallingConv::ID CC;
+ unsigned CC;
Type *RetType = nullptr;
LocTy RetTypeLoc;
ValID CalleeID;
@@ -4149,7 +4228,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
- ParseParameterList(ArgList, PFS) ||
+ ParseParameterList(ArgList, PFS, TCK == CallInst::TCK_MustTail,
+ PFS.getFunction().isVarArg()) ||
ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
BuiltinLoc))
return true;
@@ -4596,3 +4676,135 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
return false;
}
+
+//===----------------------------------------------------------------------===//
+// Use-list order directives.
+//===----------------------------------------------------------------------===//
+bool LLParser::sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes,
+ SMLoc Loc) {
+ if (V->use_empty())
+ return Error(Loc, "value has no uses");
+
+ unsigned NumUses = 0;
+ SmallDenseMap<const Use *, unsigned, 16> Order;
+ for (const Use &U : V->uses()) {
+ if (++NumUses > Indexes.size())
+ break;
+ Order[&U] = Indexes[NumUses - 1];
+ }
+ if (NumUses < 2)
+ return Error(Loc, "value only has one use");
+ if (Order.size() != Indexes.size() || NumUses > Indexes.size())
+ return Error(Loc, "wrong number of indexes, expected " +
+ Twine(std::distance(V->use_begin(), V->use_end())));
+
+ V->sortUseList([&](const Use &L, const Use &R) {
+ return Order.lookup(&L) < Order.lookup(&R);
+ });
+ return false;
+}
+
+/// ParseUseListOrderIndexes
+/// ::= '{' uint32 (',' uint32)+ '}'
+bool LLParser::ParseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes) {
+ SMLoc Loc = Lex.getLoc();
+ if (ParseToken(lltok::lbrace, "expected '{' here"))
+ return true;
+ if (Lex.getKind() == lltok::rbrace)
+ return Lex.Error("expected non-empty list of uselistorder indexes");
+
+ // Use Offset, Max, and IsOrdered to check consistency of indexes. The
+ // indexes should be distinct numbers in the range [0, size-1], and should
+ // not be in order.
+ unsigned Offset = 0;
+ unsigned Max = 0;
+ bool IsOrdered = true;
+ assert(Indexes.empty() && "Expected empty order vector");
+ do {
+ unsigned Index;
+ if (ParseUInt32(Index))
+ return true;
+
+ // Update consistency checks.
+ Offset += Index - Indexes.size();
+ Max = std::max(Max, Index);
+ IsOrdered &= Index == Indexes.size();
+
+ Indexes.push_back(Index);
+ } while (EatIfPresent(lltok::comma));
+
+ if (ParseToken(lltok::rbrace, "expected '}' here"))
+ return true;
+
+ if (Indexes.size() < 2)
+ return Error(Loc, "expected >= 2 uselistorder indexes");
+ if (Offset != 0 || Max >= Indexes.size())
+ return Error(Loc, "expected distinct uselistorder indexes in range [0, size)");
+ if (IsOrdered)
+ return Error(Loc, "expected uselistorder indexes to change the order");
+
+ return false;
+}
+
+/// ParseUseListOrder
+/// ::= 'uselistorder' Type Value ',' UseListOrderIndexes
+bool LLParser::ParseUseListOrder(PerFunctionState *PFS) {
+ SMLoc Loc = Lex.getLoc();
+ if (ParseToken(lltok::kw_uselistorder, "expected uselistorder directive"))
+ return true;
+
+ Value *V;
+ SmallVector<unsigned, 16> Indexes;
+ if (ParseTypeAndValue(V, PFS) ||
+ ParseToken(lltok::comma, "expected comma in uselistorder directive") ||
+ ParseUseListOrderIndexes(Indexes))
+ return true;
+
+ return sortUseListOrder(V, Indexes, Loc);
+}
+
+/// ParseUseListOrderBB
+/// ::= 'uselistorder_bb' @foo ',' %bar ',' UseListOrderIndexes
+bool LLParser::ParseUseListOrderBB() {
+ assert(Lex.getKind() == lltok::kw_uselistorder_bb);
+ SMLoc Loc = Lex.getLoc();
+ Lex.Lex();
+
+ ValID Fn, Label;
+ SmallVector<unsigned, 16> Indexes;
+ if (ParseValID(Fn) ||
+ ParseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
+ ParseValID(Label) ||
+ ParseToken(lltok::comma, "expected comma in uselistorder_bb directive") ||
+ ParseUseListOrderIndexes(Indexes))
+ return true;
+
+ // Check the function.
+ GlobalValue *GV;
+ if (Fn.Kind == ValID::t_GlobalName)
+ GV = M->getNamedValue(Fn.StrVal);
+ else if (Fn.Kind == ValID::t_GlobalID)
+ GV = Fn.UIntVal < NumberedVals.size() ? NumberedVals[Fn.UIntVal] : nullptr;
+ else
+ return Error(Fn.Loc, "expected function name in uselistorder_bb");
+ if (!GV)
+ return Error(Fn.Loc, "invalid function forward reference in uselistorder_bb");
+ auto *F = dyn_cast<Function>(GV);
+ if (!F)
+ return Error(Fn.Loc, "expected function name in uselistorder_bb");
+ if (F->isDeclaration())
+ return Error(Fn.Loc, "invalid declaration in uselistorder_bb");
+
+ // Check the basic block.
+ if (Label.Kind == ValID::t_LocalID)
+ return Error(Label.Loc, "invalid numeric label in uselistorder_bb");
+ if (Label.Kind != ValID::t_LocalName)
+ return Error(Label.Loc, "expected basic block name in uselistorder_bb");
+ Value *V = F->getValueSymbolTable().lookup(Label.StrVal);
+ if (!V)
+ return Error(Label.Loc, "invalid basic block in uselistorder_bb");
+ if (!isa<BasicBlock>(V))
+ return Error(Label.Loc, "expected basic block in uselistorder_bb");
+
+ return sortUseListOrder(V, Indexes, Loc);
+}
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 2efb260..aa62bcc 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ASMPARSER_LLPARSER_H
-#define LLVM_ASMPARSER_LLPARSER_H
+#ifndef LLVM_LIB_ASMPARSER_LLPARSER_H
+#define LLVM_LIB_ASMPARSER_LLPARSER_H
#include "LLLexer.h"
#include "llvm/ADT/DenseMap.h"
@@ -128,17 +128,21 @@ namespace llvm {
// 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;
+ std::map<ValID, std::map<ValID, GlobalValue *>> ForwardRefBlockAddresses;
+ class PerFunctionState;
+ /// Reference to per-function state to allow basic blocks to be
+ /// forward-referenced by blockaddress instructions within the same
+ /// function.
+ PerFunctionState *BlockAddressPFS;
// 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) :
- Context(m->getContext()), Lex(F, SM, Err, m->getContext()),
- M(m) {}
+ LLParser(StringRef F, SourceMgr &SM, SMDiagnostic &Err, Module *m)
+ : Context(m->getContext()), Lex(F, SM, Err, m->getContext()), M(m),
+ BlockAddressPFS(nullptr) {}
bool Run();
LLVMContext &getContext() { return Context; }
@@ -202,6 +206,11 @@ namespace llvm {
Loc = Lex.getLoc();
return ParseUInt32(Val);
}
+ bool ParseUInt64(uint64_t &Val);
+ bool ParseUInt64(uint64_t &Val, LocTy &Loc) {
+ Loc = Lex.getLoc();
+ return ParseUInt64(Val);
+ }
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
@@ -217,8 +226,9 @@ namespace llvm {
}
bool ParseOptionalVisibility(unsigned &Visibility);
bool ParseOptionalDLLStorageClass(unsigned &DLLStorageClass);
- bool ParseOptionalCallingConv(CallingConv::ID &CC);
+ bool ParseOptionalCallingConv(unsigned &CC);
bool ParseOptionalAlignment(unsigned &Alignment);
+ bool ParseOptionalDereferenceableBytes(uint64_t &Bytes);
bool ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope,
AtomicOrdering &Ordering);
bool ParseOrdering(AtomicOrdering &Ordering);
@@ -252,8 +262,8 @@ namespace llvm {
bool HasLinkage, unsigned Visibility,
unsigned DLLStorageClass,
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
- bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility,
- unsigned DLLStorageClass,
+ bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Linkage,
+ unsigned Visibility, unsigned DLLStorageClass,
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
bool parseComdat();
bool ParseStandaloneMetadata();
@@ -321,6 +331,8 @@ namespace llvm {
/// unnamed. If there is an error, this returns null otherwise it returns
/// the block being defined.
BasicBlock *DefineBB(const std::string &Name, LocTy Loc);
+
+ bool resolveForwardRefBlockAddresses();
};
bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
@@ -360,13 +372,15 @@ namespace llvm {
: Loc(loc), V(v), Attrs(attrs) {}
};
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
- PerFunctionState &PFS);
+ PerFunctionState &PFS,
+ bool IsMustTailCall = false,
+ bool InVarArgsFunc = false);
// Constant Parsing.
bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr);
bool ParseGlobalValue(Type *Ty, Constant *&V);
bool ParseGlobalTypeAndValue(Constant *&V);
- bool ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts);
+ bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts);
bool parseOptionalComdat(Comdat *&C);
bool ParseMetadataListValue(ValID &ID, PerFunctionState *PFS);
bool ParseMetadataValue(ValID &ID, PerFunctionState *PFS);
@@ -427,9 +441,11 @@ namespace llvm {
int ParseExtractValue(Instruction *&I, PerFunctionState &PFS);
int ParseInsertValue(Instruction *&I, PerFunctionState &PFS);
- bool ResolveForwardRefBlockAddresses(Function *TheFn,
- std::vector<std::pair<ValID, GlobalValue*> > &Refs,
- PerFunctionState *PFS);
+ // Use-list order directives.
+ bool ParseUseListOrder(PerFunctionState *PFS = nullptr);
+ bool ParseUseListOrderBB();
+ bool ParseUseListOrderIndexes(SmallVectorImpl<unsigned> &Indexes);
+ bool sortUseListOrder(Value *V, ArrayRef<unsigned> Indexes, SMLoc Loc);
};
} // End llvm namespace
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 534d824..f9821f7 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LIBS_ASMPARSER_LLTOKEN_H
-#define LIBS_ASMPARSER_LLTOKEN_H
+#ifndef LLVM_LIB_ASMPARSER_LLTOKEN_H
+#define LLVM_LIB_ASMPARSER_LLTOKEN_H
namespace llvm {
namespace lltok {
@@ -39,8 +39,6 @@ namespace lltok {
kw_private,
kw_internal,
- kw_linker_private, // NOTE: deprecated, for parser compatibility
- kw_linker_private_weak, // NOTE: deprecated, for parser compatibility
kw_linkonce, kw_linkonce_odr,
kw_weak, // Used as a linkage, and a modifier for "cmpxchg".
kw_weak_odr, kw_appending,
@@ -89,7 +87,7 @@ namespace lltok {
kw_cc, kw_ccc, kw_fastcc, kw_coldcc,
kw_intel_ocl_bicc,
- kw_x86_stdcallcc, kw_x86_fastcallcc, kw_x86_thiscallcc,
+ kw_x86_stdcallcc, kw_x86_fastcallcc, kw_x86_thiscallcc, kw_x86_vectorcallcc,
kw_arm_apcscc, kw_arm_aapcscc, kw_arm_aapcs_vfpcc,
kw_msp430_intrcc,
kw_ptx_kernel, kw_ptx_device,
@@ -106,6 +104,7 @@ namespace lltok {
kw_byval,
kw_inalloca,
kw_cold,
+ kw_dereferenceable,
kw_inlinehint,
kw_inreg,
kw_jumptable,
@@ -181,6 +180,9 @@ namespace lltok {
kw_extractelement, kw_insertelement, kw_shufflevector,
kw_extractvalue, kw_insertvalue, kw_blockaddress,
+ // Use-list order directives.
+ kw_uselistorder, kw_uselistorder_bb,
+
// Unsigned Valued tokens (UIntVal).
GlobalID, // @42
LocalVarID, // %42
diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp
index 91bb51c..0815907 100644
--- a/lib/AsmParser/Parser.cpp
+++ b/lib/AsmParser/Parser.cpp
@@ -21,26 +21,29 @@
#include <system_error>
using namespace llvm;
-Module *llvm::ParseAssembly(MemoryBuffer *F,
- Module *M,
- SMDiagnostic &Err,
- LLVMContext &Context) {
+bool llvm::parseAssemblyInto(MemoryBufferRef F, Module &M, SMDiagnostic &Err) {
SourceMgr SM;
- SM.AddNewSourceBuffer(F, SMLoc());
+ std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(F, false);
+ SM.AddNewSourceBuffer(std::move(Buf), SMLoc());
- // If we are parsing into an existing module, do it.
- if (M)
- return LLParser(F, SM, Err, M).Run() ? nullptr : M;
+ return LLParser(F.getBuffer(), SM, Err, &M).Run();
+}
+
+std::unique_ptr<Module> llvm::parseAssembly(MemoryBufferRef F,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ std::unique_ptr<Module> M =
+ make_unique<Module>(F.getBufferIdentifier(), Context);
- // Otherwise create a new module.
- std::unique_ptr<Module> M2(new Module(F->getBufferIdentifier(), Context));
- if (LLParser(F, SM, Err, M2.get()).Run())
+ if (parseAssemblyInto(F, *M, Err))
return nullptr;
- return M2.release();
+
+ return std::move(M);
}
-Module *llvm::ParseAssemblyFile(const std::string &Filename, SMDiagnostic &Err,
- LLVMContext &Context) {
+std::unique_ptr<Module> llvm::parseAssemblyFile(StringRef Filename,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Filename);
if (std::error_code EC = FileOrErr.getError()) {
@@ -49,13 +52,12 @@ Module *llvm::ParseAssemblyFile(const std::string &Filename, SMDiagnostic &Err,
return nullptr;
}
- return ParseAssembly(FileOrErr.get().release(), nullptr, Err, Context);
+ return parseAssembly(FileOrErr.get()->getMemBufferRef(), Err, Context);
}
-Module *llvm::ParseAssemblyString(const char *AsmString, Module *M,
- SMDiagnostic &Err, LLVMContext &Context) {
- MemoryBuffer *F =
- MemoryBuffer::getMemBuffer(StringRef(AsmString), "<string>");
-
- return ParseAssembly(F, M, Err, Context);
+std::unique_ptr<Module> llvm::parseAssemblyString(StringRef AsmString,
+ SMDiagnostic &Err,
+ LLVMContext &Context) {
+ MemoryBufferRef F(AsmString, "<string>");
+ return parseAssembly(F, Err, Context);
}