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
10691069
10701070 int err;
10711071 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)))
10731073 {
10741074 zig_panic("unable to parse h file: %s\n", err_str(err));
10751075 }
src/main.cpp+6-2
......@@ -33,6 +33,7 @@ static int usage(const char *arg0) {
3333 " --libc-path [path] set the C compiler data path\n"
3434 " -isystem [dir] add additional search path for other .h files\n"
3535 " -dirafter [dir] same as -isystem but do it last\n"
36 " --c-import-warnings enable warnings when importing .h files\n"
3637 , arg0);
3738 return EXIT_FAILURE;
3839}
......@@ -167,6 +168,7 @@ static int parseh(const char *arg0, int argc, char **argv) {
167168 char *in_file = nullptr;
168169 ZigList<const char *> clang_argv = {0};
169170 ErrColor color = ErrColorAuto;
171 bool warnings_on = false;
170172 for (int i = 0; i < argc; i += 1) {
171173 char *arg = argv[i];
172174 if (arg[0] == '-') {
......@@ -193,7 +195,9 @@ static int parseh(const char *arg0, int argc, char **argv) {
193195 } else {
194196 return usage(arg0);
195197 }
196 } else {
198 } else if (strcmp(arg, "--c-import-warnings") == 0) {
199 warnings_on = true;
200 } else {
197201 fprintf(stderr, "unrecognized argument: %s", arg);
198202 return usage(arg0);
199203 }
......@@ -217,7 +221,7 @@ static int parseh(const char *arg0, int argc, char **argv) {
217221
218222 ImportTableEntry import = {0};
219223 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
222226 if (err) {
223227 fprintf(stderr, "unable to parse .h file: %s\n", err_str(err));
src/parseh.cpp+49-29
......@@ -28,9 +28,36 @@ struct Context {
2828 AstNode *root;
2929 HashMap<Buf *, bool, buf_hash, buf_eql_buf> type_table;
3030 HashMap<Buf *, bool, buf_hash, buf_eql_buf> fn_table;
31 SourceManager *source_manager;
3132};
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
3562static AstNode *create_node(Context *c, NodeType type) {
3663 AstNode *node = allocate<AstNode>(1);
......@@ -96,7 +123,7 @@ static AstNode *pointer_to_type(Context *c, AstNode *type_node, bool is_const) {
96123 return node;
97124}
98125
99static AstNode *make_type_node(Context *c, const Type *ty) {
126static AstNode *make_type_node(Context *c, const Type *ty, Decl *decl) {
100127 switch (ty->getTypeClass()) {
101128 case Type::Builtin:
102129 {
......@@ -159,9 +186,7 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
159186 case BuiltinType::UnknownAny:
160187 case BuiltinType::BuiltinFn:
161188 case BuiltinType::ARCUnbridgedCast:
162 if (c->warnings_on) {
163 fprintf(stderr, "missed a builtin type\n");
164 }
189 emit_warning(c, decl, "missed a builtin type");
165190 return nullptr;
166191 }
167192 break;
......@@ -170,7 +195,7 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
170195 {
171196 const PointerType *pointer_ty = static_cast<const PointerType*>(ty);
172197 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);
174199 return pointer_to_type(c, type_node, child_qt.isConstQualified());
175200 }
176201 case Type::Typedef:
......@@ -208,14 +233,10 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
208233 }
209234 }
210235 case Type::Elaborated:
211 if (c->warnings_on) {
212 fprintf(stderr, "ignoring elaborated type\n");
213 }
236 emit_warning(c, decl, "ignoring elaborated type");
214237 return nullptr;
215238 case Type::FunctionProto:
216 if (c->warnings_on) {
217 fprintf(stderr, "ignoring function type\n");
218 }
239 emit_warning(c, decl, "ignoring function type");
219240 return nullptr;
220241 case Type::Record:
221242 case Type::Enum:
......@@ -254,15 +275,13 @@ static AstNode *make_type_node(Context *c, const Type *ty) {
254275 case Type::Complex:
255276 case Type::ObjCObjectPointer:
256277 case Type::Atomic:
257 if (c->warnings_on) {
258 fprintf(stderr, "missed a '%s' type\n", ty->getTypeClassName());
259 }
278 emit_warning(c, decl, "missed a '%s' type", ty->getTypeClassName());
260279 return nullptr;
261280 }
262281}
263282
264static AstNode *make_qual_type_node(Context *c, QualType qt) {
265 return make_type_node(c, qt.getTypePtr());
283static AstNode *make_qual_type_node(Context *c, QualType qt, Decl *decl) {
284 return make_type_node(c, qt.getTypePtr(), decl);
266285}
267286
268287static 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) {
292311 buf_init_from_str(&param_decl_node->data.param_decl.name, name);
293312 QualType qt = param->getOriginalType();
294313 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);
296315 if (!param_decl_node->data.param_decl.type) {
297316 all_ok = false;
298317 break;
......@@ -305,7 +324,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
305324 if (fn_decl->isNoReturn()) {
306325 node->data.fn_proto.return_type = simple_type_node(c, "unreachable");
307326 } 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);
309328 }
310329
311330 if (!node->data.fn_proto.return_type) {
......@@ -313,9 +332,7 @@ static void visit_fn_decl(Context *c, const FunctionDecl *fn_decl) {
313332 }
314333 if (!all_ok) {
315334 // not all the types could be resolved, so we give up on the function decl
316 if (c->warnings_on) {
317 fprintf(stderr, "skipping function %s", buf_ptr(&node->data.fn_proto.name));
318 }
335 emit_warning(c, (Decl*)fn_decl, "skipping function %s\n", buf_ptr(&node->data.fn_proto.name));
319336 return;
320337 }
321338
......@@ -344,7 +361,7 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
344361 return;
345362 }
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
349366 if (node) {
350367 normalize_parent_ptrs(node);
......@@ -363,16 +380,14 @@ static bool decl_visitor(void *context, const Decl *decl) {
363380 visit_typedef_decl(c, static_cast<const TypedefNameDecl *>(decl));
364381 break;
365382 default:
366 if (c->warnings_on) {
367 fprintf(stderr, "ignoring %s\n", decl->getDeclKindName());
368 }
383 emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName());
369384 }
370385
371386 return true;
372387}
373388
374389int 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)
376391{
377392 int err;
378393 Buf tmp_file_path = BUF_INIT;
......@@ -389,16 +404,19 @@ int parse_h_buf(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, Buf *sour
389404 clang_argv.append(args[i]);
390405 }
391406
392 err = parse_h_file(import, errors, &clang_argv);
407 err = parse_h_file(import, errors, &clang_argv, warnings_on);
393408
394409 os_delete_file(&tmp_file_path);
395410
396411 return err;
397412}
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{
400417 Context context = {0};
401418 Context *c = &context;
419 c->warnings_on = warnings_on;
402420 c->import = import;
403421 c->errors = errors;
404422 c->visib_mod = VisibModPub;
......@@ -492,6 +510,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, ZigList<
492510 return 0;
493511 }
494512
513 c->source_manager = &ast_unit->getSourceManager();
514
495515 c->root = create_node(c, NodeTypeRoot);
496516 ast_unit->visitLocalTopLevelDecls(c, decl_visitor);
497517 normalize_parent_ptrs(c->root);
src/parseh.hpp+3-2
......@@ -12,8 +12,9 @@
1212#include "all_types.hpp"
1313
1414int 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);
1616int 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
1920#endif