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);
76 Scope(
const Scope &) =
delete;
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);
90 mapType &commonBlocks() {
return commonBlocks_; }
91 const mapType &commonBlocks()
const {
return commonBlocks_; }
93 mapType &commonBlockUses() {
return commonBlockUses_; }
94 const mapType &commonBlockUses()
const {
return commonBlockUses_; }
96 Kind kind()
const {
return kind_; }
97 bool IsGlobal()
const {
return kind_ == Kind::Global; }
98 bool IsIntrinsicModules()
const {
return kind_ == Kind::IntrinsicModules; }
99 bool IsTopLevel()
const {
100 return kind_ == Kind::Global || kind_ == Kind::IntrinsicModules;
102 bool IsModule()
const {
103 return kind_ == Kind::Module &&
106 bool IsSubmodule()
const {
107 return kind_ == Kind::Module && symbol_->get<
ModuleDetails>().isSubmodule();
109 bool IsDerivedType()
const {
return kind_ == Kind::DerivedType; }
110 bool IsStmtFunction()
const;
111 bool IsParameterizedDerivedType()
const;
112 bool IsParameterizedDerivedTypeInstantiation()
const {
113 return kind_ == Kind::DerivedType && !symbol_;
119 Symbol *symbol() {
return symbol_; }
120 const Symbol *symbol()
const {
return symbol_; }
123 inline const Symbol *GetSymbol()
const;
124 const Scope *GetDerivedTypeParent()
const;
125 const Scope &GetDerivedTypeBase()
const;
126 inline std::optional<SourceName> GetName()
const;
128 bool Contains(
const Scope &)
const;
136 using size_type = mapType::size_type;
137 using iterator = mapType::iterator;
138 using const_iterator = mapType::const_iterator;
140 iterator begin() {
return symbols_.begin(); }
141 iterator end() {
return symbols_.end(); }
142 const_iterator begin()
const {
return symbols_.begin(); }
143 const_iterator end()
const {
return symbols_.end(); }
144 const_iterator cbegin()
const {
return symbols_.cbegin(); }
145 const_iterator cend()
const {
return symbols_.cend(); }
150 SymbolVector GetSymbols()
const;
151 MutableSymbolVector GetSymbols();
153 iterator find(
const SourceName &name);
154 const_iterator find(
const SourceName &name)
const {
155 return symbols_.find(name);
157 size_type erase(
const SourceName &);
158 bool empty()
const {
return symbols_.empty(); }
161 Symbol *FindSymbol(
const SourceName &)
const;
165 Symbol *FindComponent(SourceName)
const;
169 const SourceName &name, Attrs attrs = Attrs()) {
173 template <
typename D>
175 const SourceName &name, D &&details) {
176 return try_emplace(name, Attrs(), std::move(details));
179 template <
typename D>
181 const SourceName &name, Attrs attrs, D &&details) {
183 return symbols_.emplace(name, symbol);
188 std::list<EquivalenceSet> &equivalenceSets() {
return equivalenceSets_; }
189 const std::list<EquivalenceSet> &equivalenceSets()
const {
190 return equivalenceSets_;
192 void add_equivalenceSet(EquivalenceSet &&);
194 const mapType &crayPointers()
const {
return crayPointers_; }
195 void add_crayPointer(
const SourceName &, Symbol &);
196 Symbol &MakeCommonBlock(SourceName, SourceName location);
197 bool AddCommonBlockUse(
198 const SourceName &name, Attrs attrs, Symbol &cbUltimate);
201 Symbol *FindCommonBlock(
const SourceName &name)
const;
204 Symbol *FindCommonBlockUse(
const SourceName &name)
const;
208 Symbol *FindCommonBlockInVisibleScopes(
const SourceName &)
const;
211 template <
typename D>
213 const SourceName &name, Attrs attrs, D &&details) {
214 return allSymbols.Make(*
this, name, attrs, std::move(details));
217 std::list<Scope> &children() {
return children_; }
218 const std::list<Scope> &children()
const {
return children_; }
222 Scope *FindSubmodule(
const SourceName &)
const;
223 bool AddSubmodule(
const SourceName &, Scope &);
225 const DeclTypeSpec *FindType(
const DeclTypeSpec &)
const;
226 const DeclTypeSpec &MakeNumericType(TypeCategory, KindExpr &&kind);
227 const DeclTypeSpec &MakeLogicalType(KindExpr &&kind);
228 const DeclTypeSpec &MakeCharacterType(
229 ParamValue &&length, KindExpr &&kind = KindExpr{0});
230 DeclTypeSpec &MakeDerivedType(DeclTypeSpec::Category, DerivedTypeSpec &&);
231 const DeclTypeSpec &MakeTypeStarType();
232 const DeclTypeSpec &MakeClassStarType();
233 const DeclTypeSpec *GetType(
const SomeExpr &);
235 std::size_t size()
const {
return size_; }
236 void set_size(std::size_t size) { size_ = size; }
237 std::optional<std::size_t> alignment()
const {
return alignment_; }
239 void SetAlignment(std::size_t n) {
240 alignment_ = std::max(alignment_.value_or(0), n);
243 ImportKind GetImportKind()
const;
245 std::set<SourceName> importNames()
const {
return importNames_; }
246 bool CanImport(
const SourceName &)
const;
250 std::optional<parser::MessageFixedText> SetImportKind(ImportKind);
252 void add_importName(
const SourceName &);
255 const DerivedTypeSpec *derivedTypeSpec()
const {
return derivedTypeSpec_; }
256 DerivedTypeSpec *derivedTypeSpec() {
return derivedTypeSpec_; }
257 void set_derivedTypeSpec(DerivedTypeSpec &spec) { derivedTypeSpec_ = &spec; }
258 parser::Message::Reference instantiationContext()
const {
259 return instantiationContext_;
261 void set_instantiationContext(parser::Message::Reference &&mref) {
262 instantiationContext_ = std::move(mref);
265 bool hasSAVE()
const {
return hasSAVE_; }
266 void set_hasSAVE(
bool yes =
true) { hasSAVE_ = yes; }
269 const parser::CharBlock &sourceRange()
const {
return sourceRange_; }
270 void AddSourceRange(parser::CharBlock);
273 const DeclTypeSpec *FindInstantiatedDerivedType(
const DerivedTypeSpec &,
274 DeclTypeSpec::Category = DeclTypeSpec::TypeDerived)
const;
276 bool IsModuleFile()
const {
277 return kind_ == Kind::Module && symbol_ &&
278 symbol_->test(Symbol::Flag::ModFile);
281 void InstantiateDerivedTypes();
283 const Symbol *runtimeDerivedTypeDescription()
const {
284 return runtimeDerivedTypeDescription_;
286 void set_runtimeDerivedTypeDescription(
const Symbol &symbol) {
287 runtimeDerivedTypeDescription_ = &symbol;
294 std::size_t size_{0};
295 std::optional<std::size_t> alignment_;
296 parser::CharBlock sourceRange_;
297 const parser::CookedSource *cookedSource_{
nullptr};
298 Symbol *
const symbol_;
299 std::list<Scope> children_;
301 mapType commonBlocks_;
302 mapType commonBlockUses_;
303 std::list<EquivalenceSet> equivalenceSets_;
304 mapType crayPointers_;
305 std::map<SourceName, common::Reference<Scope>> submodules_;
306 std::list<DeclTypeSpec> declTypeSpecs_;
307 std::optional<ImportKind> importKind_;
308 std::set<SourceName> importNames_;
309 DerivedTypeSpec *derivedTypeSpec_{
nullptr};
310 parser::Message::Reference instantiationContext_;
311 bool hasSAVE_{
false};
312 const Symbol *runtimeDerivedTypeDescription_{
nullptr};
313 SemanticsContext &context_;
319 static Symbols<1024> allSymbols;
321 const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
323 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Scope &);