Commit 6bc11fe3 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

adding small updates to fuzzy parsing prototype

parent 6224cdce
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -7,4 +7,5 @@ pass off to XACC.

To build run 'make', to execute 

$ build/fuzzy_parsing test.c
$ build/fuzzy_parsing test.c (to see errors)
$ build/fuzzy_parsing test.c 1 (to see no errors)
+198 −79
Original line number Diff line number Diff line
@@ -8,20 +8,20 @@
// Eli Bendersky (eliben@gmail.com)
// This code is in the public domain
//------------------------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <string>
#include <iostream>

#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/raw_ostream.h"
@@ -35,37 +35,36 @@
#include "clang/Parse/ParseAST.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Program.h"

#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/CommandLine.h>
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.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/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Parse/Parser.h"
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Frontend/ASTConsumers.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <llvm/Support/raw_ostream.h>
#include <clang/Sema/ExternalSemaSource.h>
#include <clang/Sema/Sema.h>
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseAST.h"
#include <clang/Sema/Lookup.h>
#include <clang/Sema/Sema.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/raw_ostream.h>

using namespace clang;
using namespace clang::driver;
@@ -77,7 +76,8 @@ static llvm::cl::OptionCategory ToolingSampleCategory("Tooling Sample");
// we're interested in by overriding relevant methods.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
  MyASTVisitor(Rewriter &R, CompilerInstance& c) : TheRewriter(R), TheCompInst(c) {}
  MyASTVisitor(Rewriter &R, CompilerInstance &c)
      : TheRewriter(R), TheCompInst(c) {}

  bool VisitStmt(Stmt *s) {
    // Only care about If statements.
@@ -135,15 +135,20 @@ bool TraverseLambdaBody(LambdaExpr *LE) {
    //   LE->getLambdaClass()->dump();
    std::cout << "Check it out, I got the Lambda as a source string :)\n";

      std::cout << Lexer::getSourceText(CharSourceRange(LE->getSourceRange(), true), SM, lo).str() << "\n";
    auto xaccKernelLambdaStr = Lexer::getSourceText(
                     CharSourceRange(LE->getSourceRange(), true), SM, lo)
                     .str();
    std::cout << xaccKernelLambdaStr << "\n";

    TheRewriter.ReplaceText(LE->getBody()->getSourceRange(), "{ int hello = 0; }");
    return true;
  }

private:
  Rewriter &TheRewriter;
  CompilerInstance &TheCompInst;
};


