| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2025 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include <llvm/TargetParser/Triple.h> | ||
| 6 | |||
| 7 | #include "../../lib/cli11/CLI11.hpp" | ||
| 8 | |||
| 9 | // Undef conflicting macros (only problematic on Windows) | ||
| 10 | #undef TRUE | ||
| 11 | #undef FALSE | ||
| 12 | #undef CONST | ||
| 13 | |||
| 14 | namespace spice::compiler { | ||
| 15 | |||
| 16 | const char *const TARGET_UNKNOWN = "unknown"; | ||
| 17 | const char *const TARGET_WASM32 = "wasm32"; | ||
| 18 | const char *const TARGET_WASM64 = "wasm64"; | ||
| 19 | const char *const ENV_VAR_DOCKERIZED = "SPICE_DOCKERIZED"; | ||
| 20 | |||
| 21 | enum class OptLevel : uint8_t { | ||
| 22 | O0 = 0, // No optimization | ||
| 23 | O1 = 1, // Only basic optimizations | ||
| 24 | O2 = 2, // Default optimization level | ||
| 25 | O3 = 3, // Aggressively optimize for performance | ||
| 26 | Os = 4, // Optimize for code size | ||
| 27 | Oz = 5, // Aggressively optimize for code size | ||
| 28 | }; | ||
| 29 | |||
| 30 | enum class Sanitizer : uint8_t { | ||
| 31 | NONE = 0, // No sanitizer | ||
| 32 | ADDRESS = 1, // Sanitize memory accesses | ||
| 33 | THREAD = 2, // Sanitize threads for data race prevention | ||
| 34 | MEMORY = 3, // Sanitize against uninitialized memory reads | ||
| 35 | }; | ||
| 36 | const char *const SANITIZER_NONE = "none"; | ||
| 37 | const char *const SANITIZER_ADDRESS = "address"; | ||
| 38 | const char *const SANITIZER_THREAD = "thread"; | ||
| 39 | const char *const SANITIZER_MEMORY = "memory"; | ||
| 40 | |||
| 41 | enum class BuildMode : uint8_t { | ||
| 42 | DEBUG = 0, // Default build mode, uses -O0 per default | ||
| 43 | RELEASE = 1, // Build without debug information and with -O2 per default | ||
| 44 | TEST = 2, // Build with test main function and always emit assertions | ||
| 45 | }; | ||
| 46 | const char *const BUILD_MODE_DEBUG = "debug"; | ||
| 47 | const char *const BUILD_MODE_RELEASE = "release"; | ||
| 48 | const char *const BUILD_MODE_TEST = "test"; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Representation of the various cli options | ||
| 52 | */ | ||
| 53 | struct CliOptions { | ||
| 54 | std::filesystem::path mainSourceFile; // e.g. ./main.spice | ||
| 55 | llvm::Triple targetTriple; // In format: <arch><sub>-<vendor>-<sys>-<abi> | ||
| 56 | std::string targetArch = TARGET_UNKNOWN; | ||
| 57 | std::string targetVendor = TARGET_UNKNOWN; | ||
| 58 | std::string targetOs = TARGET_UNKNOWN; | ||
| 59 | bool isNativeTarget = true; | ||
| 60 | bool useCPUFeatures = true; | ||
| 61 | bool execute = false; | ||
| 62 | std::filesystem::path cacheDir; // Where the cache files go. Should always be a temp directory | ||
| 63 | std::filesystem::path outputDir = "./"; // Where the object files go. Should always be a temp directory | ||
| 64 | std::filesystem::path outputPath; // Where the output binary goes. | ||
| 65 | BuildMode buildMode = BuildMode::DEBUG; // Default build mode is debug | ||
| 66 | unsigned short compileJobCount = 0; // 0 for auto | ||
| 67 | bool ignoreCache = false; | ||
| 68 | std::string llvmArgs; | ||
| 69 | bool printDebugOutput = false; | ||
| 70 | struct DumpSettings { | ||
| 71 | bool dumpCST = false; | ||
| 72 | bool dumpAST = false; | ||
| 73 | bool dumpSymbolTable = false; | ||
| 74 | bool dumpTypes = false; | ||
| 75 | bool dumpCacheStats = false; | ||
| 76 | bool dumpDependencyGraph = false; | ||
| 77 | bool dumpIR = false; | ||
| 78 | bool dumpAssembly = false; | ||
| 79 | bool dumpObjectFiles = false; | ||
| 80 | bool dumpToFiles = false; | ||
| 81 | bool abortAfterDump = false; | ||
| 82 | } dump; | ||
| 83 | bool namesForIRValues = false; | ||
| 84 | bool useLifetimeMarkers = false; | ||
| 85 | bool useTBAAMetadata = false; | ||
| 86 | OptLevel optLevel = OptLevel::O0; // The default optimization level for debug build mode is O0 | ||
| 87 | bool useLTO = false; | ||
| 88 | bool noEntryFct = false; | ||
| 89 | bool generateTestMain = false; | ||
| 90 | bool staticLinking = false; | ||
| 91 | struct InstrumentationSettings { | ||
| 92 | bool generateDebugInfo = false; | ||
| 93 | Sanitizer sanitizer = Sanitizer::NONE; | ||
| 94 | } instrumentation; | ||
| 95 | bool disableVerifier = false; | ||
| 96 | bool testMode = false; | ||
| 97 | bool comparableOutput = false; | ||
| 98 | }; | ||
| 99 | |||
| 100 | /** | ||
| 101 | * Helper class to set up the driver and command line parser | ||
| 102 | */ | ||
| 103 | class Driver { | ||
| 104 | public: | ||
| 105 | // Constructors | ||
| 106 | ✗ | Driver() = default; | |
| 107 |
7/26✓ Branch 6 → 7 taken 8 times.
✗ Branch 6 → 50 not taken.
✓ Branch 9 → 10 taken 8 times.
✗ Branch 9 → 44 not taken.
✓ Branch 12 → 13 taken 8 times.
✗ Branch 12 → 38 not taken.
✓ Branch 14 → 15 taken 8 times.
✗ Branch 14 → 32 not taken.
✓ Branch 22 → 23 taken 8 times.
✗ Branch 22 → 67 not taken.
✓ Branch 25 → 26 taken 8 times.
✗ Branch 25 → 61 not taken.
✓ Branch 26 → 27 taken 8 times.
✗ Branch 26 → 59 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 34 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 37 not taken.
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 43 not taken.
✗ Branch 47 → 48 not taken.
✗ Branch 47 → 49 not taken.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
✗ Branch 56 → 57 not taken.
✗ Branch 56 → 58 not taken.
|
64 | explicit Driver(bool dryRun) : dryRun(dryRun) {} |
| 108 | Driver(const Driver &) = delete; | ||
| 109 | |||
| 110 | // Public methods | ||
| 111 | void init(); | ||
| 112 | int parse(int argc, const char *argv[]); | ||
| 113 | void enrich(); | ||
| 114 | void runBinary() const; | ||
| 115 | |||
| 116 | // Public members | ||
| 117 | CliOptions cliOptions = {}; | ||
| 118 | bool shouldCompile = false; | ||
| 119 | bool shouldInstall = false; | ||
| 120 | bool shouldUninstall = false; | ||
| 121 | bool shouldExecute = false; | ||
| 122 | bool dryRun = false; // For unit testing purposes | ||
| 123 | |||
| 124 | private: | ||
| 125 | // Private methods | ||
| 126 | void addBuildSubcommand(); | ||
| 127 | void addRunSubcommand(); | ||
| 128 | void addTestSubcommand(); | ||
| 129 | void addInstallSubcommand(); | ||
| 130 | void addUninstallSubcommand(); | ||
| 131 | void addCompileSubcommandOptions(CLI::App *subCmd); | ||
| 132 | void addInstrumentationOptions(CLI::App *subCmd); | ||
| 133 | static void ensureNotDockerized(); | ||
| 134 | |||
| 135 | // Members | ||
| 136 | CLI::App app = CLI::App{"Spice Programming Language", "spice"}; | ||
| 137 | }; | ||
| 138 | |||
| 139 | } // namespace spice::compiler | ||
| 140 |