1818using namespace clang ;
1919using namespace clang ::CIRGen;
2020
21- CIRGenFunctionInfo *CIRGenFunctionInfo::create () {
22- // For now we just create an empty CIRGenFunctionInfo.
23- CIRGenFunctionInfo *fi = new CIRGenFunctionInfo ();
21+ CIRGenFunctionInfo *CIRGenFunctionInfo::create (CanQualType resultType) {
22+ void *buffer = operator new (totalSizeToAlloc<ArgInfo>(1 ));
23+
24+ CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo ();
25+ fi->getArgsBuffer ()[0 ].type = resultType;
26+
2427 return fi;
2528}
2629
@@ -29,13 +32,29 @@ CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
2932 return *this ;
3033}
3134
32- static const CIRGenFunctionInfo &arrangeFreeFunctionLikeCall (CIRGenTypes &cgt) {
35+ static const CIRGenFunctionInfo &
36+ arrangeFreeFunctionLikeCall (CIRGenTypes &cgt, CIRGenModule &cgm,
37+ const FunctionType *fnType) {
38+ if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
39+ if (proto->isVariadic ())
40+ cgm.errorNYI (" call to variadic function" );
41+ if (proto->hasExtParameterInfos ())
42+ cgm.errorNYI (" call to functions with extra parameter info" );
43+ } else if (cgm.getTargetCIRGenInfo ().isNoProtoCallVariadic (
44+ cast<FunctionNoProtoType>(fnType)))
45+ cgm.errorNYI (" call to function without a prototype" );
46+
3347 assert (!cir::MissingFeatures::opCallArgs ());
34- return cgt.arrangeCIRFunctionInfo ();
48+
49+ CanQualType retType = fnType->getReturnType ()
50+ ->getCanonicalTypeUnqualified ()
51+ .getUnqualifiedType ();
52+ return cgt.arrangeCIRFunctionInfo (retType);
3553}
3654
37- const CIRGenFunctionInfo &CIRGenTypes::arrangeFreeFunctionCall () {
38- return arrangeFreeFunctionLikeCall (*this );
55+ const CIRGenFunctionInfo &
56+ CIRGenTypes::arrangeFreeFunctionCall (const FunctionType *fnType) {
57+ return arrangeFreeFunctionLikeCall (*this , cgm, fnType);
3958}
4059
4160static cir::CIRCallOpInterface emitCallLikeOp (CIRGenFunction &cgf,
@@ -54,8 +73,12 @@ static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf,
5473
5574RValue CIRGenFunction::emitCall (const CIRGenFunctionInfo &funcInfo,
5675 const CIRGenCallee &callee,
76+ ReturnValueSlot returnValue,
5777 cir::CIRCallOpInterface *callOp,
5878 mlir::Location loc) {
79+ QualType retTy = funcInfo.getReturnType ();
80+ const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo ();
81+
5982 assert (!cir::MissingFeatures::opCallArgs ());
6083 assert (!cir::MissingFeatures::emitLifetimeMarkers ());
6184
@@ -87,9 +110,45 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
87110 assert (!cir::MissingFeatures::opCallMustTail ());
88111 assert (!cir::MissingFeatures::opCallReturn ());
89112
90- // For now we just return nothing because we don't have support for return
91- // values yet.
92- RValue ret = RValue::get (nullptr );
113+ RValue ret;
114+ switch (retInfo.getKind ()) {
115+ case cir::ABIArgInfo::Direct: {
116+ mlir::Type retCIRTy = convertType (retTy);
117+ if (retInfo.getCoerceToType () == retCIRTy &&
118+ retInfo.getDirectOffset () == 0 ) {
119+ switch (getEvaluationKind (retTy)) {
120+ case cir::TEK_Scalar: {
121+ mlir::ResultRange results = theCall->getOpResults ();
122+ assert (results.size () == 1 && " unexpected number of returns" );
123+
124+ // If the argument doesn't match, perform a bitcast to coerce it. This
125+ // can happen due to trivial type mismatches.
126+ if (results[0 ].getType () != retCIRTy)
127+ cgm.errorNYI (loc, " bitcast on function return value" );
128+
129+ mlir::Region *region = builder.getBlock ()->getParent ();
130+ if (region != theCall->getParentRegion ())
131+ cgm.errorNYI (loc, " function calls with cleanup" );
132+
133+ return RValue::get (results[0 ]);
134+ }
135+ default :
136+ cgm.errorNYI (loc,
137+ " unsupported evaluation kind of function call result" );
138+ }
139+ } else
140+ cgm.errorNYI (loc, " unsupported function call form" );
141+
142+ break ;
143+ }
144+ case cir::ABIArgInfo::Ignore:
145+ // If we are ignoring an argument that had a result, make sure to construct
146+ // the appropriate return value for our caller.
147+ ret = getUndefRValue (retTy);
148+ break ;
149+ default :
150+ cgm.errorNYI (loc, " unsupported return value information" );
151+ }
93152
94153 return ret;
95154}
0 commit comments