Less hacky means of differentiating LLVM 3.9 ownership behavior

This commit is contained in:
Jack Andersen 2016-09-11 08:36:32 -10:00
parent 002e113906
commit 161206fdd9
1 changed files with 29 additions and 18 deletions

View File

@ -2324,21 +2324,24 @@ public:
class ATDNAConsumer : public clang::ASTConsumer class ATDNAConsumer : public clang::ASTConsumer
{ {
std::unique_ptr<StreamOut> fileOut; std::unique_ptr<StreamOut> fileOut;
StreamOut& fileOutOld;
ATDNAEmitVisitor emitVisitor; ATDNAEmitVisitor emitVisitor;
public: public:
explicit ATDNAConsumer(clang::ASTContext& context, std::unique_ptr<StreamOut>&& fo) explicit ATDNAConsumer(clang::ASTContext& context, std::unique_ptr<StreamOut>&& fo, StreamOut* foOld)
: fileOut(std::move(fo)), : fileOut(std::move(fo)),
emitVisitor(context, *fileOut) {} fileOutOld(*foOld),
emitVisitor(context, *foOld) {}
void HandleTranslationUnit(clang::ASTContext& context) void HandleTranslationUnit(clang::ASTContext& context)
{ {
/* Write file head */ /* Write file head */
*fileOut << "/* Auto generated atdna implementation */\n" fileOutOld << "/* Auto generated atdna implementation */\n"
"#include <athena/Global.hpp>\n" "#include <athena/Global.hpp>\n"
"#include <athena/IStreamReader.hpp>\n" "#include <athena/IStreamReader.hpp>\n"
"#include <athena/IStreamWriter.hpp>\n\n"; "#include <athena/IStreamWriter.hpp>\n\n";
for (const std::string& inputf : InputFilenames) for (const std::string& inputf : InputFilenames)
*fileOut << "#include \"" << inputf << "\"\n"; fileOutOld << "#include \"" << inputf << "\"\n";
*fileOut << "\n"; fileOutOld << "\n";
/* Emit file */ /* Emit file */
emitVisitor.TraverseDecl(context.getTranslationUnitDecl()); emitVisitor.TraverseDecl(context.getTranslationUnitDecl());
@ -2347,25 +2350,33 @@ public:
class ATDNAAction : public clang::ASTFrontendAction class ATDNAAction : public clang::ASTFrontendAction
{ {
/* Used by LLVM 3.9+; client owns stream */
std::unique_ptr<StreamOut> MakeStreamOut(std::unique_ptr<StreamOut>&& so, StreamOut*& outPtr)
{
outPtr = so.get();
return std::move(so);
}
/* Used by previous versions of LLVM; CompilerInstance owns stream */
std::unique_ptr<StreamOut> MakeStreamOut(StreamOut* so, StreamOut*& outPtr)
{
outPtr = so;
return {};
}
public: public:
explicit ATDNAAction() {} explicit ATDNAAction() {}
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& compiler, std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(clang::CompilerInstance& compiler,
llvm::StringRef /*filename*/) llvm::StringRef /*filename*/)
{ {
std::unique_ptr<StreamOut> fileout; std::unique_ptr<StreamOut> fileout;
#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 9) StreamOut* fileoutOld;
if (OutputFilename.size()) if (OutputFilename.size())
fileout = compiler.createOutputFile(OutputFilename, false, true, "", "", true); fileout = MakeStreamOut(compiler.createOutputFile(OutputFilename, false, true, "", "", true), fileoutOld);
else else
fileout = compiler.createDefaultOutputFile(false, "a", "cpp"); fileout = MakeStreamOut(compiler.createDefaultOutputFile(false, "a", "cpp"), fileoutOld);
#else
if (OutputFilename.size())
fileout.reset(compiler.createOutputFile(OutputFilename, false, true, "", "", true));
else
fileout.reset(compiler.createDefaultOutputFile(false, "a", "cpp"));
#endif
AthenaError = compiler.getASTContext().getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "Athena error: %0"); AthenaError = compiler.getASTContext().getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "Athena error: %0");
return std::unique_ptr<clang::ASTConsumer>(new ATDNAConsumer(compiler.getASTContext(), std::move(fileout))); return std::unique_ptr<clang::ASTConsumer>(new ATDNAConsumer(compiler.getASTContext(), std::move(fileout), fileoutOld));
} }
}; };