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<<(
801 CrayPointer, CrayPointee,
815 AccPrivate, AccFirstPrivate, AccShared,
817 AccCopy, AccCopyIn, AccCopyInReadOnly, AccCopyOut, AccCreate, AccDelete,
818 AccPresent, AccLink, AccDeviceResident, AccDevicePtr, AccUseDevice,
822 AccDevice, AccHost, AccSelf,
824 AccCommonBlock, AccThreadPrivate, AccReduction, AccNone, AccPreDetermined,
826 OmpShared, OmpPrivate, OmpLinear, OmpFirstPrivate, OmpLastPrivate,
829 OmpMapTo, OmpMapFrom, OmpMapToFrom, OmpMapStorage, OmpMapDelete,
830 OmpUseDevicePtr, OmpUseDeviceAddr, OmpIsDevicePtr, OmpHasDeviceAddr,
832 OmpCopyIn, OmpCopyPrivate,
834 OmpCommonBlock, OmpReduction, OmpInReduction, OmpAligned, OmpNontemporal,
835 OmpAllocate, OmpDeclarativeAllocateDirective,
836 OmpExecutableAllocateDirective, OmpDeclareSimd, OmpDeclareTarget,
837 OmpThreadprivate, OmpDeclareReduction, OmpFlushed, OmpCriticalLock,
838 OmpIfSpecified, OmpNone, OmpPreDetermined, OmpExplicit, OmpImplicit,
839 OmpDependObject, OmpInclusiveScan, OmpExclusiveScan, OmpInScanReduction,
843 const Scope &owner()
const {
return *owner_; }
844 const SourceName &name()
const {
return name_; }
845 Attrs &attrs() {
return attrs_; }
846 const Attrs &attrs()
const {
return attrs_; }
847 Attrs &implicitAttrs() {
return implicitAttrs_; }
848 const Attrs &implicitAttrs()
const {
return implicitAttrs_; }
849 Flags &flags() {
return flags_; }
850 const Flags &flags()
const {
return flags_; }
851 bool test(Flag flag)
const {
return flags_.test(flag); }
852 void set(Flag flag,
bool value =
true) { flags_.set(flag, value); }
854 Scope *scope() {
return scope_; }
855 const Scope *scope()
const {
return scope_; }
856 void set_scope(Scope *scope) { scope_ = scope; }
857 std::size_t size()
const {
return size_; }
858 void set_size(std::size_t size) { size_ = size; }
859 std::size_t offset()
const {
return offset_; }
860 void set_offset(std::size_t offset) { offset_ = offset; }
862 void ReplaceName(
const SourceName &);
863 static std::string OmpFlagToClauseName(Flag ompFlag);
866 template <
typename D>
bool has()
const {
867 return std::holds_alternative<D>(details_);
871 template <
typename D> D *detailsIf() {
return std::get_if<D>(&details_); }
872 template <
typename D>
const D *detailsIf()
const {
873 return std::get_if<D>(&details_);
877 template <
typename D> D &get() {
878 return const_cast<D &
>(
const_cast<const Symbol *
>(
this)->get<D>());
880 template <
typename D>
const D &get()
const {
881 const auto *p{detailsIf<D>()};
886 Details &details() {
return details_; }
887 const Details &details()
const {
return details_; }
890 void set_details(Details &&);
893 bool CanReplaceDetails(
const Details &details)
const;
896 inline Symbol &GetUltimate();
897 inline const Symbol &GetUltimate()
const;
899 inline DeclTypeSpec *GetType();
900 inline const DeclTypeSpec *GetType()
const;
901 void SetType(
const DeclTypeSpec &);
903 const std::string *GetBindName()
const;
904 void SetBindName(std::string &&);
905 bool GetIsExplicitBindName()
const;
906 void SetIsExplicitBindName(
bool);
907 void SetIsCDefined(
bool);
908 bool IsFuncResult()
const;
909 bool IsObjectArray()
const;
910 const ArraySpec *GetShape()
const;
911 bool IsSubprogram()
const;
912 bool IsFromModFile()
const;
913 bool HasExplicitInterface()
const {
914 return common::visit(
916 [](
const SubprogramDetails &) {
return true; },
917 [](
const SubprogramNameDetails &) {
return true; },
918 [&](
const ProcEntityDetails &x) {
919 return attrs_.test(Attr::INTRINSIC) || x.HasExplicitInterface();
921 [](
const ProcBindingDetails &x) {
922 return x.symbol().HasExplicitInterface();
924 [](
const UseDetails &x) {
925 return x.symbol().HasExplicitInterface();
927 [](
const HostAssocDetails &x) {
928 return x.symbol().HasExplicitInterface();
930 [](
const GenericDetails &x) {
931 return x.specific() && x.specific()->HasExplicitInterface();
933 [](
const auto &) {
return false; },
937 bool HasLocalLocality()
const {
938 return test(Flag::LocalityLocal) || test(Flag::LocalityLocalInit);
941 bool operator==(
const Symbol &that)
const {
return this == &that; }
942 bool operator!=(
const Symbol &that)
const {
return !(*
this == that); }
944 int Rank()
const {
return RankImpl(); }
945 int Corank()
const {
return CorankImpl(); }
950 const DerivedTypeSpec *GetParentTypeSpec(
const Scope * =
nullptr)
const;
955 const Symbol *GetParentComponent(
const Scope * =
nullptr)
const;
957 SemanticsContext &GetSemanticsContext()
const;
958#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
959 LLVM_DUMP_METHOD
void dump()
const;
966 Attrs implicitAttrs_;
968 Scope *scope_{
nullptr};
969 std::size_t size_{0};
970 std::size_t offset_{0};
974 std::string GetDetailsName()
const;
975 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
const Symbol &);
976 friend llvm::raw_ostream &DumpForUnparse(
977 llvm::raw_ostream &,
const Symbol &,
bool);
979 static constexpr int startRecursionDepth{100};
981 inline const DeclTypeSpec *GetTypeImpl(
int depth = startRecursionDepth)
const;
982 inline int RankImpl(
int depth = startRecursionDepth)
const {
986 return common::visit(
988 [&](
const SubprogramDetails &sd) {
989 return sd.isFunction() ? sd.result().RankImpl(depth) : 0;
991 [](
const GenericDetails &) {
994 [&](
const ProcBindingDetails &x) {
995 return x.symbol().RankImpl(depth);
997 [&](
const UseDetails &x) {
return x.symbol().RankImpl(depth); },
998 [&](
const HostAssocDetails &x) {
999 return x.symbol().RankImpl(depth);
1001 [](
const ObjectEntityDetails &oed) {
return oed.shape().Rank(); },
1002 [&](
const ProcEntityDetails &ped) {
1003 const Symbol *iface{ped.procInterface()};
1004 return iface ? iface->RankImpl(depth) : 0;
1006 [](
const AssocEntityDetails &aed) {
1007 if (
auto assocRank{aed.rank()}) {
1010 }
else if (aed.IsAssumedRank()) {
1013 }
else if (
const auto &expr{aed.expr()}) {
1014 return expr->Rank();
1019 [](
const auto &) {
return 0; },
1023 inline int CorankImpl(
int depth = startRecursionDepth)
const {
1027 return common::visit(
1029 [&](
const SubprogramDetails &sd) {
1030 return sd.isFunction() ? sd.result().CorankImpl(depth) : 0;
1032 [](
const GenericDetails &) {
return 0; },
1033 [&](
const ProcEntityDetails &ped) {
1034 const Symbol *iface{ped.procInterface()};
1035 return iface ? iface->CorankImpl(depth) : 0;
1037 [&](
const UseDetails &x) {
return x.symbol().CorankImpl(depth); },
1038 [&](
const HostAssocDetails &x) {
1039 return x.symbol().CorankImpl(depth);
1041 [](
const ObjectEntityDetails &oed) {
return oed.coshape().Rank(); },
1042 [](
const AssocEntityDetails &aed) {
1043 return aed.expr() ? aed.expr()->Corank() : 0;
1045 [](
const auto &) {
return 0; },
1049 template <std::
size_t>
friend class Symbols;
1050 template <
class, std::
size_t>
friend class std::array;