@@ -157,6 +157,7 @@ template <typename Ty> struct EnumTraits {};
157157 }
158158
159159REGISTER_ENUM_TYPE (GlobalLinkageKind);
160+ REGISTER_ENUM_TYPE (CallingConv);
160161REGISTER_ENUM_TYPE_WITH_NS (sob, SignedOverflowBehavior);
161162} // namespace
162163
@@ -176,6 +177,20 @@ static RetTy parseOptionalCIRKeyword(AsmParser &parser, EnumTy defaultValue) {
176177 return static_cast <RetTy>(index);
177178}
178179
180+ // / Parse an enum from the keyword, return failure if the keyword is not found.
181+ template <typename EnumTy, typename RetTy = EnumTy>
182+ static ParseResult parseCIRKeyword (AsmParser &parser, RetTy &result) {
183+ SmallVector<StringRef, 10 > names;
184+ for (unsigned i = 0 , e = EnumTraits<EnumTy>::getMaxEnumVal (); i <= e; ++i)
185+ names.push_back (EnumTraits<EnumTy>::stringify (static_cast <EnumTy>(i)));
186+
187+ int index = parseOptionalKeywordAlternative (parser, names);
188+ if (index == -1 )
189+ return failure ();
190+ result = static_cast <RetTy>(index);
191+ return success ();
192+ }
193+
179194// Check if a region's termination omission is valid and, if so, creates and
180195// inserts the omitted terminator into the region.
181196LogicalResult ensureRegionTerm (OpAsmParser &parser, Region ®ion,
@@ -1874,7 +1889,7 @@ static StringRef getLinkageAttrNameString() { return "linkage"; }
18741889
18751890void cir::FuncOp::build (OpBuilder &builder, OperationState &result,
18761891 StringRef name, cir::FuncType type,
1877- GlobalLinkageKind linkage,
1892+ GlobalLinkageKind linkage, CallingConv callingConv,
18781893 ArrayRef<NamedAttribute> attrs,
18791894 ArrayRef<DictionaryAttr> argAttrs) {
18801895 result.addRegion ();
@@ -1885,6 +1900,8 @@ void cir::FuncOp::build(OpBuilder &builder, OperationState &result,
18851900 result.addAttribute (
18861901 getLinkageAttrNameString (),
18871902 GlobalLinkageKindAttr::get (builder.getContext (), linkage));
1903+ result.addAttribute (getCallingConvAttrName (result.name ),
1904+ CallingConvAttr::get (builder.getContext (), callingConv));
18881905 result.attributes .append (attrs.begin (), attrs.end ());
18891906 if (argAttrs.empty ())
18901907 return ;
@@ -1991,6 +2008,20 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
19912008 hasAlias = true ;
19922009 }
19932010
2011+ // Default to C calling convention if no keyword is provided.
2012+ auto callConvNameAttr = getCallingConvAttrName (state.name );
2013+ CallingConv callConv = CallingConv::C;
2014+ if (parser.parseOptionalKeyword (" cc" ).succeeded ()) {
2015+ if (parser.parseLParen ().failed ())
2016+ return failure ();
2017+ if (parseCIRKeyword<CallingConv>(parser, callConv).failed ())
2018+ return parser.emitError (loc) << " unknown calling convention" ;
2019+ if (parser.parseRParen ().failed ())
2020+ return failure ();
2021+ }
2022+ state.addAttribute (callConvNameAttr,
2023+ CallingConvAttr::get (parser.getContext (), callConv));
2024+
19942025 auto parseGlobalDtorCtor =
19952026 [&](StringRef keyword,
19962027 llvm::function_ref<void (std::optional<int > prio)> createAttr)
@@ -2144,6 +2175,7 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
21442175 getGlobalDtorAttrName (),
21452176 getLambdaAttrName (),
21462177 getLinkageAttrName (),
2178+ getCallingConvAttrName (),
21472179 getNoProtoAttrName (),
21482180 getSymVisibilityAttrName (),
21492181 getArgAttrsAttrName (),
@@ -2157,6 +2189,12 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
21572189 p << " )" ;
21582190 }
21592191
2192+ if (getCallingConv () != CallingConv::C) {
2193+ p << " cc(" ;
2194+ p << stringifyCallingConv (getCallingConv ());
2195+ p << " )" ;
2196+ }
2197+
21602198 if (auto globalCtor = getGlobalCtorAttr ()) {
21612199 p << " global_ctor" ;
21622200 if (!globalCtor.isDefaultPriority ())
0 commit comments