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