From 8a03a67cb044f357db30576d9d0d80bc679c052c Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Fri, 15 Feb 2019 10:16:25 -0800 Subject: [PATCH] [flang] Change handling of BIND attributes Previously `BIND(C, NAME="...")` caused `bindName` to be set but not the `BIND` attribute. This made writing the `.mod` file easier, but it makes it hard to ask: does this symbol have a C binding. This change causes the `BIND` attribute to be set whenever there is `BIND(C)` in the source, regardless of whether there is a name or not. `bindName` is only set when the `BIND` attribute is also set. Original-commit: flang-compiler/f18@5a6706ffcbb96c4439a6af5a1f739ad4e7b8c00a Reviewed-on: https://github.com/flang-compiler/f18/pull/298 Tree-same-pre-rewrite: false --- flang/lib/semantics/mod-file.cc | 44 ++++++++++++++++++++---------------- flang/lib/semantics/resolve-names.cc | 8 +++---- flang/test/semantics/modfile16.f90 | 2 +- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/flang/lib/semantics/mod-file.cc b/flang/lib/semantics/mod-file.cc index 7023c96..cfd49d3 100644 --- a/flang/lib/semantics/mod-file.cc +++ b/flang/lib/semantics/mod-file.cc @@ -42,14 +42,14 @@ static void PutEntity(std::ostream &, const Symbol &); static void PutObjectEntity(std::ostream &, const Symbol &); static void PutProcEntity(std::ostream &, const Symbol &); static void PutPassName(std::ostream &, const std::optional &); -static void PutBindName(std::ostream &, const MaybeExpr &); static void PutTypeParam(std::ostream &, const Symbol &); static void PutEntity(std::ostream &, const Symbol &, std::function); static void PutInit(std::ostream &, const MaybeExpr &); static void PutInit(std::ostream &, const MaybeIntExpr &); static void PutBound(std::ostream &, const Bound &); -static std::ostream &PutAttrs( - std::ostream &, Attrs, std::string before = ","s, std::string after = ""s); +static std::ostream &PutAttrs(std::ostream &, Attrs, + const MaybeExpr & = std::nullopt, std::string before = ","s, + std::string after = ""s); static std::ostream &PutLower(std::ostream &, const Symbol &); static std::ostream &PutLower(std::ostream &, const DeclTypeSpec &); static std::ostream &PutLower(std::ostream &, const std::string &); @@ -151,7 +151,7 @@ void ModFileWriter::PutSymbol( PutLower(typeBindings << '(', x.symbol()) << ')'; } PutPassName(typeBindings, x.passName()); - PutAttrs(typeBindings, symbol.attrs(), ","s, ""s); + PutAttrs(typeBindings, symbol.attrs()); PutLower(typeBindings << "::", symbol); if (!deferred && x.symbol().name() != symbol.name()) { PutLower(typeBindings << "=>", x.symbol()); @@ -166,7 +166,7 @@ void ModFileWriter::PutSymbol( }, [&](const NamelistDetails &x) { PutLower(decls_ << "namelist/", symbol); - char sep = '/'; + char sep{'/'}; for (const auto *object : x.objects()) { PutLower(decls_ << sep, *object); sep = ','; @@ -194,7 +194,7 @@ void ModFileWriter::PutSymbol( void ModFileWriter::PutDerivedType(const Symbol &typeSymbol) { auto &details{typeSymbol.get()}; - PutAttrs(decls_ << "type", typeSymbol.attrs(), ","s, ""s); + PutAttrs(decls_ << "type", typeSymbol.attrs()); if (const DerivedTypeSpec * extends{typeSymbol.GetParentTypeSpec()}) { PutLower(decls_ << ",extends(", extends->typeSymbol()) << ')'; } @@ -231,7 +231,7 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) { if (isInterface) { os << "interface\n"; } - PutAttrs(os, attrs, ""s, " "s); + PutAttrs(os, attrs, std::nullopt, ""s, " "s); os << (details.isFunction() ? "function " : "subroutine "); PutLower(os, symbol) << '('; int n = 0; @@ -240,8 +240,7 @@ void ModFileWriter::PutSubprogram(const Symbol &symbol) { PutLower(os, *dummy); } os << ')'; - PutBindName(os, details.bindName()); - PutAttrs(os, bindAttrs, " "s, ""s); + PutAttrs(os, bindAttrs, details.bindName(), " "s, ""s); if (details.isFunction()) { const Symbol &result{details.result()}; if (result.name() != symbol.name()) { @@ -374,7 +373,6 @@ void PutObjectEntity(std::ostream &os, const Symbol &symbol) { auto *type{symbol.GetType()}; CHECK(type); PutLower(os, *type); - PutBindName(os, details.bindName()); }); PutShape(os, details.shape()); PutInit(os, details.init()); @@ -392,7 +390,6 @@ void PutProcEntity(std::ostream &os, const Symbol &symbol) { } os << ')'; PutPassName(os, details.passName()); - PutBindName(os, details.bindName()); }); } @@ -402,12 +399,6 @@ void PutPassName(std::ostream &os, const std::optional &passName) { } } -void PutBindName(std::ostream &os, const MaybeExpr &bindName) { - if (bindName) { - bindName->AsFortran(os << ",bind(c, name=") << ')'; - } -} - void PutTypeParam(std::ostream &os, const Symbol &symbol) { auto &details{symbol.get()}; PutEntity(os, symbol, [&]() { @@ -446,16 +437,29 @@ void PutBound(std::ostream &os, const Bound &x) { void PutEntity( std::ostream &os, const Symbol &symbol, std::function writeType) { writeType(); - PutAttrs(os, symbol.attrs()); + MaybeExpr bindName; + std::visit( + common::visitors{ + [&](const SubprogramDetails &x) { bindName = x.bindName(); }, + [&](const ObjectEntityDetails &x) { bindName = x.bindName(); }, + [&](const ProcEntityDetails &x) { bindName = x.bindName(); }, + [&](const auto &) {}, + }, + symbol.details()); + PutAttrs(os, symbol.attrs(), bindName); PutLower(os << "::", symbol); } // Put out each attribute to os, surrounded by `before` and `after` and // mapped to lower case. -std::ostream &PutAttrs( - std::ostream &os, Attrs attrs, std::string before, std::string after) { +std::ostream &PutAttrs(std::ostream &os, Attrs attrs, const MaybeExpr &bindName, + std::string before, std::string after) { attrs.set(Attr::PUBLIC, false); // no need to write PUBLIC attrs.set(Attr::EXTERNAL, false); // no need to write EXTERNAL + if (bindName) { + bindName->AsFortran(os << before << "bind(c, name=") << ')' << after; + attrs.set(Attr::BIND_C, false); + } for (std::size_t i{0}; i < Attr_enumSize; ++i) { Attr attr{static_cast(i)}; if (attrs.test(attr)) { diff --git a/flang/lib/semantics/resolve-names.cc b/flang/lib/semantics/resolve-names.cc index c9b326d..9b49838 100644 --- a/flang/lib/semantics/resolve-names.cc +++ b/flang/lib/semantics/resolve-names.cc @@ -1123,10 +1123,9 @@ bool AttrsVisitor::SetBindNameOn(Symbol &symbol) { void AttrsVisitor::Post(const parser::LanguageBindingSpec &x) { CHECK(attrs_); + attrs_->set(Attr::BIND_C); if (x.v) { bindName_ = EvaluateExpr(*x.v); - } else { - attrs_->set(Attr::BIND_C); } } bool AttrsVisitor::Pre(const parser::AccessSpec &x) { @@ -2559,8 +2558,9 @@ Symbol &DeclarationVisitor::HandleAttributeStmt( } else { symbol = &MakeSymbol(name, EntityDetails{}); } - if (attr != Attr::BIND_C || !SetBindNameOn(*symbol)) { - symbol->attrs().set(attr); + symbol->attrs().set(attr); + if (SetBindNameOn(*symbol)) { + CHECK(attr == Attr::BIND_C); } return *symbol; } diff --git a/flang/test/semantics/modfile16.f90 b/flang/test/semantics/modfile16.f90 index 0d8fbc6..a68f694 100644 --- a/flang/test/semantics/modfile16.f90 +++ b/flang/test/semantics/modfile16.f90 @@ -45,6 +45,6 @@ end ! procedure(real(4)),bind(c, name=1_"ee")::e ! procedure(real(4)),bind(c, name=1_"ff")::f !contains -! subroutine sub(),bind(c, name=1_"sub") +! subroutine sub() bind(c, name=1_"sub") ! end !end -- 2.7.4