Main Question
I am trying to build a clang plugin as per the instructions here, but I am encountering linker errors when I try to build.
These are the errors:
/tmp/Test-1ea47e.o: In function `ASTFrontendAction':
/usr/lib/llvm-3.4/include/clang/Frontend/FrontendAction.h:216: undefined reference to `clang::FrontendAction::FrontendAction()'
/tmp/Test-1ea47e.o: In function `~TestPlugin':
/home/path/to/plugin/Test.cpp:12: undefined reference to `clang::FrontendAction::~FrontendAction()'
/tmp/Test-1ea47e.o:(.data.rel.ro+0x20): undefined reference to `clang::FrontendAction::~FrontendAction()'
/tmp/Test-1ea47e.o:(.data.rel.ro+0x50): undefined reference to `typeinfo for clang::PluginASTAction'
My class is TestPlugin
(code is below), and it extends from three abstract library classes in the following chain: FrontendAction
> ASTFrontendAction
> PluginASTAction
> TestPlugin
. I would have expected that since the library classes are abstract, their constructors and destructors would never be needed, but I am fairly new to C++, so kindly correct me, if I'm wrong. What might be causing these linker errors?
Supplementary Info
For background: the instructions I'm following are meant for clang 3.7, but I am on the standard Ubuntu distribution of clang 3.4, so that could be part of the problem. The unmodified tutorial code wouldn't even compile, so I had to make a number of changes (mostly deletions) to get this far, but I am still getting the aforementioned errors during linking.
Here is my entire plugin file (some whitespace condensed for brevity)
Test.cpp
:
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
namespace {
class TestPlugin: public PluginASTAction {
private:
void anchor(){}
protected:
ASTConsumer* CreateASTConsumer(CompilerInstance &CI, llvm::StringRef){ return NULL; }
void ExecuteAction(){ return; }
bool shouldEraseOutputFiles(){ return false; }
public:
bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string>& args){ return true; }
};
}
static FrontendPluginRegistry::Add<TestPlugin>
X("test-stuff", "Does some test stuff");
int main(){ return 0; }
And here are the relevant parts (I think) of the library code from which mine inherits
FrontendAction.h
:
//////// snip ////////
namespace clang {
class FrontendAction {
//////// snip ////////
public:
FrontendAction();
virtual ~FrontendAction();
virtual bool usesPreprocessorOnly() const = 0;
//////// snip ////////
}; // class FrontendAction
class ASTFrontendAction : public FrontendAction {
protected:
virtual void ExecuteAction();
public:
virtual bool usesPreprocessorOnly() const { return false; }
}; // class ASTFrontendAction
class PluginASTAction : public ASTFrontendAction {
virtual void anchor();
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef InFile) = 0;
public:
virtual bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string> &arg) = 0;
}; // class PluginASTAction
//////// snip ////////
} // namespace clang
I'm Happy to provide any other information that might be useful.
Aucun commentaire:
Enregistrer un commentaire