9#ifndef FORTRAN_SEMANTICS_SYMBOL_H_
10#define FORTRAN_SEMANTICS_SYMBOL_H_
13#include "flang/Common/Fortran.h"
14#include "flang/Common/enum-set.h"
15#include "flang/Common/reference.h"
16#include "flang/Common/visit.h"
17#include "flang/Semantics/module-dependences.h"
18#include "llvm/ADT/DenseMapInfo.h"
34namespace Fortran::semantics {
44using SymbolRef = common::Reference<const Symbol>;
45using SymbolVector = std::vector<SymbolRef>;
46using MutableSymbolRef = common::Reference<Symbol>;
47using MutableSymbolVector = std::vector<MutableSymbolRef>;
51 using OmpAtomicOrderType = common::OmpAtomicDefaultMemOrderType;
54 ENUM_CLASS(RequiresFlag, ReverseOffload, UnifiedAddress, UnifiedSharedMemory,
58 bool has_ompRequires()
const {
return ompRequires_.has_value(); }
60 return ompRequires_ ? &*ompRequires_ :
nullptr;
62 void set_ompRequires(
RequiresFlags flags) { ompRequires_ = flags; }
64 bool has_ompAtomicDefaultMemOrder()
const {
65 return ompAtomicDefaultMemOrder_.has_value();
67 const OmpAtomicOrderType *ompAtomicDefaultMemOrder()
const {
68 return ompAtomicDefaultMemOrder_ ? &*ompAtomicDefaultMemOrder_ :
nullptr;
70 void set_ompAtomicDefaultMemOrder(OmpAtomicOrderType flags) {
71 ompAtomicDefaultMemOrder_ = flags;
75 std::optional<RequiresFlags> ompRequires_;
76 std::optional<OmpAtomicOrderType> ompAtomicDefaultMemOrder_;
82 ModuleDetails(
bool isSubmodule =
false) : isSubmodule_{isSubmodule} {}
83 bool isSubmodule()
const {
return isSubmodule_; }
84 const Scope *scope()
const {
return scope_; }
85 const Scope *ancestor()
const;
86 const Scope *parent()
const;
87 void set_scope(
const Scope *);
88 bool isDefaultPrivate()
const {
return isDefaultPrivate_; }
89 void set_isDefaultPrivate(
bool yes =
true) { isDefaultPrivate_ = yes; }
90 std::optional<ModuleCheckSumType> moduleFileHash()
const {
91 return moduleFileHash_;
93 void set_moduleFileHash(ModuleCheckSumType x) { moduleFileHash_ = x; }
94 const Symbol *previous()
const {
return previous_; }
95 void set_previous(
const Symbol *p) { previous_ = p; }
99 bool isDefaultPrivate_{
false};
100 const Scope *scope_{
nullptr};
101 std::optional<ModuleCheckSumType> moduleFileHash_;
102 const Symbol *previous_{
nullptr};
112 const std::string *bindName()
const {
113 return bindName_ ? &*bindName_ :
nullptr;
115 bool isExplicitBindName()
const {
return isExplicitBindName_; }
116 void set_bindName(std::string &&name) { bindName_ = std::move(name); }
117 void set_isExplicitBindName(
bool yes) { isExplicitBindName_ = yes; }
118 bool isCDefined()
const {
return isCDefined_; }
119 void set_isCDefined(
bool yes) { isCDefined_ = yes; }
122 std::optional<std::string> bindName_;
123 bool isExplicitBindName_{
false};
124 bool isCDefined_{
false};
130 bool isSeq()
const {
return isSeq_; }
131 void set_isSeq(
bool value =
true) { isSeq_ = value; }
132 bool isVector()
const {
return isVector_; }
133 void set_isVector(
bool value =
true) { isVector_ = value; }
134 bool isWorker()
const {
return isWorker_; }
135 void set_isWorker(
bool value =
true) { isWorker_ = value; }
136 bool isGang()
const {
return isGang_; }
137 void set_isGang(
bool value =
true) { isGang_ = value; }
138 unsigned gangDim()
const {
return gangDim_; }
139 void set_gangDim(
unsigned value) { gangDim_ = value; }
140 const std::string *bindName()
const {
141 return bindName_ ? &*bindName_ :
nullptr;
143 void set_bindName(std::string &&name) { bindName_ = std::move(name); }
144 void set_dType(Fortran::common::OpenACCDeviceType dType) {
147 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
151 bool isVector_{
false};
152 bool isWorker_{
false};
154 unsigned gangDim_{0};
155 std::optional<std::string> bindName_;
156 Fortran::common::OpenACCDeviceType deviceType_{
157 Fortran::common::OpenACCDeviceType::None};
165 bool isNohost()
const {
return isNohost_; }
166 void set_isNohost(
bool value =
true) { isNohost_ = value; }
167 std::list<OpenACCRoutineDeviceTypeInfo> &deviceTypeInfos() {
168 return deviceTypeInfos_;
171 deviceTypeInfos_.push_back(info);
175 std::list<OpenACCRoutineDeviceTypeInfo> deviceTypeInfos_;
176 bool isNohost_{
false};
184 bool isFunction()
const {
return result_ !=
nullptr; }
185 bool isInterface()
const {
return isInterface_; }
186 void set_isInterface(
bool value =
true) { isInterface_ = value; }
187 bool isDummy()
const {
return isDummy_; }
188 void set_isDummy(
bool value =
true) { isDummy_ = value; }
189 Scope *entryScope() {
return entryScope_; }
190 const Scope *entryScope()
const {
return entryScope_; }
191 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
192 const Symbol &result()
const {
196 void set_result(
Symbol &result) {
200 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
201 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
202 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
203 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
204 void set_stmtFunction(
SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
205 Symbol *moduleInterface() {
return moduleInterface_; }
206 const Symbol *moduleInterface()
const {
return moduleInterface_; }
207 void set_moduleInterface(
Symbol &);
208 void ReplaceResult(
Symbol &result) {
209 CHECK(result_ !=
nullptr);
212 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
213 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
214 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
215 return cudaSubprogramAttrs_;
217 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
218 cudaSubprogramAttrs_ = csas;
220 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
221 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
222 return cudaLaunchBounds_;
224 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
225 cudaLaunchBounds_ = std::move(x);
227 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
228 const std::vector<std::int64_t> &cudaClusterDims()
const {
229 return cudaClusterDims_;
231 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
232 cudaClusterDims_ = std::move(x);
234 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
235 return openACCRoutineInfos_;
238 openACCRoutineInfos_.push_back(info);
242 bool isInterface_{
false};
243 bool isDummy_{
false};
244 std::vector<Symbol *> dummyArgs_;
246 Scope *entryScope_{
nullptr};
247 MaybeExpr stmtFunction_;
251 Symbol *moduleInterface_{
nullptr};
252 bool defaultIgnoreTKR_{
false};
254 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
256 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
258 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
260 friend llvm::raw_ostream &operator<<(
266ENUM_CLASS(SubprogramKind, Module, Internal)
275 : kind_{kind}, node_{node} {}
277 SubprogramKind kind()
const {
return kind_; }
281 SubprogramKind kind_;
288 explicit EntityDetails(
bool isDummy =
false) : isDummy_{isDummy} {}
292 bool isDummy()
const {
return isDummy_; }
293 void set_isDummy(
bool value =
true) { isDummy_ = value; }
294 bool isFuncResult()
const {
return isFuncResult_; }
295 void set_funcResult(
bool x) { isFuncResult_ = x; }
298 bool isDummy_{
false};
299 bool isFuncResult_{
false};
301 friend llvm::raw_ostream &operator<<(
315 const MaybeExpr &expr()
const {
return expr_; }
320 std::optional<int> rank()
const {
321 int r{rank_.value_or(0)};
322 if (r == isAssumedSize) {
324 }
else if (r == isAssumedRank) {
330 bool IsAssumedSize()
const {
return rank_.value_or(0) == isAssumedSize; }
331 bool IsAssumedRank()
const {
return rank_.value_or(0) == isAssumedRank; }
332 void set_rank(
int rank);
333 void set_IsAssumedSize();
334 void set_IsAssumedRank();
340 static constexpr int isAssumedSize{-1};
341 static constexpr int isAssumedRank{-2};
342 std::optional<int> rank_;
354 MaybeExpr &init() {
return init_; }
355 const MaybeExpr &init()
const {
return init_; }
356 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
357 const parser::Expr *unanalyzedPDTComponentInit()
const {
358 return unanalyzedPDTComponentInit_;
360 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
361 unanalyzedPDTComponentInit_ = expr;
364 const ArraySpec &shape()
const {
return shape_; }
365 ArraySpec &coshape() {
return coshape_; }
366 const ArraySpec &coshape()
const {
return coshape_; }
369 const Symbol *commonBlock()
const {
return commonBlock_; }
370 void set_commonBlock(
const Symbol &commonBlock) {
371 commonBlock_ = &commonBlock;
373 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
374 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
375 bool IsArray()
const {
return !shape_.empty(); }
376 bool IsCoarray()
const {
return !coshape_.empty(); }
377 bool IsAssumedShape()
const {
378 return isDummy() && shape_.CanBeAssumedShape();
380 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
381 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
382 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
383 return cudaDataAttr_;
385 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
386 cudaDataAttr_ = attr;
391 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
394 common::IgnoreTKRSet ignoreTKR_;
395 const Symbol *commonBlock_{
nullptr};
396 std::optional<common::CUDADataAttr> cudaDataAttr_;
397 friend llvm::raw_ostream &operator<<(
408 std::optional<SourceName> passName()
const {
return passName_; }
409 void set_passName(
const SourceName &passName) { passName_ = passName; }
412 std::optional<SourceName> passName_;
426 const Symbol *rawProcInterface()
const {
return rawProcInterface_; }
427 const Symbol *procInterface()
const {
return procInterface_; }
428 void set_procInterfaces(
const Symbol &raw,
const Symbol &resolved) {
429 rawProcInterface_ = &raw;
430 procInterface_ = &resolved;
432 inline bool HasExplicitInterface()
const;
436 std::optional<const Symbol *> init()
const {
return init_; }
437 void set_init(
const Symbol &symbol) { init_ = &symbol; }
438 void set_init(std::nullptr_t) { init_ =
nullptr; }
439 bool isCUDAKernel()
const {
return isCUDAKernel_; }
440 void set_isCUDAKernel(
bool yes =
true) { isCUDAKernel_ = yes; }
441 std::optional<SourceName> usedAsProcedureHere()
const {
442 return usedAsProcedureHere_;
444 void set_usedAsProcedureHere(
SourceName here) { usedAsProcedureHere_ = here; }
447 const Symbol *rawProcInterface_{
nullptr};
448 const Symbol *procInterface_{
nullptr};
449 std::optional<const Symbol *> init_;
450 bool isCUDAKernel_{
false};
451 std::optional<SourceName> usedAsProcedureHere_;
452 friend llvm::raw_ostream &operator<<(
463 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
464 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
465 bool sequence()
const {
return sequence_; }
466 bool isDECStructure()
const {
return isDECStructure_; }
467 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
468 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
469 bool isForwardReferenced()
const {
return isForwardReferenced_; }
470 void add_paramNameOrder(
const Symbol &symbol) {
471 paramNameOrder_.push_back(symbol);
473 void add_paramDeclOrder(
const Symbol &symbol) {
474 paramDeclOrder_.push_back(symbol);
476 void add_component(
const Symbol &);
477 void set_sequence(
bool x =
true) { sequence_ = x; }
478 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
479 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
480 const std::list<SourceName> &componentNames()
const {
481 return componentNames_;
485 const Symbol *GetParentComponent(
const Scope &)
const;
487 std::optional<SourceName> GetParentComponentName()
const {
488 if (componentNames_.empty()) {
491 return componentNames_.front();
495 const Symbol *GetFinalForRank(
int)
const;
502 SymbolVector paramNameOrder_;
503 SymbolVector paramDeclOrder_;
506 std::list<SourceName> componentNames_;
507 std::map<SourceName, SymbolRef> finals_;
508 bool sequence_{
false};
509 bool isDECStructure_{
false};
510 bool isForwardReferenced_{
false};
511 friend llvm::raw_ostream &operator<<(
518 const Symbol &symbol()
const {
return symbol_; }
519 void ReplaceSymbol(
const Symbol &symbol) { symbol_ = symbol; }
520 int numPrivatesNotOverridden()
const {
return numPrivatesNotOverridden_; }
521 void set_numPrivatesNotOverridden(
int n) { numPrivatesNotOverridden_ = n; }
526 int numPrivatesNotOverridden_{0};
531 const SymbolVector &objects()
const {
return objects_; }
532 void add_object(
const Symbol &
object) { objects_.push_back(
object); }
533 void add_objects(
const SymbolVector &objects) {
534 objects_.insert(objects_.end(), objects.begin(), objects.end());
538 SymbolVector objects_;
543 MutableSymbolVector &objects() {
return objects_; }
544 const MutableSymbolVector &objects()
const {
return objects_; }
545 void add_object(
Symbol &
object) { objects_.emplace_back(
object); }
546 void replace_object(
Symbol &
object,
unsigned index) {
547 CHECK(index < (
unsigned)objects_.size());
548 objects_[index] = object;
550 std::size_t alignment()
const {
return alignment_; }
551 void set_alignment(std::size_t alignment) { alignment_ = alignment; }
554 MutableSymbolVector objects_;
555 std::size_t alignment_{0};
560 ENUM_CLASS(Kind, None, ConstructName, ScopeName, PassName, ComplexPartRe,
561 ComplexPartIm, KindParamInquiry, LenParamInquiry, SelectRankAssociateName,
562 SelectTypeAssociateName, TypeBoundDefinedOp);
564 Kind kind()
const {
return kind_; }
574 std::optional<common::TypeParamAttr> attr()
const {
return attr_; }
576 MaybeIntExpr &init() {
return init_; }
577 const MaybeIntExpr &init()
const {
return init_; }
578 void set_init(MaybeIntExpr &&expr) { init_ = std::move(expr); }
584 std::optional<common::TypeParamAttr> attr_;
594 : location_{location}, symbol_{symbol} {}
595 const SourceName &location()
const {
return location_; }
596 const Symbol &symbol()
const {
return symbol_; }
609 using listType = std::list<std::pair<SourceName, const Scope *>>;
610 const listType occurrences()
const {
return occurrences_; };
613 listType occurrences_;
620 const Symbol &symbol()
const {
return symbol_; }
621 bool implicitOrSpecExprError{
false};
622 bool implicitOrExplicitTypeError{
false};
631 ENUM_CLASS(OtherKind, Name, DefinedOp, Assignment, Concat)
633 template <
typename T>
GenericKind(
const T &x) { u = x; }
634 bool IsName()
const {
return Is(OtherKind::Name); }
635 bool IsAssignment()
const {
return Is(OtherKind::Assignment); }
636 bool IsDefinedOperator()
const {
return Is(OtherKind::DefinedOp); }
637 bool IsIntrinsicOperator()
const;
638 bool IsOperator()
const;
639 std::string ToString()
const;
640 static SourceName AsFortran(common::DefinedIo);
641 std::variant<OtherKind, common::NumericOperator, common::LogicalOperator,
642 common::RelationalOperator, common::DefinedIo>
646 template <
typename T>
bool Has()
const {
647 return std::holds_alternative<T>(u);
649 bool Is(OtherKind)
const;
660 const SymbolVector &specificProcs()
const {
return specificProcs_; }
661 const std::vector<SourceName> &bindingNames()
const {
return bindingNames_; }
663 const SymbolVector &uses()
const {
return uses_; }
669 Symbol *specific() {
return specific_; }
670 const Symbol *specific()
const {
return specific_; }
671 void set_specific(
Symbol &specific);
672 void clear_specific();
673 Symbol *derivedType() {
return derivedType_; }
674 const Symbol *derivedType()
const {
return derivedType_; }
675 void set_derivedType(
Symbol &derivedType);
676 void clear_derivedType();
677 void AddUse(
const Symbol &);
684 const Symbol *CheckSpecific()
const;
690 SymbolVector specificProcs_;
691 std::vector<SourceName> bindingNames_;
695 Symbol *specific_{
nullptr};
697 Symbol *derivedType_{
nullptr};
699llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const GenericDetails &);
709llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Details &);
710std::string DetailsToString(
const Details &);
722 CrayPointer, CrayPointee,
735 AccPrivate, AccFirstPrivate, AccShared,
737 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
738 AccPresent, AccLink, AccDeviceResident, AccDevicePtr,
742 AccDevice, AccHost, AccSelf,
744 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
746 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
748 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapAlloc, OmpMapRelease,
749 OmpMapDelete, OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr,
752 OmpCopyIn, OmpCopyPrivate,
754 OmpCommonBlock, OmpReduction, OmpAligned, OmpNontemporal, OmpAllocate,
755 OmpDeclarativeAllocateDirective, OmpExecutableAllocateDirective,
756 OmpDeclareSimd, OmpDeclareTarget, OmpThreadprivate, OmpDeclareReduction,
757 OmpFlushed, OmpCriticalLock, OmpIfSpecified, OmpNone, OmpPreDetermined,
758 OmpImplicit, OmpDependObject, OmpInclusiveScan, OmpExclusiveScan,
762 const Scope &owner()
const {
return *owner_; }
763 const SourceName &name()
const {
return name_; }
764 Attrs &attrs() {
return attrs_; }
765 const Attrs &attrs()
const {
return attrs_; }
766 Attrs &implicitAttrs() {
return implicitAttrs_; }
767 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
768 Flags &flags() {
return flags_; }
769 const Flags &flags()
const {
return flags_; }
770 bool test(Flag flag)
const {
return flags_.test(flag); }
771 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
773 Scope *scope() {
return scope_; }
774 const Scope *scope()
const {
return scope_; }
775 void set_scope(
Scope *scope) { scope_ = scope; }
776 std::size_t size()
const {
return size_; }
777 void set_size(std::size_t size) { size_ = size; }
778 std::size_t offset()
const {
return offset_; }
779 void set_offset(std::size_t offset) { offset_ = offset; }
782 static std::string OmpFlagToClauseName(Flag ompFlag);
785 template <
typename D>
bool has()
const {
786 return std::holds_alternative<D>(details_);
790 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
791 template <
typename D>
const D *detailsIf()
const {
792 return std::get_if<D>(&details_);
796 template <
typename D> D &get() {
797 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
799 template <
typename D>
const D &get()
const {
800 const auto *p{detailsIf<D>()};
805 Details &details() {
return details_; }
806 const Details &details()
const {
return details_; }
809 void set_details(Details &&);
812 bool CanReplaceDetails(
const Details &details)
const;
815 inline Symbol &GetUltimate();
816 inline const Symbol &GetUltimate()
const;
822 const std::string *GetBindName()
const;
823 void SetBindName(std::string &&);
824 bool GetIsExplicitBindName()
const;
825 void SetIsExplicitBindName(
bool);
826 void SetIsCDefined(
bool);
827 bool IsFuncResult()
const;
828 bool IsObjectArray()
const;
830 bool IsSubprogram()
const;
831 bool IsFromModFile()
const;
832 bool HasExplicitInterface()
const {
833 return common::visit(
838 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
841 return x.symbol().HasExplicitInterface();
844 return x.symbol().HasExplicitInterface();
847 return x.symbol().HasExplicitInterface();
850 return x.specific() && x.specific()->HasExplicitInterface();
852 [](
const auto &) {
return false; },
856 bool HasLocalLocality()
const {
857 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
860 bool operator==(
const Symbol &that)
const {
return this == &that; }
861 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
863 int Rank()
const {
return RankImpl(); }
864 int Corank()
const {
return CorankImpl(); }
874 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
877#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
878 LLVM_DUMP_METHOD
void dump()
const;
885 Attrs implicitAttrs_;
887 Scope *scope_{
nullptr};
888 std::size_t size_{0};
889 std::size_t offset_{0};
893 std::string GetDetailsName()
const;
894 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
895 friend llvm::raw_ostream &DumpForUnparse(
896 llvm::raw_ostream &,
const Symbol &,
bool);
898 static constexpr int startRecursionDepth{100};
900 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
901 inline int RankImpl(
int depth = startRecursionDepth)
const {
905 return common::visit(
908 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
914 return x.symbol().RankImpl(depth);
916 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
918 return x.symbol().RankImpl(depth);
922 const Symbol *iface{ped.procInterface()};
923 return iface ? iface->RankImpl(depth) : 0;
926 if (
auto assocRank{aed.rank()}) {
929 }
else if (aed.IsAssumedRank()) {
932 }
else if (
const auto &expr{aed.expr()}) {
938 [](
const auto &) {
return 0; },
942 inline int CorankImpl(
int depth = startRecursionDepth)
const {
946 return common::visit(
949 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
953 const Symbol *iface{ped.procInterface()};
954 return iface ? iface->CorankImpl(depth) : 0;
956 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
958 return x.symbol().CorankImpl(depth);
962 return aed.expr() ? aed.expr()->Corank() : 0;
964 [](
const auto &) {
return 0; },
968 template <std::
size_t>
friend class Symbols;
969 template <
class, std::
size_t>
friend class std::array;
972llvm::raw_ostream &operator<<(llvm::raw_ostream &, Symbol::Flag);
977template <std::
size_t BLOCK_SIZE>
class Symbols {
982 symbol.owner_ = &owner;
984 symbol.attrs_ = attrs;
985 symbol.details_ = std::move(details);
990 using blockType = std::array<Symbol, BLOCK_SIZE>;
991 std::list<blockType *> blocks_;
992 std::size_t nextIndex_{0};
993 blockType *currBlock_{
nullptr};
996 if (nextIndex_ == 0) {
997 blocks_.push_back(
new blockType());
998 currBlock_ = blocks_.back();
1000 Symbol &result = (*currBlock_)[nextIndex_];
1001 if (++nextIndex_ >= BLOCK_SIZE) {
1012inline bool ProcEntityDetails::HasExplicitInterface()
const {
1013 return procInterface_ && procInterface_->HasExplicitInterface();
1016inline Symbol &Symbol::GetUltimate() {
1017 return const_cast<Symbol &
>(
const_cast<const Symbol *
>(
this)->GetUltimate());
1019inline const Symbol &Symbol::GetUltimate()
const {
1020 if (
const auto *details{detailsIf<UseDetails>()}) {
1021 return details->symbol().GetUltimate();
1022 }
else if (
const auto *details{detailsIf<HostAssocDetails>()}) {
1023 return details->symbol().GetUltimate();
1029inline DeclTypeSpec *Symbol::GetType() {
1030 return const_cast<DeclTypeSpec *
>(
1031 const_cast<const Symbol *
>(
this)->GetType());
1034inline const DeclTypeSpec *Symbol::GetTypeImpl(
int depth)
const {
1038 return common::visit(
1040 [](
const EntityDetails &x) {
return x.type(); },
1041 [](
const ObjectEntityDetails &x) {
return x.type(); },
1042 [](
const AssocEntityDetails &x) {
return x.type(); },
1043 [&](
const SubprogramDetails &x) {
1044 return x.isFunction() ? x.result().GetTypeImpl(depth) :
nullptr;
1046 [&](
const ProcEntityDetails &x) {
1047 const Symbol *symbol{x.procInterface()};
1048 return symbol ? symbol->GetTypeImpl(depth) : x.type();
1050 [&](
const ProcBindingDetails &x) {
1051 return x.symbol().GetTypeImpl(depth);
1053 [](
const TypeParamDetails &x) {
return x.type(); },
1054 [&](
const UseDetails &x) {
return x.symbol().GetTypeImpl(depth); },
1055 [&](
const HostAssocDetails &x) {
1056 return x.symbol().GetTypeImpl(depth);
1058 [](
const auto &) ->
const DeclTypeSpec * {
return nullptr; },
1063inline const DeclTypeSpec *Symbol::GetType()
const {
return GetTypeImpl(); }
1093using UnorderedSymbolSet = std::set<SymbolRef, SymbolAddressCompare>;
1094using SourceOrderedSymbolSet = std::set<SymbolRef, SymbolSourcePositionCompare>;
1096template <
typename A>
1097SourceOrderedSymbolSet OrderBySourcePosition(
const A &container) {
1098 SourceOrderedSymbolSet result;
1109template <>
struct DenseMapInfo<
Fortran::semantics::SymbolRef> {
1111 auto ptr = DenseMapInfo<const Fortran::semantics::Symbol *>::getEmptyKey();
1117 DenseMapInfo<const Fortran::semantics::Symbol *>::getTombstoneKey();
1122 return DenseMapInfo<const Fortran::semantics::Symbol *>::getHashValue(
Definition: enum-set.h:28
Definition: reference.h:18
Definition: char-block.h:28
Definition: program-tree.h:31
Definition: semantics.h:67
Definition: check-expression.h:19
Definition: bit-population-count.h:20
Definition: parse-tree.h:1700
Definition: symbol.h:1067
Definition: symbol.h:1088
Definition: symbol.h:1081