static clang::CanQualType getClangSelectorType( const clang::ASTContext &clangCtx) { return clangCtx.getPointerType(clangCtx.ObjCBuiltinSelTy); }
clang::QualType AppleObjCTypeEncodingParser::BuildType (clang::ASTContext &ast_ctx, StringLexer& type, bool for_expression, uint32_t *bitfield_bit_size) { if (!type.HasAtLeast(1)) return clang::QualType(); switch (type.Peek()) { default: break; case '{': return BuildStruct(ast_ctx, type, for_expression); case '[': return BuildArray(ast_ctx, type, for_expression); case '(': return BuildUnion(ast_ctx, type, for_expression); case '@': return BuildObjCObjectPointerType(ast_ctx, type, for_expression); } switch (type.Next()) { default: type.PutBack(1); return clang::QualType(); case 'c': return ast_ctx.CharTy; case 'i': return ast_ctx.IntTy; case 's': return ast_ctx.ShortTy; case 'l': return ast_ctx.getIntTypeForBitwidth(32, true); // this used to be done like this: // ClangASTContext *lldb_ctx = ClangASTContext::GetASTContext(&ast_ctx); // if (!lldb_ctx) // return clang::QualType(); // return lldb_ctx->GetIntTypeFromBitSize(32, true).GetQualType(); // which uses one of the constants if one is available, but we don't think all this work is necessary. case 'q': return ast_ctx.LongLongTy; case 'C': return ast_ctx.UnsignedCharTy; case 'I': return ast_ctx.UnsignedIntTy; case 'S': return ast_ctx.UnsignedShortTy; case 'L': return ast_ctx.getIntTypeForBitwidth(32, false); // see note for 'l' case 'Q': return ast_ctx.UnsignedLongLongTy; case 'f': return ast_ctx.FloatTy; case 'd': return ast_ctx.DoubleTy; case 'B': return ast_ctx.BoolTy; case 'v': return ast_ctx.VoidTy; case '*': return ast_ctx.getPointerType(ast_ctx.CharTy); case '#': return ast_ctx.getObjCClassType(); case ':': return ast_ctx.getObjCSelType(); case 'b': { uint32_t size = ReadNumber(type); if (bitfield_bit_size) { *bitfield_bit_size = size; return ast_ctx.UnsignedIntTy; // FIXME: the spec is fairly vague here. } else return clang::QualType(); } case 'r': { clang::QualType target_type = BuildType(ast_ctx, type, for_expression); if (target_type.isNull()) return clang::QualType(); else if (target_type == ast_ctx.UnknownAnyTy) return ast_ctx.UnknownAnyTy; else return ast_ctx.getConstType(target_type); } case '^': { if (!for_expression && type.NextIf('?')) { // if we are not supporting the concept of unknownAny, but what is being created here is an unknownAny*, then // we can just get away with a void* // this is theoretically wrong (in the same sense as 'theoretically nothing exists') but is way better than outright failure // in many practical cases return ast_ctx.VoidPtrTy; } else { clang::QualType target_type = BuildType(ast_ctx, type, for_expression); if (target_type.isNull()) return clang::QualType(); else if (target_type == ast_ctx.UnknownAnyTy) return ast_ctx.UnknownAnyTy; else return ast_ctx.getPointerType(target_type); } } case '?': return for_expression ? ast_ctx.UnknownAnyTy : clang::QualType(); } }