diff --git a/include/Compiler/Clang.h b/include/Compiler/Clang.h new file mode 100644 index 00000000..8e742837 --- /dev/null +++ b/include/Compiler/Clang.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include +#include +#include +#include diff --git a/include/Compiler/Compiler.h b/include/Compiler/Compiler.h index 300bf58a..fcf0b3be 100644 --- a/include/Compiler/Compiler.h +++ b/include/Compiler/Compiler.h @@ -1,21 +1,9 @@ #pragma once -#include -#include +#include namespace clice { -// TODO: - -class Preamble; - -// std::unique_ptr createInvocation(StringRef filename, -// StringRef content, -// llvm::ArrayRef args, -// Preamble* preamble = nullptr); -// -// std::unique_ptr createInstance(std::shared_ptr invocation); - class Compiler { public: Compiler(llvm::StringRef filepath, @@ -34,7 +22,7 @@ public: bool applyPCM(llvm::StringRef filepath, llvm::StringRef name); - /// build AST. + /// Build AST. void buildAST(); /// Generate the PCH(PreCompiledHeader) to output path. Generally execute `clang::GeneratePCHAction`. @@ -45,6 +33,7 @@ public: /// `clang::GenerateReducedModuleInterfaceAction`. void generatePCM(llvm::StringRef outpath); + /// Run code complete in given file and location. void codeCompletion(llvm::StringRef filepath, std::uint32_t line, std::uint32_t column, @@ -54,6 +43,10 @@ public: return instance->getSema(); } + clang::FileManager& fileMgr() { + return instance->getFileManager(); + } + clang::SourceManager& srcMgr() { return instance->getSourceManager(); } @@ -66,6 +59,10 @@ public: return instance->getASTContext().getTranslationUnitDecl(); } + clang::syntax::TokenBuffer& tokBuf() { + return *buffer; + } + private: void ExecuteAction(); diff --git a/include/Compiler/Dependency.h b/include/Compiler/Dependency.h index 925036e5..db196a7b 100644 --- a/include/Compiler/Dependency.h +++ b/include/Compiler/Dependency.h @@ -1,10 +1,10 @@ #pragma once -#include +#include namespace clice::dependencies { -void load(ArrayRef dirs); +void load(llvm::ArrayRef dirs); /// Record the include graph of the translation unit. struct IncludeGraph {}; diff --git a/include/Compiler/Diagnostic.h b/include/Compiler/Diagnostic.h index 6d41a2b4..b42c1e5b 100644 --- a/include/Compiler/Diagnostic.h +++ b/include/Compiler/Diagnostic.h @@ -1,19 +1,10 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "clang/Sema/TemplateDeduction.h" +#include namespace clice { -class Diagnostic : public clang::DiagnosticConsumer { +class DiagnosticCollector : public clang::DiagnosticConsumer { public: void BeginSourceFile(const clang::LangOptions& Opts, const clang::Preprocessor* PP) override; diff --git a/include/Compiler/Directive.h b/include/Compiler/Directive.h index 7d5a3bb8..ad75a3cd 100644 --- a/include/Compiler/Directive.h +++ b/include/Compiler/Directive.h @@ -1,4 +1,6 @@ -#include "Diagnostic.h" +#pragma once + +#include namespace clice { diff --git a/include/Compiler/ParsedAST.h b/include/Compiler/ParsedAST.h index ba800256..e8ada415 100644 --- a/include/Compiler/ParsedAST.h +++ b/include/Compiler/ParsedAST.h @@ -1,6 +1,6 @@ #pragma once -#include "Preamble.h" +#include namespace clice { @@ -11,12 +11,10 @@ struct ParsedAST { clang::FileManager& fileManager; clang::SourceManager& sourceManager; clang::syntax::TokenBuffer tokenBuffer; - std::unique_ptr directive; + // std::unique_ptr directive; std::unique_ptr action; std::unique_ptr instance; - - clang::FileID getFileID(llvm::StringRef filename) const { auto entry = fileManager.getFileRef(filename); if(!entry) { diff --git a/include/Compiler/Preamble.h b/include/Compiler/Preamble.h index 6504fb0b..f1a63953 100644 --- a/include/Compiler/Preamble.h +++ b/include/Compiler/Preamble.h @@ -1,6 +1,6 @@ #pragma once -#include "Directive.h" +#include namespace clice { diff --git a/include/Compiler/Resolver.h b/include/Compiler/Resolver.h index dcc79489..9b026b30 100644 --- a/include/Compiler/Resolver.h +++ b/include/Compiler/Resolver.h @@ -1,9 +1,6 @@ #pragma once -#include "ParsedAST.h" -#include -#include -#include +#include namespace clice { @@ -21,6 +18,7 @@ public: // TODO: // use a relative clear way to resolve `UnresolvedLookupExpr`. + private: clang::Sema& sema; }; diff --git a/include/Compiler/Selection.h b/include/Compiler/Selection.h index 2352b963..caad0d8d 100644 --- a/include/Compiler/Selection.h +++ b/include/Compiler/Selection.h @@ -1,5 +1,6 @@ -#include "ParsedAST.h" -#include +#pragma once + +#include namespace clice { diff --git a/include/Index/CSIF.h b/include/Index/CSIF.h index 89db31a3..c76602f0 100644 --- a/include/Index/CSIF.h +++ b/include/Index/CSIF.h @@ -19,28 +19,28 @@ struct Occurrence; /// [SemanticDB](https://scalameta.org/docs/semanticdb/specification.html). struct CSIF { /// The version of the CSIF format. - StringRef version; + llvm::StringRef version; /// The language of the source code, currently only supports "c" and "c++". - StringRef language; + llvm::StringRef language; /// The URI of the source file. - StringRef uri; + llvm::StringRef uri; /// The context of the source file, used to check whether need to re-index the source file. - StringRef content; + llvm::StringRef content; /// The commands used to compile the source file. - ArrayRef commands; + llvm::ArrayRef commands; /// The symbols in the source file. - ArrayRef symbols; + llvm::ArrayRef symbols; /// The occurrences in the source file. - ArrayRef occurrences; + llvm::ArrayRef occurrences; /// The semantic tokens in the source file. - ArrayRef semanticTokens; + llvm::ArrayRef semanticTokens; // FIXME: /// The diagnostics in the source file. - // ArrayRef diagnostics; + // llvm::ArrayRef diagnostics; /// The inlay hints in the source file. - // ArrayRef inlayHints; + // llvm::ArrayRef inlayHints; }; enum Role { @@ -69,12 +69,12 @@ struct Symbol { /// The ID of the symbol. SymbolID id; /// display when hover. - StringRef document; + llvm::StringRef document; // TODO: append more useful information. /// The relations of the symbol. - ArrayRef relations; + llvm::ArrayRef relations; }; struct Occurrence { diff --git a/include/Support/ADT.h b/include/Support/ADT.h index b966f542..ec7ae074 100644 --- a/include/Support/ADT.h +++ b/include/Support/ADT.h @@ -9,9 +9,7 @@ #include #include +#include + namespace clice { -using llvm::ArrayRef; -using llvm::StringRef; -using llvm::SmallVector; -using llvm::SmallString; } // namespace clice diff --git a/src/Compiler/Compiler.cpp b/src/Compiler/Compiler.cpp index eef5c8cd..88a5636a 100644 --- a/src/Compiler/Compiler.cpp +++ b/src/Compiler/Compiler.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace clice { @@ -9,13 +10,15 @@ static void setInvocation(clang::CompilerInvocation& invocation) { clang::LangOptions& langOpts = invocation.getLangOpts(); langOpts.CommentOpts.ParseAllComments = true; langOpts.RetainCommentsFromSystemHeaders = true; + + // FIXME: add more. } Compiler::Compiler(llvm::StringRef filepath, llvm::StringRef content, llvm::ArrayRef args, llvm::IntrusiveRefCntPtr vfs) : filepath(filepath), content(content) { - // TODO: figure out should we use createInvocation? + // FIXME: figure out should we use createInvocation? clang::CreateInvocationOptions options; auto invocation = clang::createInvocation(args, options); @@ -23,6 +26,7 @@ Compiler::Compiler(llvm::StringRef filepath, instance->setInvocation(std::move(invocation)); + // FIXME: customize DiagnosticConsumer instance->createDiagnostics(new clang::TextDiagnosticPrinter(llvm::outs(), new clang::DiagnosticOptions()), true); if(!instance->createTarget()) { @@ -32,7 +36,7 @@ Compiler::Compiler(llvm::StringRef filepath, } bool Compiler::applyPCH(llvm::StringRef filepath, std::uint32_t bound, bool endAtStart) { - // TODO: check reuseable? + // FIXME: check reuseable? auto& preproc = instance->getPreprocessorOpts(); preproc.UsePredefines = false; preproc.ImplicitPCHInclude = filepath; @@ -43,7 +47,7 @@ bool Compiler::applyPCH(llvm::StringRef filepath, std::uint32_t bound, bool endA } bool Compiler::applyPCM(llvm::StringRef filepath, llvm::StringRef name) { - // TODO: check reuseable? + // FIXME: check reuseable? instance->getHeaderSearchOpts().PrebuiltModuleFiles.try_emplace(name.str(), filepath); return true; } @@ -89,10 +93,24 @@ void Compiler::ExecuteAction() { std::terminate(); } + auto& preproc = instance->getPreprocessor(); + + // FIXME: add PPCallbacks to collect information. + + // Beacuse CompilerInstance may create new Preprocessor in `BeginSourceFile`, + // So we must need to create TokenCollector here. + clang::syntax::TokenCollector collector{preproc}; + + // FIXME: clang-tidy, include-fixer, etc? + if(auto error = action->Execute()) { llvm::errs() << "Failed to execute action: " << error << "\n"; std::terminate(); } + + // Build TokenBuffer and index expanded tokens for improving performance. + buffer = std::make_unique(std::move(collector).consume()); + buffer->indexExpandedTokens(); } Compiler::~Compiler() { diff --git a/src/Compiler/Dependency.cpp b/src/Compiler/Dependency.cpp index 84146e79..0b063d0e 100644 --- a/src/Compiler/Dependency.cpp +++ b/src/Compiler/Dependency.cpp @@ -7,7 +7,7 @@ namespace clice::dependencies { namespace { /// module name -> file path. -llvm::StringMap moduleMap; +llvm::StringMap moduleMap; llvm::BumpPtrAllocator allocator; void scan() { @@ -23,7 +23,7 @@ void scan() { } // namespace -void load(ArrayRef dirs) { +void load(llvm::ArrayRef dirs) { for(auto dir: dirs) { std::string message; diff --git a/src/Compiler/Diagnostic.cpp b/src/Compiler/Diagnostic.cpp index 9a48a95c..bd5067a4 100644 --- a/src/Compiler/Diagnostic.cpp +++ b/src/Compiler/Diagnostic.cpp @@ -2,18 +2,18 @@ namespace clice { -void Diagnostic::BeginSourceFile(const clang::LangOptions& Opts, const clang::Preprocessor* PP) { +void DiagnosticCollector::BeginSourceFile(const clang::LangOptions& Opts, const clang::Preprocessor* PP) { }; -void Diagnostic::HandleDiagnostic(clang::DiagnosticsEngine::Level level, const clang::Diagnostic& diagnostic) { +void DiagnosticCollector::HandleDiagnostic(clang::DiagnosticsEngine::Level level, const clang::Diagnostic& diagnostic) { llvm::SmallString<128> message; diagnostic.FormatDiagnostic(message); // diagnostic.getLocation(); llvm::outs() << "Diagnostic: " << message << "\n"; }; -void Diagnostic::EndSourceFile() { +void DiagnosticCollector::EndSourceFile() { }; diff --git a/src/Compiler/Resolver.cpp b/src/Compiler/Resolver.cpp index 2744bc98..e4bfb666 100644 --- a/src/Compiler/Resolver.cpp +++ b/src/Compiler/Resolver.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include namespace clice { diff --git a/src/Index/Pack.cpp b/src/Index/Pack.cpp index 0fc8b187..7f34f747 100644 --- a/src/Index/Pack.cpp +++ b/src/Index/Pack.cpp @@ -25,16 +25,16 @@ struct Metadata { class Encoder { public: - void encode(StringRef& string) { + void encode(llvm::StringRef& string) { std::size_t offset = stringData.size(); stringData.insert(stringData.end(), string.begin(), string.end()); stringData.push_back('\0'); // modify pointer to offset - string = StringRef(reinterpret_cast(offset), string.size()); + string = llvm::StringRef(reinterpret_cast(offset), string.size()); } template - void encode(ArrayRef& array) { + void encode(llvm::ArrayRef& array) { std::size_t offset = arrayData.size(); arrayData.reserve(arrayData.size() + array.size() * sizeof(T)); for(auto elem: array) { @@ -44,7 +44,7 @@ public: arrayData.insert(arrayData.end(), begin, begin + sizeof(T)); } // modify pointer to offset - array = ArrayRef(reinterpret_cast(offset), array.size()); + array = llvm::ArrayRef(reinterpret_cast(offset), array.size()); } template @@ -91,13 +91,13 @@ private: class Decoder { public: - void decode(StringRef& string) { - string = StringRef(data + stringOffset, string.size()); + void decode(llvm::StringRef& string) { + string = llvm::StringRef(data + stringOffset, string.size()); } template - void decode(ArrayRef& array) { - array = ArrayRef(reinterpret_cast(data + arrayOffset), array.size()); + void decode(llvm::ArrayRef& array) { + array = llvm::ArrayRef(reinterpret_cast(data + arrayOffset), array.size()); for(auto& elem: array) { decodeMemberRef(const_cast(elem)); } diff --git a/src/Support/URI.cpp b/src/Support/URI.cpp index 9e6bde84..47fa09f5 100644 --- a/src/Support/URI.cpp +++ b/src/Support/URI.cpp @@ -1,6 +1,6 @@ #include #include - +#include namespace clice { /// returns true if the scheme is valid according to RFC 3986. diff --git a/tests/AST/Selection.cpp b/tests/AST/Selection.cpp index f253dbbf..a433c75a 100644 --- a/tests/AST/Selection.cpp +++ b/tests/AST/Selection.cpp @@ -1,5 +1,6 @@ #include "../Test.h" #include +#include namespace { @@ -15,13 +16,22 @@ using namespace clice; TEST(clice, SelectionTree) { foreachFile("SelectionTree", [](std::string file, llvm::StringRef content) { - // auto compiler = Compiler("main.cpp", content, compileArgs); - // auto AST = ParsedAST::build("main.cpp", content, compileArgs); - // auto id = AST->getFileID("main.cpp"); - // auto& sm = AST->context.getSourceManager(); - // auto begin = sm.translateLineCol(id, 7, 17); - // auto end = sm.translateLineCol(id, 7, 17); - // SelectionTree tree(sm.getFileOffset(begin), sm.getFileOffset(end), AST->context, AST->tokenBuffer); + auto compiler = Compiler("main.cpp", content, compileArgs); + compiler.buildAST(); + auto& fileMgr = compiler.fileMgr(); + auto entry = fileMgr.getFileRef("main.cpp"); + if(!entry) { + llvm::outs() << "Failed to get file id\n"; + std::terminate(); + } + auto& srcMgr = compiler.srcMgr(); + auto id = srcMgr.translateFile(*entry); + auto begin = srcMgr.translateLineCol(id, 7, 17); + auto end = srcMgr.translateLineCol(id, 7, 17); + SelectionTree tree(srcMgr.getFileOffset(begin), + srcMgr.getFileOffset(end), + compiler.context(), + compiler.tokBuf()); }); }