FLANG
program-tree.h
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 "symbol.h"
13#include "flang/Parser/parse-tree.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;
30
31class ProgramTree {
32public:
33 using EntryStmtList = std::list<common::Reference<const parser::EntryStmt>>;
34 using GenericSpecList =
35 std::list<common::Reference<const parser::GenericSpec>>;
36
37 // Build the ProgramTree rooted at one of these program units.
38 // The ProgramUnit overload requires a scope-bearing unit. Its caller must
39 // handle compiler directives, OpenACC ROUTINE, and ErrorRecovery separately.
40 static ProgramTree &Build(const parser::ProgramUnit &, SemanticsContext &);
41 static std::optional<ProgramTree> Build(
43 static std::optional<ProgramTree> Build(
45 static std::optional<ProgramTree> Build(
47 static std::optional<ProgramTree> Build(
49 static std::optional<ProgramTree> Build(
51 static std::optional<ProgramTree> Build(
53 static std::optional<ProgramTree> Build(
55 static std::optional<ProgramTree> Build(
57 static std::optional<ProgramTree> Build(
59
60 ENUM_CLASS(Kind, // kind of node
61 Program, Function, Subroutine, MpSubprogram, Module, Submodule, BlockData)
62 using Stmt = std::variant< // the statement that introduces the program unit
70
71 ProgramTree(const parser::Name &name, const parser::SpecificationPart &spec,
72 const parser::ExecutionPart *exec = nullptr)
73 : name_{name}, spec_{spec}, exec_{exec} {}
74
75 const parser::Name &name() const { return name_; }
76 Kind GetKind() const;
77 const Stmt &stmt() const { return stmt_; }
78 bool isSpecificationPartResolved() const {
79 return isSpecificationPartResolved_;
80 }
81 void set_isSpecificationPartResolved(bool yes = true) {
82 isSpecificationPartResolved_ = yes;
83 }
84 const parser::ParentIdentifier &GetParentId() const; // only for Submodule
85 const parser::SpecificationPart &spec() const { return spec_; }
86 const parser::ExecutionPart *exec() const { return exec_; }
87 std::list<ProgramTree> &children() { return children_; }
88 const std::list<ProgramTree> &children() const { return children_; }
89 const EntryStmtList &entryStmts() const { return entryStmts_; }
90 const GenericSpecList &genericSpecs() const { return genericSpecs_; }
91
92 Symbol::Flag GetSubpFlag() const;
93 bool IsModule() const; // Module or Submodule
94 bool HasModulePrefix() const; // in function or subroutine stmt
95 Scope *scope() const { return scope_; }
96 void set_scope(Scope &);
97 const parser::LanguageBindingSpec *bindingSpec() const {
98 return bindingSpec_;
99 }
100 ProgramTree &set_bindingSpec(const parser::LanguageBindingSpec *spec) {
101 bindingSpec_ = spec;
102 return *this;
103 }
104 void AddChild(ProgramTree &&);
105 void AddEntry(const parser::EntryStmt &);
106 void AddGeneric(const parser::GenericSpec &);
107
108 template <typename T>
109 ProgramTree &set_stmt(const parser::Statement<T> &stmt) {
110 stmt_ = &stmt;
111 return *this;
112 }
113 template <typename T>
114 ProgramTree &set_endStmt(const parser::Statement<T> &stmt) {
115 endStmt_ = &stmt.source;
116 return *this;
117 }
118
119private:
120 const parser::Name &name_;
121 Stmt stmt_{
122 static_cast<const parser::Statement<parser::ProgramStmt> *>(nullptr)};
123 const parser::SpecificationPart &spec_;
124 const parser::ExecutionPart *exec_{nullptr};
125 std::list<ProgramTree> children_;
126 EntryStmtList entryStmts_;
127 GenericSpecList genericSpecs_;
128 Scope *scope_{nullptr};
129 const parser::CharBlock *endStmt_{nullptr};
130 bool isSpecificationPartResolved_{false};
131 const parser::LanguageBindingSpec *bindingSpec_{nullptr};
132};
133
134} // namespace Fortran::semantics
135#endif // FORTRAN_SEMANTICS_PROGRAM_TREE_H_
Definition char-block.h:27
Definition scope.h:69
Definition semantics.h:71
Definition parse-tree.h:3075
Definition parse-tree.h:3444
Definition parse-tree.h:3411
Definition parse-tree.h:3377
Definition parse-tree.h:3088
Definition parse-tree.h:1337
Definition parse-tree.h:2983
Definition parse-tree.h:3019
Definition parse-tree.h:592
Definition parse-tree.h:5858
Definition parse-tree.h:3044
Definition parse-tree.h:576
Definition parse-tree.h:3403
Definition parse-tree.h:456
Definition parse-tree.h:362
Definition parse-tree.h:3061
Definition parse-tree.h:3387