70 using mapType = std::map<SourceName, MutableSymbolRef>;
73 ENUM_CLASS(Kind, Global, IntrinsicModules, Module, MainProgram, Subprogram,
74 BlockData, DerivedType, BlockConstruct, Forall, OtherConstruct,
75 OpenACCConstruct, ImpliedDos, OtherClause)
76 using ImportKind = common::ImportKind;
80 : Scope{*
this, Kind::Global,
nullptr, context} {}
82 : parent_{&parent}, kind_{kind}, symbol_{symbol}, context_{context} {
84 symbol->set_scope(
this);
87 Scope(
const Scope &) =
delete;
89 bool operator==(
const Scope &that)
const {
return this == &that; }
90 bool operator!=(
const Scope &that)
const {
return this != &that; }
93 CHECK(parent_ !=
this);
96 const Scope &parent()
const {
97 CHECK(parent_ !=
this);
101 mapType &commonBlocks() {
return commonBlocks_; }
102 const mapType &commonBlocks()
const {
return commonBlocks_; }
104 mapType &commonBlockUses() {
return commonBlockUses_; }
105 const mapType &commonBlockUses()
const {
return commonBlockUses_; }
107 Kind kind()
const {
return kind_; }
108 bool IsGlobal()
const {
return kind_ == Kind::Global; }
109 bool IsIntrinsicModules()
const {
return kind_ == Kind::IntrinsicModules; }
110 bool IsTopLevel()
const {
111 return kind_ == Kind::Global || kind_ == Kind::IntrinsicModules;
113 bool IsModule()
const {
114 return kind_ == Kind::Module &&
117 bool IsSubmodule()
const {
118 return kind_ == Kind::Module && symbol_->get<
ModuleDetails>().isSubmodule();
120 bool IsDerivedType()
const {
return kind_ == Kind::DerivedType; }
121 bool IsStmtFunction()
const;
122 bool IsParameterizedDerivedType()
const;
123 bool IsParameterizedDerivedTypeInstantiation()
const {
124 return kind_ == Kind::DerivedType && !symbol_;
130 Symbol *symbol() {
return symbol_; }
131 const Symbol *symbol()
const {
return symbol_; }
134 inline const Symbol *GetSymbol()
const;
135 const Scope *GetDerivedTypeParent()
const;
136 const Scope &GetDerivedTypeBase()
const;
137 inline std::optional<SourceName> GetName()
const;
139 bool Contains(
const Scope &)
const;
147 using size_type = mapType::size_type;
148 using iterator = mapType::iterator;
149 using const_iterator = mapType::const_iterator;
151 iterator begin() {
return symbols_.begin(); }
152 iterator end() {
return symbols_.end(); }
153 const_iterator begin()
const {
return symbols_.begin(); }
154 const_iterator end()
const {
return symbols_.end(); }
155 const_iterator cbegin()
const {
return symbols_.cbegin(); }
156 const_iterator cend()
const {
return symbols_.cend(); }
161 SymbolVector GetSymbols()
const;
162 MutableSymbolVector GetSymbols();
164 iterator find(
const SourceName &name);
165 const_iterator find(
const SourceName &name)
const {
166 return symbols_.find(name);
168 size_type erase(
const SourceName &);
169 bool empty()
const {
return symbols_.empty(); }
172 Symbol *FindSymbol(
const SourceName &)
const;
176 Symbol *FindComponent(SourceName)
const;
180 const SourceName &name, Attrs attrs = Attrs()) {
184 template <
typename D>
186 const SourceName &name, D &&details) {
187 return try_emplace(name, Attrs(), std::move(details));
190 template <
typename D>
192 const SourceName &name, Attrs attrs, D &&details) {
194 return symbols_.emplace(name, symbol);
199 std::list<EquivalenceSet> &equivalenceSets() {
return equivalenceSets_; }
200 const std::list<EquivalenceSet> &equivalenceSets()
const {
201 return equivalenceSets_;
203 void add_equivalenceSet(EquivalenceSet &&);
205 const mapType &crayPointers()
const {
return crayPointers_; }
206 void add_crayPointer(
const SourceName &, Symbol &);
207 Symbol &MakeCommonBlock(SourceName, SourceName location);
208 bool AddCommonBlockUse(
209 const SourceName &name, Attrs attrs, Symbol &cbUltimate);
212 Symbol *FindCommonBlock(
const SourceName &name)
const;
215 Symbol *FindCommonBlockUse(
const SourceName &name)
const;
219 Symbol *FindCommonBlockInVisibleScopes(
const SourceName &)
const;
222 template <
typename D>
224 const SourceName &name, Attrs attrs, D &&details) {
225 return allSymbols.Make(*
this, name, attrs, std::move(details));
228 std::list<Scope> &children() {
return children_; }
229 const std::list<Scope> &children()
const {
return children_; }
233 Scope *FindSubmodule(
const SourceName &)
const;
234 bool AddSubmodule(
const SourceName &, Scope &);
236 const DeclTypeSpec *FindType(
const DeclTypeSpec &)
const;
237 const DeclTypeSpec &MakeNumericType(TypeCategory, KindExpr &&kind);
238 const DeclTypeSpec &MakeLogicalType(KindExpr &&kind);
239 const DeclTypeSpec &MakeCharacterType(ParamValue &&length, KindExpr &&kind);
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; }
278 const std::set<llvm::omp::Directive> &ompAssumesAbsent()
const {
279 return ompAssumesAbsent_;
281 void add_ompAssumesAbsent(llvm::omp::Directive directive) {
282 ompAssumesAbsent_.insert(directive);
286 const parser::CharBlock &sourceRange()
const {
return sourceRange_; }
287 void AddSourceRange(parser::CharBlock);
292 void AddOpenACCMappedSymbol(
const Symbol &symbol) {
293 openACCMappedSymbols_.insert(symbol.GetUltimate());
295 bool IsOpenACCMappedSymbol(
const Symbol &symbol)
const {
296 return openACCMappedSymbols_.count(symbol.GetUltimate()) != 0;
300 const DeclTypeSpec *FindInstantiatedDerivedType(
const DerivedTypeSpec &,
301 DeclTypeSpec::Category = DeclTypeSpec::TypeDerived)
const;
303 bool IsModuleFile()
const {
304 return kind_ == Kind::Module && symbol_ &&
305 symbol_->test(Symbol::Flag::ModFile);
308 void InstantiateDerivedTypes();
310 const Symbol *runtimeDerivedTypeDescription()
const {
311 return runtimeDerivedTypeDescription_;
313 void set_runtimeDerivedTypeDescription(
const Symbol &symbol) {
314 runtimeDerivedTypeDescription_ = &symbol;
321 std::size_t size_{0};
322 std::optional<std::size_t> alignment_;
323 parser::CharBlock sourceRange_;
324 const parser::CookedSource *cookedSource_{
nullptr};
325 Symbol *
const symbol_;
326 std::list<Scope> children_;
328 mapType commonBlocks_;
329 mapType commonBlockUses_;
330 std::list<EquivalenceSet> equivalenceSets_;
331 mapType crayPointers_;
332 std::map<SourceName, common::Reference<Scope>> submodules_;
333 std::list<DeclTypeSpec> declTypeSpecs_;
334 std::optional<ImportKind> importKind_;
335 std::set<SourceName> importNames_;
336 UnorderedSymbolSet openACCMappedSymbols_;
337 std::set<llvm::omp::Directive> ompAssumesAbsent_;
338 DerivedTypeSpec *derivedTypeSpec_{
nullptr};
339 parser::Message::Reference instantiationContext_;
340 bool hasSAVE_{
false};
341 const Symbol *runtimeDerivedTypeDescription_{
nullptr};
342 SemanticsContext &context_;
348 static Symbols<1024> allSymbols;
350 const DeclTypeSpec &MakeLengthlessType(DeclTypeSpec &&);
352 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Scope &);