| author | |
| committer | |
| log | 95619ecb8ccf8a5405b901e02cfbb389a8f95aba |
| tree | 46dce328a8b95b3aaac1fe1e3ed02820f2689533 |
| parent | 9cc7fb66bc00d54d8e4ff77cb6a0327488ceb59d |
* Refactor the error-writing code to be more compact and flexible3 files changed, 72 insertions(+), 59 deletions(-)
src/codegen.cpp+6-9| ... | @@ -9242,15 +9242,12 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) { | ... | @@ -9242,15 +9242,12 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) { |
| 9242 | for (size_t i = 0; i < errors_len; i += 1) { | 9242 | for (size_t i = 0; i < errors_len; i += 1) { |
| 9243 | Stage2ErrorMsg *clang_err = &errors_ptr[i]; | 9243 | Stage2ErrorMsg *clang_err = &errors_ptr[i]; |
| 9244 | 9244 | ||
| 9245 | // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null | 9245 | ErrorMsg *err_msg = err_msg_create_with_offset( |
| 9246 | if (clang_err->source && clang_err->filename_ptr) { | 9246 | clang_err->filename_ptr ? |
| 9247 | ErrorMsg *err_msg = err_msg_create_with_offset( | 9247 | buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : nullptr, |
| 9248 | clang_err->filename_ptr ? | 9248 | clang_err->line, clang_err->column, clang_err->offset, clang_err->source, |
| 9249 | buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), | 9249 | buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); |
| 9250 | clang_err->line, clang_err->column, clang_err->offset, clang_err->source, | 9250 | print_err_msg(err_msg, g->err_color); |
| 9251 | buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); | ||
| 9252 | print_err_msg(err_msg, g->err_color); | ||
| 9253 | } | ||
| 9254 | } | 9251 | } |
| 9255 | exit(1); | 9252 | exit(1); |
| 9256 | } | 9253 | } |
src/errmsg.cpp+40-36| ... | @@ -16,51 +16,49 @@ enum ErrType { | ... | @@ -16,51 +16,49 @@ enum ErrType { |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | static void print_err_msg_type(ErrorMsg *err, ErrColor color, ErrType err_type) { | 18 | static void print_err_msg_type(ErrorMsg *err, ErrColor color, ErrType err_type) { |
| 19 | const char *path = buf_ptr(err->path); | ||
| 20 | size_t line = err->line_start + 1; | ||
| 21 | size_t col = err->column_start + 1; | ||
| 22 | const char *text = buf_ptr(err->msg); | ||
| 23 | |||
| 24 | bool is_tty = os_stderr_tty(); | 19 | bool is_tty = os_stderr_tty(); |
| 25 | if (color == ErrColorOn || (color == ErrColorAuto && is_tty)) { | 20 | bool use_colors = color == ErrColorOn || (color == ErrColorAuto && is_tty); |
| 26 | if (err_type == ErrTypeError) { | 21 | |
| 27 | os_stderr_set_color(TermColorBold); | 22 | // Show the error location, if available |
| 28 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col); | 23 | if (err->path != nullptr) { |
| 29 | os_stderr_set_color(TermColorRed); | 24 | const size_t line = err->line_start + 1; |
| 30 | fprintf(stderr, "error:"); | 25 | const size_t col = err->column_start + 1; |
| 31 | os_stderr_set_color(TermColorBold); | 26 | |
| 32 | fprintf(stderr, " %s", text); | 27 | if (use_colors) os_stderr_set_color(TermColorBold); |
| 33 | os_stderr_set_color(TermColorReset); | 28 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", buf_ptr(err->path), line, col); |
| 34 | fprintf(stderr, "\n"); | 29 | } |
| 35 | } else if (err_type == ErrTypeNote) { | 30 | |
| 36 | os_stderr_set_color(TermColorBold); | 31 | // Write out the error type |
| 37 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col); | 32 | switch (err_type) { |
| 38 | os_stderr_set_color(TermColorCyan); | 33 | case ErrTypeError: |
| 39 | fprintf(stderr, "note:"); | 34 | if (use_colors) os_stderr_set_color(TermColorRed); |
| 40 | os_stderr_set_color(TermColorBold); | 35 | fprintf(stderr, "error: "); |
| 41 | fprintf(stderr, " %s", text); | 36 | break; |
| 42 | os_stderr_set_color(TermColorReset); | 37 | case ErrTypeNote: |
| 43 | fprintf(stderr, "\n"); | 38 | if (use_colors) os_stderr_set_color(TermColorCyan); |
| 44 | } else { | 39 | fprintf(stderr, "note: "); |
| 40 | break; | ||
| 41 | default: | ||
| 45 | zig_unreachable(); | 42 | zig_unreachable(); |
| 46 | } | 43 | } |
| 47 | 44 | ||
| 45 | // Write out the error message | ||
| 46 | if (use_colors) os_stderr_set_color(TermColorBold); | ||
| 47 | fputs(buf_ptr(err->msg), stderr); | ||
| 48 | if (use_colors) os_stderr_set_color(TermColorReset); | ||
| 49 | fputc('\n', stderr); | ||
| 50 | |||
| 51 | if (buf_len(&err->line_buf) != 0){ | ||
| 52 | // Show the referenced line | ||
| 48 | fprintf(stderr, "%s\n", buf_ptr(&err->line_buf)); | 53 | fprintf(stderr, "%s\n", buf_ptr(&err->line_buf)); |
| 49 | for (size_t i = 0; i < err->column_start; i += 1) { | 54 | for (size_t i = 0; i < err->column_start; i += 1) { |
| 50 | fprintf(stderr, " "); | 55 | fprintf(stderr, " "); |
| 51 | } | 56 | } |
| 52 | os_stderr_set_color(TermColorGreen); | 57 | // Draw the caret |
| 58 | if (use_colors) os_stderr_set_color(TermColorGreen); | ||
| 53 | fprintf(stderr, "^"); | 59 | fprintf(stderr, "^"); |
| 54 | os_stderr_set_color(TermColorReset); | 60 | if (use_colors) os_stderr_set_color(TermColorReset); |
| 55 | fprintf(stderr, "\n"); | 61 | fprintf(stderr, "\n"); |
| 56 | } else { | ||
| 57 | if (err_type == ErrTypeError) { | ||
| 58 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": error: %s\n", path, line, col, text); | ||
| 59 | } else if (err_type == ErrTypeNote) { | ||
| 60 | fprintf(stderr, " %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": note: %s\n", path, line, col, text); | ||
| 61 | } else { | ||
| 62 | zig_unreachable(); | ||
| 63 | } | ||
| 64 | } | 62 | } |
| 65 | 63 | ||
| 66 | for (size_t i = 0; i < err->notes.length; i += 1) { | 64 | for (size_t i = 0; i < err->notes.length; i += 1) { |
| ... | @@ -86,6 +84,12 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size | ... | @@ -86,6 +84,12 @@ ErrorMsg *err_msg_create_with_offset(Buf *path, size_t line, size_t column, size |
| 86 | err_msg->column_start = column; | 84 | err_msg->column_start = column; |
| 87 | err_msg->msg = msg; | 85 | err_msg->msg = msg; |
| 88 | 86 | ||
| 87 | if (source == nullptr) { | ||
| 88 | // Must initialize the buffer anyway | ||
| 89 | buf_init_from_str(&err_msg->line_buf, ""); | ||
| 90 | return err_msg; | ||
| 91 | } | ||
| 92 | |||
| 89 | size_t line_start_offset = offset; | 93 | size_t line_start_offset = offset; |
| 90 | for (;;) { | 94 | for (;;) { |
| 91 | if (line_start_offset == 0) { | 95 | if (line_start_offset == 0) { |
src/zig_clang.cpp+26-14| ... | @@ -2111,28 +2111,40 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char | ... | @@ -2111,28 +2111,40 @@ ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char |
| 2111 | llvm::StringRef msg_str_ref = it->getMessage(); | 2111 | llvm::StringRef msg_str_ref = it->getMessage(); |
| 2112 | 2112 | ||
| 2113 | Stage2ErrorMsg *msg = errors.add_one(); | 2113 | Stage2ErrorMsg *msg = errors.add_one(); |
| 2114 | memset(msg, 0, sizeof(*msg)); | ||
| 2115 | |||
| 2114 | msg->msg_ptr = (const char *)msg_str_ref.bytes_begin(); | 2116 | msg->msg_ptr = (const char *)msg_str_ref.bytes_begin(); |
| 2115 | msg->msg_len = msg_str_ref.size(); | 2117 | msg->msg_len = msg_str_ref.size(); |
| 2116 | 2118 | ||
| 2117 | clang::FullSourceLoc fsl = it->getLocation(); | 2119 | clang::FullSourceLoc fsl = it->getLocation(); |
| 2120 | // Expand the location if possible | ||
| 2121 | fsl = fsl.getFileLoc(); | ||
| 2122 | |||
| 2123 | // The only known way to obtain a Loc without a manager associated | ||
| 2124 | // to it is if you have a lot of errors clang emits "too many errors | ||
| 2125 | // emitted, stopping now" | ||
| 2118 | if (fsl.hasManager()) { | 2126 | if (fsl.hasManager()) { |
| 2119 | clang::FileID file_id = fsl.getFileID(); | 2127 | const clang::SourceManager &SM = fsl.getManager(); |
| 2120 | clang::StringRef filename = fsl.getManager().getFilename(fsl); | 2128 | |
| 2121 | if (filename.empty()) { | 2129 | clang::PresumedLoc presumed_loc = SM.getPresumedLoc(fsl); |
| 2122 | msg->filename_ptr = nullptr; | 2130 | assert(!presumed_loc.isInvalid()); |
| 2123 | } else { | 2131 | |
| 2132 | msg->line = presumed_loc.getLine() - 1; | ||
| 2133 | msg->column = presumed_loc.getColumn() - 1; | ||
| 2134 | |||
| 2135 | clang::StringRef filename = presumed_loc.getFilename(); | ||
| 2136 | if (!filename.empty()) { | ||
| 2124 | msg->filename_ptr = (const char *)filename.bytes_begin(); | 2137 | msg->filename_ptr = (const char *)filename.bytes_begin(); |
| 2125 | msg->filename_len = filename.size(); | 2138 | msg->filename_len = filename.size(); |
| 2126 | } | 2139 | } |
| 2127 | msg->source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); | 2140 | |
| 2128 | msg->line = fsl.getSpellingLineNumber() - 1; | 2141 | bool invalid; |
| 2129 | msg->column = fsl.getSpellingColumnNumber() - 1; | 2142 | clang::StringRef buffer = fsl.getBufferData(&invalid); |
| 2130 | msg->offset = fsl.getManager().getFileOffset(fsl); | 2143 | |
| 2131 | } else { | 2144 | if (!invalid) { |
| 2132 | // The only known way this gets triggered right now is if you have a lot of errors | 2145 | msg->source = (const char *)buffer.bytes_begin(); |
| 2133 | // clang emits "too many errors emitted, stopping now" | 2146 | msg->offset = SM.getFileOffset(fsl); |
| 2134 | msg->filename_ptr = nullptr; | 2147 | } |
| 2135 | msg->source = nullptr; | ||
| 2136 | } | 2148 | } |
| 2137 | } | 2149 | } |
| 2138 | 2150 |