@@ -202,6 +202,102 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd,
202202 curCGF = nullptr ;
203203}
204204
205+ mlir::Operation *CIRGenModule::getGlobalValue (StringRef name) {
206+ return mlir::SymbolTable::lookupSymbolIn (theModule, name);
207+ }
208+
209+ // / If the specified mangled name is not in the module,
210+ // / create and return an mlir GlobalOp with the specified type (TODO(cir):
211+ // / address space).
212+ // /
213+ // / TODO(cir):
214+ // / 1. If there is something in the module with the specified name, return
215+ // / it potentially bitcasted to the right type.
216+ // /
217+ // / 2. If \p d is non-null, it specifies a decl that correspond to this. This
218+ // / is used to set the attributes on the global when it is first created.
219+ // /
220+ // / 3. If \p isForDefinition is true, it is guaranteed that an actual global
221+ // / with type \p ty will be returned, not conversion of a variable with the same
222+ // / mangled name but some other type.
223+ cir::GlobalOp
224+ CIRGenModule::getOrCreateCIRGlobal (StringRef mangledName, mlir::Type ty,
225+ LangAS langAS, const VarDecl *d,
226+ ForDefinition_t isForDefinition) {
227+ // Lookup the entry, lazily creating it if necessary.
228+ cir::GlobalOp entry;
229+ if (mlir::Operation *v = getGlobalValue (mangledName)) {
230+ if (!isa<cir::GlobalOp>(v))
231+ errorNYI (d->getSourceRange (), " global with non-GlobalOp type" );
232+ entry = cast<cir::GlobalOp>(v);
233+ }
234+
235+ if (entry) {
236+ assert (!cir::MissingFeatures::addressSpace ());
237+ assert (!cir::MissingFeatures::opGlobalWeakRef ());
238+
239+ assert (!cir::MissingFeatures::setDLLStorageClass ());
240+ assert (!cir::MissingFeatures::openMP ());
241+
242+ if (entry.getSymType () == ty)
243+ return entry;
244+
245+ // If there are two attempts to define the same mangled name, issue an
246+ // error.
247+ //
248+ // TODO(cir): look at mlir::GlobalValue::isDeclaration for all aspects of
249+ // recognizing the global as a declaration, for now only check if
250+ // initializer is present.
251+ if (isForDefinition && !entry.isDeclaration ()) {
252+ errorNYI (d->getSourceRange (), " global with conflicting type" );
253+ }
254+
255+ // Address space check removed because it is unnecessary because CIR records
256+ // address space info in types.
257+
258+ // (If global is requested for a definition, we always need to create a new
259+ // global, not just return a bitcast.)
260+ if (!isForDefinition)
261+ return entry;
262+ }
263+
264+ errorNYI (d->getSourceRange (), " reference of undeclared global" );
265+ }
266+
267+ cir::GlobalOp
268+ CIRGenModule::getOrCreateCIRGlobal (const VarDecl *d, mlir::Type ty,
269+ ForDefinition_t isForDefinition) {
270+ assert (d->hasGlobalStorage () && " Not a global variable" );
271+ QualType astTy = d->getType ();
272+ if (!ty)
273+ ty = getTypes ().convertTypeForMem (astTy);
274+
275+ assert (!cir::MissingFeatures::mangledNames ());
276+ return getOrCreateCIRGlobal (d->getIdentifier ()->getName (), ty,
277+ astTy.getAddressSpace (), d, isForDefinition);
278+ }
279+
280+ // / Return the mlir::Value for the address of the given global variable. If
281+ // / \p ty is non-null and if the global doesn't exist, then it will be created
282+ // / with the specified type instead of whatever the normal requested type would
283+ // / be. If \p isForDefinition is true, it is guaranteed that an actual global
284+ // / with type \p ty will be returned, not conversion of a variable with the same
285+ // / mangled name but some other type.
286+ mlir::Value CIRGenModule::getAddrOfGlobalVar (const VarDecl *d, mlir::Type ty,
287+ ForDefinition_t isForDefinition) {
288+ assert (d->hasGlobalStorage () && " Not a global variable" );
289+ QualType astTy = d->getType ();
290+ if (!ty)
291+ ty = getTypes ().convertTypeForMem (astTy);
292+
293+ assert (!cir::MissingFeatures::opGlobalThreadLocal ());
294+
295+ cir::GlobalOp g = getOrCreateCIRGlobal (d, ty, isForDefinition);
296+ mlir::Type ptrTy = builder.getPointerTo (g.getSymType ());
297+ return builder.create <cir::GetGlobalOp>(getLoc (d->getSourceRange ()), ptrTy,
298+ g.getSymName ());
299+ }
300+
205301void CIRGenModule::emitGlobalVarDefinition (const clang::VarDecl *vd,
206302 bool isTentative) {
207303 const QualType astTy = vd->getType ();
@@ -507,6 +603,7 @@ cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd,
507603 funcType = convertType (fd->getType ());
508604 }
509605
606+ assert (!cir::MissingFeatures::mangledNames ());
510607 cir::FuncOp func = getOrCreateCIRFunction (
511608 cast<NamedDecl>(gd.getDecl ())->getIdentifier ()->getName (), funcType, gd,
512609 forVTable, dontDefer, /* isThunk=*/ false , isForDefinition);
0 commit comments