diff options
Diffstat (limited to 'flang/lib/Lower/CallInterface.cpp')
-rw-r--r-- | flang/lib/Lower/CallInterface.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/flang/lib/Lower/CallInterface.cpp b/flang/lib/Lower/CallInterface.cpp index 05a0c10..2d4d17a 100644 --- a/flang/lib/Lower/CallInterface.cpp +++ b/flang/lib/Lower/CallInterface.cpp @@ -575,13 +575,6 @@ mlir::Value Fortran::lower::CalleeInterface::getHostAssociatedTuple() const { return converter.hostAssocTupleValue(); } -void Fortran::lower::CalleeInterface::setFuncAttrs( - mlir::func::FuncOp func) const { - if (funit.parentHasHostAssoc()) - func->setAttr(fir::getInternalProcedureAttrName(), - mlir::UnitAttr::get(func->getContext())); -} - //===----------------------------------------------------------------------===// // CallInterface implementation: this part is common to both caller and callee. //===----------------------------------------------------------------------===// @@ -589,6 +582,34 @@ void Fortran::lower::CalleeInterface::setFuncAttrs( static void addSymbolAttribute(mlir::func::FuncOp func, const Fortran::semantics::Symbol &sym, mlir::MLIRContext &mlirContext) { + const Fortran::semantics::Symbol &ultimate = sym.GetUltimate(); + // The link between an internal procedure and its host procedure is lost + // in FIR if the host is BIND(C) since the internal mangling will not + // allow retrieving the host bind(C) name, and therefore func.func symbol. + // Preserve it as an attribute so that this can be later retrieved. + if (Fortran::semantics::ClassifyProcedure(ultimate) == + Fortran::semantics::ProcedureDefinitionClass::Internal) { + if (ultimate.owner().kind() == + Fortran::semantics::Scope::Kind::Subprogram) { + if (const Fortran::semantics::Symbol *hostProcedure = + ultimate.owner().symbol()) { + std::string hostName = Fortran::lower::mangle::mangleName( + *hostProcedure, /*keepExternalInScope=*/true); + func->setAttr( + fir::getHostSymbolAttrName(), + mlir::SymbolRefAttr::get( + &mlirContext, mlir::StringAttr::get(&mlirContext, hostName))); + } + } else if (ultimate.owner().kind() == + Fortran::semantics::Scope::Kind::MainProgram) { + func->setAttr(fir::getHostSymbolAttrName(), + mlir::SymbolRefAttr::get( + &mlirContext, + mlir::StringAttr::get( + &mlirContext, fir::NameUniquer::doProgramEntry()))); + } + } + // Only add this on bind(C) functions for which the symbol is not reflected in // the current context. if (!Fortran::semantics::IsBindCProcedure(sym)) @@ -686,7 +707,6 @@ void Fortran::lower::CallInterface<T>::declare() { for (const auto &placeHolder : llvm::enumerate(inputs)) if (!placeHolder.value().attributes.empty()) func.setArgAttrs(placeHolder.index(), placeHolder.value().attributes); - side().setFuncAttrs(func); setCUDAAttributes(func, side().getProcedureSymbol(), characteristic); } @@ -1599,10 +1619,6 @@ public: return proc; } - /// Set internal procedure attribute on MLIR function. Internal procedure - /// are defined in the current file and will not go through SignatureBuilder. - void setFuncAttrs(mlir::func::FuncOp) const {} - /// This is not the description of an indirect call. static constexpr bool isIndirectCall() { return false; } |