69 using mapType = std::map<SourceName, MutableSymbolRef>;
72 ENUM_CLASS(Kind, Global, IntrinsicModules, Module, MainProgram, Subprogram,
73 BlockData, DerivedType, BlockConstruct, Forall, OtherConstruct,
74 OpenACCConstruct, ImpliedDos, OtherClause)
75 using ImportKind = common::ImportKind;
79 : Scope{*
this, Kind::Global,
nullptr, context} {}
81 : parent_{&parent}, kind_{kind}, symbol_{symbol}, context_{context} {
83 symbol->set_scope(
this);
86 Scope(
const Scope &) =
delete;
88 bool operator==(
const Scope &that)
const {
return this == &that; }
89 bool operator!=(
const Scope &that)
const {
return this != &that; }
92 CHECK(parent_ !=
this);
95 const Scope &parent()
const {
96 CHECK(parent_ !=
this);
100 mapType &commonBlocks() {
return commonBlocks_; }
101 const mapType &commonBlocks()
const {
return commonBlocks_; }
103 mapType &commonBlockUses() {
return commonBlockUses_; }
104 const mapType &commonBlockUses()
const {
return commonBlockUses_; }
106 Kind kind()
const {
return kind_; }
107 bool IsGlobal()
const {
return kind_ == Kind::Global; }
108 bool IsIntrinsicModules()
const {
return kind_ == Kind::IntrinsicModules; }
109 bool IsTopLevel()
const {
110 return kind_ == Kind::Global || kind_ == Kind::IntrinsicModules;
112 bool IsModule()
const {
113 return kind_ == Kind::Module &&
116 bool IsSubmodule()
const {
117 return kind_ == Kind::Module && symbol_->get<
ModuleDetails>().isSubmodule();
119 bool IsDerivedType()
const {
return kind_ == Kind::DerivedType; }
120 bool IsStmtFunction()
const;
121 bool IsParameterizedDerivedType()
const;
122 bool IsParameterizedDerivedTypeInstantiation()
const {
123 return kind_ == Kind::DerivedType && !symbol_;
129 Symbol *symbol() {
return symbol_; }
130 const Symbol *symbol()
const {
return symbol_; }
133 inline const Symbol *GetSymbol()
const;
134 const Scope *GetDerivedTypeParent()
const;
135 const Scope &GetDerivedTypeBase()
const;
136 inline std::optional<SourceName> GetName()
const;
138 bool Contains(
const Scope &)
const;
146 using size_type = mapType::size_type;
147 using iterator = mapType::iterator;
148 using const_iterator = mapType::const_iterator;
150 iterator begin() {
return symbols_.begin(); }
151 iterator end() {
return symbols_.end(); }
152 const_iterator begin()
const {
return symbols_.begin(); }
153 const_iterator end()
const {
return symbols_.end(); }
154 const_iterator cbegin()
const {
return symbols_.cbegin(); }
155 const_iterator cend()
const {
return symbols_.cend(); }
160 SymbolVector GetSymbols()
const;
161 MutableSymbolVector GetSymbols();
163 iterator find(
const SourceName &name);
164 const_iterator find(
const SourceName &name)
const {
165 return symbols_.find(name);
167 size_type erase(
const SourceName &);
168 bool empty()
const {
return symbols_.empty(); }
171 Symbol *FindSymbol(
const SourceName &)
const;
175 Symbol *FindComponent(SourceName)
const;
179 const SourceName &name, Attrs attrs = Attrs()) {
183 template <
typename D>
185 const SourceName &name, D &&details) {
186 return try_emplace(name, Attrs(), std::move(details));
189 template <
typename D>
191 const SourceName &name, Attrs attrs, D &&details) {
193 return symbols_.emplace(name, symbol);
198 std::list<EquivalenceSet> &equivalenceSets() {
return equivalenceSets_; }
199 const std::list<EquivalenceSet> &equivalenceSets()
const {
200 return equivalenceSets_;
202 void add_equivalenceSet(EquivalenceSet &&);
204 const mapType &crayPointers()
const {
return crayPointers_; }
205 void add_crayPointer(
const SourceName &, Symbol &);
206 Symbol &MakeCommonBlock(SourceName, SourceName location);
207 bool AddCommonBlockUse(
208 const SourceName &name, Attrs attrs, Symbol &cbUltimate);
211 Symbol *FindCommonBlock(
const SourceName &name)
const;
214 Symbol *FindCommonBlockUse(
const SourceName &name)
const;
218 Symbol *FindCommonBlockInVisibleScopes(
const SourceName &)
const;
221 template <
typename D>
223 const SourceName &name, Attrs attrs, D &&details) {
224 return allSymbols.Make(*
this, name, attrs, std::move(details));
227 std::list<Scope> &children() {
return children_; }
228 const std::list<Scope> &children()
const {
return children_; }
232 Scope *FindSubmodule(
const SourceName &)
const;
233 bool AddSubmodule(
const SourceName &, Scope &);
235 const DeclTypeSpec *FindType(
const DeclTypeSpec &)
const;
236 const DeclTypeSpec &MakeNumericType(TypeCategory, KindExpr &&kind);
237 const DeclTypeSpec &MakeLogicalType(KindExpr &&kind);
238 const DeclTypeSpec &MakeCharacterType(
239 ParamValue &&length, KindExpr &&kind = KindExpr{0});
240 DeclTypeSpec &MakeDerivedType(DeclTypeSpec::Category, DerivedTypeSpec &&);
241 const DeclTypeSpec &MakeTypeStarType();
242 const DeclTypeSpec &MakeClassStarType();
243 const DeclTypeSpec *GetType(
const SomeExpr &);
245 std::size_t size()
const {
return size_; }
246 void set_size(std::size_t size) { size_ = size; }
247 std::optional<std::size_t> alignment()
const {
return alignment_; }
249 void SetAlignment(std::size_t n) {
250 alignment_ = std::max(alignment_.value_or(0), n);
253 ImportKind GetImportKind()
const;
255 std::set<SourceName> importNames()
const {
return importNames_; }
256 bool CanImport(
const SourceName &)
const;
260 std::optional<parser::MessageFixedText> SetImportKind(ImportKind);
262 void add_importName(
const SourceName &);
265 const DerivedTypeSpec *derivedTypeSpec()
const {
return derivedTypeSpec_; }
266 DerivedTypeSpec *derivedTypeSpec() {
return derivedTypeSpec_; }
267 void set_derivedTypeSpec(DerivedTypeSpec &spec) { derivedTypeSpec_ = &spec; }
268 parser::Message::Reference instantiationContext()
const {
269 return instantiationContext_;
271 void set_instantiationContext(parser::Message::Reference &&mref) {
272 instantiationContext_ = std::move(mref);
275 bool hasSAVE()
const {
return hasSAVE_; }
276 void set_hasSAVE(
bool yes =
true) { hasSAVE_ = yes; }
279 const parser::CharBlock &sourceRange()
const {
return sourceRange_; }
280 void AddSourceRange(parser::CharBlock);
283 const DeclTypeSpec *FindInstantiatedDerivedType(
const DerivedTypeSpec &,
284 DeclTypeSpec::Category = DeclTypeSpec::TypeDerived)
const;
286 bool IsModuleFile()
const {
287 return kind_ == Kind::Module && symbol_ &&
288 symbol_->test(Symbol::Flag::ModFile);
291 void InstantiateDerivedTypes();
293 const Symbol *runtimeDerivedTypeDescription()
const {
294 return runtimeDerivedTypeDescription_;
296 void set_runtimeDerivedTypeDescription(
const Symbol &symbol) {
297 runtimeDerivedTypeDescription_ = &symbol;
304 std::size_t size_{0};
305 std::optional<std::size_t> alignment_;
306 parser::CharBlock sourceRange_;
307 const parser::CookedSource *cookedSource_{
nullptr};
308 Symbol *
const symbol_;
309 std::list<Scope> children_;
311 mapType commonBlocks_;
312 mapType commonBlockUses_;
313 std::list<EquivalenceSet> equivalenceSets_;
314 mapType crayPointers_;
315 std::map<SourceName, common::Reference<Scope>> submodules_;
316 std::list<DeclTypeSpec> declTypeSpecs_;
317 std::optional<ImportKind> importKind_;
318 std::set<SourceName> importNames_;
319 DerivedTypeSpec *derivedTypeSpec_{
nullptr};
320 parser::Message::Reference instantiationContext_;
321 bool hasSAVE_{
false};
322 const Symbol *runtimeDerivedTypeDescription_{
nullptr};
323 SemanticsContext &context_;
329 static Symbols<1024> allSymbols;
331 const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
333 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Scope &);