summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2012-12-04 23:40:58 +0000
committerBill Wendling <isanbard@gmail.com>2012-12-04 23:40:58 +0000
commite01b81be33ebbc3e087d758341de0c2ba5d44135 (patch)
tree13c6141ac57be5bf728602c110055938153adc49 /lib
parent46c5f79789947b75ff3b0cc107f133fb0c5ffb5e (diff)
downloadllvm-e01b81be33ebbc3e087d758341de0c2ba5d44135.tar.gz
llvm-e01b81be33ebbc3e087d758341de0c2ba5d44135.tar.bz2
llvm-e01b81be33ebbc3e087d758341de0c2ba5d44135.tar.xz
Split up the ParseOptionalAttrs method into three different methods for each
class of attributes. This makes it much easier to check for errors and to reuse the code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@169336 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AsmParser/LLParser.cpp199
-rw-r--r--lib/AsmParser/LLParser.h4
2 files changed, 122 insertions, 81 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index c0557727c3..e854ddb05e 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -912,11 +912,8 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
ParseToken(lltok::rparen, "expected ')' in address space");
}
-/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
-/// indicates what kind of attribute list this is: 0: function arg, 1: result,
-/// 2: function attr.
-bool LLParser::ParseOptionalAttrs(AttrBuilder &B, unsigned AttrKind) {
- LocTy AttrLoc = Lex.getLoc();
+/// ParseOptionalFuncAttrs - Parse a potentially empty list of function attributes.
+bool LLParser::ParseOptionalFuncAttrs(AttrBuilder &B) {
bool HaveError = false;
B.clear();
@@ -926,42 +923,70 @@ bool LLParser::ParseOptionalAttrs(AttrBuilder &B, unsigned AttrKind) {
switch (Token) {
default: // End of attributes.
return HaveError;
- case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break;
- case lltok::kw_signext: B.addAttribute(Attributes::SExt); break;
- case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break;
- case lltok::kw_sret: B.addAttribute(Attributes::StructRet); break;
- case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break;
- case lltok::kw_nocapture: B.addAttribute(Attributes::NoCapture); break;
- case lltok::kw_byval: B.addAttribute(Attributes::ByVal); break;
- case lltok::kw_nest: B.addAttribute(Attributes::Nest); break;
-
+ case lltok::kw_alignstack: {
+ unsigned Alignment;
+ if (ParseOptionalStackAlignment(Alignment))
+ return true;
+ B.addStackAlignmentAttr(Alignment);
+ continue;
+ }
+ case lltok::kw_align: {
+ // As a hack, we allow "align 2" on functions as a synonym for "alignstack
+ // 2".
+ unsigned Alignment;
+ if (ParseOptionalAlignment(Alignment))
+ return true;
+ B.addAlignmentAttr(Alignment);
+ continue;
+ }
+ case lltok::kw_address_safety: B.addAttribute(Attributes::AddressSafety); break;
+ case lltok::kw_alwaysinline: B.addAttribute(Attributes::AlwaysInline); break;
+ case lltok::kw_inlinehint: B.addAttribute(Attributes::InlineHint); break;
+ case lltok::kw_minsize: B.addAttribute(Attributes::MinSize); break;
+ case lltok::kw_naked: B.addAttribute(Attributes::Naked); break;
+ case lltok::kw_noinline: B.addAttribute(Attributes::NoInline); break;
+ case lltok::kw_nonlazybind: B.addAttribute(Attributes::NonLazyBind); break;
+ case lltok::kw_noredzone: B.addAttribute(Attributes::NoRedZone); break;
+ case lltok::kw_noimplicitfloat: B.addAttribute(Attributes::NoImplicitFloat); break;
case lltok::kw_noreturn: B.addAttribute(Attributes::NoReturn); break;
case lltok::kw_nounwind: B.addAttribute(Attributes::NoUnwind); break;
- case lltok::kw_uwtable: B.addAttribute(Attributes::UWTable); break;
- case lltok::kw_returns_twice: B.addAttribute(Attributes::ReturnsTwice); break;
- case lltok::kw_noinline: B.addAttribute(Attributes::NoInline); break;
+ case lltok::kw_optsize: B.addAttribute(Attributes::OptimizeForSize); break;
case lltok::kw_readnone: B.addAttribute(Attributes::ReadNone); break;
case lltok::kw_readonly: B.addAttribute(Attributes::ReadOnly); break;
- case lltok::kw_inlinehint: B.addAttribute(Attributes::InlineHint); break;
- case lltok::kw_alwaysinline: B.addAttribute(Attributes::AlwaysInline); break;
- case lltok::kw_optsize: B.addAttribute(Attributes::OptimizeForSize); break;
+ case lltok::kw_returns_twice: B.addAttribute(Attributes::ReturnsTwice); break;
case lltok::kw_ssp: B.addAttribute(Attributes::StackProtect); break;
case lltok::kw_sspreq: B.addAttribute(Attributes::StackProtectReq); break;
- case lltok::kw_noredzone: B.addAttribute(Attributes::NoRedZone); break;
- case lltok::kw_noimplicitfloat: B.addAttribute(Attributes::NoImplicitFloat); break;
- case lltok::kw_naked: B.addAttribute(Attributes::Naked); break;
- case lltok::kw_nonlazybind: B.addAttribute(Attributes::NonLazyBind); break;
- case lltok::kw_address_safety: B.addAttribute(Attributes::AddressSafety); break;
- case lltok::kw_minsize: B.addAttribute(Attributes::MinSize); break;
+ case lltok::kw_uwtable: B.addAttribute(Attributes::UWTable); break;
- case lltok::kw_alignstack: {
- unsigned Alignment;
- if (ParseOptionalStackAlignment(Alignment))
- return true;
- B.addStackAlignmentAttr(Alignment);
- continue;
+ // Error handling.
+ case lltok::kw_zeroext:
+ case lltok::kw_signext:
+ case lltok::kw_inreg:
+ HaveError |= Error(Lex.getLoc(), "invalid use of attribute on a function");
+ break;
+ case lltok::kw_sret: case lltok::kw_noalias:
+ case lltok::kw_nocapture: case lltok::kw_byval:
+ case lltok::kw_nest:
+ HaveError |=
+ Error(Lex.getLoc(), "invalid use of parameter-only attribute on a function");
+ break;
}
+ Lex.Lex();
+ }
+}
+
+/// ParseOptionalParamAttrs - Parse a potentially empty list of parameter attributes.
+bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
+ bool HaveError = false;
+
+ B.clear();
+
+ while (1) {
+ lltok::Kind Token = Lex.getKind();
+ switch (Token) {
+ default: // End of attributes.
+ return HaveError;
case lltok::kw_align: {
unsigned Alignment;
if (ParseOptionalAlignment(Alignment))
@@ -969,51 +994,65 @@ bool LLParser::ParseOptionalAttrs(AttrBuilder &B, unsigned AttrKind) {
B.addAlignmentAttr(Alignment);
continue;
}
+ case lltok::kw_byval: B.addAttribute(Attributes::ByVal); break;
+ case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break;
+ case lltok::kw_nest: B.addAttribute(Attributes::Nest); break;
+ case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break;
+ case lltok::kw_nocapture: B.addAttribute(Attributes::NoCapture); break;
+ case lltok::kw_signext: B.addAttribute(Attributes::SExt); break;
+ case lltok::kw_sret: B.addAttribute(Attributes::StructRet); break;
+ case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break;
+ case lltok::kw_noreturn: case lltok::kw_nounwind:
+ case lltok::kw_uwtable: case lltok::kw_returns_twice:
+ case lltok::kw_noinline: case lltok::kw_readnone:
+ case lltok::kw_readonly: case lltok::kw_inlinehint:
+ case lltok::kw_alwaysinline: case lltok::kw_optsize:
+ case lltok::kw_ssp: case lltok::kw_sspreq:
+ case lltok::kw_noredzone: case lltok::kw_noimplicitfloat:
+ case lltok::kw_naked: case lltok::kw_nonlazybind:
+ case lltok::kw_address_safety: case lltok::kw_minsize:
+ case lltok::kw_alignstack:
+ HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
+ break;
}
- // Perform some error checking.
+ Lex.Lex();
+ }
+}
+
+/// ParseOptionalReturnAttrs - Parse a potentially empty list of return attributes.
+bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
+ bool HaveError = false;
+
+ B.clear();
+
+ while (1) {
+ lltok::Kind Token = Lex.getKind();
switch (Token) {
- default:
- if (AttrKind == 2)
- HaveError |= Error(AttrLoc, "invalid use of attribute on a function");
- break;
- case lltok::kw_align:
- // As a hack, we allow "align 2" on functions as a synonym for
- // "alignstack 2".
- break;
+ default: // End of attributes.
+ return HaveError;
+ case lltok::kw_inreg: B.addAttribute(Attributes::InReg); break;
+ case lltok::kw_noalias: B.addAttribute(Attributes::NoAlias); break;
+ case lltok::kw_signext: B.addAttribute(Attributes::SExt); break;
+ case lltok::kw_zeroext: B.addAttribute(Attributes::ZExt); break;
- // Parameter Only:
- case lltok::kw_sret:
- case lltok::kw_nocapture:
- case lltok::kw_byval:
- case lltok::kw_nest:
- if (AttrKind != 0)
- HaveError |= Error(AttrLoc, "invalid use of parameter-only attribute");
+ // Error handling.
+ case lltok::kw_sret: case lltok::kw_nocapture:
+ case lltok::kw_byval: case lltok::kw_nest:
+ HaveError |= Error(Lex.getLoc(), "invalid use of parameter-only attribute");
break;
-
- // Function Only:
- case lltok::kw_noreturn:
- case lltok::kw_nounwind:
- case lltok::kw_readnone:
- case lltok::kw_readonly:
- case lltok::kw_noinline:
- case lltok::kw_alwaysinline:
- case lltok::kw_optsize:
- case lltok::kw_ssp:
- case lltok::kw_sspreq:
- case lltok::kw_noredzone:
- case lltok::kw_noimplicitfloat:
- case lltok::kw_naked:
- case lltok::kw_inlinehint:
- case lltok::kw_alignstack:
- case lltok::kw_uwtable:
- case lltok::kw_nonlazybind:
- case lltok::kw_returns_twice:
- case lltok::kw_address_safety:
- case lltok::kw_minsize:
- if (AttrKind != 2)
- HaveError |= Error(AttrLoc, "invalid use of function-only attribute");
+ case lltok::kw_noreturn: case lltok::kw_nounwind:
+ case lltok::kw_uwtable: case lltok::kw_returns_twice:
+ case lltok::kw_noinline: case lltok::kw_readnone:
+ case lltok::kw_readonly: case lltok::kw_inlinehint:
+ case lltok::kw_alwaysinline: case lltok::kw_optsize:
+ case lltok::kw_ssp: case lltok::kw_sspreq:
+ case lltok::kw_noredzone: case lltok::kw_noimplicitfloat:
+ case lltok::kw_naked: case lltok::kw_nonlazybind:
+ case lltok::kw_address_safety: case lltok::kw_minsize:
+ case lltok::kw_alignstack: case lltok::kw_align:
+ HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
break;
}
@@ -1444,7 +1483,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
return true;
// Otherwise, handle normal operands.
- if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS))
+ if (ParseOptionalParamAttrs(ArgAttrs) || ParseValue(ArgTy, V, PFS))
return true;
ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(V->getContext(),
ArgAttrs)));
@@ -1483,7 +1522,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
std::string Name;
if (ParseType(ArgTy) ||
- ParseOptionalAttrs(Attrs, 0)) return true;
+ ParseOptionalParamAttrs(Attrs)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
@@ -1509,7 +1548,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ParseType(ArgTy) || ParseOptionalParamAttrs(Attrs)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
@@ -2686,7 +2725,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
@@ -2753,7 +2792,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
&UnnamedAddrLoc) ||
- ParseOptionalAttrs(FuncAttrs, 2) ||
+ ParseOptionalFuncAttrs(FuncAttrs) ||
(EatIfPresent(lltok::kw_section) &&
ParseStringConstant(Section)) ||
ParseOptionalAlignment(Alignment) ||
@@ -3281,11 +3320,11 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
BasicBlock *NormalBB, *UnwindBB;
if (ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseOptionalAttrs(FnAttrs, 2) ||
+ ParseOptionalFuncAttrs(FnAttrs) ||
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
@@ -3687,11 +3726,11 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
ParseOptionalCallingConv(CC) ||
- ParseOptionalAttrs(RetAttrs, 1) ||
+ ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
ParseValID(CalleeID) ||
ParseParameterList(ArgList, PFS) ||
- ParseOptionalAttrs(FnAttrs, 2))
+ ParseOptionalFuncAttrs(FnAttrs))
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 b4cc12b28b..0039164cc7 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -191,7 +191,9 @@ namespace llvm {
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
- bool ParseOptionalAttrs(AttrBuilder &Attrs, unsigned AttrKind);
+ bool ParseOptionalFuncAttrs(AttrBuilder &B);
+ bool ParseOptionalParamAttrs(AttrBuilder &B);
+ bool ParseOptionalReturnAttrs(AttrBuilder &B);
bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);
bool ParseOptionalLinkage(unsigned &Linkage) {
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);