From dae101f0dd072de2e035e8ce3038e70bd0a37a2d Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Tue, 30 Jan 2024 21:29:40 +0800 Subject: [PATCH] feat(c): add macro support to primaryExpression and genericSelection #24 - Added support for macros in primaryExpression and genericSelection in the C grammar. - Updated primaryExpression to include typeKeywords, Identifier, '==', '!=', and pointer. - Updated genericSelection to include singleLineMacroDeclaration. - Updated initializerList to include singleLineMacroDeclaration. --- chapi-ast-c/src/main/antlr/C.g4 | 9 +++-- .../chapi/ast/cast/CFullIdentListenerTest.kt | 34 ++++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/chapi-ast-c/src/main/antlr/C.g4 b/chapi-ast-c/src/main/antlr/C.g4 index b74056d0..aa169fef 100644 --- a/chapi-ast-c/src/main/antlr/C.g4 +++ b/chapi-ast-c/src/main/antlr/C.g4 @@ -66,7 +66,6 @@ includeIdentifier primaryExpression : Identifier - | typeKeywords (Identifier | typeKeywords)* pointer? | Constant | StringLiteral+ | '(' expression ')' @@ -74,7 +73,10 @@ primaryExpression | '__extension__'? '(' compoundStatement ')' // Blocks (GCC extension) | '__builtin_va_arg' '(' unaryExpression ',' typeName ')' | '__builtin_offsetof' '(' typeName ',' unaryExpression ')' - | StringLiteral singleLineMacroDeclaration StringLiteral (singleLineMacroDeclaration | StringLiteral)* + // for macro support + | (typeKeywords | Identifier | '==' | '!=') (Identifier | typeKeywords )* pointer? + | StringLiteral singleLineMacroDeclaration (singleLineMacroDeclaration | StringLiteral)* + | Ellipsis ; genericSelection @@ -347,6 +349,7 @@ directDeclarator | Identifier ':' DigitSequence #bitFieldDirectDeclarator // bit field | vcSpecificModifer Identifier #vcSpecificModiferDirectDeclarator | '(' typeSpecifier? pointer directDeclarator ')' #functionPointerDirectDeclarator // function pointer like: (__cdecl *f) + | singleLineMacroDeclaration #macroDirectDeclarator ; vcSpecificModifer @@ -434,7 +437,7 @@ typedefName initializer : assignmentExpression - | '{' initializerList ','? '}' + | '{' initializerList ','? singleLineMacroDeclaration? '}' ; initializerList diff --git a/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt b/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt index 33461b4a..7eb0a80a 100644 --- a/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt +++ b/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt @@ -9,7 +9,7 @@ internal class CFullIdentListenerTest { @Test fun allGrammarUnderResources() { val content = this::class.java.getResource("/grammar")!!.toURI() -// val content = "/Users/phodal/Downloads/redis-unstable" +// val content = "/Users/phodal/Downloads/redis-unstable/deps/jemalloc/test" File(content).walkTopDown().forEach { if (it.isFile && (it.extension == "c" || it.extension == "h")) { println("Analyse ${it.path}") @@ -409,4 +409,36 @@ typedef struct { val codeFile = CAnalyser().analysis(code, "helloworld.c") assertEquals(codeFile.DataStructures.size, 1) } + + @Test + fun shouldHandleMacroInDecl() { + val code = """ + TEST_BEGIN(test_junk_alloc_free) { + size_t sizevals[] = { + 1, 8, 100, 1000, 100*1000 + #if LG_SIZEOF_PTR == 3 + , 10 * 1000 * 1000 + #endif + }; + size_t lg_alignvals[] = { + 0, 4, 10, 15, 16, LG_PAGE + #if LG_SIZEOF_PTR == 3 + , 20, 24 + #endif + }; + } + END_TEST + + #if 0 + #define TRACE_HOOK(fmt, ...) malloc_printf(fmt, __VA_ARGS__) + #else + #define TRACE_HOOK(fmt, ...) + #endif + + size_t n = malloc_snprintf(&buf[i], buflen-i, "%"FMTu64, t0 / t1); + """.trimIndent() + + val codeFile = CAnalyser().analysis(code, "helloworld.c") + assertEquals(codeFile.DataStructures.size, 1) + } }