Skip to content

Commit 03d49a5

Browse files
committed
improve type traits support
- close #2306 ```C++ struct C { template<typename T, std::enable_if_t< std::is_integral_t<T>, int> = 0 > C( T num ) {} template<typename T, std::enable_if_t< std::is_integral_v<T>, int> = 0 > int foo( T num ) {} }; template< typename T, std::enable_if_t< std::is_integral_v<T>, int> > A operator+( T num ) {} template< typename T, std::enable_if_t< std::is_integral_v<T>, int> = 0> A operator+( T num ) {} ```
1 parent 78d1bee commit 03d49a5

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,13 +2182,9 @@ private static void templates(LexerfulGrammarBuilder b) {
21822182
b.sequence( // C++ (PEG: different order) todo one up
21832183
typeConstraint,
21842184
b.firstOf(
2185-
b.sequence(
2186-
b.optional(IDENTIFIER), "=",
2187-
b.firstOf(
2188-
typeId, // C++
2189-
initializerClause // syntax sugar to handle type traits providing type name (e.g. std::enable_if_t<>=0)
2190-
)
2191-
),
2185+
b.sequence(b.optional(IDENTIFIER), "=", typeId), // C++
2186+
// syntax sugar to handle type traits providing type name (e.g. std::enable_if_t<>=0, std::enable_if_t<>*=nullptr)
2187+
b.sequence(b.optional("*"), "=", LITERAL),
21922188
b.sequence(b.optional("..."), b.optional(IDENTIFIER)) // C++ (PEG: different order)
21932189
)
21942190
)
@@ -2198,7 +2194,7 @@ private static void templates(LexerfulGrammarBuilder b) {
21982194
b.rule(typeTraits).is( // syntax sugar to handle type traits ...::type (not part of C++ grammar)
21992195
b.zeroOrMore(b.sequence(IDENTIFIER, "::")),
22002196
simpleTemplateId, "::", "type", b.optional("*"),
2201-
b.optional("=", initializerClause)
2197+
b.optional("=", LITERAL)
22022198
);
22032199

22042200
b.rule(typeParameterKey).is(

cxx-squid/src/test/resources/parser/own/C++14/type-traits-helper.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,25 @@ template <typename T, typename std::enable_if <std::is_base_of<BaseT, T>::value
55
template <typename T, typename std::enable_if <std::is_base_of<BaseT, T>::value, int>::type> class B {};
66
template <typename T, std::enable_if_t<std::is_base_of<BaseT, T>::value, int> = 0> class C {};
77
template <typename T, std::enable_if_t<std::is_base_of<BaseT, T>::value, int>> class D {};
8+
9+
10+
template <typename Collection, std::enable_if_t<std::is_convertible_v<Collection, interface_type>>* = nullptr> class E {};
11+
template <typename Collection, std::enable_if<std::is_convertible_v<Collection, interface_type>>::type* = nullptr> class F {};
12+
template <class T, typename std::enable_if <!std::is_trivially_destructible<T>{} && (std::is_class<T>{} || std::is_union<T>{}), bool>::type = true> class G {};
13+
template <class T, std::enable_if_t<!std::is_trivially_destructible<T>{} && (std::is_class<T>{} || std::is_union<T>{}), bool> = true> class H {};
14+
15+
16+
struct I {
17+
template<typename T, std::enable_if_t< std::is_integral_t<T>, int> = 0 >
18+
I( T num ) {}
19+
20+
template<typename T, std::enable_if_t< std::is_integral_v<T>, int> = 0 >
21+
int foo( T num ) {}
22+
};
23+
24+
25+
template< typename T, std::enable_if_t< std::is_integral_v<T>, int> >
26+
A operator+( T num ) {}
27+
28+
template< typename T, std::enable_if_t< std::is_integral_v<T>, int> = 0>
29+
A operator+( T num ) {}

0 commit comments

Comments
 (0)