1 // Copyright (c) 2021 Google LLC.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <iostream>
16
17 #include "source/opt/log.h"
18 #include "spirv-tools/linter.hpp"
19 #include "tools/io.h"
20 #include "tools/util/cli_consumer.h"
21
22 const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;
23
24 namespace {
25 // Status and actions to perform after parsing command-line arguments.
26 enum LintActions { LINT_CONTINUE, LINT_STOP };
27
28 struct LintStatus {
29 LintActions action;
30 int code;
31 };
32
33 // Parses command-line flags. |argc| contains the number of command-line flags.
34 // |argv| points to an array of strings holding the flags.
35 //
36 // On return, this function stores the name of the input program in |in_file|.
37 // The return value indicates whether optimization should continue and a status
38 // code indicating an error or success.
ParseFlags(int argc,const char ** argv,const char ** in_file)39 LintStatus ParseFlags(int argc, const char** argv, const char** in_file) {
40 // TODO (dongja): actually parse flags, etc.
41 if (argc != 2) {
42 spvtools::Error(spvtools::utils::CLIMessageConsumer, nullptr, {},
43 "expected exactly one argument: in_file");
44 return {LINT_STOP, 1};
45 }
46
47 *in_file = argv[1];
48
49 return {LINT_CONTINUE, 0};
50 }
51 } // namespace
52
main(int argc,const char ** argv)53 int main(int argc, const char** argv) {
54 const char* in_file = nullptr;
55
56 spv_target_env target_env = kDefaultEnvironment;
57
58 spvtools::Linter linter(target_env);
59 linter.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);
60
61 LintStatus status = ParseFlags(argc, argv, &in_file);
62
63 if (status.action == LINT_STOP) {
64 return status.code;
65 }
66
67 std::vector<uint32_t> binary;
68 if (!ReadBinaryFile(in_file, &binary)) {
69 return 1;
70 }
71
72 bool ok = linter.Run(binary.data(), binary.size());
73
74 return ok ? 0 : 1;
75 }
76