[cfe-dev] AST modifications that apply to the binary
John Brawn via cfe-dev
cfe-dev at lists.llvm.org
Thu Dec 1 10:07:01 PST 2016
What's happening here is some slightly non-obvious behaviour in how ASTConsumers are used.
In brief:
* Adding a PluginASTAction means we get a MultiplexConsumer whose list of consumers
is FuncnameChangeAction then the main action
* This means that for each of the HandleXXX functions it calls the HandleXXX function on the
FuncnameChangeAction then the main action
* clang::parseAST is where it ultimately ends up using the MultiplexConsumer and there it
calls HandleTopLevelDecl on each DeclGroup then calls HandleTranslationUnit
* You've done your transformation in HandleTranslationUnit, but CodeGenAction generates code
in HandleTopLevelDecl, so though your HandleTranslationUnit is called before the CodeGenAction's
HandleTranslationUnit it doesn't matter because the code has already been generated.
* Doing the transformation in HandleTopLevelDecl works
(I myself didn't realise that this would happen, I only figured it out by running clang in a debugger,
setting breakpoints at various places and trying to figure out what was going on.)
John
From: Ori Zaig [mailto:oriz at mellanox.com]
Sent: 28 November 2016 12:58
To: John Brawn
Cc: Eran Jakoby; nd; cfe-dev at lists.llvm.org
Subject: RE: AST modifications that apply to the binary
Unfortunately it doesn't work - maybe I'm missing something...
I added the getActionType method:
class FuncnameChangeAction: public PluginASTAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
return llvm::make_unique< FuncnameChangeConsumer >(CI, &CI.getSourceManager());
}
bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string> &args) override {
return true;
}
virtual ActionType getActionType() override { return AddBeforeMainAction; }
};
And used the below command line:
clang++ -Xclang -load -Xclang ModifyFunc.so -Xclang -add-plugin -Xclang modify-func -c some_code.cpp -o some_code.o
And yet, changes were not reflected in the binary (some_code.o) or even in IR
Any other ideas please?
From: John Brawn [mailto:John.Brawn at arm.com]
Sent: Wednesday, November 23, 2016 7:14 PM
To: Ori Zaig <oriz at mellanox.com<mailto:oriz at mellanox.com>>
Cc: Eran Jakoby <eranj at mellanox.com<mailto:eranj at mellanox.com>>; nd <nd at arm.com<mailto:nd at arm.com>>; cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
Subject: RE: AST modifications that apply to the binary
By default a PluginASTAction will replace the main AST action (if you use -plugin pluginname on the
cc1 command line) or go after the main AST action (if you use -add-plugin pluginname on the cc1
command line), where the "main AST action" is "generate an object file" if using -c, "generate
assembly" is using -S, etc.
If you want the PluginASTAction to go before the main AST action, i.e. you want it to change the
AST in a way that will affect the compiled output, then define a getActionType method in the
PluginASTAction which returns AddBeforeMainAction.
John
From: cfe-dev [mailto:cfe-dev-bounces at lists.llvm.org] On Behalf Of Ori Zaig via cfe-dev
Sent: 20 November 2016 16:49
To: cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
Cc: Eran Jakoby
Subject: [cfe-dev] AST modifications that apply to the binary
Hi all
Is there any possible making AST modification that finally will be reflected in the binary?
I tried doing that via plugin, for instance changing a method name (let's say turn foo() to my_foo() ) such:
class FuncnameChangeVisitor : public RecursiveASTVisitor< FuncnameChangeVisitor > {
private:
ASTContext *m_context;
public:
/* some code */
bool VisitFunctionDecl(FunctionDecl *f) {
DeclarationNameInfo newNameInfo(f->getNameInfo());
DeclarationName origName(f->getDeclName());
std::string newName("my_");
newName += origName.getAsString();
IdentifierInfo& newNameIdInfo(m_context->Idents.get(StringRef(newName.c_str())));
f->setDeclName(DeclarationName(&newNameIdInfo));
return true;
}
};
class FuncnameChangeConsumer: public ASTConsumer {
private:
FuncnameChangeVisitor m_visitor;
public:
/* some code*/
virtual void HandleTranslationUnit(ASTContext &Cntx) {
m_visitor.TraverseDecl(Cntx.getTranslationUnitDecl());
}
};
class FuncnameChangeAction: public PluginASTAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
return llvm::make_unique< FuncnameChangeConsumer >(CI, &CI.getSourceManager());
}
bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string> &args) override {
return true;
}
};
static FrontendPluginRegistry::Add< FuncnameChangeAction > reg("modify-func", "add my_ prefix to funtions");
But in vain... I understood that the IR and hence the binary are generated regardless the plugins
And if there isn't a way to do so, is there another way via Clang to make code-modifications that affect the binary, which are not source-to-source compilation?
Tnx
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20161201/2733d1d7/attachment.html>
More information about the cfe-dev
mailing list