Prevent code generator for records which are only included
This commit is contained in:
parent
bae7cf3414
commit
5f799cc65d
|
@ -1,8 +1,10 @@
|
||||||
#include "./codegenerator.h"
|
#include "./codegenerator.h"
|
||||||
|
#include "./codefactory.h"
|
||||||
|
|
||||||
#include <c++utilities/application/global.h>
|
#include <c++utilities/application/global.h>
|
||||||
|
|
||||||
#include <clang/AST/DeclCXX.h>
|
#include <clang/AST/DeclCXX.h>
|
||||||
|
#include <clang/Frontend/CompilerInstance.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -20,6 +22,26 @@ void CodeGenerator::addDeclaration(clang::Decl *decl)
|
||||||
VAR_UNUSED(decl)
|
VAR_UNUSED(decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Lazy initializes the source manager.
|
||||||
|
* \remarks This method must be called in generate() when subclassing to make use of isOnlyIncluded().
|
||||||
|
*/
|
||||||
|
void CodeGenerator::lazyInitializeSourceManager() const
|
||||||
|
{
|
||||||
|
if (factory().compilerInstance()) {
|
||||||
|
const_cast<CodeGenerator *>(this)->m_sourceManager = &factory().compilerInstance()->getSourceManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns whether the specified \a declaration is only included and not part of the actual file.
|
||||||
|
*/
|
||||||
|
bool CodeGenerator::isOnlyIncluded(const clang::Decl *declaration) const
|
||||||
|
{
|
||||||
|
return m_sourceManager
|
||||||
|
&& m_sourceManager->getFileID(m_sourceManager->getExpansionLoc(declaration->getSourceRange().getBegin())) != m_sourceManager->getMainFileID();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns whether the specified \a record inherits from an instantiation of the specified \a templateClass.
|
* \brief Returns whether the specified \a record inherits from an instantiation of the specified \a templateClass.
|
||||||
* \remarks The specified \a record must be defined (not only forward-declared).
|
* \remarks The specified \a record must be defined (not only forward-declared).
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class Decl;
|
class Decl;
|
||||||
class CXXRecordDecl;
|
class CXXRecordDecl;
|
||||||
|
class SourceManager;
|
||||||
} // namespace clang
|
} // namespace clang
|
||||||
|
|
||||||
namespace ReflectiveRapidJSON {
|
namespace ReflectiveRapidJSON {
|
||||||
|
@ -29,14 +30,18 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CodeFactory &factory() const;
|
CodeFactory &factory() const;
|
||||||
|
void lazyInitializeSourceManager() const;
|
||||||
|
bool isOnlyIncluded(const clang::Decl *declaration) const;
|
||||||
static bool inheritsFromInstantiationOf(clang::CXXRecordDecl *record, const char *templateClass);
|
static bool inheritsFromInstantiationOf(clang::CXXRecordDecl *record, const char *templateClass);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CodeFactory &m_factory;
|
CodeFactory &m_factory;
|
||||||
|
const clang::SourceManager *m_sourceManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline CodeGenerator::CodeGenerator(CodeFactory &factory)
|
inline CodeGenerator::CodeGenerator(CodeFactory &factory)
|
||||||
: m_factory(factory)
|
: m_factory(factory)
|
||||||
|
, m_sourceManager(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,11 @@ void JsonSerializationCodeGenerator::addDeclaration(clang::Decl *decl)
|
||||||
*/
|
*/
|
||||||
string JsonSerializationCodeGenerator::qualifiedNameIfRelevant(clang::CXXRecordDecl *record) const
|
string JsonSerializationCodeGenerator::qualifiedNameIfRelevant(clang::CXXRecordDecl *record) const
|
||||||
{
|
{
|
||||||
|
// skip all classes which are only included
|
||||||
|
if (isOnlyIncluded(record)) {
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
// consider all classes inheriting from an instantiation of "JsonSerializable" relevant
|
// consider all classes inheriting from an instantiation of "JsonSerializable" relevant
|
||||||
if (inheritsFromInstantiationOf(record, JsonSerializable<void>::qualifiedName)) {
|
if (inheritsFromInstantiationOf(record, JsonSerializable<void>::qualifiedName)) {
|
||||||
return record->getQualifiedNameAsString();
|
return record->getQualifiedNameAsString();
|
||||||
|
@ -143,6 +148,9 @@ ostream &operator<<(ostream &os, llvm::StringRef str)
|
||||||
*/
|
*/
|
||||||
void JsonSerializationCodeGenerator::generate(ostream &os) const
|
void JsonSerializationCodeGenerator::generate(ostream &os) const
|
||||||
{
|
{
|
||||||
|
// initialize source manager to make use of isOnlyIncluded() for skipping records which are only included
|
||||||
|
lazyInitializeSourceManager();
|
||||||
|
|
||||||
// find relevant classes
|
// find relevant classes
|
||||||
const auto relevantClasses = findRelevantClasses();
|
const auto relevantClasses = findRelevantClasses();
|
||||||
if (relevantClasses.empty()) {
|
if (relevantClasses.empty()) {
|
||||||
|
|
|
@ -46,18 +46,18 @@ private:
|
||||||
const Options &m_options;
|
const Options &m_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void JsonSerializationCodeGenerator::Options::appendTo(ApplicationUtilities::Argument *arg)
|
|
||||||
{
|
|
||||||
arg->addSubArgument(&additionalClassesArg);
|
|
||||||
arg->addSubArgument(&visibilityArg);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline JsonSerializationCodeGenerator::JsonSerializationCodeGenerator(CodeFactory &factory, const Options &options)
|
inline JsonSerializationCodeGenerator::JsonSerializationCodeGenerator(CodeFactory &factory, const Options &options)
|
||||||
: CodeGenerator(factory)
|
: CodeGenerator(factory)
|
||||||
, m_options(options)
|
, m_options(options)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void JsonSerializationCodeGenerator::Options::appendTo(ApplicationUtilities::Argument *arg)
|
||||||
|
{
|
||||||
|
arg->addSubArgument(&additionalClassesArg);
|
||||||
|
arg->addSubArgument(&visibilityArg);
|
||||||
|
}
|
||||||
|
|
||||||
inline JsonSerializationCodeGenerator::RelevantClass::RelevantClass(std::string &&qualifiedName, clang::CXXRecordDecl *record)
|
inline JsonSerializationCodeGenerator::RelevantClass::RelevantClass(std::string &&qualifiedName, clang::CXXRecordDecl *record)
|
||||||
: qualifiedName(qualifiedName)
|
: qualifiedName(qualifiedName)
|
||||||
, record(record)
|
, record(record)
|
||||||
|
|
Loading…
Reference in New Issue