[clang-tools-extra] [clangd] Add includes from source to non-self-contained headers (PR #72479)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 15 22:17:21 PST 2023
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
More information about the cfe-commits
mailing list