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

connor horman via cfe-dev cfe-dev at lists.llvm.org
Thu Jun 11 11:56:00 PDT 2020


On Thu, Jun 11, 2020 at 14:55 connor horman <chorman64 at gmail.com> wrote:

> This seems similar in goal (and somewhat similar in style) to rust's
> declarative macros. Would this be able to support similar things to that,
> or would that be beyond the scope of this?
>
> On Thu, Jun 11, 2020 at 14:32 Min-Yih Hsu via cfe-dev <
> 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), 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 valueint caller(int x) {
>>     foo(x)
>> }
>>
>>
>> ```
>> Please checkout the its wiki page (
>> 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
>> 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/5daf665a/attachment-0001.html>


More information about the cfe-dev mailing list