diff --git a/AthenaCore.pri b/AthenaCore.pri index 3a30e01..2b43eed 100644 --- a/AthenaCore.pri +++ b/AthenaCore.pri @@ -62,7 +62,8 @@ HEADERS += \ $$PWD/include/utf8/unchecked.h \ $$PWD/include/Athena/FileInfo.hpp \ $$PWD/include/Athena/Dir.hpp \ - $$PWD/include/gekko_support.h + $$PWD/include/gekko_support.h \ + $$PWD/include/Athena/DNA.hpp win32:HEADERS += \ $$PWD/include/win32_largefilewrapper.h diff --git a/atdna/atdna.pro b/atdna/atdna.pro new file mode 100644 index 0000000..c19b807 --- /dev/null +++ b/atdna/atdna.pro @@ -0,0 +1,47 @@ +TEMPLATE = app +CONFIG += console c++11 +CONFIG -= app_bundle +CONFIG -= qt +QT = +DEFINES += __STDC_LIMIT_MACROS=1 __STDC_CONSTANT_MACROS=1 +QMAKE_CXXFLAGS += -fno-rtti +QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter + +INCLUDEPATH += ../include /run/media/jacko/Extra/llvm-build/usr/include + +SOURCES += \ + main.cpp + +LIBS += -L/run/media/jacko/Extra/llvm-build/usr/lib \ + -lclangFrontendTool -lclangFrontend -lclangTooling -lclangDriver \ + -lclangSerialization -lclangCodeGen -lclangParse -lclangSema \ + -lclangRewriteFrontend -lclangRewrite -lclangAnalysis -lclangEdit \ + -lclangAST -lclangLex -lclangBasic \ + -lLLVMLTO -lLLVMObjCARCOpts -lLLVMLinker -lLLVMBitWriter -lLLVMIRReader \ + -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo \ + -lLLVMXCoreAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen \ + -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter \ + -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc \ + -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen \ + -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter \ + -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter \ + -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter \ + -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc \ + -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen \ + -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo \ + -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMBPFAsmPrinter -lLLVMARMDisassembler \ + -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter \ + -lLLVMAMDGPUCodeGen -lLLVMAMDGPUAsmParser -lLLVMAMDGPUDesc -lLLVMAMDGPUInfo \ + -lLLVMAMDGPUAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser \ + -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils \ + -lLLVMMIRParser -lLLVMAsmParser -lLLVMLibDriver -lLLVMOption -lLLVMDebugInfoPDB -lLLVMTableGen \ + -lLLVMOrcJIT -lLLVMLineEditor -lLLVMInstrumentation -lLLVMX86Disassembler -lLLVMX86AsmParser \ + -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMMCDisassembler \ + -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMDebugInfoDWARF \ + -lLLVMPasses -lLLVMipo -lLLVMVectorize -lLLVMInterpreter -lLLVMExecutionEngine \ + -lLLVMRuntimeDyld -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMProfileData \ + -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMInstCombine -lLLVMTransformUtils \ + -lLLVMipa -lLLVMMC -lLLVMAnalysis -lLLVMCore -lLLVMSupport -lz -lpthread -lcurses -ldl -g + +HEADERS += \ + test.hpp diff --git a/atdna/main.cpp b/atdna/main.cpp new file mode 100644 index 0000000..d0e3f34 --- /dev/null +++ b/atdna/main.cpp @@ -0,0 +1,147 @@ +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Tooling/Tooling.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Sema/Sema.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/DeclCXX.h" + +class FindNamedClassVisitor : public clang::RecursiveASTVisitor +{ + clang::ASTContext& context; +public: + explicit FindNamedClassVisitor(clang::ASTContext& ctxin) + : context(ctxin) {} + + bool VisitCXXRecordDecl(clang::CXXRecordDecl* decl) + { + if (decl->isInvalidDecl() || !decl->hasDefinition()) + return true; + + if (!decl->getNumBases()) + return true; + + bool foundDNA = false; + for (const clang::CXXBaseSpecifier& base : decl->bases()) + { + llvm::outs() << "BASE " << base.getType().getCanonicalType().getAsString() << "\n"; + if (!base.getType().getCanonicalType().getAsString().compare("struct Athena::io::DNA")) + { + foundDNA = true; + break; + } + } + if (!foundDNA) + return true; + + llvm::outs() << "DECL name " << decl->getQualifiedNameAsString() << "\n"; + llvm::outs() << "DECL kind " << decl->getKindName() << "\n"; + const clang::ASTRecordLayout& layout = context.getASTRecordLayout(decl); + for (const clang::FieldDecl* field : decl->fields()) + { + llvm::outs() << " Field " << field->getName(); + clang::QualType qualType = field->getType(); + const clang::Type* regType = qualType.getTypePtrOrNull(); + if (regType->getTypeClass() == clang::Type::Typedef) + { + const clang::TypedefType* tdType = (const clang::TypedefType*)regType; + llvm::outs() << " Typedef " << tdType->getDecl()->getNameAsString(); + } + else if (regType->getTypeClass() == clang::Type::TemplateSpecialization) + { + const clang::TemplateSpecializationType* tsType = (const clang::TemplateSpecializationType*)regType; + llvm::outs() << " Alias " << tsType->getTemplateName().getAsTemplateDecl()->getNameAsString(); + llvm::outs() << " " << tsType->getNumArgs() << " "; + for (const clang::TemplateArgument& arg : *tsType) + { + if (arg.getKind() == clang::TemplateArgument::Expression) + { + llvm::APSInt value; + if (arg.getAsExpr()->isIntegerConstantExpr(value, context)) + { + llvm::outs() << " Expr " << value; + } + } + else if (arg.getKind() == clang::TemplateArgument::Type) + { + llvm::outs() << " Type " << arg.getAsType().getAsString(); + } + } + } + else if (regType->getTypeClass() == clang::Type::Builtin) + { + const clang::BuiltinType* bType = (const clang::BuiltinType*)regType; + llvm::outs() << " Builtin " << bType->getName(clang::PrintingPolicy(clang::LangOptions())); + } + clang::TypeInfo regTypeInfo = context.getTypeInfo(qualType); + llvm::outs() << " Width " << regTypeInfo.Width; + llvm::outs() << " Off " << layout.getFieldOffset(field->getFieldIndex()) << "\n"; + } + /* + if (decl->getQualifiedNameAsString() == "n::m::C") + { + clang::FullSourceLoc fullLoc = context.getFullLoc(decl->getLocStart()); + if (fullLoc.isValid()) + llvm::outs() << "Found declaration at " + << fullLoc.getSpellingLineNumber() << ":" + << fullLoc.getSpellingColumnNumber() << "\n"; + } + */ + return true; + } +}; + +class FindNamedClassConsumer : public clang::ASTConsumer +{ + FindNamedClassVisitor visitor; +public: + explicit FindNamedClassConsumer(clang::ASTContext& context) + : visitor(context) {} + void HandleTranslationUnit(clang::ASTContext& context) + {visitor.TraverseDecl(context.getTranslationUnitDecl());} +}; + +static const char ATDNA_PREAMBLE[] = +"#include \n" +"typedef uint16_t atUint16;\n" +"typedef int16_t atInt16;\n" +"typedef uint32_t atUint32;\n" +"typedef int32_t atInt32;\n" +"typedef uint64_t atUint64;\n" +"typedef int64_t atInt64;\n" +"#define TYPES_HPP\n"; + +class FindNamedClassAction : public clang::ASTFrontendAction +{ + std::unique_ptr preambleBuf; +public: + explicit FindNamedClassAction() + : preambleBuf(llvm::MemoryBuffer::getMemBuffer(ATDNA_PREAMBLE, "ATDNA_PREAMBLE.hpp")) {} + std::unique_ptr CreateASTConsumer(clang::CompilerInstance& compiler, + llvm::StringRef /*filename*/) + { + //compiler.getDiagnostics().setSuppressAllDiagnostics(); + compiler.getPreprocessorOpts().addRemappedFile("ATDNA_PREAMBLE.hpp", preambleBuf.get()); + compiler.getPreprocessorOpts().ChainedIncludes.push_back("ATDNA_PREAMBLE.hpp"); + compiler.getPreprocessorOpts().RetainRemappedFileBuffers = true; + return std::unique_ptr(new FindNamedClassConsumer(compiler.getASTContext())); + } +}; + +int main(int argc, const char** argv) +{ + if (argc > 1) + { + clang::FileManager fman((clang::FileSystemOptions())); + llvm::ErrorOr> buf = fman.getBufferForFile(argv[1]); + std::error_code ec; + if ((ec = buf.getError())) + throw ec; + llvm::Twine buft(buf->get()->getBuffer()); + clang::tooling::runToolOnCodeWithArgs(new FindNamedClassAction, buft, {"-std=c++11"}, argv[1]); + } + return 0; +} + diff --git a/atdna/test.hpp b/atdna/test.hpp new file mode 100644 index 0000000..9ab3829 --- /dev/null +++ b/atdna/test.hpp @@ -0,0 +1,39 @@ +#include +#include +typedef uint32_t atUint32; +typedef uint16_t atUint16; + +enum Endian +{ + LITTLE, + BIG +}; + +template +using Value = T; + +template +using Vector = std::vector; + +namespace Athena +{ +namespace io +{ +class IStreamReader; +class IStreamWriter; +struct DNA +{ + void read(IStreamReader&); + void write(IStreamWriter&) const; +}; +} +} + +using namespace Athena; + +struct ANCSFile : public io::DNA +{ + Value var32; + Value var16; + Vector vec; +}; diff --git a/include/Athena/DNA.hpp b/include/Athena/DNA.hpp new file mode 100644 index 0000000..27a4f4a --- /dev/null +++ b/include/Athena/DNA.hpp @@ -0,0 +1,30 @@ +#ifndef DNA_HPP +#define DNA_HPP + +#include + +namespace Athena +{ +namespace io +{ +class IStreamReader; +class IStreamWriter; + +template +struct DNA +{ + virtual bool read(IStreamReader& reader)=0; + virtual bool write(IStreamWriter& writer) const=0; +}; + +template +using DNAValue = T; + +template +using DNAVector = std::vector; + +} +} + +#endif // DNA_HPP +