Don't call generator when declarations already deleted

This commit is contained in:
Martchus 2017-10-27 17:38:57 +02:00
parent 31c37a8ee4
commit fe40840486
6 changed files with 34 additions and 32 deletions

View File

@ -66,20 +66,7 @@ void CodeFactory::addDeclaration(clang::Decl *decl)
} }
/*! /*!
* \brief Reads (relevent) AST elements using Clang. * \brief Generates code based on the added declarations.
*/
bool CodeFactory::readAST()
{
// lazy initialize Clang tool invocation
if (!m_toolInvocation) {
m_toolInvocation = make_unique<ToolInvocation>(*this);
}
// run Clang
return m_toolInvocation->invocation.run();
}
/*!
* \brief Generates code based on the AST elements which have been read by invoking readAST().
*/ */
bool CodeFactory::generate() const bool CodeFactory::generate() const
{ {
@ -89,4 +76,17 @@ bool CodeFactory::generate() const
return true; return true;
} }
/*!
* \brief Reads (relevent) AST elements using Clang and generates code.
*/
bool CodeFactory::run()
{
// lazy initialize Clang tool invocation
if (!m_toolInvocation) {
m_toolInvocation = make_unique<ToolInvocation>(*this);
}
// run Clang
return m_toolInvocation->invocation.run();
}
} // namespace ReflectiveRapidJSON } // namespace ReflectiveRapidJSON

View File

@ -14,6 +14,9 @@ class CompilerInstance;
namespace ReflectiveRapidJSON { namespace ReflectiveRapidJSON {
class Consumer;
class Visitor;
/*! /*!
* \brief The CodeFactory class produces additional (reflection) code for a specified list of C++ source files. * \brief The CodeFactory class produces additional (reflection) code for a specified list of C++ source files.
* \remarks * \remarks
@ -21,6 +24,9 @@ namespace ReflectiveRapidJSON {
* - The CodeFactory class is constituted by its underlying CodeGenerator instances. * - The CodeFactory class is constituted by its underlying CodeGenerator instances.
*/ */
class CodeFactory { class CodeFactory {
friend class Consumer;
friend class Visitor;
public: public:
CodeFactory( CodeFactory(
const char *applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<const char *> &clangOptions, std::ostream &os); const char *applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<const char *> &clangOptions, std::ostream &os);
@ -29,15 +35,15 @@ public:
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const; const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
template <typename GeneratorType> void addGenerator(); template <typename GeneratorType> void addGenerator();
void addDeclaration(clang::Decl *decl); bool run();
bool readAST();
bool generate() const;
clang::CompilerInstance *compilerInstance(); clang::CompilerInstance *compilerInstance();
void setCompilerInstance(clang::CompilerInstance *compilerInstance); void setCompilerInstance(clang::CompilerInstance *compilerInstance);
private: private:
struct ToolInvocation; struct ToolInvocation;
void addDeclaration(clang::Decl *decl);
bool generate() const;
std::vector<std::string> makeClangArgs() const; std::vector<std::string> makeClangArgs() const;
const char *const m_applicationPath; const char *const m_applicationPath;

View File

@ -123,7 +123,7 @@ std::vector<const JSONSerializationCodeGenerator::RelevantClass *> JSONSerializa
{ {
vector<const RelevantClass *> relevantBaseClasses; vector<const RelevantClass *> relevantBaseClasses;
for (const RelevantClass &otherClass : m_relevantClasses) { for (const RelevantClass &otherClass : m_relevantClasses) {
if (relevantClass.record->isDerivedFrom(otherClass.record)) { if (relevantClass.record != otherClass.record && relevantClass.record->isDerivedFrom(otherClass.record)) {
relevantBaseClasses.push_back(&otherClass); relevantBaseClasses.push_back(&otherClass);
} }
} }

View File

@ -1,4 +1,5 @@
#include "./consumer.h" #include "./consumer.h"
#include "./codefactory.h"
#include <clang/AST/ASTContext.h> #include <clang/AST/ASTContext.h>
#include <clang/AST/DeclCXX.h> #include <clang/AST/DeclCXX.h>
@ -29,6 +30,12 @@ bool Consumer::HandleTopLevelDecl(clang::DeclGroupRef groupRefDecl)
return clang::ASTConsumer::HandleTopLevelDecl(groupRefDecl); return clang::ASTConsumer::HandleTopLevelDecl(groupRefDecl);
} }
void Consumer::HandleTranslationUnit(clang::ASTContext &context)
{
m_visitor.TraverseDecl(context.getTranslationUnitDecl());
m_factory.generate();
}
void DiagConsumer::BeginSourceFile(const clang::LangOptions &langOpts, const clang::Preprocessor *pp) void DiagConsumer::BeginSourceFile(const clang::LangOptions &langOpts, const clang::Preprocessor *pp)
{ {
m_proxy->BeginSourceFile(langOpts, pp); m_proxy->BeginSourceFile(langOpts, pp);

View File

@ -44,11 +44,6 @@ inline Consumer::Consumer(CodeFactory &factory, clang::CompilerInstance &compile
{ {
} }
inline void Consumer::HandleTranslationUnit(clang::ASTContext &context)
{
m_visitor.TraverseDecl(context.getTranslationUnitDecl());
}
/*! /*!
* \brief The DiagConsumer class changes most errors into warnings. * \brief The DiagConsumer class changes most errors into warnings.
* \remarks This class is based on MocDiagConsumer from https://github.com/woboq/moc-ng. * \remarks This class is based on MocDiagConsumer from https://github.com/woboq/moc-ng.

View File

@ -77,18 +77,12 @@ int main(int argc, char *argv[])
factory.addGenerator<JSONSerializationCodeGenerator>(); factory.addGenerator<JSONSerializationCodeGenerator>();
} }
// read AST elements from input files // read AST elements from input files and run the code generator
if (!factory.readAST()) { if (!factory.run()) {
cerr << Phrases::Error << "Errors occured when parsing the input file." << Phrases::EndFlush; cerr << Phrases::Error << "Errors occured." << Phrases::EndFlush;
return -2; return -2;
} }
// run the code generator
if (!factory.generate()) {
cerr << Phrases::Error << "Errors occured when during code generation." << Phrases::EndFlush;
return -3;
}
} catch (...) { } catch (...) {
catchIoFailure(); catchIoFailure();
const char *errorMessage; const char *errorMessage;