CBMC
ms_cl_mode.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Visual Studio CL Mode
4 
5 Author: 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 
32 static 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 
51  compilet compiler(cmdline, message_handler, cmdline.isset("WX"));
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(
63  cmdline.get_value("verbosity"), default_verbosity, message_handler);
65 
66  ms_cl_versiont ms_cl_version;
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 
78  if(ms_cl_version.target == ms_cl_versiont::targett::x86)
80  else if(ms_cl_version.target == ms_cl_versiont::targett::ARM)
82  else if(ms_cl_version.target == ms_cl_versiont::targett::x86)
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
131  if(has_directory_suffix(Fo_value))
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(
143  compiler.mode == compilet::COMPILE_ONLY &&
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  {
155 
156  // this could be a directory
157  if(
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'))
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();
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
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 echo_file_name
Definition: compile.h:35
std::string output_file_object
Definition: compile.h:55
std::string output_directory_object
Definition: compile.h:55
bool doit()
reads and source and object files, compiles and links them into goto program objects.
Definition: compile.cpp:54
std::string object_file_extension
Definition: compile.h:51
bool validate_goto_model
Definition: compile.h:36
enum compilet::@3 mode
std::list< std::string > library_paths
Definition: compile.h:46
std::string output_file_executable
Definition: compile.h:52
bool set(const cmdlinet &cmdline)
Definition: config.cpp:863
struct configt::cppt cpp
struct configt::ansi_ct ansi_c
const std::string base_name
Definition: goto_cc_mode.h:39
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.
Definition: ms_cl_mode.cpp:42
virtual void help_mode()
display command line help
Definition: ms_cl_mode.cpp:238
void get(const std::string &executable)
enum ms_cl_versiont::targett target
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:2776
static bool has_directory_suffix(const std::string &path)
Definition: ms_cl_mode.cpp:32
Visual Studio CL Mode.
std::list< std::string > include_paths
Definition: config.h:272
void set_32()
Definition: config.cpp:32
std::list< std::string > undefines
Definition: config.h:270
void set_64()
Definition: config.cpp:37
std::list< std::string > preprocessor_options
Definition: config.h:271
std::list< std::string > defines
Definition: config.h:269
bool char_is_unsigned
Definition: config.h:150
flavourt mode
Definition: config.h:256
void set_cpp14()
Definition: config.h:326
void set_cpp11()
Definition: config.h:322