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; }