| 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 | 9242 | for (size_t i = 0; i < errors_len; i += 1) { |
| 9243 | 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 | |
| 9246 | if (clang_err->source && clang_err->filename_ptr) { | |
| 9247 | ErrorMsg *err_msg = err_msg_create_with_offset( | |
| 9248 | clang_err->filename_ptr ? | |
| 9249 | buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), | |
| 9250 | clang_err->line, clang_err->column, clang_err->offset, clang_err->source, | |
| 9251 | buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); | |
| 9252 | print_err_msg(err_msg, g->err_color); | |
| 9253 | } | |
| 9245 | ErrorMsg *err_msg = err_msg_create_with_offset( | |
| 9246 | clang_err->filename_ptr ? | |
| 9247 | buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : nullptr, | |
| 9248 | clang_err->line, clang_err->column, clang_err->offset, clang_err->source, | |
| 9249 | buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); | |
| 9250 | print_err_msg(err_msg, g->err_color); | |
| 9254 | 9251 | } |
| 9255 | 9252 | exit(1); |
| 9256 | 9253 | } |
src/errmsg.cpp+40-36| ... | ... | @@ -16,51 +16,49 @@ enum ErrType { |
| 16 | 16 | }; |
| 17 | 17 | |
| 18 | 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 | 19 | bool is_tty = os_stderr_tty(); |
| 25 | if (color == ErrColorOn || (color == ErrColorAuto && is_tty)) { | |
| 26 | if (err_type == ErrTypeError) { | |
| 27 | os_stderr_set_color(TermColorBold); | |
| 28 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col); | |
| 29 | os_stderr_set_color(TermColorRed); | |
| 30 | fprintf(stderr, "error:"); | |
| 31 | os_stderr_set_color(TermColorBold); | |
| 32 | fprintf(stderr, " %s", text); | |
| 33 | os_stderr_set_color(TermColorReset); | |
| 34 | fprintf(stderr, "\n"); | |
| 35 | } else if (err_type == ErrTypeNote) { | |
| 36 | os_stderr_set_color(TermColorBold); | |
| 37 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", path, line, col); | |
| 38 | os_stderr_set_color(TermColorCyan); | |
| 39 | fprintf(stderr, "note:"); | |
| 40 | os_stderr_set_color(TermColorBold); | |
| 41 | fprintf(stderr, " %s", text); | |
| 42 | os_stderr_set_color(TermColorReset); | |
| 43 | fprintf(stderr, "\n"); | |
| 44 | } else { | |
| 20 | bool use_colors = color == ErrColorOn || (color == ErrColorAuto && is_tty); | |
| 21 | ||
| 22 | // Show the error location, if available | |
| 23 | if (err->path != nullptr) { | |
| 24 | const size_t line = err->line_start + 1; | |
| 25 | const size_t col = err->column_start + 1; | |
| 26 | ||
| 27 | if (use_colors) os_stderr_set_color(TermColorBold); | |
| 28 | fprintf(stderr, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ": ", buf_ptr(err->path), line, col); | |
| 29 | } | |
| 30 | ||
| 31 | // Write out the error type | |
| 32 | switch (err_type) { | |
| 33 | case ErrTypeError: | |
| 34 | if (use_colors) os_stderr_set_color(TermColorRed); | |
| 35 | fprintf(stderr, "error: "); | |
| 36 | break; | |
| 37 | case ErrTypeNote: | |
| 38 | if (use_colors) os_stderr_set_color(TermColorCyan); | |
| 39 | fprintf(stderr, "note: "); | |
| 40 | break; | |
| 41 | default: | |
| 45 | 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 | 53 | fprintf(stderr, "%s\n", buf_ptr(&err->line_buf)); |
| 49 | 54 | for (size_t i = 0; i < err->column_start; i += 1) { |
| 50 | 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 | 59 | fprintf(stderr, "^"); |
| 54 | os_stderr_set_color(TermColorReset); | |
| 60 | if (use_colors) os_stderr_set_color(TermColorReset); | |
| 55 | 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 | 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 | 84 | err_msg->column_start = column; |
| 87 | 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 | 93 | size_t line_start_offset = offset; |
| 90 | 94 | for (;;) { |
| 91 | 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 | 2111 | llvm::StringRef msg_str_ref = it->getMessage(); |
| 2112 | 2112 | |
| 2113 | 2113 | Stage2ErrorMsg *msg = errors.add_one(); |
| 2114 | memset(msg, 0, sizeof(*msg)); | |
| 2115 | ||
| 2114 | 2116 | msg->msg_ptr = (const char *)msg_str_ref.bytes_begin(); |
| 2115 | 2117 | msg->msg_len = msg_str_ref.size(); |
| 2116 | 2118 | |
| 2117 | 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 | 2126 | if (fsl.hasManager()) { |
| 2119 | clang::FileID file_id = fsl.getFileID(); | |
| 2120 | clang::StringRef filename = fsl.getManager().getFilename(fsl); | |
| 2121 | if (filename.empty()) { | |
| 2122 | msg->filename_ptr = nullptr; | |
| 2123 | } else { | |
| 2127 | const clang::SourceManager &SM = fsl.getManager(); | |
| 2128 | ||
| 2129 | clang::PresumedLoc presumed_loc = SM.getPresumedLoc(fsl); | |
| 2130 | assert(!presumed_loc.isInvalid()); | |
| 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 | 2137 | msg->filename_ptr = (const char *)filename.bytes_begin(); |
| 2125 | 2138 | msg->filename_len = filename.size(); |
| 2126 | 2139 | } |
| 2127 | msg->source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin(); | |
| 2128 | msg->line = fsl.getSpellingLineNumber() - 1; | |
| 2129 | msg->column = fsl.getSpellingColumnNumber() - 1; | |
| 2130 | msg->offset = fsl.getManager().getFileOffset(fsl); | |
| 2131 | } else { | |
| 2132 | // The only known way this gets triggered right now is if you have a lot of errors | |
| 2133 | // clang emits "too many errors emitted, stopping now" | |
| 2134 | msg->filename_ptr = nullptr; | |
| 2135 | msg->source = nullptr; | |
| 2140 | ||
| 2141 | bool invalid; | |
| 2142 | clang::StringRef buffer = fsl.getBufferData(&invalid); | |
| 2143 | ||
| 2144 | if (!invalid) { | |
| 2145 | msg->source = (const char *)buffer.bytes_begin(); | |
| 2146 | msg->offset = SM.getFileOffset(fsl); | |
| 2147 | } | |
| 2136 | 2148 | } |
| 2137 | 2149 | } |
| 2138 | 2150 |