CBMC
Loading...
Searching...
No Matches
ms_cl_mode.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Visual Studio CL Mode
4
5Author: CM Wintersteiger, 2006
6
7\*******************************************************************/
8
11
12#include "ms_cl_mode.h"
13
14#ifdef _WIN32
15#define EX_OK 0
16#define EX_USAGE 64
17#define EX_SOFTWARE 70
18#else
19#include <sysexits.h>
20#endif
21
22#include <util/config.h>
23#include <util/get_base_name.h>
24#include <util/message.h>
25
26#include "compile.h"
27#include "ms_cl_version.h"
28
29#include <filesystem>
30#include <iostream>
31
32static bool has_directory_suffix(const std::string &path)
33{
34 // MS CL decides whether a parameter is a directory on the
35 // basis of the / or \\ suffix; it doesn't matter
36 // whether the directory actually exists.
37 return path.empty() ? false :
38 path.back()=='/' || path.back()=='\\';
39}
40
43{
44 if(cmdline.isset('?') ||
45 cmdline.isset("help"))
46 {
47 help();
48 return EX_OK;
49 }
50
52
53 #if 0
54 bool act_as_ld=
55 has_prefix(base_name, "link") ||
56 has_prefix(base_name, "goto-link");
57 #endif
58
59 const auto default_verbosity = (cmdline.isset("Wall") || cmdline.isset("W4"))
62 const auto verbosity = messaget::eval_verbosity(
65
67 ms_cl_version.get("cl.exe");
68
70 log.debug() << "Visual Studio mode " << ms_cl_version << messaget::eom;
71
72 // model validation
73 compiler.validate_goto_model = cmdline.isset("validate-goto-model");
74
75 // get configuration
77
79 config.ansi_c.set_32();
81 config.ansi_c.set_32();
83 config.ansi_c.set_64();
84
86 compiler.object_file_extension="obj";
87
88 // determine actions to be undertaken
89
90 if(cmdline.isset('E') || cmdline.isset('P'))
92 else if(cmdline.isset('c'))
94 else
96
97 if(cmdline.isset("std"))
98 {
99 const std::string std_string = cmdline.get_value("std");
100
101 if(
102 std_string == ":c++14" || std_string == "=c++14" ||
103 std_string == ":c++17" || std_string == "=c++17" ||
104 std_string == ":c++latest" || std_string == "=c++latest")
105 {
106 // we don't have any newer version at the moment
107 config.cpp.set_cpp14();
108 }
109 else if(std_string == ":c++11" || std_string == "=c++11")
110 {
111 // this isn't really a Visual Studio variant, we just do this for GCC
112 // command-line compatibility
113 config.cpp.set_cpp11();
114 }
115 else
116 {
117 log.warning() << "unknown language standard " << std_string
118 << messaget::eom;
119 }
120 }
121 else
122 config.cpp.set_cpp14();
123
124 compiler.echo_file_name=true;
125
126 if(cmdline.isset("Fo"))
127 {
128 std::string Fo_value = cmdline.get_value("Fo");
129
130 // this could be a directory or a file name
132 {
133 compiler.output_directory_object = Fo_value;
134
135 if(!std::filesystem::is_directory(Fo_value))
136 log.warning() << "not a directory: " << Fo_value << messaget::eom;
137 }
138 else
139 compiler.output_file_object = Fo_value;
140 }
141
142 if(
144 cmdline.args.size() > 1 &&
145 compiler.output_directory_object.empty())
146 {
147 log.error() << "output directory required for /c with multiple input files"
148 << messaget::eom;
149 return EX_USAGE;
150 }
151
152 if(cmdline.isset("Fe"))
153 {
154 compiler.output_file_executable=cmdline.get_value("Fe");
155
156 // this could be a directory
157 if(
158 has_directory_suffix(compiler.output_file_executable) &&
159 cmdline.args.size() >= 1)
160 {
161 if(!std::filesystem::is_directory(compiler.output_file_executable))
162 {
163 log.warning() << "not a directory: " << compiler.output_file_executable
164 << messaget::eom;
165 }
166
167 compiler.output_file_executable+=
168 get_base_name(cmdline.args[0], true) + ".exe";
169 }
170 }
171 else
172 {
173 // We need at least one argument.
174 // CL uses the first file name it gets!
175 if(cmdline.args.size()>=1)
176 compiler.output_file_executable=
177 get_base_name(cmdline.args[0], true)+".exe";
178 }
179
180 if(cmdline.isset('J'))
181 config.ansi_c.char_is_unsigned=true;
182
183 if(verbosity > messaget::M_STATISTICS)
184 {
185 std::list<std::string>::iterator it;
186
187 std::cout << "Defines:\n";
188 for(it=config.ansi_c.defines.begin();
189 it!=config.ansi_c.defines.end();
190 it++)
191 {
192 std::cout << " " << (*it) << '\n';
193 }
194
195 std::cout << "Undefines:\n";
196 for(it=config.ansi_c.undefines.begin();
197 it!=config.ansi_c.undefines.end();
198 it++)
199 {
200 std::cout << " " << (*it) << '\n';
201 }
202
203 std::cout << "Preprocessor Options:\n";
204 for(it=config.ansi_c.preprocessor_options.begin();
205 it!=config.ansi_c.preprocessor_options.end();
206 it++)
207 {
208 std::cout << " " << (*it) << '\n';
209 }
210
211 std::cout << "Include Paths:\n";
212 for(it=config.ansi_c.include_paths.begin();
213 it!=config.ansi_c.include_paths.end();
214 it++)
215 {
216 std::cout << " " << (*it) << '\n';
217 }
218
219 std::cout << "Library Paths:\n";
220 for(it=compiler.library_paths.begin();
221 it!=compiler.library_paths.end();
222 it++)
223 {
224 std::cout << " " << (*it) << '\n';
225 }
226
227 std::cout << "Output file (object): "
228 << compiler.output_file_object << '\n';
229 std::cout << "Output file (executable): "
230 << compiler.output_file_executable << '\n';
231 }
232
233 // Parse input program, convert to goto program, write output
234 return compiler.doit() ? EX_USAGE : EX_OK;
235}
236
239{
240 std::cout << "goto-cl understands the options of CL plus the following.\n\n";
241}
configt config
Definition config.cpp:25
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
void print_warnings_as_errors(bool yes)
With yes set to true, prefix warnings with an error message.
std::string get_value(char option) const
Definition cmdline.cpp:48
virtual bool isset(char option) const
Definition cmdline.cpp:30
argst args
Definition cmdline.h:154
@ PREPROCESS_ONLY
Definition compile.h:38
@ COMPILE_LINK_EXECUTABLE
Definition compile.h:43
@ COMPILE_ONLY
Definition compile.h:39
bool set(const cmdlinet &cmdline)
Definition config.cpp:863
struct configt::cppt cpp
struct configt::ansi_ct ansi_c
const std::string base_name
void help()
display command line help
Class that provides messages with a built-in verbosity 'level'.
Definition message.h:154
static unsigned eval_verbosity(const std::string &user_input, const message_levelt default_verbosity, message_handlert &dest)
Parse a (user-)provided string as a verbosity level and set it as the verbosity of dest.
Definition message.cpp:105
@ M_STATISTICS
Definition message.h:170
@ M_ERROR
Definition message.h:169
@ M_WARNING
Definition message.h:169
static eomt eom
Definition message.h:289
ms_cl_cmdlinet & cmdline
Definition ms_cl_mode.h:36
cl_message_handlert message_handler
Definition ms_cl_mode.h:37
virtual int doit()
does it.
virtual void help_mode()
display command line help
Compile and link source and object files.
bool has_prefix(const std::string &s, const std::string &prefix)
Definition converter.cpp:13
std::string get_base_name(const std::string &in, bool strip_suffix)
cleans a filename from path and extension
double log(double x)
Definition math.c:2449
static bool has_directory_suffix(const std::string &path)
Visual Studio CL Mode.