authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 03:11:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-27 03:12:06-07:00
logfa1ea6062b172e75674353ee19857db9046ec9ee
treee11a3a1c576af16b29e13f9afd87a7369a1e070b
parent0278468479d52d6ea64521ab78574b593a6832ae

parseh works for simple functions


2 files changed, 221 insertions(+), 15 deletions(-)

src/main.cpp+28-11
......@@ -170,9 +170,19 @@ static void print_indent(ParseHPrint *p) {
170170 }
171171}
172172
173static const char *type_node_to_name(AstNode *type_node) {
174 assert(type_node->type == NodeTypeSymbol);
175 return buf_ptr(&type_node->data.symbol_expr.symbol);
173static Buf *type_node_to_name(AstNode *type_node) {
174 if (type_node->type == NodeTypeSymbol) {
175 return &type_node->data.symbol_expr.symbol;
176 } else if (type_node->type == NodeTypePrefixOpExpr) {
177 PrefixOp op = type_node->data.prefix_op_expr.prefix_op;
178 if (op == PrefixOpAddressOf) {
179 return buf_sprintf("&%s", buf_ptr(type_node_to_name(type_node->data.prefix_op_expr.primary_expr)));
180 } else {
181 zig_unreachable();
182 }
183 } else {
184 zig_unreachable();
185 }
176186}
177187
178188static int parseh(const char *arg0, int argc, char **argv) {
......@@ -208,6 +218,11 @@ static int parseh(const char *arg0, int argc, char **argv) {
208218
209219 clang_argv.append(in_file);
210220
221 Buf *libc_include_path = buf_alloc();
222 os_path_join(buf_create_from_str(ZIG_LIBC_DIR), buf_create_from_str("include"), libc_include_path);
223 clang_argv.append("-isystem");
224 clang_argv.append(buf_ptr(libc_include_path));
225
211226 ParseHPrint parse_h_print = {{{0}}};
212227 ParseHPrint *p = &parse_h_print;
213228 p->f = stdout;
......@@ -235,9 +250,9 @@ static int parseh(const char *arg0, int argc, char **argv) {
235250 AstNode *field_node = struct_decl->data.struct_decl.fields.at(field_i);
236251 assert(field_node->type == NodeTypeStructField);
237252 const char *field_name = buf_ptr(&field_node->data.struct_field.name);
238 const char *type_name = type_node_to_name(field_node->data.struct_field.type);
253 Buf *type_name = type_node_to_name(field_node->data.struct_field.type);
239254 print_indent(p);
240 fprintf(p->f, "%s: %s,\n", field_name, type_name);
255 fprintf(p->f, "%s: %s,\n", field_name, buf_ptr(type_name));
241256 }
242257
243258 p->cur_indent -= indent_size;
......@@ -249,15 +264,17 @@ static int parseh(const char *arg0, int argc, char **argv) {
249264 assert(fn_proto->type == NodeTypeFnProto);
250265 print_indent(p);
251266 const char *fn_name = buf_ptr(&fn_proto->data.fn_proto.name);
252 fprintf(p->f, "extern fn %s(", fn_name);
267 const char *pub_str = (fn_proto->data.fn_proto.visib_mod == VisibModPub) ? "pub " : "";
268 fprintf(p->f, "%sextern fn %s(", pub_str, fn_name);
253269 int arg_count = fn_proto->data.fn_proto.params.length;
254270 bool is_var_args = fn_proto->data.fn_proto.is_var_args;
255271 for (int arg_i = 0; arg_i < arg_count; arg_i += 1) {
256272 AstNode *param_decl = fn_proto->data.fn_proto.params.at(arg_i);
257273 assert(param_decl->type == NodeTypeParamDecl);
258274 const char *arg_name = buf_ptr(&param_decl->data.param_decl.name);
259 const char *arg_type = type_node_to_name(param_decl->data.param_decl.type);
260 fprintf(p->f, "%s: %s", arg_name, arg_type);
275 Buf *arg_type = type_node_to_name(param_decl->data.param_decl.type);
276 const char *noalias_str = param_decl->data.param_decl.is_noalias ? "noalias " : "";
277 fprintf(p->f, "%s%s: %s", noalias_str, arg_name, buf_ptr(arg_type));
261278 if (arg_i + 1 < arg_count || is_var_args) {
262279 fprintf(p->f, ", ");
263280 }
......@@ -266,9 +283,9 @@ static int parseh(const char *arg0, int argc, char **argv) {
266283 fprintf(p->f, "...");
267284 }
268285 fprintf(p->f, ")");
269 const char *return_type_name = type_node_to_name(fn_proto->data.fn_proto.return_type);
270 if (strcmp(return_type_name, "void") != 0) {
271 fprintf(p->f, " -> %s", return_type_name);
286 Buf *return_type_name = type_node_to_name(fn_proto->data.fn_proto.return_type);
287 if (!buf_eql_str(return_type_name, "void")) {
288 fprintf(p->f, " -> %s", buf_ptr(return_type_name));
272289 }
273290 fprintf(p->f, ";\n");
274291 }
src/parseh.cpp+193-4
......@@ -19,12 +19,202 @@ using namespace clang;
1919
2020struct Context {
2121 ParseH *parse_h;
22 bool warnings_on;
23 bool pub;
2224};
2325
26static AstNode *type_node_from_qual_type(Context *c, QualType qt);
27
28static AstNode *create_node(Context *c, NodeType type) {
29 AstNode *node = allocate<AstNode>(1);
30 node->type = type;
31 return node;
32}
33
34static AstNode *simple_type_node(Context *c, const char *type_name) {
35 AstNode *node = create_node(c, NodeTypeSymbol);
36 buf_init_from_str(&node->data.symbol_expr.symbol, type_name);
37 return node;
38}
39
40static const char *decl_name(const Decl *decl) {
41 const NamedDecl *named_decl = static_cast<const NamedDecl *>(decl);
42 return (const char *)named_decl->getName().bytes_begin();
43}
44
45static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {
46 AstNode *node = create_node(c, NodeTypePrefixOpExpr);
47 node->data.prefix_op_expr.prefix_op = is_const ? PrefixOpConstAddressOf : PrefixOpAddressOf;
48 node->data.prefix_op_expr.primary_expr = type_node;
49 return node;
50}
51
52static AstNode *type_node(Context *c, const Type *ty, bool is_const) {
53 switch (ty->getTypeClass()) {
54 case Type::Builtin:
55 {
56 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
57 switch (builtin_ty->getKind()) {
58 case BuiltinType::Void:
59 return simple_type_node(c, "void");
60 case BuiltinType::Bool:
61 return simple_type_node(c, "bool");
62 case BuiltinType::Char_U:
63 case BuiltinType::UChar:
64 return simple_type_node(c, "u8");
65 case BuiltinType::Char_S:
66 case BuiltinType::SChar:
67 return simple_type_node(c, "i8");
68 case BuiltinType::UShort:
69 return simple_type_node(c, "c_ushort");
70 case BuiltinType::UInt:
71 return simple_type_node(c, "c_uint");
72 case BuiltinType::ULong:
73 return simple_type_node(c, "c_ulong");
74 case BuiltinType::ULongLong:
75 return simple_type_node(c, "c_ulonglong");
76 case BuiltinType::Short:
77 return simple_type_node(c, "c_short");
78 case BuiltinType::Int:
79 return simple_type_node(c, "c_int");
80 case BuiltinType::Long:
81 return simple_type_node(c, "c_long");
82 case BuiltinType::LongLong:
83 return simple_type_node(c, "c_longlong");
84 case BuiltinType::Float:
85 return simple_type_node(c, "f32");
86 case BuiltinType::Double:
87 return simple_type_node(c, "f64");
88 case BuiltinType::LongDouble:
89 return simple_type_node(c, "f128");
90 case BuiltinType::WChar_U:
91 case BuiltinType::Char16:
92 case BuiltinType::Char32:
93 case BuiltinType::UInt128:
94 case BuiltinType::WChar_S:
95 case BuiltinType::Int128:
96 case BuiltinType::Half:
97 case BuiltinType::NullPtr:
98 case BuiltinType::ObjCId:
99 case BuiltinType::ObjCClass:
100 case BuiltinType::ObjCSel:
101 case BuiltinType::OCLImage1d:
102 case BuiltinType::OCLImage1dArray:
103 case BuiltinType::OCLImage1dBuffer:
104 case BuiltinType::OCLImage2d:
105 case BuiltinType::OCLImage2dArray:
106 case BuiltinType::OCLImage3d:
107 case BuiltinType::OCLSampler:
108 case BuiltinType::OCLEvent:
109 case BuiltinType::Dependent:
110 case BuiltinType::Overload:
111 case BuiltinType::BoundMember:
112 case BuiltinType::PseudoObject:
113 case BuiltinType::UnknownAny:
114 case BuiltinType::BuiltinFn:
115 case BuiltinType::ARCUnbridgedCast:
116 zig_panic("TODO - make error for these types");
117 }
118 break;
119 }
120 case Type::Pointer:
121 {
122 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
123 AstNode *type_node = type_node_from_qual_type(c, pointer_ty->getPointeeType());
124 return pointer_to_type(c, type_node, is_const);
125 }
126 case Type::Typedef:
127 case Type::FunctionProto:
128 case Type::Record:
129 case Type::Enum:
130 case Type::BlockPointer:
131 case Type::LValueReference:
132 case Type::RValueReference:
133 case Type::MemberPointer:
134 case Type::ConstantArray:
135 case Type::IncompleteArray:
136 case Type::VariableArray:
137 case Type::DependentSizedArray:
138 case Type::DependentSizedExtVector:
139 case Type::Vector:
140 case Type::ExtVector:
141 case Type::FunctionNoProto:
142 case Type::UnresolvedUsing:
143 case Type::Paren:
144 case Type::Adjusted:
145 case Type::Decayed:
146 case Type::TypeOfExpr:
147 case Type::TypeOf:
148 case Type::Decltype:
149 case Type::UnaryTransform:
150 case Type::Elaborated:
151 case Type::Attributed:
152 case Type::TemplateTypeParm:
153 case Type::SubstTemplateTypeParm:
154 case Type::SubstTemplateTypeParmPack:
155 case Type::TemplateSpecialization:
156 case Type::Auto:
157 case Type::InjectedClassName:
158 case Type::DependentName:
159 case Type::DependentTemplateSpecialization:
160 case Type::PackExpansion:
161 case Type::ObjCObject:
162 case Type::ObjCInterface:
163 case Type::Complex:
164 case Type::ObjCObjectPointer:
165 case Type::Atomic:
166 zig_panic("TODO - make error for type: %s", ty->getTypeClassName());
167 }
168}
169
170static AstNode *type_node_from_qual_type(Context *c, QualType qt) {
171 bool is_const = qt.isConstQualified();
172 return type_node(c, qt.getTypePtr(), is_const);
173}
174
24175static bool decl_visitor(void *context, const Decl *decl) {
25 //Context *c = (Context*)context;
176 Context *c = (Context*)context;
177
178 switch (decl->getKind()) {
179 case Decl::Function:
180 {
181 const FunctionDecl *fn_decl = static_cast<const FunctionDecl*>(decl);
182 AstNode *node = create_node(c, NodeTypeFnProto);
183 node->data.fn_proto.is_extern = true;
184 node->data.fn_proto.visib_mod = c->pub ? VisibModPub : VisibModPrivate;
185 node->data.fn_proto.is_var_args = fn_decl->isVariadic();
186 buf_init_from_str(&node->data.fn_proto.name, decl_name(decl));
187
188 int arg_count = fn_decl->getNumParams();
189 for (int i = 0; i < arg_count; i += 1) {
190 const ParmVarDecl *param = fn_decl->getParamDecl(i);
191 AstNode *param_decl_node = create_node(c, NodeTypeParamDecl);
192 const char *name = decl_name(param);
193 if (strlen(name) == 0) {
194 name = buf_ptr(buf_sprintf("arg%d", i));
195 }
196 buf_init_from_str(&param_decl_node->data.param_decl.name, name);
197 QualType qt = param->getOriginalType();
198 param_decl_node->data.param_decl.is_noalias = qt.isRestrictQualified();
199 param_decl_node->data.param_decl.type = type_node_from_qual_type(c, qt);
200 node->data.fn_proto.params.append(param_decl_node);
201 }
26202
27 fprintf(stderr, "got top level decl\n");
203 if (fn_decl->isNoReturn()) {
204 node->data.fn_proto.return_type = simple_type_node(c, "unreachable");
205 } else {
206 node->data.fn_proto.return_type = type_node_from_qual_type(c, fn_decl->getReturnType());
207 }
208
209 c->parse_h->fn_list.append(node);
210
211 break;
212 }
213 default:
214 if (c->warnings_on) {
215 fprintf(stderr, "ignoring %s\n", decl->getDeclKindName());
216 }
217 }
28218
29219 return true;
30220}
......@@ -46,7 +236,6 @@ int parse_h_buf(ParseH *parse_h, Buf *source, const char *libc_include_path) {
46236 os_delete_file(&tmp_file_path);
47237
48238 return err;
49 // write to temp file, parse it, delete it
50239}
51240
52241int parse_h_file(ParseH *parse_h, ZigList<const char *> *clang_argv) {
......@@ -124,7 +313,7 @@ int parse_h_file(ParseH *parse_h, ZigList<const char *> *clang_argv) {
124313 }
125314 StringRef msg_str_ref = it->getMessage();
126315 FullSourceLoc fsl = it->getLocation();
127 FileID file_id = fsl.getManager().getFileID(fsl);
316 FileID file_id = fsl.getFileID();
128317 StringRef filename = fsl.getManager().getFilename(fsl);
129318 unsigned line = fsl.getSpellingLineNumber() - 1;
130319 unsigned column = fsl.getSpellingColumnNumber() - 1;