clang-tools  14.0.0git
Preamble.cpp
Go to the documentation of this file.
1 //===--- Preamble.cpp - Reusing expensive parts of the AST ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Preamble.h"
10 #include "Compiler.h"
11 #include "Config.h"
12 #include "Headers.h"
13 #include "SourceCode.h"
14 #include "support/Logger.h"
15 #include "support/ThreadsafeFS.h"
16 #include "support/Trace.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/DiagnosticLex.h"
20 #include "clang/Basic/LangOptions.h"
21 #include "clang/Basic/SourceLocation.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "clang/Basic/TokenKinds.h"
24 #include "clang/Frontend/CompilerInvocation.h"
25 #include "clang/Frontend/FrontendActions.h"
26 #include "clang/Lex/HeaderSearch.h"
27 #include "clang/Lex/Lexer.h"
28 #include "clang/Lex/PPCallbacks.h"
29 #include "clang/Lex/Preprocessor.h"
30 #include "clang/Lex/PreprocessorOptions.h"
31 #include "clang/Tooling/CompilationDatabase.h"
32 #include "llvm/ADT/ArrayRef.h"
33 #include "llvm/ADT/DenseMap.h"
34 #include "llvm/ADT/DenseSet.h"
35 #include "llvm/ADT/IntrusiveRefCntPtr.h"
36 #include "llvm/ADT/None.h"
37 #include "llvm/ADT/Optional.h"
38 #include "llvm/ADT/STLExtras.h"
39 #include "llvm/ADT/SmallString.h"
40 #include "llvm/ADT/StringExtras.h"
41 #include "llvm/ADT/StringRef.h"
42 #include "llvm/ADT/StringSet.h"
43 #include "llvm/Support/Error.h"
44 #include "llvm/Support/ErrorHandling.h"
45 #include "llvm/Support/FormatVariadic.h"
46 #include "llvm/Support/MemoryBuffer.h"
47 #include "llvm/Support/Path.h"
48 #include "llvm/Support/VirtualFileSystem.h"
49 #include "llvm/Support/raw_ostream.h"
50 #include <iterator>
51 #include <memory>
52 #include <string>
53 #include <system_error>
54 #include <utility>
55 #include <vector>
56 
57 namespace clang {
58 namespace clangd {
59 namespace {
60 constexpr llvm::StringLiteral PreamblePatchHeaderName = "__preamble_patch__.h";
61 
62 bool compileCommandsAreEqual(const tooling::CompileCommand &LHS,
63  const tooling::CompileCommand &RHS) {
64  // We don't check for Output, it should not matter to clangd.
65  return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
66  llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine);
67 }
68 
69 class CppFilePreambleCallbacks : public PreambleCallbacks {
70 public:
71  CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback)
72  : File(File), ParsedCallback(ParsedCallback) {}
73 
74  IncludeStructure takeIncludes() { return std::move(Includes); }
75 
76  MainFileMacros takeMacros() { return std::move(Macros); }
77 
78  std::vector<PragmaMark> takeMarks() { return std::move(Marks); }
79 
80  CanonicalIncludes takeCanonicalIncludes() { return std::move(CanonIncludes); }
81 
82  bool isMainFileIncludeGuarded() const { return IsMainFileIncludeGuarded; }
83 
84  void AfterExecute(CompilerInstance &CI) override {
85  if (ParsedCallback) {
86  trace::Span Tracer("Running PreambleCallback");
87  ParsedCallback(CI.getASTContext(), CI.getPreprocessor(), CanonIncludes);
88  }
89 
90  const SourceManager &SM = CI.getSourceManager();
91  const FileEntry *MainFE = SM.getFileEntryForID(SM.getMainFileID());
92  IsMainFileIncludeGuarded =
93  CI.getPreprocessor().getHeaderSearchInfo().isFileMultipleIncludeGuarded(
94  MainFE);
95  }
96 
97  void BeforeExecute(CompilerInstance &CI) override {
98  CanonIncludes.addSystemHeadersMapping(CI.getLangOpts());
99  LangOpts = &CI.getLangOpts();
100  SourceMgr = &CI.getSourceManager();
101  Includes.collect(CI);
102  }
103 
104  std::unique_ptr<PPCallbacks> createPPCallbacks() override {
105  assert(SourceMgr && LangOpts &&
106  "SourceMgr and LangOpts must be set at this point");
107 
108  return std::make_unique<PPChainedCallbacks>(
109  std::make_unique<CollectMainFileMacros>(*SourceMgr, Macros),
111  }
112 
113  CommentHandler *getCommentHandler() override {
114  IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes);
115  return IWYUHandler.get();
116  }
117 
118  bool shouldSkipFunctionBody(Decl *D) override {
119  // Generally we skip function bodies in preambles for speed.
120  // We can make exceptions for functions that are cheap to parse and
121  // instantiate, widely used, and valuable (e.g. commonly produce errors).
122  if (const auto *FT = llvm::dyn_cast<clang::FunctionTemplateDecl>(D)) {
123  if (const auto *II = FT->getDeclName().getAsIdentifierInfo())
124  // std::make_unique is trivial, and we diagnose bad constructor calls.
125  if (II->isStr("make_unique") && FT->isInStdNamespace())
126  return false;
127  }
128  return true;
129  }
130 
131 private:
132  PathRef File;
133  PreambleParsedCallback ParsedCallback;
134  IncludeStructure Includes;
135  CanonicalIncludes CanonIncludes;
136  MainFileMacros Macros;
137  std::vector<PragmaMark> Marks;
138  bool IsMainFileIncludeGuarded = false;
139  std::unique_ptr<CommentHandler> IWYUHandler = nullptr;
140  const clang::LangOptions *LangOpts = nullptr;
141  const SourceManager *SourceMgr = nullptr;
142 };
143 
144 // Represents directives other than includes, where basic textual information is
145 // enough.
146 struct TextualPPDirective {
147  unsigned DirectiveLine;
148  // Full text that's representing the directive, including the `#`.
149  std::string Text;
150  unsigned Offset;
151 
152  bool operator==(const TextualPPDirective &RHS) const {
153  return std::tie(DirectiveLine, Offset, Text) ==
154  std::tie(RHS.DirectiveLine, RHS.Offset, RHS.Text);
155  }
156 };
157 
158 // Formats a PP directive consisting of Prefix (e.g. "#define ") and Body ("X
159 // 10"). The formatting is copied so that the tokens in Body have PresumedLocs
160 // with correct columns and lines.
161 std::string spellDirective(llvm::StringRef Prefix,
162  CharSourceRange DirectiveRange,
163  const LangOptions &LangOpts, const SourceManager &SM,
164  unsigned &DirectiveLine, unsigned &Offset) {
165  std::string SpelledDirective;
166  llvm::raw_string_ostream OS(SpelledDirective);
167  OS << Prefix;
168 
169  // Make sure DirectiveRange is a char range and doesn't contain macro ids.
170  DirectiveRange = SM.getExpansionRange(DirectiveRange);
171  if (DirectiveRange.isTokenRange()) {
172  DirectiveRange.setEnd(
173  Lexer::getLocForEndOfToken(DirectiveRange.getEnd(), 0, SM, LangOpts));
174  }
175 
176  auto DecompLoc = SM.getDecomposedLoc(DirectiveRange.getBegin());
177  DirectiveLine = SM.getLineNumber(DecompLoc.first, DecompLoc.second);
178  Offset = DecompLoc.second;
179  auto TargetColumn = SM.getColumnNumber(DecompLoc.first, DecompLoc.second) - 1;
180 
181  // Pad with spaces before DirectiveRange to make sure it will be on right
182  // column when patched.
183  if (Prefix.size() <= TargetColumn) {
184  // There is enough space for Prefix and space before directive, use it.
185  // We try to squeeze the Prefix into the same line whenever we can, as
186  // putting onto a separate line won't work at the beginning of the file.
187  OS << std::string(TargetColumn - Prefix.size(), ' ');
188  } else {
189  // Prefix was longer than the space we had. We produce e.g.:
190  // #line N-1
191  // #define \
192  // X 10
193  OS << "\\\n" << std::string(TargetColumn, ' ');
194  // Decrement because we put an additional line break before
195  // DirectiveRange.begin().
196  --DirectiveLine;
197  }
198  OS << toSourceCode(SM, DirectiveRange.getAsRange());
199  return OS.str();
200 }
201 
202 // Collects #define directives inside the main file.
203 struct DirectiveCollector : public PPCallbacks {
204  DirectiveCollector(const Preprocessor &PP,
205  std::vector<TextualPPDirective> &TextualDirectives)
206  : LangOpts(PP.getLangOpts()), SM(PP.getSourceManager()),
207  TextualDirectives(TextualDirectives) {}
208 
209  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
210  SrcMgr::CharacteristicKind FileType,
211  FileID PrevFID) override {
212  InMainFile = SM.isWrittenInMainFile(Loc);
213  }
214 
215  void MacroDefined(const Token &MacroNameTok,
216  const MacroDirective *MD) override {
217  if (!InMainFile)
218  return;
219  TextualDirectives.emplace_back();
220  TextualPPDirective &TD = TextualDirectives.back();
221 
222  const auto *MI = MD->getMacroInfo();
223  TD.Text =
224  spellDirective("#define ",
225  CharSourceRange::getTokenRange(
226  MI->getDefinitionLoc(), MI->getDefinitionEndLoc()),
227  LangOpts, SM, TD.DirectiveLine, TD.Offset);
228  }
229 
230 private:
231  bool InMainFile = true;
232  const LangOptions &LangOpts;
233  const SourceManager &SM;
234  std::vector<TextualPPDirective> &TextualDirectives;
235 };
236 
237 struct ScannedPreamble {
238  std::vector<Inclusion> Includes;
239  std::vector<TextualPPDirective> TextualDirectives;
240  PreambleBounds Bounds = {0, false};
241 };
242 
243 /// Scans the preprocessor directives in the preamble section of the file by
244 /// running preprocessor over \p Contents. Returned includes do not contain
245 /// resolved paths. \p Cmd is used to build the compiler invocation, which might
246 /// stat/read files.
247 llvm::Expected<ScannedPreamble>
248 scanPreamble(llvm::StringRef Contents, const tooling::CompileCommand &Cmd) {
249  class EmptyFS : public ThreadsafeFS {
250  private:
251  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> viewImpl() const override {
253  }
254  };
255  EmptyFS FS;
256  // Build and run Preprocessor over the preamble.
257  ParseInputs PI;
258  PI.Contents = Contents.str();
259  PI.TFS = &FS;
260  PI.CompileCommand = Cmd;
261  IgnoringDiagConsumer IgnoreDiags;
263  if (!CI)
264  return error("failed to create compiler invocation");
265  CI->getDiagnosticOpts().IgnoreWarnings = true;
266  auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Contents);
267  // This means we're scanning (though not preprocessing) the preamble section
268  // twice. However, it's important to precisely follow the preamble bounds used
269  // elsewhere.
270  auto Bounds = ComputePreambleBounds(*CI->getLangOpts(), *ContentsBuffer, 0);
271  auto PreambleContents =
272  llvm::MemoryBuffer::getMemBufferCopy(Contents.substr(0, Bounds.Size));
274  std::move(CI), nullptr, std::move(PreambleContents),
275  // Provide an empty FS to prevent preprocessor from performing IO. This
276  // also implies missing resolved paths for includes.
277  FS.view(llvm::None), IgnoreDiags);
278  if (Clang->getFrontendOpts().Inputs.empty())
279  return error("compiler instance had no inputs");
280  // We are only interested in main file includes.
281  Clang->getPreprocessorOpts().SingleFileParseMode = true;
282  PreprocessOnlyAction Action;
283  if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0]))
284  return error("failed BeginSourceFile");
285  Preprocessor &PP = Clang->getPreprocessor();
286  IncludeStructure Includes;
287  Includes.collect(*Clang);
288  ScannedPreamble SP;
289  SP.Bounds = Bounds;
290  PP.addPPCallbacks(
291  std::make_unique<DirectiveCollector>(PP, SP.TextualDirectives));
292  if (llvm::Error Err = Action.Execute())
293  return std::move(Err);
294  Action.EndSourceFile();
295  SP.Includes = std::move(Includes.MainFileIncludes);
296  return SP;
297 }
298 
299 const char *spellingForIncDirective(tok::PPKeywordKind IncludeDirective) {
300  switch (IncludeDirective) {
301  case tok::pp_include:
302  return "include";
303  case tok::pp_import:
304  return "import";
305  case tok::pp_include_next:
306  return "include_next";
307  default:
308  break;
309  }
310  llvm_unreachable("not an include directive");
311 }
312 
313 // Checks whether \p FileName is a valid spelling of main file.
314 bool isMainFile(llvm::StringRef FileName, const SourceManager &SM) {
315  auto FE = SM.getFileManager().getFile(FileName);
316  return FE && *FE == SM.getFileEntryForID(SM.getMainFileID());
317 }
318 
319 } // namespace
320 
321 std::shared_ptr<const PreambleData>
322 buildPreamble(PathRef FileName, CompilerInvocation CI,
323  const ParseInputs &Inputs, bool StoreInMemory,
324  PreambleParsedCallback PreambleCallback) {
325  // Note that we don't need to copy the input contents, preamble can live
326  // without those.
327  auto ContentsBuffer =
328  llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName);
329  auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), *ContentsBuffer, 0);
330 
331  trace::Span Tracer("BuildPreamble");
332  SPAN_ATTACH(Tracer, "File", FileName);
333  std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
334  if (Inputs.FeatureModules) {
335  for (auto &M : *Inputs.FeatureModules) {
336  if (auto Listener = M.astListeners())
337  ASTListeners.emplace_back(std::move(Listener));
338  }
339  }
340  StoreDiags PreambleDiagnostics;
341  PreambleDiagnostics.setDiagCallback(
342  [&ASTListeners](const clang::Diagnostic &D, clangd::Diag &Diag) {
343  llvm::for_each(ASTListeners,
344  [&](const auto &L) { L->sawDiagnostic(D, Diag); });
345  });
346  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine =
347  CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(),
348  &PreambleDiagnostics, false);
349  const Config &Cfg = Config::current();
350  PreambleDiagnostics.setLevelAdjuster([&](DiagnosticsEngine::Level DiagLevel,
351  const clang::Diagnostic &Info) {
352  if (Cfg.Diagnostics.SuppressAll ||
354  *CI.getLangOpts()))
355  return DiagnosticsEngine::Ignored;
356  switch (Info.getID()) {
357  case diag::warn_no_newline_eof:
358  case diag::warn_cxx98_compat_no_newline_eof:
359  case diag::ext_no_newline_eof:
360  // If the preamble doesn't span the whole file, drop the no newline at
361  // eof warnings.
362  return Bounds.Size != ContentsBuffer->getBufferSize()
363  ? DiagnosticsEngine::Level::Ignored
364  : DiagLevel;
365  }
366  return DiagLevel;
367  });
368 
369  // Skip function bodies when building the preamble to speed up building
370  // the preamble and make it smaller.
371  assert(!CI.getFrontendOpts().SkipFunctionBodies);
372  CI.getFrontendOpts().SkipFunctionBodies = true;
373  // We don't want to write comment locations into PCH. They are racy and slow
374  // to read back. We rely on dynamic index for the comments instead.
375  CI.getPreprocessorOpts().WriteCommentListToPCH = false;
376 
377  CppFilePreambleCallbacks CapturedInfo(FileName, PreambleCallback);
378  auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
379  llvm::SmallString<32> AbsFileName(FileName);
380  VFS->makeAbsolute(AbsFileName);
381  auto StatCache = std::make_unique<PreambleFileStatusCache>(AbsFileName);
382  auto BuiltPreamble = PrecompiledPreamble::Build(
383  CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine,
384  StatCache->getProducingFS(VFS),
385  std::make_shared<PCHContainerOperations>(), StoreInMemory, CapturedInfo);
386 
387  // When building the AST for the main file, we do want the function
388  // bodies.
389  CI.getFrontendOpts().SkipFunctionBodies = false;
390 
391  if (BuiltPreamble) {
392  vlog("Built preamble of size {0} for file {1} version {2}",
393  BuiltPreamble->getSize(), FileName, Inputs.Version);
394  std::vector<Diag> Diags = PreambleDiagnostics.take();
395  auto Result = std::make_shared<PreambleData>(std::move(*BuiltPreamble));
396  Result->Version = Inputs.Version;
397  Result->CompileCommand = Inputs.CompileCommand;
398  Result->Diags = std::move(Diags);
399  Result->Includes = CapturedInfo.takeIncludes();
400  Result->Macros = CapturedInfo.takeMacros();
401  Result->Marks = CapturedInfo.takeMarks();
402  Result->CanonIncludes = CapturedInfo.takeCanonicalIncludes();
403  Result->StatCache = std::move(StatCache);
404  Result->MainIsIncludeGuarded = CapturedInfo.isMainFileIncludeGuarded();
405  return Result;
406  }
407 
408  elog("Could not build a preamble for file {0} version {1}: {2}", FileName,
409  Inputs.Version, BuiltPreamble.getError().message());
410  return nullptr;
411 }
412 
413 bool isPreambleCompatible(const PreambleData &Preamble,
415  const CompilerInvocation &CI) {
416  auto ContentsBuffer =
417  llvm::MemoryBuffer::getMemBuffer(Inputs.Contents, FileName);
418  auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), *ContentsBuffer, 0);
419  auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
420  return compileCommandsAreEqual(Inputs.CompileCommand,
422  Preamble.Preamble.CanReuse(CI, *ContentsBuffer, Bounds, *VFS);
423 }
424 
425 void escapeBackslashAndQuotes(llvm::StringRef Text, llvm::raw_ostream &OS) {
426  for (char C : Text) {
427  switch (C) {
428  case '\\':
429  case '"':
430  OS << '\\';
431  break;
432  default:
433  break;
434  }
435  OS << C;
436  }
437 }
438 
439 PreamblePatch PreamblePatch::create(llvm::StringRef FileName,
440  const ParseInputs &Modified,
441  const PreambleData &Baseline,
442  PatchType PatchType) {
443  trace::Span Tracer("CreatePreamblePatch");
444  SPAN_ATTACH(Tracer, "File", FileName);
445  assert(llvm::sys::path::is_absolute(FileName) && "relative FileName!");
446  // First scan preprocessor directives in Baseline and Modified. These will be
447  // used to figure out newly added directives in Modified. Scanning can fail,
448  // the code just bails out and creates an empty patch in such cases, as:
449  // - If scanning for Baseline fails, no knowledge of existing includes hence
450  // patch will contain all the includes in Modified. Leading to rebuild of
451  // whole preamble, which is terribly slow.
452  // - If scanning for Modified fails, cannot figure out newly added ones so
453  // there's nothing to do but generate an empty patch.
454  auto BaselineScan = scanPreamble(
455  // Contents needs to be null-terminated.
456  Baseline.Preamble.getContents().str(), Modified.CompileCommand);
457  if (!BaselineScan) {
458  elog("Failed to scan baseline of {0}: {1}", FileName,
459  BaselineScan.takeError());
460  return PreamblePatch::unmodified(Baseline);
461  }
462  auto ModifiedScan = scanPreamble(Modified.Contents, Modified.CompileCommand);
463  if (!ModifiedScan) {
464  elog("Failed to scan modified contents of {0}: {1}", FileName,
465  ModifiedScan.takeError());
466  return PreamblePatch::unmodified(Baseline);
467  }
468 
469  bool IncludesChanged = BaselineScan->Includes != ModifiedScan->Includes;
470  bool DirectivesChanged =
471  BaselineScan->TextualDirectives != ModifiedScan->TextualDirectives;
472  if ((PatchType == PatchType::MacroDirectives || !IncludesChanged) &&
473  !DirectivesChanged)
474  return PreamblePatch::unmodified(Baseline);
475 
476  PreamblePatch PP;
477  // This shouldn't coincide with any real file name.
478  llvm::SmallString<128> PatchName;
479  llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName),
480  PreamblePatchHeaderName);
481  PP.PatchFileName = PatchName.str().str();
482  PP.ModifiedBounds = ModifiedScan->Bounds;
483 
484  llvm::raw_string_ostream Patch(PP.PatchContents);
485  // Set default filename for subsequent #line directives
486  Patch << "#line 0 \"";
487  // FileName part of a line directive is subject to backslash escaping, which
488  // might lead to problems on windows especially.
490  Patch << "\"\n";
491 
492  if (IncludesChanged && PatchType == PatchType::All) {
493  // We are only interested in newly added includes, record the ones in
494  // Baseline for exclusion.
495  llvm::DenseMap<std::pair<tok::PPKeywordKind, llvm::StringRef>,
496  /*Resolved=*/llvm::StringRef>
497  ExistingIncludes;
498  for (const auto &Inc : Baseline.Includes.MainFileIncludes)
499  ExistingIncludes[{Inc.Directive, Inc.Written}] = Inc.Resolved;
500  // There might be includes coming from disabled regions, record these for
501  // exclusion too. note that we don't have resolved paths for those.
502  for (const auto &Inc : BaselineScan->Includes)
503  ExistingIncludes.try_emplace({Inc.Directive, Inc.Written});
504  // Calculate extra includes that needs to be inserted.
505  for (auto &Inc : ModifiedScan->Includes) {
506  auto It = ExistingIncludes.find({Inc.Directive, Inc.Written});
507  // Include already present in the baseline preamble. Set resolved path and
508  // put into preamble includes.
509  if (It != ExistingIncludes.end()) {
510  Inc.Resolved = It->second.str();
511  PP.PreambleIncludes.push_back(Inc);
512  continue;
513  }
514  // Include is new in the modified preamble. Inject it into the patch and
515  // use #line to set the presumed location to where it is spelled.
516  auto LineCol = offsetToClangLineColumn(Modified.Contents, Inc.HashOffset);
517  Patch << llvm::formatv("#line {0}\n", LineCol.first);
518  Patch << llvm::formatv(
519  "#{0} {1}\n", spellingForIncDirective(Inc.Directive), Inc.Written);
520  }
521  }
522 
523  if (DirectivesChanged) {
524  // We need to patch all the directives, since they are order dependent. e.g:
525  // #define BAR(X) NEW(X) // Newly introduced in Modified
526  // #define BAR(X) OLD(X) // Exists in the Baseline
527  //
528  // If we've patched only the first directive, the macro definition would've
529  // been wrong for the rest of the file, since patch is applied after the
530  // baseline preamble.
531  //
532  // Note that we deliberately ignore conditional directives and undefs to
533  // reduce complexity. The former might cause problems because scanning is
534  // imprecise and might pick directives from disabled regions.
535  for (const auto &TD : ModifiedScan->TextualDirectives) {
536  Patch << "#line " << TD.DirectiveLine << '\n';
537  Patch << TD.Text << '\n';
538  }
539  }
540  dlog("Created preamble patch: {0}", Patch.str());
541  Patch.flush();
542  return PP;
543 }
544 
546  const ParseInputs &Modified,
547  const PreambleData &Baseline) {
548  return create(FileName, Modified, Baseline, PatchType::All);
549 }
550 
552  const ParseInputs &Modified,
553  const PreambleData &Baseline) {
554  return create(FileName, Modified, Baseline, PatchType::MacroDirectives);
555 }
556 
557 void PreamblePatch::apply(CompilerInvocation &CI) const {
558  // No need to map an empty file.
559  if (PatchContents.empty())
560  return;
561  auto &PPOpts = CI.getPreprocessorOpts();
562  auto PatchBuffer =
563  // we copy here to ensure contents are still valid if CI outlives the
564  // PreamblePatch.
565  llvm::MemoryBuffer::getMemBufferCopy(PatchContents, PatchFileName);
566  // CI will take care of the lifetime of the buffer.
567  PPOpts.addRemappedFile(PatchFileName, PatchBuffer.release());
568  // The patch will be parsed after loading the preamble ast and before parsing
569  // the main file.
570  PPOpts.Includes.push_back(PatchFileName);
571 }
572 
573 std::vector<Inclusion> PreamblePatch::preambleIncludes() const {
574  return PreambleIncludes;
575 }
576 
579  PP.PreambleIncludes = Preamble.Includes.MainFileIncludes;
580  PP.ModifiedBounds = Preamble.Preamble.getBounds();
581  return PP;
582 }
583 
584 SourceLocation translatePreamblePatchLocation(SourceLocation Loc,
585  const SourceManager &SM) {
586  auto DefFile = SM.getFileID(Loc);
587  if (auto *FE = SM.getFileEntryForID(DefFile)) {
588  auto IncludeLoc = SM.getIncludeLoc(DefFile);
589  // Preamble patch is included inside the builtin file.
590  if (IncludeLoc.isValid() && SM.isWrittenInBuiltinFile(IncludeLoc) &&
591  FE->getName().endswith(PreamblePatchHeaderName)) {
592  auto Presumed = SM.getPresumedLoc(Loc);
593  // Check that line directive is pointing at main file.
594  if (Presumed.isValid() && Presumed.getFileID().isInvalid() &&
595  isMainFile(Presumed.getFilename(), SM)) {
596  Loc = SM.translateLineCol(SM.getMainFileID(), Presumed.getLine(),
597  Presumed.getColumn());
598  }
599  }
600  }
601  return Loc;
602 }
603 } // namespace clangd
604 } // namespace clang
dlog
#define dlog(...)
Definition: Logger.h:102
clang::clangd::ParseInputs::Version
std::string Version
Definition: Compiler.h:52
clang::clangd::IncludeStructure::collect
void collect(const CompilerInstance &CI)
Definition: Headers.cpp:212
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
clang::clangd::collectIWYUHeaderMaps
std::unique_ptr< CommentHandler > collectIWYUHeaderMaps(CanonicalIncludes *Includes)
Returns a CommentHandler that parses pragma comment on include files to determine when we should incl...
Definition: CanonicalIncludes.cpp:59
clang::clangd::isPreambleCompatible
bool isPreambleCompatible(const PreambleData &Preamble, const ParseInputs &Inputs, PathRef FileName, const CompilerInvocation &CI)
Returns true if Preamble is reusable for Inputs.
Definition: Preamble.cpp:413
Headers.h
clang::clangd::ParseInputs::FeatureModules
FeatureModuleSet * FeatureModules
Definition: Compiler.h:61
clang::clangd::escapeBackslashAndQuotes
void escapeBackslashAndQuotes(llvm::StringRef Text, llvm::raw_ostream &OS)
Definition: Preamble.cpp:425
clang::clangd::prepareCompilerInstance
std::unique_ptr< CompilerInstance > prepareCompilerInstance(std::unique_ptr< clang::CompilerInvocation > CI, const PrecompiledPreamble *Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, DiagnosticConsumer &DiagsClient)
Definition: Compiler.cpp:114
clang::clangd::ParseInputs::Contents
std::string Contents
Definition: Compiler.h:50
Macros
llvm::DenseSet< FileID > Macros
Definition: IncludeCleaner.cpp:171
clang::doc::MD
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
Tracer
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:164
clang::clangd::error
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&... Vals)
Definition: Logger.h:80
clang::clangd::PreambleData::Preamble
PrecompiledPreamble Preamble
Definition: Preamble.h:55
CI
std::unique_ptr< CompilerInvocation > CI
Definition: TUScheduler.cpp:456
clang::clangd::PreamblePatch::unmodified
static PreamblePatch unmodified(const PreambleData &Preamble)
Preamble is used verbatim.
Definition: Preamble.cpp:577
Preamble.h
Text
std::string Text
Definition: HTMLGenerator.cpp:80
Trace.h
clang::clangd::Config
Settings that express user/project preferences and control clangd behavior.
Definition: Config.h:43
clang::clangd::PreamblePatch
Stores information required to parse a TU using a (possibly stale) Baseline preamble.
Definition: Preamble.h:99
SourceMgr
llvm::SourceMgr * SourceMgr
Definition: ConfigCompile.cpp:102
clang::clangd::ParseInputs::CompileCommand
tooling::CompileCommand CompileCommand
Definition: Compiler.h:48
Action
llvm::unique_function< void()> Action
Definition: TUScheduler.cpp:604
clang::clangd::IncludeStructure::MainFileIncludes
std::vector< Inclusion > MainFileIncludes
Definition: Headers.h:236
Preamble
const PreambleData & Preamble
Definition: CodeComplete.cpp:1193
M
const google::protobuf::Message & M
Definition: Server.cpp:309
ThreadsafeFS.h
Inputs
ParseInputs Inputs
Definition: TUScheduler.cpp:457
clang::clangd::PreamblePatch::apply
void apply(CompilerInvocation &CI) const
Adjusts CI (which compiles the modified inputs) to be used with the baseline preamble.
Definition: Preamble.cpp:557
clang::clangd::ParseInputs
Information required to run clang, e.g. to parse AST or do code completion.
Definition: Compiler.h:47
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
Diagnostic
DiagnosticCallback Diagnostic
Definition: ConfigCompile.cpp:101
clang::clangd::ParseInputs::TFS
const ThreadsafeFS * TFS
Definition: Compiler.h:49
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
clang::clangd::PreambleData
The parsed preamble and associated data.
Definition: Preamble.h:49
clang::clangd::PreamblePatch::createMacroPatch
static PreamblePatch createMacroPatch(llvm::StringRef FileName, const ParseInputs &Modified, const PreambleData &Baseline)
Definition: Preamble.cpp:551
clang::clangd::PreamblePatch::PatchType::MacroDirectives
@ MacroDirectives
clang::clangd::PreamblePatch::PatchType
PatchType
Definition: Preamble.h:101
clang::clangd::Diag
A top-level diagnostic that may have Notes and Fixes.
Definition: Diagnostics.h:97
clang::clangd::buildPreamble
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation CI, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback)
Build a preamble for the new inputs unless an old one can be reused.
Definition: Preamble.cpp:322
clang::clangd::Config::Suppress
llvm::StringSet Suppress
Definition: Config.h:93
Logger.h
Bounds
PreambleBounds Bounds
Definition: Preamble.cpp:240
clang::clangd::collectPragmaMarksCallback
std::unique_ptr< PPCallbacks > collectPragmaMarksCallback(const SourceManager &SM, std::vector< PragmaMark > &Out)
Collect all pragma marks from the main file.
Definition: CollectMacros.cpp:56
Patch
const llvm::Optional< PreamblePatch > Patch
Definition: CodeComplete.cpp:1194
SPAN_ATTACH
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:164
clang::clangd::vlog
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:73
FileName
StringRef FileName
Definition: KernelNameRestrictionCheck.cpp:46
clang::clangd::Config::SuppressAll
bool SuppressAll
Definition: Config.h:92
Offset
unsigned Offset
Definition: Preamble.cpp:150
DirectiveLine
unsigned DirectiveLine
Definition: Preamble.cpp:147
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:29
clang::clangd::PreambleData::CompileCommand
tooling::CompileCommand CompileCommand
Definition: Preamble.h:54
clang::clangd::buildCompilerInvocation
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D, std::vector< std::string > *CC1Args)
Builds compiler invocation that could be used to build AST or preamble.
Definition: Compiler.cpp:88
SourceCode.h
Config.h
Compiler.h
InMemoryFileSystem
llvm::IntrusiveRefCntPtr< llvm::vfs::InMemoryFileSystem > InMemoryFileSystem
Definition: IndexActionTests.cpp:109
clang::clangd::PreamblePatch::createFullPatch
static PreamblePatch createFullPatch(llvm::StringRef FileName, const ParseInputs &Modified, const PreambleData &Baseline)
Builds a patch that contains new PP directives introduced to the preamble section of Modified compare...
Definition: Preamble.cpp:545
Info
FunctionInfo Info
Definition: FunctionSizeCheck.cpp:120
clang::clangd::PathRef
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:29
clang::clangd::ThreadsafeFS::view
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > view(llvm::NoneType CWD) const
Obtain a vfs::FileSystem with an arbitrary initial working directory.
Definition: ThreadsafeFS.h:34
C
const Criteria C
Definition: FunctionCognitiveComplexityCheck.cpp:93
PPCallbacks
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
OS
llvm::raw_string_ostream OS
Definition: TraceTests.cpp:163
clang::clangd::StoreDiags::setDiagCallback
void setDiagCallback(DiagCallback CB)
Invokes a callback every time a diagnostics is completely formed.
Definition: Diagnostics.h:163
clang::clangd::StoreDiags
StoreDiags collects the diagnostics that can later be reported by clangd.
Definition: Diagnostics.h:136
Diags
CapturedDiags Diags
Definition: ConfigCompileTests.cpp:38
clang::clangd::Config::current
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
Definition: Config.cpp:17
clang::clangd::operator==
bool operator==(const Inclusion &LHS, const Inclusion &RHS)
Definition: Headers.cpp:346
clang::clangd::Config::Diagnostics
struct clang::clangd::Config::@4 Diagnostics
Controls warnings and errors when parsing code.
clang::clangd::StoreDiags::setLevelAdjuster
void setLevelAdjuster(LevelAdjuster Adjuster)
If set, this allows the client of this class to adjust the level of diagnostics, such as promoting wa...
Definition: Diagnostics.h:160
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:62
clang::clangd::PreambleParsedCallback
std::function< void(ASTContext &, Preprocessor &, const CanonicalIncludes &)> PreambleParsedCallback
Definition: Preamble.h:76
clang::clangd::PreamblePatch::preambleIncludes
std::vector< Inclusion > preambleIncludes() const
Returns #include directives from the Modified preamble that were resolved using the Baseline preamble...
Definition: Preamble.cpp:573
clang::clangd::isBuiltinDiagnosticSuppressed
bool isBuiltinDiagnosticSuppressed(unsigned ID, const llvm::StringSet<> &Suppress, const LangOptions &LangOpts)
Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
Definition: Diagnostics.cpp:884
clang::clangd::toSourceCode
llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R)
Returns the source code covered by the source range.
Definition: SourceCode.cpp:446
clang::clangd::PreamblePatch::PatchType::All
@ All
clang::clangd::StoreDiags::take
std::vector< Diag > take(const clang::tidy::ClangTidyContext *Tidy=nullptr)
Definition: Diagnostics.cpp:562
IgnoreDiags
IgnoringDiagConsumer IgnoreDiags
Definition: HeadersTests.cpp:138
Clang
std::unique_ptr< CompilerInstance > Clang
Definition: HeadersTests.cpp:139
clang::clangd::translatePreamblePatchLocation
SourceLocation translatePreamblePatchLocation(SourceLocation Loc, const SourceManager &SM)
Translates locations inside preamble patch to their main-file equivalent using presumed locations.
Definition: Preamble.cpp:584
clang::clangd::offsetToClangLineColumn
std::pair< size_t, size_t > offsetToClangLineColumn(llvm::StringRef Code, size_t Offset)
Definition: SourceCode.cpp:481
clang::clangd::trace::Span
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:143