From: Jay Freeman (saurik) Date: Sun, 3 Jan 2016 22:07:40 +0000 (-0800) Subject: Allow C++ tagless type reference, in struct field. X-Git-Tag: v0.9.590~71 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/b0e6429c745211a7fa3036f22a74e85ae227af2b Allow C++ tagless type reference, in struct field. --- diff --git a/Analyze.cpp b/Analyze.cpp index 82c829f..49ff5cb 100644 --- a/Analyze.cpp +++ b/Analyze.cpp @@ -298,6 +298,18 @@ static CYTypedIdentifier *CYDecodeType(CXType type, const CYCXString &identifier return typed; } +static void CYParseStructure(CXCursor cursor, CYTypedIdentifier *typed) { + CYList fields; + CYForChild(cursor, fun([&](CXCursor child) { + if (clang_getCursorKind(child) == CXCursor_FieldDecl) { + CYTypedIdentifier *field(CYDecodeType(clang_getCursorType(child), child)); + fields->*$ CYTypeStructField(field); + } + })); + + typed->specifier_ = $ CYTypeStruct(NULL, $ CYStructTail(fields)); +} + static void CYParseCursor(CXType type, CXCursor cursor, CYTypedIdentifier *typed) { CYCXString spelling(cursor); @@ -314,17 +326,8 @@ static void CYParseCursor(CXType type, CXCursor cursor, CYTypedIdentifier *typed case CXCursor_StructDecl: { if (spelling[0] != '\0') typed->specifier_ = $ CYTypeReference($I(spelling.Pool($pool))); - else { - CYList fields; - CYForChild(cursor, fun([&](CXCursor child) { - if (clang_getCursorKind(child) == CXCursor_FieldDecl) { - CYTypedIdentifier *field(CYDecodeType(clang_getCursorType(child), child)); - fields->*$ CYTypeStructField(field); - } - })); - - typed->specifier_ = $ CYTypeStruct(NULL, $ CYStructTail(fields)); - } + else + CYParseStructure(cursor, typed); } break; case CXCursor_UnionDecl: { @@ -409,6 +412,10 @@ static void CYParseType(CXType type, CYTypedIdentifier *typed) { _assert(false); break; + case CXType_ObjCClass: + typed->specifier_ = $ CYTypeVariable("Class"); + break; + case CXType_ObjCId: typed->specifier_ = $ CYTypeVariable("id"); break; @@ -483,12 +490,12 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien CYCXPosition<> position(location); std::cerr << spelling << " " << position << std::endl;*/ - switch (CXCursorKind kind = clang_getCursorKind(cursor)) { + try { switch (CXCursorKind kind = clang_getCursorKind(cursor)) { case CXCursor_EnumConstantDecl: { value << clang_getEnumConstantDeclValue(cursor); } break; - case CXCursor_MacroDefinition: try { + case CXCursor_MacroDefinition: { CXSourceRange range(clang_getCursorExtent(cursor)); CYTokens tokens(unit, range); _assert(tokens.size() != 0); @@ -541,10 +548,6 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien value << body.str(); out << ';' << '}' << ')'; } - } catch (const CYException &error) { - CYPool pool; - //std::cerr << error.PoolCString(pool) << std::endl; - goto skip; } break; case CXCursor_StructDecl: { @@ -553,23 +556,21 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien if (!clang_isCursorDefinition(cursor)) priority = 1; - std::ostringstream types; - std::ostringstream names; + CYLocalPool pool; - CYForChild(cursor, fun([&](CXCursor child) { - if (clang_getCursorKind(child) == CXCursor_FieldDecl) { - CXType type(clang_getCursorType(child)); - types << "(typedef " << CYCXString(clang_getTypeSpelling(type)) << "),"; - names << "'" << CYCXString(child) << "',"; - } - })); + CYTypedIdentifier typed(NULL); + CYParseStructure(cursor, &typed); + + CYOptions options; + CYOutput out(*value.rdbuf(), options); + CYTypeExpression(&typed).Output(out, CYNoBFC); - value << "new Type([" << types.str() << "],[" << names.str() << "]).withName(\"" << name << "\")"; + value << ".withName(\"" << name << "\")"; name += "$cy"; flags = CYBridgeType; } break; - case CXCursor_TypedefDecl: try { + case CXCursor_TypedefDecl: { CYLocalPool local; CYTypedIdentifier *typed(CYDecodeType(clang_getTypedefDeclUnderlyingType(cursor))); @@ -580,14 +581,10 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien CYOutput out(*value.rdbuf(), options); CYTypeExpression(typed).Output(out, CYNoBFC); } - } catch (const CYException &error) { - CYPool pool; - //std::cerr << error.PoolCString(pool) << std::endl; - goto skip; } break; case CXCursor_FunctionDecl: - case CXCursor_VarDecl: try { + case CXCursor_VarDecl: { std::string label; CYList parameters; @@ -637,24 +634,21 @@ static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClien function->Output(out, CYNoBFC); //std::cerr << value.str() << std::endl; } - } catch (const CYException &error) { - CYPool pool; - //std::cerr << error.PoolCString(pool) << std::endl; - goto skip; } break; default: { return CXChildVisit_Recurse; } break; - } - - { + } { CYKey &key(baton.keys[name]); if (key.priority_ <= priority) { key.priority_ = priority; key.code_ = value.str(); key.flags_ = flags; } + } } catch (const CYException &error) { + CYPool pool; + //std::cerr << error.PoolCString(pool) << std::endl; } skip: