@@ -501,6 +501,34 @@ void CIRGenModule::setCommonAttributes(GlobalDecl GD, mlir::Operation *GV) {
501501 assert (!UnimplementedFeature::setCommonAttributes ());
502502}
503503
504+ // / Given the type of a previously-seen declaration and the type of a new
505+ // / declaration, determine whether the new declaration can re-declare the
506+ // / previous declaration.
507+ // /
508+ // / This typically requires that the given two types are identical. However
509+ // / there are some exceptions:
510+ // / - If the given two types are array types with identical element type,
511+ // / and PreviousTy has unknown array bound, this function returns true.
512+ static bool isValidRedeclarationType (mlir::Type PreviousTy, mlir::Type NowTy) {
513+ if (PreviousTy == NowTy)
514+ return true ;
515+
516+ if (isa<mlir::cir::ArrayType>(PreviousTy) &&
517+ isa<mlir::cir::ArrayType>(NowTy)) {
518+ auto PreviousArrayTy = cast<mlir::cir::ArrayType>(PreviousTy);
519+ auto NowArrayTy = cast<mlir::cir::ArrayType>(NowTy);
520+
521+ if (PreviousArrayTy.getEltType () != NowArrayTy.getEltType ())
522+ return false ;
523+
524+ // At this point PreviousTy and NowTy cannot have identical sizes because
525+ // this would make PreviousTy and NowTy identical.
526+ return PreviousArrayTy.getSize () == 0 ;
527+ }
528+
529+ return false ;
530+ }
531+
504532// / If the specified mangled name is not in the module,
505533// / create and return an mlir GlobalOp with the specified type (TODO(cir):
506534// / address space).
@@ -546,7 +574,7 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef MangledName, mlir::Type Ty,
546574 assert (0 && " not implemented" );
547575
548576 // TODO(cir): check TargetAS matches Entry address space
549- if (Entry.getSymType () == Ty &&
577+ if (isValidRedeclarationType ( Entry.getSymType (), Ty) &&
550578 !UnimplementedFeature::addressSpaceInGlobalVar ())
551579 return Entry;
552580
@@ -909,7 +937,7 @@ void CIRGenModule::buildGlobalVarDefinition(const clang::VarDecl *D,
909937 // from the type of the global (this happens with unions).
910938 if (!GV || GV.getSymType () != InitType) {
911939 // TODO(cir): this should include an address space check as well.
912- assert ( 0 && " not implemented " );
940+ setTypeOfGlobal (GV, InitType );
913941 }
914942
915943 maybeHandleStaticInExternC (D, GV);
@@ -1512,6 +1540,28 @@ mlir::cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator(
15121540 return mlir::cir::GlobalLinkageKind::ExternalLinkage;
15131541}
15141542
1543+ void CIRGenModule::setTypeOfGlobal (mlir::cir::GlobalOp &Op, mlir::Type Ty) {
1544+ if (Op.getSymType () == Ty)
1545+ return ;
1546+
1547+ Op.setSymType (Ty);
1548+ auto Sym = cast<mlir::SymbolOpInterface>(Op.getOperation ());
1549+
1550+ // Replace the types at every use site.
1551+ auto SymUses = Sym.getSymbolUses (theModule.getOperation ());
1552+ if (!SymUses.has_value ())
1553+ return ;
1554+
1555+ for (auto SymUse : *SymUses) {
1556+ auto UseOp = dyn_cast<mlir::cir::GetGlobalOp>(SymUse.getUser ());
1557+ assert (UseOp && " symbol users of GlobalOp is not a GetGlobalOp" );
1558+
1559+ auto UseOpResultValue = UseOp.getAddr ();
1560+ UseOpResultValue.setType (
1561+ mlir::cir::PointerType::get (builder.getContext (), Ty));
1562+ }
1563+ }
1564+
15151565// / This function is called when we implement a function with no prototype, e.g.
15161566// / "int foo() {}". If there are existing call uses of the old function in the
15171567// / module, this adjusts them to call the new function directly.
0 commit comments