133class OpenACCRoutineDeviceTypeInfo {
135 explicit OpenACCRoutineDeviceTypeInfo(
136 Fortran::common::OpenACCDeviceType dType)
137 : deviceType_{dType} {}
138 bool isSeq()
const {
return isSeq_; }
139 void set_isSeq(
bool value =
true) { isSeq_ = value; }
140 bool isVector()
const {
return isVector_; }
141 void set_isVector(
bool value =
true) { isVector_ = value; }
142 bool isWorker()
const {
return isWorker_; }
143 void set_isWorker(
bool value =
true) { isWorker_ = value; }
144 bool isGang()
const {
return isGang_; }
145 void set_isGang(
bool value =
true) { isGang_ = value; }
146 unsigned gangDim()
const {
return gangDim_; }
147 void set_gangDim(
unsigned value) { gangDim_ = value; }
148 const std::variant<std::string, SymbolRef> *bindName()
const {
149 return bindName_.has_value() ? &*bindName_ :
nullptr;
151 const std::optional<std::variant<std::string, SymbolRef>> &
152 bindNameOpt()
const {
155 void set_bindName(std::string &&name) { bindName_.emplace(std::move(name)); }
156 void set_bindName(SymbolRef symbol) { bindName_.emplace(symbol); }
158 Fortran::common::OpenACCDeviceType dType()
const {
return deviceType_; }
160 friend llvm::raw_ostream &operator<<(
161 llvm::raw_ostream &,
const OpenACCRoutineDeviceTypeInfo &);
165 bool isVector_{
false};
166 bool isWorker_{
false};
168 unsigned gangDim_{0};
171 std::optional<std::variant<std::string, SymbolRef>> bindName_;
172 Fortran::common::OpenACCDeviceType deviceType_{
173 Fortran::common::OpenACCDeviceType::None};
214 bool isFunction()
const {
return result_ !=
nullptr; }
215 bool isInterface()
const {
return isInterface_; }
216 void set_isInterface(
bool value =
true) { isInterface_ = value; }
217 bool isDummy()
const {
return isDummy_; }
218 void set_isDummy(
bool value =
true) { isDummy_ = value; }
219 Scope *entryScope() {
return entryScope_; }
220 const Scope *entryScope()
const {
return entryScope_; }
221 void set_entryScope(
Scope &scope) { entryScope_ = &scope; }
222 const Symbol &result()
const {
226 void set_result(
Symbol &result) {
230 const std::vector<Symbol *> &dummyArgs()
const {
return dummyArgs_; }
231 void add_dummyArg(
Symbol &symbol) { dummyArgs_.push_back(&symbol); }
232 void add_alternateReturn() { dummyArgs_.push_back(
nullptr); }
233 const MaybeExpr &stmtFunction()
const {
return stmtFunction_; }
234 void set_stmtFunction(SomeExpr &&expr) { stmtFunction_ = std::move(expr); }
235 Symbol *moduleInterface() {
return moduleInterface_; }
236 const Symbol *moduleInterface()
const {
return moduleInterface_; }
237 void set_moduleInterface(
Symbol &);
238 void ReplaceResult(
Symbol &result) {
239 CHECK(result_ !=
nullptr);
242 bool defaultIgnoreTKR()
const {
return defaultIgnoreTKR_; }
243 void set_defaultIgnoreTKR(
bool yes) { defaultIgnoreTKR_ = yes; }
244 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs()
const {
245 return cudaSubprogramAttrs_;
247 void set_cudaSubprogramAttrs(common::CUDASubprogramAttrs csas) {
248 cudaSubprogramAttrs_ = csas;
250 std::vector<std::int64_t> &cudaLaunchBounds() {
return cudaLaunchBounds_; }
251 const std::vector<std::int64_t> &cudaLaunchBounds()
const {
252 return cudaLaunchBounds_;
254 void set_cudaLaunchBounds(std::vector<std::int64_t> &&x) {
255 cudaLaunchBounds_ = std::move(x);
257 std::vector<std::int64_t> &cudaClusterDims() {
return cudaClusterDims_; }
258 const std::vector<std::int64_t> &cudaClusterDims()
const {
259 return cudaClusterDims_;
261 void set_cudaClusterDims(std::vector<std::int64_t> &&x) {
262 cudaClusterDims_ = std::move(x);
264 const std::vector<OpenACCRoutineInfo> &openACCRoutineInfos()
const {
265 return openACCRoutineInfos_;
268 openACCRoutineInfos_.push_back(info);
272 bool isInterface_{
false};
273 bool isDummy_{
false};
274 std::vector<Symbol *> dummyArgs_;
276 Scope *entryScope_{
nullptr};
277 MaybeExpr stmtFunction_;
281 Symbol *moduleInterface_{
nullptr};
282 bool defaultIgnoreTKR_{
false};
284 std::optional<common::CUDASubprogramAttrs> cudaSubprogramAttrs_;
286 std::vector<std::int64_t> cudaLaunchBounds_, cudaClusterDims_;
288 std::vector<OpenACCRoutineInfo> openACCRoutineInfos_;
290 friend llvm::raw_ostream &operator<<(
380class ObjectEntityDetails :
public EntityDetails {
382 explicit ObjectEntityDetails(EntityDetails &&);
383 ObjectEntityDetails(
const ObjectEntityDetails &) =
default;
384 ObjectEntityDetails(ObjectEntityDetails &&) =
default;
385 ObjectEntityDetails &operator=(
const ObjectEntityDetails &) =
default;
386 ObjectEntityDetails(
bool isDummy =
false) : EntityDetails(isDummy) {}
387 MaybeExpr &init() {
return init_; }
388 const MaybeExpr &init()
const {
return init_; }
389 void set_init(MaybeExpr &&expr) { init_ = std::move(expr); }
390 const parser::Expr *unanalyzedPDTComponentInit()
const {
391 return unanalyzedPDTComponentInit_;
393 void set_unanalyzedPDTComponentInit(
const parser::Expr *expr) {
394 unanalyzedPDTComponentInit_ = expr;
397 const ArraySpec &shape()
const {
return shape_; }
398 ArraySpec &coshape() {
return coshape_; }
399 const ArraySpec &coshape()
const {
return coshape_; }
402 const Symbol *commonBlock()
const {
return commonBlock_; }
403 void set_commonBlock(
const Symbol &commonBlock) {
404 commonBlock_ = &commonBlock;
406 common::IgnoreTKRSet ignoreTKR()
const {
return ignoreTKR_; }
407 void set_ignoreTKR(common::IgnoreTKRSet set) { ignoreTKR_ = set; }
408 bool IsArray()
const {
return !shape_.empty(); }
409 bool IsCoarray()
const {
return !coshape_.empty(); }
410 bool IsAssumedShape()
const {
411 return isDummy() && shape_.CanBeAssumedShape();
413 bool CanBeDeferredShape()
const {
return shape_.CanBeDeferredShape(); }
414 bool IsAssumedRank()
const {
return isDummy() && shape_.IsAssumedRank(); }
415 std::optional<common::CUDADataAttr> cudaDataAttr()
const {
416 return cudaDataAttr_;
418 void set_cudaDataAttr(std::optional<common::CUDADataAttr> attr) {
419 cudaDataAttr_ = attr;
424 const parser::Expr *unanalyzedPDTComponentInit_{
nullptr};
427 common::IgnoreTKRSet ignoreTKR_;
428 const Symbol *commonBlock_{
nullptr};
429 std::optional<common::CUDADataAttr> cudaDataAttr_;
430 friend llvm::raw_ostream &operator<<(
431 llvm::raw_ostream &,
const ObjectEntityDetails &);
496 const SymbolVector ¶mNameOrder()
const {
return paramNameOrder_; }
497 const SymbolVector ¶mDeclOrder()
const {
return paramDeclOrder_; }
498 bool sequence()
const {
return sequence_; }
499 bool isDECStructure()
const {
return isDECStructure_; }
500 std::map<SourceName, SymbolRef> &finals() {
return finals_; }
501 const std::map<SourceName, SymbolRef> &finals()
const {
return finals_; }
502 bool isForwardReferenced()
const {
return isForwardReferenced_; }
503 void add_paramNameOrder(
const Symbol &symbol) {
504 paramNameOrder_.push_back(symbol);
506 void add_paramDeclOrder(
const Symbol &symbol) {
507 paramDeclOrder_.push_back(symbol);
509 void add_component(
const Symbol &);
510 void set_sequence(
bool x =
true) { sequence_ = x; }
511 void set_isDECStructure(
bool x =
true) { isDECStructure_ = x; }
512 void set_isForwardReferenced(
bool value) { isForwardReferenced_ = value; }
513 const std::list<SourceName> &componentNames()
const {
514 return componentNames_;
516 const std::map<SourceName, const parser::Expr *> &
517 originalKindParameterMap()
const {
518 return originalKindParameterMap_;
520 void add_originalKindParameter(SourceName,
const parser::Expr *);
523 const Symbol *GetParentComponent(
const Scope &)
const;
525 std::optional<SourceName> GetParentComponentName()
const {
526 if (componentNames_.empty()) {
529 return componentNames_.front();
533 const Symbol *GetFinalForRank(
int)
const;
540 SymbolVector paramNameOrder_;
541 SymbolVector paramDeclOrder_;
544 std::list<SourceName> componentNames_;
545 std::map<SourceName, SymbolRef> finals_;
546 bool sequence_{
false};
547 bool isDECStructure_{
false};
548 bool isForwardReferenced_{
false};
549 std::map<SourceName, const parser::Expr *> originalKindParameterMap_;
551 friend llvm::raw_ostream &operator<<(
819 CrayPointer, CrayPointee,
833 AccPrivate, AccFirstPrivate, AccShared,
835 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
836 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
840 AccDevice, AccHost, AccSelf,
842 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
844 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
847 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
848 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
850 OmpCopyIn, OmpCopyPrivate,
852 OmpInVar, OmpOrigVar, OmpOutVar, OmpPrivVar,
854 OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
855 OmpAllocate, OmpDeclarativeAllocateDirective,
856 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
857 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
858 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
859 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
863 const Scope &owner()
const {
return *owner_; }
864 const SourceName &name()
const {
return name_; }
865 Attrs &attrs() {
return attrs_; }
866 const Attrs &attrs()
const {
return attrs_; }
867 Attrs &implicitAttrs() {
return implicitAttrs_; }
868 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
869 Flags &flags() {
return flags_; }
870 const Flags &flags()
const {
return flags_; }
871 bool test(Flag flag)
const {
return flags_.test(flag); }
872 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
874 Scope *scope() {
return scope_; }
875 const Scope *scope()
const {
return scope_; }
876 void set_scope(Scope *scope) { scope_ = scope; }
877 std::size_t size()
const {
return size_; }
878 void set_size(std::size_t size) { size_ = size; }
879 std::size_t offset()
const {
return offset_; }
880 void set_offset(std::size_t offset) { offset_ = offset; }
882 void ReplaceName(
const SourceName &);
883 static std::string OmpFlagToClauseName(Flag ompFlag);
886 template <
typename D>
bool has()
const {
887 return std::holds_alternative<D>(details_);
891 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
892 template <
typename D>
const D *detailsIf()
const {
893 return std::get_if<D>(&details_);
897 template <
typename D> D &get() {
898 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
900 template <
typename D>
const D &get()
const {
901 const auto *p{detailsIf<D>()};
906 Details &details() {
return details_; }
907 const Details &details()
const {
return details_; }
910 void set_details(Details &&);
913 bool CanReplaceDetails(
const Details &details)
const;
916 inline Symbol &GetUltimate();
917 inline const Symbol &GetUltimate()
const;
919 inline DeclTypeSpec *GetType();
920 inline const DeclTypeSpec *GetType()
const;
921 void SetType(
const DeclTypeSpec &);
923 const std::string *GetBindName()
const;
924 void SetBindName(std::string &&);
925 bool GetIsExplicitBindName()
const;
926 void SetIsExplicitBindName(
bool);
927 void SetIsCDefined(
bool);
928 bool IsFuncResult()
const;
929 bool IsObjectArray()
const;
930 const ArraySpec *GetShape()
const;
931 bool IsSubprogram()
const;
932 bool IsFromModFile()
const;
933 bool HasExplicitInterface()
const {
934 return common::visit(
936 [](
const SubprogramDetails &) {
return true; },
937 [](
const SubprogramNameDetails &) {
return true; },
938 [&](
const ProcEntityDetails &x) {
939 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
941 [](
const ProcBindingDetails &x) {
942 return x.symbol().HasExplicitInterface();
944 [](
const UseDetails &x) {
945 return x.symbol().HasExplicitInterface();
947 [](
const HostAssocDetails &x) {
948 return x.symbol().HasExplicitInterface();
950 [](
const GenericDetails &x) {
951 return x.specific() && x.specific()->HasExplicitInterface();
953 [](
const auto &) {
return false; },
957 bool HasLocalLocality()
const {
958 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
961 bool operator==(
const Symbol &that)
const {
return this == &that; }
962 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
964 int Rank()
const {
return RankImpl(); }
965 int Corank()
const {
return CorankImpl(); }
970 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
975 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
977 SemanticsContext &GetSemanticsContext()
const;
978#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
979 LLVM_DUMP_METHOD
void dump()
const;
986 Attrs implicitAttrs_;
988 Scope *scope_{
nullptr};
989 std::size_t size_{0};
990 std::size_t offset_{0};
994 std::string GetDetailsName()
const;
995 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
996 friend llvm::raw_ostream &DumpForUnparse(
997 llvm::raw_ostream &,
const Symbol &,
bool);
999 static constexpr int startRecursionDepth{100};
1001 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
1002 inline int RankImpl(
int depth = startRecursionDepth)
const {
1006 return common::visit(
1008 [&](
const SubprogramDetails &sd) {
1009 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
1011 [](
const GenericDetails &) {
1014 [&](
const ProcBindingDetails &x) {
1015 return x.symbol().RankImpl(depth);
1017 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
1018 [&](
const HostAssocDetails &x) {
1019 return x.symbol().RankImpl(depth);
1021 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1022 [&](
const ProcEntityDetails &ped) {
1023 const Symbol *iface{ped.procInterface()};
1024 return iface ? iface->RankImpl(depth) : 0;
1026 [](
const AssocEntityDetails &aed) {
1027 if (
auto assocRank{aed.rank()}) {
1030 }
else if (aed.IsAssumedRank()) {
1033 }
else if (
const auto &expr{aed.expr()}) {
1034 return expr->Rank();
1039 [](
const auto &) {
return 0; },
1043 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1047 return common::visit(
1049 [&](
const SubprogramDetails &sd) {
1050 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1052 [](
const GenericDetails &) {
return 0; },
1053 [&](
const ProcEntityDetails &ped) {
1054 const Symbol *iface{ped.procInterface()};
1055 return iface ? iface->CorankImpl(depth) : 0;
1057 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1058 [&](
const HostAssocDetails &x) {
1059 return x.symbol().CorankImpl(depth);
1061 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1062 [](
const AssocEntityDetails &aed) {
1063 return aed.expr() ? aed.expr()->Corank() : 0;
1065 [](
const auto &) {
return 0; },
1069 template <std::
size_t>
friend class Symbols;
1070 template <
class, std::
size_t>
friend class std::array;