llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangd Author: SR_team (sr-tream) <details> <summary>Changes</summary> It's a hack to solve include headers from source to non-self-contained headers Limitations: - header file must be matched by `isHeaderFile` without language options - non-self-contained header must be included by source - AST for source must be cached before open non-self-contained header - resolved only includes, without macros and symbols from source file Example: ```cpp // header void hello(std::string Name); ``` ```cpp // source #include <string> #include "header.h" #include <iostream> int main(){ hello("World"); return 0; } void hello(std::string Name){ std::cout << "Hello, " << Name << "\n"; } ``` Current clangd behavior for header - show error `Use of undeclared identifier 'std'` With this PR clangd add include <string> to command line for header --- Full diff: https://github.com/llvm/llvm-project/pull/72479.diff 1 Files Affected: - (modified) clang-tools-extra/clangd/TUScheduler.cpp (+50-3) ``````````diff diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 324ba1fc8cb8952..208a723d8b7ea8f 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -52,6 +52,7 @@ #include "Config.h" #include "Diagnostics.h" #include "GlobalCompilationDatabase.h" +#include "HeaderSourceSwitch.h" #include "ParsedAST.h" #include "Preamble.h" #include "clang-include-cleaner/Record.h" @@ -64,6 +65,7 @@ #include "support/Threading.h" #include "support/Trace.h" #include "clang/Basic/Stack.h" +#include "clang/Driver/Driver.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/FunctionExtras.h" @@ -881,10 +883,30 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags, } } } - if (Cmd) + if (!Cmd) + Cmd = CDB.getFallbackCommand(FileName); + if (Cmd) { + if (!Inputs.CompileCommand.CommandLine.empty()) { + auto PosArg = + std::find(Cmd->CommandLine.begin(), Cmd->CommandLine.end(), "--"); + SmallVector<const char *, 16> TmpArgv; + for (const std::string &S : Cmd->CommandLine) + TmpArgv.push_back(S.c_str()); + auto ClangCLMode = + !TmpArgv.empty() && + driver::IsClangCL(driver::getDriverMode( + TmpArgv.front(), llvm::ArrayRef(TmpArgv).slice(1))); + for (auto &&Arg : Inputs.CompileCommand.CommandLine) { + if (ClangCLMode) + Arg.replace(0, 8, "/FI"); // 8 - strlen("-include") + if (PosArg == Cmd->CommandLine.end()) + Cmd->CommandLine.push_back(std::move(Arg)); + else + PosArg = std::next(Cmd->CommandLine.insert(PosArg, std::move(Arg))); + } + } Inputs.CompileCommand = std::move(*Cmd); - else - Inputs.CompileCommand = CDB.getFallbackCommand(FileName); + } bool InputsAreTheSame = std::tie(FileInputs.CompileCommand, FileInputs.Contents) == @@ -1684,6 +1706,31 @@ bool TUScheduler::update(PathRef File, ParseInputs Inputs, ContentChanged = true; FD->Contents = Inputs.Contents; } + if (isHeaderFile(File)) { + std::string SourceFile = HeaderIncluders->get(File); + if (SourceFile.empty()) { + auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory); + if (auto CorrespondingFile = + clang::clangd::getCorrespondingHeaderOrSource(File, + std::move(VFS))) + SourceFile = *CorrespondingFile; + } + if (!SourceFile.empty()) { + std::unique_ptr<FileData> &FD = Files[SourceFile]; + if (FD && FD->Worker->isASTCached()) { + if (auto AST = IdleASTs->take(FD->Worker.lock().get())) { + auto &Headers = AST.value()->getIncludeStructure().MainFileIncludes; + for (const auto &H : Headers) { + if (H.Resolved == File) + break; + auto CmdLine = "-include" + H.Resolved; + Inputs.CompileCommand.CommandLine.push_back(std::move(CmdLine)); + } + IdleASTs->put(FD->Worker.lock().get(), std::move(AST.value())); + } + } + } + } FD->Worker->update(std::move(Inputs), WantDiags, ContentChanged); // There might be synthetic update requests, don't change the LastActiveFile // in such cases. `````````` </details> https://github.com/llvm/llvm-project/pull/72479 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits