68 using mapType = std::map<SourceName, MutableSymbolRef>;
71 ENUM_CLASS(Kind, Global, IntrinsicModules, Module, MainProgram, Subprogram,
72 BlockData, DerivedType, BlockConstruct, Forall, OtherConstruct,
73 OpenACCConstruct, ImpliedDos, OtherClause)
74 using ImportKind = common::ImportKind;
78 : Scope{*
this, Kind::Global,
nullptr, context} {}
80 : parent_{&parent}, kind_{kind}, symbol_{symbol}, context_{context} {
82 symbol->set_scope(
this);
85 Scope(
const Scope &) =
delete;
87 bool operator==(
const Scope &that)
const {
return this == &that; }
88 bool operator!=(
const Scope &that)
const {
return this != &that; }
91 CHECK(parent_ !=
this);
94 const Scope &parent()
const {
95 CHECK(parent_ !=
this);
99 mapType &commonBlocks() {
return commonBlocks_; }
100 const mapType &commonBlocks()
const {
return commonBlocks_; }
102 mapType &commonBlockUses() {
return commonBlockUses_; }
103 const mapType &commonBlockUses()
const {
return commonBlockUses_; }
105 Kind kind()
const {
return kind_; }
106 bool IsGlobal()
const {
return kind_ == Kind::Global; }
107 bool IsIntrinsicModules()
const {
return kind_ == Kind::IntrinsicModules; }
108 bool IsTopLevel()
const {
109 return kind_ == Kind::Global || kind_ == Kind::IntrinsicModules;
111 bool IsModule()
const {
112 return kind_ == Kind::Module &&
115 bool IsSubmodule()
const {
116 return kind_ == Kind::Module && symbol_->get<
ModuleDetails>().isSubmodule();
118 bool IsDerivedType()
const {
return kind_ == Kind::DerivedType; }
119 bool IsStmtFunction()
const;
120 bool IsParameterizedDerivedType()
const;
121 bool IsParameterizedDerivedTypeInstantiation()
const {
122 return kind_ == Kind::DerivedType && !symbol_;
128 Symbol *symbol() {
return symbol_; }
129 const Symbol *symbol()
const {
return symbol_; }
132 inline const Symbol *GetSymbol()
const;
133 const Scope *GetDerivedTypeParent()
const;
134 const Scope &GetDerivedTypeBase()
const;
135 inline std::optional<SourceName> GetName()
const;
137 bool Contains(
const Scope &)
const;
145 using size_type = mapType::size_type;
146 using iterator = mapType::iterator;
147 using const_iterator = mapType::const_iterator;
149 iterator begin() {
return symbols_.begin(); }
150 iterator end() {
return symbols_.end(); }
151 const_iterator begin()
const {
return symbols_.begin(); }
152 const_iterator end()
const {
return symbols_.end(); }
153 const_iterator cbegin()
const {
return symbols_.cbegin(); }
154 const_iterator cend()
const {
return symbols_.cend(); }
159 SymbolVector GetSymbols()
const;
160 MutableSymbolVector GetSymbols();
162 iterator find(
const SourceName &name);
163 const_iterator find(
const SourceName &name)
const {
164 return symbols_.find(name);
166 size_type erase(
const SourceName &);
167 bool empty()
const {
return symbols_.empty(); }
170 Symbol *FindSymbol(
const SourceName &)
const;
174 Symbol *FindComponent(SourceName)
const;
178 const SourceName &name, Attrs attrs = Attrs()) {
182 template <
typename D>
184 const SourceName &name, D &&details) {
185 return try_emplace(name, Attrs(), std::move(details));
188 template <
typename D>
190 const SourceName &name, Attrs attrs, D &&details) {
192 return symbols_.emplace(name, symbol);
197 std::list<EquivalenceSet> &equivalenceSets() {
return equivalenceSets_; }
198 const std::list<EquivalenceSet> &equivalenceSets()
const {
199 return equivalenceSets_;
201 void add_equivalenceSet(EquivalenceSet &&);
203 const mapType &crayPointers()
const {
return crayPointers_; }
204 void add_crayPointer(
const SourceName &, Symbol &);
205 Symbol &MakeCommonBlock(SourceName, SourceName location);
206 bool AddCommonBlockUse(
207 const SourceName &name, Attrs attrs, Symbol &cbUltimate);
210 Symbol *FindCommonBlock(
const SourceName &name)
const;
213 Symbol *FindCommonBlockUse(
const SourceName &name)
const;
217 Symbol *FindCommonBlockInVisibleScopes(
const SourceName &)
const;
220 template <
typename D>
222 const SourceName &name, Attrs attrs, D &&details) {
223 return allSymbols.Make(*
this, name, attrs, std::move(details));
226 std::list<Scope> &children() {
return children_; }
227 const std::list<Scope> &children()
const {
return children_; }
231 Scope *FindSubmodule(
const SourceName &)
const;
232 bool AddSubmodule(
const SourceName &, Scope &);
234 const DeclTypeSpec *FindType(
const DeclTypeSpec &)
const;
235 const DeclTypeSpec &MakeNumericType(TypeCategory, KindExpr &&kind);
236 const DeclTypeSpec &MakeLogicalType(KindExpr &&kind);
237 const DeclTypeSpec &MakeCharacterType(
238 ParamValue &&length, KindExpr &&kind = KindExpr{0});
239 DeclTypeSpec &MakeDerivedType(DeclTypeSpec::Category, DerivedTypeSpec &&);
240 const DeclTypeSpec &MakeTypeStarType();
241 const DeclTypeSpec &MakeClassStarType();
242 const DeclTypeSpec *GetType(
const SomeExpr &);
244 std::size_t size()
const {
return size_; }
245 void set_size(std::size_t size) { size_ = size; }
246 std::optional<std::size_t> alignment()
const {
return alignment_; }
248 void SetAlignment(std::size_t n) {
249 alignment_ = std::max(alignment_.value_or(0), n);
252 ImportKind GetImportKind()
const;
254 std::set<SourceName> importNames()
const {
return importNames_; }
255 bool CanImport(
const SourceName &)
const;
259 std::optional<parser::MessageFixedText> SetImportKind(ImportKind);
261 void add_importName(
const SourceName &);
264 const DerivedTypeSpec *derivedTypeSpec()
const {
return derivedTypeSpec_; }
265 DerivedTypeSpec *derivedTypeSpec() {
return derivedTypeSpec_; }
266 void set_derivedTypeSpec(DerivedTypeSpec &spec) { derivedTypeSpec_ = &spec; }
267 parser::Message::Reference instantiationContext()
const {
268 return instantiationContext_;
270 void set_instantiationContext(parser::Message::Reference &&mref) {
271 instantiationContext_ = std::move(mref);
274 bool hasSAVE()
const {
return hasSAVE_; }
275 void set_hasSAVE(
bool yes =
true) { hasSAVE_ = yes; }
278 const parser::CharBlock &sourceRange()
const {
return sourceRange_; }
279 void AddSourceRange(parser::CharBlock);
282 const DeclTypeSpec *FindInstantiatedDerivedType(
const DerivedTypeSpec &,
283 DeclTypeSpec::Category = DeclTypeSpec::TypeDerived)
const;
285 bool IsModuleFile()
const {
286 return kind_ == Kind::Module && symbol_ &&
287 symbol_->test(Symbol::Flag::ModFile);
290 void InstantiateDerivedTypes();
292 const Symbol *runtimeDerivedTypeDescription()
const {
293 return runtimeDerivedTypeDescription_;
295 void set_runtimeDerivedTypeDescription(
const Symbol &symbol) {
296 runtimeDerivedTypeDescription_ = &symbol;
303 std::size_t size_{0};
304 std::optional<std::size_t> alignment_;
305 parser::CharBlock sourceRange_;
306 const parser::CookedSource *cookedSource_{
nullptr};
307 Symbol *
const symbol_;
308 std::list<Scope> children_;
310 mapType commonBlocks_;
311 mapType commonBlockUses_;
312 std::list<EquivalenceSet> equivalenceSets_;
313 mapType crayPointers_;
314 std::map<SourceName, common::Reference<Scope>> submodules_;
315 std::list<DeclTypeSpec> declTypeSpecs_;
316 std::optional<ImportKind> importKind_;
317 std::set<SourceName> importNames_;
318 DerivedTypeSpec *derivedTypeSpec_{
nullptr};
319 parser::Message::Reference instantiationContext_;
320 bool hasSAVE_{
false};
321 const Symbol *runtimeDerivedTypeDescription_{
nullptr};
322 SemanticsContext &context_;
328 static Symbols<1024> allSymbols;
330 const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
332 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Scope &);