forked from OSchip/llvm-project
[flang][NFC] Add GetTopLevelUnitContaining functions
`GetTopLevelUnitContaining` returns the Scope nested in the global scope that contains the given Scope or Symbol. Use "Get" rather than "Find" in the name because "Find" implies it might not be found, which can't happen. Following that logic, rename `FindProgramUnitContaining` to `GetProgramUnitContaining` and have it also return a reference rather that a pointer. Note that the use of "ProgramUnit" is slightly confusing. In the Fortran standard, "program-unit" refers to what is called a "TopLevelUnit" here. What we are calling a "ProgramUnit" (here and in `ProgramTree`) includes internal subprograms while "TopLevelUnit" does not. Differential Revision: https://reviews.llvm.org/D92491
This commit is contained in:
parent
291cc1bbea
commit
1f525ece4a
|
@ -30,9 +30,14 @@ class DerivedTypeSpec;
|
||||||
class Scope;
|
class Scope;
|
||||||
class Symbol;
|
class Symbol;
|
||||||
|
|
||||||
|
// Note: Here ProgramUnit includes internal subprograms while TopLevelUnit
|
||||||
|
// does not. "program-unit" in the Fortran standard matches TopLevelUnit.
|
||||||
|
const Scope &GetTopLevelUnitContaining(const Scope &);
|
||||||
|
const Scope &GetTopLevelUnitContaining(const Symbol &);
|
||||||
|
const Scope &GetProgramUnitContaining(const Scope &);
|
||||||
|
const Scope &GetProgramUnitContaining(const Symbol &);
|
||||||
|
|
||||||
const Scope *FindModuleContaining(const Scope &);
|
const Scope *FindModuleContaining(const Scope &);
|
||||||
const Scope *FindProgramUnitContaining(const Scope &);
|
|
||||||
const Scope *FindProgramUnitContaining(const Symbol &);
|
|
||||||
const Scope *FindPureProcedureContaining(const Scope &);
|
const Scope *FindPureProcedureContaining(const Scope &);
|
||||||
const Scope *FindPureProcedureContaining(const Symbol &);
|
const Scope *FindPureProcedureContaining(const Symbol &);
|
||||||
const Symbol *FindPointerComponent(const Scope &);
|
const Symbol *FindPointerComponent(const Scope &);
|
||||||
|
|
|
@ -16,11 +16,10 @@
|
||||||
namespace Fortran::semantics {
|
namespace Fortran::semantics {
|
||||||
|
|
||||||
static const Scope *FindContainingSubprogram(const Scope &start) {
|
static const Scope *FindContainingSubprogram(const Scope &start) {
|
||||||
const Scope *scope{FindProgramUnitContaining(start)};
|
const Scope &scope{GetProgramUnitContaining(start)};
|
||||||
return scope &&
|
return scope.kind() == Scope::Kind::MainProgram ||
|
||||||
(scope->kind() == Scope::Kind::MainProgram ||
|
scope.kind() == Scope::Kind::Subprogram
|
||||||
scope->kind() == Scope::Kind::Subprogram)
|
? &scope
|
||||||
? scope
|
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5602,11 +5602,11 @@ bool DeclarationVisitor::CheckForHostAssociatedImplicit(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeclarationVisitor::IsUplevelReference(const Symbol &symbol) {
|
bool DeclarationVisitor::IsUplevelReference(const Symbol &symbol) {
|
||||||
const Scope *symbolUnit{FindProgramUnitContaining(symbol)};
|
const Scope &symbolUnit{GetProgramUnitContaining(symbol)};
|
||||||
if (symbolUnit == FindProgramUnitContaining(currScope())) {
|
if (symbolUnit == GetProgramUnitContaining(currScope())) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Scope::Kind kind{DEREF(symbolUnit).kind()};
|
Scope::Kind kind{symbolUnit.kind()};
|
||||||
return kind == Scope::Kind::Subprogram || kind == Scope::Kind::MainProgram;
|
return kind == Scope::Kind::Subprogram || kind == Scope::Kind::MainProgram;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,24 @@ static const Scope *FindScopeContaining(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Scope &GetTopLevelUnitContaining(const Scope &start) {
|
||||||
|
CHECK(!start.IsGlobal());
|
||||||
|
return DEREF(FindScopeContaining(
|
||||||
|
start, [](const Scope &scope) { return scope.parent().IsGlobal(); }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const Scope &GetTopLevelUnitContaining(const Symbol &symbol) {
|
||||||
|
return GetTopLevelUnitContaining(symbol.owner());
|
||||||
|
}
|
||||||
|
|
||||||
const Scope *FindModuleContaining(const Scope &start) {
|
const Scope *FindModuleContaining(const Scope &start) {
|
||||||
return FindScopeContaining(
|
return FindScopeContaining(
|
||||||
start, [](const Scope &scope) { return scope.IsModule(); });
|
start, [](const Scope &scope) { return scope.IsModule(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
const Scope *FindProgramUnitContaining(const Scope &start) {
|
const Scope &GetProgramUnitContaining(const Scope &start) {
|
||||||
return FindScopeContaining(start, [](const Scope &scope) {
|
CHECK(!start.IsGlobal());
|
||||||
|
return DEREF(FindScopeContaining(start, [](const Scope &scope) {
|
||||||
switch (scope.kind()) {
|
switch (scope.kind()) {
|
||||||
case Scope::Kind::Module:
|
case Scope::Kind::Module:
|
||||||
case Scope::Kind::MainProgram:
|
case Scope::Kind::MainProgram:
|
||||||
|
@ -53,23 +64,19 @@ const Scope *FindProgramUnitContaining(const Scope &start) {
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Scope *FindProgramUnitContaining(const Symbol &symbol) {
|
const Scope &GetProgramUnitContaining(const Symbol &symbol) {
|
||||||
return FindProgramUnitContaining(symbol.owner());
|
return GetProgramUnitContaining(symbol.owner());
|
||||||
}
|
}
|
||||||
|
|
||||||
const Scope *FindPureProcedureContaining(const Scope &start) {
|
const Scope *FindPureProcedureContaining(const Scope &start) {
|
||||||
// N.B. We only need to examine the innermost containing program unit
|
// N.B. We only need to examine the innermost containing program unit
|
||||||
// because an internal subprogram of a pure subprogram must also
|
// because an internal subprogram of a pure subprogram must also
|
||||||
// be pure (C1592).
|
// be pure (C1592).
|
||||||
if (const Scope * scope{FindProgramUnitContaining(start)}) {
|
const Scope &scope{GetProgramUnitContaining(start)};
|
||||||
if (IsPureProcedure(*scope)) {
|
return IsPureProcedure(scope) ? &scope : nullptr;
|
||||||
return scope;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tristate IsDefinedAssignment(
|
Tristate IsDefinedAssignment(
|
||||||
|
@ -176,9 +183,9 @@ bool IsCommonBlockContaining(const Symbol &block, const Symbol &object) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsUseAssociated(const Symbol &symbol, const Scope &scope) {
|
bool IsUseAssociated(const Symbol &symbol, const Scope &scope) {
|
||||||
const Scope *owner{FindProgramUnitContaining(symbol.GetUltimate().owner())};
|
const Scope &owner{GetProgramUnitContaining(symbol.GetUltimate().owner())};
|
||||||
return owner && owner->kind() == Scope::Kind::Module &&
|
return owner.kind() == Scope::Kind::Module &&
|
||||||
owner != FindProgramUnitContaining(scope);
|
owner != GetProgramUnitContaining(scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DoesScopeContain(
|
bool DoesScopeContain(
|
||||||
|
@ -203,10 +210,9 @@ static const Symbol &FollowHostAssoc(const Symbol &symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsHostAssociated(const Symbol &symbol, const Scope &scope) {
|
bool IsHostAssociated(const Symbol &symbol, const Scope &scope) {
|
||||||
const Scope *subprogram{FindProgramUnitContaining(scope)};
|
const Scope &subprogram{GetProgramUnitContaining(scope)};
|
||||||
return subprogram &&
|
return DoesScopeContain(
|
||||||
DoesScopeContain(
|
&GetProgramUnitContaining(FollowHostAssoc(symbol)), subprogram);
|
||||||
FindProgramUnitContaining(FollowHostAssoc(symbol)), *subprogram);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsInStmtFunction(const Symbol &symbol) {
|
bool IsInStmtFunction(const Symbol &symbol) {
|
||||||
|
|
Loading…
Reference in New Issue