Loading compiler/CMakeLists.txt +3 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,6 @@ endif() configure_file(qcor-driver.in.cpp ${CMAKE_BINARY_DIR}/compiler/qcor-driver.cpp) #add_executable(qcor-driver ${CMAKE_BINARY_DIR}/compiler/qcor-driver.cpp) #target_link_libraries(qcor-driver PRIVATE qcor-ast-plugin qcor) #install(PROGRAMS ${CMAKE_BINARY_DIR}/compiler/qcor-driver DESTINATION bin) add_executable(qcor-driver ${CMAKE_BINARY_DIR}/compiler/qcor-driver.cpp) target_link_libraries(qcor-driver PRIVATE qcor-ast-plugin qcor) install(PROGRAMS ${CMAKE_BINARY_DIR}/compiler/qcor-driver DESTINATION bin) compiler/fuzzy_parsing.cpp +33 −98 Original line number Diff line number Diff line Loading @@ -6,131 +6,66 @@ #include "Utils.hpp" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/AST/ASTStructuralEquivalence.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Tooling/Tooling.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/AST/ASTImporter.h" #include "qcor_clang_utils.hpp" using namespace clang; using namespace clang::ast_matchers; namespace qcor { namespace compiler { enum class DeclMatcherKind { First, Last }; // Matcher class to retrieve the first/last matched node under a given AST. template <typename NodeType, DeclMatcherKind MatcherKind> class DeclMatcher : public ast_matchers::MatchFinder::MatchCallback { NodeType *Node = nullptr; void run(const MatchFinder::MatchResult &Result) override { if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) || MatcherKind == DeclMatcherKind::Last) { Node = const_cast<NodeType *>(Result.Nodes.getNodeAs<NodeType>("")); void FuzzyParsingExternalSemaSource::initialize() { auto provider = xacc::getService<xacc::IRProvider>("quantum"); validInstructions = provider->getInstructions(); validInstructions.push_back("CX"); for (auto &instructionName : validInstructions) { std::string tmpSource = "void " + instructionName + "("; auto tmpInst = provider->createInstruction( instructionName == "CX" ? "CNOT" : instructionName, {}); int nRequiredBits = tmpInst->nRequiredBits(); tmpSource += "int q0"; for (int i = 1; i < nRequiredBits; i++) { tmpSource += ", int q" + std::to_string(i); } if (tmpInst->isParameterized() && instructionName != "Measure") { int nRequiredParams = tmpInst->nParameters(); tmpSource += ", double p0"; for (int i = 1; i < nRequiredParams; i++) { tmpSource += ", double p" + std::to_string(i); } public: // Returns the first/last matched node under the tree rooted in `D`. template <typename MatcherType> NodeType *match(const Decl *D, const MatcherType &AMatcher) { MatchFinder Finder; Finder.addMatcher(AMatcher.bind(""), this); Finder.matchAST(D->getASTContext()); assert(Node); return Node; } }; template <typename NodeType> using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>; void FuzzyParsingExternalSemaSource::initialize() { auto irProvider = xacc::getService<xacc::IRProvider>("quantum"); validInstructions = irProvider->getInstructions(); validInstructions.push_back("CX"); tmpSource += "){return;}"; quantumInstructionASTs.insert( {instructionName + "__qcor_instruction", tooling::buildASTFromCodeWithArgs(tmpSource, {"-std=c++11"})}); } } bool FuzzyParsingExternalSemaSource::LookupUnqualified(clang::LookupResult &R, clang::Scope *S) { DeclarationName Name = R.getLookupName(); std::string unknownName = Name.getAsString(); std::string unknownName = R.getLookupName().getAsString(); // If this is a valid quantum instruction, tell Clang its // all gonna be ok, we got this... if (std::find(validInstructions.begin(), validInstructions.end(), // not template scope unknownName) != validInstructions.end() && if (quantumInstructionASTs.count(unknownName + "__qcor_instruction") && S->getFlags() != 128 && S->getBlockParent() != nullptr) { std::cout << "HELLO FP: " << unknownName << ", " << S->getFlags() << "\n"; IdentifierInfo *II = Name.getAsIdentifierInfo(); SourceLocation Loc = R.getNameLoc(); std::string src = ""; if (unknownName == "H" || unknownName == "Measure") { src ="void "+unknownName+"(int q) {return;}"; } else if (unknownName == "CX") { src = "void "+unknownName+"(int q, int q2){return;}"; } auto AST = tooling::buildASTFromCodeWithArgs( src, {"-std=c++11"}); ASTs.push_back(std::move(AST)); auto Matcher = namedDecl(hasName(unknownName)); FunctionDecl *D0 = FirstDeclMatcher<FunctionDecl>().match( ASTs[ASTs.size()-1]->getASTContext().getTranslationUnitDecl(), Matcher); D0->setDeclContext(R.getSema().getFunctionLevelDeclContext()); // FunctionDecl *copy =FunctionDecl::Create( // *m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, Name, // m_Context->DependentTy, 0, SC_None); // std::memcpy(copy, D0, sizeof(FunctionDecl)); // auto fdecl = FunctionDecl::Create( // *m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, Name, // m_Context->DependentTy, 0, SC_None); // // xacc::print_backtrace(); quantumInstructionASTs[unknownName + "__qcor_instruction"] ->getASTContext() .getTranslationUnitDecl(), Matcher); // Stmt *S = new (*m_Context) NullStmt(Stmt::EmptyShell()); // fdecl->setBody(S); D0->dump(); R.addDecl(D0); // fdecl->getReturnType()->isUndeducedType() // std::cout << "ISDELETED: " << std::boolalpha << fdecl->isDeleted() << ", " << fdecl->getReturnType()->isUndeducedType() << "\n"; return true; } return false; } } // namespace compiler } // namespace qcor // VarDecl *Result = // VarDecl:Create(*m_Context, R.getSema().getFunctionLevelDeclContext(), // Loc, Loc, II, m_Context->DependentTy, // /*TypeSourceInfo*/ 0, SC_None); // Create the const char * QualType // SourceLocation sl; // QualType StrTy = m_Context->getConstantArrayType( // m_Context->adjustStringLiteralBaseType(m_Context->CharTy.withConst()), // llvm::APInt(32, 1), ArrayType::Normal, 0); // auto fnameSL = StringLiteral::Create( // *m_Context, StringRef(""), StringLiteral::Ascii, false, StrTy, &sl, 1); // // Create the return statement that will return // // the string literal file name // auto rtrn = // ReturnStmt::Create(*m_Context, SourceLocation(), fnameSL, nullptr); // std::vector<Stmt *> svec; // svec.push_back(rtrn); // llvm::ArrayRef<Stmt *> stmts(svec); // auto cmp = CompoundStmt::Create(*m_Context, stmts, SourceLocation(), // SourceLocation()); compiler/fuzzy_parsing.hpp +4 −4 Original line number Diff line number Diff line Loading @@ -2,9 +2,9 @@ #define COMPILER_FUZZYPARSINGEXTERNALSEMASOURCE_HPP_ #include "clang/AST/ASTContext.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/Lookup.h" #include "clang/Frontend/ASTUnit.h" using namespace clang; Loading @@ -20,7 +20,7 @@ private: // This ExternalSemaSource should exist throughout // the tooling lifetime, so we should be good with // regards to these nodes being deleted std::vector<std::unique_ptr<ASTUnit>> ASTs; std::map<std::string, std::unique_ptr<ASTUnit>> quantumInstructionASTs; public: FuzzyParsingExternalSemaSource() = default; Loading compiler/qcor-driver.in.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ int main(int argc, char **argv) { auto action = new QCORFrontendAction(Rewrite, fileName); std::vector<std::string> args{ "-ftime-report", "-std=c++11", "-I@CMAKE_INSTALL_PREFIX@/include/qcor", "-ftime-report", "-std=c++14", "-I@CMAKE_INSTALL_PREFIX@/include/qcor", "-I@CMAKE_INSTALL_PREFIX@/include/xacc"}; if (!tooling::runToolOnCodeWithArgs(action, src, args)) { Loading compiler/qcor_ast_consumer.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -7,8 +7,7 @@ using namespace clang; namespace qcor { namespace compiler { QCORASTConsumer::QCORASTConsumer(CompilerInstance &c, Rewriter &rw) : ci(c), rewriter(rw) {} : ci(c), rewriter(rw) {} bool QCORASTConsumer::HandleTopLevelDecl(DeclGroupRef DR) { QCORASTVisitor visitor(ci, rewriter); Loading Loading
compiler/CMakeLists.txt +3 −3 Original line number Diff line number Diff line Loading @@ -24,6 +24,6 @@ endif() configure_file(qcor-driver.in.cpp ${CMAKE_BINARY_DIR}/compiler/qcor-driver.cpp) #add_executable(qcor-driver ${CMAKE_BINARY_DIR}/compiler/qcor-driver.cpp) #target_link_libraries(qcor-driver PRIVATE qcor-ast-plugin qcor) #install(PROGRAMS ${CMAKE_BINARY_DIR}/compiler/qcor-driver DESTINATION bin) add_executable(qcor-driver ${CMAKE_BINARY_DIR}/compiler/qcor-driver.cpp) target_link_libraries(qcor-driver PRIVATE qcor-ast-plugin qcor) install(PROGRAMS ${CMAKE_BINARY_DIR}/compiler/qcor-driver DESTINATION bin)
compiler/fuzzy_parsing.cpp +33 −98 Original line number Diff line number Diff line Loading @@ -6,131 +6,66 @@ #include "Utils.hpp" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/AST/ASTStructuralEquivalence.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Tooling/Tooling.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/AST/ASTImporter.h" #include "qcor_clang_utils.hpp" using namespace clang; using namespace clang::ast_matchers; namespace qcor { namespace compiler { enum class DeclMatcherKind { First, Last }; // Matcher class to retrieve the first/last matched node under a given AST. template <typename NodeType, DeclMatcherKind MatcherKind> class DeclMatcher : public ast_matchers::MatchFinder::MatchCallback { NodeType *Node = nullptr; void run(const MatchFinder::MatchResult &Result) override { if ((MatcherKind == DeclMatcherKind::First && Node == nullptr) || MatcherKind == DeclMatcherKind::Last) { Node = const_cast<NodeType *>(Result.Nodes.getNodeAs<NodeType>("")); void FuzzyParsingExternalSemaSource::initialize() { auto provider = xacc::getService<xacc::IRProvider>("quantum"); validInstructions = provider->getInstructions(); validInstructions.push_back("CX"); for (auto &instructionName : validInstructions) { std::string tmpSource = "void " + instructionName + "("; auto tmpInst = provider->createInstruction( instructionName == "CX" ? "CNOT" : instructionName, {}); int nRequiredBits = tmpInst->nRequiredBits(); tmpSource += "int q0"; for (int i = 1; i < nRequiredBits; i++) { tmpSource += ", int q" + std::to_string(i); } if (tmpInst->isParameterized() && instructionName != "Measure") { int nRequiredParams = tmpInst->nParameters(); tmpSource += ", double p0"; for (int i = 1; i < nRequiredParams; i++) { tmpSource += ", double p" + std::to_string(i); } public: // Returns the first/last matched node under the tree rooted in `D`. template <typename MatcherType> NodeType *match(const Decl *D, const MatcherType &AMatcher) { MatchFinder Finder; Finder.addMatcher(AMatcher.bind(""), this); Finder.matchAST(D->getASTContext()); assert(Node); return Node; } }; template <typename NodeType> using FirstDeclMatcher = DeclMatcher<NodeType, DeclMatcherKind::First>; void FuzzyParsingExternalSemaSource::initialize() { auto irProvider = xacc::getService<xacc::IRProvider>("quantum"); validInstructions = irProvider->getInstructions(); validInstructions.push_back("CX"); tmpSource += "){return;}"; quantumInstructionASTs.insert( {instructionName + "__qcor_instruction", tooling::buildASTFromCodeWithArgs(tmpSource, {"-std=c++11"})}); } } bool FuzzyParsingExternalSemaSource::LookupUnqualified(clang::LookupResult &R, clang::Scope *S) { DeclarationName Name = R.getLookupName(); std::string unknownName = Name.getAsString(); std::string unknownName = R.getLookupName().getAsString(); // If this is a valid quantum instruction, tell Clang its // all gonna be ok, we got this... if (std::find(validInstructions.begin(), validInstructions.end(), // not template scope unknownName) != validInstructions.end() && if (quantumInstructionASTs.count(unknownName + "__qcor_instruction") && S->getFlags() != 128 && S->getBlockParent() != nullptr) { std::cout << "HELLO FP: " << unknownName << ", " << S->getFlags() << "\n"; IdentifierInfo *II = Name.getAsIdentifierInfo(); SourceLocation Loc = R.getNameLoc(); std::string src = ""; if (unknownName == "H" || unknownName == "Measure") { src ="void "+unknownName+"(int q) {return;}"; } else if (unknownName == "CX") { src = "void "+unknownName+"(int q, int q2){return;}"; } auto AST = tooling::buildASTFromCodeWithArgs( src, {"-std=c++11"}); ASTs.push_back(std::move(AST)); auto Matcher = namedDecl(hasName(unknownName)); FunctionDecl *D0 = FirstDeclMatcher<FunctionDecl>().match( ASTs[ASTs.size()-1]->getASTContext().getTranslationUnitDecl(), Matcher); D0->setDeclContext(R.getSema().getFunctionLevelDeclContext()); // FunctionDecl *copy =FunctionDecl::Create( // *m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, Name, // m_Context->DependentTy, 0, SC_None); // std::memcpy(copy, D0, sizeof(FunctionDecl)); // auto fdecl = FunctionDecl::Create( // *m_Context, R.getSema().getFunctionLevelDeclContext(), Loc, Loc, Name, // m_Context->DependentTy, 0, SC_None); // // xacc::print_backtrace(); quantumInstructionASTs[unknownName + "__qcor_instruction"] ->getASTContext() .getTranslationUnitDecl(), Matcher); // Stmt *S = new (*m_Context) NullStmt(Stmt::EmptyShell()); // fdecl->setBody(S); D0->dump(); R.addDecl(D0); // fdecl->getReturnType()->isUndeducedType() // std::cout << "ISDELETED: " << std::boolalpha << fdecl->isDeleted() << ", " << fdecl->getReturnType()->isUndeducedType() << "\n"; return true; } return false; } } // namespace compiler } // namespace qcor // VarDecl *Result = // VarDecl:Create(*m_Context, R.getSema().getFunctionLevelDeclContext(), // Loc, Loc, II, m_Context->DependentTy, // /*TypeSourceInfo*/ 0, SC_None); // Create the const char * QualType // SourceLocation sl; // QualType StrTy = m_Context->getConstantArrayType( // m_Context->adjustStringLiteralBaseType(m_Context->CharTy.withConst()), // llvm::APInt(32, 1), ArrayType::Normal, 0); // auto fnameSL = StringLiteral::Create( // *m_Context, StringRef(""), StringLiteral::Ascii, false, StrTy, &sl, 1); // // Create the return statement that will return // // the string literal file name // auto rtrn = // ReturnStmt::Create(*m_Context, SourceLocation(), fnameSL, nullptr); // std::vector<Stmt *> svec; // svec.push_back(rtrn); // llvm::ArrayRef<Stmt *> stmts(svec); // auto cmp = CompoundStmt::Create(*m_Context, stmts, SourceLocation(), // SourceLocation());
compiler/fuzzy_parsing.hpp +4 −4 Original line number Diff line number Diff line Loading @@ -2,9 +2,9 @@ #define COMPILER_FUZZYPARSINGEXTERNALSEMASOURCE_HPP_ #include "clang/AST/ASTContext.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/Lookup.h" #include "clang/Frontend/ASTUnit.h" using namespace clang; Loading @@ -20,7 +20,7 @@ private: // This ExternalSemaSource should exist throughout // the tooling lifetime, so we should be good with // regards to these nodes being deleted std::vector<std::unique_ptr<ASTUnit>> ASTs; std::map<std::string, std::unique_ptr<ASTUnit>> quantumInstructionASTs; public: FuzzyParsingExternalSemaSource() = default; Loading
compiler/qcor-driver.in.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -118,7 +118,7 @@ int main(int argc, char **argv) { auto action = new QCORFrontendAction(Rewrite, fileName); std::vector<std::string> args{ "-ftime-report", "-std=c++11", "-I@CMAKE_INSTALL_PREFIX@/include/qcor", "-ftime-report", "-std=c++14", "-I@CMAKE_INSTALL_PREFIX@/include/qcor", "-I@CMAKE_INSTALL_PREFIX@/include/xacc"}; if (!tooling::runToolOnCodeWithArgs(action, src, args)) { Loading
compiler/qcor_ast_consumer.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -7,8 +7,7 @@ using namespace clang; namespace qcor { namespace compiler { QCORASTConsumer::QCORASTConsumer(CompilerInstance &c, Rewriter &rw) : ci(c), rewriter(rw) {} : ci(c), rewriter(rw) {} bool QCORASTConsumer::HandleTopLevelDecl(DeclGroupRef DR) { QCORASTVisitor visitor(ci, rewriter); Loading