1 //===-- lib/Semantics/program-tree.h ----------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef FORTRAN_SEMANTICS_PROGRAM_TREE_H_
10 #define FORTRAN_SEMANTICS_PROGRAM_TREE_H_
12 #include "flang/Parser/parse-tree.h"
13 #include "flang/Semantics/symbol.h"
17 // A ProgramTree represents a tree of program units and their contained
18 // subprograms. The root nodes represent: main program, function, subroutine,
19 // module subprogram, module, or submodule.
20 // Each node of the tree consists of:
21 // - the statement that introduces the program unit
22 // - the specification part
23 // - the execution part if applicable (not for module or submodule)
24 // - a child node for each contained subprogram
26 namespace Fortran::semantics
{
32 using EntryStmtList
= std::list
<common::Reference
<const parser::EntryStmt
>>;
33 using GenericSpecList
=
34 std::list
<common::Reference
<const parser::GenericSpec
>>;
36 // Build the ProgramTree rooted at one of these program units.
37 static ProgramTree
Build(const parser::ProgramUnit
&);
38 static ProgramTree
Build(const parser::MainProgram
&);
39 static ProgramTree
Build(const parser::FunctionSubprogram
&);
40 static ProgramTree
Build(const parser::SubroutineSubprogram
&);
41 static ProgramTree
Build(const parser::SeparateModuleSubprogram
&);
42 static ProgramTree
Build(const parser::Module
&);
43 static ProgramTree
Build(const parser::Submodule
&);
44 static ProgramTree
Build(const parser::BlockData
&);
45 static ProgramTree
Build(const parser::CompilerDirective
&);
47 ENUM_CLASS(Kind
, // kind of node
48 Program
, Function
, Subroutine
, MpSubprogram
, Module
, Submodule
, BlockData
)
49 using Stmt
= std::variant
< // the statement that introduces the program unit
50 const parser::Statement
<parser::ProgramStmt
> *,
51 const parser::Statement
<parser::FunctionStmt
> *,
52 const parser::Statement
<parser::SubroutineStmt
> *,
53 const parser::Statement
<parser::MpSubprogramStmt
> *,
54 const parser::Statement
<parser::ModuleStmt
> *,
55 const parser::Statement
<parser::SubmoduleStmt
> *,
56 const parser::Statement
<parser::BlockDataStmt
> *>;
58 ProgramTree(const parser::Name
&name
, const parser::SpecificationPart
&spec
,
59 const parser::ExecutionPart
*exec
= nullptr)
60 : name_
{name
}, spec_
{spec
}, exec_
{exec
} {}
62 const parser::Name
&name() const { return name_
; }
64 const Stmt
&stmt() const { return stmt_
; }
65 bool isSpecificationPartResolved() const {
66 return isSpecificationPartResolved_
;
68 void set_isSpecificationPartResolved(bool yes
= true) {
69 isSpecificationPartResolved_
= yes
;
71 const parser::ParentIdentifier
&GetParentId() const; // only for Submodule
72 const parser::SpecificationPart
&spec() const { return spec_
; }
73 const parser::ExecutionPart
*exec() const { return exec_
; }
74 std::list
<ProgramTree
> &children() { return children_
; }
75 const std::list
<ProgramTree
> &children() const { return children_
; }
76 const EntryStmtList
&entryStmts() const { return entryStmts_
; }
77 const GenericSpecList
&genericSpecs() const { return genericSpecs_
; }
79 Symbol::Flag
GetSubpFlag() const;
80 bool IsModule() const; // Module or Submodule
81 bool HasModulePrefix() const; // in function or subroutine stmt
82 Scope
*scope() const { return scope_
; }
83 void set_scope(Scope
&);
84 const parser::LanguageBindingSpec
*bindingSpec() const {
87 ProgramTree
&set_bindingSpec(const parser::LanguageBindingSpec
*spec
) {
91 void AddChild(ProgramTree
&&);
92 void AddEntry(const parser::EntryStmt
&);
93 void AddGeneric(const parser::GenericSpec
&);
96 ProgramTree
&set_stmt(const parser::Statement
<T
> &stmt
) {
100 template <typename T
>
101 ProgramTree
&set_endStmt(const parser::Statement
<T
> &stmt
) {
102 endStmt_
= &stmt
.source
;
107 const parser::Name
&name_
;
109 static_cast<const parser::Statement
<parser::ProgramStmt
> *>(nullptr)};
110 const parser::SpecificationPart
&spec_
;
111 const parser::ExecutionPart
*exec_
{nullptr};
112 std::list
<ProgramTree
> children_
;
113 EntryStmtList entryStmts_
;
114 GenericSpecList genericSpecs_
;
115 Scope
*scope_
{nullptr};
116 const parser::CharBlock
*endStmt_
{nullptr};
117 bool isSpecificationPartResolved_
{false};
118 const parser::LanguageBindingSpec
*bindingSpec_
{nullptr};
121 } // namespace Fortran::semantics
122 #endif // FORTRAN_SEMANTICS_PROGRAM_TREE_H_