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_namer.h"
19 : #include "syzygy/refinery/types/type_repository.h"
20 :
21 m : namespace refinery {
22 :
23 m : Type::Type(TypeKind kind,
24 m : size_t size)
25 m : : repository_(nullptr),
26 m : type_id_(kNoTypeId),
27 m : kind_(kind),
28 m : size_(size) {
29 m : }
30 :
31 m : Type::~Type() {
32 m : }
33 :
34 m : base::string16 Type::GetName() const {
35 m : base::string16 name;
36 m : if (TypeNamer::GetName(this, &name))
37 m : return name;
38 m : return kUnknownTypeName;
39 m : }
40 :
41 m : base::string16 Type::GetDecoratedName() const {
42 m : base::string16 name;
43 m : if (TypeNamer::GetDecoratedName(this, &name))
44 m : return name;
45 m : return kUnknownTypeName;
46 m : }
47 :
48 m : void Type::SetRepository(TypeRepository* repository, TypeId type_id) {
49 m : DCHECK(repository);
50 m : DCHECK(!repository_);
51 m : DCHECK_EQ(kNoTypeId, type_id_);
52 m : DCHECK_NE(kNoTypeId, type_id);
53 :
54 m : repository_ = repository;
55 m : type_id_ = type_id;
56 m : }
57 :
58 m : NamedType::NamedType(TypeKind kind,
59 m : size_t size,
60 m : const base::string16& name,
61 m : const base::string16& decorated_name)
62 m : : Type(kind, size), name_(name), decorated_name_(decorated_name) {
63 m : }
64 :
65 m : NamedType::~NamedType() {
66 m : }
67 :
68 m : BasicType::BasicType(const base::string16& name, size_t size)
69 m : : NamedType(BASIC_TYPE_KIND, size, name, name) {
70 m : }
71 :
72 m : UserDefinedType::UserDefinedType(const base::string16& name,
73 m : size_t size,
74 m : UdtKind udt_kind)
75 m : : is_fwd_decl_(false),
76 m : udt_kind_(udt_kind),
77 m : NamedType(USER_DEFINED_TYPE_KIND, size, name, name) {
78 m : }
79 :
80 m : UserDefinedType::UserDefinedType(const base::string16& name,
81 m : const base::string16& decorated_name,
82 m : size_t size,
83 m : UdtKind udt_kind)
84 m : : is_fwd_decl_(false),
85 m : udt_kind_(udt_kind),
86 m : NamedType(USER_DEFINED_TYPE_KIND, size, name, decorated_name) {
87 m : }
88 :
89 m : TypePtr UserDefinedType::GetFieldType(size_t field_no) const {
90 m : DCHECK(repository());
91 m : DCHECK(!is_fwd_decl_);
92 m : DCHECK_GT(fields_.size(), field_no);
93 :
94 m : return repository()->GetType(fields_[field_no]->type_id());
95 m : }
96 :
97 m : TypePtr UserDefinedType::GetFunctionType(size_t function_no) const {
98 m : DCHECK(repository());
99 m : DCHECK(!is_fwd_decl_);
100 m : DCHECK_GT(functions_.size(), function_no);
101 :
102 m : return repository()->GetType(functions_[function_no].type_id());
103 m : }
104 :
105 m : void UserDefinedType::Finalize(Fields* fields, Functions* functions) {
106 m : DCHECK(!is_fwd_decl_);
107 m : DCHECK_EQ(0U, fields_.size());
108 m : DCHECK_EQ(0U, functions_.size());
109 m : DCHECK(fields);
110 m : DCHECK(functions);
111 :
112 m : fields_.swap(*fields);
113 m : functions_.swap(*functions);
114 m : }
115 :
116 m : void UserDefinedType::SetIsForwardDeclaration() {
117 m : DCHECK(!is_fwd_decl_);
118 m : DCHECK_EQ(0U, fields_.size());
119 m : DCHECK_EQ(0U, functions_.size());
120 :
121 m : is_fwd_decl_ = true;
122 m : }
123 :
124 m : UserDefinedType::Field::Field(FieldKind kind,
125 m : ptrdiff_t offset,
126 m : TypeId type_id,
127 m : TypeRepository* repository)
128 m : : kind_(kind), offset_(offset), type_id_(type_id), repository_(repository) {
129 m : DCHECK_NE(kNoTypeId, type_id);
130 m : DCHECK(repository);
131 m : }
132 :
133 m : TypePtr UserDefinedType::Field::GetType() const {
134 m : DCHECK(repository_);
135 m : return repository_->GetType(type_id_);
136 m : }
137 :
138 m : bool UserDefinedType::Field::operator==(const Field& o) const {
139 m : return IsEqual(o);
140 m : }
141 :
142 m : bool UserDefinedType::Field::IsEqual(const Field& o) const {
143 m : return kind_ == o.kind_ && offset_ == o.offset_ && type_id_ == o.type_id_;
144 m : }
145 :
146 m : UserDefinedType::Field::~Field() {
147 m : }
148 :
149 m : UserDefinedType::BaseClassField::BaseClassField(ptrdiff_t offset,
150 m : TypeId type_id,
151 m : TypeRepository* repository)
152 m : : Field(BASE_CLASS_KIND, offset, type_id, repository) {
153 m : }
154 :
155 m : UserDefinedType::MemberField::MemberField(const base::string16& name,
156 m : ptrdiff_t offset,
157 m : Type::Flags flags,
158 m : size_t bit_pos,
159 m : size_t bit_len,
160 m : TypeId type_id,
161 m : TypeRepository* repository)
162 m : : Field(MEMBER_KIND, offset, type_id, repository),
163 m : name_(name),
164 m : flags_(flags),
165 m : bit_pos_(bit_pos),
166 m : bit_len_(bit_len) {
167 m : DCHECK_GE(63u, bit_pos);
168 m : DCHECK_GE(63u, bit_len);
169 m : }
170 :
171 m : bool UserDefinedType::MemberField::IsEqual(const Field& o) const {
172 m : if (!Field::IsEqual(o))
173 m : return false;
174 :
175 m : const MemberField* o_member = static_cast<const MemberField*>(&o);
176 :
177 m : return name_ == o_member->name_ && flags_ == o_member->flags_ &&
178 m : bit_pos_ == o_member->bit_pos_ && bit_len_ == o_member->bit_len_;
179 m : }
180 :
181 m : UserDefinedType::VfptrField::VfptrField(ptrdiff_t offset,
182 m : TypeId type_id,
183 m : TypeRepository* repository)
184 m : : Field(VFPTR_KIND, offset, type_id, repository) {
185 m : }
186 :
187 m : UserDefinedType::Function::Function(const base::string16& name, TypeId type_id)
188 m : : name_(name), type_id_(type_id) {
189 m : DCHECK_NE(kNoTypeId, type_id);
190 m : }
191 :
192 m : bool UserDefinedType::Function::operator==(const Function& other) const {
193 m : return name_ == other.name_ && type_id_ == other.type_id_;
194 m : }
195 :
196 m : PointerType::PointerType(size_t size, Mode ptr_mode)
197 m : : Type(POINTER_TYPE_KIND, size),
198 m : flags_(kNoTypeFlags),
199 m : content_type_id_(kNoTypeId),
200 m : ptr_mode_(ptr_mode) {
201 m : }
202 :
203 m : TypePtr PointerType::GetContentType() const {
204 m : DCHECK(repository());
205 :
206 m : return repository()->GetType(content_type_id());
207 m : }
208 :
209 m : void PointerType::Finalize(Flags flags, TypeId content_type_id) {
210 m : DCHECK_EQ(kNoTypeFlags, flags_);
211 m : DCHECK_EQ(kNoTypeId, content_type_id_);
212 m : DCHECK_NE(kNoTypeId, content_type_id);
213 :
214 m : flags_ = flags;
215 m : content_type_id_ = content_type_id;
216 m : }
217 :
218 m : ArrayType::ArrayType(size_t size)
219 m : : Type(ARRAY_TYPE_KIND, size),
220 m : index_type_id_(kNoTypeId),
221 m : num_elements_(0),
222 m : element_type_id_(kNoTypeId) {
223 m : }
224 :
225 m : TypePtr ArrayType::GetIndexType() const {
226 m : DCHECK(repository());
227 :
228 m : return repository()->GetType(index_type_id_);
229 m : }
230 :
231 m : TypePtr ArrayType::GetElementType() const {
232 m : DCHECK(repository());
233 :
234 m : return repository()->GetType(element_type_id_);
235 m : }
236 :
237 m : void ArrayType::Finalize(Flags flags,
238 m : TypeId index_type_id,
239 m : size_t num_elements,
240 m : TypeId element_type_id) {
241 m : DCHECK_EQ(kNoTypeId, index_type_id_);
242 m : DCHECK_EQ(0U, num_elements_);
243 m : DCHECK_EQ(kNoTypeId, element_type_id_);
244 :
245 m : flags_ = flags;
246 m : index_type_id_ = index_type_id;
247 m : num_elements_ = num_elements;
248 m : element_type_id_ = element_type_id;
249 m : }
250 :
251 m : FunctionType::FunctionType(CallConvention call_convention)
252 m : : Type(FUNCTION_TYPE_KIND, 0),
253 m : call_convention_(call_convention),
254 m : containing_class_id_(kNoTypeId),
255 m : return_type_(kNoTypeFlags, kNoTypeId) {
256 m : }
257 :
258 m : FunctionType::ArgumentType::ArgumentType(Flags flags, TypeId type_id)
259 m : : flags_(flags), type_id_(type_id) {
260 m : }
261 :
262 m : bool FunctionType::ArgumentType::operator==(const ArgumentType& other) const {
263 m : return flags_ == other.flags_ && type_id_ == other.type_id_;
264 m : }
265 :
266 m : void FunctionType::Finalize(const ArgumentType& return_type,
267 m : const Arguments& arg_types,
268 m : TypeId containing_class_id) {
269 m : DCHECK_EQ(0U, arg_types_.size());
270 m : DCHECK_EQ(kNoTypeId, return_type_.type_id());
271 :
272 m : return_type_ = return_type;
273 m : arg_types_ = arg_types;
274 m : containing_class_id_ = containing_class_id;
275 m : }
276 :
277 m : TypePtr FunctionType::GetArgumentType(size_t arg_no) const {
278 m : DCHECK(repository());
279 m : DCHECK_GT(arg_types_.size(), arg_no);
280 :
281 m : return repository()->GetType(arg_types_[arg_no].type_id());
282 m : }
283 :
284 m : TypePtr FunctionType::GetReturnType() const {
285 m : DCHECK(repository());
286 :
287 m : return repository()->GetType(return_type_.type_id());
288 m : }
289 :
290 m : TypePtr FunctionType::GetContainingClassType() const {
291 m : DCHECK(repository());
292 m : DCHECK(containing_class_id_ != kNoTypeId);
293 :
294 m : return repository()->GetType(containing_class_id_);
295 m : }
296 :
297 m : GlobalType::GlobalType(const base::string16& name,
298 m : uint64_t rva,
299 m : TypeId data_type_id,
300 m : size_t size)
301 m : : NamedType(GLOBAL_TYPE_KIND, size, name, name),
302 m : rva_(rva),
303 m : data_type_id_(data_type_id) {
304 m : }
305 :
306 m : TypePtr GlobalType::GetDataType() const {
307 m : DCHECK(repository());
308 m : return repository()->GetType(data_type_id_);
309 m : }
310 :
311 m : WildcardType::WildcardType(const base::string16& name, size_t size)
312 m : : NamedType(WILDCARD_TYPE_KIND, size, name, name) {
313 m : }
314 :
315 m : WildcardType::WildcardType(const base::string16& name,
316 m : const base::string16& decorated_name,
317 m : size_t size)
318 m : : NamedType(WILDCARD_TYPE_KIND, size, name, decorated_name) {
319 m : }
320 :
321 m : } // namespace refinery
|