Skip to content

Commit

Permalink
[clang][test] add TestLanguage.def to specify all tested language ver…
Browse files Browse the repository at this point in the history
…sions

Adds a def file to have a single location where tested language versions are
specified. Removes the need to update multiple locations in the testing
infrastructure to add a new language version to be tested.
Test instatiation can now include all languages without needing to
specify them.
This patch also adds pretty printing for instantiated test names.
That means, that a test instantiated with C++23 will have the
name `...TestSuite/TestName/CXX23` instead ending with some number
(index of the argument for instantiation of the test), which improves a
better experience when encountering a test failure with a specific
language version. The suffix will also contain an `_win` if the target
contains `win`.
  • Loading branch information
5chmidti committed Jun 3, 2024
1 parent b301a98 commit 1c6f2a0
Show file tree
Hide file tree
Showing 12 changed files with 280 additions and 149 deletions.
17 changes: 8 additions & 9 deletions clang/include/clang/Testing/CommandLineArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,18 @@
namespace clang {

enum TestLanguage {
Lang_C89,
Lang_C99,
Lang_CXX03,
Lang_CXX11,
Lang_CXX14,
Lang_CXX17,
Lang_CXX20,
Lang_CXX23,
#define TESTLANGUAGE(lang, version, std_flag, version_index) \
Lang_##lang##version,
#include "clang/Testing/TestLanguage.def"

Lang_OpenCL,
Lang_OBJC,
Lang_OBJCXX
Lang_OBJCXX,
};

std::vector<TestLanguage> getCOrLater(int MinimumStd);
std::vector<TestLanguage> getCXXOrLater(int MinimumStd);

std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang);
std::vector<std::string> getCC1ArgsForTesting(TestLanguage Lang);

