Skip to content

Commit 34c41b1

Browse files
authored
Merge pull request #2740 from guwirth/cpp23-grammar
C++23: some more grammar changes
2 parents 1136201 + 230c5d6 commit 34c41b1

File tree

9 files changed

+123
-42
lines changed

9 files changed

+123
-42
lines changed

cxx-squid/dox/diff-cpp20-cpp23_grammar.txt

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -131,32 +131,3 @@ d-char:
131131
any member of the basic character set except:
132132
u+0020 space, u+0028 left parenthesis, u+0029 right parenthesis, u+005c reverse solidus,
133133
u+0009 character tabulation, u+000b line tabulation, u+000c form feed, and new-line
134-
135-
**A.5 Expressions [gram.expr]**
136-
137-
requirement-parameter-list:
138-
( parameter-declaration-clause )
139-
140-
requirement-seq:
141-
requirement
142-
requirement requirement-seq
143-
144-
**A.7 Declarations [gram.dcl]**
145-
146-
elaborated-type-specifier:
147-
class-key attribute-specifier-seqopt nested-name-specifieropt identifier
148-
class-key simple-template-id
149-
class-key nested-name-specifier templateopt simple-template-id
150-
enum nested-name-specifieropt identifier
151-
152-
using-enum-declaration:
153-
using enum using-enum-declarator ;
154-
155-
using-enum-declarator:
156-
nested-name-specifieropt identifier
157-
nested-name-specifieropt simple-template-id
158-
159-
**A.11 Templates [gram.temp]**
160-
161-
concept-definition:
162-
concept concept-name attribute-specifier-seqopt = constraint-expression ;

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ public enum CxxGrammarImpl implements GrammarRuleKey {
164164
decltypeSpecifier,
165165
placeholderTypeSpecifier,
166166
elaboratedTypeSpecifier,
167-
elaboratedEnumSpecifier,
168167
enumName,
169168
enumSpecifier,
170169
enumHead,
@@ -176,6 +175,7 @@ public enum CxxGrammarImpl implements GrammarRuleKey {
176175
enumeratorDefinition,
177176
enumerator,
178177
usingEnumDeclaration,
178+
usingEnumDeclarator,
179179
namespaceName,
180180
namespaceDefinition,
181181
namedNamespaceDefinition,
@@ -649,7 +649,7 @@ private static void expressions(LexerfulGrammarBuilder b) {
649649
);
650650

651651
b.rule(requirementParameterList).is(
652-
"(", b.optional(parameterDeclarationClause), ")" // C++
652+
"(", parameterDeclarationClause, ")" // C++
653653
);
654654

655655
b.rule(requirementBody).is(
@@ -1290,14 +1290,10 @@ private static void declarations(LexerfulGrammarBuilder b) {
12901290
b.sequence(b.optional(attributeSpecifierSeq), b.optional(nestedNameSpecifier), IDENTIFIER) // C++
12911291
)
12921292
),
1293-
elaboratedEnumSpecifier // C++
1293+
b.sequence(CxxKeyword.ENUM, b.optional(nestedNameSpecifier), IDENTIFIER) // C++
12941294
)
12951295
);
12961296

