9#ifndef FORTRAN_SEMANTICS_SCOPE_H_
10#define FORTRAN_SEMANTICS_SCOPE_H_
14#include "flang/Common/Fortran.h"
15#include "flang/Common/idioms.h"
16#include "flang/Common/reference.h"
17#include "flang/Parser/message.h"
18#include "flang/Parser/provenance.h"
29namespace Fortran::semantics {
31using namespace parser::literals;
33using common::ConstantSubscript;
35class SemanticsContext;
42 : symbol{symbol}, subscripts{subscripts},
43 substringStart{substringStart}, source{source} {}
45 : symbol{symbol}, source{symbol.name()} {}
49 std::string AsFortran()
const;
52 std::vector<ConstantSubscript> subscripts;
53 std::optional<ConstantSubscript> substringStart;
56using EquivalenceSet = std::vector<EquivalenceObject>;
59 using mapType = std::map<SourceName, MutableSymbolRef>;
62 ENUM_CLASS(Kind, Global, IntrinsicModules, Module, MainProgram, Subprogram,
63 BlockData, DerivedType, BlockConstruct, Forall, OtherConstruct,
64 OpenACCConstruct, ImpliedDos, OtherClause)
65 using ImportKind = common::ImportKind;
69 :
Scope{*
this, Kind::Global,
nullptr, context} {}
71 : parent_{&parent}, kind_{kind}, symbol_{symbol}, context_{context} {
73 symbol->set_scope(
this);
78 bool operator==(
const Scope &that)
const {
return this == &that; }
79 bool operator!=(
const Scope &that)
const {
return this != &that; }
82 CHECK(parent_ !=
this);
85 const Scope &parent()
const {
86 CHECK(parent_ !=
this);
89 Kind kind()
const {
return kind_; }
90 bool IsGlobal()
const {
return kind_ == Kind::Global; }
91 bool IsIntrinsicModules()
const {
return kind_ == Kind::IntrinsicModules; }
92 bool IsTopLevel()
const {
93 return kind_ == Kind::Global || kind_ == Kind::IntrinsicModules;
95 bool IsModule()
const {
96 return kind_ == Kind::Module &&
99 bool IsSubmodule()
const {
100 return kind_ == Kind::Module && symbol_->get<
ModuleDetails>().isSubmodule();
102 bool IsDerivedType()
const {
return kind_ == Kind::DerivedType; }
103 bool IsStmtFunction()
const;
104 bool IsParameterizedDerivedType()
const;
105 bool IsParameterizedDerivedTypeInstantiation()
const {
106 return kind_ == Kind::DerivedType && !symbol_;
112 Symbol *symbol() {
return symbol_; }
113 const Symbol *symbol()
const {
return symbol_; }
116 inline const Symbol *GetSymbol()
const;
117 const Scope *GetDerivedTypeParent()
const;
118 const Scope &GetDerivedTypeBase()
const;
119 inline std::optional<SourceName> GetName()
const;
121 bool Contains(
const Scope &)
const;
129 using size_type = mapType::size_type;
130 using iterator = mapType::iterator;
131 using const_iterator = mapType::const_iterator;
133 iterator begin() {
return symbols_.begin(); }
134 iterator end() {
return symbols_.end(); }
135 const_iterator begin()
const {
return symbols_.begin(); }
136 const_iterator end()
const {
return symbols_.end(); }
137 const_iterator cbegin()
const {
return symbols_.cbegin(); }
138 const_iterator cend()
const {
return symbols_.cend(); }
143 SymbolVector GetSymbols()
const;
144 MutableSymbolVector GetSymbols();
147 const_iterator find(
const SourceName &name)
const {
148 return symbols_.find(name);
151 bool empty()
const {
return symbols_.empty(); }
162 const SourceName &name, Attrs attrs = Attrs()) {
166 template <
typename D>
169 return try_emplace(name, Attrs(), std::move(details));
172 template <
typename D>
174 const SourceName &name, Attrs attrs, D &&details) {
176 return symbols_.emplace(name, symbol);
181 std::list<EquivalenceSet> &equivalenceSets() {
return equivalenceSets_; }
182 const std::list<EquivalenceSet> &equivalenceSets()
const {
183 return equivalenceSets_;
185 void add_equivalenceSet(EquivalenceSet &&);
187 const mapType &crayPointers()
const {
return crayPointers_; }
188 void add_crayPointer(
const SourceName &, Symbol &);
189 mapType &commonBlocks() {
return commonBlocks_; }
190 const mapType &commonBlocks()
const {
return commonBlocks_; }
191 Symbol &MakeCommonBlock(
const SourceName &);
192 Symbol *FindCommonBlock(
const SourceName &)
const;
195 template <
typename D>
197 const SourceName &name, Attrs attrs, D &&details) {
198 return allSymbols.Make(*
this, name, attrs, std::move(details));
201 std::list<Scope> &children() {
return children_; }
202 const std::list<Scope> &children()
const {
return children_; }
206 Scope *FindSubmodule(
const SourceName &)
const;
207 bool AddSubmodule(
const SourceName &, Scope &);
209 const DeclTypeSpec *FindType(
const DeclTypeSpec &)
const;
210 const DeclTypeSpec &MakeNumericType(TypeCategory, KindExpr &&kind);
211 const DeclTypeSpec &MakeLogicalType(KindExpr &&kind);
212 const DeclTypeSpec &MakeCharacterType(
213 ParamValue &&length, KindExpr &&kind = KindExpr{0});
214 DeclTypeSpec &MakeDerivedType(DeclTypeSpec::Category, DerivedTypeSpec &&);
215 const DeclTypeSpec &MakeTypeStarType();
216 const DeclTypeSpec &MakeClassStarType();
217 const DeclTypeSpec *GetType(
const SomeExpr &);
219 std::size_t size()
const {
return size_; }
220 void set_size(std::size_t size) { size_ = size; }
221 std::optional<std::size_t> alignment()
const {
return alignment_; }
223 void SetAlignment(std::size_t n) {
224 alignment_ = std::max(alignment_.value_or(0), n);
227 ImportKind GetImportKind()
const;
229 std::set<SourceName> importNames()
const {
return importNames_; }
230 bool CanImport(
const SourceName &)
const;
234 std::optional<parser::MessageFixedText> SetImportKind(ImportKind);
236 void add_importName(
const SourceName &);
239 const DerivedTypeSpec *derivedTypeSpec()
const {
return derivedTypeSpec_; }
240 DerivedTypeSpec *derivedTypeSpec() {
return derivedTypeSpec_; }
241 void set_derivedTypeSpec(DerivedTypeSpec &spec) { derivedTypeSpec_ = &spec; }
242 parser::Message::Reference instantiationContext()
const {
243 return instantiationContext_;
245 void set_instantiationContext(parser::Message::Reference &&mref) {
246 instantiationContext_ = std::move(mref);
249 bool hasSAVE()
const {
return hasSAVE_; }
250 void set_hasSAVE(
bool yes =
true) { hasSAVE_ = yes; }
253 const parser::CharBlock &sourceRange()
const {
return sourceRange_; }
254 void AddSourceRange(parser::CharBlock);
257 const DeclTypeSpec *FindInstantiatedDerivedType(
const DerivedTypeSpec &,
258 DeclTypeSpec::Category = DeclTypeSpec::TypeDerived)
const;
260 bool IsModuleFile()
const {
261 return kind_ == Kind::Module && symbol_ &&
262 symbol_->test(Symbol::Flag::ModFile);
265 void InstantiateDerivedTypes();
267 const Symbol *runtimeDerivedTypeDescription()
const {
268 return runtimeDerivedTypeDescription_;
270 void set_runtimeDerivedTypeDescription(
const Symbol &symbol) {
271 runtimeDerivedTypeDescription_ = &symbol;
278 std::size_t size_{0};
279 std::optional<std::size_t> alignment_;
280 parser::CharBlock sourceRange_;
281 const parser::CookedSource *cookedSource_{
nullptr};
282 Symbol *
const symbol_;
283 std::list<Scope> children_;
285 mapType commonBlocks_;
286 std::list<EquivalenceSet> equivalenceSets_;
287 mapType crayPointers_;
288 std::map<SourceName, common::Reference<Scope>> submodules_;
289 std::list<DeclTypeSpec> declTypeSpecs_;
290 std::optional<ImportKind> importKind_;
291 std::set<SourceName> importNames_;
292 DerivedTypeSpec *derivedTypeSpec_{
nullptr};
293 parser::Message::Reference instantiationContext_;
294 bool hasSAVE_{
false};
295 const Symbol *runtimeDerivedTypeDescription_{
nullptr};
296 SemanticsContext &context_;
302 static Symbols<1024> allSymbols;
304 const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
306 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Scope &);
311inline const Symbol *Scope::GetSymbol()
const {
312 return symbol_ ? symbol_
313 : derivedTypeSpec_ ? &derivedTypeSpec_->typeSymbol()
317inline std::optional<SourceName> Scope::GetName()
const {
318 if (
const auto *sym{GetSymbol()}) {
Definition: char-block.h:28
common::IfNoLvalue< std::pair< iterator, bool >, D > try_emplace(const SourceName &name, Attrs attrs, D &&details)
Make a Symbol with attrs and details.
Definition: scope.h:173
bool IsDerivedTypeWithKindParameter() const
Does this derived type have at least one kind parameter ?
Definition: scope.cpp:437
common::IfNoLvalue< std::pair< iterator, bool >, D > try_emplace(const SourceName &name, D &&details)
Make a Symbol with provided details.
Definition: scope.h:167
Scope & MakeScope(Kind kind, Symbol *symbol=nullptr)
Make a scope nested in this one.
Definition: scope.cpp:53
std::pair< iterator, bool > try_emplace(const SourceName &name, Attrs attrs=Attrs())
Make a Symbol with unknown details.
Definition: scope.h:161
common::IfNoLvalue< Symbol &, D > MakeSymbol(const SourceName &name, Attrs attrs, D &&details)
Make a Symbol but don't add it to the scope.
Definition: scope.h:196
bool IsDerivedTypeWithLengthParameter() const
Does this derived type have at least one length parameter ?
Definition: scope.cpp:434
Definition: semantics.h:67