Skip to content

Commit

Permalink
support Feature Checking Macros
Browse files Browse the repository at this point in the history
* https://clang.llvm.org/docs/LanguageExtensions.html

```
#define __has_builtin(x) 0
#define __has_feature(x) 0
#define __has_extension(x) 0
#define __has_cpp_attribute(x) 0
#define __has_c_attribute(x) 0
#define __has_attribute(x) 0
#define __has_declspec_attribute(x) 0
#define __is_identifier(x) 1
#define __has_warning(x) 0
```

* close SonarOpenCommunity#2395
* close SonarOpenCommunity#2376
* close SonarOpenCommunity#2369
  • Loading branch information
guwirth committed Jul 26, 2022
1 parent 0ff9a10 commit 3d70c50
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,18 @@ final class PPPredefinedMacros {
// set C++14 as default
"__cplusplus 201402L",
// __has_include support (C++17)
"__has_include __has_include" // define __has_include as macro, for e.g. #if __has_include
"__has_include __has_include", // define __has_include as macro, for e.g. #if __has_include
"__has_include_next __has_include_next", // define __has_include as macro, for e.g. #if __has_include
// source: https://clang.llvm.org/docs/LanguageExtensions.html
"__has_builtin(x) 0",
"__has_feature(x) 0",
"__has_extension(x) 0",
"__has_cpp_attribute(x) 0",
"__has_c_attribute(x) 0",
"__has_attribute(x) 0",
"__has_declspec_attribute(x) 0",
"__is_identifier(x) 1",
"__has_warning(x) 0"
};

private PPPredefinedMacros() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,4 +560,127 @@ void has_include() {
.isEqualTo("r = 0 ; EOF");
}

@Test
void featureCheckingMacros() {
//
// source: https://clang.llvm.org/docs/LanguageExtensions.html
//
assertThat(parse(
"#ifdef __has_builtin\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_feature\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_extension\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_cpp_attribute\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_c_attribute\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_attribute\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_attribute\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_declspec_attribute\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __is_identifier\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_attribute\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_include\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_include_next\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");

assertThat(parse(
"#ifdef __has_warning\n"
+ "# define OK 1\n"
+ "#else\n"
+ "# define OK 0\n"
+ "#endif\n"
+ "r = OK;"))
.isEqualTo("r = 1 ; EOF");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,17 @@ void std_macro_evaluated_as_expected() {
assertThat(evaluate("__STDC__")).isTrue();
assertThat(evaluate("__STDC_HOSTED__")).isTrue();
assertThat(evaluate("__cplusplus")).isTrue();
assertThat(evaluate("__has_builtin")).isFalse();
assertThat(evaluate("__has_feature")).isFalse();
assertThat(evaluate("__has_extension")).isFalse();
assertThat(evaluate("__has_cpp_attribute")).isFalse();
assertThat(evaluate("__has_c_attribute")).isFalse();
assertThat(evaluate("__has_attribute")).isFalse();
assertThat(evaluate("__has_declspec_attribute")).isFalse();
assertThat(evaluate("__is_identifier")).isTrue();
assertThat(evaluate("__has_include")).isTrue();
assertThat(evaluate("__has_include_next")).isTrue();
assertThat(evaluate("__has_warning")).isFalse();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,24 @@ void testPredefinedMacroValues() {
"__STDC__",
"__STDC_HOSTED__",
"__cplusplus",
"__has_include"
// __has_include support (C++17)
"__has_include",
"__has_include_next",
// source: https://clang.llvm.org/docs/LanguageExtensions.html
"__has_builtin",
"__has_feature",
"__has_extension",
"__has_cpp_attribute",
"__has_c_attribute",
"__has_attribute",
"__has_declspec_attribute",
"__is_identifier",
"__has_warning"
);
String[] result = PPPredefinedMacros.predefinedMacroValues();
assertThat(result)
.hasSize(8)
.allMatch(s -> expResult.contains(s.split(" ")[0]));
.hasSize(18)
.allMatch(s -> expResult.contains(s.split("[^a-zA-Z_]")[0]));
}

}

0 comments on commit 3d70c50

Please sign in to comment.