xref: /aosp_15_r20/art/libdexfile/dex/class_accessor.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "code_item_accessors.h"
21*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file.h"
22*795d594fSAndroid Build Coastguard Worker #include "dex_file_types.h"
23*795d594fSAndroid Build Coastguard Worker #include "invoke_type.h"
24*795d594fSAndroid Build Coastguard Worker #include "modifiers.h"
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker namespace art {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker namespace dex {
29*795d594fSAndroid Build Coastguard Worker struct ClassDef;
30*795d594fSAndroid Build Coastguard Worker struct CodeItem;
31*795d594fSAndroid Build Coastguard Worker class DexFileVerifier;
32*795d594fSAndroid Build Coastguard Worker }  // namespace dex
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker class ClassIteratorData;
35*795d594fSAndroid Build Coastguard Worker class DexFile;
36*795d594fSAndroid Build Coastguard Worker template <typename Iter> class IterationRange;
37*795d594fSAndroid Build Coastguard Worker class MethodReference;
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker // Classes to access Dex data.
40*795d594fSAndroid Build Coastguard Worker class ClassAccessor {
41*795d594fSAndroid Build Coastguard Worker  public:
42*795d594fSAndroid Build Coastguard Worker   class BaseItem {
43*795d594fSAndroid Build Coastguard Worker    public:
BaseItem(const DexFile & dex_file,const uint8_t * ptr_pos,const uint8_t * hiddenapi_ptr_pos)44*795d594fSAndroid Build Coastguard Worker     explicit BaseItem(const DexFile& dex_file,
45*795d594fSAndroid Build Coastguard Worker                       const uint8_t* ptr_pos,
46*795d594fSAndroid Build Coastguard Worker                       const uint8_t* hiddenapi_ptr_pos)
47*795d594fSAndroid Build Coastguard Worker         : dex_file_(dex_file), ptr_pos_(ptr_pos), hiddenapi_ptr_pos_(hiddenapi_ptr_pos) {}
48*795d594fSAndroid Build Coastguard Worker 
GetIndex()49*795d594fSAndroid Build Coastguard Worker     uint32_t GetIndex() const {
50*795d594fSAndroid Build Coastguard Worker       return index_;
51*795d594fSAndroid Build Coastguard Worker     }
52*795d594fSAndroid Build Coastguard Worker 
GetAccessFlags()53*795d594fSAndroid Build Coastguard Worker     uint32_t GetAccessFlags() const {
54*795d594fSAndroid Build Coastguard Worker       return access_flags_;
55*795d594fSAndroid Build Coastguard Worker     }
56*795d594fSAndroid Build Coastguard Worker 
GetHiddenapiFlags()57*795d594fSAndroid Build Coastguard Worker     uint32_t GetHiddenapiFlags() const {
58*795d594fSAndroid Build Coastguard Worker       return hiddenapi_flags_;
59*795d594fSAndroid Build Coastguard Worker     }
60*795d594fSAndroid Build Coastguard Worker 
IsFinal()61*795d594fSAndroid Build Coastguard Worker     bool IsFinal() const {
62*795d594fSAndroid Build Coastguard Worker       return (GetAccessFlags() & kAccFinal) != 0;
63*795d594fSAndroid Build Coastguard Worker     }
64*795d594fSAndroid Build Coastguard Worker 
GetDexFile()65*795d594fSAndroid Build Coastguard Worker     const DexFile& GetDexFile() const {
66*795d594fSAndroid Build Coastguard Worker       return dex_file_;
67*795d594fSAndroid Build Coastguard Worker     }
68*795d594fSAndroid Build Coastguard Worker 
GetDataPointer()69*795d594fSAndroid Build Coastguard Worker     const uint8_t* GetDataPointer() const {
70*795d594fSAndroid Build Coastguard Worker       return ptr_pos_;
71*795d594fSAndroid Build Coastguard Worker     }
72*795d594fSAndroid Build Coastguard Worker 
MemberIsNative()73*795d594fSAndroid Build Coastguard Worker     bool MemberIsNative() const {
74*795d594fSAndroid Build Coastguard Worker       return GetAccessFlags() & kAccNative;
75*795d594fSAndroid Build Coastguard Worker     }
76*795d594fSAndroid Build Coastguard Worker 
MemberIsFinal()77*795d594fSAndroid Build Coastguard Worker     bool MemberIsFinal() const {
78*795d594fSAndroid Build Coastguard Worker       return GetAccessFlags() & kAccFinal;
79*795d594fSAndroid Build Coastguard Worker     }
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker    protected:
82*795d594fSAndroid Build Coastguard Worker     // Internal data pointer for reading.
83*795d594fSAndroid Build Coastguard Worker     const DexFile& dex_file_;
84*795d594fSAndroid Build Coastguard Worker     const uint8_t* ptr_pos_ = nullptr;
85*795d594fSAndroid Build Coastguard Worker     const uint8_t* hiddenapi_ptr_pos_ = nullptr;
86*795d594fSAndroid Build Coastguard Worker     uint32_t index_ = 0u;
87*795d594fSAndroid Build Coastguard Worker     uint32_t access_flags_ = 0u;
88*795d594fSAndroid Build Coastguard Worker     uint32_t hiddenapi_flags_ = 0u;
89*795d594fSAndroid Build Coastguard Worker   };
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   // A decoded version of the method of a class_data_item.
92*795d594fSAndroid Build Coastguard Worker   class Method : public BaseItem {
93*795d594fSAndroid Build Coastguard Worker    public:
GetCodeItemOffset()94*795d594fSAndroid Build Coastguard Worker     uint32_t GetCodeItemOffset() const {
95*795d594fSAndroid Build Coastguard Worker       return code_off_;
96*795d594fSAndroid Build Coastguard Worker     }
97*795d594fSAndroid Build Coastguard Worker 
GetInvokeType(uint32_t class_access_flags)98*795d594fSAndroid Build Coastguard Worker     InvokeType GetInvokeType(uint32_t class_access_flags) const {
99*795d594fSAndroid Build Coastguard Worker       return is_static_or_direct_
100*795d594fSAndroid Build Coastguard Worker           ? GetDirectMethodInvokeType()
101*795d594fSAndroid Build Coastguard Worker           : GetVirtualMethodInvokeType(class_access_flags);
102*795d594fSAndroid Build Coastguard Worker     }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker     MethodReference GetReference() const;
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker     CodeItemInstructionAccessor GetInstructions() const;
107*795d594fSAndroid Build Coastguard Worker     CodeItemDataAccessor GetInstructionsAndData() const;
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker     const dex::CodeItem* GetCodeItem() const;
110*795d594fSAndroid Build Coastguard Worker 
IsStaticOrDirect()111*795d594fSAndroid Build Coastguard Worker     bool IsStaticOrDirect() const {
112*795d594fSAndroid Build Coastguard Worker       return is_static_or_direct_;
113*795d594fSAndroid Build Coastguard Worker     }
114*795d594fSAndroid Build Coastguard Worker 
115*795d594fSAndroid Build Coastguard Worker    private:
116*795d594fSAndroid Build Coastguard Worker     Method(const DexFile& dex_file,
117*795d594fSAndroid Build Coastguard Worker            const uint8_t* ptr_pos,
118*795d594fSAndroid Build Coastguard Worker            const uint8_t* hiddenapi_ptr_pos = nullptr,
119*795d594fSAndroid Build Coastguard Worker            bool is_static_or_direct = true)
BaseItem(dex_file,ptr_pos,hiddenapi_ptr_pos)120*795d594fSAndroid Build Coastguard Worker         : BaseItem(dex_file, ptr_pos, hiddenapi_ptr_pos),
121*795d594fSAndroid Build Coastguard Worker           is_static_or_direct_(is_static_or_direct) {}
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker     void Read();
124*795d594fSAndroid Build Coastguard Worker 
GetDirectMethodInvokeType()125*795d594fSAndroid Build Coastguard Worker     InvokeType GetDirectMethodInvokeType() const {
126*795d594fSAndroid Build Coastguard Worker       return (GetAccessFlags() & kAccStatic) != 0 ? kStatic : kDirect;
127*795d594fSAndroid Build Coastguard Worker     }
128*795d594fSAndroid Build Coastguard Worker 
GetVirtualMethodInvokeType(uint32_t class_access_flags)129*795d594fSAndroid Build Coastguard Worker     InvokeType GetVirtualMethodInvokeType(uint32_t class_access_flags) const {
130*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(GetAccessFlags() & kAccStatic, 0U);
131*795d594fSAndroid Build Coastguard Worker       if ((class_access_flags & kAccInterface) != 0) {
132*795d594fSAndroid Build Coastguard Worker         return kInterface;
133*795d594fSAndroid Build Coastguard Worker       } else if ((GetAccessFlags() & kAccConstructor) != 0) {
134*795d594fSAndroid Build Coastguard Worker         return kSuper;
135*795d594fSAndroid Build Coastguard Worker       } else {
136*795d594fSAndroid Build Coastguard Worker         return kVirtual;
137*795d594fSAndroid Build Coastguard Worker       }
138*795d594fSAndroid Build Coastguard Worker     }
139*795d594fSAndroid Build Coastguard Worker 
140*795d594fSAndroid Build Coastguard Worker     // Move to virtual method section.
NextSection()141*795d594fSAndroid Build Coastguard Worker     void NextSection() {
142*795d594fSAndroid Build Coastguard Worker       DCHECK(is_static_or_direct_) << "Already in the virtual methods section";
143*795d594fSAndroid Build Coastguard Worker       is_static_or_direct_ = false;
144*795d594fSAndroid Build Coastguard Worker       index_ = 0u;
145*795d594fSAndroid Build Coastguard Worker     }
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker     bool is_static_or_direct_ = true;
148*795d594fSAndroid Build Coastguard Worker     uint32_t code_off_ = 0u;
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker     friend class ClassAccessor;
151*795d594fSAndroid Build Coastguard Worker     friend class dex::DexFileVerifier;
152*795d594fSAndroid Build Coastguard Worker   };
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker   // A decoded version of the field of a class_data_item.
155*795d594fSAndroid Build Coastguard Worker   class Field : public BaseItem {
156*795d594fSAndroid Build Coastguard Worker    public:
157*795d594fSAndroid Build Coastguard Worker     Field(const DexFile& dex_file,
158*795d594fSAndroid Build Coastguard Worker           const uint8_t* ptr_pos,
159*795d594fSAndroid Build Coastguard Worker           const uint8_t* hiddenapi_ptr_pos = nullptr)
BaseItem(dex_file,ptr_pos,hiddenapi_ptr_pos)160*795d594fSAndroid Build Coastguard Worker         : BaseItem(dex_file, ptr_pos, hiddenapi_ptr_pos) {}
161*795d594fSAndroid Build Coastguard Worker 
IsStatic()162*795d594fSAndroid Build Coastguard Worker     bool IsStatic() const {
163*795d594fSAndroid Build Coastguard Worker      return is_static_;
164*795d594fSAndroid Build Coastguard Worker     }
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker    private:
167*795d594fSAndroid Build Coastguard Worker     void Read();
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker     // Move to instance fields section.
NextSection()170*795d594fSAndroid Build Coastguard Worker     void NextSection() {
171*795d594fSAndroid Build Coastguard Worker       index_ = 0u;
172*795d594fSAndroid Build Coastguard Worker       is_static_ = false;
173*795d594fSAndroid Build Coastguard Worker     }
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker     bool is_static_ = true;
176*795d594fSAndroid Build Coastguard Worker     friend class ClassAccessor;
177*795d594fSAndroid Build Coastguard Worker     friend class dex::DexFileVerifier;
178*795d594fSAndroid Build Coastguard Worker   };
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker   template <typename DataType>
181*795d594fSAndroid Build Coastguard Worker   class DataIterator {
182*795d594fSAndroid Build Coastguard Worker    public:
183*795d594fSAndroid Build Coastguard Worker     using iterator_category = std::forward_iterator_tag;
184*795d594fSAndroid Build Coastguard Worker     using value_type = DataType;
185*795d594fSAndroid Build Coastguard Worker     using difference_type = ptrdiff_t;
186*795d594fSAndroid Build Coastguard Worker     using pointer = value_type*;
187*795d594fSAndroid Build Coastguard Worker     using reference = value_type&;
188*795d594fSAndroid Build Coastguard Worker 
DataIterator(const DexFile & dex_file,uint32_t position,uint32_t partition_pos,uint32_t iterator_end,const uint8_t * ptr_pos,const uint8_t * hiddenapi_ptr_pos)189*795d594fSAndroid Build Coastguard Worker     DataIterator(const DexFile& dex_file,
190*795d594fSAndroid Build Coastguard Worker                  uint32_t position,
191*795d594fSAndroid Build Coastguard Worker                  uint32_t partition_pos,
192*795d594fSAndroid Build Coastguard Worker                  uint32_t iterator_end,
193*795d594fSAndroid Build Coastguard Worker                  const uint8_t* ptr_pos,
194*795d594fSAndroid Build Coastguard Worker                  const uint8_t* hiddenapi_ptr_pos)
195*795d594fSAndroid Build Coastguard Worker         : data_(dex_file, ptr_pos, hiddenapi_ptr_pos),
196*795d594fSAndroid Build Coastguard Worker           position_(position),
197*795d594fSAndroid Build Coastguard Worker           partition_pos_(partition_pos),
198*795d594fSAndroid Build Coastguard Worker           iterator_end_(iterator_end) {
199*795d594fSAndroid Build Coastguard Worker       ReadData();
200*795d594fSAndroid Build Coastguard Worker     }
201*795d594fSAndroid Build Coastguard Worker 
IsValid()202*795d594fSAndroid Build Coastguard Worker     bool IsValid() const {
203*795d594fSAndroid Build Coastguard Worker       return position_ < iterator_end_;
204*795d594fSAndroid Build Coastguard Worker     }
205*795d594fSAndroid Build Coastguard Worker 
206*795d594fSAndroid Build Coastguard Worker     // Value after modification.
207*795d594fSAndroid Build Coastguard Worker     DataIterator& operator++() {
208*795d594fSAndroid Build Coastguard Worker       ++position_;
209*795d594fSAndroid Build Coastguard Worker       ReadData();
210*795d594fSAndroid Build Coastguard Worker       return *this;
211*795d594fSAndroid Build Coastguard Worker     }
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker     const value_type& operator*() const {
214*795d594fSAndroid Build Coastguard Worker       return data_;
215*795d594fSAndroid Build Coastguard Worker     }
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker     const value_type* operator->() const {
218*795d594fSAndroid Build Coastguard Worker       return &data_;
219*795d594fSAndroid Build Coastguard Worker     }
220*795d594fSAndroid Build Coastguard Worker 
221*795d594fSAndroid Build Coastguard Worker     bool operator==(const DataIterator& rhs) const {
222*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files.";
223*795d594fSAndroid Build Coastguard Worker       return position_ == rhs.position_;
224*795d594fSAndroid Build Coastguard Worker     }
225*795d594fSAndroid Build Coastguard Worker 
226*795d594fSAndroid Build Coastguard Worker     bool operator!=(const DataIterator& rhs) const {
227*795d594fSAndroid Build Coastguard Worker       return !(*this == rhs);
228*795d594fSAndroid Build Coastguard Worker     }
229*795d594fSAndroid Build Coastguard Worker 
230*795d594fSAndroid Build Coastguard Worker     bool operator<(const DataIterator& rhs) const {
231*795d594fSAndroid Build Coastguard Worker       DCHECK_EQ(&data_.dex_file_, &rhs.data_.dex_file_) << "Comparing different dex files.";
232*795d594fSAndroid Build Coastguard Worker       return position_ < rhs.position_;
233*795d594fSAndroid Build Coastguard Worker     }
234*795d594fSAndroid Build Coastguard Worker 
235*795d594fSAndroid Build Coastguard Worker     bool operator>(const DataIterator& rhs) const {
236*795d594fSAndroid Build Coastguard Worker       return rhs < *this;
237*795d594fSAndroid Build Coastguard Worker     }
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker     bool operator<=(const DataIterator& rhs) const {
240*795d594fSAndroid Build Coastguard Worker       return !(rhs < *this);
241*795d594fSAndroid Build Coastguard Worker     }
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker     bool operator>=(const DataIterator& rhs) const {
244*795d594fSAndroid Build Coastguard Worker       return !(*this < rhs);
245*795d594fSAndroid Build Coastguard Worker     }
246*795d594fSAndroid Build Coastguard Worker 
GetDataPointer()247*795d594fSAndroid Build Coastguard Worker     const uint8_t* GetDataPointer() const {
248*795d594fSAndroid Build Coastguard Worker       return data_.ptr_pos_;
249*795d594fSAndroid Build Coastguard Worker     }
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker    private:
252*795d594fSAndroid Build Coastguard Worker     // Read data at current position.
ReadData()253*795d594fSAndroid Build Coastguard Worker     void ReadData() {
254*795d594fSAndroid Build Coastguard Worker       if (IsValid()) {
255*795d594fSAndroid Build Coastguard Worker         // At the end of the first section, go to the next section.
256*795d594fSAndroid Build Coastguard Worker         if (position_ == partition_pos_) {
257*795d594fSAndroid Build Coastguard Worker           data_.NextSection();
258*795d594fSAndroid Build Coastguard Worker         }
259*795d594fSAndroid Build Coastguard Worker         data_.Read();
260*795d594fSAndroid Build Coastguard Worker       }
261*795d594fSAndroid Build Coastguard Worker     }
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker     DataType data_;
264*795d594fSAndroid Build Coastguard Worker     // Iterator position.
265*795d594fSAndroid Build Coastguard Worker     uint32_t position_;
266*795d594fSAndroid Build Coastguard Worker     // At partition_pos_, we go to the next section.
267*795d594fSAndroid Build Coastguard Worker     const uint32_t partition_pos_;
268*795d594fSAndroid Build Coastguard Worker     // At iterator_end_, the iterator is no longer valid.
269*795d594fSAndroid Build Coastguard Worker     const uint32_t iterator_end_;
270*795d594fSAndroid Build Coastguard Worker 
271*795d594fSAndroid Build Coastguard Worker     friend class dex::DexFileVerifier;
272*795d594fSAndroid Build Coastguard Worker   };
273*795d594fSAndroid Build Coastguard Worker 
274*795d594fSAndroid Build Coastguard Worker   // Not explicit specifically for range-based loops.
275*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ClassAccessor(const ClassIteratorData& data);  // NOLINT [runtime/explicit] [5]
276*795d594fSAndroid Build Coastguard Worker 
277*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ClassAccessor(const DexFile& dex_file,
278*795d594fSAndroid Build Coastguard Worker                               const dex::ClassDef& class_def,
279*795d594fSAndroid Build Coastguard Worker                               bool parse_hiddenapi_class_data = false);
280*795d594fSAndroid Build Coastguard Worker 
281*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ClassAccessor(const DexFile& dex_file, uint32_t class_def_index);
282*795d594fSAndroid Build Coastguard Worker 
283*795d594fSAndroid Build Coastguard Worker   ClassAccessor(const DexFile& dex_file,
284*795d594fSAndroid Build Coastguard Worker                 const uint8_t* class_data,
285*795d594fSAndroid Build Coastguard Worker                 uint32_t class_def_index = DexFile::kDexNoIndex32,
286*795d594fSAndroid Build Coastguard Worker                 bool parse_hiddenapi_class_data = false);
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker   // Return the code item for a method.
289*795d594fSAndroid Build Coastguard Worker   const dex::CodeItem* GetCodeItem(const Method& method) const;
290*795d594fSAndroid Build Coastguard Worker 
291*795d594fSAndroid Build Coastguard Worker   // Iterator data is not very iterator friendly, use visitors to get around this.
292*795d594fSAndroid Build Coastguard Worker   template <typename StaticFieldVisitor,
293*795d594fSAndroid Build Coastguard Worker             typename InstanceFieldVisitor,
294*795d594fSAndroid Build Coastguard Worker             typename DirectMethodVisitor,
295*795d594fSAndroid Build Coastguard Worker             typename VirtualMethodVisitor>
296*795d594fSAndroid Build Coastguard Worker   void VisitFieldsAndMethods(const StaticFieldVisitor& static_field_visitor,
297*795d594fSAndroid Build Coastguard Worker                              const InstanceFieldVisitor& instance_field_visitor,
298*795d594fSAndroid Build Coastguard Worker                              const DirectMethodVisitor& direct_method_visitor,
299*795d594fSAndroid Build Coastguard Worker                              const VirtualMethodVisitor& virtual_method_visitor) const;
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker   template <typename DirectMethodVisitor,
302*795d594fSAndroid Build Coastguard Worker             typename VirtualMethodVisitor>
303*795d594fSAndroid Build Coastguard Worker   void VisitMethods(const DirectMethodVisitor& direct_method_visitor,
304*795d594fSAndroid Build Coastguard Worker                     const VirtualMethodVisitor& virtual_method_visitor) const;
305*795d594fSAndroid Build Coastguard Worker 
306*795d594fSAndroid Build Coastguard Worker   template <typename StaticFieldVisitor,
307*795d594fSAndroid Build Coastguard Worker             typename InstanceFieldVisitor>
308*795d594fSAndroid Build Coastguard Worker   void VisitFields(const StaticFieldVisitor& static_field_visitor,
309*795d594fSAndroid Build Coastguard Worker                    const InstanceFieldVisitor& instance_field_visitor) const;
310*795d594fSAndroid Build Coastguard Worker 
311*795d594fSAndroid Build Coastguard Worker   // Return the iteration range for all the fields.
312*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Field>> GetFields() const;
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker   // Return the iteration range for all the static fields.
315*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Field>> GetStaticFields() const;
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker   // Return the iteration range for all the instance fields.
318*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Field>> GetInstanceFields() const;
319*795d594fSAndroid Build Coastguard Worker 
320*795d594fSAndroid Build Coastguard Worker   // Return the iteration range for all the methods.
321*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Method>> GetMethods() const;
322*795d594fSAndroid Build Coastguard Worker 
323*795d594fSAndroid Build Coastguard Worker   // Return the iteration range for the direct methods.
324*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Method>> GetDirectMethods() const;
325*795d594fSAndroid Build Coastguard Worker 
326*795d594fSAndroid Build Coastguard Worker   // Return the iteration range for the virtual methods.
327*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Method>> GetVirtualMethods() const;
328*795d594fSAndroid Build Coastguard Worker 
NumStaticFields()329*795d594fSAndroid Build Coastguard Worker   uint32_t NumStaticFields() const {
330*795d594fSAndroid Build Coastguard Worker     return num_static_fields_;
331*795d594fSAndroid Build Coastguard Worker   }
332*795d594fSAndroid Build Coastguard Worker 
NumInstanceFields()333*795d594fSAndroid Build Coastguard Worker   uint32_t NumInstanceFields() const {
334*795d594fSAndroid Build Coastguard Worker     return num_instance_fields_;
335*795d594fSAndroid Build Coastguard Worker   }
336*795d594fSAndroid Build Coastguard Worker 
NumFields()337*795d594fSAndroid Build Coastguard Worker   uint32_t NumFields() const {
338*795d594fSAndroid Build Coastguard Worker     return NumStaticFields() + NumInstanceFields();
339*795d594fSAndroid Build Coastguard Worker   }
340*795d594fSAndroid Build Coastguard Worker 
NumDirectMethods()341*795d594fSAndroid Build Coastguard Worker   uint32_t NumDirectMethods() const {
342*795d594fSAndroid Build Coastguard Worker     return num_direct_methods_;
343*795d594fSAndroid Build Coastguard Worker   }
344*795d594fSAndroid Build Coastguard Worker 
NumVirtualMethods()345*795d594fSAndroid Build Coastguard Worker   uint32_t NumVirtualMethods() const {
346*795d594fSAndroid Build Coastguard Worker     return num_virtual_methods_;
347*795d594fSAndroid Build Coastguard Worker   }
348*795d594fSAndroid Build Coastguard Worker 
NumMethods()349*795d594fSAndroid Build Coastguard Worker   uint32_t NumMethods() const {
350*795d594fSAndroid Build Coastguard Worker     return NumDirectMethods() + NumVirtualMethods();
351*795d594fSAndroid Build Coastguard Worker   }
352*795d594fSAndroid Build Coastguard Worker 
353*795d594fSAndroid Build Coastguard Worker   const char* GetDescriptor() const;
354*795d594fSAndroid Build Coastguard Worker   std::string_view GetDescriptorView() const;
355*795d594fSAndroid Build Coastguard Worker 
356*795d594fSAndroid Build Coastguard Worker   dex::TypeIndex GetClassIdx() const;
357*795d594fSAndroid Build Coastguard Worker 
GetDexFile()358*795d594fSAndroid Build Coastguard Worker   const DexFile& GetDexFile() const {
359*795d594fSAndroid Build Coastguard Worker     return dex_file_;
360*795d594fSAndroid Build Coastguard Worker   }
361*795d594fSAndroid Build Coastguard Worker 
HasClassData()362*795d594fSAndroid Build Coastguard Worker   bool HasClassData() const {
363*795d594fSAndroid Build Coastguard Worker     return ptr_pos_ != nullptr;
364*795d594fSAndroid Build Coastguard Worker   }
365*795d594fSAndroid Build Coastguard Worker 
HasHiddenapiClassData()366*795d594fSAndroid Build Coastguard Worker   bool HasHiddenapiClassData() const {
367*795d594fSAndroid Build Coastguard Worker     return hiddenapi_ptr_pos_ != nullptr;
368*795d594fSAndroid Build Coastguard Worker   }
369*795d594fSAndroid Build Coastguard Worker 
GetClassDefIndex()370*795d594fSAndroid Build Coastguard Worker   uint32_t GetClassDefIndex() const {
371*795d594fSAndroid Build Coastguard Worker     return class_def_index_;
372*795d594fSAndroid Build Coastguard Worker   }
373*795d594fSAndroid Build Coastguard Worker 
374*795d594fSAndroid Build Coastguard Worker   const dex::ClassDef& GetClassDef() const;
375*795d594fSAndroid Build Coastguard Worker 
376*795d594fSAndroid Build Coastguard Worker  protected:
377*795d594fSAndroid Build Coastguard Worker   // Template visitor to reduce copy paste for visiting elements.
378*795d594fSAndroid Build Coastguard Worker   // No thread safety analysis since the visitor may require capabilities.
379*795d594fSAndroid Build Coastguard Worker   template <typename DataType, typename Visitor>
380*795d594fSAndroid Build Coastguard Worker   void VisitMembers(size_t count, const Visitor& visitor, DataType* data) const
381*795d594fSAndroid Build Coastguard Worker       NO_THREAD_SAFETY_ANALYSIS;
382*795d594fSAndroid Build Coastguard Worker 
383*795d594fSAndroid Build Coastguard Worker   // Return an iteration range for the first <count> fields.
384*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Field>> GetFieldsInternal(size_t count) const;
385*795d594fSAndroid Build Coastguard Worker 
386*795d594fSAndroid Build Coastguard Worker   // Return an iteration range for the first <count> methods.
387*795d594fSAndroid Build Coastguard Worker   IterationRange<DataIterator<Method>> GetMethodsInternal(size_t count) const;
388*795d594fSAndroid Build Coastguard Worker 
389*795d594fSAndroid Build Coastguard Worker   const DexFile& dex_file_;
390*795d594fSAndroid Build Coastguard Worker   const uint32_t class_def_index_;
391*795d594fSAndroid Build Coastguard Worker   const uint8_t* ptr_pos_ = nullptr;  // Pointer into stream of class_data_item.
392*795d594fSAndroid Build Coastguard Worker   const uint8_t* hiddenapi_ptr_pos_ = nullptr;  // Pointer into stream of hiddenapi_metadata.
393*795d594fSAndroid Build Coastguard Worker   const uint32_t num_static_fields_ = 0u;
394*795d594fSAndroid Build Coastguard Worker   const uint32_t num_instance_fields_ = 0u;
395*795d594fSAndroid Build Coastguard Worker   const uint32_t num_direct_methods_ = 0u;
396*795d594fSAndroid Build Coastguard Worker   const uint32_t num_virtual_methods_ = 0u;
397*795d594fSAndroid Build Coastguard Worker 
398*795d594fSAndroid Build Coastguard Worker   friend class dex::DexFileVerifier;
399*795d594fSAndroid Build Coastguard Worker };
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker }  // namespace art
402*795d594fSAndroid Build Coastguard Worker 
403*795d594fSAndroid Build Coastguard Worker #endif  // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_H_
404