-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
The current implementation of the plugin correctly handles inline and implicit destructors, however modifications made to non-inline destructors don't actually propagate to the code generation phase.
struct MyClass
{
vector<char> myData;
// This dtor is non-inline, and doesn't get annotated properly
~MyClass();
};
MyClass::~MyClass() {
// ...
}Minimal Example
This issue is not specific to destructor calls, but instead applies to all non-inline functions.
See https://github.com/codeinred/minimal_clang_plugin for a complete implementation that demonstrates and explains this issue.
Planned Solution
The planned solution right now is to use a similar trick as to clad, wherein we steal and then modify the multiplexer such that we can ensure the plugin runs first:
void CladPlugin::Initialize(clang::ASTContext& C) {
// We know we have a multiplexer. We commit a sin here by stealing it and
// making the consumer pass-through so that we can delay all operations
// until clad is happy.
auto& MultiplexC = cast<MultiplexConsumer>(m_CI.getASTConsumer());
auto& RobbedCs = ACCESS(MultiplexC, Consumers);
assert(RobbedCs.back().get() == this && "Clad is not the last consumer");
std::vector<std::unique_ptr<ASTConsumer>> StolenConsumers;
// The range-based for loop in MultiplexConsumer::Initialize has
// dispatched this call. Generally, it is unsafe to delete elements while
// iterating but we know we are in the end of the loop and ::end() won't
// be invalidated.
std::move(RobbedCs.begin(), RobbedCs.end() - 1,
std::back_inserter(StolenConsumers));
RobbedCs.erase(RobbedCs.begin(), RobbedCs.end() - 1);
m_Multiplexer.reset(new MultiplexConsumer(std::move(StolenConsumers)));
}Metadata
Metadata
Assignees
Labels
No labels