blob: fcd3ab0c1e7fb52d347b432a625836f3796d0c1e [file] [log] [blame]
David Sehr7629f602016-08-07 16:01:51 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Header file of an in-memory representation of DEX files.
17 */
18
19#ifndef ART_DEXLAYOUT_DEX_IR_H_
20#define ART_DEXLAYOUT_DEX_IR_H_
21
22#include <iostream>
23#include <map>
24#include <vector>
25#include <stdint.h>
26
27#include "dex_file.h"
28
29namespace art {
30namespace dex_ir {
31
32// Forward declarations for classes used in containers or pointed to.
33class AnnotationsDirectoryItem;
34class AnnotationSetItem;
35class ArrayItem;
36class ClassData;
37class ClassDef;
38class CodeItem;
39class DebugInfoItem;
40class FieldId;
41class FieldItem;
42class Header;
43class MapList;
44class MapItem;
45class MethodId;
46class MethodItem;
47class ProtoId;
48class StringId;
49class TryItem;
50class TypeId;
51
52// Visitor support
53class AbstractDispatcher {
54 public:
55 AbstractDispatcher() = default;
56 virtual ~AbstractDispatcher() { }
57
58 virtual void Dispatch(Header* header) = 0;
59 virtual void Dispatch(const StringId* string_id) = 0;
60 virtual void Dispatch(const TypeId* type_id) = 0;
61 virtual void Dispatch(const ProtoId* proto_id) = 0;
62 virtual void Dispatch(const FieldId* field_id) = 0;
63 virtual void Dispatch(const MethodId* method_id) = 0;
64 virtual void Dispatch(ClassData* class_data) = 0;
65 virtual void Dispatch(ClassDef* class_def) = 0;
66 virtual void Dispatch(FieldItem* field_item) = 0;
67 virtual void Dispatch(MethodItem* method_item) = 0;
68 virtual void Dispatch(ArrayItem* array_item) = 0;
69 virtual void Dispatch(CodeItem* code_item) = 0;
70 virtual void Dispatch(TryItem* try_item) = 0;
71 virtual void Dispatch(DebugInfoItem* debug_info_item) = 0;
72 virtual void Dispatch(AnnotationSetItem* annotation_set_item) = 0;
73 virtual void Dispatch(AnnotationsDirectoryItem* annotations_directory_item) = 0;
74 virtual void Dispatch(MapList* map_list) = 0;
75 virtual void Dispatch(MapItem* map_item) = 0;
76
77 private:
78 DISALLOW_COPY_AND_ASSIGN(AbstractDispatcher);
79};
80
81// Collections become owners of the objects added by moving them into unique pointers.
82template<class T> class CollectionWithOffset {
83 public:
84 CollectionWithOffset() = default;
85 std::vector<std::unique_ptr<T>>& Collection() { return collection_; }
86 // Read-time support methods
87 void AddWithPosition(uint32_t position, T* object) {
88 collection_.push_back(std::unique_ptr<T>(object));
89 collection_.back()->SetOffset(position);
90 }
91 // Ordinary object insertion into collection.
92 void Insert(T object ATTRIBUTE_UNUSED) {
93 // TODO(sehr): add ordered insertion support.
94 UNIMPLEMENTED(FATAL) << "Insertion not ready";
95 }
96 uint32_t GetOffset() const { return offset_; }
97 void SetOffset(uint32_t new_offset) { offset_ = new_offset; }
98 uint32_t Size() const { return collection_.size(); }
99
100 private:
101 std::vector<std::unique_ptr<T>> collection_;
102 uint32_t offset_ = 0;
103 DISALLOW_COPY_AND_ASSIGN(CollectionWithOffset);
104};
105
106class Item {
107 public:
108 virtual ~Item() { }
109 uint32_t GetOffset() const { return offset_; }
110 void SetOffset(uint32_t offset) { offset_ = offset; }
111 protected:
112 uint32_t offset_ = 0;
113};
114
115class Header : public Item {
116 public:
117 explicit Header(const DexFile& dex_file);
118 ~Header() OVERRIDE { }
119
120 const DexFile& GetDexFile() const { return dex_file_; }
121
122 const uint8_t* Magic() const { return magic_; }
123 uint32_t Checksum() const { return checksum_; }
124 const uint8_t* Signature() const { return signature_; }
125 uint32_t EndianTag() const { return endian_tag_; }
126 uint32_t FileSize() const { return file_size_; }
127 uint32_t HeaderSize() const { return header_size_; }
128 uint32_t LinkSize() const { return link_size_; }
129 uint32_t LinkOffset() const { return link_offset_; }
130 uint32_t DataSize() const { return data_size_; }
131 uint32_t DataOffset() const { return data_offset_; }
132
133 void SetChecksum(uint32_t new_checksum) { checksum_ = new_checksum; }
134 void SetSignature(const uint8_t* new_signature) {
135 memcpy(signature_, new_signature, sizeof(signature_));
136 }
137 void SetFileSize(uint32_t new_file_size) { file_size_ = new_file_size; }
138 void SetHeaderSize(uint32_t new_header_size) { header_size_ = new_header_size; }
139 void SetLinkSize(uint32_t new_link_size) { link_size_ = new_link_size; }
140 void SetLinkOffset(uint32_t new_link_offset) { link_offset_ = new_link_offset; }
141 void SetDataSize(uint32_t new_data_size) { data_size_ = new_data_size; }
142 void SetDataOffset(uint32_t new_data_offset) { data_offset_ = new_data_offset; }
143
144 // Collections.
145 std::vector<std::unique_ptr<StringId>>& StringIds() { return string_ids_.Collection(); }
146 std::vector<std::unique_ptr<TypeId>>& TypeIds() { return type_ids_.Collection(); }
147 std::vector<std::unique_ptr<ProtoId>>& ProtoIds() { return proto_ids_.Collection(); }
148 std::vector<std::unique_ptr<FieldId>>& FieldIds() { return field_ids_.Collection(); }
149 std::vector<std::unique_ptr<MethodId>>& MethodIds() { return method_ids_.Collection(); }
150 std::vector<std::unique_ptr<ClassDef>>& ClassDefs() { return class_defs_.Collection(); }
151 uint32_t StringIdsOffset() const { return string_ids_.GetOffset(); }
152 uint32_t TypeIdsOffset() const { return type_ids_.GetOffset(); }
153 uint32_t ProtoIdsOffset() const { return proto_ids_.GetOffset(); }
154 uint32_t FieldIdsOffset() const { return field_ids_.GetOffset(); }
155 uint32_t MethodIdsOffset() const { return method_ids_.GetOffset(); }
156 uint32_t ClassDefsOffset() const { return class_defs_.GetOffset(); }
157 void SetStringIdsOffset(uint32_t new_offset) { string_ids_.SetOffset(new_offset); }
158 void SetTypeIdsOffset(uint32_t new_offset) { type_ids_.SetOffset(new_offset); }
159 void SetProtoIdsOffset(uint32_t new_offset) { proto_ids_.SetOffset(new_offset); }
160 void SetFieldIdsOffset(uint32_t new_offset) { field_ids_.SetOffset(new_offset); }
161 void SetMethodIdsOffset(uint32_t new_offset) { method_ids_.SetOffset(new_offset); }
162 void SetClassDefsOffset(uint32_t new_offset) { class_defs_.SetOffset(new_offset); }
163 uint32_t StringIdsSize() const { return string_ids_.Size(); }
164 uint32_t TypeIdsSize() const { return type_ids_.Size(); }
165 uint32_t ProtoIdsSize() const { return proto_ids_.Size(); }
166 uint32_t FieldIdsSize() const { return field_ids_.Size(); }
167 uint32_t MethodIdsSize() const { return method_ids_.Size(); }
168 uint32_t ClassDefsSize() const { return class_defs_.Size(); }
169
Jeff Haoc3acfc52016-08-29 14:18:26 -0700170 TypeId* GetTypeIdOrNullPtr(uint16_t index) {
171 return index == DexFile::kDexNoIndex16 ? nullptr : TypeIds()[index].get();
172 }
173
174 StringId* GetStringIdOrNullPtr(uint32_t index) {
175 return index == DexFile::kDexNoIndex ? nullptr : StringIds()[index].get();
176 }
177
David Sehr7629f602016-08-07 16:01:51 -0700178 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
179
180 private:
181 const DexFile& dex_file_;
182 uint8_t magic_[8];
183 uint32_t checksum_;
184 uint8_t signature_[DexFile::kSha1DigestSize];
185 uint32_t endian_tag_;
186 uint32_t file_size_;
187 uint32_t header_size_;
188 uint32_t link_size_;
189 uint32_t link_offset_;
190 uint32_t data_size_;
191 uint32_t data_offset_;
192
193 CollectionWithOffset<StringId> string_ids_;
194 CollectionWithOffset<TypeId> type_ids_;
195 CollectionWithOffset<ProtoId> proto_ids_;
196 CollectionWithOffset<FieldId> field_ids_;
197 CollectionWithOffset<MethodId> method_ids_;
198 CollectionWithOffset<ClassDef> class_defs_;
199 DISALLOW_COPY_AND_ASSIGN(Header);
200};
201
202class StringId : public Item {
203 public:
204 StringId(const DexFile::StringId& disk_string_id, Header& header) :
205 data_(strdup(header.GetDexFile().GetStringData(disk_string_id))) {
206 }
207 ~StringId() OVERRIDE { }
208
209 const char* Data() const { return data_.get(); }
210
211 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
212
213 private:
214 std::unique_ptr<const char> data_;
215 DISALLOW_COPY_AND_ASSIGN(StringId);
216};
217
218class TypeId : public Item {
219 public:
220 TypeId(const DexFile::TypeId& disk_type_id, Header& header) :
221 string_id_(header.StringIds()[disk_type_id.descriptor_idx_].get()) {
222 }
223 ~TypeId() OVERRIDE { }
224
225 StringId* GetStringId() const { return string_id_; }
226
227 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
228
229 private:
230 StringId* string_id_;
231 DISALLOW_COPY_AND_ASSIGN(TypeId);
232};
233
234class ProtoId : public Item {
235 public:
236 ProtoId(const DexFile::ProtoId& disk_proto_id, Header& header) {
237 shorty_ = header.StringIds()[disk_proto_id.shorty_idx_].get();
238 return_type_ = header.TypeIds()[disk_proto_id.return_type_idx_].get();
239 DexFileParameterIterator dfpi(header.GetDexFile(), disk_proto_id);
240 while (dfpi.HasNext()) {
241 parameters_.push_back(header.TypeIds()[dfpi.GetTypeIdx()].get());
242 dfpi.Next();
243 }
244 }
245 ~ProtoId() OVERRIDE { }
246
247 const StringId* Shorty() const { return shorty_; }
248 const TypeId* ReturnType() const { return return_type_; }
249 const std::vector<const TypeId*>& Parameters() const { return parameters_; }
250
251 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
252
253 private:
254 const StringId* shorty_;
255 const TypeId* return_type_;
256 std::vector<const TypeId*> parameters_;
257 DISALLOW_COPY_AND_ASSIGN(ProtoId);
258};
259
260class FieldId : public Item {
261 public:
262 FieldId(const DexFile::FieldId& disk_field_id, Header& header) {
263 class_ = header.TypeIds()[disk_field_id.class_idx_].get();
264 type_ = header.TypeIds()[disk_field_id.type_idx_].get();
265 name_ = header.StringIds()[disk_field_id.name_idx_].get();
266 }
267 ~FieldId() OVERRIDE { }
268
269 const TypeId* Class() const { return class_; }
270 const TypeId* Type() const { return type_; }
271 const StringId* Name() const { return name_; }
272
273 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
274
275 private:
276 const TypeId* class_;
277 const TypeId* type_;
278 const StringId* name_;
279 DISALLOW_COPY_AND_ASSIGN(FieldId);
280};
281
282class MethodId : public Item {
283 public:
284 MethodId(const DexFile::MethodId& disk_method_id, Header& header) {
285 class_ = header.TypeIds()[disk_method_id.class_idx_].get();
286 proto_ = header.ProtoIds()[disk_method_id.proto_idx_].get();
287 name_ = header.StringIds()[disk_method_id.name_idx_].get();
288 }
289 ~MethodId() OVERRIDE { }
290
291 const TypeId* Class() const { return class_; }
292 const ProtoId* Proto() const { return proto_; }
293 const StringId* Name() const { return name_; }
294
295 void Accept(AbstractDispatcher* dispatch) const { dispatch->Dispatch(this); }
296
297 private:
298 const TypeId* class_;
299 const ProtoId* proto_;
300 const StringId* name_;
301 DISALLOW_COPY_AND_ASSIGN(MethodId);
302};
303
304class FieldItem : public Item {
305 public:
306 FieldItem(uint32_t access_flags, const FieldId* field_id) :
307 access_flags_(access_flags), field_id_(field_id) { }
308 ~FieldItem() OVERRIDE { }
309
310 uint32_t GetAccessFlags() const { return access_flags_; }
311 const FieldId* GetFieldId() const { return field_id_; }
312
313 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
314
315 private:
316 uint32_t access_flags_;
317 const FieldId* field_id_;
318 DISALLOW_COPY_AND_ASSIGN(FieldItem);
319};
320
321class MethodItem : public Item {
322 public:
323 MethodItem(uint32_t access_flags, const MethodId* method_id, const CodeItem* code) :
324 access_flags_(access_flags), method_id_(method_id), code_(code) { }
325 ~MethodItem() OVERRIDE { }
326
327 uint32_t GetAccessFlags() const { return access_flags_; }
328 const MethodId* GetMethodId() const { return method_id_; }
329 const CodeItem* GetCodeItem() const { return code_.get(); }
330
331 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
332
333 private:
334 uint32_t access_flags_;
335 const MethodId* method_id_;
336 std::unique_ptr<const CodeItem> code_;
337 DISALLOW_COPY_AND_ASSIGN(MethodItem);
338};
339
340class ArrayItem : public Item {
341 public:
342 class NameValuePair {
343 public:
344 NameValuePair(StringId* name, ArrayItem* value) :
345 name_(name), value_(value) { }
346
347 StringId* Name() const { return name_; }
348 ArrayItem* Value() const { return value_.get(); }
349
350 private:
351 StringId* name_;
352 std::unique_ptr<ArrayItem> value_;
353 DISALLOW_COPY_AND_ASSIGN(NameValuePair);
354 };
355
356 ArrayItem(Header& header, const uint8_t** data, uint8_t type, uint8_t length);
357 ArrayItem(Header& header, const uint8_t** data);
358 ~ArrayItem() OVERRIDE { }
359
360 int8_t Type() const { return type_; }
361 bool GetBoolean() const { return item_.bool_val_; }
362 int8_t GetByte() const { return item_.byte_val_; }
363 int16_t GetShort() const { return item_.short_val_; }
364 uint16_t GetChar() const { return item_.char_val_; }
365 int32_t GetInt() const { return item_.int_val_; }
366 int64_t GetLong() const { return item_.long_val_; }
367 float GetFloat() const { return item_.float_val_; }
368 double GetDouble() const { return item_.double_val_; }
369 StringId* GetStringId() const { return item_.string_val_; }
370 FieldId* GetFieldId() const { return item_.field_val_; }
371 MethodId* GetMethodId() const { return item_.method_val_; }
372 std::vector<std::unique_ptr<ArrayItem>>* GetAnnotationArray() const {
373 return item_.annotation_array_val_;
374 }
375 StringId* GetAnnotationAnnotationString() const {
376 return item_.annotation_annotation_val_.string_;
377 }
378 std::vector<std::unique_ptr<NameValuePair>>* GetAnnotationAnnotationNameValuePairArray() const {
379 return item_.annotation_annotation_val_.array_;
380 }
381
382 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
383
384 private:
385 void Read(Header& header, const uint8_t** data, uint8_t type, uint8_t length);
386 uint8_t type_;
387 union {
388 bool bool_val_;
389 int8_t byte_val_;
390 int16_t short_val_;
391 uint16_t char_val_;
392 int32_t int_val_;
393 int64_t long_val_;
394 float float_val_;
395 double double_val_;
396 StringId* string_val_;
397 FieldId* field_val_;
398 MethodId* method_val_;
399 std::vector<std::unique_ptr<ArrayItem>>* annotation_array_val_;
400 struct {
401 StringId* string_;
402 std::vector<std::unique_ptr<NameValuePair>>* array_;
403 } annotation_annotation_val_;
404 } item_;
405 DISALLOW_COPY_AND_ASSIGN(ArrayItem);
406};
407
408class ClassData : public Item {
409 public:
410 ClassData() = default;
411 ~ClassData() OVERRIDE = default;
412 std::vector<std::unique_ptr<FieldItem>>& StaticFields() { return static_fields_; }
413 std::vector<std::unique_ptr<FieldItem>>& InstanceFields() { return instance_fields_; }
414 std::vector<std::unique_ptr<MethodItem>>& DirectMethods() { return direct_methods_; }
415 std::vector<std::unique_ptr<MethodItem>>& VirtualMethods() { return virtual_methods_; }
416
417 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
418
419 private:
420 std::vector<std::unique_ptr<FieldItem>> static_fields_;
421 std::vector<std::unique_ptr<FieldItem>> instance_fields_;
422 std::vector<std::unique_ptr<MethodItem>> direct_methods_;
423 std::vector<std::unique_ptr<MethodItem>> virtual_methods_;
424 DISALLOW_COPY_AND_ASSIGN(ClassData);
425};
426
427class ClassDef : public Item {
428 public:
429 ClassDef(const DexFile::ClassDef& disk_class_def, Header& header);
430 ~ClassDef() OVERRIDE { }
431
432 const TypeId* ClassType() const { return class_type_; }
433 uint32_t GetAccessFlags() const { return access_flags_; }
434 const TypeId* Superclass() const { return superclass_; }
435 std::vector<TypeId*>* Interfaces() { return &interfaces_; }
436 uint32_t InterfacesOffset() const { return interfaces_offset_; }
437 void SetInterfacesOffset(uint32_t new_offset) { interfaces_offset_ = new_offset; }
438 const StringId* SourceFile() const { return source_file_; }
439 AnnotationsDirectoryItem* Annotations() const { return annotations_.get(); }
440 std::vector<std::unique_ptr<ArrayItem>>* StaticValues() { return static_values_; }
441 ClassData* GetClassData() { return &class_data_; }
442
Jeff Haoc3acfc52016-08-29 14:18:26 -0700443 MethodItem* GenerateMethodItem(Header& header, ClassDataItemIterator& cdii);
444
David Sehr7629f602016-08-07 16:01:51 -0700445 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
446
447 private:
448 const TypeId* class_type_;
449 uint32_t access_flags_;
450 const TypeId* superclass_;
451 std::vector<TypeId*> interfaces_;
452 uint32_t interfaces_offset_;
453 const StringId* source_file_;
454 std::unique_ptr<AnnotationsDirectoryItem> annotations_;
455 std::vector<std::unique_ptr<ArrayItem>>* static_values_;
456 ClassData class_data_;
457 DISALLOW_COPY_AND_ASSIGN(ClassDef);
458};
459
460class CodeItem : public Item {
461 public:
462 CodeItem(const DexFile::CodeItem& disk_code_item, Header& header);
463 ~CodeItem() OVERRIDE { }
464
465 uint16_t RegistersSize() const { return registers_size_; }
466 uint16_t InsSize() const { return ins_size_; }
467 uint16_t OutsSize() const { return outs_size_; }
468 uint16_t TriesSize() const { return tries_size_; }
469 DebugInfoItem* DebugInfo() const { return debug_info_.get(); }
470 uint32_t InsnsSize() const { return insns_size_; }
471 uint16_t* Insns() const { return insns_.get(); }
472 std::vector<std::unique_ptr<const TryItem>>* Tries() const { return tries_; }
473
474 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
475
476 private:
477 uint16_t registers_size_;
478 uint16_t ins_size_;
479 uint16_t outs_size_;
480 uint16_t tries_size_;
481 std::unique_ptr<DebugInfoItem> debug_info_;
482 uint32_t insns_size_;
483 std::unique_ptr<uint16_t[]> insns_;
484 std::vector<std::unique_ptr<const TryItem>>* tries_;
485 DISALLOW_COPY_AND_ASSIGN(CodeItem);
486};
487
488class TryItem : public Item {
489 public:
490 class CatchHandler {
491 public:
492 CatchHandler(const TypeId* type_id, uint32_t address) : type_id_(type_id), address_(address) { }
493
494 const TypeId* GetTypeId() const { return type_id_; }
495 uint32_t GetAddress() const { return address_; }
496
497 private:
498 const TypeId* type_id_;
499 uint32_t address_;
500 DISALLOW_COPY_AND_ASSIGN(CatchHandler);
501 };
502
503 TryItem(const DexFile::TryItem& disk_try_item,
504 const DexFile::CodeItem& disk_code_item,
505 Header& header) {
506 start_addr_ = disk_try_item.start_addr_;
507 insn_count_ = disk_try_item.insn_count_;
508 for (CatchHandlerIterator it(disk_code_item, disk_try_item); it.HasNext(); it.Next()) {
509 const uint16_t type_index = it.GetHandlerTypeIndex();
Jeff Haoc3acfc52016-08-29 14:18:26 -0700510 const TypeId* type_id = header.GetTypeIdOrNullPtr(type_index);
David Sehr7629f602016-08-07 16:01:51 -0700511 handlers_.push_back(std::unique_ptr<const CatchHandler>(
512 new CatchHandler(type_id, it.GetHandlerAddress())));
513 }
514 }
515 ~TryItem() OVERRIDE { }
516
517 uint32_t StartAddr() const { return start_addr_; }
518 uint16_t InsnCount() const { return insn_count_; }
519 const std::vector<std::unique_ptr<const CatchHandler>>& GetHandlers() const { return handlers_; }
520
521 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
522
523 private:
524 uint32_t start_addr_;
525 uint16_t insn_count_;
526 std::vector<std::unique_ptr<const CatchHandler>> handlers_;
527 DISALLOW_COPY_AND_ASSIGN(TryItem);
528};
529
530
531struct PositionInfo {
532 PositionInfo(uint32_t address, uint32_t line) : address_(address), line_(line) { }
533
534 uint32_t address_;
535 uint32_t line_;
536};
537
538struct LocalInfo {
539 LocalInfo(const char* name, const char* descriptor, const char* signature, uint32_t start_address,
540 uint32_t end_address, uint16_t reg) :
541 name_(name), descriptor_(descriptor), signature_(signature), start_address_(start_address),
542 end_address_(end_address), reg_(reg) { }
543
544 std::string name_;
545 std::string descriptor_;
546 std::string signature_;
547 uint32_t start_address_;
548 uint32_t end_address_;
549 uint16_t reg_;
550};
551
552class DebugInfoItem : public Item {
553 public:
554 DebugInfoItem() = default;
555
556 std::vector<std::unique_ptr<PositionInfo>>& GetPositionInfo() { return positions_; }
557 std::vector<std::unique_ptr<LocalInfo>>& GetLocalInfo() { return locals_; }
558
559 private:
560 std::vector<std::unique_ptr<PositionInfo>> positions_;
561 std::vector<std::unique_ptr<LocalInfo>> locals_;
562 DISALLOW_COPY_AND_ASSIGN(DebugInfoItem);
563};
564
565class AnnotationSetItem : public Item {
566 public:
567 class AnnotationItem {
568 public:
569 AnnotationItem(uint8_t visibility, ArrayItem* item) :
570 visibility_(visibility), item_(item) { }
571
572 uint8_t GetVisibility() const { return visibility_; }
573 ArrayItem* GetItem() const { return item_.get(); }
574
575 private:
576 uint8_t visibility_;
577 std::unique_ptr<ArrayItem> item_;
578 DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
579 };
580
581 AnnotationSetItem(const DexFile::AnnotationSetItem& disk_annotations_item, Header& header);
582 ~AnnotationSetItem() OVERRIDE { }
583
584 std::vector<std::unique_ptr<AnnotationItem>>& GetItems() { return items_; }
585
586 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
587
588 private:
589 std::vector<std::unique_ptr<AnnotationItem>> items_;
590 DISALLOW_COPY_AND_ASSIGN(AnnotationSetItem);
591};
592
593class AnnotationsDirectoryItem : public Item {
594 public:
595 class FieldAnnotation {
596 public:
597 FieldAnnotation(FieldId* field_id, AnnotationSetItem* annotation_set_item) :
598 field_id_(field_id), annotation_set_item_(annotation_set_item) { }
599
600 FieldId* GetFieldId() const { return field_id_; }
601 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
602
603 private:
604 FieldId* field_id_;
605 std::unique_ptr<AnnotationSetItem> annotation_set_item_;
606 DISALLOW_COPY_AND_ASSIGN(FieldAnnotation);
607 };
608
609 class MethodAnnotation {
610 public:
611 MethodAnnotation(MethodId* method_id, AnnotationSetItem* annotation_set_item) :
612 method_id_(method_id), annotation_set_item_(annotation_set_item) { }
613
614 MethodId* GetMethodId() const { return method_id_; }
615 AnnotationSetItem* GetAnnotationSetItem() const { return annotation_set_item_.get(); }
616
617 private:
618 MethodId* method_id_;
619 std::unique_ptr<AnnotationSetItem> annotation_set_item_;
620 DISALLOW_COPY_AND_ASSIGN(MethodAnnotation);
621 };
622
623 class ParameterAnnotation {
624 public:
625 ParameterAnnotation(MethodId* method_id,
626 const DexFile::AnnotationSetRefList* annotation_set_ref_list,
627 Header& header) :
628 method_id_(method_id) {
629 for (uint32_t i = 0; i < annotation_set_ref_list->size_; ++i) {
630 const DexFile::AnnotationSetItem* annotation_set_item =
631 header.GetDexFile().GetSetRefItemItem(&annotation_set_ref_list->list_[i]);
632 annotations_.push_back(std::unique_ptr<AnnotationSetItem>(
633 new AnnotationSetItem(*annotation_set_item, header)));
634 }
635 }
636
637 MethodId* GetMethodId() const { return method_id_; }
638 std::vector<std::unique_ptr<AnnotationSetItem>>& GetAnnotations() { return annotations_; }
639
640 private:
641 MethodId* method_id_;
642 std::vector<std::unique_ptr<AnnotationSetItem>> annotations_;
643 DISALLOW_COPY_AND_ASSIGN(ParameterAnnotation);
644 };
645
646 AnnotationsDirectoryItem(const DexFile::AnnotationsDirectoryItem* disk_annotations_item,
647 Header& header);
648
649 AnnotationSetItem* GetClassAnnotation() const { return class_annotation_.get(); }
650
651 std::vector<std::unique_ptr<FieldAnnotation>>& GetFieldAnnotations() {
652 return field_annotations_;
653 }
654
655 std::vector<std::unique_ptr<MethodAnnotation>>& GetMethodAnnotations() {
656 return method_annotations_;
657 }
658
659 std::vector<std::unique_ptr<ParameterAnnotation>>& GetParameterAnnotations() {
660 return parameter_annotations_;
661 }
662
663 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
664
665 private:
666 std::unique_ptr<AnnotationSetItem> class_annotation_;
667 std::vector<std::unique_ptr<FieldAnnotation>> field_annotations_;
668 std::vector<std::unique_ptr<MethodAnnotation>> method_annotations_;
669 std::vector<std::unique_ptr<ParameterAnnotation>> parameter_annotations_;
670 DISALLOW_COPY_AND_ASSIGN(AnnotationsDirectoryItem);
671};
672
673// TODO(sehr): implement MapList.
674class MapList : public Item {
675 public:
676 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
677
678 private:
679 DISALLOW_COPY_AND_ASSIGN(MapList);
680};
681
682class MapItem : public Item {
683 public:
684 void Accept(AbstractDispatcher* dispatch) { dispatch->Dispatch(this); }
685
686 private:
687 DISALLOW_COPY_AND_ASSIGN(MapItem);
688};
689
690} // namespace dex_ir
691} // namespace art
692
693#endif // ART_DEXLAYOUT_DEX_IR_H_