Fix gcc and clang builds.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn 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 * SourcePawn 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 * SourcePawn. If not, see http://www.gnu.org/licenses/.
24 #include "Structures.h"
30 Type::init(Kind kind, Type *root)
33 this->root_ = root ? root : this;
37 Type::NewVoid(Zone *zone)
39 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
48 Type::NewImportable(Zone *zone)
50 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
54 type->init(IMPORTABLE);
59 Type::NewString(Zone *zone)
61 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
70 Type::NewUnchecked(Zone *zone)
72 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
76 type->init(UNCHECKED);
81 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
83 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
87 type->init(PRIMITIVE);
88 type->primitive_ = prim;
93 Type::NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> root)
95 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
99 type->init(QUALTYPE, root);
105 ArrayType::New(Zone *zone, Handle<Type> contained, int elements)
107 if (contained->isArray() &&
108 ArrayType::cast(contained)->levels() == MAX_ARRAY_DEPTH)
110 zone->reportError(Message_MaximumArrayDepth);
114 Local<ArrayType> type(zone, (ArrayType *)zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old));
119 type->contained_ = contained;
120 type->elements_ = elements;
121 if (!contained->isArray())
124 type->levels_ = ArrayType::cast(contained)->levels() + 1;
126 type->newMap_ = ArrayMap::New(zone, type);
134 ArrayType::NewExternal(Zone *zone, Handle<Type> contained)
136 Local<ArrayType> type(zone, (ArrayType *)zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old));
140 assert(contained->isPrimitive());
142 type->init(EXTERNAL_ARRAY);
143 type->contained_ = contained;
144 type->elements_ = DYNAMIC_ARRAY_SIZE;
150 ReferenceType::New(Zone *zone, Handle<Type> contained)
152 Local<ReferenceType> type(zone, (ReferenceType *)zone->allocate(MapKind_ReferenceType, sizeof(ReferenceType), Heap::Tenure_Old));
156 type->init(REFERENCE);
157 type->contained_ = contained;
162 EnumType::New(Zone *zone, Handle<String> name)
164 Local<EnumType> type(zone, (EnumType *)zone->allocate(MapKind_EnumType, sizeof(EnumType), Heap::Tenure_Old));
174 StructType::New(Zone *zone, Handle<String> name, Handle<FixedArray> fields)
176 Local<StructType> type(zone, (StructType *)zone->allocate(MapKind_StructType, sizeof(StructType), Heap::Tenure_Old));
181 type->newMap_ = NULL;
182 type->fields_ = fields;
185 // Fill in field offsets.
186 StructureBufferBuilder builder;
187 Local<Type> fieldType(zone);
188 for (size_t i = 0; i < fields->length(); i++) {
189 Descriptor *desc = Descriptor::cast(fields->at(i));
190 fieldType = desc->type();
193 if (!builder.add(fieldType, &offset))
195 desc->setOffset(offset);
198 Local<StructMap> map(zone, StructMap::New(zone, builder, type));
208 StructType::lookupField(Handle<String> name, unsigned *index)
210 for (unsigned i = 0; i < fields_->length(); i++) {
211 Descriptor *desc = Descriptor::cast(fields_->at(i));
212 if (desc->name() == name) {
223 FunctionType::New(Zone *zone, Handle<String> name, TokenKind token)
225 Local<FunctionType> type(zone, (FunctionType *)zone->allocate(MapKind_FunctionType, sizeof(FunctionType), Heap::Tenure_Old));
229 type->init(FUNCTION);
230 type->parameters_ = NULL;
231 type->defaults_ = NULL;
232 type->returnType_ = NULL;
234 type->token_ = token;
239 FormatVA(char *buffer, size_t maxlen, const char *text, va_list ap)
241 size_t len = vsnprintf(buffer, maxlen, text, ap);
243 buffer[maxlen - 1] = '\0';
250 Format(char *buffer, size_t maxlen, const char *text, ...)
254 size_t len = FormatVA(buffer, maxlen, text, ap);
260 FormatTypeName(Type *type, char *buffer, size_t maxlen)
262 if (type->isArray()) {
263 ArrayType *atype = ArrayType::cast(type);
264 Type *innermost = atype->innermost();
266 size_t len = FormatTypeName(innermost, buffer, maxlen);
268 if (atype->isFixedLength())
269 len += Format(buffer + len, maxlen - len, "[%d]", atype->fixedLength());
271 len += Format(buffer + len, maxlen - len, "[]");
272 if (!atype->contained()->isArray())
274 atype = ArrayType::cast(atype->contained());
278 if (type->hasTypeQualifiers()) {
280 if (type->quals() & TypeQual_Const)
281 len += Format(buffer, maxlen, "const ");
282 return len + FormatTypeName(type->unqualified(), buffer + len, maxlen - len);
284 if (type->isFunction())
285 return Format(buffer, maxlen, "function");
287 return Format(buffer, maxlen, "void");
288 if (type->isUnchecked())
289 return Format(buffer, maxlen, "unchecked");
290 if (type->isImportable())
291 return Format(buffer, maxlen, "import");
293 return Format(buffer, maxlen, "%s", EnumType::cast(type)->name()->chars());
294 if (type->isStruct())
295 return Format(buffer, maxlen, "%s", StructType::cast(type)->name()->chars());
296 if (type->isReference()) {
297 ReferenceType *ref = ReferenceType::cast(type);
298 size_t len = Format(buffer, maxlen, "&");
299 return len + FormatTypeName(ref->contained(), buffer + len, maxlen - len);
301 switch (type->primitive()) {
302 case PrimitiveType_Bool:
303 return Format(buffer, maxlen, "bool");
304 case PrimitiveType_Char:
305 return Format(buffer, maxlen, "char");
306 case PrimitiveType_Int32:
307 return Format(buffer, maxlen, "int");
308 case PrimitiveType_Float:
309 return Format(buffer, maxlen, "float");
311 return Format(buffer, maxlen, "<UNKNOWN>");
316 ke::GetTypeName(Type *type, char *buffer, size_t maxlen)
318 FormatTypeName(type, buffer, maxlen);