From e01b81be33ebbc3e087d758341de0c2ba5d44135 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 4 Dec 2012 23:40:58 +0000 Subject: [PATCH] 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 --- lib/AsmParser/LLParser.cpp | 199 +++++++++++++++++++++++++++------------------ lib/AsmParser/LLParser.h | 4 +- 2 files changed, 122 insertions(+), 81 deletions(-) diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index c0557727c3c..e854ddb05e8 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 &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 &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 &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 b4cc12b28b0..0039164cc7c 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); -- 2.11.0