authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 16:01:06-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-01 16:01:06-04:00
log783f73c7e3590f05825d66f1f0ccb108be74b5c4
tree429e9e06852b06bd6758ab2bd7d53a240a71771c
parent6695fa4f326e807256b9afc6321e63a90b08e1ba
signaturelock-open Commit is signed but in an unrecognized format.

zig cc properly handles -S flag and .ll, .bc extensions


13 files changed, 122 insertions(+), 90 deletions(-)

src-self-hosted/clang_options_data.zig+5-5
......@@ -7,7 +7,7 @@ flagpd1("CC"),
77.{
88 .name = "E",
99 .syntax = .flag,
10 .zig_equivalent = .preprocess,
10 .zig_equivalent = .pp_or_asm,
1111 .pd1 = true,
1212 .pd2 = false,
1313 .psl = false,
......@@ -53,7 +53,7 @@ flagpd1("Qy"),
5353.{
5454 .name = "S",
5555 .syntax = .flag,
56 .zig_equivalent = .driver_punt,
56 .zig_equivalent = .pp_or_asm,
5757 .pd1 = true,
5858 .pd2 = false,
5959 .psl = false,
......@@ -154,7 +154,7 @@ sepd1("Zlinker-input"),
154154.{
155155 .name = "E",
156156 .syntax = .flag,
157 .zig_equivalent = .preprocess,
157 .zig_equivalent = .pp_or_asm,
158158 .pd1 = true,
159159 .pd2 = false,
160160 .psl = true,
......@@ -1442,7 +1442,7 @@ sepd1("Zlinker-input"),
14421442.{
14431443 .name = "assemble",
14441444 .syntax = .flag,
1445 .zig_equivalent = .driver_punt,
1445 .zig_equivalent = .pp_or_asm,
14461446 .pd1 = false,
14471447 .pd2 = true,
14481448 .psl = false,
......@@ -1770,7 +1770,7 @@ sepd1("Zlinker-input"),
17701770.{
17711771 .name = "preprocess",
17721772 .syntax = .flag,
1773 .zig_equivalent = .preprocess,
1773 .zig_equivalent = .pp_or_asm,
17741774 .pd1 = false,
17751775 .pd2 = true,
17761776 .psl = false,
src-self-hosted/stage2.zig+1-1
......@@ -1280,7 +1280,7 @@ pub const ClangArgIterator = extern struct {
12801280 shared,
12811281 rdynamic,
12821282 wl,
1283 preprocess,
1283 pp_or_asm,
12841284 optimize,
12851285 debug,
12861286 sanitize,
src/all_types.hpp+10
......@@ -54,6 +54,16 @@ struct ResultLocCast;
5454struct ResultLocReturn;
5555struct IrExecutableGen;
5656
57enum FileExt {
58 FileExtUnknown,
59 FileExtAsm,
60 FileExtC,
61 FileExtCpp,
62 FileExtHeader,
63 FileExtLLVMIr,
64 FileExtLLVMBitCode,
65};
66
5767enum PtrLen {
5868 PtrLenUnknown,
5969 PtrLenSingle,
src/analyze.hpp+1-7
......@@ -257,14 +257,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
257257LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type);
258258ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
259259
260enum CSourceKind {
261 CSourceKindAsm,
262 CSourceKindC,
263 CSourceKindCpp,
264};
265
266260void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c,
267 CSourceKind source_kind);
261 FileExt source_kind);
268262
269263void src_assert(bool ok, AstNode *source_node);
270264bool is_container(ZigType *type_entry);
src/buffer.hpp+1-4
......@@ -178,10 +178,7 @@ static inline bool buf_starts_with_str(Buf *buf, const char *str) {
178178}
179179
180180static inline bool buf_ends_with_mem(Buf *buf, const char *mem, size_t mem_len) {
181 if (buf_len(buf) < mem_len) {
182 return false;
183 }
184 return memcmp(buf_ptr(buf) + buf_len(buf) - mem_len, mem, mem_len) == 0;
181 return mem_ends_with_mem(buf_ptr(buf), buf_len(buf), mem, mem_len);
185182}
186183
187184static inline bool buf_ends_with_str(Buf *buf, const char *str) {
src/codegen.cpp+37-45
......@@ -9170,20 +9170,13 @@ static void detect_libc(CodeGen *g) {
91709170
91719171// does not add the "cc" arg
91729172void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path,
9173 bool translate_c, CSourceKind source_kind)
9173 bool translate_c, FileExt source_kind)
91749174{
91759175 if (translate_c) {
91769176 args.append("-x");
91779177 args.append("c");
91789178 }
91799179
9180 if (source_kind != CSourceKindAsm && out_dep_path != nullptr) {
9181 args.append("-MD");
9182 args.append("-MV");
9183 args.append("-MF");
9184 args.append(out_dep_path);
9185 }
9186
91879180 args.append("-nostdinc");
91889181 args.append("-fno-spell-checking");
91899182
......@@ -9191,14 +9184,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
91919184 args.append("-ffunction-sections");
91929185 }
91939186
9194 if (translate_c) {
9195 if (source_kind != CSourceKindAsm) {
9196 // this gives us access to preprocessing entities, presumably at
9197 // the cost of performance
9198 args.append("-Xclang");
9199 args.append("-detailed-preprocessing-record");
9200 }
9201 } else {
9187 if (!translate_c) {
92029188 switch (g->err_color) {
92039189 case ErrColorAuto:
92049190 break;
......@@ -9232,24 +9218,25 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
92329218 args.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
92339219 }
92349220
9235 // According to Rich Felker libc headers are supposed to go before C language headers.
9236 // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics
9237 // and other compiler specific items.
9238 args.append("-isystem");
9239 args.append(buf_ptr(g->zig_c_headers_dir));
9240
9241 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
9242 const char *include_dir = g->libc_include_dir_list[i];
9243 args.append("-isystem");
9244 args.append(include_dir);
9245 }
9246
92479221 args.append("-target");
92489222 args.append(buf_ptr(&g->llvm_triple_str));
92499223
92509224 switch (source_kind) {
9251 case CSourceKindC:
9252 case CSourceKindCpp:
9225 case FileExtC:
9226 case FileExtCpp:
9227 case FileExtHeader:
9228 // According to Rich Felker libc headers are supposed to go before C language headers.
9229 // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics
9230 // and other compiler specific items.
9231 args.append("-isystem");
9232 args.append(buf_ptr(g->zig_c_headers_dir));
9233
9234 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
9235 const char *include_dir = g->libc_include_dir_list[i];
9236 args.append("-isystem");
9237 args.append(include_dir);
9238 }
9239
92539240 if (g->zig_target->llvm_cpu_name != nullptr) {
92549241 args.append("-Xclang");
92559242 args.append("-target-cpu");
......@@ -9262,8 +9249,23 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
92629249 args.append("-Xclang");
92639250 args.append(g->zig_target->llvm_cpu_features);
92649251 }
9252 if (translate_c) {
9253 // this gives us access to preprocessing entities, presumably at
9254 // the cost of performance
9255 args.append("-Xclang");
9256 args.append("-detailed-preprocessing-record");
9257 }
9258 if (out_dep_path != nullptr) {
9259 args.append("-MD");
9260 args.append("-MV");
9261 args.append("-MF");
9262 args.append(out_dep_path);
9263 }
92659264 break;
9266 case CSourceKindAsm:
9265 case FileExtAsm:
9266 case FileExtLLVMIr:
9267 case FileExtLLVMBitCode:
9268 case FileExtUnknown:
92679269 break;
92689270 }
92699271 for (size_t i = 0; i < g->zig_target->llvm_cpu_features_asm_len; i += 1) {
......@@ -9413,7 +9415,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) {
94139415 }
94149416
94159417 ZigList<const char *> clang_argv = {0};
9416 add_cc_args(g, clang_argv, out_dep_path_cstr, true, CSourceKindC);
9418 add_cc_args(g, clang_argv, out_dep_path_cstr, true, FileExtC);
94179419
94189420 clang_argv.append(buf_ptr(full_path));
94199421
......@@ -9751,15 +9753,6 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
97519753 Buf *c_source_basename = buf_alloc();
97529754 os_path_split(c_source_file, nullptr, c_source_basename);
97539755
9754 CSourceKind c_source_kind;
9755 if (buf_ends_with_str(c_source_basename, ".s") ||
9756 buf_ends_with_str(c_source_basename, ".S"))
9757 {
9758 c_source_kind = CSourceKindAsm;
9759 } else {
9760 c_source_kind = CSourceKindC;
9761 }
9762
97639756 Stage2ProgressNode *child_prog_node = stage2_progress_start(g->sub_progress_node, buf_ptr(c_source_basename),
97649757 buf_len(c_source_basename), 0);
97659758
......@@ -9825,14 +9818,13 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
98259818 args.append(buf_ptr(self_exe_path));
98269819 args.append("clang");
98279820
9828 if (c_file->preprocessor_only_basename != nullptr) {
9829 args.append("-E");
9830 } else {
9821 if (c_file->preprocessor_only_basename == nullptr) {
98319822 args.append("-c");
98329823 }
98339824
98349825 Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path));
9835 add_cc_args(g, args, buf_ptr(out_dep_path), false, c_source_kind);
9826 FileExt ext = classify_file_ext(buf_ptr(c_source_basename), buf_len(c_source_basename));
9827 add_cc_args(g, args, buf_ptr(out_dep_path), false, ext);
98369828
98379829 args.append("-o");
98389830 args.append(buf_ptr(out_obj_path));
src/compiler.cpp+22
......@@ -164,3 +164,25 @@ Buf *get_global_cache_dir(void) {
164164 buf_deinit(&app_data_dir);
165165 return &saved_global_cache_dir;
166166}
167
168FileExt classify_file_ext(const char *filename_ptr, size_t filename_len) {
169 if (mem_ends_with_str(filename_ptr, filename_len, ".c")) {
170 return FileExtC;
171 } else if (mem_ends_with_str(filename_ptr, filename_len, ".C") ||
172 mem_ends_with_str(filename_ptr, filename_len, ".cc") ||
173 mem_ends_with_str(filename_ptr, filename_len, ".cpp") ||
174 mem_ends_with_str(filename_ptr, filename_len, ".cxx"))
175 {
176 return FileExtCpp;
177 } else if (mem_ends_with_str(filename_ptr, filename_len, ".ll")) {
178 return FileExtLLVMIr;
179 } else if (mem_ends_with_str(filename_ptr, filename_len, ".bc")) {
180 return FileExtLLVMBitCode;
181 } else if (mem_ends_with_str(filename_ptr, filename_len, ".s") ||
182 mem_ends_with_str(filename_ptr, filename_len, ".S"))
183 {
184 return FileExtAsm;
185 }
186 // TODO look for .so, .so.X, .so.X.Y, .so.X.Y.Z
187 return FileExtUnknown;
188}
src/compiler.hpp+4-2
......@@ -8,8 +8,7 @@
88#ifndef ZIG_COMPILER_HPP
99#define ZIG_COMPILER_HPP
1010
11#include "buffer.hpp"
12#include "error.hpp"
11#include "all_types.hpp"
1312
1413Error get_compiler_id(Buf **result);
1514
......@@ -19,4 +18,7 @@ Buf *get_zig_std_dir(Buf *zig_lib_dir);
1918
2019Buf *get_global_cache_dir(void);
2120
21
22FileExt classify_file_ext(const char *filename_ptr, size_t filename_len);
23
2224#endif
src/ir.cpp+1-1
......@@ -25171,7 +25171,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo
2517125171
2517225172 ZigList<const char *> clang_argv = {0};
2517325173
25174 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, CSourceKindC);
25174 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, FileExtC);
2517525175
2517625176 clang_argv.append(buf_ptr(&tmp_c_file_path));
2517725177
src/main.cpp+26-20
......@@ -455,7 +455,7 @@ static int main0(int argc, char **argv) {
455455 const char *mcpu = nullptr;
456456 CodeModel code_model = CodeModelDefault;
457457 const char *override_soname = nullptr;
458 bool only_preprocess = false;
458 bool only_pp_or_asm = false;
459459 bool ensure_libc_on_non_freestanding = false;
460460 bool ensure_libcpp_on_non_freestanding = false;
461461
......@@ -615,20 +615,22 @@ static int main0(int argc, char **argv) {
615615 }
616616 break;
617617 case Stage2ClangArgPositional: {
618 Buf *arg_buf = buf_create_from_str(it.only_arg);
619 if (buf_ends_with_str(arg_buf, ".c") ||
620 buf_ends_with_str(arg_buf, ".C") ||
621 buf_ends_with_str(arg_buf, ".cc") ||
622 buf_ends_with_str(arg_buf, ".cpp") ||
623 buf_ends_with_str(arg_buf, ".cxx") ||
624 buf_ends_with_str(arg_buf, ".s") ||
625 buf_ends_with_str(arg_buf, ".S"))
626 {
627 CFile *c_file = heap::c_allocator.create<CFile>();
628 c_file->source_path = it.only_arg;
629 c_source_files.append(c_file);
630 } else {
631 objects.append(it.only_arg);
618 FileExt file_ext = classify_file_ext(it.only_arg, strlen(it.only_arg));
619 switch (file_ext) {
620 case FileExtAsm:
621 case FileExtC:
622 case FileExtCpp:
623 case FileExtLLVMIr:
624 case FileExtLLVMBitCode:
625 case FileExtHeader: {
626 CFile *c_file = heap::c_allocator.create<CFile>();
627 c_file->source_path = it.only_arg;
628 c_source_files.append(c_file);
629 break;
630 }
631 case FileExtUnknown:
632 objects.append(it.only_arg);
633 break;
632634 }
633635 break;
634636 }
......@@ -674,8 +676,12 @@ static int main0(int argc, char **argv) {
674676 }
675677 break;
676678 }
677 case Stage2ClangArgPreprocess:
678 only_preprocess = true;
679 case Stage2ClangArgPreprocessOrAsm:
680 // this handles both -E and -S
681 only_pp_or_asm = true;
682 for (size_t i = 0; i < it.other_args_len; i += 1) {
683 clang_argv.append(it.other_args_ptr[i]);
684 }
679685 break;
680686 case Stage2ClangArgOptimize:
681687 // alright what release mode do they want?
......@@ -799,7 +805,7 @@ static int main0(int argc, char **argv) {
799805 build_mode = BuildModeSafeRelease;
800806 }
801807
802 if (only_preprocess) {
808 if (only_pp_or_asm) {
803809 cmd = CmdBuild;
804810 out_type = OutTypeObj;
805811 emit_bin = false;
......@@ -1597,7 +1603,7 @@ static int main0(int argc, char **argv) {
15971603#endif
15981604 Buf *dest_path = buf_create_from_str(emit_bin_override_path);
15991605 Buf *source_path;
1600 if (only_preprocess) {
1606 if (only_pp_or_asm) {
16011607 source_path = buf_alloc();
16021608 Buf *pp_only_basename = buf_create_from_str(
16031609 c_source_files.at(0)->preprocessor_only_basename);
......@@ -1611,7 +1617,7 @@ static int main0(int argc, char **argv) {
16111617 buf_ptr(dest_path), err_str(err));
16121618 return main_exit(root_progress_node, EXIT_FAILURE);
16131619 }
1614 } else if (only_preprocess) {
1620 } else if (only_pp_or_asm) {
16151621#if defined(ZIG_OS_WINDOWS)
16161622 buf_replace(g->c_artifact_dir, '/', '\\');
16171623#endif
src/stage2.h+1-1
......@@ -339,7 +339,7 @@ enum Stage2ClangArg {
339339 Stage2ClangArgShared,
340340 Stage2ClangArgRDynamic,
341341 Stage2ClangArgWL,
342 Stage2ClangArgPreprocess,
342 Stage2ClangArgPreprocessOrAsm,
343343 Stage2ClangArgOptimize,
344344 Stage2ClangArgDebug,
345345 Stage2ClangArgSanitize,
src/util.hpp+9
......@@ -100,6 +100,15 @@ static inline bool is_power_of_2(uint64_t x) {
100100 return x != 0 && ((x & (~x + 1)) == x);
101101}
102102
103static inline bool mem_ends_with_mem(const char *mem, size_t mem_len, const char *end, size_t end_len) {
104 if (mem_len < end_len) return false;
105 return memcmp(mem + mem_len - end_len, end, end_len) == 0;
106}
107
108static inline bool mem_ends_with_str(const char *mem, size_t mem_len, const char *str) {
109 return mem_ends_with_mem(mem, mem_len, str, strlen(str));
110}
111
103112static inline uint64_t round_to_next_power_of_2(uint64_t x) {
104113 --x;
105114 x |= x >> 1;
tools/update_clang_options.zig+4-4
......@@ -96,19 +96,19 @@ const known_options = [_]KnownOpt{
9696 },
9797 .{
9898 .name = "E",
99 .ident = "preprocess",
99 .ident = "pp_or_asm",
100100 },
101101 .{
102102 .name = "preprocess",
103 .ident = "preprocess",
103 .ident = "pp_or_asm",
104104 },
105105 .{
106106 .name = "S",
107 .ident = "driver_punt",
107 .ident = "pp_or_asm",
108108 },
109109 .{
110110 .name = "assemble",
111 .ident = "driver_punt",
111 .ident = "pp_or_asm",
112112 },
113113 .{
114114 .name = "O1",