1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : #include "syzygy/refinery/types/type.h"
15 :
16 : #include "base/md5.h"
17 : #include "base/strings/string_piece.h"
18 : #include "syzygy/refinery/types/type_repository.h"
19 :
20 : namespace refinery {
21 :
22 : Type::Type(TypeKind kind, const base::string16& name, size_t size)
23 E : : Type(kind, name, name, size) {
24 E : }
25 :
26 : Type::Type(TypeKind kind,
27 : const base::string16& name,
28 : const base::string16& decorated_name,
29 : size_t size)
30 : : repository_(nullptr),
31 : type_id_(kNoTypeId),
32 : kind_(kind),
33 : name_(name),
34 : decorated_name_(decorated_name),
35 E : size_(size) {
36 E : }
37 :
38 E : Type::~Type() {
39 E : }
40 :
41 E : void Type::SetRepository(TypeRepository* repository, TypeId type_id) {
42 E : DCHECK(repository);
43 E : DCHECK(!repository_);
44 E : DCHECK_EQ(kNoTypeId, type_id_);
45 E : DCHECK_NE(kNoTypeId, type_id);
46 :
47 E : repository_ = repository;
48 E : type_id_ = type_id;
49 E : }
50 :
51 E : void Type::SetName(const base::string16& name) {
52 E : DCHECK_EQ(L"", name_);
53 E : name_ = name;
54 E : }
55 :
56 E : void Type::SetDecoratedName(const base::string16& decorated_name) {
57 E : DCHECK_EQ(L"", decorated_name_);
58 E : decorated_name_ = decorated_name;
59 E : }
60 :
61 : UserDefinedType::UserDefinedType(const base::string16& name,
62 : size_t size,
63 : UdtKind udt_kind)
64 : : is_fwd_decl_(false),
65 : udt_kind_(udt_kind),
66 E : Type(USER_DEFINED_TYPE_KIND, name, size) {
67 E : }
68 :
69 : UserDefinedType::UserDefinedType(const base::string16& name,
70 : const base::string16& decorated_name,
71 : size_t size,
72 : UdtKind udt_kind)
73 : : is_fwd_decl_(false),
74 : udt_kind_(udt_kind),
75 E : Type(USER_DEFINED_TYPE_KIND, name, decorated_name, size) {
76 E : }
77 :
78 E : TypePtr UserDefinedType::GetFieldType(size_t field_no) const {
79 E : DCHECK(repository());
80 E : DCHECK(!is_fwd_decl_);
81 E : DCHECK_GT(fields_.size(), field_no);
82 :
83 E : return repository()->GetType(fields_[field_no].type_id());
84 E : }
85 :
86 E : TypePtr UserDefinedType::GetFunctionType(size_t function_no) const {
87 E : DCHECK(repository());
88 E : DCHECK(!is_fwd_decl_);
89 E : DCHECK_GT(functions_.size(), function_no);
90 :
91 E : return repository()->GetType(functions_[function_no].type_id());
92 E : }
93 :
94 : BasicType::BasicType(const base::string16& name, size_t size)
95 E : : Type(BASIC_TYPE_KIND, name, name, size) {
96 E : }
97 :
98 : void UserDefinedType::Finalize(const Fields& fields,
99 E : const Functions& functions) {
100 E : DCHECK(!is_fwd_decl_);
101 E : DCHECK_EQ(0U, fields_.size());
102 E : DCHECK_EQ(0U, functions_.size());
103 E : for (auto field : fields)
104 E : fields_.push_back(field);
105 :
106 E : for (auto function : functions)
107 E : functions_.push_back(function);
108 E : }
109 :
110 E : void UserDefinedType::SetIsForwardDeclaration() {
111 E : DCHECK(!is_fwd_decl_);
112 E : DCHECK_EQ(0U, fields_.size());
113 E : DCHECK_EQ(0U, functions_.size());
114 :
115 E : is_fwd_decl_ = true;
116 E : }
117 :
118 : UserDefinedType::Field::Field(const base::string16& name,
119 : ptrdiff_t offset,
120 : Flags flags,
121 : size_t bit_pos,
122 : size_t bit_len,
123 : TypeId type_id)
124 : : name_(name),
125 : offset_(offset),
126 : flags_(flags),
127 : bit_pos_(bit_pos),
128 : bit_len_(bit_len),
129 E : type_id_(type_id) {
130 E : DCHECK_GE(63u, bit_pos);
131 E : DCHECK_GE(63u, bit_len);
132 E : DCHECK_NE(kNoTypeId, type_id);
133 E : }
134 :
135 : UserDefinedType::Function::Function(const base::string16& name, TypeId type_id)
136 E : : name_(name), type_id_(type_id) {
137 E : DCHECK_NE(kNoTypeId, type_id);
138 E : }
139 :
140 : bool UserDefinedType::Function::operator==(const Function& other) const {
141 : return name_ == other.name_ && type_id_ == other.type_id_;
142 : }
143 :
144 E : bool UserDefinedType::Field::operator==(const Field& o) const {
145 : return name_ == o.name_ && offset_ == o.offset_ && flags_ == o.flags_ &&
146 : bit_pos_ == o.bit_pos_ && bit_len_ == o.bit_len_ &&
147 E : type_id_ == o.type_id_;
148 E : }
149 :
150 : PointerType::PointerType(size_t size, Mode ptr_mode)
151 : : Type(POINTER_TYPE_KIND, L"", size),
152 : flags_(kNoTypeFlags),
153 : content_type_id_(kNoTypeId),
154 E : ptr_mode_(ptr_mode) {
155 E : }
156 :
157 E : TypePtr PointerType::GetContentType() const {
158 E : DCHECK(repository());
159 :
160 E : return repository()->GetType(content_type_id());
161 E : }
162 :
163 E : void PointerType::Finalize(Flags flags, TypeId content_type_id) {
164 E : DCHECK_EQ(kNoTypeFlags, flags_);
165 E : DCHECK_EQ(kNoTypeId, content_type_id_);
166 E : DCHECK_NE(kNoTypeId, content_type_id);
167 :
168 E : flags_ = flags;
169 E : content_type_id_ = content_type_id;
170 E : }
171 :
172 : ArrayType::ArrayType(size_t size)
173 : : Type(ARRAY_TYPE_KIND, L"", L"", size),
174 : index_type_id_(kNoTypeId),
175 : num_elements_(0),
176 E : element_type_id_(kNoTypeId) {
177 E : }
178 :
179 E : TypePtr ArrayType::GetIndexType() const {
180 E : DCHECK(repository());
181 :
182 E : return repository()->GetType(index_type_id_);
183 E : }
184 :
185 E : TypePtr ArrayType::GetElementType() const {
186 E : DCHECK(repository());
187 :
188 E : return repository()->GetType(element_type_id_);
189 E : }
190 :
191 : void ArrayType::Finalize(Flags flags,
192 : TypeId index_type_id,
193 : size_t num_elements,
194 E : TypeId element_type_id) {
195 E : DCHECK_EQ(kNoTypeId, index_type_id_);
196 E : DCHECK_EQ(0U, num_elements_);
197 E : DCHECK_EQ(kNoTypeId, element_type_id_);
198 :
199 E : flags_ = flags;
200 E : index_type_id_ = index_type_id;
201 E : num_elements_ = num_elements;
202 E : element_type_id_ = element_type_id;
203 E : }
204 :
205 : FunctionType::FunctionType(CallConvention call_convention)
206 : : Type(FUNCTION_TYPE_KIND, L"", 0),
207 : call_convention_(call_convention),
208 : containing_class_id_(kNoTypeId),
209 E : return_type_(kNoTypeFlags, kNoTypeId) {
210 E : }
211 :
212 : FunctionType::ArgumentType::ArgumentType(Flags flags, TypeId type_id)
213 E : : flags_(flags), type_id_(type_id) {
214 E : }
215 :
216 : bool FunctionType::ArgumentType::operator==(const ArgumentType& other) const {
217 : return flags_ == other.flags_ && type_id_ == other.type_id_;
218 : }
219 :
220 : void FunctionType::Finalize(const ArgumentType& return_type,
221 : const Arguments& arg_types,
222 E : TypeId containing_class_id) {
223 E : DCHECK_EQ(0U, arg_types_.size());
224 E : DCHECK_EQ(kNoTypeId, return_type_.type_id());
225 :
226 E : return_type_ = return_type;
227 E : arg_types_ = arg_types;
228 E : containing_class_id_ = containing_class_id;
229 E : }
230 :
231 E : TypePtr FunctionType::GetArgumentType(size_t arg_no) const {
232 E : DCHECK(repository());
233 E : DCHECK_GT(arg_types_.size(), arg_no);
234 :
235 E : return repository()->GetType(arg_types_[arg_no].type_id());
236 E : }
237 :
238 E : TypePtr FunctionType::GetReturnType() const {
239 E : DCHECK(repository());
240 :
241 E : return repository()->GetType(return_type_.type_id());
242 E : }
243 :
244 E : TypePtr FunctionType::GetContainingClassType() const {
245 E : DCHECK(repository());
246 E : DCHECK(containing_class_id_ != kNoTypeId);
247 :
248 E : return repository()->GetType(containing_class_id_);
249 E : }
250 :
251 : GlobalType::GlobalType(const base::string16& name,
252 : uint64_t rva,
253 : TypeId data_type_id,
254 : size_t size)
255 : : Type(GLOBAL_TYPE_KIND, name, size),
256 : rva_(rva),
257 E : data_type_id_(data_type_id) {
258 E : }
259 :
260 E : TypePtr GlobalType::GetDataType() const {
261 E : DCHECK(repository());
262 E : return repository()->GetType(data_type_id_);
263 E : }
264 :
265 : WildcardType::WildcardType(const base::string16& name, size_t size)
266 E : : Type(WILDCARD_TYPE_KIND, name, size) {
267 E : }
268 :
269 : WildcardType::WildcardType(const base::string16& name,
270 : const base::string16& decorated_name,
271 : size_t size)
272 E : : Type(WILDCARD_TYPE_KIND, name, size) {
273 E : }
274 :
275 : } // namespace refinery
|