| ... | ... | @@ -17,6 +17,7 @@ struct Fn { |
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | struct ParseH { |
| 20 | CXTranslationUnit tu; |
| 20 | 21 | FILE *f; |
| 21 | 22 | ZigList<Fn *> fn_list; |
| 22 | 23 | Fn *cur_fn; |
| ... | ... | @@ -243,18 +244,26 @@ static bool is_storage_class_export(CX_StorageClass storage_class) { |
| 243 | 244 | zig_unreachable(); |
| 244 | 245 | } |
| 245 | 246 | |
| 246 | | static void begin_fn(ParseH *p) { |
| 247 | | assert(!p->cur_fn); |
| 248 | | p->cur_fn = allocate<Fn>(1); |
| 249 | | } |
| 247 | static enum CXChildVisitResult visit_fn_children(CXCursor cursor, CXCursor parent, CXClientData client_data) { |
| 248 | ParseH *p = (ParseH*)client_data; |
| 249 | enum CXCursorKind kind = clang_getCursorKind(cursor); |
| 250 | 250 | |
| 251 | | static void end_fn(ParseH *p) { |
| 252 | | if (p->cur_fn) { |
| 253 | | p->fn_list.append(p->cur_fn); |
| 254 | | p->cur_fn = nullptr; |
| 251 | switch (kind) { |
| 252 | case CXCursor_ParmDecl: |
| 253 | { |
| 254 | assert(p->cur_fn); |
| 255 | assert(p->arg_index < p->cur_fn->arg_count); |
| 256 | CXString name = clang_getCursorSpelling(cursor); |
| 257 | buf_init_from_str(&p->cur_fn->args[p->arg_index].name, clang_getCString(name)); |
| 258 | p->arg_index += 1; |
| 259 | return CXChildVisit_Continue; |
| 260 | } |
| 261 | default: |
| 262 | return CXChildVisit_Recurse; |
| 255 | 263 | } |
| 256 | 264 | } |
| 257 | 265 | |
| 266 | |
| 258 | 267 | static enum CXChildVisitResult fn_visitor(CXCursor cursor, CXCursor parent, CXClientData client_data) { |
| 259 | 268 | ParseH *p = (ParseH*)client_data; |
| 260 | 269 | enum CXCursorKind kind = clang_getCursorKind(cursor); |
| ... | ... | @@ -282,8 +291,8 @@ static enum CXChildVisitResult fn_visitor(CXCursor cursor, CXCursor parent, CXCl |
| 282 | 291 | return CXChildVisit_Continue; |
| 283 | 292 | } |
| 284 | 293 | |
| 285 | | end_fn(p); |
| 286 | | begin_fn(p); |
| 294 | assert(!p->cur_fn); |
| 295 | p->cur_fn = allocate<Fn>(1); |
| 287 | 296 | |
| 288 | 297 | CXType return_type = clang_getResultType(fn_type); |
| 289 | 298 | p->cur_fn->return_type = to_zig_type(p, return_type); |
| ... | ... | @@ -300,17 +309,13 @@ static enum CXChildVisitResult fn_visitor(CXCursor cursor, CXCursor parent, CXCl |
| 300 | 309 | |
| 301 | 310 | p->arg_index = 0; |
| 302 | 311 | |
| 312 | clang_visitChildren(cursor, visit_fn_children, p); |
| 313 | |
| 314 | p->fn_list.append(p->cur_fn); |
| 315 | p->cur_fn = nullptr; |
| 316 | |
| 303 | 317 | return CXChildVisit_Recurse; |
| 304 | 318 | } |
| 305 | | case CXCursor_ParmDecl: |
| 306 | | { |
| 307 | | assert(p->cur_fn); |
| 308 | | assert(p->arg_index < p->cur_fn->arg_count); |
| 309 | | buf_init_from_str(&p->cur_fn->args[p->arg_index].name, clang_getCString(name)); |
| 310 | | p->arg_index += 1; |
| 311 | | return CXChildVisit_Continue; |
| 312 | | } |
| 313 | | case CXCursor_UnexposedAttr: |
| 314 | 319 | case CXCursor_CompoundStmt: |
| 315 | 320 | case CXCursor_FieldDecl: |
| 316 | 321 | case CXCursor_TypedefDecl: |
| ... | ... | @@ -330,7 +335,6 @@ void parse_h_file(const char *target_path, ZigList<const char *> *clang_argv, FI |
| 330 | 335 | ParseH parse_h = {0}; |
| 331 | 336 | ParseH *p = &parse_h; |
| 332 | 337 | p->f = f; |
| 333 | | CXTranslationUnit tu; |
| 334 | 338 | CXIndex index = clang_createIndex(1, 0); |
| 335 | 339 | |
| 336 | 340 | char *ZIG_PARSEH_CFLAGS = getenv("ZIG_PARSEH_CFLAGS"); |
| ... | ... | @@ -355,17 +359,17 @@ void parse_h_file(const char *target_path, ZigList<const char *> *clang_argv, FI |
| 355 | 359 | enum CXErrorCode err_code; |
| 356 | 360 | if ((err_code = clang_parseTranslationUnit2(index, target_path, |
| 357 | 361 | clang_argv->items, clang_argv->length - 1, |
| 358 | | NULL, 0, CXTranslationUnit_None, &tu))) |
| 362 | NULL, 0, CXTranslationUnit_None, &p->tu))) |
| 359 | 363 | { |
| 360 | 364 | zig_panic("parse translation unit failure"); |
| 361 | 365 | } |
| 362 | 366 | |
| 363 | 367 | |
| 364 | | unsigned diag_count = clang_getNumDiagnostics(tu); |
| 368 | unsigned diag_count = clang_getNumDiagnostics(p->tu); |
| 365 | 369 | |
| 366 | 370 | if (diag_count > 0) { |
| 367 | 371 | for (unsigned i = 0; i < diag_count; i += 1) { |
| 368 | | CXDiagnostic diagnostic = clang_getDiagnostic(tu, i); |
| 372 | CXDiagnostic diagnostic = clang_getDiagnostic(p->tu, i); |
| 369 | 373 | CXSourceLocation location = clang_getDiagnosticLocation(diagnostic); |
| 370 | 374 | |
| 371 | 375 | CXFile file; |
| ... | ... | @@ -381,9 +385,8 @@ void parse_h_file(const char *target_path, ZigList<const char *> *clang_argv, FI |
| 381 | 385 | } |
| 382 | 386 | |
| 383 | 387 | |
| 384 | | CXCursor cursor = clang_getTranslationUnitCursor(tu); |
| 388 | CXCursor cursor = clang_getTranslationUnitCursor(p->tu); |
| 385 | 389 | clang_visitChildren(cursor, fn_visitor, p); |
| 386 | | end_fn(p); |
| 387 | 390 | |
| 388 | 391 | if (p->fn_list.length) { |
| 389 | 392 | fprintf(f, "extern {\n"); |