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