qcor-driver.in.cpp 3.76 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#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>

24
#include "FuzzyParsingExternalSemaSource.hpp"
25
#include "QCORPragmaHandler.hpp"
26

27
28
#include "QCORASTConsumer.hpp"
#include "XACC.hpp"
29
30
#include "xacc_service.hpp"

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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 llvm::make_unique<qcor::compiler::QCORASTConsumer>(Compiler,
                                                              rewriter);
  }

  void ExecuteAction() override {
    CompilerInstance &CI = getCompilerInstance();
    CI.createSema(getTranslationUnitKind(), nullptr);
    rewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());

54
55
56
57
58
59
60
61
62
63
64
65
    auto externalSemaSources = xacc::getServices<qcor::compiler::QCORExternalSemaSource>();
    for (auto es : externalSemaSources) {
        es->setASTContext(&CI.getASTContext());
        es->initialize();
        CI.getSema().addExternalSource(es.get());
    }

    auto pragmaHandlers = xacc::getServices<qcor::compiler::QCORPragmaHandler>();
    for (auto p : pragmaHandlers) {
        p->setRewriter(&rewriter);
        CI.getSema().getPreprocessor().AddPragmaHandler(p.get());
    }
66

67
68
    ParseAST(CI.getSema());

69
70
71
    for (auto& p : pragmaHandlers) {
        CI.getSema().getPreprocessor().RemovePragmaHandler(p.get());
    }
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    CI.getDiagnosticClient().EndSourceFile();

    std::string outName(fileName);
    size_t ext = outName.rfind(".");
    if (ext == std::string::npos)
      ext = outName.length();
    outName.insert(ext, "_out");
    outName = "."+outName;

    llvm::errs() << "Output to: " << outName << "\n";
    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) {

      const RewriteBuffer *RewriteBuf = rewriter.getRewriteBufferFor(
          CI.getSourceManager().getMainFileID());
      outFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
    } else {
      llvm::errs() << "Cannot open " << outName << " for writing\n";
    }

    outFile.close();
  }
};

int main(int argc, char **argv) {

  xacc::Initialize(argc, argv);

  // Get filename
  std::string fileName(argv[argc - 1]);
  if (!xacc::fileExists(fileName)) {
    xacc::error("File " + fileName + " does not exist.");
  }

  std::ifstream t(fileName);
  std::string src((std::istreambuf_iterator<char>(t)),
                  std::istreambuf_iterator<char>());

  // Initialize rewriter
  Rewriter Rewrite;

  auto action = new QCORFrontendAction(Rewrite, fileName);
  std::vector<std::string> args{
119
120
      "-ftime-report", "-std=c++11", "-I@CMAKE_INSTALL_PREFIX@/include/qcor",
      "-I@CMAKE_INSTALL_PREFIX@/include/xacc"};
121
122
123
124
125
126
127
128

  if (!tooling::runToolOnCodeWithArgs(action, src, args)) {
      xacc::error("Error running qcor compiler.");
  }

  return 0;

}