blob: 0eaf42564f84d577e970f964e7a8ae6e9a0dba4f [file] [log] [blame]
Shih-wei Liao462aefd2010-06-04 15:32:04 -07001#include "libslang.h"
2
3#include <assert.h>
4#include <getopt.h>
5
6#include <cstring>
7#include <cstdlib>
8#include <iomanip>
9#include <iostream>
10
11using namespace std;
12
13#define ERR_NO_INPUT_FILE "no input file"
14
15#define WARN(x) cerr << "warning: " WARN_ ## x << endl
16#define WARN1(x, v1) cerr << "warning: " WARN_ ## x(v1) << endl
17#define WARN2(x, v1, v2) cerr << "warning: " WARN_ ## x(v1, v2) << endl
18
19#define WARN_MULTIPLE_INPUT_FILES "multiple input files is not supported currently, only first input file will be compiled"
20
21#define WARN_UNKNOWN_CPU(v1) "the given CPU " << (v1) << " cannot be recognized, but we'll force passing it to Slang compiler"
22
23#define WARN_MISMATCH_CPU_TARGET_ARCH(v1, v2) \
24 "CPU (target: " << (v1) << ") you selected doesn't match the target of enable features you specified or the triple string you given (" << (v2) << ")"
25#define WARN_MISMATCH_FEATURE_TARGET_ARCH(v1, v2) \
26 "Feature (target: " << (v1) << ") you selected doesn't match the target of CPU you specified or the triple string you given (" << (v2) << ")"
27
28#define DEFAULT_OUTPUT_FILENAME "a.out"
29
30/* List of all support target, will look like "ArchARM" */
31#define MK_TARGET_ARCH(target) Arch ## target
32typedef enum {
33 ArchNone,
34#define DEF_SUPPORT_TARGET(target, name, default_triple) \
35 MK_TARGET_ARCH(target),
36# include "target.inc"
37
38 MaxTargetArch
39} TargetArchEnum;
40
41typedef struct {
42 TargetArchEnum Arch;
43 const char* Name;
44 const char* DefaultTriple;
45} TargetArch;
46
47static const TargetArch TargetArchTable[] = {
48 { ArchNone, "none", "unknown-unknown-linux" },
49#define DEF_SUPPORT_TARGET(target, name, default_triple) \
50 { MK_TARGET_ARCH(target), name, default_triple },
51# include "target.inc"
52};
53
54#if defined(__arm__)
55# define HOST_ARCH MK_TARGET_ARCH(X86)
56#elif defined(__i386__)
57# define HOST_ARCH MK_TARGET_ARCH(ARM)
58#elif defined(__x86_64__)
59# define HOST_ARCH MK_TARGET_ARCH(X64)
60#else
61# error "We can not find default triple string for your host machine, please define it by yourself via option '--triple' or '-t'"
62#endif
63
64#define DEFAULT_TARGET_TRIPLE_STRING TargetArchTable[HOST_ARCH].DefaultTriple
65
66/* Lists of all target features, will look like "{Target}FeatureNEON" */
67#define MK_TARGET_FEATURE(target, id) target ## id
68typedef enum {
69 FeatureNone = 0,
70#define DEF_TARGET_FEATURE(target, id, key, description) \
71 MK_TARGET_FEATURE(target, id),
72#define HOOK_TARGET_FIRST_FEATURE(target, id, key, description) \
73 target ## FeatureStart, \
74 MK_TARGET_FEATURE(target, id) = target ## FeatureStart,
75# include "target.inc"
76
77 MaxTargetFeature
78} TargetFeatureEnum;
79
80/* Feature as bits using in {Target}TargetCPU, will look like "X{Target}FeatureNEON" */
81#define MK_TARGET_FEATURE_BIT(target, id) X ## target ## id
82typedef enum {
83 XFeatureNone = 0,
84#define DEF_TARGET_FEATURE(target, id, key, description) \
85 MK_TARGET_FEATURE_BIT(target, id) = 1 << (MK_TARGET_FEATURE(target, id) - target ## FeatureStart),
86# include "target.inc"
87
88 XMaxTargetFeature
89} TargetFeatureBit;
90
91typedef struct {
92 TargetArchEnum Arch;
93 TargetFeatureEnum Key;
94 TargetFeatureBit Bit;
95 const char* Name;
96 const char* Desc;
97} TargetFeature;
98
99/* Should be 1-1 mapping with TargetFeatureEnum */
100static const TargetFeature TargetFeatureTable[] = {
101 { ArchNone, FeatureNone, XFeatureNone, "none", "Empty feature" }, /* FeatureNone */
102#define DEF_TARGET_FEATURE(target, id, key, description) \
103 { MK_TARGET_ARCH(target), MK_TARGET_FEATURE(target, id), MK_TARGET_FEATURE_BIT(target, id), key, description },
104# include "target.inc"
105};
106
107typedef struct {
108 TargetArchEnum Arch;
109 const char* Name;
110 const char* Desc;
111 unsigned int FeatureEnabled;
112} TargetCPU;
113
114/* Sorted by CPU name such that we can call bsearch() to quickly retain the CPU entry corresponding to the name */
115#define E(feature) MK_TARGET_FEATURE_BIT(ARM, feature)
116static const TargetCPU TargetCPUTable[] = {
117 { MK_TARGET_ARCH(ARM), "arm1020e", "Select the arm1020e processor", E(ArchV5TE) },
118 { MK_TARGET_ARCH(ARM), "arm1020t", "Select the arm1020t processor", E(ArchV5T) },
119 { MK_TARGET_ARCH(ARM), "arm1022e", "Select the arm1022e processor", E(ArchV5TE) },
120 { MK_TARGET_ARCH(ARM), "arm10e", "Select the arm10e processor", E(ArchV5TE) },
121 { MK_TARGET_ARCH(ARM), "arm10tdmi", "Select the arm10tdmi processor", E(ArchV5T) },
122 { MK_TARGET_ARCH(ARM), "arm1136j-s", "Select the arm1136j-s processor", E(ArchV6) },
123 { MK_TARGET_ARCH(ARM), "arm1136jf-s", "Select the arm1136jf-s processor", E(ArchV6) | E(FeatureVFP2) },
124 { MK_TARGET_ARCH(ARM), "arm1156t2-s", "Select the arm1156t2-s processor", E(ArchV6T2) | E(FeatureThumb2) },
125 { MK_TARGET_ARCH(ARM), "arm1156t2f-s", "Select the arm1156t2f-s processor", E(ArchV6T2) | E(FeatureThumb2) | E(FeatureVFP2) },
126 { MK_TARGET_ARCH(ARM), "arm1176jz-s", "Select the arm1176jz-s processor", E(ArchV6) },
127 { MK_TARGET_ARCH(ARM), "arm1176jzf-s", "Select the arm1176jzf-s processor", E(ArchV6) | E(FeatureVFP2) },
128 { MK_TARGET_ARCH(ARM), "arm710t", "Select the arm710t processor", E(ArchV4T) },
129 { MK_TARGET_ARCH(ARM), "arm720t", "Select the arm720t processor", E(ArchV4T) },
130 { MK_TARGET_ARCH(ARM), "arm7tdmi", "Select the arm7tdmi processor", E(ArchV4T) },
131 { MK_TARGET_ARCH(ARM), "arm7tdmi-s", "Select the arm7tdmi-s processor", E(ArchV4T) },
132 { MK_TARGET_ARCH(ARM), "arm8", "Select the arm8 processor", XFeatureNone },
133 { MK_TARGET_ARCH(ARM), "arm810", "Select the arm810 processor", XFeatureNone },
134 { MK_TARGET_ARCH(ARM), "arm9", "Select the arm9 processor", E(ArchV4T) },
135 { MK_TARGET_ARCH(ARM), "arm920", "Select the arm920 processor", E(ArchV4T) },
136 { MK_TARGET_ARCH(ARM), "arm920t", "Select the arm920t processor", E(ArchV4T) },
137 { MK_TARGET_ARCH(ARM), "arm922t", "Select the arm922t processor", E(ArchV4T) },
138 { MK_TARGET_ARCH(ARM), "arm926ej-s", "Select the arm926ej-s processor", E(ArchV5TE) },
139 { MK_TARGET_ARCH(ARM), "arm940t", "Select the arm940t processor", E(ArchV4T) },
140 { MK_TARGET_ARCH(ARM), "arm946e-s", "Select the arm946e-s processor", E(ArchV5TE) },
141 { MK_TARGET_ARCH(ARM), "arm966e-s", "Select the arm966e-s processor", E(ArchV5TE) },
142 { MK_TARGET_ARCH(ARM), "arm968e-s", "Select the arm968e-s processor", E(ArchV5TE) },
143 { MK_TARGET_ARCH(ARM), "arm9e", "Select the arm9e processor", E(ArchV5TE) },
144 { MK_TARGET_ARCH(ARM), "arm9tdmi", "Select the arm9tdmi processor", E(ArchV4T) },
145 { MK_TARGET_ARCH(ARM), "cortex-a8", "Select the cortex-a8 processor", E(ArchV7A) | E(FeatureThumb2) | E(FeatureNEON) },
146 { MK_TARGET_ARCH(ARM), "cortex-a9", "Select the cortex-a9 processor", E(ArchV7A) | E(FeatureThumb2) | E(FeatureNEON) },
147 { MK_TARGET_ARCH(ARM), "ep9312", "Select the ep9312 processor", E(ArchV4T) },
148 { MK_TARGET_ARCH(ARM), "generic", "Select the generic processor", XFeatureNone },
149 { MK_TARGET_ARCH(ARM), "iwmmxt", "Select the iwmmxt processor", E(ArchV5TE) },
150 { MK_TARGET_ARCH(ARM), "mpcore", "Select the mpcore processor", E(ArchV6) | E(FeatureVFP2) },
151 { MK_TARGET_ARCH(ARM), "mpcorenovfp", "Select the mpcorenovfp processor", E(ArchV6) },
152 { MK_TARGET_ARCH(ARM), "strongarm", "Select the strongarm processor", XFeatureNone },
153 { MK_TARGET_ARCH(ARM), "strongarm110", "Select the strongarm110 processor", XFeatureNone },
154 { MK_TARGET_ARCH(ARM), "strongarm1100", "Select the strongarm1100 processor", XFeatureNone },
155 { MK_TARGET_ARCH(ARM), "strongarm1110", "Select the strongarm1110 processor", XFeatureNone },
156 { MK_TARGET_ARCH(ARM), "xscale", "Select the xscale processor", MK_TARGET_FEATURE_BIT(ARM, ArchV5TE) }
157};
158#undef E
159static int CompareCPUName(const void* a, const void* b) {
160 return strcasecmp(((TargetCPU*) a)->Name, ((TargetCPU*) b)->Name);
161}
162#define NUM_TARGET_CPU (sizeof(TargetCPUTable) / sizeof(TargetCPU))
163
164static struct option* SlangOpts = NULL;
165
166static const char* CPUString;
167static const TargetCPU* CPU;
168static const char* TripleString;
169static TargetFeatureEnum EnableFeatureValue, DisableFeatureValue;
170static SlangCompilerOutputTy OutputFileType;
171static const char* OutputFileName;
172static const char* JavaReflectionPackageName;
173static const char* InputFileName;
174static bool Verbose;
175static const char* FeatureEnabledList[MaxTargetFeature + 1];
Kirk Stewart1fd85792010-07-07 09:51:23 -0700176static int AllowRSPrefix = 0;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700177
178/* Construct the command options table used in ParseOption::getopt_long */
179static void ConstructCommandOptions() {
180 /* Basic slang command option */
181 static struct option BasicSlangOpts[] = {
Kirk Stewart1fd85792010-07-07 09:51:23 -0700182 { "allow-rs-prefix", no_argument, &AllowRSPrefix, 1 },
183
184 { "emit-llvm", no_argument, (int*) &OutputFileType, SlangCompilerOutput_LL },
185 { "emit-bc", no_argument, (int*) &OutputFileType, SlangCompilerOutput_Bitcode },
186 { "emit-asm", no_argument, NULL, 'S' },
187 { "emit-obj", no_argument, NULL, 'c' },
188 { "emit-nothing", no_argument, (int*) &OutputFileType, SlangCompilerOutput_Nothing },
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700189
190 { "help", no_argument, NULL, 'h' }, /* -h */
191 { "verbose", no_argument, NULL, 'v' }, /* -v */
192
193 { "output", required_argument, NULL, 'o' }, /* -o */
194 { "cpu", required_argument, NULL, 'u' }, /* -u */
195 { "triple", required_argument, NULL, 't' }, /* -t */
196
197 { "output-java-reflection-class", required_argument, NULL, 'j'} /* -j */
198 };
199
200 const int NumberOfBasicOptions = sizeof(BasicSlangOpts) / sizeof(struct option);
201
202 SlangOpts = new struct option [ NumberOfBasicOptions + MaxTargetFeature * 2 /* for --enable-feature and --disable-feature */ ];
203
204 /* Fill SlangOpts with basic options */
205 memcpy(SlangOpts, BasicSlangOpts, sizeof(BasicSlangOpts));
206
207 int i = NumberOfBasicOptions;
208 /* Add --enable-TARGET_FEATURE option into slang command option */
209#define DEF_TARGET_FEATURE(target, id, key, description) \
210 SlangOpts[i].name = "enable-" key; \
211 SlangOpts[i].has_arg = optional_argument; \
212 SlangOpts[i].flag = (int*) &EnableFeatureValue; \
213 SlangOpts[i].val = target ## id; \
214 i++;
215# include "target.inc"
216
217 /* Add --disable-TARGET_FEATURE option into slang command option */
218#define DEF_TARGET_FEATURE(target, id, key, description) \
219 SlangOpts[i].name = "disable-" key; \
220 SlangOpts[i].has_arg = optional_argument; \
221 SlangOpts[i].flag = (int*) &DisableFeatureValue; \
222 SlangOpts[i].val = target ## id; \
223 i++;
224# include "target.inc"
225
226 /* NULL-terminated the SlangOpts */
227 memset(&SlangOpts[i], 0, sizeof(struct option));
228
229 return;
230}
231
232extern char *optarg;
233extern int optind;
234extern int optopt;
235extern int opterr;
236
237static void Usage(const char* CommandName) {
238#define OUTPUT_OPTION(short_name, long_name, desc) \
239 do { \
240 if(short_name) \
241 cout << setw(4) << right << (short_name) << ", "; \
242 else \
243 cout << " "; \
244 cout << setw(17) << left << (long_name); \
245 cout << " " << (desc) << endl; \
246 } while(false)
247
248 cout << "Usage: " << CommandName << " [OPTION]... " << "[INPUT FILE]" << endl;
249
250 cout << endl;
251
252 cout << "Basic: " << endl;
253
254 OUTPUT_OPTION("-h", "--help", "print this help");
Kirk Stewart1fd85792010-07-07 09:51:23 -0700255 OUTPUT_OPTION("-v", "--verbose", "be verbose");
256 OUTPUT_OPTION(NULL, "--allow-rs-prefix", "Allow user-defined function names with the \"rs\" prefix");
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700257 OUTPUT_OPTION("-o", "--output=<FILE>", "write the output of compilation to FILE ('-' means stdout)");
258 OUTPUT_OPTION("-j", "--output-java-reflection-package=<PACKAGE NAME>", "output reflection to Java for BCC exportables");
259
260 cout << endl;
261
262 cout << "Output type:" << endl;
263
264 OUTPUT_OPTION(NULL, "--emit-llvm", "set output type to LLVM assembly (.ll)");
265 OUTPUT_OPTION(NULL, "--emit-bc", "set output type to Bitcode (.bc) (Default)");
266 OUTPUT_OPTION("-S", "--emit-asm", "set output type to target assmbly code (.S)");
267 OUTPUT_OPTION("-c", "--emit-obj", "set output type to target object file (.o)");
268 OUTPUT_OPTION(NULL, "--emit-nothing", "output nothing");
269
270 cout << endl;
271
272 cout << "Code generation option: " << endl;
273
274 OUTPUT_OPTION("-u", "--cpu=CPU", "generate the assembly / object file for the CPU");
275 cout << endl;
276 cout << "\tAvailable CPU:" << endl;
277
278 for(int i=0;i<NUM_TARGET_CPU;i++)
279 cout << "\t" << setw(13) << right << TargetCPUTable[i].Name << left << ": (" << TargetArchTable[(TargetCPUTable[i].Arch)].Name << ") " << TargetCPUTable[i].Desc << endl;
280
281 cout << endl;
282
283 OUTPUT_OPTION("-t", "--triple=TRIPLE", "generate the assembly / object file for the Triple");
284 cout << "\tDefault triple: " << endl;
285#define DEF_SUPPORT_TARGET(target, name, default_triple) \
286 cout << "\t" << setw(5) << right << name << left << ": " << default_triple << endl;
287#include "target.inc"
288 cout << endl;
289
290 OUTPUT_OPTION(NULL, "--enable-FEATURE", "enable the FEATURE for the generation of the assembly / object file");
291 OUTPUT_OPTION(NULL, "--disable-FEATURE", "disable the FEATURE for the generation of the assembly / object file");
292 cout << endl;
293 cout << "\tAvailable features:" << endl;
294#define DEF_TARGET_FEATURE(target, id, key, description) \
295 cout << "\t" << setw(6) << right << key \
296 << left << ": (" << TargetArchTable[MK_TARGET_ARCH(target)].Name << ") " \
297 << description << endl;
298#include "target.inc"
299
300
301 cout << endl;
302
303
304#undef OUTPUT_OPTION
305 return;
306}
307
308static bool ParseOption(int Argc, char** Argv) {
309 assert(SlangOpts != NULL && "Slang command options table was not initialized!");
310
311 /* Set default value to option */
312 CPU = NULL;
313 TripleString = DEFAULT_TARGET_TRIPLE_STRING;
314 EnableFeatureValue = DisableFeatureValue = FeatureNone;
315 OutputFileType = SlangCompilerOutput_Default;
316 OutputFileName = DEFAULT_OUTPUT_FILENAME;
317 JavaReflectionPackageName = NULL;
318 InputFileName = NULL;
319 Verbose = false;
320 FeatureEnabledList[0] = NULL;
321
322 int ch;
323
324 unsigned int FeatureEnableBits = 0;
325 unsigned int FeatureDisableBits = 0;
326#define ENABLE_FEATURE(x) \
327 FeatureEnableBits |= (x)
328#define DISABLE_FEATURE(x) \
329 FeatureDisableBits |= (x)
330 TargetArchEnum ExpectedArch = ArchNone;
331
332 /* Turn off the error message output by getopt_long */
333 opterr = 0;
334
335 while((ch = getopt_long(Argc, Argv, "Schvo:u:t:j:", SlangOpts, NULL)) != -1) {
336 switch(ch) {
337 case 'S':
338 OutputFileType = SlangCompilerOutput_Assembly;
339 break;
340
341 case 'c':
342 OutputFileType = SlangCompilerOutput_Obj;
343 break;
344
345 case 'o':
346 OutputFileName = optarg;
347 break;
348
349 case 'j':
350 JavaReflectionPackageName = optarg;
351 break;
352
353 case 'u':
354 {
355 CPUString = optarg;
356 const TargetCPU SearchCPU = { ArchNone, CPUString, NULL, XFeatureNone };
357 CPU = (TargetCPU*) bsearch(&SearchCPU, TargetCPUTable, sizeof(TargetCPUTable) / sizeof(TargetCPU), sizeof(TargetCPU), CompareCPUName);
358 if(CPU == NULL) {
359 WARN1(UNKNOWN_CPU, SearchCPU.Name);
360 } else {
361 CPUString = CPU->Name;
362
363 if(ExpectedArch == ArchNone)
364 ExpectedArch = CPU->Arch;
365 else if(ExpectedArch != CPU->Arch) {
366 WARN2(MISMATCH_CPU_TARGET_ARCH, TargetArchTable[CPU->Arch].Name, TargetArchTable[ExpectedArch].Name);
367 break;
368 }
369
370 /* Get CPU Feature and enable its available feature */
371 FeatureEnableBits |= CPU->FeatureEnabled;
372 }
373 }
374 break;
375
376 case 't':
377 TripleString = optarg;
378 break;
379
380 case 'h':
381 Usage(Argv[0]);
382 return false;
383 break;
384
385 case 'v':
386 Verbose = true;
387 break;
388
389 case 0:
390 {
391 if(EnableFeatureValue != FeatureNone || DisableFeatureValue != FeatureNone) {
392 bool IsDisable = (DisableFeatureValue != FeatureNone);
393 const TargetFeature* FeatureSelected = &TargetFeatureTable[ ((IsDisable) ? DisableFeatureValue : EnableFeatureValue) ];
394 assert(FeatureSelected != NULL && "Unexpected target feature! (not presented in table but parsed!?)");
395
396 if(ExpectedArch == ArchNone)
397 ExpectedArch = FeatureSelected->Arch;
398 else if(FeatureSelected->Arch != ExpectedArch) {
399 WARN2(MISMATCH_FEATURE_TARGET_ARCH, TargetArchTable[FeatureSelected->Arch].Name, TargetArchTable[ExpectedArch].Name);
400 break;
401 }
402
403 if(optarg != NULL && atoi(optarg) == 0)
404 IsDisable = !IsDisable;
405
406 if(IsDisable)
407 DISABLE_FEATURE(FeatureSelected->Bit);
408 else
409 ENABLE_FEATURE(FeatureSelected->Bit);
410 }
411 }
412 break;
413
414 default:
415 cerr << "Unknown option: " << Argv[optind - 1] << endl;
416 return false;
417 break;
418 }
419 }
420#undef ENABLE_FEATURE
421#undef DISABLE_FEATURE
422
423 int CurFeatureEnableListIdx = 0;
424 /* Add the enable/disable feature string to */
425 switch(ExpectedArch) {
426 case ArchNone:
427 ExpectedArch = HOST_ARCH;
428 break;
429
430#define DEF_TARGET_FEATURE(target, id, key, description) \
431 if(FeatureDisableBits & MK_TARGET_FEATURE_BIT(target, id)) \
432 FeatureEnabledList[ CurFeatureEnableListIdx++ ] = "-" key; \
433 else if(FeatureEnableBits & MK_TARGET_FEATURE_BIT(target, id)) \
434 FeatureEnabledList[ CurFeatureEnableListIdx++ ] = "+" key;
435#define HOOK_TARGET_FIRST_FEATURE(target, id, key, description) \
436 case Arch ## target: \
437 /* Fix target triple */ \
438 if(TripleString == DEFAULT_TARGET_TRIPLE_STRING) \
439 TripleString = TargetArchTable[MK_TARGET_ARCH(target)].DefaultTriple; \
440 DEF_TARGET_FEATURE(target, id, key, description)
441#define HOOK_TARGET_LAST_FEATURE(target, id, key, description) \
442 DEF_TARGET_FEATURE(target, id, key, description) \
443 FeatureEnabledList[ CurFeatureEnableListIdx++ ] = NULL; /* null-terminator */ \
444 break;
445#include "target.inc"
446
447 default:
448 assert(false && "Unknown / Unsupported CPU architecture");
449 break;
450 }
451
452 Argc -= optind;
453 if(Argc <= 0) {
454 cerr << Argv[0] << ": "ERR_NO_INPUT_FILE << endl;
455 return false;
456 }
457
458 if(Argc > 1)
459 WARN(MULTIPLE_INPUT_FILES);
460 InputFileName = Argv[optind];
461
462 if(Verbose) {
463 cout << "Input: " << InputFileName << endl;
464
465 if(CPU != NULL)
466 cout << "Use CPU: " << CPU->Name << endl;
467 cout << "Use triple string: " << TripleString << endl;
468 cout << "Expected architecture: " << TargetArchTable[ExpectedArch].Name << endl;
469
470 cout << "Enable target feature: " << endl;
471 for(int i=0;FeatureEnabledList[i]!=NULL;i++)
472 if(*FeatureEnabledList[i] == '+')
473 cout << "\t" << &FeatureEnabledList[i][1] << endl;
474 cout << endl;
475
476 cout << "Disable target feature: " << endl;
477 for(int i=0;FeatureEnabledList[i]!=NULL;i++)
478 if(*FeatureEnabledList[i] == '-')
479 cout << "\t" << &FeatureEnabledList[i][1] << endl;
480 cout << endl;
481
482 cout << "Output to: " << ((strcmp(OutputFileName, "-")) ? OutputFileName : "(standard output)") << ", type: ";
483 switch(OutputFileType) {
484 case SlangCompilerOutput_Assembly: cout << "Target Assembly"; break;
485 case SlangCompilerOutput_LL: cout << "LLVM Assembly"; break;
486 case SlangCompilerOutput_Bitcode: cout << "Bitcode"; break;
487 case SlangCompilerOutput_Nothing: cout << "No output (test)"; break;
488 case SlangCompilerOutput_Obj: cout << "Object file"; break;
489 default: assert(false && "Unknown output type"); break;
490 }
491 cout << endl;
492 }
493
494 return true;
495}
496
497static void DestroyCommandOptions() {
498 if(SlangOpts != NULL) {
499 delete [] SlangOpts;
500 SlangOpts = NULL;
501 }
502 return;
503}
504
505#define SLANG_CALL_AND_CHECK(expr) \
506 if(!(expr)) { \
507 if(slangGetInfoLog(slang)) \
508 cerr << slangGetInfoLog(slang); \
Shih-wei Liaoc552b7c2010-06-25 11:06:57 -0700509 ret = 1; \
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700510 goto on_slang_error; \
511 }
512
513int main(int argc, char** argv) {
Shih-wei Liaoc552b7c2010-06-25 11:06:57 -0700514 int ret = 0;
515
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700516 if(argc < 2) {
517 cerr << argv[0] << ": "ERR_NO_INPUT_FILE << endl;
518 return 1;
519 }
520
521 ConstructCommandOptions();
522
523 if(ParseOption(argc, argv)) {
524 /* Start compilation */
525 SlangCompiler* slang = slangCreateCompiler(TripleString, CPUString, FeatureEnabledList);
526 if(slang != NULL) {
527 SLANG_CALL_AND_CHECK( slangSetSourceFromFile(slang, InputFileName) );
528
529 slangSetOutputType(slang, OutputFileType);
530
Kirk Stewart1fd85792010-07-07 09:51:23 -0700531 if (AllowRSPrefix)
532 slangAllowRSPrefix();
533
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700534 SLANG_CALL_AND_CHECK( slangSetOutputToFile(slang, OutputFileName) );
535
536 SLANG_CALL_AND_CHECK( slangCompile(slang) <= 0 );
537
538 /* output log anyway */
539 if(slangGetInfoLog(slang))
540 cout << slangGetInfoLog(slang);
541
Shih-wei Liao537446c2010-06-11 16:05:55 -0700542 SLANG_CALL_AND_CHECK( slangReflectToJava(slang, JavaReflectionPackageName) );
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700543
544on_slang_error:
545 delete slang;
546 }
547 }
548
549 DestroyCommandOptions();
550
Shih-wei Liaoc552b7c2010-06-25 11:06:57 -0700551 return ret;
Shih-wei Liao462aefd2010-06-04 15:32:04 -0700552}