]> git.saurik.com Git - cycript.git/blame - Decode.cpp
Use libclang to walk CXType for anonymous structs.
[cycript.git] / Decode.cpp
CommitLineData
7341eedb
JF
1/* Cycript - The Truly Universal Scripting Language
2 * Copyright (C) 2009-2016 Jay Freeman (saurik)
9a39f705
JF
3*/
4
f95d2598 5/* GNU Affero General Public License, Version 3 {{{ */
9a39f705 6/*
f95d2598
JF
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9a39f705 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f95d2598
JF
15 * GNU Affero General Public License for more details.
16
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
9a39f705
JF
19**/
20/* }}} */
21
22#include <sstream>
23
24#include "Decode.hpp"
25#include "Replace.hpp"
26
0559abf8
JF
27namespace sig {
28
29template <>
30CYTypedIdentifier *Primitive<bool>::Decode(CYPool &pool) const {
31 return $ CYTypedIdentifier($ CYTypeVariable("bool"));
32}
33
34template <>
35CYTypedIdentifier *Primitive<char>::Decode(CYPool &pool) const {
36 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeNeutral));
37}
38
39template <>
40CYTypedIdentifier *Primitive<double>::Decode(CYPool &pool) const {
41 return $ CYTypedIdentifier($ CYTypeVariable("double"));
42}
43
44template <>
45CYTypedIdentifier *Primitive<float>::Decode(CYPool &pool) const {
46 return $ CYTypedIdentifier($ CYTypeVariable("float"));
47}
48
49template <>
50CYTypedIdentifier *Primitive<signed char>::Decode(CYPool &pool) const {
51 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeSigned));
52}
53
54template <>
55CYTypedIdentifier *Primitive<signed int>::Decode(CYPool &pool) const {
56 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 1));
57}
58
59template <>
60CYTypedIdentifier *Primitive<signed long int>::Decode(CYPool &pool) const {
61 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 2));
62}
63
64template <>
65CYTypedIdentifier *Primitive<signed long long int>::Decode(CYPool &pool) const {
66 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 3));
67}
68
69template <>
70CYTypedIdentifier *Primitive<signed short int>::Decode(CYPool &pool) const {
71 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeSigned, 0));
72}
73
74template <>
75CYTypedIdentifier *Primitive<unsigned char>::Decode(CYPool &pool) const {
76 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeUnsigned));
77}
78
79template <>
80CYTypedIdentifier *Primitive<unsigned int>::Decode(CYPool &pool) const {
81 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 1));
82}
83
84template <>
85CYTypedIdentifier *Primitive<unsigned long int>::Decode(CYPool &pool) const {
86 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 2));
87}
88
89template <>
90CYTypedIdentifier *Primitive<unsigned long long int>::Decode(CYPool &pool) const {
91 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 3));
92}
93
94template <>
95CYTypedIdentifier *Primitive<unsigned short int>::Decode(CYPool &pool) const {
96 return $ CYTypedIdentifier($ CYTypeIntegral(CYTypeUnsigned, 0));
97}
98
99CYTypedIdentifier *Void::Decode(CYPool &pool) const {
100 return $ CYTypedIdentifier($ CYTypeVoid());
101}
102
103CYTypedIdentifier *Unknown::Decode(CYPool &pool) const {
104 return $ CYTypedIdentifier($ CYTypeError());
105}
106
107CYTypedIdentifier *String::Decode(CYPool &pool) const {
108 return $ CYTypedIdentifier($ CYTypeCharacter(CYTypeNeutral), $ CYTypePointerTo());
109}
9a39f705 110
e2ce853b 111#ifdef CY_OBJECTIVEC
0559abf8
JF
112CYTypedIdentifier *Meta::Decode(CYPool &pool) const {
113 return $ CYTypedIdentifier($ CYTypeVariable("Class"));
114}
115
116CYTypedIdentifier *Selector::Decode(CYPool &pool) const {
117 return $ CYTypedIdentifier($ CYTypeVariable("SEL"));
118}
e2ce853b 119#endif
0559abf8
JF
120
121CYTypedIdentifier *Bits::Decode(CYPool &pool) const {
9a39f705 122 _assert(false);
9a39f705
JF
123}
124
0559abf8
JF
125CYTypedIdentifier *Pointer::Decode(CYPool &pool) const {
126 return CYDecodeType(pool, &type)->Modify($ CYTypePointerTo());
127}
128
129CYTypedIdentifier *Array::Decode(CYPool &pool) const {
130 return CYDecodeType(pool, &type)->Modify($ CYTypeArrayOf($D(size)));
131}
132
e2ce853b 133#ifdef CY_OBJECTIVEC
0559abf8
JF
134CYTypedIdentifier *Object::Decode(CYPool &pool) const {
135 if (name == NULL)
136 return $ CYTypedIdentifier($ CYTypeVariable("id"));
137 else
138 return $ CYTypedIdentifier($ CYTypeVariable(name), $ CYTypePointerTo());
139}
e2ce853b 140#endif
0559abf8
JF
141
142CYTypedIdentifier *Aggregate::Decode(CYPool &pool) const {
143 _assert(!overlap);
144
145 CYTypeStructField *fields(NULL);
146 for (size_t i(signature.count); i != 0; --i) {
147 sig::Element &element(signature.elements[i - 1]);
148 CYTypedIdentifier *typed(CYDecodeType(pool, element.type));
149 if (element.name != NULL)
150 typed->identifier_ = $I(element.name);
151 fields = $ CYTypeStructField(typed, fields);
152 }
153 CYIdentifier *identifier(name == NULL ? NULL : $I(name));
154 return $ CYTypedIdentifier($ CYTypeStruct(identifier, $ CYStructTail(fields)));
155}
156
574d4720 157CYTypedIdentifier *Callable::Decode(CYPool &pool) const {
0559abf8 158 _assert(signature.count != 0);
574d4720 159 CYTypedParameter *parameters(NULL);
0559abf8 160 for (size_t i(signature.count - 1); i != 0; --i)
574d4720
JF
161 parameters = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), parameters);
162 return Modify(pool, CYDecodeType(pool, signature.elements[0].type), parameters);
163}
164
165CYTypedIdentifier *Function::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
166 return result->Modify($ CYTypeFunctionWith(variadic, parameters));
167}
168
e2ce853b 169#ifdef CY_OBJECTIVEC
574d4720
JF
170CYTypedIdentifier *Block::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
171 return result->Modify($ CYTypeBlockWith(parameters));
0559abf8
JF
172}
173
174CYTypedIdentifier *Block::Decode(CYPool &pool) const {
175 if (signature.count == 0)
176 return $ CYTypedIdentifier($ CYTypeVariable("NSBlock"), $ CYTypePointerTo());
574d4720 177 return Callable::Decode(pool);
0559abf8 178}
e2ce853b 179#endif
0559abf8
JF
180
181}
182
183CYTypedIdentifier *CYDecodeType(CYPool &pool, struct sig::Type *type) {
184 CYTypedIdentifier *typed(type->Decode(pool));
02873b72 185 if ((type->flags & JOC_TYPE_CONST) != 0) {
0559abf8 186 if (dynamic_cast<sig::String *>(type) != NULL)
02873b72
JF
187 typed->modifier_ = $ CYTypeConstant(typed->modifier_);
188 else
189 typed = typed->Modify($ CYTypeConstant());
190 }
9a39f705
JF
191 return typed;
192}