1//===-- lib/Semantics/program-tree.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_PROGRAM_TREE_H_
10#define FORTRAN_SEMANTICS_PROGRAM_TREE_H_
11
12#include "flang/Parser/parse-tree.h"
13#include "flang/Semantics/symbol.h"
14#include <list>
15#include <variant>
16
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
25
26namespace Fortran::semantics {
27
28class Scope;
29
30class ProgramTree {
31public:
32 using EntryStmtList = std::list<common::Reference<const parser::EntryStmt>>;
33 using GenericSpecList =
34 std::list<common::Reference<const parser::GenericSpec>>;
35
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 &);
46 static ProgramTree Build(const parser::OpenACCRoutineConstruct &);
47
48 ENUM_CLASS(Kind, // kind of node
49 Program, Function, Subroutine, MpSubprogram, Module, Submodule, BlockData)
50 using Stmt = std::variant< // the statement that introduces the program unit
51 const parser::Statement<parser::ProgramStmt> *,
52 const parser::Statement<parser::FunctionStmt> *,
53 const parser::Statement<parser::SubroutineStmt> *,
54 const parser::Statement<parser::MpSubprogramStmt> *,
55 const parser::Statement<parser::ModuleStmt> *,
56 const parser::Statement<parser::SubmoduleStmt> *,
57 const parser::Statement<parser::BlockDataStmt> *>;
58
59 ProgramTree(const parser::Name &name, const parser::SpecificationPart &spec,
60 const parser::ExecutionPart *exec = nullptr)
61 : name_{name}, spec_{spec}, exec_{exec} {}
62
63 const parser::Name &name() const { return name_; }
64 Kind GetKind() const;
65 const Stmt &stmt() const { return stmt_; }
66 bool isSpecificationPartResolved() const {
67 return isSpecificationPartResolved_;
68 }
69 void set_isSpecificationPartResolved(bool yes = true) {
70 isSpecificationPartResolved_ = yes;
71 }
72 const parser::ParentIdentifier &GetParentId() const; // only for Submodule
73 const parser::SpecificationPart &spec() const { return spec_; }
74 const parser::ExecutionPart *exec() const { return exec_; }
75 std::list<ProgramTree> &children() { return children_; }
76 const std::list<ProgramTree> &children() const { return children_; }
77 const EntryStmtList &entryStmts() const { return entryStmts_; }
78 const GenericSpecList &genericSpecs() const { return genericSpecs_; }
79
80 Symbol::Flag GetSubpFlag() const;
81 bool IsModule() const; // Module or Submodule
82 bool HasModulePrefix() const; // in function or subroutine stmt
83 Scope *scope() const { return scope_; }
84 void set_scope(Scope &);
85 const parser::LanguageBindingSpec *bindingSpec() const {
86 return bindingSpec_;
87 }
88 ProgramTree &set_bindingSpec(const parser::LanguageBindingSpec *spec) {
89 bindingSpec_ = spec;
90 return *this;
91 }
92 void AddChild(ProgramTree &&);
93 void AddEntry(const parser::EntryStmt &);
94 void AddGeneric(const parser::GenericSpec &);
95
96 template <typename T>
97 ProgramTree &set_stmt(const parser::Statement<T> &stmt) {
98 stmt_ = &stmt;
99 return *this;
100 }
101 template <typename T>
102 ProgramTree &set_endStmt(const parser::Statement<T> &stmt) {
103 endStmt_ = &stmt.source;
104 return *this;
105 }
106
107private:
108 const parser::Name &name_;
109 Stmt stmt_{
110 static_cast<const parser::Statement<parser::ProgramStmt> *>(nullptr)};
111 const parser::SpecificationPart &spec_;
112 const parser::ExecutionPart *exec_{nullptr};
113 std::list<ProgramTree> children_;
114 EntryStmtList entryStmts_;
115 GenericSpecList genericSpecs_;
116 Scope *scope_{nullptr};
117 const parser::CharBlock *endStmt_{nullptr};
118 bool isSpecificationPartResolved_{false};
119 const parser::LanguageBindingSpec *bindingSpec_{nullptr};
120};
121
122} // namespace Fortran::semantics
123#endif // FORTRAN_SEMANTICS_PROGRAM_TREE_H_
124

source code of flang/lib/Semantics/program-tree.h