static String typeString(const CXType &type) { const char *builtIn = builtinTypeName(type.kind); if (builtIn) return builtIn; if (char pointer = (type.kind == CXType_Pointer ? '*' : (type.kind == CXType_LValueReference ? '&' : 0))) { const CXType pointee = clang_getPointeeType(type); String ret = typeString(pointee); if (ret.endsWith('*') || ret.endsWith('&')) { ret += pointer; } else { ret += ' '; ret += pointer; } return ret; } if (type.kind == CXType_ConstantArray) { String arrayType = typeString(clang_getArrayElementType(type)); const long long count = clang_getNumElements(type); arrayType += '['; if (count >= 0) arrayType += String::number(count); arrayType += ']'; return arrayType; } String ret = IndexerJob::typeName(clang_getTypeDeclaration(type)); if (ret.endsWith(' ')) ret.chop(1); return ret; }
cursor::type cursor::type::pointee_type() { return { clang_getPointeeType(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; } }
std::string Generator::stringize(const CXType &type, const std::string &varName, bool makeConstReference) const { std::string result; if (makeConstReference) { switch (type.kind) { case CXType_LValueReference: case CXType_RValueReference: case CXType_Pointer: case CXType_Enum: case CXType_Bool: case CXType_Char_S: case CXType_Char_U: case CXType_Char16: case CXType_Int: case CXType_Long: case CXType_LongLong: case CXType_Float: case CXType_Double: case CXType_LongDouble: makeConstReference = false; break; default: break; } } if (makeConstReference || clang_isConstQualifiedType(type)) result += "const "; switch (type.kind) { case CXType_Void: result += "void"; if (!varName.empty()) result += ' '; break; case CXType_Bool: result += "bool"; if (!varName.empty()) result += ' '; break; case CXType_Int: result += "int"; if (!varName.empty()) result += ' '; break; case CXType_Float: result += "float"; if (!varName.empty()) result += ' '; break; case CXType_Double: result += "double"; if (!varName.empty()) result += ' '; break; case CXType_Pointer: { CXType pointee = clang_getPointeeType(type); result += stringize(pointee); result += " *"; } break; case CXType_LValueReference: { CXType pointee = clang_getPointeeType(type); result += stringize(pointee); } break; case CXType_Record: case CXType_Enum: { result += stringize(clang_getTypeDeclaration(type)); if (!varName.empty()) result += ' '; } break; case CXType_Unexposed: result += stringize(clang_getCursorDisplayName(clang_getTypeDeclaration(type))); if (!varName.empty()) result += ' '; break; case CXType_Overload: result += "<CXType_Overload>"; reportWarning("stringize: CXType_Overload not handled: " + stringize(clang_getCursorDisplayName(clang_getTypeDeclaration(type)))); break; case CXType_Dependent: result += "<CXType_Dependent>"; reportWarning("stringize: CXType_Dependent not handled: " + stringize(clang_getCursorDisplayName(clang_getTypeDeclaration(type)))); break; case CXType_Invalid: result += "<CXType_Invalid>"; reportWarning("stringize: CXType_Invalid not handled: " + stringize(clang_getCursorDisplayName(clang_getTypeDeclaration(type)))); break; default: result += "<other CXTypeKind>"; reportWarning("stringize: such CXTypeKind not handled: " + stringize(clang_getCursorDisplayName(clang_getTypeDeclaration(type)))); break; } if (makeConstReference) { result += "&"; } result += varName; return result; }
Type Type::pointeeType() const { return clang_getPointeeType(m_cxType); }