コード例 #1
0
ファイル: swift-syntax-test.cpp プロジェクト: hughbe/swift
int getSyntaxTree(const char *MainExecutablePath,
                  const StringRef InputFilename,
                  CompilerInstance &Instance,
                  llvm::SmallVectorImpl<syntax::Syntax> &TopLevelDecls,
                  std::vector<std::pair<RC<syntax::TokenSyntax>,
                              syntax::AbsolutePosition>> &Tokens) {
  CompilerInvocation Invocation;
  Invocation.addInputFilename(InputFilename);

  Invocation.setMainExecutablePath(
    llvm::sys::fs::getMainExecutable(MainExecutablePath,
      reinterpret_cast<void *>(&anchorForGetMainExecutable)));

  Invocation.setModuleName("Test");

  auto &SourceMgr = Instance.getSourceMgr();

  PrintingDiagnosticConsumer DiagPrinter;
  Instance.addDiagnosticConsumer(&DiagPrinter);
  if (Instance.setup(Invocation)) {
    return EXIT_FAILURE;
  }

  // First, parse the file normally and get the regular old AST.
  Instance.performParseOnly();

  if (Instance.getDiags().hadAnyError()) {
    return EXIT_FAILURE;
  }

  auto BufferID = Instance.getInputBufferIDs().back();
  SourceFile *SF = nullptr;
  for (auto Unit : Instance.getMainModule()->getFiles()) {
    SF = dyn_cast<SourceFile>(Unit);
    if (SF != nullptr) {
      break;
    }
  }
  assert(SF && "No source file");

  // Retokenize the buffer with full fidelity
  if (getTokensFromFile(BufferID, Invocation.getLangOptions(),
                        SourceMgr,
                        Instance.getDiags(), Tokens) == EXIT_FAILURE) {
    return EXIT_FAILURE;
  }

  SmallVector<Decl *, 256> FileDecls;
  SF->getTopLevelDecls(FileDecls);
  sema::Semantics Sema;
  // Convert the old ASTs to the new full-fidelity syntax tree and print
  // them out.
  for (auto *Decl : FileDecls) {
    if (Decl->escapedFromIfConfig()) {
      continue;
    }
    auto NewNode = transformAST(ASTNode(Decl), Sema, SourceMgr,
                                BufferID, Tokens);
    if (NewNode.hasValue()) {
      TopLevelDecls.push_back(NewNode.getValue());
    }
  }

  return EXIT_SUCCESS;
}