Commit ec489ae6 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

creating qcor_frontend_action


Signed-off-by: Mccaskey, Alex's avatarAlex McCaskey <mccaskeyaj@ornl.gov>
parent 558209bd
Pipeline #78609 canceled with stage
......@@ -3,7 +3,8 @@ add_library(${LIBRARY_NAME}
SHARED
fuzzy_parsing.cpp
qcor_ast_visitor.cpp
qcor_ast_consumer.cpp)
qcor_ast_consumer.cpp
qcor_frontend_action.cpp)
target_include_directories(${LIBRARY_NAME}
PUBLIC .
......
#include "clang/Frontend/FrontendAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Rewrite/Frontend/Rewriters.h"
#include "clang/Tooling/Tooling.h"
#include <fstream>
#include <string>
#include "fuzzy_parsing.hpp"
#include "qcor_ast_consumer.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"
using namespace clang;
class QCORFrontendAction : public clang::ASTFrontendAction {
public:
QCORFrontendAction(Rewriter &rw, const std::string file)
: rewriter(rw), fileName(file) {}
protected:
Rewriter &rewriter;
std::string fileName;
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler,
llvm::StringRef /* dummy */) override {
return std::make_unique<qcor::compiler::QCORASTConsumer>(Compiler,
rewriter);
}
void ExecuteAction() override {
CompilerInstance &CI = getCompilerInstance();
CI.createSema(getTranslationUnitKind(), nullptr);
rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
auto fuzzyParser =
std::make_shared<qcor::compiler::FuzzyParsingExternalSemaSource>(CI);
fuzzyParser->initialize();
// fuzzyParser->setASTContext(&CI.getASTContext());
// fuzzyParser->setFileManager(&CI.getFileManager());
CI.getSema().addExternalSource(fuzzyParser.get());
// FIXME Hook this back up
// auto pragmaHandlers =
// xacc::getServices<qcor::compiler::QCORPragmaHandler>(); for (auto p :
// pragmaHandlers) {
// p->setRewriter(&rewriter);
// CI.getSema().getPreprocessor().AddPragmaHandler(p.get());
// }
ParseAST(CI.getSema());
// for (auto& p : pragmaHandlers) {
// CI.getSema().getPreprocessor().RemovePragmaHandler(p.get());
// }
CI.getDiagnosticClient().EndSourceFile();
// Get the rewrite buffer
const RewriteBuffer *RewriteBuf =
rewriter.getRewriteBufferFor(CI.getSourceManager().getMainFileID());
// if not null, rewrite to .fileName_out.cpp
if (RewriteBuf) {
auto getFileName = [](const std::string &s) {
char sep = '/';
size_t i = s.rfind(sep, s.length());
if (i != std::string::npos) {
return (s.substr(i + 1, s.length() - i));
}
return std::string("");
};
auto fileNameNoPath = getFileName(fileName);
if (!fileNameNoPath.empty()) {
fileName = fileNameNoPath;
}
std::string outName(fileName);
size_t ext = outName.rfind(".");
if (ext == std::string::npos)
ext = outName.length();
outName.insert(ext, "_out");
outName = "." + outName;
std::error_code OutErrorInfo;
std::error_code ok;
llvm::raw_fd_ostream outFile(llvm::StringRef(outName), OutErrorInfo,
llvm::sys::fs::F_None);
if (OutErrorInfo == ok) {
auto s = std::string(RewriteBuf->begin(), RewriteBuf->end());
outFile << s;
} else {
llvm::errs() << "Cannot open " << outName << " for writing\n";
llvm::errs() << OutErrorInfo.message() << "\n";
}
outFile.close();
} else {
// Do we need to do anything here?
}
}
};
#include "qcor_frontend_action.hpp"
int main(int argc, char **argv) {
xacc::Initialize(); // argc, argv);
xacc::Initialize();
// Get filename
// FIXME, we assume it is the last arg...
std::string fileName(argv[argc - 1]);
if (!xacc::fileExists(fileName)) {
xacc::error("File " + fileName + " does not exist.");
......@@ -140,14 +18,16 @@ int main(int argc, char **argv) {
// Initialize rewriter
Rewriter Rewrite;
auto action = new QCORFrontendAction(Rewrite, fileName);
auto action = new qcor::compiler::QCORFrontendAction(Rewrite, fileName);
std::vector<std::string> args{"-Wno-dangling", "-std=c++14",
"-I@CMAKE_INSTALL_PREFIX@/include/qcor",
"-I@CMAKE_INSTALL_PREFIX@/include/xacc"};
// Do a little bit of argument analysis
// We need to know any new include paths
// and the accelerator backend
std::string accName = "";
std::vector<std::string> arguments(argv + 1, argv + argc);
// Add incoming includes...
for (int i = 0; i < arguments.size(); i++) {
if (arguments[i] == "-I") {
if (arguments[i + 1] != "@CMAKE_INSTALL_PREFIX@/include/qcor" &&
......
#include "qcor_frontend_action.hpp"
namespace qcor {
namespace compiler {
void QCORFrontendAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
CI.createSema(getTranslationUnitKind(), nullptr);
rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
auto fuzzyParser =
std::make_shared<qcor::compiler::FuzzyParsingExternalSemaSource>(CI);
fuzzyParser->initialize();
// fuzzyParser->setASTContext(&CI.getASTContext());
// fuzzyParser->setFileManager(&CI.getFileManager());
CI.getSema().addExternalSource(fuzzyParser.get());
// FIXME Hook this back up
// auto pragmaHandlers =
// xacc::getServices<qcor::compiler::QCORPragmaHandler>(); for (auto p :
// pragmaHandlers) {
// p->setRewriter(&rewriter);
// CI.getSema().getPreprocessor().AddPragmaHandler(p.get());
// }
ParseAST(CI.getSema());
// for (auto& p : pragmaHandlers) {
// CI.getSema().getPreprocessor().RemovePragmaHandler(p.get());
// }
CI.getDiagnosticClient().EndSourceFile();
// Get the rewrite buffer
const RewriteBuffer *RewriteBuf =
rewriter.getRewriteBufferFor(CI.getSourceManager().getMainFileID());
// if not null, rewrite to .fileName_out.cpp
if (RewriteBuf) {
auto getFileName = [](const std::string &s) {
char sep = '/';
size_t i = s.rfind(sep, s.length());
if (i != std::string::npos) {
return (s.substr(i + 1, s.length() - i));
}
return std::string("");
};
auto fileNameNoPath = getFileName(fileName);
if (!fileNameNoPath.empty()) {
fileName = fileNameNoPath;
}
std::string outName(fileName);
size_t ext = outName.rfind(".");
if (ext == std::string::npos)
ext = outName.length();
outName.insert(ext, "_out");
outName = "." + outName;
std::error_code OutErrorInfo;
std::error_code ok;
llvm::raw_fd_ostream outFile(llvm::StringRef(outName), OutErrorInfo,
llvm::sys::fs::F_None);
if (OutErrorInfo == ok) {
auto s = std::string(RewriteBuf->begin(), RewriteBuf->end());
outFile << s;
} else {
llvm::errs() << "Cannot open " << outName << " for writing\n";
llvm::errs() << OutErrorInfo.message() << "\n";
}
outFile.close();
} else {
// Do we need to do anything here?
}
}
} // namespace compiler
} // namespace qcor
\ No newline at end of file
#ifndef COMPILER_QCORFRONTENDACTION_HPP_
#define COMPILER_QCORFRONTENDACTION_HPP_
#include "clang/Frontend/FrontendAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Rewrite/Frontend/Rewriters.h"
#include "clang/Tooling/Tooling.h"
#include <fstream>
#include <string>
#include "fuzzy_parsing.hpp"
#include "qcor_ast_consumer.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"
using namespace clang;
namespace qcor {
namespace compiler {
class QCORFrontendAction : public clang::ASTFrontendAction {
public:
QCORFrontendAction(Rewriter &rw, const std::string file)
: rewriter(rw), fileName(file) {}
protected:
Rewriter &rewriter;
std::string fileName;
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler,
llvm::StringRef /* dummy */) override {
return std::make_unique<qcor::compiler::QCORASTConsumer>(Compiler,
rewriter);
}
void ExecuteAction() override;
};
} // namespace compiler
} // namespace qcor
#endif
\ No newline at end of file
#include <gtest/gtest.h>
#include <llvm/Support/raw_ostream.h>
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "fuzzy_parsing.hpp"
#include "qcor_ast_visitor.hpp"
#include "qcor_ast_consumer.hpp"
#include "CommonGates.hpp"
#include "CountGatesOfTypeVisitor.hpp"
......@@ -25,55 +7,14 @@
#include "clang/Parse/ParseAST.h"
#include "qcor_frontend_action.hpp"
#include <fstream>
using namespace llvm;
using namespace clang;
using namespace qcor;
using namespace qcor::compiler;
class TestQCORFrontendAction : public clang::ASTFrontendAction {
public:
TestQCORFrontendAction(Rewriter &rw) : rewriter(rw) {}
protected:
Rewriter &rewriter;
std::unique_ptr<clang::ASTConsumer>
CreateASTConsumer(clang::CompilerInstance &Compiler,
llvm::StringRef /* dummy */) override {
return std::make_unique<compiler::QCORASTConsumer>(Compiler, rewriter);
}
void ExecuteAction() override {
CompilerInstance &CI = getCompilerInstance();
CI.createSema(getTranslationUnitKind(), nullptr);
compiler::FuzzyParsingExternalSemaSource fuzzyParser(CI);
fuzzyParser.initialize();
// fuzzyParser.setASTContext(&CI.getASTContext());
CI.getSema().addExternalSource(&fuzzyParser);
rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
ParseAST(CI.getSema());
CI.getDiagnosticClient().EndSourceFile();
std::error_code error_code;
llvm::raw_fd_ostream outFile(".output.cpp", error_code,
llvm::sys::fs::F_None);
rewriter.getEditBuffer(CI.getSourceManager().getMainFileID())
.write(outFile);
}
};
const std::string bell = R"bell(#include <vector>
using qbit = std::vector<int>;
int main() {
auto l = [&](qbit q) {
H(q[0]);
CX(q[0],q[1]);
Measure(q[0]);
};
return 0;
})bell";
const std::string param0 = R"param0(#include <vector>
using qbit = std::vector<int>;
int main() {
......@@ -150,13 +91,24 @@ int main() {
TEST(LambdaVisitorTester, checkSimple) {
Rewriter rewriter1, rewriter2;
auto action1 = new TestQCORFrontendAction(rewriter1);
auto action2 = new TestQCORFrontendAction(rewriter2);
auto action1 = new QCORFrontendAction(rewriter1, "temp.cpp");
// auto action2 = new TestQCORFrontendAction(rewriter2);
xacc::setOption("qcor-compiled-filename", "lambda_visitor_tester");
std::vector<std::string> args{"-std=c++14","-I/usr/lib/gcc/x86_64-linux-gnu/8/include"};
const std::string bell = R"bell(#include <vector>
using qbit = std::vector<int>;
int main() {
auto l = [&](qbit q) {
H(q[0]);
CX(q[0],q[1]);
Measure(q[0]);
};
return 0;
})bell";
EXPECT_TRUE(tooling::runToolOnCodeWithArgs(action1, bell, args));
const std::string expectedSrc = R"expectedSrc(
......@@ -164,30 +116,30 @@ int main() {
auto l = [&](){return "lambda_visitor_tester";};
return 0;
})expectedSrc";
std::ifstream t(".output.cpp");
std::ifstream t(".temp_out.cpp");
std::string src((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
std::remove(".output.cpp");
std::remove(".temp_out.cpp");
std::cout << "OUTPUT:\n" << src << "\n";
// EXPECT_EQ(expectedSrc, src);
EXPECT_EQ(R"()", src);
// auto function = qcor::loadCompiledCircuit("lambda_visitor_tester");
// xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Hadamard> h(function);
// xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::CNOT> cx(function);
// xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Measure> m(function);
// // auto function = qcor::loadCompiledCircuit("lambda_visitor_tester");
// // xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Hadamard> h(function);
// // xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::CNOT> cx(function);
// // xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Measure> m(function);
// EXPECT_EQ(1, h.countGates());
// EXPECT_EQ(1, cx.countGates());
// EXPECT_EQ(1, m.countGates());
// // EXPECT_EQ(1, h.countGates());
// // EXPECT_EQ(1, cx.countGates());
// // EXPECT_EQ(1, m.countGates());
EXPECT_TRUE(tooling::runToolOnCodeWithArgs(action2, param0, args));
// EXPECT_TRUE(tooling::runToolOnCodeWithArgs(action2, param0, args));
std::ifstream t2(".output.cpp");
std::string src2((std::istreambuf_iterator<char>(t2)),
std::istreambuf_iterator<char>());
std::remove(".output.cpp");
std::cout << "OUTPUT:\n" << src2 << "\n";
// std::ifstream t2(".output.cpp");
// std::string src2((std::istreambuf_iterator<char>(t2)),
// std::istreambuf_iterator<char>());
// std::remove(".output.cpp");
// EXPECT_EQ(expectedSrc, src2);
}
......
......@@ -8,10 +8,6 @@ target_include_directories(${LIBRARY_NAME} PUBLIC .)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc::xacc PRIVATE xacc::pauli xacc::fermion)
if(QCOR_BUILD_TESTS)
# add_subdirectory(tests)
endif()
xacc_configure_library_rpath(${LIBRARY_NAME})
file(GLOB HEADERS qcor.hpp)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment