aboutsummaryrefslogtreecommitdiffstats
path: root/lib/AsmParser
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-02-22 00:12:35 +0000
committerBill Wendling <isanbard@gmail.com>2013-02-22 00:12:35 +0000
commit143d46476cdcf5b88b9ee18ebd799e5820a2db0e (patch)
tree8b99f1da4df8777771cf9355beeefc3660950465 /lib/AsmParser
parenta931a12e04b856421977c86d94789cd8b47d6ad3 (diff)
downloadexternal_llvm-143d46476cdcf5b88b9ee18ebd799e5820a2db0e.zip
external_llvm-143d46476cdcf5b88b9ee18ebd799e5820a2db0e.tar.gz
external_llvm-143d46476cdcf5b88b9ee18ebd799e5820a2db0e.tar.bz2
Implement the NoBuiltin attribute.
The 'nobuiltin' attribute is applied to call sites to indicate that LLVM should not treat the callee function as a built-in function. I.e., it shouldn't try to replace that function with different code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175835 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLLexer.cpp1
-rw-r--r--lib/AsmParser/LLParser.cpp27
-rw-r--r--lib/AsmParser/LLParser.h2
-rw-r--r--lib/AsmParser/LLToken.h1
4 files changed, 24 insertions, 7 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp
index 35108af..2b14559 100644
--- a/lib/AsmParser/LLLexer.cpp
+++ b/lib/AsmParser/LLLexer.cpp
@@ -571,6 +571,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(naked);
KEYWORD(nest);
KEYWORD(noalias);
+ KEYWORD(nobuiltin);
KEYWORD(nocapture);
KEYWORD(noduplicate);
KEYWORD(noimplicitfloat);
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 86e2fd9..bde18cd 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -810,11 +810,13 @@ bool LLParser::ParseUnnamedAttrGrp() {
assert(Lex.getKind() == lltok::AttrGrpID);
unsigned VarID = Lex.getUIntVal();
std::vector<unsigned> unused;
+ LocTy NoBuiltinLoc;
Lex.Lex();
if (ParseToken(lltok::equal, "expected '=' here") ||
ParseToken(lltok::lbrace, "expected '{' here") ||
- ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true) ||
+ ParseFnAttributeValuePairs(NumberedAttrBuilders[VarID], unused, true,
+ NoBuiltinLoc) ||
ParseToken(lltok::rbrace, "expected end of attribute group"))
return true;
@@ -828,13 +830,15 @@ bool LLParser::ParseUnnamedAttrGrp() {
/// ::= <attr> | <attr> '=' <value>
bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
std::vector<unsigned> &FwdRefAttrGrps,
- bool inAttrGrp) {
+ bool inAttrGrp, LocTy &NoBuiltinLoc) {
bool HaveError = false;
B.clear();
while (true) {
lltok::Kind Token = Lex.getKind();
+ if (Token == lltok::kw_nobuiltin)
+ NoBuiltinLoc = Lex.getLoc();
switch (Token) {
default:
if (!inAttrGrp) return HaveError;
@@ -908,6 +912,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
+ case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
case lltok::kw_noimplicitfloat: B.addAttribute(Attribute::NoImplicitFloat); break;
case lltok::kw_noinline: B.addAttribute(Attribute::NoInline); break;
@@ -1164,7 +1169,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
case lltok::kw_naked: case lltok::kw_nonlazybind:
case lltok::kw_address_safety: case lltok::kw_minsize:
case lltok::kw_alignstack: case lltok::kw_thread_safety:
- case lltok::kw_uninitialized_checks:
+ case lltok::kw_nobuiltin: case lltok::kw_uninitialized_checks:
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
}
@@ -1207,6 +1212,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
case lltok::kw_minsize: case lltok::kw_alignstack:
case lltok::kw_align: case lltok::kw_noduplicate:
case lltok::kw_thread_safety: case lltok::kw_uninitialized_checks:
+ case lltok::kw_nobuiltin:
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
}
@@ -2944,6 +2950,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
bool isVarArg;
AttrBuilder FuncAttrs;
std::vector<unsigned> FwdRefAttrGrps;
+ LocTy NoBuiltinLoc;
std::string Section;
unsigned Alignment;
std::string GC;
@@ -2953,7 +2960,8 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
&UnnamedAddrLoc) ||
- ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false) ||
+ ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
+ NoBuiltinLoc) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
ParseOptionalAlignment(Alignment) ||
@@ -2961,6 +2969,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
ParseStringConstant(GC)))
return true;
+ if (FuncAttrs.contains(Attribute::NoBuiltin))
+ return Error(NoBuiltinLoc, "'nobuiltin' attribute not valid on function");
+
// If the alignment was parsed as an attribute, move to the alignment field.
if (FuncAttrs.hasAlignmentAttr()) {
Alignment = FuncAttrs.getAlignment();
@@ -3474,6 +3485,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
+ LocTy NoBuiltinLoc;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@@ -3486,7 +3498,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false) ||
+ ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+ NoBuiltinLoc) ||
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
@@ -3881,6 +3894,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
AttrBuilder RetAttrs, FnAttrs;
std::vector<unsigned> FwdRefAttrGrps;
+ LocTy NoBuiltinLoc;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc;
@@ -3894,7 +3908,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false))
+ ParseFnAttributeValuePairs(FnAttrs, FwdRefAttrGrps, false,
+ NoBuiltinLoc))
return true;
// If RetType is a non-function pointer type, then this is the short syntax
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index 42cdbd5..1f2879e 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -242,7 +242,7 @@ namespace llvm {
bool ParseUnnamedAttrGrp();
bool ParseFnAttributeValuePairs(AttrBuilder &B,
std::vector<unsigned> &FwdRefAttrGrps,
- bool inAttrGrp);
+ bool inAttrGrp, LocTy &NoBuiltinLoc);
// Type Parsing.
bool ParseType(Type *&Result, bool AllowVoid = false);
diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h
index 97429b8..a51dada 100644
--- a/lib/AsmParser/LLToken.h
+++ b/lib/AsmParser/LLToken.h
@@ -102,6 +102,7 @@ namespace lltok {
kw_naked,
kw_nest,
kw_noalias,
+ kw_nobuiltin,
kw_nocapture,
kw_noduplicate,
kw_noimplicitfloat,