aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Lower/CallInterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Lower/CallInterface.cpp')
-rw-r--r--flang/lib/Lower/CallInterface.cpp40
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; }