Skip to content

Commit aee625a

Browse files
committed
[flang] Add general symbol dependence collection utility
Replace HarvestSymbolsNeededFromOtherModules() in mod-file.cpp with a general utility function in Semantics. This new code will find other uses in further rework of hermetic module file generation as the means by which the necessary subsets of symbols in dependency modules are collected.
1 parent bc89380 commit aee625a

File tree

6 files changed

+406
-67
lines changed

6 files changed

+406
-67
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//===-- include/flang/Semantics/symbol-dependence.h -------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef FORTRAN_SEMANTICS_SYMBOL_DEPENDENCE_H_
10+
#define FORTRAN_SEMANTICS_SYMBOL_DEPENDENCE_H_
11+
12+
#include "flang/Semantics/symbol.h"
13+
14+
namespace Fortran::semantics {
15+
16+
// For a set or scope of symbols, computes the transitive closure of their
17+
// dependences due to their types, bounds, specific procedures, interfaces,
18+
// initialization, storage association, &c. Includes the original symbol
19+
// or members of the original set. Does not include dependences from
20+
// subprogram definitions, only their interfaces.
21+
enum DependenceCollectionFlags {
22+
NoDependenceCollectionFlags = 0,
23+
IncludeOriginalSymbols = 1 << 0,
24+
FollowUseAssociations = 1 << 1,
25+
IncludeSpecificsOfGenerics = 1 << 2,
26+
IncludeUsesOfGenerics = 1 << 3,
27+
NotJustForOneModule = 1 << 4,
28+
};
29+
30+
SymbolVector CollectAllDependences(const SymbolVector &,
31+
int = NoDependenceCollectionFlags, const Scope * = nullptr);
32+
SymbolVector CollectAllDependences(
33+
const Scope &, int = NoDependenceCollectionFlags);
34+
35+
} // namespace Fortran::semantics
36+
#endif // FORTRAN_SEMANTICS_SYMBOL_DEPENDENCE_H_

flang/lib/Semantics/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ add_flang_library(FortranSemantics
4848
runtime-type-info.cpp
4949
scope.cpp
5050
semantics.cpp
51+
symbol-dependence.cpp
5152
symbol.cpp
5253
tools.cpp
5354
type.cpp

flang/lib/Semantics/mod-file.cpp

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "flang/Parser/unparse.h"
1616
#include "flang/Semantics/scope.h"
1717
#include "flang/Semantics/semantics.h"
18+
#include "flang/Semantics/symbol-dependence.h"
1819
#include "flang/Semantics/symbol.h"
1920
#include "flang/Semantics/tools.h"
2021
#include "llvm/Support/FileSystem.h"
@@ -223,72 +224,13 @@ std::string ModFileWriter::GetAsString(const Symbol &symbol) {
223224
// Collect symbols from constant and specification expressions that are being
224225
// referenced directly from other modules; they may require new USE
225226
// associations.
226-
static void HarvestSymbolsNeededFromOtherModules(
227-
SourceOrderedSymbolSet &, const Scope &);
228-
static void HarvestSymbolsNeededFromOtherModules(
229-
SourceOrderedSymbolSet &set, const Symbol &symbol, const Scope &scope) {
230-
auto HarvestBound{[&](const Bound &bound) {
231-
if (const auto &expr{bound.GetExplicit()}) {
232-
for (SymbolRef ref : evaluate::CollectSymbols(*expr)) {
233-
set.emplace(*ref);
234-
}
235-
}
236-
}};
237-
auto HarvestShapeSpec{[&](const ShapeSpec &shapeSpec) {
238-
HarvestBound(shapeSpec.lbound());
239-
HarvestBound(shapeSpec.ubound());
240-
}};
241-
auto HarvestArraySpec{[&](const ArraySpec &arraySpec) {
242-
for (const auto &shapeSpec : arraySpec) {
243-
HarvestShapeSpec(shapeSpec);
244-
}
245-
}};
246-
247-
if (symbol.has<DerivedTypeDetails>()) {
248-
if (symbol.scope()) {
249-
HarvestSymbolsNeededFromOtherModules(set, *symbol.scope());
250-
}
251-
} else if (const auto &generic{symbol.detailsIf<GenericDetails>()};
252-
generic && generic->derivedType()) {
253-
const Symbol &dtSym{*generic->derivedType()};
254-
if (dtSym.has<DerivedTypeDetails>()) {
255-
if (dtSym.scope()) {
256-
HarvestSymbolsNeededFromOtherModules(set, *dtSym.scope());
257-
}
258-
} else {
259-
CHECK(dtSym.has<UseDetails>() || dtSym.has<UseErrorDetails>());
260-
}
261-
} else if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
262-
HarvestArraySpec(object->shape());
263-
HarvestArraySpec(object->coshape());
264-
if (IsNamedConstant(symbol) || scope.IsDerivedType()) {
265-
if (object->init()) {
266-
for (SymbolRef ref : evaluate::CollectSymbols(*object->init())) {
267-
set.emplace(*ref);
268-
}
269-
}
270-
}
271-
} else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}) {
272-
if (proc->init() && *proc->init() && scope.IsDerivedType()) {
273-
set.emplace(**proc->init());
274-
}
275-
} else if (const auto *subp{symbol.detailsIf<SubprogramDetails>()}) {
276-
for (const Symbol *dummy : subp->dummyArgs()) {
277-
if (dummy) {
278-
HarvestSymbolsNeededFromOtherModules(set, *dummy, scope);
279-
}
280-
}
281-
if (subp->isFunction()) {
282-
HarvestSymbolsNeededFromOtherModules(set, subp->result(), scope);
283-
}
284-
}
285-
}
286-
287-
static void HarvestSymbolsNeededFromOtherModules(
288-
SourceOrderedSymbolSet &set, const Scope &scope) {
289-
for (const auto &[_, symbol] : scope) {
290-
HarvestSymbolsNeededFromOtherModules(set, *symbol, scope);
227+
static SourceOrderedSymbolSet HarvestSymbolsNeededFromOtherModules(
228+
const Scope &scope) {
229+
SourceOrderedSymbolSet set;
230+
for (const Symbol &symbol : CollectAllDependences(scope)) {
231+
set.insert(symbol);
291232
}
233+
return set;
292234
}
293235

294236
void ModFileWriter::PrepareRenamings(const Scope &scope) {
@@ -304,8 +246,8 @@ void ModFileWriter::PrepareRenamings(const Scope &scope) {
304246
}
305247
}
306248
// Collect symbols needed from other modules
307-
SourceOrderedSymbolSet symbolsNeeded;
308-
HarvestSymbolsNeededFromOtherModules(symbolsNeeded, scope);
249+
SourceOrderedSymbolSet symbolsNeeded{
250+
HarvestSymbolsNeededFromOtherModules(scope)};
309251
// Establish any necessary renamings of symbols in other modules
310252
// to their names in this scope, creating those new names when needed.
311253
auto &renamings{context_.moduleFileOutputRenamings()};

0 commit comments

Comments
 (0)