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