Skip to content

Commit

Permalink
Merge pull request SonarOpenCommunity#2738 from guwirth/cpp23-meaning…
Browse files Browse the repository at this point in the history
…ful-exports

C++23: meaningful exports
  • Loading branch information
guwirth authored Sep 2, 2024
2 parents fab0556 + be44729 commit 1136201
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 51 deletions.
32 changes: 0 additions & 32 deletions cxx-squid/dox/diff-cpp20-cpp23_grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,27 +143,6 @@ requirement-seq:

**A.7 Declarations [gram.dcl]**

declaration:
name-declaration
special-declaration

name-declaration:
block-declaration
nodeclspec-function-declaration
function-definition
template-declaration
deduction-guide
linkage-specification
namespace-definition
empty-declaration
attribute-declaration
module-import-declaration

special-declaration:
explicit-instantiation
explicit-specialization
export-declaration

elaborated-type-specifier:
class-key attribute-specifier-seqopt nested-name-specifieropt identifier
class-key simple-template-id
Expand All @@ -177,17 +156,6 @@ using-enum-declarator:
nested-name-specifieropt identifier
nested-name-specifieropt simple-template-id

linkage-specification:
extern string-literal { declaration-seqopt }
extern string-literal name-declaration

**A.8 Modules [gram.module]**

export-declaration:
export name-declaration
export { declaration-seqopt }
export-keyword module-import-declaration

**A.11 Templates [gram.temp]**

concept-definition:
Expand Down
27 changes: 20 additions & 7 deletions cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ public enum CxxGrammarImpl implements GrammarRuleKey {
// Declarations
declarationSeq,
declaration,
nameDeclaration,
specialDeclaration,
blockDeclaration,
nodeclspecFunctionDeclaration,
aliasDeclaration,
Expand Down Expand Up @@ -1079,6 +1081,13 @@ private static void declarations(LexerfulGrammarBuilder b) {
).skipIfOneChild();

b.rule(declaration).is(
b.firstOf(
nameDeclaration,
specialDeclaration
)
);

b.rule(nameDeclaration).is(
b.firstOf(
// identifiers with special meaning: import and module => must be placed before rules that start with an identifier!
moduleImportDeclaration, // C++ import ...
Expand All @@ -1088,15 +1097,19 @@ private static void declarations(LexerfulGrammarBuilder b) {
functionDefinition, // C++
templateDeclaration, // C++
deductionGuide, // C++
cliGenericDeclaration, // C++/CLI
explicitInstantiation, // C++
explicitSpecialization, // C++
exportDeclaration, // C++
linkageSpecification, // C++
namespaceDefinition, // C++
emptyDeclaration, // C++
attributeDeclaration, // C++
attributeDeclaration // C++
)
);

b.rule(specialDeclaration).is(
b.firstOf(
cliGenericDeclaration, // C++/CLI
explicitInstantiation, // C++
explicitSpecialization, // C++
exportDeclaration, // C++
vcAtlDeclaration // Attributted-ATL
)
);
Expand Down Expand Up @@ -1713,7 +1726,7 @@ private static void declarations(LexerfulGrammarBuilder b) {
CxxKeyword.EXTERN, STRING,
b.firstOf(
b.sequence("{", b.optional(declarationSeq), "}"), // C++
declaration // C++
nameDeclaration // C++
)
);

Expand Down Expand Up @@ -1807,7 +1820,7 @@ private static void modules(LexerfulGrammarBuilder b) {
b.rule(exportDeclaration).is( // C++
"export",
b.firstOf(
declaration,
nameDeclaration,
b.sequence("{", b.optional(declarationSeq), "}"),
moduleImportDeclaration
)
Expand Down
42 changes: 32 additions & 10 deletions cxx-squid/src/test/java/org/sonar/cxx/parser/DeclarationsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,55 @@ void declarationSeq() {
void declaration() {
setRootRule(CxxGrammarImpl.declaration);

mockRule(CxxGrammarImpl.nameDeclaration);
mockRule(CxxGrammarImpl.specialDeclaration);

assertThatParser()
.matches("nameDeclaration")
.matches("specialDeclaration");
}

@Test
void nameDeclaration() {
setRootRule(CxxGrammarImpl.nameDeclaration);

mockRule(CxxGrammarImpl.blockDeclaration);
mockRule(CxxGrammarImpl.nodeclspecFunctionDeclaration);
mockRule(CxxGrammarImpl.functionDefinition);
mockRule(CxxGrammarImpl.templateDeclaration);
mockRule(CxxGrammarImpl.deductionGuide);
mockRule(CxxGrammarImpl.cliGenericDeclaration);
mockRule(CxxGrammarImpl.explicitInstantiation);
mockRule(CxxGrammarImpl.explicitSpecialization);
mockRule(CxxGrammarImpl.linkageSpecification);
mockRule(CxxGrammarImpl.namespaceDefinition);
mockRule(CxxGrammarImpl.emptyDeclaration);
mockRule(CxxGrammarImpl.attributeDeclaration);
mockRule(CxxGrammarImpl.vcAtlDeclaration);

assertThatParser()
.matches("blockDeclaration")
.matches("nodeclspecFunctionDeclaration")
.matches("functionDefinition")
.matches("templateDeclaration")
.matches("deductionGuide")
.matches("cliGenericDeclaration")
.matches("explicitInstantiation")
.matches("explicitSpecialization")
.matches("linkageSpecification")
.matches("namespaceDefinition")
.matches("emptyDeclaration")
.matches("attributeDeclaration")
.matches("attributeDeclaration");
}

@Test
void specialDeclaration() {
setRootRule(CxxGrammarImpl.specialDeclaration);

mockRule(CxxGrammarImpl.cliGenericDeclaration);
mockRule(CxxGrammarImpl.explicitInstantiation);
mockRule(CxxGrammarImpl.explicitSpecialization);
mockRule(CxxGrammarImpl.exportDeclaration);
mockRule(CxxGrammarImpl.vcAtlDeclaration);

assertThatParser()
.matches("cliGenericDeclaration")
.matches("explicitInstantiation")
.matches("explicitSpecialization")
.matches("exportDeclaration")
.matches("vcAtlDeclaration");
}

Expand Down Expand Up @@ -650,12 +672,12 @@ void usingDirective() {
void linkageSpecification() {
setRootRule(CxxGrammarImpl.linkageSpecification);

mockRule(CxxGrammarImpl.declaration);
mockRule(CxxGrammarImpl.nameDeclaration);
mockRule(CxxGrammarImpl.declarationSeq);

assertThatParser()
.matches("extern \"foo\" { declarationSeq }")
.matches("extern \"foo\" declaration");
.matches("extern \"foo\" nameDeclaration");
}

@Test
Expand Down
4 changes: 2 additions & 2 deletions cxx-squid/src/test/java/org/sonar/cxx/parser/ModuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,12 @@ void moduleNameQualifier() {
void exportDeclaration() {
setRootRule(CxxGrammarImpl.exportDeclaration);

mockRule(CxxGrammarImpl.declaration);
mockRule(CxxGrammarImpl.nameDeclaration);
mockRule(CxxGrammarImpl.declarationSeq);
mockRule(CxxGrammarImpl.moduleImportDeclaration);

assertThatParser()
.matches("export declaration")
.matches("export nameDeclaration")
.matches("export { }")
.matches("export { declarationSeq }")
.matches("export moduleImportDeclaration");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export module M; // OK
export int f(); // OK
export namespace N { } // OK
export using namespace N; // OK

0 comments on commit 1136201

Please sign in to comment.