@@ -501,6 +501,34 @@ void CIRGenModule::setCommonAttributes(GlobalDecl GD, mlir::Operation *GV) {
501
501
assert (!UnimplementedFeature::setCommonAttributes ());
502
502
}
503
503
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
+
504
532
// / If the specified mangled name is not in the module,
505
533
// / create and return an mlir GlobalOp with the specified type (TODO(cir):
506
534
// / address space).
@@ -546,7 +574,7 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef MangledName, mlir::Type Ty,
546
574
assert (0 && " not implemented" );
547
575
548
576
// TODO(cir): check TargetAS matches Entry address space
549
- if (Entry.getSymType () == Ty &&
577
+ if (isValidRedeclarationType ( Entry.getSymType (), Ty) &&
550
578
!UnimplementedFeature::addressSpaceInGlobalVar ())
551
579
return Entry;
552
580
@@ -909,7 +937,7 @@ void CIRGenModule::buildGlobalVarDefinition(const clang::VarDecl *D,
909
937
// from the type of the global (this happens with unions).
910
938
if (!GV || GV.getSymType () != InitType) {
911
939
// TODO(cir): this should include an address space check as well.
912
- assert ( 0 && " not implemented " );
940
+ setTypeOfGlobal (GV, InitType );
913
941
}
914
942
915
943
maybeHandleStaticInExternC (D, GV);
@@ -1512,6 +1540,28 @@ mlir::cir::GlobalLinkageKind CIRGenModule::getCIRLinkageForDeclarator(
1512
1540
return mlir::cir::GlobalLinkageKind::ExternalLinkage;
1513
1541
}
1514
1542
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
+
1515
1565
// / This function is called when we implement a function with no prototype, e.g.
1516
1566
// / "int foo() {}". If there are existing call uses of the old function in the
1517
1567
// / module, this adjusts them to call the new function directly.
0 commit comments