WIP: Experiment with annotations

This commit is contained in:
Martchus 2021-05-13 17:56:48 +02:00
parent a4dd52acfa
commit a6461795a7
4 changed files with 34 additions and 1 deletions

View File

@ -127,6 +127,9 @@ void BinarySerializationCodeGenerator::generate(ostream &os) const
os << " // write members\n";
auto membersWritten = false;
for (const clang::FieldDecl *field : relevantClass.record->fields()) {
for (const auto &attr : field->getAttrs()) {
cout << " // annotation: " << readAnnotation(attr) << '\n';
}
if (writePrivateMembers || field->getAccess() == clang::AS_public) {
os << " serializer.write(customObject." << field->getName() << ");\n";
membersWritten = true;

View File

@ -3,8 +3,10 @@
#include <c++utilities/application/global.h>
#include <clang/AST/Attr.h>
#include <clang/AST/DeclCXX.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Lex/Lexer.h>
using namespace std;
@ -24,7 +26,7 @@ void CodeGenerator::addDeclaration(clang::Decl *decl)
/*!
* \brief Lazy initializes the source manager.
* \remarks This method must be called in generate() when subclassing to make use of isOnlyIncluded().
* \remarks This method must be called in generate() when subclassing to make use of isOnlyIncluded() and readAnnotation().
*/
void CodeGenerator::lazyInitializeSourceManager() const
{
@ -42,6 +44,21 @@ bool CodeGenerator::isOnlyIncluded(const clang::Decl *declaration) const
&& m_sourceManager->getFileID(m_sourceManager->getExpansionLoc(declaration->getSourceRange().getBegin())) != m_sourceManager->getMainFileID();
}
/*!
* \brief Returns the specified \a annotation's text.
*/
std::string_view CodeGenerator::readAnnotation(const clang::Attr *annotation) const
{
if (!m_sourceManager) {
return std::string_view();
}
auto text = clang::Lexer::getSourceText(clang::CharSourceRange::getTokenRange(annotation->getRange()), *sourceManager(), clang::LangOptions());
if (text.size() >= 12 && text.startswith("annotate(\"") && text.endswith("\")")) {
text = text.substr(10, text.size() - 12);
}
return text;
}
/*!
* \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).

View File

@ -6,6 +6,7 @@
#include <vector>
namespace clang {
class Attr;
class Decl;
class CXXRecordDecl;
class SourceManager;
@ -32,6 +33,8 @@ protected:
CodeFactory &factory() const;
void lazyInitializeSourceManager() const;
bool isOnlyIncluded(const clang::Decl *declaration) const;
std::string_view readAnnotation(const clang::Attr *annotation) const;
const clang::SourceManager *sourceManager() const;
static bool inheritsFromInstantiationOf(clang::CXXRecordDecl *record, const char *templateClass);
private:
@ -50,6 +53,11 @@ inline CodeFactory &CodeGenerator::factory() const
return m_factory;
}
inline const clang::SourceManager *CodeGenerator::sourceManager() const
{
return m_sourceManager;
}
} // namespace ReflectiveRapidJSON
#endif // REFLECTIVE_RAPIDJSON_CODE_GENERATOR_H

View File

@ -67,4 +67,9 @@ struct PointerStruct : public BinarySerializable<PointerStruct> {
std::shared_ptr<PointerTarget> s3;
};
struct AnnotatedStruct : public BinarySerializable<AnnotatedStruct> {
int anyVersion;
__attribute__((annotate("cond:version >= 1"))) __attribute__((annotate("foo"))) int newInVersion1;
};
#endif // REFLECTIVE_RAPIDJSON_TESTS_MORE_STRUCTS_H