Skip to content

Commit 30a5c5b

Browse files
committed
Merge from 'master' to 'sycl-web' (#5)
CONFLICT (content): Merge conflict in clang/lib/Basic/IdentifierTable.cpp
2 parents 1d54cbb + 6a30894 commit 30a5c5b

File tree

769 files changed

+24479
-6789
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

769 files changed

+24479
-6789
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ void ProTypeMemberInitCheck::checkMissingMemberInitializer(
456456
// Don't suggest fixes for bitfields because in-class initialization is not
457457
// possible until C++2a.
458458
if (F->getType()->isEnumeralType() ||
459-
(!getLangOpts().CPlusPlus2a && F->isBitField()))
459+
(!getLangOpts().CPlusPlus20 && F->isBitField()))
460460
return;
461461
if (!F->getParent()->isUnion() || UnionsSeen.insert(F->getParent()).second)
462462
FieldsToFix.insert(F);

clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ void UseDefaultMemberInitCheck::registerMatchers(MatchFinder *Finder) {
217217
isDefaultConstructor(), unless(isInstantiated()),
218218
forEachConstructorInitializer(
219219
cxxCtorInitializer(
220-
forField(unless(anyOf(getLangOpts().CPlusPlus2a
220+
forField(unless(anyOf(getLangOpts().CPlusPlus20
221221
? unless(anything())
222222
: isBitField(),
223223
hasInClassInitializer(anything()),

clang-tools-extra/clang-tidy/portability/SIMDIntrinsicsCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ void SIMDIntrinsicsCheck::registerMatchers(MatchFinder *Finder) {
9696
// If Std is not specified, infer it from the language options.
9797
// libcxx implementation backports it to C++11 std::experimental::simd.
9898
if (Std.empty())
99-
Std = getLangOpts().CPlusPlus2a ? "std" : "std::experimental";
99+
Std = getLangOpts().CPlusPlus20 ? "std" : "std::experimental";
100100

101101
Finder->addMatcher(callExpr(callee(functionDecl(
102102
matchesName("^::(_mm_|_mm256_|_mm512_|vec_)"),

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,8 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos,
280280
Pos, FS, Index));
281281
};
282282

283-
// Unlike code completion, we wait for an up-to-date preamble here.
284-
// Signature help is often triggered after code completion. If the code
285-
// completion inserted a header to make the symbol available, then using
286-
// the old preamble would yield useless results.
287-
WorkScheduler.runWithPreamble("SignatureHelp", File, TUScheduler::Consistent,
283+
// Unlike code completion, we wait for a preamble here.
284+
WorkScheduler.runWithPreamble("SignatureHelp", File, TUScheduler::Stale,
288285
std::move(Action));
289286
}
290287

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ struct SemaCompleteInput {
10231023
PathRef FileName;
10241024
const tooling::CompileCommand &Command;
10251025
const PreambleData &Preamble;
1026+
const PreamblePatch &Patch;
10261027
llvm::StringRef Contents;
10271028
size_t Offset;
10281029
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS;
@@ -1060,7 +1061,6 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
10601061
ParseInput.CompileCommand = Input.Command;
10611062
ParseInput.FS = VFS;
10621063
ParseInput.Contents = std::string(Input.Contents);
1063-
ParseInput.Opts = ParseOptions();
10641064

10651065
IgnoreDiagnostics IgnoreDiags;
10661066
auto CI = buildCompilerInvocation(ParseInput, IgnoreDiags);
@@ -1096,6 +1096,7 @@ bool semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
10961096
PreambleBounds PreambleRegion =
10971097
ComputePreambleBounds(*CI->getLangOpts(), ContentsBuffer.get(), 0);
10981098
bool CompletingInPreamble = PreambleRegion.Size > Input.Offset;
1099+
Input.Patch.apply(*CI);
10991100
// NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise
11001101
// the remapped buffers do not get freed.
11011102
auto Clang = prepareCompilerInstance(
@@ -1754,8 +1755,10 @@ codeComplete(PathRef FileName, const tooling::CompileCommand &Command,
17541755
SpecFuzzyFind, Opts);
17551756
return (!Preamble || Opts.RunParser == CodeCompleteOptions::NeverParse)
17561757
? std::move(Flow).runWithoutSema(Contents, *Offset, VFS)
1757-
: std::move(Flow).run(
1758-
{FileName, Command, *Preamble, Contents, *Offset, VFS});
1758+
: std::move(Flow).run({FileName, Command, *Preamble,
1759+
// We want to serve code completions with
1760+
// low latency, so don't bother patching.
1761+
PreamblePatch(), Contents, *Offset, VFS});
17591762
}
17601763

17611764
SignatureHelp signatureHelp(PathRef FileName,
@@ -1775,10 +1778,15 @@ SignatureHelp signatureHelp(PathRef FileName,
17751778
Options.IncludeMacros = false;
17761779
Options.IncludeCodePatterns = false;
17771780
Options.IncludeBriefComments = false;
1778-
IncludeStructure PreambleInclusions; // Unused for signatureHelp
1781+
1782+
ParseInputs PI;
1783+
PI.CompileCommand = Command;
1784+
PI.Contents = Contents.str();
1785+
PI.FS = std::move(VFS);
1786+
auto PP = PreamblePatch::create(FileName, PI, Preamble);
17791787
semaCodeComplete(
17801788
std::make_unique<SignatureHelpCollector>(Options, Index, Result), Options,
1781-
{FileName, Command, Preamble, Contents, *Offset, std::move(VFS)});
1789+
{FileName, Command, Preamble, PP, Contents, *Offset, std::move(PI.FS)});
17821790
return Result;
17831791
}
17841792

clang-tools-extra/clangd/Diagnostics.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -556,10 +556,23 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
556556
if (!InsideMainFile)
557557
return false;
558558

559+
// Copy as we may modify the ranges.
560+
auto FixIts = Info.getFixItHints().vec();
559561
llvm::SmallVector<TextEdit, 1> Edits;
560-
for (auto &FixIt : Info.getFixItHints()) {
561-
// Follow clang's behavior, don't apply FixIt to the code in macros,
562-
// we are less certain it is the right fix.
562+
for (auto &FixIt : FixIts) {
563+
// Allow fixits within a single macro-arg expansion to be applied.
564+
// This can be incorrect if the argument is expanded multiple times in
565+
// different contexts. Hopefully this is rare!
566+
if (FixIt.RemoveRange.getBegin().isMacroID() &&
567+
FixIt.RemoveRange.getEnd().isMacroID() &&
568+
SM.getFileID(FixIt.RemoveRange.getBegin()) ==
569+
SM.getFileID(FixIt.RemoveRange.getEnd())) {
570+
FixIt.RemoveRange = CharSourceRange(
571+
{SM.getTopMacroCallerLoc(FixIt.RemoveRange.getBegin()),
572+
SM.getTopMacroCallerLoc(FixIt.RemoveRange.getEnd())},
573+
FixIt.RemoveRange.isTokenRange());
574+
}
575+
// Otherwise, follow clang's behavior: no fixits in macros.
563576
if (FixIt.RemoveRange.getBegin().isMacroID() ||
564577
FixIt.RemoveRange.getEnd().isMacroID())
565578
return false;
@@ -570,8 +583,8 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
570583

571584
llvm::SmallString<64> Message;
572585
// If requested and possible, create a message like "change 'foo' to 'bar'".
573-
if (SyntheticMessage && Info.getNumFixItHints() == 1) {
574-
const auto &FixIt = Info.getFixItHint(0);
586+
if (SyntheticMessage && FixIts.size() == 1) {
587+
const auto &FixIt = FixIts.front();
575588
bool Invalid = false;
576589
llvm::StringRef Remove =
577590
Lexer::getSourceText(FixIt.RemoveRange, SM, *LangOpts, &Invalid);

clang-tools-extra/clangd/Headers.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class RecordHeaders : public PPCallbacks {
2828

2929
// Record existing #includes - both written and resolved paths. Only #includes
3030
// in the main file are collected.
31-
void InclusionDirective(SourceLocation HashLoc, const Token & /*IncludeTok*/,
31+
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
3232
llvm::StringRef FileName, bool IsAngled,
3333
CharSourceRange FilenameRange, const FileEntry *File,
3434
llvm::StringRef /*SearchPath*/,
@@ -44,6 +44,7 @@ class RecordHeaders : public PPCallbacks {
4444
Inc.Resolved = std::string(File ? File->tryGetRealPathName() : "");
4545
Inc.HashOffset = SM.getFileOffset(HashLoc);
4646
Inc.FileKind = FileKind;
47+
Inc.Directive = IncludeTok.getIdentifierInfo()->getPPKeywordID();
4748
}
4849
if (File) {
4950
auto *IncludingFileEntry = SM.getFileEntryForID(SM.getFileID(HashLoc));

clang-tools-extra/clangd/Headers.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Protocol.h"
1414
#include "SourceCode.h"
1515
#include "index/Symbol.h"
16+
#include "clang/Basic/TokenKinds.h"
1617
#include "clang/Format/Format.h"
1718
#include "clang/Lex/HeaderSearch.h"
1819
#include "clang/Lex/PPCallbacks.h"
@@ -22,6 +23,7 @@
2223
#include "llvm/ADT/StringSet.h"
2324
#include "llvm/Support/Error.h"
2425
#include "llvm/Support/VirtualFileSystem.h"
26+
#include <string>
2527

2628
namespace clang {
2729
namespace clangd {
@@ -50,9 +52,10 @@ llvm::SmallVector<llvm::StringRef, 1> getRankedIncludes(const Symbol &Sym);
5052

5153
// An #include directive that we found in the main file.
5254
struct Inclusion {
53-
Range R; // Inclusion range.
54-
std::string Written; // Inclusion name as written e.g. <vector>.
55-
Path Resolved; // Resolved path of included file. Empty if not resolved.
55+
Range R; // Inclusion range.
56+
tok::PPKeywordKind Directive; // Directive used for inclusion, e.g. import
57+
std::string Written; // Inclusion name as written e.g. <vector>.
58+
Path Resolved; // Resolved path of included file. Empty if not resolved.
5659
unsigned HashOffset = 0; // Byte offset from start of file to #.
5760
SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User;
5861
};

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,39 @@
88

99
#include "Preamble.h"
1010
#include "Compiler.h"
11+
#include "Headers.h"
1112
#include "Logger.h"
1213
#include "Trace.h"
14+
#include "clang/Basic/Diagnostic.h"
15+
#include "clang/Basic/LangOptions.h"
1316
#include "clang/Basic/SourceLocation.h"
17+
#include "clang/Basic/TokenKinds.h"
18+
#include "clang/Frontend/CompilerInvocation.h"
19+
#include "clang/Frontend/FrontendActions.h"
20+
#include "clang/Lex/Lexer.h"
1421
#include "clang/Lex/PPCallbacks.h"
22+
#include "clang/Lex/Preprocessor.h"
1523
#include "clang/Lex/PreprocessorOptions.h"
24+
#include "clang/Tooling/CompilationDatabase.h"
25+
#include "llvm/ADT/ArrayRef.h"
26+
#include "llvm/ADT/IntrusiveRefCntPtr.h"
27+
#include "llvm/ADT/STLExtras.h"
28+
#include "llvm/ADT/SmallString.h"
29+
#include "llvm/ADT/StringRef.h"
30+
#include "llvm/ADT/StringSet.h"
31+
#include "llvm/Support/Error.h"
32+
#include "llvm/Support/ErrorHandling.h"
33+
#include "llvm/Support/FormatVariadic.h"
34+
#include "llvm/Support/MemoryBuffer.h"
35+
#include "llvm/Support/Path.h"
36+
#include "llvm/Support/VirtualFileSystem.h"
37+
#include "llvm/Support/raw_ostream.h"
38+
#include <iterator>
39+
#include <memory>
40+
#include <string>
41+
#include <system_error>
42+
#include <utility>
43+
#include <vector>
1644

1745
namespace clang {
1846
namespace clangd {
@@ -74,6 +102,81 @@ class CppFilePreambleCallbacks : public PreambleCallbacks {
74102
const SourceManager *SourceMgr = nullptr;
75103
};
76104

105+
// Runs preprocessor over preamble section.
106+
class PreambleOnlyAction : public PreprocessorFrontendAction {
107+
protected:
108+
void ExecuteAction() override {
109+
Preprocessor &PP = getCompilerInstance().getPreprocessor();
110+
auto &SM = PP.getSourceManager();
111+
PP.EnterMainSourceFile();
112+
auto Bounds = ComputePreambleBounds(getCompilerInstance().getLangOpts(),
113+
SM.getBuffer(SM.getMainFileID()), 0);
114+
Token Tok;
115+
do {
116+
PP.Lex(Tok);
117+
assert(SM.isInMainFile(Tok.getLocation()));
118+
} while (Tok.isNot(tok::eof) &&
119+
SM.getDecomposedLoc(Tok.getLocation()).second < Bounds.Size);
120+
}
121+
};
122+
123+
/// Gets the includes in the preamble section of the file by running
124+
/// preprocessor over \p Contents. Returned includes do not contain resolved
125+
/// paths. \p VFS and \p Cmd is used to build the compiler invocation, which
126+
/// might stat/read files.
127+
llvm::Expected<std::vector<Inclusion>>
128+
scanPreambleIncludes(llvm::StringRef Contents,
129+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
130+
const tooling::CompileCommand &Cmd) {
131+
// Build and run Preprocessor over the preamble.
132+
ParseInputs PI;
133+
PI.Contents = Contents.str();
134+
PI.FS = std::move(VFS);
135+
PI.CompileCommand = Cmd;
136+
IgnoringDiagConsumer IgnoreDiags;
137+
auto CI = buildCompilerInvocation(PI, IgnoreDiags);
138+
if (!CI)
139+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
140+
"failed to create compiler invocation");
141+
CI->getDiagnosticOpts().IgnoreWarnings = true;
142+
auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Contents);
143+
auto Clang = prepareCompilerInstance(
144+
std::move(CI), nullptr, std::move(ContentsBuffer),
145+
// Provide an empty FS to prevent preprocessor from performing IO. This
146+
// also implies missing resolved paths for includes.
147+
new llvm::vfs::InMemoryFileSystem, IgnoreDiags);
148+
if (Clang->getFrontendOpts().Inputs.empty())
149+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
150+
"compiler instance had no inputs");
151+
// We are only interested in main file includes.
152+
Clang->getPreprocessorOpts().SingleFileParseMode = true;
153+
PreambleOnlyAction Action;
154+
if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
155+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
156+
"failed BeginSourceFile");
157+
Preprocessor &PP = Clang->getPreprocessor();
158+
IncludeStructure Includes;
159+
PP.addPPCallbacks(
160+
collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
161+
if (llvm::Error Err = Action.Execute())
162+
return std::move(Err);
163+
Action.EndSourceFile();
164+
return Includes.MainFileIncludes;
165+
}
166+
167+
const char *spellingForIncDirective(tok::PPKeywordKind IncludeDirective) {
168+
switch (IncludeDirective) {
169+
case tok::pp_include:
170+
return "include";
171+
case tok::pp_import:
172+
return "import";
173+
case tok::pp_include_next:
174+
return "include_next";
175+
default:
176+
break;
177+
}
178+
llvm_unreachable("not an include directive");
179+
}
77180
} // namespace
78181

79182
PreambleData::PreambleData(const ParseInputs &Inputs,
@@ -166,5 +269,78 @@ bool isPreambleCompatible(const PreambleData &Preamble,
166269
Preamble.Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
167270
Inputs.FS.get());
168271
}
272+
273+
PreamblePatch PreamblePatch::create(llvm::StringRef FileName,
274+
const ParseInputs &Modified,
275+
const PreambleData &Baseline) {
276+
// First scan the include directives in Baseline and Modified. These will be
277+
// used to figure out newly added directives in Modified. Scanning can fail,
278+
// the code just bails out and creates an empty patch in such cases, as:
279+
// - If scanning for Baseline fails, no knowledge of existing includes hence
280+
// patch will contain all the includes in Modified. Leading to rebuild of
281+
// whole preamble, which is terribly slow.
282+
// - If scanning for Modified fails, cannot figure out newly added ones so
283+
// there's nothing to do but generate an empty patch.
284+
auto BaselineIncludes = scanPreambleIncludes(
285+
// Contents needs to be null-terminated.
286+
Baseline.Preamble.getContents().str(),
287+
Baseline.StatCache->getConsumingFS(Modified.FS), Modified.CompileCommand);
288+
if (!BaselineIncludes) {
289+
elog("Failed to scan includes for baseline of {0}: {1}", FileName,
290+
BaselineIncludes.takeError());
291+
return {};
292+
}
293+
auto ModifiedIncludes = scanPreambleIncludes(
294+
Modified.Contents, Baseline.StatCache->getConsumingFS(Modified.FS),
295+
Modified.CompileCommand);
296+
if (!ModifiedIncludes) {
297+
elog("Failed to scan includes for modified contents of {0}: {1}", FileName,
298+
ModifiedIncludes.takeError());
299+
return {};
300+
}
301+
302+
PreamblePatch PP;
303+
// This shouldn't coincide with any real file name.
304+
llvm::SmallString<128> PatchName;
305+
llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName),
306+
"__preamble_patch__.h");
307+
PP.PatchFileName = PatchName.str().str();
308+
309+
// We are only interested in newly added includes, record the ones in Baseline
310+
// for exclusion.
311+
llvm::DenseSet<std::pair<tok::PPKeywordKind, llvm::StringRef>>
312+
ExistingIncludes;
313+
for (const auto &Inc : *BaselineIncludes)
314+
ExistingIncludes.insert({Inc.Directive, Inc.Written});
315+
// Calculate extra includes that needs to be inserted.
316+
llvm::raw_string_ostream Patch(PP.PatchContents);
317+
for (const auto &Inc : *ModifiedIncludes) {
318+
if (ExistingIncludes.count({Inc.Directive, Inc.Written}))
319+
continue;
320+
Patch << llvm::formatv("#{0} {1}\n", spellingForIncDirective(Inc.Directive),
321+
Inc.Written);
322+
}
323+
Patch.flush();
324+
325+
// FIXME: Handle more directives, e.g. define/undef.
326+
return PP;
327+
}
328+
329+
void PreamblePatch::apply(CompilerInvocation &CI) const {
330+
// No need to map an empty file.
331+
if (PatchContents.empty())
332+
return;
333+
auto &PPOpts = CI.getPreprocessorOpts();
334+
auto PatchBuffer =
335+
// we copy here to ensure contents are still valid if CI outlives the
336+
// PreamblePatch.
337+
llvm::MemoryBuffer::getMemBufferCopy(PatchContents, PatchFileName);
338+
// CI will take care of the lifetime of the buffer.
339+
PPOpts.addRemappedFile(PatchFileName, PatchBuffer.release());
340+
// The patch will be parsed after loading the preamble ast and before parsing
341+
// the main file.
342+
PPOpts.Includes.push_back(PatchFileName);
343+
}
344+
169345
} // namespace clangd
170346
} // namespace clang

0 commit comments

Comments
 (0)