@@ -106,6 +106,78 @@ mlir::MLIRContext &CIRGenTypes::getMLIRContext() const {
106
106
return *Builder.getContext ();
107
107
}
108
108
109
+ mlir::Type CIRGenTypes::ConvertFunctionTypeInternal (QualType QFT) {
110
+ assert (QFT.isCanonical ());
111
+ const Type *Ty = QFT.getTypePtr ();
112
+ const FunctionType *FT = cast<FunctionType>(QFT.getTypePtr ());
113
+ // First, check whether we can build the full fucntion type. If the function
114
+ // type depends on an incomplete type (e.g. a struct or enum), we cannot lower
115
+ // the function type.
116
+ assert (isFuncTypeConvertible (FT) && " NYI" );
117
+
118
+ // While we're converting the parameter types for a function, we don't want to
119
+ // recursively convert any pointed-to structs. Converting directly-used
120
+ // structs is ok though.
121
+ assert (RecordsBeingLaidOut.insert (Ty).second && " NYI" );
122
+
123
+ // The function type can be built; call the appropriate routines to build it
124
+ const CIRGenFunctionInfo *FI;
125
+ const auto *FPT = dyn_cast<FunctionProtoType>(FT);
126
+ assert (FPT && " FunctionNonPrototype NIY" );
127
+ FI = &arrangeFreeFunctionType (
128
+ CanQual<FunctionProtoType>::CreateUnsafe (QualType (FPT, 0 )));
129
+
130
+ mlir::Type ResultType = nullptr ;
131
+ // If there is something higher level prodding our CIRGenFunctionInfo, then
132
+ // don't recurse into it again.
133
+ assert (!FunctionsBeingProcessed.count (FI) && " NYI" );
134
+
135
+ // Otherwise, we're good to go, go ahead and convert it.
136
+ ResultType = GetFunctionType (*FI);
137
+
138
+ RecordsBeingLaidOut.erase (Ty);
139
+
140
+ assert (!SkippedLayout && " Shouldn't have skipped anything yet" );
141
+
142
+ assert (RecordsBeingLaidOut.empty () && " Deferral NYI" );
143
+ assert (DeferredRecords.empty () && " Deferral NYI" );
144
+
145
+ return ResultType;
146
+ }
147
+
148
+ // / isFuncParamTypeConvertible - Return true if the specified type in a function
149
+ // / parameter or result position can be converted to a CIR type at this point.
150
+ // / This boils down to being whether it is complete, as well as whether we've
151
+ // / temporarily deferred expanding the type because we're in a recursive
152
+ // / context.
153
+ bool CIRGenTypes::isFuncParamTypeConvertible (clang::QualType Ty) {
154
+ // Some ABIs cannot have their member pointers represented in LLVM IR unless
155
+ // certain circumstances have been reached.
156
+ assert (!Ty->getAs <MemberPointerType>() && " NYI" );
157
+
158
+ // If this isn't a tagged type, we can convert it!
159
+ auto *TT = Ty->getAs <TagType>();
160
+ assert (!TT && " Only non-TagTypes implemented atm." );
161
+ return true ;
162
+ }
163
+
164
+ // / Code to verify a given function type is complete, i.e. the return type and
165
+ // / all of the parameter types are complete. Also check to see if we are in a
166
+ // / RS_StructPointer context, and if so whether any struct types have been
167
+ // / pended. If so, we don't want to ask the ABI lowering code to handle a type
168
+ // / that cannot be converted to a CIR type.
169
+ bool CIRGenTypes::isFuncTypeConvertible (const FunctionType *FT) {
170
+ if (!isFuncParamTypeConvertible (FT->getReturnType ()))
171
+ return false ;
172
+
173
+ if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
174
+ for (unsigned i = 0 , e = FPT->getNumParams (); i != e; i++)
175
+ if (!isFuncParamTypeConvertible (FPT->getParamType (i)))
176
+ return false ;
177
+
178
+ return true ;
179
+ }
180
+
109
181
// / ConvertType - Convert the specified type to its MLIR form.
110
182
mlir::Type CIRGenTypes::ConvertType (QualType T) {
111
183
T = Context.getCanonicalType (T);
@@ -376,7 +448,7 @@ mlir::Type CIRGenTypes::ConvertType(QualType T) {
376
448
}
377
449
case Type::FunctionNoProto:
378
450
case Type::FunctionProto:
379
- assert ( 0 && " not implemented " );
451
+ ResultType = ConvertFunctionTypeInternal (T );
380
452
break ;
381
453
case Type::ObjCObject:
382
454
assert (0 && " not implemented" );
0 commit comments