[cfe-dev] Nacro: A better C/C++ macro extension implemented in Clang plugins

Min-Yih Hsu via cfe-dev cfe-dev at lists.llvm.org
Thu Jun 11 12:08:54 PDT 2020



> On Jun 11, 2020, at 11:50 AM, Madhur Amilkanthwar <madhur13490 at gmail.com> wrote:
> 
> Sounds interesting. It would be a good addition if you can support a bit of type system and ensuring type sanity too somehow.
That was part of my original plan, still thinking on how to make good use of the type system.

-Min

> 
> On Fri, Jun 12, 2020, 12:02 AM Min-Yih Hsu via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
> Hi Clang folks,
> 
> Recently I have been working on a side project, Nacro (https://github.com/mshockwave/nacro <https://github.com/mshockwave/nacro>), that you might find interesting.
> 
> Nacro is a small DSL aim to provide a better C/C++ macro experience. Here is an example:
> ```
> #pragma nacro rule myPrint
> (val:$expr) -> $stmt {
>     printf("%d\n", val * 2)
> }
> 
> #pragma nacro rule genColors
> (cases:$expr*) -> {
>     $loop(c in cases) {
>         case c:
>         printf("the color is %s\n", $str(c));
>         break;
>     }
> }
> 
> enum Color { RED, BLUE, YELLOW };
> void printColor(enum Color color) {
>     switch(color) genColors(RED, BLUE, YELLOW)
> }
> 
> int main() {
>     myPrint(1 + 3)   // print out '8'
>     printColor(RED); // print 'the color is RED'
>     return 0;
> }
> ```
> You can create a nacro rule with a pragma directive and follows with definitions written a simple DSL. The defined nacro rule works just like a normal macro function (i.e. expanded during preprocessing and called like a function), but with some extra features:
>  - Multiline definitions without ‘\’.
>  - Expression Protection: As shown in the ‘myPrint’ nacro above, you don’t need to add parens around expressions anymore, the nacro preprocessor will do that for you.
>  - Loops, one of the most exciting features in nacro: You can use “$loop” directive to ‘unroll’ a list of argument (argument type trailing with ‘*’, like ‘$expr*’. It’s equivalent to VA_ARGS) during preprocessing.
>  - Detecting invalid capturing. This is still an unstable feature, but basically it’s aiming to detect issues like this:
> ```
> #define foo(arg) {\
>     int x = 0;  \
>     return arg + x; \
> }
> 
> // ERROR: caller will always return 0 
> // regardless the argument value
> int caller(int x) {
>     foo(x)
> }
> 
> ```
> Please checkout the its wiki page (https://github.com/mshockwave/nacro/wiki/Invalid-Capture-Detection <https://github.com/mshockwave/nacro/wiki/Invalid-Capture-Detection>) for more info.
> 
> Another important thing is that nacro _doesn’t require a custom Clang / LLVM_. All of the features are implemented in a Clang plugin. So all you need is a Clang 10 by your hand and the plugin.
> 
> Though not modifying Clang actually put a tons of restrictions and force me to create many hacky workarounds that might be broken in newer version of Clang. For example, as a preprocessor plugin, all i can do is mutating and injecting tokens. But the preprocessor doesn’t like it, or in other words, current preprocessor doesn’t have a good support on this kind of actions. Especially while I was dealing with SourceLocation: there are many time i need to use an imprecise one or even fake one.
> 
> Another hard part is the Invalid Capture Detection. My original plan was to automatically fix it rather than throwing an error message. However, that will require symbol table and scope info that merely exist in AST. Though Parser/Sema has those info but currently we don’t have any plugin support on Parser/Sema. 
> 
> Hope you find this project interesting, or at least find it amusing. 
> 
> -Min
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev <https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200611/eea86fd5/attachment-0001.html>


More information about the cfe-dev mailing list