20
20
namespace Fortran ::runtime {
21
21
22
22
Descriptor::~Descriptor () {
23
- // Descriptors created by Descriptor::Create() must be destroyed by
24
- // Descriptor::Destroy(), not by the default destructor, so that
25
- // the array variant operator delete[] is properly used.
26
- assert (!(Addendum () && (Addendum ()->flags () & DescriptorAddendum::Created)));
23
+ if (raw_.attribute != CFI_attribute_pointer) {
24
+ Deallocate ();
25
+ }
27
26
}
28
27
29
28
void Descriptor::Establish (TypeCode t, std::size_t elementBytes, void *p,
@@ -60,42 +59,33 @@ void Descriptor::Establish(const DerivedType &dt, void *p, int rank,
60
59
new (Addendum ()) DescriptorAddendum{&dt};
61
60
}
62
61
63
- Descriptor *Descriptor::Create (TypeCode t, std::size_t elementBytes, void *p,
64
- int rank, const SubscriptValue *extent, ISO::CFI_attribute_t attribute) {
62
+ std::unique_ptr<Descriptor> Descriptor::Create (TypeCode t,
63
+ std::size_t elementBytes, void *p, int rank, const SubscriptValue *extent,
64
+ ISO::CFI_attribute_t attribute) {
65
65
std::size_t bytes{SizeInBytes (rank, true )};
66
- Descriptor *result{reinterpret_cast <Descriptor *>(std::malloc ( bytes) )};
66
+ Descriptor *result{reinterpret_cast <Descriptor *>(new char [ bytes] )};
67
67
CHECK (result != nullptr );
68
68
result->Establish (t, elementBytes, p, rank, extent, attribute, true );
69
- result->Addendum ()->flags () |= DescriptorAddendum::Created;
70
- return result;
69
+ return std::unique_ptr<Descriptor>{result};
71
70
}
72
71
73
- Descriptor *Descriptor::Create (TypeCategory c, int kind, void *p, int rank,
74
- const SubscriptValue *extent, ISO::CFI_attribute_t attribute) {
72
+ std::unique_ptr<Descriptor> Descriptor::Create (TypeCategory c, int kind,
73
+ void *p, int rank, const SubscriptValue *extent,
74
+ ISO::CFI_attribute_t attribute) {
75
75
std::size_t bytes{SizeInBytes (rank, true )};
76
- Descriptor *result{reinterpret_cast <Descriptor *>(std::malloc ( bytes) )};
76
+ Descriptor *result{reinterpret_cast <Descriptor *>(new char [ bytes] )};
77
77
CHECK (result != nullptr );
78
78
result->Establish (c, kind, p, rank, extent, attribute, true );
79
- result->Addendum ()->flags () |= DescriptorAddendum::Created;
80
- return result;
79
+ return std::unique_ptr<Descriptor>{result};
81
80
}
82
81
83
- Descriptor * Descriptor::Create (const DerivedType &dt, void *p, int rank ,
84
- const SubscriptValue *extent, ISO::CFI_attribute_t attribute) {
82
+ std::unique_ptr< Descriptor> Descriptor::Create (const DerivedType &dt, void *p,
83
+ int rank, const SubscriptValue *extent, ISO::CFI_attribute_t attribute) {
85
84
std::size_t bytes{SizeInBytes (rank, true , dt.lenParameters ())};
86
- Descriptor *result{reinterpret_cast <Descriptor *>(std::malloc ( bytes) )};
85
+ Descriptor *result{reinterpret_cast <Descriptor *>(new char [ bytes] )};
87
86
CHECK (result != nullptr );
88
87
result->Establish (dt, p, rank, extent, attribute);
89
- result->Addendum ()->flags () |= DescriptorAddendum::Created;
90
- return result;
91
- }
92
-
93
- void Descriptor::Destroy () {
94
- if (const DescriptorAddendum * addendum{Addendum ()}) {
95
- if (addendum->flags () & DescriptorAddendum::Created) {
96
- std::free (reinterpret_cast <void *>(this ));
97
- }
98
- }
88
+ return std::unique_ptr<Descriptor>{result};
99
89
}
100
90
101
91
std::size_t Descriptor::SizeInBytes () const {
@@ -113,11 +103,75 @@ std::size_t Descriptor::Elements() const {
113
103
return elements;
114
104
}
115
105
106
+ int Descriptor::Allocate (
107
+ const SubscriptValue lb[], const SubscriptValue ub[], std::size_t charLen) {
108
+ int result{ISO::CFI_allocate (&raw_, lb, ub, charLen)};
109
+ if (result == CFI_SUCCESS) {
110
+ // TODO: derived type initialization
111
+ }
112
+ return result;
113
+ }
114
+
115
+ int Descriptor::Deallocate (bool finalize) {
116
+ if (raw_.base_addr != nullptr ) {
117
+ Destroy (static_cast <char *>(raw_.base_addr ), finalize);
118
+ }
119
+ return ISO::CFI_deallocate (&raw_);
120
+ }
121
+
122
+ void Descriptor::Destroy (char *data, bool finalize) const {
123
+ if (data != nullptr ) {
124
+ if (const DescriptorAddendum * addendum{Addendum ()}) {
125
+ if (addendum->flags () & DescriptorAddendum::DoNotFinalize) {
126
+ finalize = false ;
127
+ }
128
+ if (const DerivedType * dt{addendum->derivedType ()}) {
129
+ std::size_t elements{Elements ()};
130
+ std::size_t elementBytes{ElementBytes ()};
131
+ for (std::size_t j{0 }; j < elements; ++j) {
132
+ dt->Destroy (data + j * elementBytes, finalize);
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+
116
139
void Descriptor::Check () const {
117
140
// TODO
118
141
}
119
142
143
+ std::ostream &Descriptor::Dump (std::ostream &o) const {
144
+ o << " Descriptor @ 0x" << std::hex << reinterpret_cast <std::intptr_t >(this )
145
+ << std::dec << " :\n " ;
146
+ o << " base_addr 0x" << std::hex
147
+ << reinterpret_cast <std::intptr_t >(raw_.base_addr ) << std::dec << ' \n ' ;
148
+ o << " elem_len " << raw_.elem_len << ' \n ' ;
149
+ o << " version " << raw_.version
150
+ << (raw_.version == CFI_VERSION ? " (ok)" : " BAD!" ) << ' \n ' ;
151
+ o << " rank " << static_cast <int >(raw_.rank ) << ' \n ' ;
152
+ o << " type " << static_cast <int >(raw_.type ) << ' \n ' ;
153
+ o << " attribute " << static_cast <int >(raw_.attribute ) << ' \n ' ;
154
+ o << " addendum? " << static_cast <bool >(raw_.f18Addendum ) << ' \n ' ;
155
+ for (int j{0 }; j < raw_.rank ; ++j) {
156
+ o << " dim[" << j << " ] lower_bound " << raw_.dim [j].lower_bound << ' \n ' ;
157
+ o << " extent " << raw_.dim [j].extent << ' \n ' ;
158
+ o << " sm " << raw_.dim [j].sm << ' \n ' ;
159
+ }
160
+ if (const DescriptorAddendum * addendum{Addendum ()}) {
161
+ addendum->Dump (o);
162
+ }
163
+ return o;
164
+ }
165
+
120
166
std::size_t DescriptorAddendum::SizeInBytes () const {
121
167
return SizeInBytes (LenParameters ());
122
168
}
169
+
170
+ std::ostream &DescriptorAddendum::Dump (std::ostream &o) const {
171
+ o << " derivedType @ 0x" << std::hex
172
+ << reinterpret_cast <std::intptr_t >(derivedType_) << std::dec << ' \n ' ;
173
+ o << " flags " << flags_ << ' \n ' ;
174
+ // TODO: LEN parameter values
175
+ return o;
176
+ }
123
177
} // namespace Fortran::runtime
0 commit comments