bool Type::Build(const CXType &cxType) { bool result = true; auto arraySize = clang_getArraySize(cxType); m_ArraySize = arraySize > 0 ? static_cast<int>(arraySize) : 0; int numTemplateArgs = clang_Type_getNumTemplateArguments(cxType); for (int i = 0; i < numTemplateArgs; ++i) { CXType tempType = clang_Type_getTemplateArgumentAsType(cxType, static_cast<unsigned>(i)); const char *tempTypeSpelling = clang_getCString(clang_getTypeSpelling(tempType)); std::unique_ptr<Type> t = std::unique_ptr<Type>(CreateFromString(this, tempTypeSpelling)); if (t->Build(tempType)) { m_TemplateArgs.push_back(std::move(t)); } else result = false; } return result; }
long long cursor::type::array_size() { return clang_getArraySize(ctype); }
json_t* render_type(CXType type) { int i; CXCursor decl = clang_getTypeDeclaration(type); json_t* js = json_object(); enum CXTypeKind kind = type.kind; if (type.kind == CXType_Unexposed) { // workaround for libclang bug if (clang_getResultType(type).kind != CXType_Invalid) { kind = CXType_FunctionProto; } } if (clang_isVolatileQualifiedType(type)) { json_object_set_new(js, "volatile", json_true()); } if (clang_isConstQualifiedType(type)) { json_object_set_new(js, "const", json_true()); } if (clang_isRestrictQualifiedType(type)) { json_object_set_new(js, "restrict", json_true()); } static const struct { enum CXTypeKind kind; const char* name; } PRIMITIVE_TYPES[] = { {CXType_Void, "void"}, {CXType_Bool, "bool"}, {CXType_Char_U, "char"}, {CXType_Char_S, "char"}, {CXType_UChar, "unsigned char"}, {CXType_SChar, "signed char"}, {CXType_WChar, "wchar_t"}, {CXType_Char16, "char16_t"}, {CXType_Char32, "char32_t"}, {CXType_Short, "short"}, {CXType_UShort, "unsigned short"}, {CXType_Int, "int"}, {CXType_UInt, "unsigned int"}, {CXType_Long, "long"}, {CXType_ULong, "unsigned long"}, {CXType_LongLong, "unsigned long"}, {CXType_ULongLong, "unsigned long long"}, {CXType_Int128, "__int128"}, {CXType_UInt128, "unsigned __int128"}, {CXType_Float, "float"}, {CXType_Double, "double"}, {CXType_LongDouble, "long double"} }; switch (kind) { case CXType_Pointer: json_object_set_new(js, "kind", json_string("pointer")); json_object_set_new(js, "pointee", render_type(clang_getPointeeType(type))); return js; case CXType_ConstantArray: json_object_set_new(js, "kind", json_string("array")); json_object_set_new(js, "element", render_type(clang_getArrayElementType(type))); json_object_set_new(js, "length", json_integer(clang_getArraySize(type))); return js; case CXType_FunctionNoProto: case CXType_FunctionProto: json_object_set_new(js, "kind", json_string("function")); json_object_set_new(js, "return", render_type(clang_getResultType(type))); switch (clang_getFunctionTypeCallingConv(type)) { case CXCallingConv_C: json_object_set_new(js, "calling_convention", json_string("cdecl")); break; case CXCallingConv_X86StdCall: json_object_set_new(js, "calling_convention", json_string("stdcall")); break; case CXCallingConv_X86FastCall: json_object_set_new(js, "calling_convention", json_string("fastcall")); break; case CXCallingConv_X86ThisCall: json_object_set_new(js, "calling_convention", json_string("thiscall")); break; case CXCallingConv_X86Pascal: json_object_set_new(js, "calling_convention", json_string("pascal")); break; case CXCallingConv_AAPCS: json_object_set_new(js, "calling_convention", json_string("aapcs")); break; case CXCallingConv_AAPCS_VFP: json_object_set_new(js, "calling_convention", json_string("aapcs-vfp")); break; default: break; } json_t* arguments = json_array(); for (i=0; i<clang_getNumArgTypes(type); i++) { json_array_append_new(arguments, render_type(clang_getArgType(type, i))); } json_object_set_new(js, "arguments", arguments); return js; default: if (clang_getCursorKind(decl) != CXCursor_NoDeclFound) { json_object_set_new(js, "kind", json_string("ref")); json_object_set_new(js, "id", render_string(clang_getCursorUSR(decl))); } else { int found = 0, i; for (i=0; i<sizeof(PRIMITIVE_TYPES)/sizeof(PRIMITIVE_TYPES[0]); i++) { if (PRIMITIVE_TYPES[i].kind == kind) { json_object_set_new(js, "kind", json_string("primitive")); json_object_set_new(js, "primitive", json_string(PRIMITIVE_TYPES[i].name)); found = 1; break; } } if (!found) { json_object_set_new(js, "kind", json_string("unknown")); json_object_set_new(js, "clang_kind", render_string(clang_getTypeKindSpelling(kind))); } } return js; } }