1297-
b.rule(elaboratedEnumSpecifier).is(
1298-
CxxKeyword.ENUM, b.optional(nestedNameSpecifier), IDENTIFIER // C++
1299-
);
1300-
13011297
b.rule(decltypeSpecifier).is(
13021298
CxxKeyword.DECLTYPE, "(",
13031299
b.firstOf(
@@ -1632,7 +1628,15 @@ private static void declarations(LexerfulGrammarBuilder b) {
16321628
);
16331629

16341630
b.rule(usingEnumDeclaration).is(
1635-
CxxKeyword.USING, elaboratedEnumSpecifier, ";"
1631+
CxxKeyword.USING, CxxKeyword.ENUM, usingEnumDeclarator, ";"
1632+
);
1633+
1634+
b.rule(usingEnumDeclarator).is(
1635+
b.optional(nestedNameSpecifier),
1636+
b.firstOf(
1637+
IDENTIFIER,
1638+
simpleTemplateId
1639+
)
16361640
);
16371641

16381642
b.rule(namespaceName).is(
@@ -2306,7 +2310,7 @@ private static void templates(LexerfulGrammarBuilder b) {
23062310
);
23072311

23082312
b.rule(conceptDefinition).is(
2309-
CxxKeyword.CONCEPT, conceptName, "=", constraintExpression, ";" // C++
2313+
CxxKeyword.CONCEPT, conceptName, b.optional(attributeSpecifierSeq), "=", constraintExpression, ";" // C++
23102314
);
23112315

23122316
b.rule(conceptName).is(

cxx-squid/src/test/java/org/sonar/cxx/parser/DeclarationsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,6 @@ void elaboratedTypeSpecifier() {
433433
mockRule(CxxGrammarImpl.attributeSpecifierSeq);
434434
mockRule(CxxGrammarImpl.nestedNameSpecifier);
435435
mockRule(CxxGrammarImpl.simpleTemplateId);
436-
mockRule(CxxGrammarImpl.elaboratedEnumSpecifier);
437436

438437
assertThatParser()
439438
.matches("classKey foo")
@@ -443,7 +442,8 @@ void elaboratedTypeSpecifier() {
443442
.matches("classKey simpleTemplateId")
444443
.matches("classKey nestedNameSpecifier simpleTemplateId")
445444
.matches("classKey nestedNameSpecifier template simpleTemplateId")
446-
.matches("elaboratedEnumSpecifier");
445+
.matches("enum foo")
446+
.matches("enum nestedNameSpecifier foo");
447447
}
448448

449449
@Test

cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ void requirementParameterList() {
8787
mockRule(CxxGrammarImpl.parameterDeclarationClause);
8888

8989
assertThatParser()
90-
.matches("( )")
9190
.matches("( parameterDeclarationClause )");
9291
}
9392

cxx-squid/src/test/java/org/sonar/cxx/parser/TemplatesTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,11 @@ void conceptDefinition() {
279279

280280
mockRule(CxxGrammarImpl.conceptName);
281281
mockRule(CxxGrammarImpl.constraintExpression);
282+
mockRule(CxxGrammarImpl.attributeSpecifierSeq);
282283

283-
assertThatParser().matches("concept conceptName = constraintExpression ;");
284+
assertThatParser()
285+
.matches("concept conceptName = constraintExpression ;")
286+
.matches("concept conceptName attributeSpecifierSeq = constraintExpression ;");
284287
}
285288

286289
@Test
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
void foo() {
2+
// variable definition
3+
auto v(x);
4+
auto v{x};
5+
ClassTemplate v(x);
6+
ClassTemplate v{x};
7+
8+
// new expression
9+
new auto(x);
10+
new auto{x};
11+
new ClassTemplate(x);
12+
new ClassTemplate{x};
13+
}
14+
15+
// function-style cast
16+
template<typename T, typename U>
17+
T cast1(U const &u) {
18+
return auto(u);
19+
}
20+
template<typename T, typename U>
21+
T cast2(U const &u) {
22+
return auto{u};
23+
}
24+
template<typename T, typename U>
25+
T cast3(U const &u) {
26+
return ClassTemplate(u);
27+
}
28+
template<typename T, typename U>
29+
T cast4(U const &u) {
30+
return ClassTemplate{u};
31+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[[gnu::sample]] [[gnu::sample]] [[gnu::hot]] [[nodiscard]]
2+
inline int f(); // declare f with four attributes
3+
4+
[[gnu::sample, gnu::sample, gnu::hot, nodiscard]]
5+
int f(); // same as above, but uses a single attr specifier that contains four attributes
6+
7+
[[using gnu : sample, sample, hot]] [[nodiscard]] [[gnu::sample]]
8+
int f(); // same as above
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
char xdigit1(int n) {
2+
static constexpr char digits[] = "0123456789abcdef";
3+
return digits[n];
4+
}
5+
6+
constexpr char xdigit2(int n) {
7+
static constexpr char digits[] = "0123456789abcdef"; // C++23
8+
return digits[n];
9+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// --- static operator() ---
2+
3+
// Overload Resolution
4+
struct less {
5+
static constexpr auto operator()(int i, int j) -> bool {
6+
return i < j;
7+
}
8+
using P = bool( * )(int, int);
9+
operator P() const {
10+
return operator();
11+
}
12+
};
13+
14+
void foo() {
15+
static_assert(less {}(1, 2));
16+
}
17+
18+
// Lambdas
19+
auto four = []() static {
20+
return 4;
21+
};
22+
23+
// Static lambdas with capture
24+
auto under_lock = [lock = std::unique_lock(mtx)]() static {
25+
/* do something */ ;
26+
};
27+
28+
// --- static operator[] ---
29+
30+
template < typename T, std::size_t S > struct array: std::array < T, S > {
31+
static constexpr inline std::size_t extent = []() -> std::size_t {
32+
if constexpr(_is_array < T > ) {
33+
return 1 + T::extent;
34+
}
35+
return 1;
36+
}();
37+
constexpr decltype(auto)
38+
operator[](std::size_t idx) {
39+
return * (this -> data() + idx);
40+
}
41+
constexpr decltype(auto)
42+
operator[](std::size_t idx, convertible_to < std::size_t > auto && ...args)
43+
requires(sizeof...(args) < extent) && (sizeof...(args) >= 1) {
44+
typename std::array < T, S > ::reference v = * (this -> data() + idx);
45+
return v.operator[](args...);
46+
}
47+
constexpr decltype(auto)
48+
operator[](std::size_t idx) const {
49+
return * (this -> data() + idx);
50+
}
51+
constexpr decltype(auto)
52+
operator[](std::size_t idx, convertible_to < std::size_t > auto && ...args) const requires(sizeof...(args) < extent) && (sizeof...(args) >= 1) {
53+
typename std::array < T, S > ::reference v = * (this -> data() + idx);
54+
return v.operator[](args...);
55+
}
56+
};

0 commit comments

Comments
 (0)