1
votes

I am running ANTLR 4.2 and using the canonical C grammar from:
https://github.com/antlr/grammars-v4/tree/master/c

I am doing the following steps: (using batch files from the ANTLR4 book)

  1. antlr C.g4
  2. javac C*.java
  3. grun C compilationUnit -tokens test.c

Where test.c has the following code:

PASSING:

typedef
void
(*EFI_SET_MEM) (
   void     *Buffer,
   UINTN    Size,
   UINT8    Value
  );

FAILING: error is: line 3:9 no viable alternative at input 'typedefvoid(__cdecl*'

typedef
void
(__cdecl *EFI_SET_MEM) (
   void     *Buffer,
   UINTN    Size,
   UINT8    Value
  );

The only difference is __cdecl. I tried several changes to fix this, e.g.:

functionSpecifier
    :   ('inline'
    |   '_Noreturn'
    |   '__inline__' // GCC extension
    |   '__cdecl'
    |   '__stdcall')
    |   gccAttributeSpecifier
    |   '__declspec' '(' Identifier ')'
    ;

...but this is not working. Any ideas on how to fix this problem? Since what I'm doing doesn't care about the calling convention, creating this lexer rule makes the problem go away:

Cdecl
    :   '__cdecl'
        -> skip
    ;

I still wish I had a real solution.

1

1 Answers

1
votes

__cdecl is used in C++ to declare an interface as using the C-calling convention for linkage (explicitly with undecorated names and the like). __cdecl is C++ (and I believe specific to certain compilers on top of that), not C, so the C grammar doesn't specify it.

I'm not sure why your proposed fix isn't working, tho.