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} ...@@ -3,7 +3,8 @@ add_library(${LIBRARY_NAME}
SHARED SHARED
fuzzy_parsing.cpp fuzzy_parsing.cpp
qcor_ast_visitor.cpp qcor_ast_visitor.cpp
qcor_ast_consumer.cpp) qcor_ast_consumer.cpp
qcor_frontend_action.cpp)
target_include_directories(${LIBRARY_NAME} target_include_directories(${LIBRARY_NAME}
PUBLIC . PUBLIC .
......
#include "clang/Frontend/FrontendAction.h" #include "qcor_frontend_action.hpp"
#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?
}
}
};
int main(int argc, char **argv) { int main(int argc, char **argv) {
xacc::Initialize(); // argc, argv); xacc::Initialize();
// Get filename // Get filename
// FIXME, we assume it is the last arg...
std::string fileName(argv[argc - 1]); std::string fileName(argv[argc - 1]);
if (!xacc::fileExists(fileName)) { if (!xacc::fileExists(fileName)) {
xacc::error("File " + fileName + " does not exist."); xacc::error("File " + fileName + " does not exist.");
...@@ -140,14 +18,16 @@ int main(int argc, char **argv) { ...@@ -140,14 +18,16 @@ int main(int argc, char **argv) {
// Initialize rewriter // Initialize rewriter
Rewriter Rewrite; 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", std::vector<std::string> args{"-Wno-dangling", "-std=c++14",
"-I@CMAKE_INSTALL_PREFIX@/include/qcor", "-I@CMAKE_INSTALL_PREFIX@/include/qcor",
"-I@CMAKE_INSTALL_PREFIX@/include/xacc"}; "-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::string accName = "";
std::vector<std::string> arguments(argv + 1, argv + argc); std::vector<std::string> arguments(argv + 1, argv + argc);
// Add incoming includes...
for (int i = 0; i < arguments.size(); i++) { for (int i = 0; i < arguments.size(); i++) {
if (arguments[i] == "-I") { if (arguments[i] == "-I") {
if (arguments[i + 1] != "@CMAKE_INSTALL_PREFIX@/include/qcor" && 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 <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 "CommonGates.hpp"
#include "CountGatesOfTypeVisitor.hpp" #include "CountGatesOfTypeVisitor.hpp"
...@@ -25,55 +7,14 @@ ...@@ -25,55 +7,14 @@
#include "clang/Parse/ParseAST.h" #include "clang/Parse/ParseAST.h"
#include "qcor_frontend_action.hpp"
#include <fstream> #include <fstream>
using namespace llvm; using namespace llvm;
using namespace clang; using namespace clang;
using namespace qcor; 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> const std::string param0 = R"param0(#include <vector>
using qbit = std::vector<int>; using qbit = std::vector<int>;
int main() { int main() {
...@@ -150,13 +91,24 @@ int main() { ...@@ -150,13 +91,24 @@ int main() {
TEST(LambdaVisitorTester, checkSimple) { TEST(LambdaVisitorTester, checkSimple) {
Rewriter rewriter1, rewriter2; Rewriter rewriter1, rewriter2;
auto action1 = new TestQCORFrontendAction(rewriter1); auto action1 = new QCORFrontendAction(rewriter1, "temp.cpp");
auto action2 = new TestQCORFrontendAction(rewriter2); // auto action2 = new TestQCORFrontendAction(rewriter2);
xacc::setOption("qcor-compiled-filename", "lambda_visitor_tester"); 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"}; 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)); EXPECT_TRUE(tooling::runToolOnCodeWithArgs(action1, bell, args));
const std::string expectedSrc = R"expectedSrc( const std::string expectedSrc = R"expectedSrc(
...@@ -164,30 +116,30 @@ int main() { ...@@ -164,30 +116,30 @@ int main() {
auto l = [&](){return "lambda_visitor_tester";}; auto l = [&](){return "lambda_visitor_tester";};
return 0; return 0;
})expectedSrc"; })expectedSrc";
std::ifstream t(".output.cpp"); std::ifstream t(".temp_out.cpp");
std::string src((std::istreambuf_iterator<char>(t)), std::string src((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>()); 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"); // // auto function = qcor::loadCompiledCircuit("lambda_visitor_tester");
// xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Hadamard> h(function); // // xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Hadamard> h(function);
// xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::CNOT> cx(function); // // xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::CNOT> cx(function);
// xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Measure> m(function); // // xacc::quantum::CountGatesOfTypeVisitor<xacc::quantum::Measure> m(function);
// EXPECT_EQ(1, h.countGates()); // // EXPECT_EQ(1, h.countGates());
// EXPECT_EQ(1, cx.countGates()); // // EXPECT_EQ(1, cx.countGates());
// EXPECT_EQ(1, m.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::ifstream t2(".output.cpp");
std::string src2((std::istreambuf_iterator<char>(t2)), // std::string src2((std::istreambuf_iterator<char>(t2)),
std::istreambuf_iterator<char>()); // std::istreambuf_iterator<char>());
std::remove(".output.cpp"); // std::remove(".output.cpp");
std::cout << "OUTPUT:\n" << src2 << "\n";
// EXPECT_EQ(expectedSrc, src2); // EXPECT_EQ(expectedSrc, src2);
} }
......
...@@ -8,10 +8,6 @@ target_include_directories(${LIBRARY_NAME} PUBLIC .) ...@@ -8,10 +8,6 @@ target_include_directories(${LIBRARY_NAME} PUBLIC .)
target_link_libraries(${LIBRARY_NAME} PUBLIC xacc::xacc PRIVATE xacc::pauli xacc::fermion) 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}) xacc_configure_library_rpath(${LIBRARY_NAME})
file(GLOB HEADERS qcor.hpp) 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