Split generator.h and generator.cpp
This commit is contained in:
parent
1ecf12b7f5
commit
f8678f2c3f
|
@ -7,14 +7,16 @@ set(LINK_TESTS_AGAINST_APP_TARGET ON)
|
||||||
|
|
||||||
# add project files
|
# add project files
|
||||||
set(HEADER_FILES
|
set(HEADER_FILES
|
||||||
generator.h
|
codegenerator.h
|
||||||
|
codefactory.h
|
||||||
frontendaction.h
|
frontendaction.h
|
||||||
consumer.h
|
consumer.h
|
||||||
visitor.h
|
visitor.h
|
||||||
clangversionabstraction.h
|
clangversionabstraction.h
|
||||||
)
|
)
|
||||||
set(SRC_FILES
|
set(SRC_FILES
|
||||||
generator.cpp
|
codegenerator.cpp
|
||||||
|
codefactory.cpp
|
||||||
frontendaction.cpp
|
frontendaction.cpp
|
||||||
consumer.cpp
|
consumer.cpp
|
||||||
clangversionabstraction.cpp
|
clangversionabstraction.cpp
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
#include "./codefactory.h"
|
||||||
|
#include "./frontendaction.h"
|
||||||
|
|
||||||
|
#include <clang/Basic/FileManager.h>
|
||||||
|
#include <clang/Frontend/FrontendActions.h>
|
||||||
|
#include <clang/Tooling/Tooling.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace ReflectiveRapidJSON {
|
||||||
|
|
||||||
|
struct CodeFactory::ToolInvocation {
|
||||||
|
ToolInvocation(CodeFactory &factory);
|
||||||
|
|
||||||
|
clang::FileManager fileManager;
|
||||||
|
clang::tooling::ToolInvocation invocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
CodeFactory::ToolInvocation::ToolInvocation(CodeFactory &factory)
|
||||||
|
: fileManager({ "." })
|
||||||
|
, invocation(factory.makeClangArgs(), new FrontendAction(factory), &fileManager)
|
||||||
|
{
|
||||||
|
fileManager.Retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeFactory::CodeFactory(
|
||||||
|
const char *applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<const char *> &clangOptions, std::ostream &os)
|
||||||
|
: m_applicationPath(applicationPath)
|
||||||
|
, m_sourceFiles(sourceFiles)
|
||||||
|
, m_clangOptions(clangOptions)
|
||||||
|
, m_os(os)
|
||||||
|
, m_compilerInstance(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeFactory::~CodeFactory()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Constructs arguments for the Clang tool invocation.
|
||||||
|
*/
|
||||||
|
std::vector<string> CodeFactory::makeClangArgs() const
|
||||||
|
{
|
||||||
|
static const initializer_list<const char *> flags
|
||||||
|
= { m_applicationPath, "-x", "c++", "-fPIE", "-fPIC", "-Wno-microsoft", "-Wno-pragma-once-outside-header", "-std=c++14", "-fsyntax-only" };
|
||||||
|
vector<string> clangArgs;
|
||||||
|
clangArgs.reserve(flags.size() + m_clangOptions.size() + m_sourceFiles.size());
|
||||||
|
clangArgs.insert(clangArgs.end(), flags.begin(), flags.end());
|
||||||
|
clangArgs.insert(clangArgs.end(), m_clangOptions.cbegin(), m_clangOptions.cend());
|
||||||
|
clangArgs.insert(clangArgs.end(), m_sourceFiles.cbegin(), m_sourceFiles.cend());
|
||||||
|
return clangArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Adds the specified \a decl to all underlying code generators. The generators might ignore irrelevant declarations.
|
||||||
|
* \remarks Supposed to be called by assigned generators inside readAST().
|
||||||
|
*/
|
||||||
|
void CodeFactory::addDeclaration(clang::Decl *decl)
|
||||||
|
{
|
||||||
|
for (const auto &generator : m_generators) {
|
||||||
|
generator->addDeclaration(decl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Reads (relevent) AST elements using Clang.
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
{
|
||||||
|
for (const auto &generator : m_generators) {
|
||||||
|
generator->generate(m_os);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ReflectiveRapidJSON
|
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef REFLECTIVE_RAPIDJSON_CODE_FACTORY_H
|
||||||
|
#define REFLECTIVE_RAPIDJSON_CODE_FACTORY_H
|
||||||
|
|
||||||
|
#include "./codegenerator.h"
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
class CompilerInstance;
|
||||||
|
} // namespace clang
|
||||||
|
|
||||||
|
namespace ReflectiveRapidJSON {
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The CodeFactory class produces additional (reflection) code for a specified list of C++ source files.
|
||||||
|
* \remarks
|
||||||
|
* - The code is written to a specified std::ostream instance.
|
||||||
|
* - The CodeFactory class is constituted by its underlying CodeGenerator instances.
|
||||||
|
*/
|
||||||
|
class CodeFactory {
|
||||||
|
public:
|
||||||
|
CodeFactory(
|
||||||
|
const char *applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<const char *> &clangOptions, std::ostream &os);
|
||||||
|
~CodeFactory();
|
||||||
|
|
||||||
|
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
|
||||||
|
template <typename GeneratorType> void addGenerator();
|
||||||
|
|
||||||
|
void addDeclaration(clang::Decl *decl);
|
||||||
|
bool readAST();
|
||||||
|
bool generate() const;
|
||||||
|
clang::CompilerInstance *compilerInstance();
|
||||||
|
void setCompilerInstance(clang::CompilerInstance *compilerInstance);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ToolInvocation;
|
||||||
|
|
||||||
|
std::vector<std::string> makeClangArgs() const;
|
||||||
|
|
||||||
|
const char *const m_applicationPath;
|
||||||
|
const std::vector<const char *> &m_sourceFiles;
|
||||||
|
const std::vector<const char *> &m_clangOptions;
|
||||||
|
std::ostream &m_os;
|
||||||
|
std::vector<std::unique_ptr<CodeGenerator>> m_generators;
|
||||||
|
std::unique_ptr<ToolInvocation> m_toolInvocation;
|
||||||
|
clang::CompilerInstance *m_compilerInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename GeneratorType> void CodeFactory::addGenerator()
|
||||||
|
{
|
||||||
|
m_generators.emplace_back(std::make_unique<GeneratorType>(*this));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators() const
|
||||||
|
{
|
||||||
|
return m_generators;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline clang::CompilerInstance *CodeFactory::compilerInstance()
|
||||||
|
{
|
||||||
|
return m_compilerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CodeFactory::setCompilerInstance(clang::CompilerInstance *compilerInstance)
|
||||||
|
{
|
||||||
|
m_compilerInstance = compilerInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ReflectiveRapidJSON
|
||||||
|
|
||||||
|
#endif // REFLECTIVE_RAPIDJSON_CODE_FACTORY_H
|
|
@ -1,21 +1,15 @@
|
||||||
#include "./generator.h"
|
#include "./codegenerator.h"
|
||||||
#include "./frontendaction.h"
|
|
||||||
|
|
||||||
#include "../lib/jsonserializable.h"
|
#include "../lib/jsonserializable.h"
|
||||||
|
|
||||||
#include <c++utilities/application/global.h>
|
#include <c++utilities/application/global.h>
|
||||||
#include <c++utilities/conversion/stringbuilder.h>
|
|
||||||
|
|
||||||
#include <clang/AST/DeclCXX.h>
|
#include <clang/AST/DeclCXX.h>
|
||||||
#include <clang/Basic/FileManager.h>
|
|
||||||
#include <clang/Frontend/FrontendActions.h>
|
|
||||||
#include <clang/Tooling/Tooling.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ConversionUtilities;
|
|
||||||
|
|
||||||
namespace ReflectiveRapidJSON {
|
namespace ReflectiveRapidJSON {
|
||||||
|
|
||||||
|
@ -112,82 +106,4 @@ void JSONSerializationCodeGenerator::generate(ostream &os) const
|
||||||
"} // namespace ReflectiveRapidJSON\n";
|
"} // namespace ReflectiveRapidJSON\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CodeFactory::ToolInvocation {
|
|
||||||
ToolInvocation(CodeFactory &factory);
|
|
||||||
|
|
||||||
clang::FileManager fileManager;
|
|
||||||
clang::tooling::ToolInvocation invocation;
|
|
||||||
};
|
|
||||||
|
|
||||||
CodeFactory::ToolInvocation::ToolInvocation(CodeFactory &factory)
|
|
||||||
: fileManager({ "." })
|
|
||||||
, invocation(factory.makeClangArgs(), new FrontendAction(factory), &fileManager)
|
|
||||||
{
|
|
||||||
fileManager.Retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeFactory::CodeFactory(
|
|
||||||
const char *applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<const char *> &clangOptions, std::ostream &os)
|
|
||||||
: m_applicationPath(applicationPath)
|
|
||||||
, m_sourceFiles(sourceFiles)
|
|
||||||
, m_clangOptions(clangOptions)
|
|
||||||
, m_os(os)
|
|
||||||
, m_compilerInstance(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeFactory::~CodeFactory()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Constructs arguments for the Clang tool invocation.
|
|
||||||
*/
|
|
||||||
std::vector<string> CodeFactory::makeClangArgs() const
|
|
||||||
{
|
|
||||||
static const initializer_list<const char *> flags
|
|
||||||
= { m_applicationPath, "-x", "c++", "-fPIE", "-fPIC", "-Wno-microsoft", "-Wno-pragma-once-outside-header", "-std=c++14", "-fsyntax-only" };
|
|
||||||
vector<string> clangArgs;
|
|
||||||
clangArgs.reserve(flags.size() + m_clangOptions.size() + m_sourceFiles.size());
|
|
||||||
clangArgs.insert(clangArgs.end(), flags.begin(), flags.end());
|
|
||||||
clangArgs.insert(clangArgs.end(), m_clangOptions.cbegin(), m_clangOptions.cend());
|
|
||||||
clangArgs.insert(clangArgs.end(), m_sourceFiles.cbegin(), m_sourceFiles.cend());
|
|
||||||
return clangArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Adds the specified \a decl to all underlying code generators. The generators might ignore irrelevant declarations.
|
|
||||||
* \remarks Supposed to be called by assigned generators inside readAST().
|
|
||||||
*/
|
|
||||||
void CodeFactory::addDeclaration(clang::Decl *decl)
|
|
||||||
{
|
|
||||||
for (const auto &generator : m_generators) {
|
|
||||||
generator->addDeclaration(decl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Reads (relevent) AST elements using Clang.
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
{
|
|
||||||
for (const auto &generator : m_generators) {
|
|
||||||
generator->generate(m_os);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ReflectiveRapidJSON
|
} // namespace ReflectiveRapidJSON
|
|
@ -1,8 +1,7 @@
|
||||||
#ifndef REFLECTIVE_RAPIDJSON_GENERATOR_H
|
#ifndef REFLECTIVE_RAPIDJSON_CODE_GENERATOR_H
|
||||||
#define REFLECTIVE_RAPIDJSON_GENERATOR_H
|
#define REFLECTIVE_RAPIDJSON_CODE_GENERATOR_H
|
||||||
|
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -10,7 +9,6 @@ namespace clang {
|
||||||
class Decl;
|
class Decl;
|
||||||
class NamedDecl;
|
class NamedDecl;
|
||||||
class CXXRecordDecl;
|
class CXXRecordDecl;
|
||||||
class CompilerInstance;
|
|
||||||
} // namespace clang
|
} // namespace clang
|
||||||
|
|
||||||
namespace ReflectiveRapidJSON {
|
namespace ReflectiveRapidJSON {
|
||||||
|
@ -81,61 +79,6 @@ inline JSONSerializationCodeGenerator::RelevantClass::RelevantClass(const std::s
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief The CodeFactory class produces additional (reflection) code for a specified list of C++ source files.
|
|
||||||
* \remarks
|
|
||||||
* - The code is written to a specified std::ostream instance.
|
|
||||||
* - The CodeFactory class is constituted by its underlying CodeGenerator instances.
|
|
||||||
*/
|
|
||||||
class CodeFactory {
|
|
||||||
public:
|
|
||||||
CodeFactory(
|
|
||||||
const char *applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<const char *> &clangOptions, std::ostream &os);
|
|
||||||
~CodeFactory();
|
|
||||||
|
|
||||||
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
|
|
||||||
template <typename GeneratorType> void addGenerator();
|
|
||||||
|
|
||||||
void addDeclaration(clang::Decl *decl);
|
|
||||||
bool readAST();
|
|
||||||
bool generate() const;
|
|
||||||
clang::CompilerInstance *compilerInstance();
|
|
||||||
void setCompilerInstance(clang::CompilerInstance *compilerInstance);
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct ToolInvocation;
|
|
||||||
|
|
||||||
std::vector<std::string> makeClangArgs() const;
|
|
||||||
|
|
||||||
const char *const m_applicationPath;
|
|
||||||
const std::vector<const char *> &m_sourceFiles;
|
|
||||||
const std::vector<const char *> &m_clangOptions;
|
|
||||||
std::ostream &m_os;
|
|
||||||
std::vector<std::unique_ptr<CodeGenerator>> m_generators;
|
|
||||||
std::unique_ptr<ToolInvocation> m_toolInvocation;
|
|
||||||
clang::CompilerInstance *m_compilerInstance;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename GeneratorType> void CodeFactory::addGenerator()
|
|
||||||
{
|
|
||||||
m_generators.emplace_back(std::make_unique<GeneratorType>(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators() const
|
|
||||||
{
|
|
||||||
return m_generators;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline clang::CompilerInstance *CodeFactory::compilerInstance()
|
|
||||||
{
|
|
||||||
return m_compilerInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void CodeFactory::setCompilerInstance(clang::CompilerInstance *compilerInstance)
|
|
||||||
{
|
|
||||||
m_compilerInstance = compilerInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ReflectiveRapidJSON
|
} // namespace ReflectiveRapidJSON
|
||||||
|
|
||||||
#endif // REFLECTIVE_RAPIDJSON_GENERATOR_H
|
#endif // REFLECTIVE_RAPIDJSON_CODE_GENERATOR_H
|
|
@ -1,6 +1,6 @@
|
||||||
#include "./frontendaction.h"
|
#include "./frontendaction.h"
|
||||||
|
#include "./codefactory.h"
|
||||||
#include "./consumer.h"
|
#include "./consumer.h"
|
||||||
#include "./generator.h"
|
|
||||||
|
|
||||||
#include <c++utilities/application/global.h>
|
#include <c++utilities/application/global.h>
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "./generator.h"
|
#include "./codefactory.h"
|
||||||
|
|
||||||
#include "resources/config.h"
|
#include "resources/config.h"
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "../generator.h"
|
#include "../codefactory.h"
|
||||||
|
|
||||||
#include "../../lib/jsonserializable.h"
|
#include "../../lib/jsonserializable.h"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include "./visitor.h"
|
#include "./visitor.h"
|
||||||
#include "./generator.h"
|
#include "./codefactory.h"
|
||||||
|
|
||||||
#include <c++utilities/application/global.h>
|
#include <c++utilities/application/global.h>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue