@@ -647,13 +647,19 @@ fir::GlobalOp Fortran::lower::defineGlobal(
647647
648648// / Return linkage attribute for \p var.
649649static mlir::StringAttr
650- getLinkageAttribute (fir::FirOpBuilder &builder ,
650+ getLinkageAttribute (Fortran::lower::AbstractConverter &converter ,
651651 const Fortran::lower::pft::Variable &var) {
652+ fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
652653 // Runtime type info for a same derived type is identical in each compilation
653654 // unit. It desired to avoid having to link against module that only define a
654655 // type. Therefore the runtime type info is generated everywhere it is needed
655- // with `linkonce_odr` LLVM linkage.
656- if (var.isRuntimeTypeInfoData ())
656+ // with `linkonce_odr` LLVM linkage (unless the skipExternalRttiDefinition
657+ // option is set, in which case one will need to link against objects of
658+ // modules defining types). Builtin objects rtti is always generated because
659+ // the builtin module is currently not compiled or part of the runtime.
660+ if (var.isRuntimeTypeInfoData () &&
661+ (!converter.getLoweringOptions ().getSkipExternalRttiDefinition () ||
662+ Fortran::semantics::IsFromBuiltinModule (var.getSymbol ())))
657663 return builder.createLinkOnceODRLinkage ();
658664 if (var.isModuleOrSubmoduleVariable ())
659665 return {}; // external linkage
@@ -673,7 +679,7 @@ static void instantiateGlobal(Fortran::lower::AbstractConverter &converter,
673679 fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
674680 std::string globalName = converter.mangleName (sym);
675681 mlir::Location loc = genLocation (converter, sym);
676- mlir::StringAttr linkage = getLinkageAttribute (builder , var);
682+ mlir::StringAttr linkage = getLinkageAttribute (converter , var);
677683 fir::GlobalOp global;
678684 if (var.isModuleOrSubmoduleVariable ()) {
679685 // A non-intrinsic module global is defined when lowering the module.
@@ -1265,7 +1271,7 @@ instantiateAggregateStore(Fortran::lower::AbstractConverter &converter,
12651271 if (var.isGlobal ()) {
12661272 fir::GlobalOp global;
12671273 auto &aggregate = var.getAggregateStore ();
1268- mlir::StringAttr linkage = getLinkageAttribute (builder , var);
1274+ mlir::StringAttr linkage = getLinkageAttribute (converter , var);
12691275 if (var.isModuleOrSubmoduleVariable ()) {
12701276 // A module global was or will be defined when lowering the module. Emit
12711277 // only a declaration if the global does not exist at that point.
@@ -2470,8 +2476,7 @@ void Fortran::lower::defineModuleVariable(
24702476 AbstractConverter &converter, const Fortran::lower::pft::Variable &var) {
24712477 // Use empty linkage for module variables, which makes them available
24722478 // for use in another unit.
2473- mlir::StringAttr linkage =
2474- getLinkageAttribute (converter.getFirOpBuilder (), var);
2479+ mlir::StringAttr linkage = getLinkageAttribute (converter, var);
24752480 if (!var.isGlobal ())
24762481 fir::emitFatalError (converter.getCurrentLocation (),
24772482 " attempting to lower module variable as local" );
@@ -2606,10 +2611,9 @@ void Fortran::lower::createIntrinsicModuleGlobal(
26062611void Fortran::lower::createRuntimeTypeInfoGlobal (
26072612 Fortran::lower::AbstractConverter &converter,
26082613 const Fortran::semantics::Symbol &typeInfoSym) {
2609- fir::FirOpBuilder &builder = converter.getFirOpBuilder ();
26102614 std::string globalName = converter.mangleName (typeInfoSym);
26112615 auto var = Fortran::lower::pft::Variable (typeInfoSym, /* global=*/ true );
2612- mlir::StringAttr linkage = getLinkageAttribute (builder , var);
2616+ mlir::StringAttr linkage = getLinkageAttribute (converter , var);
26132617 defineGlobal (converter, var, globalName, linkage);
26142618}
26152619
0 commit comments