authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 00:25:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 00:25:10-07:00
log137bb51e200517c40e4863d9d45dd31c5bf90967
tree5e21549c802dca94f6d6019ae4946001d3329040
parent3f0062d7a934f7bfcfe80afe31aa1d166edadf54

parseh: add --c-import-warnings option


4 files changed, 59 insertions(+), 34 deletions(-)

src/analyze.cpp+1-1
...@@ -1069,7 +1069,7 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A...@@ -1069,7 +1069,7 @@ static void resolve_c_import_decl(CodeGen *g, ImportTableEntry *parent_import, A
10691069
1070 int err;1070 int err;
1071 if ((err = parse_h_buf(child_import, &errors, child_context->c_import_buf, g->clang_argv, g->clang_argv_len,1071 if ((err = parse_h_buf(child_import, &errors, child_context->c_import_buf, g->clang_argv, g->clang_argv_len,
1072 buf_ptr(g->libc_include_path))))1072 buf_ptr(g->libc_include_path), false)))
1073 {1073 {
1074 zig_panic("unable to parse h file: %s\n", err_str(err));1074 zig_panic("unable to parse h file: %s\n", err_str(err));
1075 }1075 }
src/main.cpp+6-2
...@@ -33,6 +33,7 @@ static int usage(const char *arg0) {...@@ -33,6 +33,7 @@ static int usage(const char *arg0) {
33 " --libc-path [path] set the C compiler data path\n"33 " --libc-path [path] set the C compiler data path\n"
34 " -isystem [dir] add additional search path for other .h files\n"34 " -isystem [dir] add additional search path for other .h files\n"
35 " -dirafter [dir] same as -isystem but do it last\n"35 " -dirafter [dir] same as -isystem but do it last\n"
36 " --c-import-warnings enable warnings when importing .h files\n"
36 , arg0);37 , arg0);
37 return EXIT_FAILURE;38 return EXIT_FAILURE;
38}39}
...@@ -167,6 +168,7 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -167,6 +168,7 @@ static int parseh(const char *arg0, int argc, char **argv) {
167 char *in_file = nullptr;168 char *in_file = nullptr;
168 ZigList<const char *> clang_argv = {0};169 ZigList<const char *> clang_argv = {0};
169 ErrColor color = ErrColorAuto;170 ErrColor color = ErrColorAuto;
171 bool warnings_on = false;
170 for (int i = 0; i < argc; i += 1) {172 for (int i = 0; i < argc; i += 1) {
171 char *arg = argv[i];173 char *arg = argv[i];
172 if (arg[0] == '-') {174 if (arg[0] == '-') {
...@@ -193,7 +195,9 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -193,7 +195,9 @@ static int parseh(const char *arg0, int argc, char **argv) {
193 } else {195 } else {
194 return usage(arg0);196 return usage(arg0);
195 }197 }
196 } else {198 } else if (strcmp(arg, "--c-import-warnings") == 0) {
199 warnings_on = true;
200 } else {
197 fprintf(stderr, "unrecognized argument: %s", arg);201 fprintf(stderr, "unrecognized argument: %s", arg);
198 return usage(arg0);202 return usage(arg0);
199 }203 }
...@@ -217,7 +221,7 @@ static int parseh(const char *arg0, int argc, char **argv) {...@@ -217,7 +221,7 @@ static int parseh(const char *arg0, int argc, char **argv) {
217221
218 ImportTableEntry import = {0};222 ImportTableEntry import = {0};
219 ZigList<ErrorMsg *> errors = {0};223 ZigList<ErrorMsg *> errors = {0};
220 int err = parse_h_file(&import, &errors, &clang_argv);224 int err = parse_h_file(&import, &errors, &clang_argv, warnings_on);
221225
222 if (err) {226 if (err) {
223 fprintf(stderr, "unable to parse .h file: %s\n", err_str(err));227 fprintf(stderr, "unable to parse .h file: %s\n", err_str(err));
src/parseh.cpp+49-29
...@@ -28,9 +28,36 @@ struct Context {...@@ -28,9 +28,36 @@ struct Context {
28 AstNode *root;28 AstNode *root;
29 HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table;29 HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table;
30 HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table;30 HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table;
31 SourceManager *source_manager;
31};32};
3233
33static AstNode *make_qual_type_node(Context *c, QualType qt);34__attribute__ ((format (printf, 3, 4)))
35static void emit_warning(Context *c, const Decl *decl, const char *format, ...) {
36 if (!c->warnings_on) {
37 return;
38 }
39
40 va_list ap;
41 va_start(ap, format);
42 Buf *msg = buf_vprintf(format, ap);
43 va_end(ap);
44
45 SourceLocation sl = decl->getLocation();
46
47 StringRef filename = c->source_manager->getFilename(sl);
48 const char *filename_bytes = (const char *)filename.bytes_begin();
49 Buf *path;
50 if (filename_bytes) {
51 path = buf_create_from_str(filename_bytes);
52 } else {
53 path = buf_sprintf("(no file)");
54 }
55 unsigned line = c->source_manager->getSpellingLineNumber(sl);
56 unsigned column = c->source_manager->getSpellingColumnNumber(sl);
57 fprintf(stderr, "%s:%u:%u: warning: %s\n", buf_ptr(path), line, column, buf_ptr(msg));
58}
59
60static AstNode *make_qual_type_node(Context *c, QualType qt, Decl *decl);
3461
35static AstNode *create_node(Context *c, NodeType type) {62static AstNode *create_node(Context *c, NodeType type) {
36 AstNode *node = allocate<AstNode>(1);63 AstNode *node = allocate<AstNode>(1);
...@@ -96,7 +123,7 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {...@@ -96,7 +123,7 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {
96 return node;123 return node;
97}124}
98125
99static AstNode *make_type_node(Context *c, const Type *ty) {126static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) {
100 switch (ty->getTypeClass()) {127 switch (ty->getTypeClass()) {
101 case Type::Builtin:128 case Type::Builtin:
102 {129 {
...@@ -159,9 +186,7 @@ static AstNode *make_type_node(Context *c, const Type *ty) {...@@ -159,9 +186,7 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
159 case BuiltinType::UnknownAny:186 case BuiltinType::UnknownAny:
160 case BuiltinType::BuiltinFn:187 case BuiltinType::BuiltinFn:
161 case BuiltinType::ARCUnbridgedCast:188 case BuiltinType::ARCUnbridgedCast:
162 if (c->warnings_on) {189 emit_warning(c, decl, "missed a builtin type");
163 fprintf(stderr, "missed a builtin type\n");
164 }
165 return nullptr;190 return nullptr;
166 }191 }
167 break;192 break;
...@@ -170,7 +195,7 @@ static AstNode *make_type_node(Context *c, const Type *ty) {...@@ -170,7 +195,7 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
170 {195 {
171 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);196 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
172 QualType child_qt = pointer_ty->getPointeeType();197 QualType child_qt = pointer_ty->getPointeeType();
173 AstNode *type_node = make_qual_type_node(c, child_qt);198 AstNode *type_node = make_qual_type_node(c, child_qt, decl);
174 return pointer_to_type(c, type_node, child_qt.isConstQualified());199 return pointer_to_type(c, type_node, child_qt.isConstQualified());
175 }200 }
176 case Type::Typedef:201 case Type::Typedef:
...@@ -208,14 +233,10 @@ static AstNode *make_type_node(Context *c, const Type *ty) {...@@ -208,14 +233,10 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
208 }233 }
209 }234 }
210 case Type::Elaborated:235 case Type::Elaborated:
211 if (c->warnings_on) {236 emit_warning(c, decl, "ignoring elaborated type");
212 fprintf(stderr, "ignoring elaborated type\n");
213 }
214 return nullptr;237 return nullptr;
215 case Type::FunctionProto:238 case Type::FunctionProto:
216 if (c->warnings_on) {239 emit_warning(c, decl, "ignoring function type");
217 fprintf(stderr, "ignoring function type\n");
218 }
219 return nullptr;240 return nullptr;
220 case Type::Record:241 case Type::Record:
221 case Type::Enum:242 case Type::Enum:
...@@ -254,15 +275,13 @@ static AstNode *make_type_node(Context *c, const Type *ty) {...@@ -254,15 +275,13 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
254 case Type::Complex:275 case Type::Complex:
255 case Type::ObjCObjectPointer:276 case Type::ObjCObjectPointer:
256 case Type::Atomic:277 case Type::Atomic:
257 if (c->warnings_on) {278 emit_warning(c, decl, "missed a '%s' type", ty->getTypeClassName());
258 fprintf(stderr, "missed a '%s' type\n", ty->getTypeClassName());
259 }
260 return nullptr;279 return nullptr;
261 }280 }
262}281}
263282
264static AstNode *make_qual_type_node(Context *c, QualType qt) {283static AstNode *make_qual_type_node(Context *c, QualType qt, Decl *decl) {
265 return make_type_node(c, qt.getTypePtr());284 return make_type_node(c, qt.getTypePtr(), decl);
266}285}
267286
268static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {287static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
...@@ -292,7 +311,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -292,7 +311,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
292 buf_init_from_str(&param_decl_node->data.param_decl.name, name);311 buf_init_from_str(&param_decl_node->data.param_decl.name, name);
293 QualType qt = param->getOriginalType();312 QualType qt = param->getOriginalType();
294 param_decl_node->data.param_decl.is_noalias = qt.isRestrictQualified();313 param_decl_node->data.param_decl.is_noalias = qt.isRestrictQualified();
295 param_decl_node->data.param_decl.type = make_qual_type_node(c, qt);314 param_decl_node->data.param_decl.type = make_qual_type_node(c, qt, (Decl*)fn_decl);
296 if (!param_decl_node->data.param_decl.type) {315 if (!param_decl_node->data.param_decl.type) {
297 all_ok = false;316 all_ok = false;
298 break;317 break;
...@@ -305,7 +324,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -305,7 +324,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
305 if (fn_decl->isNoReturn()) {324 if (fn_decl->isNoReturn()) {
306 node->data.fn_proto.return_type = simple_type_node(c, "unreachable");325 node->data.fn_proto.return_type = simple_type_node(c, "unreachable");
307 } else {326 } else {
308 node->data.fn_proto.return_type = make_qual_type_node(c, fn_decl->getReturnType());327 node->data.fn_proto.return_type = make_qual_type_node(c, fn_decl->getReturnType(), (Decl*)fn_decl);
309 }328 }
310329
311 if (!node->data.fn_proto.return_type) {330 if (!node->data.fn_proto.return_type) {
...@@ -313,9 +332,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {...@@ -313,9 +332,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
313 }332 }
314 if (!all_ok) {333 if (!all_ok) {
315 // not all the types could be resolved, so we give up on the function decl334 // not all the types could be resolved, so we give up on the function decl
316 if (c->warnings_on) {335 emit_warning(c, (Decl*)fn_decl, "skipping function %s\n", buf_ptr(&node->data.fn_proto.name));
317 fprintf(stderr, "skipping function %s", buf_ptr(&node->data.fn_proto.name));
318 }
319 return;336 return;
320 }337 }
321338
...@@ -344,7 +361,7 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)...@@ -344,7 +361,7 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
344 return;361 return;
345 }362 }
346363
347 AstNode *node = create_typedef_node(c, type_name, make_qual_type_node(c, child_qt));364 AstNode *node = create_typedef_node(c, type_name, make_qual_type_node(c, child_qt, (Decl*)typedef_decl));
348365
349 if (node) {366 if (node) {
350 normalize_parent_ptrs(node);367 normalize_parent_ptrs(node);
...@@ -363,16 +380,14 @@ static bool decl_visitor(void *context, const Decl *decl) {...@@ -363,16 +380,14 @@ static bool decl_visitor(void *context, const Decl *decl) {
363 visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));380 visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
364 break;381 break;
365 default:382 default:
366 if (c->warnings_on) {383 emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName());
367 fprintf(stderr, "ignoring %s\n", decl->getDeclKindName());
368 }
369 }384 }
370385
371 return true;386 return true;
372}387}
373388
374int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,389int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *source,
375 const char **args, int args_len, const char *libc_include_path)390 const char **args, int args_len, const char *libc_include_path, bool warnings_on)
376{391{
377 int err;392 int err;
378 Buf tmp_file_path = BUF_INIT;393 Buf tmp_file_path = BUF_INIT;
...@@ -389,16 +404,19 @@ int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *sour...@@ -389,16 +404,19 @@ int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *sour
389 clang_argv.append(args[i]);404 clang_argv.append(args[i]);
390 }405 }
391406
392 err = parse_h_file(import, errors, &clang_argv);407 err = parse_h_file(import, errors, &clang_argv, warnings_on);
393408
394 os_delete_file(&tmp_file_path);409 os_delete_file(&tmp_file_path);
395410
396 return err;411 return err;
397}412}
398413
399int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<const char *> *clang_argv) {414int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors,
415 ZigList<const char *> *clang_argv, bool warnings_on)
416{
400 Context context = {0};417 Context context = {0};
401 Context *c = &context;418 Context *c = &context;
419 c->warnings_on = warnings_on;
402 c->import = import;420 c->import = import;
403 c->errors = errors;421 c->errors = errors;
404 c->visib_mod = VisibModPub;422 c->visib_mod = VisibModPub;
...@@ -492,6 +510,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<...@@ -492,6 +510,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<
492 return 0;510 return 0;
493 }511 }
494512
513 c->source_manager = &ast_unit->getSourceManager();
514
495 c->root = create_node(c, NodeTypeRoot);515 c->root = create_node(c, NodeTypeRoot);
496 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);516 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
497 normalize_parent_ptrs(c->root);517 normalize_parent_ptrs(c->root);
src/parseh.hpp+3-2
...@@ -12,8 +12,9 @@...@@ -12,8 +12,9 @@
12#include "all_types.hpp"12#include "all_types.hpp"
1313
14int parse_h_file(ImportTableEntry *out_import, ZigList<ErrorMsg *> *out_errs,14int parse_h_file(ImportTableEntry *out_import, ZigList<ErrorMsg *> *out_errs,
15 ZigList<const char *> *clang_argv);15 ZigList<const char *> *clang_argv, bool warnings_on);
16int parse_h_buf(ImportTableEntry *out_import, ZigList<ErrorMsg *> *out_errs,16int parse_h_buf(ImportTableEntry *out_import, ZigList<ErrorMsg *> *out_errs,
17 Buf *source, const char **args, int args_len, const char *libc_include_path);17 Buf *source, const char **args, int args_len, const char *libc_include_path,
18 bool warnings_on);
1819
19#endif20#endif