Skip to content

Commit 35456a4

Browse files
committed
Add includes from source to non-self-contained headers
1 parent ce7fd49 commit 35456a4

File tree

1 file changed

+54
-6
lines changed

1 file changed

+54
-6
lines changed

clang-tools-extra/clangd/TUScheduler.cpp

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "Config.h"
5353
#include "Diagnostics.h"
5454
#include "GlobalCompilationDatabase.h"
55+
#include "HeaderSourceSwitch.h"
5556
#include "ParsedAST.h"
5657
#include "Preamble.h"
5758
#include "clang-include-cleaner/Record.h"
@@ -64,6 +65,7 @@
6465
#include "support/Threading.h"
6566
#include "support/Trace.h"
6667
#include "clang/Basic/Stack.h"
68+
#include "clang/Driver/Driver.h"
6769
#include "clang/Frontend/CompilerInvocation.h"
6870
#include "clang/Tooling/CompilationDatabase.h"
6971
#include "llvm/ADT/FunctionExtras.h"
@@ -622,7 +624,7 @@ class ASTWorker {
622624
const TUScheduler::Options &Opts, ParsingCallbacks &Callbacks);
623625
~ASTWorker();
624626

625-
void update(ParseInputs Inputs, WantDiagnostics, bool ContentChanged);
627+
void update(ParseInputs Inputs, WantDiagnostics, bool ContentChanged, std::optional<std::vector<std::string>> SourceInclides);
626628
void
627629
runWithAST(llvm::StringRef Name,
628630
llvm::unique_function<void(llvm::Expected<InputsAndAST>)> Action,
@@ -857,7 +859,7 @@ ASTWorker::~ASTWorker() {
857859
}
858860

859861
void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags,
860-
bool ContentChanged) {
862+
bool ContentChanged, std::optional<std::vector<std::string>> SourceInclides) {
861863
llvm::StringLiteral TaskName = "Update";
862864
auto Task = [=]() mutable {
863865
// Get the actual command as `Inputs` does not have a command.
@@ -881,10 +883,24 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags,
881883
}
882884
}
883885
}
884-
if (Cmd)
886+
if (!Cmd)
887+
Cmd = CDB.getFallbackCommand(FileName);
888+
if (Cmd) {
889+
if (SourceInclides && !SourceInclides->empty()) {
890+
Cmd->CommandLine.reserve(Cmd->CommandLine.size() +
891+
SourceInclides->size());
892+
auto PosArg =
893+
std::find(Cmd->CommandLine.begin(), Cmd->CommandLine.end(), "--");
894+
auto UsePushBack = PosArg == Cmd->CommandLine.end();
895+
for (auto &&Arg : *SourceInclides) {
896+
if (UsePushBack)
897+
Cmd->CommandLine.push_back(std::move(Arg));
898+
else
899+
PosArg = std::next(Cmd->CommandLine.insert(PosArg, std::move(Arg)));
900+
}
901+
}
885902
Inputs.CompileCommand = std::move(*Cmd);
886-
else
887-
Inputs.CompileCommand = CDB.getFallbackCommand(FileName);
903+
}
888904

889905
bool InputsAreTheSame =
890906
std::tie(FileInputs.CompileCommand, FileInputs.Contents) ==
@@ -1684,7 +1700,39 @@ bool TUScheduler::update(PathRef File, ParseInputs Inputs,
16841700
ContentChanged = true;
16851701
FD->Contents = Inputs.Contents;
16861702
}
1687-
FD->Worker->update(std::move(Inputs), WantDiags, ContentChanged);
1703+
std::optional<std::vector<std::string>> SourceInclides;
1704+
if (isHeaderFile(File)) {
1705+
std::string SourceFile;
1706+
auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
1707+
if (auto CorrespondingFile =
1708+
clang::clangd::getCorrespondingHeaderOrSource(File, std::move(VFS)))
1709+
SourceFile = *CorrespondingFile;
1710+
if (SourceFile.empty())
1711+
SourceFile = HeaderIncluders->get(File);
1712+
if (!SourceFile.empty() && Files.contains(SourceFile)) {
1713+
std::unique_ptr<FileData> &FD = Files[SourceFile];
1714+
if (FD && FD->Worker->isASTCached()) {
1715+
if (auto AST = IdleASTs->take(FD->Worker.lock().get())) {
1716+
auto &Headers = AST.value()->getIncludeStructure().MainFileIncludes;
1717+
std::vector<std::string> Includes;
1718+
Includes.reserve(Headers.size());
1719+
for (const auto &H : Headers) {
1720+
if (H.Resolved == File) {
1721+
if (isSystem(H.FileKind))
1722+
Includes.clear();
1723+
break;
1724+
}
1725+
auto Include = "-include" + H.Resolved;
1726+
Includes.push_back(std::move(Include));
1727+
}
1728+
if (!Includes.empty())
1729+
SourceInclides = std::move(Includes);
1730+
IdleASTs->put(FD->Worker.lock().get(), std::move(AST.value()));
1731+
}
1732+
}
1733+
}
1734+
}
1735+
FD->Worker->update(std::move(Inputs), WantDiags, ContentChanged, SourceInclides);
16881736
// There might be synthetic update requests, don't change the LastActiveFile
16891737
// in such cases.
16901738
if (ContentChanged)

0 commit comments

Comments
 (0)