Expand Down
146 changes: 125 additions & 21 deletions clang/include/clang/Testing/TestClangConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,117 @@ struct TestClangConfig {
/// The argument of the `-target` command line flag.
std::string Target;

bool isC() const { return Language == Lang_C89 || Language == Lang_C99; }

bool isC99OrLater() const { return Language == Lang_C99; }

bool isCXX() const {
return Language == Lang_CXX03 || Language == Lang_CXX11 ||
Language == Lang_CXX14 || Language == Lang_CXX17 ||
Language == Lang_CXX20 || Language == Lang_CXX23;
bool isC() const {
return false
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
|| Language == Lang_##lang##version
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
;
}

bool isCXX11OrLater() const {
return Language == Lang_CXX11 || Language == Lang_CXX14 ||
Language == Lang_CXX17 || Language == Lang_CXX20 ||
Language == Lang_CXX23;
bool isCOrLater(int MinimumStdVersion) const {
const auto MinimumStdVersionIndex = 0
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
+(MinimumStdVersion == version ? version_index : 0)
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
;
switch (Language) {
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return MinimumStdVersionIndex <= version_index;
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
default:
return false;
}
}

bool isCXX14OrLater() const {
return Language == Lang_CXX14 || Language == Lang_CXX17 ||
Language == Lang_CXX20 || Language == Lang_CXX23;
bool isC99OrLater() const { return isCOrLater(99); }

bool isCOrEarlier(int MaximumStdVersion) const {
const auto MaximumStdVersionIndex = 0
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
+(MaximumStdVersion == version ? version_index : 0)
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
;
switch (Language) {
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return MaximumStdVersionIndex >= version_index;
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
default:
return false;
}
}

bool isCXX17OrLater() const {
return Language == Lang_CXX17 || Language == Lang_CXX20 ||
Language == Lang_CXX23;
bool isCXX() const {
return false
#define TESTLANGUAGE
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
|| Language == Lang_##lang##version
#define TESTLANGUAGE_C(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
;
}

bool isCXX20OrLater() const {
return Language == Lang_CXX20 || Language == Lang_CXX23;
bool isCXXOrLater(int MinimumStdVersion) const {
const auto MinimumStdVersionIndex = 0
#define TESTLANGUAGE
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
+(MinimumStdVersion == version ? version_index : 0)
#define TESTLANGUAGE_C(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
;
switch (Language) {
#define TESTLANGUAGE
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return MinimumStdVersionIndex <= version_index;
#define TESTLANGUAGE_C(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
default:
return false;
}
}

bool isCXX23OrLater() const { return Language == Lang_CXX23; }
bool isCXX11OrLater() const { return isCXXOrLater(11); }

bool isCXX14OrLater() const { return isCXXOrLater(14); }

bool isCXX17OrLater() const { return isCXXOrLater(17); }

bool isCXX20OrLater() const { return isCXXOrLater(20); }

bool isCXX23OrLater() const { return isCXXOrLater(23); }

bool isCXXOrEarlier(int MaximumStdVersion) const {
const auto MaximumStdVersionIndex = 0
#define TESTLANGUAGE
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
+(MaximumStdVersion == version ? version_index : 0)
#define TESTLANGUAGE_C(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
;
switch (Language) {
#define TESTLANGUAGE
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return MaximumStdVersionIndex >= version_index;
#define TESTLANGUAGE_C(lang, version, std_flag, version_index)
#include "clang/Testing/TestLanguage.def"
default:
return false;
}
}

bool supportsCXXDynamicExceptionSpecification() const {
return Language == Lang_CXX03 || Language == Lang_CXX11 ||
Expand All @@ -75,6 +155,30 @@ struct TestClangConfig {
return Result;
}

std::string toShortString() const {
std::string Result;
llvm::raw_string_ostream OS(Result);
switch (Language) {
#define TESTLANGUAGE(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
OS << (#lang #version); \
break;
#include "clang/Testing/TestLanguage.def"
case Lang_OpenCL:
OS << "OpenCL";
break;
case Lang_OBJC:
OS << "OBJC";
break;
case Lang_OBJCXX:
OS << "OBJCXX";
break;
}

OS << (Target.find("win") != std::string::npos ? "_win" : "");
return Result;
}

std::string toString() const {
std::string Result;
llvm::raw_string_ostream OS(Result);
Expand Down
39 changes: 39 additions & 0 deletions clang/include/clang/Testing/TestLanguage.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

//===-- TestLanguage.def - Language Versions for Testing --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef TESTLANGUAGE
#error "TESTLANGUAGE must be defined before including this file"
#endif

#ifndef TESTLANGUAGE_C
#define TESTLANGUAGE_C TESTLANGUAGE
#endif

#ifndef TESTLANGUAGE_CXX
#define TESTLANGUAGE_CXX TESTLANGUAGE
#endif

TESTLANGUAGE_C(C, 89, c89, 0)
TESTLANGUAGE_C(C, 99, c99, 1)
TESTLANGUAGE_C(C, 11, c11, 2)
TESTLANGUAGE_C(C, 17, c17, 3)
TESTLANGUAGE_C(C, 23, c23, 4)

// TESTLANGUAGE_CXX(CXX, 98, c++98, 0)
TESTLANGUAGE_CXX(CXX, 03, c++03, 1)
TESTLANGUAGE_CXX(CXX, 11, c++11, 2)
TESTLANGUAGE_CXX(CXX, 14, c++14, 3)
TESTLANGUAGE_CXX(CXX, 17, c++17, 4)
TESTLANGUAGE_CXX(CXX, 20, c++20, 5)
TESTLANGUAGE_CXX(CXX, 23, c++23, 6)
TESTLANGUAGE_CXX(CXX, 26, c++26, 7)

#undef TESTLANGUAGE_CXX
#undef TESTLANGUAGE_C
#undef TESTLANGUAGE
119 changes: 52 additions & 67 deletions clang/lib/Testing/CommandLineArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,99 +11,84 @@
#include "llvm/Support/ErrorHandling.h"

namespace clang {
std::vector<TestLanguage> getCOrLater(const int MinimumStd) {
std::vector<TestLanguage> Result{};

#define TESTLANGUAGE(lang, version, std_flag, version_index)
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
if (version >= MinimumStd) \
Result.push_back(Lang_##lang##version);
#include "clang/Testing/TestLanguage.def"

return Result;
}
std::vector<TestLanguage> getCXXOrLater(const int MinimumStd) {
std::vector<TestLanguage> Result{};

#define TESTLANGUAGE(lang, version, std_flag, version_index)
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
if (version >= MinimumStd) \
Result.push_back(Lang_##lang##version);
#include "clang/Testing/TestLanguage.def"

return Result;
}

std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang) {
std::vector<std::string> Args;
// Test with basic arguments.
switch (Lang) {
case Lang_C89:
Args = {"-x", "c", "-std=c89"};
break;
case Lang_C99:
Args = {"-x", "c", "-std=c99"};
break;
case Lang_CXX03:
Args = {"-std=c++03", "-frtti"};
break;
case Lang_CXX11:
Args = {"-std=c++11", "-frtti"};
break;
case Lang_CXX14:
Args = {"-std=c++14", "-frtti"};
break;
case Lang_CXX17:
Args = {"-std=c++17", "-frtti"};
break;
case Lang_CXX20:
Args = {"-std=c++20", "-frtti"};
break;
case Lang_CXX23:
Args = {"-std=c++23", "-frtti"};
break;
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return { "-x", "c", "-std=" #std_flag };
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return { "-std=" #std_flag, "-frtti" };
#include "clang/Testing/TestLanguage.def"

case Lang_OBJC:
Args = {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"};
break;
return {"-x", "objective-c", "-frtti", "-fobjc-nonfragile-abi"};
case Lang_OBJCXX:
Args = {"-x", "objective-c++", "-frtti"};
break;
return {"-x", "objective-c++", "-frtti"};
case Lang_OpenCL:
llvm_unreachable("Not implemented yet!");
}
return Args;
llvm_unreachable("Not implemented yet!");
}

std::vector<std::string> getCC1ArgsForTesting(TestLanguage Lang) {
std::vector<std::string> Args;
switch (Lang) {
case Lang_C89:
Args = {"-xc", "-std=c89"};
break;
case Lang_C99:
Args = {"-xc", "-std=c99"};
break;
case Lang_CXX03:
Args = {"-std=c++03"};
break;
case Lang_CXX11:
Args = {"-std=c++11"};
break;
case Lang_CXX14:
Args = {"-std=c++14"};
break;
case Lang_CXX17:
Args = {"-std=c++17"};
break;
case Lang_CXX20:
Args = {"-std=c++20"};
break;
case Lang_CXX23:
Args = {"-std=c++23"};
break;
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return { "-xc", "-std=" #std_flag };
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return { "-std=" #std_flag };
#include "clang/Testing/TestLanguage.def"

case Lang_OBJC:
Args = {"-xobjective-c"};
return {"-xobjective-c"};
break;
case Lang_OBJCXX:
Args = {"-xobjective-c++"};
return {"-xobjective-c++"};
break;
case Lang_OpenCL:
llvm_unreachable("Not implemented yet!");
}
return Args;
llvm_unreachable("Not implemented yet!");
}

StringRef getFilenameForTesting(TestLanguage Lang) {
switch (Lang) {
case Lang_C89:
case Lang_C99:
#define TESTLANGUAGE
#define TESTLANGUAGE_C(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return "input.c";

case Lang_CXX03:
case Lang_CXX11:
case Lang_CXX14:
case Lang_CXX17:
case Lang_CXX20:
case Lang_CXX23:
#define TESTLANGUAGE_CXX(lang, version, std_flag, version_index) \
case Lang_##lang##version: \
return "input.cc";
#include "clang/Testing/TestLanguage.def"

case Lang_OpenCL:
return "input.cl";
Expand Down
Loading

0 comments on commit 1c6f2a0

Please sign in to comment.