1 //===--- TestClangConfig.h ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TESTING_TESTCLANGCONFIG_H 10 #define LLVM_CLANG_TESTING_TESTCLANGCONFIG_H 11 12 #include "clang/Testing/CommandLineArgs.h" 13 #include "llvm/Support/raw_ostream.h" 14 #include <string> 15 #include <vector> 16 17 namespace clang { 18 19 /// A Clang configuration for end-to-end tests that can be converted to 20 /// command line arguments for the driver. 21 /// 22 /// The configuration is represented as typed, named values, making it easier 23 /// and safer to work with compared to an array of string command line flags. 24 struct TestClangConfig { 25 TestLanguage Language; 26 27 /// The argument of the `-target` command line flag. 28 std::string Target; 29 30 bool isC() const { 31 return false 32 #define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ 33 || Language == Lang_##lang##version 34 #include "clang/Testing/TestLanguage.def" 35 ; 36 } 37 38 bool isC(int Version) const { 39 return false 40 #define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ 41 || (Version == version && Language == Lang_##lang##version) 42 #include "clang/Testing/TestLanguage.def" 43 ; 44 } 45 46 bool isCOrLater(int MinimumStdVersion) const { 47 const auto MinimumStdVersionIndex = 0 48 #define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ 49 +(MinimumStdVersion == version ? version_index : 0) 50 #include "clang/Testing/TestLanguage.def" 51 ; 52 switch (Language) { 53 #define TESTLANGUAGE_C(lang, version, std_flag, version_index) \ 54 case Lang_##lang##version: \ 55 return MinimumStdVersionIndex <= version_index; 56 #include "clang/Testing/TestLanguage.def" 57 default: 58 return false; 59 } 60 } 61 62 bool isC99OrLater() const { return isCOrLater(99); } 63 64 bool isCOrEarlier(int MaximumStdVersion) const { 65 return isC() && (isC(MaximumStdVersion) || !isCOrLater(MaximumStdVersion)); 66 } 67 68 bool isCXX() const { 69 return false 70 #define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ 71 || Language == Lang_##lang##version 72 #include "clang/Testing/TestLanguage.def" 73 ; 74 } 75 76 bool isCXX(int Version) const { 77 return false 78 #define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ 79 || (Version == version && Language == Lang_##lang##version) 80 #include "clang/Testing/TestLanguage.def" 81 ; 82 } 83 84 bool isCXXOrLater(int MinimumStdVersion) const { 85 const auto MinimumStdVersionIndex = 0 86 #define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ 87 +(MinimumStdVersion == version ? version_index : 0) 88 #include "clang/Testing/TestLanguage.def" 89 ; 90 switch (Language) { 91 #define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \ 92 case Lang_##lang##version: \ 93 return MinimumStdVersionIndex <= version_index; 94 #include "clang/Testing/TestLanguage.def" 95 default: 96 return false; 97 } 98 } 99 100 bool isCXX11OrLater() const { return isCXXOrLater(11); } 101 102 bool isCXX14OrLater() const { return isCXXOrLater(14); } 103 104 bool isCXX17OrLater() const { return isCXXOrLater(17); } 105 106 bool isCXX20OrLater() const { return isCXXOrLater(20); } 107 108 bool isCXX23OrLater() const { return isCXXOrLater(23); } 109 110 bool isCXXOrEarlier(int MaximumStdVersion) const { 111 return isCXX() && 112 (isCXX(MaximumStdVersion) || !isCXXOrLater(MaximumStdVersion)); 113 } 114 115 bool supportsCXXDynamicExceptionSpecification() const { 116 return Language == Lang_CXX03 || Language == Lang_CXX11 || 117 Language == Lang_CXX14; 118 } 119 120 bool hasDelayedTemplateParsing() const { 121 return Target == "x86_64-pc-win32-msvc"; 122 } 123 124 std::vector<std::string> getCommandLineArgs() const { 125 std::vector<std::string> Result = getCommandLineArgsForTesting(Language); 126 Result.push_back("-target"); 127 Result.push_back(Target); 128 return Result; 129 } 130 131 std::string toShortString() const { 132 std::string Result; 133 llvm::raw_string_ostream OS(Result); 134 switch (Language) { 135 #define TESTLANGUAGE(lang, version, std_flag, version_index) \ 136 case Lang_##lang##version: \ 137 OS << (#lang #version); \ 138 break; 139 #include "clang/Testing/TestLanguage.def" 140 case Lang_OpenCL: 141 OS << "OpenCL"; 142 break; 143 case Lang_OBJC: 144 OS << "OBJC"; 145 break; 146 case Lang_OBJCXX: 147 OS << "OBJCXX"; 148 break; 149 } 150 151 OS << (Target.find("win") != std::string::npos ? "_win" : ""); 152 return Result; 153 } 154 155 std::string toString() const { 156 std::string Result; 157 llvm::raw_string_ostream OS(Result); 158 OS << "{ Language=" << Language << ", Target=" << Target << " }"; 159 return Result; 160 } 161 162 friend std::ostream &operator<<(std::ostream &OS, 163 const TestClangConfig &ClangConfig) { 164 return OS << ClangConfig.toString(); 165 } 166 }; 167 168 } // end namespace clang 169 170 #endif 171