class DynamicIDHandler : public clang::ExternalSemaSource {
public:
  DynamicIDHandler(Sema *Sema) : m_Context(Sema->getASTContext()) {}
@@ -159,14 +164,25 @@ public:
  /// @param[in] S The scope in which the lookup failed.
  virtual bool LookupUnqualified(clang::LookupResult &R, clang::Scope *S) {
    DeclarationName Name = R.getLookupName();
     if (Name.getAsString() == "X") {
    
    // FIXME Figure out how to make this check general
    if (Name.getAsString() == "X" || Name.getAsString()== "analog" || Name.getAsString() == "autogen") {
      std::cout << "Looking Up Unqualified " << Name.getAsString() << "\n";

    //   std::cout << S->isClassScope() << ", " << S->isFunctionScope() << "\n";

    //   auto fnp = S->getFnParent();
    //   fnp->dump();
    //   std::cout << "DECL " << fnp->getEntity()->getDeclKindName() << "\n";
    //   fnp->getEntity()->dumpLookups();
    
      IdentifierInfo *II = Name.getAsIdentifierInfo();
      SourceLocation Loc = R.getNameLoc();
      VarDecl *Result =
          VarDecl::Create(m_Context, R.getSema().getFunctionLevelDeclContext(),
                          Loc, Loc, II, m_Context.DependentTy,
                        /*TypeSourceInfo*/ 0, SC_None);
                          0, SC_None);
      
      if (Result) {
        R.addDecl(Result);
        // Say that we can handle the situation. Clang should try to recover
@@ -180,14 +196,13 @@ public:

private:
  clang::ASTContext &m_Context;

};

// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser.
class MyASTConsumer : public ASTConsumer {
public:
  MyASTConsumer(Rewriter &R, CompilerInstance& c) : Visitor(R,c), CI(c) {}
  MyASTConsumer(Rewriter &R, CompilerInstance &c) : Visitor(R, c) {}

  // Override the method that gets called for each parsed top-level
  // declaration.
@@ -195,22 +210,19 @@ public:
    for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {
      // Traverse the declaration using our AST visitor.
      Visitor.TraverseDecl(*b);
      (*b)->dump();
    //   (*b)->dump();
    }
    return true;
  }

private:
  MyASTVisitor Visitor;
  CompilerInstance& CI;
//   DynamicIDHandler& handler;
};

// For each source file provided to the tool, a new FrontendAction is created.
class MyFrontendAction : public ASTFrontendAction {
public:
  MyFrontendAction() {
  }
  MyFrontendAction() {}
  void EndSourceFileAction() override {
    SourceManager &SM = TheRewriter.getSourceMgr();
    llvm::errs() << "** EndSourceFileAction for: "
@@ -223,9 +235,9 @@ public:
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                 StringRef file) override {
    llvm::errs() << "** Creating AST consumer for: " << file << "\n";
    // handler = std::make_shared<DynamicIDHandler>();
    TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
    return llvm::make_unique<MyASTConsumer>(TheRewriter, CI);//, *handler.get());
    return llvm::make_unique<MyASTConsumer>(TheRewriter,
                                            CI);
  }

private:
@@ -243,23 +255,36 @@ LangOptions getFormattingLangOpts(bool Cpp03 = false) {
  return LangOpts;
}

int main(int argc, const char **argv) {
//   CommonOptionsParser op(argc, argv, ToolingSampleCategory);
//   ClangTool Tool(op.getCompilations(), op.getSourcePathList());
// static void SetInstallDir(SmallVectorImpl<const char *> &argv,
//                           Driver &TheDriver, bool CanonicalPrefixes) {
//   // Attempt to find the original path used to invoke the driver, to determine
//   // the installed path. We do this manually, because we want to support that
//   // path being a symlink.
//   SmallString<128> InstalledPath(argv[0]);

//   // Do a PATH lookup, if there are no directory components.
//   if (llvm::sys::path::filename(InstalledPath) == InstalledPath)
//     if (llvm::ErrorOr<std::string> Tmp = llvm::sys::findProgramByName(
//             llvm::sys::path::filename(InstalledPath.str())))
//       InstalledPath = *Tmp;

//   // ClangTool::run accepts a FrontendActionFactory, which is then used to
//   // create new objects implementing the FrontendAction interface. Here we use
//   // the helper newFrontendActionFactory to create a default factory that will
//   // return a new MyFrontendAction object every time.
//   // To further customize this, we could create our own factory class.
//   return Tool.run(newFrontendActionFactory<MyFrontendAction>().get());
//   // FIXME: We don't actually canonicalize this, we just make it absolute.
//   if (CanonicalPrefixes)
//     llvm::sys::fs::make_absolute(InstalledPath);

//   StringRef InstalledPathParent(llvm::sys::path::parent_path(InstalledPath));
//   if (llvm::sys::fs::exists(InstalledPathParent))
//     TheDriver.setInstalledDir(InstalledPathParent);
// }

int main(int argc, const char **argv) {
  CompilerInstance ci;
  ci.getLangOpts() = getFormattingLangOpts(false);
  DiagnosticOptions diagnosticOptions;
  ci.createDiagnostics();

  std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>();
  std::shared_ptr<clang::TargetOptions> pto =
      std::make_shared<clang::TargetOptions>();
  pto->Triple = llvm::sys::getDefaultTargetTriple();

  TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto);
@@ -268,22 +293,19 @@ int main(int argc, const char **argv) {
  ci.createFileManager();
  ci.createSourceManager(ci.getFileManager());
  ci.createPreprocessor(clang::TU_Complete);
//   ci.getPreprocessorOpts().UsePredefines = false;
  ci.createASTContext();
  SourceManager &SourceMgr = ci.getSourceManager();

  Rewriter TheRewriter;
  TheRewriter.setSourceMgr(SourceMgr, ci.getLangOpts());

  ci.setASTConsumer(
      llvm::make_unique<MyASTConsumer>(TheRewriter, ci)
      );//, argv[1]));
  ci.setASTConsumer(llvm::make_unique<MyASTConsumer>(TheRewriter, ci));

  ci.createSema(TU_Complete, nullptr);
  auto &sema = ci.getSema();
  sema.Initialize();
  DynamicIDHandler handler(&sema);
  sema.addExternalSource(&handler);
  if (argc > 2) sema.addExternalSource(&handler);

  const FileEntry *pFile = ci.getFileManager().getFile(argv[1]);
  ci.getSourceManager().setMainFileID(ci.getSourceManager().createFileID(
@@ -292,4 +314,101 @@ int main(int argc, const char **argv) {
                                           &ci.getPreprocessor());
  clang::ParseAST(sema, true, false);
  ci.getDiagnosticClient().EndSourceFile();

   const RewriteBuffer *RewriteBuf =
      TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID());
  llvm::outs() << "\n" << "#include \"qcor_integration_header.hpp\"\n" << std::string(RewriteBuf->begin(), RewriteBuf->end());
  
  SmallVector<const char *, 256> argv2(argv, argv + argc);
  
  std::string Path = "/usr/bin/clang++-8";//GetExecutablePath(argv[0], CanonicalPrefixes);

  for (auto& v : argv2) {
      std::cout << "HELLO: " << v << "\n";
  }
//   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =
//       CreateAndPopulateDiagOpts(argv);

//   TextDiagnosticPrinter *DiagClient
//     = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
//   FixupDiagPrefixExeName(DiagClient, Path);

//   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());

//   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);

//   if (!DiagOpts->DiagnosticSerializationFile.empty()) {
//     auto SerializedConsumer =
//         clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile,
//                                         &*DiagOpts, /*MergeChildRecords=*/true);
//     Diags.setClient(new ChainedDiagnosticConsumer(
//         Diags.takeClient(), std::move(SerializedConsumer)));
//   }

//   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);

//   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
//   SetInstallDir(argv, TheDriver, CanonicalPrefixes);
//   TheDriver.setTargetAndMode(TargetAndMode);

//   insertTargetAndModeArgs(TargetAndMode, argv, SavedStrings);

//   SetBackdoorDriverOutputsFromEnvVars(TheDriver);

//   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
//   int Res = 1;
//   if (C && !C->containsError()) {
//     SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
//     Res = TheDriver.ExecuteCompilation(*C, FailingCommands);

//     // Force a crash to test the diagnostics.
//     if (TheDriver.GenReproducer) {
//       Diags.Report(diag::err_drv_force_crash)
//         << !::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH");

//       // Pretend that every command failed.
//       FailingCommands.clear();
//       for (const auto &J : C->getJobs())
//         if (const Command *C = dyn_cast<Command>(&J))
//           FailingCommands.push_back(std::make_pair(-1, C));
//     }

//     for (const auto &P : FailingCommands) {
//       int CommandRes = P.first;
//       const Command *FailingCommand = P.second;
//       if (!Res)
//         Res = CommandRes;

//       // If result status is < 0, then the driver command signalled an error.
//       // If result status is 70, then the driver command reported a fatal error.
//       // On Windows, abort will return an exit code of 3.  In these cases,
//       // generate additional diagnostic information if possible.
//       bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
// #ifdef _WIN32
//       DiagnoseCrash |= CommandRes == 3;
// #endif
//       if (DiagnoseCrash) {
//         TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
//         break;
//       }
//     }
//   }

//   Diags.getClient()->finish();

//   // If any timers were active but haven't been destroyed yet, print their
//   // results now.  This happens in -disable-free mode.
//   llvm::TimerGroup::printAll(llvm::errs());

// #ifdef _WIN32
//   // Exit status should not be negative on Win32, unless abnormal termination.
//   // Once abnormal termiation was caught, negative status should not be
//   // propagated.
//   if (Res < 0)
//     Res = 1;
// #endif

  // If we have multiple failing commands, we return the result of the first
  // failing command.

}
+4 −17
Original line number Diff line number Diff line
// void X(int);

void foo(int* a, int *b) {
  if (a[0] > 1) {
    b[0] = 2;
  }
//   auto x2 = []() { 
//       return 1;
//   };

  auto l = [&](int q) {
    X | 0;
    // int x = q;
  auto l = [&]() {
    X(0);
    analog("ibm-hamiltonian-evolve");
    autogen("uccsd",2);
  };
}

void bar(float x, float y); // just a declaration

void bang(int* a, int v) {
    int i;
    for (i = 0; i < v; ++i) {
        a[i] -= i;
    }
}
 No newline at end of file