2017-10-11 2 views
2

Comment l'état de l'art dans la transformation source-à-source avec clang? J'ai suivi presque toutes les ressources sur le Web et je peux réaliser des réécritures source (Rewriter) via un plugin clang, mais le binaire final n'est pas mis à jour (le CodeGen est l'activité principale, et il est compilé indépendamment de ce que J'ai modifié dans mon plugin, même en utilisant AddBeforeMainAction dans le getActionType).Transformation source-à-source avec clang (état de la technique)

J'ai vu quelques documents concernant libTooling et comment créer un programme indépendant qui utilise clang comme bibliothèque, mais mon but c'est de créer un plugin (FrontendPluginRegistry::Add<>, quelque chose "facile" à brancher à un binaire clang non personnalisé) et réaliser des modifications de source à source (de manière transparente pour les utilisateurs, en évitant d'écraser leurs fichiers sources).

Modifier: Dans le cas où il est clair: je besoin de quelque chose comme un « plug-in » d'étendre tintement d'une manière facile. J'ai besoin de quelque chose qui est "intégré" dans le processus de compilation. Pourquoi? parce que j'ai besoin de modifier le code source pendant la phase de compilation, injecter du nouveau code, modifier le code source de l'utilisateur en une seule étape (je ne veux pas créer un outil pour analyser le code source de l'utilisateur) . Aussi, je voudrais distribuer mon code (plugin) pour permettre aux utilisateurs de l'utiliser par eux-mêmes.

Il est obligatoire que ce soit pendant la phase de compilation de clang (clang $FLAGS $PLUGIN $ETC -o program source_files...).

+0

Final binaire de quoi? Bruit? Le programme en cours de modification? Pourquoi est-ce un problème? –

+0

Je modifie la question. J'espère que vous comprenez maintenant ce dont j'ai besoin. – user3819881

+0

Je vois. Vous voulez un plugin d'exécution à Clang pour implémenter les transformations source-à-source lors de la compilation. OK, je comprends. Je m'attendrais à ce que cela soit très difficile à faire, puisque la machine de transformation Clang fait largement appel à des méthodes compilées dans les classes Clang, et sûrement "vous" voudrez écrire un type de code source pour réaliser les transformations interprétées lors de l'exécution . Qui sera intermédiaire entre le texte source que vous écrivez et le code Clang compilé? Le "obligatoire lors de la compilation" semble être un problème XY ... pourquoi insistez-vous là-dessus? –

Répondre

0

le CodeGen est l'activité principale, et il est peu importe ce que compilé je l'ai modifié mon plugin

Oui, c'est parce que Clang AST est conçu pour être immuable. Vous ne pouvez pas le changer après l'analyse.

état donc de l'art s2s transformation Clang ressemble que:

  • Parse C++ code source AST
  • Appliquer le remplacement de texte au code source d'origine, générer un nouveau code source
  • Parse nouvelle source code pour créer un nouvel AST

Vous pouvez effectuer toutes les étapes «en mémoire», de sorte que l'utilisateur final ne s'en apercevra pas.

Mise à jour: Je n'ai jamais écrit de plugins clang moi-même. Mais voici ce que je l'ai remarqué: Si vous exécutez Clang affrontée pour générer effectivement le code objet:

clang -cc1 -emit-obj main.c 

Il courrai EmitObjAction. EmitObjAction est une action FrontEnd, donc il va analyser la source d'entrée et exécuter codegen. Donc, si vous exécutez d'autres actions FrontEnd en parallèle, elles n'auront aucun effet sur EmitObjAction. Parce que chaque action FrontEnd analyse le code source d'origine.

Ce que vous pouvez faire, c'est de remplacer EmitObjAction par votre propre fork qui fera autant de ré-analyse que vous le souhaitez.

Si vous définissez PluginASTAction :: ActionType sur ReplaceAction, il doit remplacer l'action Codegen intégrée par votre propre fourni depuis le plugin.

+0

Ok, pouvez-vous me montrer un exemple (repo, code) qui fait cela? Quand j'utilise Rewriter, je modifie le code source en mémoire, mais l'AST de Clang n'est pas modifié. Pouvez-vous élaborer avec un «exemple réel», peut être aussi basique que vous le souhaitez, mais il doit s'agir d'un plugin et le faire en une seule étape (lorsque l'utilisateur compile sa source). – user3819881

+0

En outre, vous pouvez me guider sur la manière de "déclencher" le reparsing après la fin de mon plugin. @au hasard – user3819881