Fix warnings when building with clang.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
19 #ifndef _include_jc_types_h_
20 #define _include_jc_types_h_
24 #include "FixedArray.h"
25 #include "compiler/Token.h"
34 #define MAX_ARRAY_DEPTH 5
38 // A boolean type semantically represents 0 or 1. As an optimization, its
39 // internal storage type is the same as int32, and any non-zero value
40 // compares positively to "true".
43 // A character is an arbitrary 8-bit value. Characters are not supported
44 // as a normal storage class; they may only be used for arrays. When read
45 // from an array, they are immediately sign extended to 32 bits. Integers
46 // stored into an char array are truncated to 8 bits.
47 PrimitiveType_Char, // signed, 8-bit character
49 // Enumerations and untyped variables are stored as signed, 32-bit integers.
52 // Floating point values are 32-bit IEEE-754 floats. This is required ro
53 // SourcePawn 1 compatibility.
56 // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
57 // on 64-bit systems), and does not exist in language semantics.
67 // Values of this type cannot be modified.
68 TypeQual_Const = (1 << 0),
70 // Values of this type can be treated as constant expressions. This allows
71 // us to export compile-time constants from modules.
72 TypeQual_ConstExpr = (1 << 1)
75 class Type : public Object
79 // A primitive is a plain-old-data type.
82 // Void is an internal type used to specify that a function returns no
86 // Enums are plain-old-data with int32 storage. They allow for extra
87 // type checking that would not be possible with integers.
90 // Unchecked is a magic type that has implicit, bitwise coercion to
91 // int32, float, bool, or an enum.
94 // Contains type qualifiers, and a back pointer to the actual
98 // ------ Add traceable types below (STRING FIRST!) -------
100 // An immutable type that is a primitive in terms of language
101 // semantics, but gets a special type here to make internal
105 // An array is a fixed-length vector of any other type.
109 // A reference type may only be specified on parameters, and
110 // references may only be computed to primitives or enums.
113 // A function type encapsulates a function signature.
116 // Structs are composite records that may contain primitives, arrays,
117 // functions, enums, and other structs.
120 // Importable types are mainly used during the compilation process
121 // to distinguish between normal names and static imports.
124 // The type of types.
128 void init(Kind kind, Type *root = NULL);
136 static Type *NewVoid(Zone *zone);
137 static Type *NewUnchecked(Zone *zone);
138 static Type *NewType(Zone *zone);
139 static Type *NewPrimitive(Zone *zone, PrimitiveType type);
140 static Type *NewString(Zone *zone);
141 static Type *NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> type);
142 static Type *NewImportable(Zone *zone);
144 static Type *cast(Object *obj) {
146 obj->is(MapKind_Type) ||
147 obj->is(MapKind_FunctionType) ||
148 obj->is(MapKind_StructType) ||
149 obj->is(MapKind_ArrayType) ||
150 obj->is(MapKind_ReferenceType) ||
151 obj->is(MapKind_EnumType));
156 return kind() == PRIMITIVE;
159 return kind() == ARRAY || kind() == EXTERNAL_ARRAY;
162 return kind() == REFERENCE;
165 return kind() == FUNCTION;
168 return kind() == VOID;
171 return kind() == UNCHECKED;
174 return kind() == STRUCT;
176 bool isImportable() {
177 return kind() == IMPORTABLE;
179 PrimitiveType primitive() {
180 assert(isPrimitive());
181 return root_->primitive_;
184 return (isPrimitive() && !isString()) || isEnum() || isUnchecked();
186 PrimitiveType pod() {
189 ? (primitive() == PrimitiveType_Bool)
190 ? PrimitiveType_Int32
192 : PrimitiveType_Int32;
195 return isPrimitive() && primitive() == PrimitiveType_Char;
198 return isPrimitive() && primitive() == PrimitiveType_Float;
201 return isPrimitive() && primitive() == PrimitiveType_Int32;
203 bool isInt32OrEnum() {
204 return isInt32() || isEnum();
207 return isPrimitive() && primitive() == PrimitiveType_Bool;
210 return kind() == STRING;
212 bool isExternalArray() {
213 return kind() == EXTERNAL_ARRAY;
216 return kind() >= STRING;
219 return kind() == ENUM;
222 return kind() == TYPE;
224 bool hasTypeQualifiers() {
225 return kind_ == QUALTYPE;
228 TypeQualifiers quals() {
229 if (!hasTypeQualifiers())
230 return TypeQual_None;
233 Type *unqualified() {
238 static inline size_t offsetOfRoot() {
239 return OFFSETOF(Type, root_);
241 // End GC Descriptor.
245 PrimitiveType primitive_;
246 TypeQualifiers quals_;
248 // For unqualified types, this points to |this|. For qualified types, it
249 // points to the unqualified original type.
250 Barriered<Type> root_;
253 class EnumType : public Type
256 static EnumType *New(Zone *Zone, Handle<String> name);
263 static inline size_t offsetOfName() {
264 return OFFSETOF(EnumType, name_);
266 static inline size_t offsetOfFields() {
267 return OFFSETOF(EnumType, fields_);
269 // End GC Descriptor.
271 static EnumType *cast(Object *obj) {
272 assert(!obj || obj->is(MapKind_EnumType));
273 return (EnumType *)obj;
277 Barriered<String> name_;
278 Barriered<FixedArray> fields_;
281 class ReferenceType : public Type
284 static ReferenceType *New(Zone *zone, Handle<Type> contained);
291 static inline size_t offsetOfContained() {
292 return OFFSETOF(ReferenceType, contained_);
294 // End GC Descriptor.
296 static ReferenceType *cast(Type *obj) {
299 obj = obj->unqualified();
300 assert(obj->is(MapKind_ReferenceType));
301 return (ReferenceType *)obj;
305 Barriered<Type> contained_;
308 class ArrayType : public Type
311 static const int DYNAMIC_ARRAY_SIZE = -1;
313 static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
314 static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
317 Type *temp = contained();
318 while (temp->isArray())
319 temp = ArrayType::cast(temp)->contained();
324 return elements_ == DYNAMIC_ARRAY_SIZE;
326 bool isExtensible() {
327 return isDynamic() && !(quals_ & TypeQual_Const);
332 bool isFixedLength() {
333 return elements_ > 0;
336 return contained()->isPrimitive() &&
337 contained()->primitive() == PrimitiveType_Char;
339 unsigned fixedLength() {
340 assert(isFixedLength());
346 bool hasInlineElements() {
347 // We don't allocate traceable elements inline, since there's no
348 // point to the optimization; we're going to be allocating lots of
349 // objects anyway (in theory).
350 return isFixedLength() && !contained()->isTraceable();
353 // Arrays of this type can be created with this cached map.
357 void setNewMap(ArrayMap *map) {
363 static inline size_t offsetOfContained() {
364 return OFFSETOF(ArrayType, contained_);
366 static inline size_t offsetOfNewMap() {
367 return OFFSETOF(ArrayType, newMap_);
369 // End GC Descriptor.
371 static ArrayType *cast(Type *obj) {
374 obj = obj->unqualified();
375 assert(obj->is(MapKind_ArrayType));
376 return (ArrayType *)obj;
382 Barriered<Type> contained_;
383 Barriered<ArrayMap> newMap_;
386 class StructType : public Type
389 static StructType *New(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
391 FixedArray *fields() {
395 Descriptor *lookupField(String *name, unsigned *index = NULL);
397 // Objects of this type can be created with this cached map.
398 StructMap *newMap() {
401 void setNewMap(StructMap *map) {
411 static inline size_t offsetOfFields() {
412 return OFFSETOF(StructType, fields_);
414 static inline size_t offsetOfNewMap() {
415 return OFFSETOF(StructType, newMap_);
417 static inline size_t offsetOfName() {
418 return OFFSETOF(StructType, name_);
420 // End GC Descriptor.
422 static StructType *cast(Type *obj) {
425 obj = obj->unqualified();
426 assert(obj->is(MapKind_StructType));
427 return (StructType *)obj;
432 Barriered<FixedArray> fields_;
433 Barriered<StructMap> newMap_;
434 Barriered<String> name_;
437 class FunctionType : public Type
440 static FunctionType *New(Zone *zone, Handle<String> name, TokenKind kind);
442 Type *parameterAt(size_t i) {
443 return Type::cast(parameters()->at(i));
446 assert(isFunction());
449 FixedArray *parameters() {
450 assert(isFunction());
453 FixedArray *defaults() {
454 assert(isFunction());
458 return token_ == TOK_NATIVE;
461 return token_ == TOK_FORWARD;
463 bool isNativeVariadic() {
465 return variadicNative_;
469 variadicNative_ = true;
471 void setReturnType(Handle<Type> returnType) {
472 assert(!returnType_);
473 returnType_ = returnType;
475 void setParameterTypes(Handle<FixedArray> types) {
476 assert(!parameters_);
487 static inline size_t offsetOfReturnType() {
488 return OFFSETOF(FunctionType, returnType_);
490 static inline size_t offsetOfParameters() {
491 return OFFSETOF(FunctionType, parameters_);
493 static inline size_t offsetOfDefaults() {
494 return OFFSETOF(FunctionType, defaults_);
496 static inline size_t offsetOfName() {
497 return OFFSETOF(FunctionType, name_);
499 // End GC Descriptor.
501 static FunctionType *cast(Type *obj) {
504 obj = obj->unqualified();
505 assert(obj->is(MapKind_FunctionType));
506 return (FunctionType *)obj;
511 Barriered<Type> returnType_;
512 Barriered<FixedArray> parameters_;
513 Barriered<FixedArray> defaults_;
514 Barriered<String> name_;
516 bool variadicNative_;
528 static BoxedPrimitive Int(int i) {
530 b.type_ = PrimitiveType_Int32;
534 static BoxedPrimitive Float(float f) {
536 b.type_ = PrimitiveType_Float;
541 PrimitiveType type() const {
545 assert(type() == PrimitiveType_Int32);
548 float toFloat() const {
549 assert(type() == PrimitiveType_Float);
554 const char *GetTypeName(Type *type, char *buffer, size_t maxlen);
558 #endif // _include_jc_types_h_