clang-tools  8.0.0
ClangdUnit.cpp
Go to the documentation of this file.
1 //===--- ClangdUnit.cpp ------------------------------------------*- C++-*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "ClangdUnit.h"
11 #include "../clang-tidy/ClangTidyDiagnosticConsumer.h"
12 #include "../clang-tidy/ClangTidyModuleRegistry.h"
13 #include "Compiler.h"
14 #include "Diagnostics.h"
15 #include "Logger.h"
16 #include "SourceCode.h"
17 #include "Trace.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/Basic/LangOptions.h"
20 #include "clang/Frontend/CompilerInstance.h"
21 #include "clang/Frontend/CompilerInvocation.h"
22 #include "clang/Frontend/FrontendActions.h"
23 #include "clang/Frontend/Utils.h"
24 #include "clang/Index/IndexDataConsumer.h"
25 #include "clang/Index/IndexingAction.h"
26 #include "clang/Lex/Lexer.h"
27 #include "clang/Lex/MacroInfo.h"
28 #include "clang/Lex/Preprocessor.h"
29 #include "clang/Lex/PreprocessorOptions.h"
30 #include "clang/Sema/Sema.h"
31 #include "clang/Serialization/ASTWriter.h"
32 #include "clang/Tooling/CompilationDatabase.h"
33 #include "llvm/ADT/ArrayRef.h"
34 #include "llvm/ADT/SmallString.h"
35 #include "llvm/ADT/SmallVector.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include <algorithm>
38 
39 namespace clang {
40 namespace clangd {
41 namespace {
42 
43 bool compileCommandsAreEqual(const tooling::CompileCommand &LHS,
44  const tooling::CompileCommand &RHS) {
45  // We don't check for Output, it should not matter to clangd.
46  return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
47  llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine);
48 }
49 
50 template <class T> std::size_t getUsedBytes(const std::vector<T> &Vec) {
51  return Vec.capacity() * sizeof(T);
52 }
53 
54 class DeclTrackingASTConsumer : public ASTConsumer {
55 public:
56  DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
57  : TopLevelDecls(TopLevelDecls) {}
58 
59  bool HandleTopLevelDecl(DeclGroupRef DG) override {
60  for (Decl *D : DG) {
61  if (D->isFromASTFile())
62  continue;
63 
64  // ObjCMethodDecl are not actually top-level decls.
65  if (isa<ObjCMethodDecl>(D))
66  continue;
67 
68  TopLevelDecls.push_back(D);
69  }
70  return true;
71  }
72 
73 private:
74  std::vector<Decl *> &TopLevelDecls;
75 };
76 
77 class ClangdFrontendAction : public SyntaxOnlyAction {
78 public:
79  std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
80 
81 protected:
82  std::unique_ptr<ASTConsumer>
83  CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
84  return llvm::make_unique<DeclTrackingASTConsumer>(/*ref*/ TopLevelDecls);
85  }
86 
87 private:
88  std::vector<Decl *> TopLevelDecls;
89 };
90 
91 class CppFilePreambleCallbacks : public PreambleCallbacks {
92 public:
93  CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback)
94  : File(File), ParsedCallback(ParsedCallback) {}
95 
96  IncludeStructure takeIncludes() { return std::move(Includes); }
97 
98  void AfterExecute(CompilerInstance &CI) override {
99  if (!ParsedCallback)
100  return;
101  trace::Span Tracer("Running PreambleCallback");
102  ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr());
103  }
104 
105  void BeforeExecute(CompilerInstance &CI) override {
106  SourceMgr = &CI.getSourceManager();
107  }
108 
109  std::unique_ptr<PPCallbacks> createPPCallbacks() override {
110  assert(SourceMgr && "SourceMgr must be set at this point");
111  return collectIncludeStructureCallback(*SourceMgr, &Includes);
112  }
113 
114 private:
115  PathRef File;
116  PreambleParsedCallback ParsedCallback;
117  IncludeStructure Includes;
118  SourceManager *SourceMgr = nullptr;
119 };
120 
121 // When using a preamble, only preprocessor events outside its bounds are seen.
122 // This is almost what we want: replaying transitive preprocessing wastes time.
123 // However this confuses clang-tidy checks: they don't see any #includes!
124 // So we replay the *non-transitive* #includes that appear in the main-file.
125 // It would be nice to replay other events (macro definitions, ifdefs etc) but
126 // this addresses the most common cases fairly cheaply.
127 class ReplayPreamble : private PPCallbacks {
128 public:
129  // Attach preprocessor hooks such that preamble events will be injected at
130  // the appropriate time.
131  // Events will be delivered to the *currently registered* PP callbacks.
132  static void attach(const IncludeStructure &Includes,
133  CompilerInstance &Clang) {
134  auto &PP = Clang.getPreprocessor();
135  auto *ExistingCallbacks = PP.getPPCallbacks();
136  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
137  new ReplayPreamble(Includes, ExistingCallbacks,
138  Clang.getSourceManager(), PP, Clang.getLangOpts())));
139  // We're relying on the fact that addPPCallbacks keeps the old PPCallbacks
140  // around, creating a chaining wrapper. Guard against other implementations.
141  assert(PP.getPPCallbacks() != ExistingCallbacks &&
142  "Expected chaining implementation");
143  }
144 
145 private:
146  ReplayPreamble(const IncludeStructure &Includes, PPCallbacks *Delegate,
147  const SourceManager &SM, Preprocessor &PP,
148  const LangOptions &LangOpts)
149  : Includes(Includes), Delegate(Delegate), SM(SM), PP(PP),
150  LangOpts(LangOpts) {}
151 
152  // In a normal compile, the preamble traverses the following structure:
153  //
154  // mainfile.cpp
155  // <built-in>
156  // ... macro definitions like __cplusplus ...
157  // <command-line>
158  // ... macro definitions for args like -Dfoo=bar ...
159  // "header1.h"
160  // ... header file contents ...
161  // "header2.h"
162  // ... header file contents ...
163  // ... main file contents ...
164  //
165  // When using a preamble, the "header1" and "header2" subtrees get skipped.
166  // We insert them right after the built-in header, which still appears.
167  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
168  SrcMgr::CharacteristicKind Kind, FileID PrevFID) override {
169  // It'd be nice if there was a better way to identify built-in headers...
170  if (Reason == FileChangeReason::ExitFile &&
171  SM.getBuffer(PrevFID)->getBufferIdentifier() == "<built-in>")
172  replay();
173  }
174 
175  void replay() {
176  for (const auto &Inc : Includes.MainFileIncludes) {
177  const FileEntry *File = nullptr;
178  if (Inc.Resolved != "")
179  File = SM.getFileManager().getFile(Inc.Resolved);
180 
181  llvm::StringRef WrittenFilename =
182  llvm::StringRef(Inc.Written).drop_front().drop_back();
183  bool Angled = llvm::StringRef(Inc.Written).startswith("<");
184 
185  // Re-lex the #include directive to find its interesting parts.
186  llvm::StringRef Src = SM.getBufferData(SM.getMainFileID());
187  Lexer RawLexer(SM.getLocForStartOfFile(SM.getMainFileID()), LangOpts,
188  Src.begin(), Src.begin() + Inc.HashOffset, Src.end());
189  Token HashTok, IncludeTok, FilenameTok;
190  RawLexer.LexFromRawLexer(HashTok);
191  assert(HashTok.getKind() == tok::hash);
192  RawLexer.setParsingPreprocessorDirective(true);
193  RawLexer.LexFromRawLexer(IncludeTok);
194  IdentifierInfo *II = PP.getIdentifierInfo(IncludeTok.getRawIdentifier());
195  IncludeTok.setIdentifierInfo(II);
196  IncludeTok.setKind(II->getTokenID());
197  RawLexer.LexIncludeFilename(FilenameTok);
198 
199  Delegate->InclusionDirective(
200  HashTok.getLocation(), IncludeTok, WrittenFilename, Angled,
201  CharSourceRange::getCharRange(FilenameTok.getLocation(),
202  FilenameTok.getEndLoc()),
203  File, "SearchPath", "RelPath", /*Imported=*/nullptr, Inc.FileKind);
204  if (File)
205  Delegate->FileSkipped(*File, FilenameTok, Inc.FileKind);
206  else {
207  llvm::SmallString<1> UnusedRecovery;
208  Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
209  }
210  }
211  }
212 
213  const IncludeStructure &Includes;
214  PPCallbacks *Delegate;
215  const SourceManager &SM;
216  Preprocessor &PP;
217  const LangOptions &LangOpts;
218 };
219 
220 } // namespace
221 
222 void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
223  AST.getASTContext().getTranslationUnitDecl()->dump(OS, true);
224 }
225 
226 llvm::Optional<ParsedAST>
227 ParsedAST::build(std::unique_ptr<CompilerInvocation> CI,
228  std::shared_ptr<const PreambleData> Preamble,
229  std::unique_ptr<llvm::MemoryBuffer> Buffer,
230  std::shared_ptr<PCHContainerOperations> PCHs,
231  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
232  assert(CI);
233  // Command-line parsing sets DisableFree to true by default, but we don't want
234  // to leak memory in clangd.
235  CI->getFrontendOpts().DisableFree = false;
236  const PrecompiledPreamble *PreamblePCH =
237  Preamble ? &Preamble->Preamble : nullptr;
238 
239  StoreDiags ASTDiags;
240  auto Clang =
241  prepareCompilerInstance(std::move(CI), PreamblePCH, std::move(Buffer),
242  std::move(PCHs), std::move(VFS), ASTDiags);
243  if (!Clang)
244  return None;
245 
246  auto Action = llvm::make_unique<ClangdFrontendAction>();
247  const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
248  if (!Action->BeginSourceFile(*Clang, MainInput)) {
249  log("BeginSourceFile() failed when building AST for {0}",
250  MainInput.getFile());
251  return None;
252  }
253 
254  // Set up ClangTidy. Must happen after BeginSourceFile() so ASTContext exists.
255  // Clang-tidy has some limitiations to ensure reasonable performance:
256  // - checks don't see all preprocessor events in the preamble
257  // - matchers run only over the main-file top-level decls (and can't see
258  // ancestors outside this scope).
259  // In practice almost all checks work well without modifications.
260  std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
261  ast_matchers::MatchFinder CTFinder;
262  llvm::Optional<tidy::ClangTidyContext> CTContext;
263  {
264  trace::Span Tracer("ClangTidyInit");
265  tidy::ClangTidyCheckFactories CTFactories;
266  for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
267  E.instantiate()->addCheckFactories(CTFactories);
268  auto CTOpts = tidy::ClangTidyOptions::getDefaults();
269  // FIXME: this needs to be configurable, and we need to support .clang-tidy
270  // files and other options providers.
271  // These checks exercise the matcher- and preprocessor-based hooks.
272  CTOpts.Checks = "bugprone-sizeof-expression,"
273  "bugprone-macro-repeated-side-effects,"
274  "modernize-deprecated-headers";
275  CTContext.emplace(llvm::make_unique<tidy::DefaultOptionsProvider>(
276  tidy::ClangTidyGlobalOptions(), CTOpts));
277  CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
278  CTContext->setASTContext(&Clang->getASTContext());
279  CTContext->setCurrentFile(MainInput.getFile());
280  CTFactories.createChecks(CTContext.getPointer(), CTChecks);
281  for (const auto &Check : CTChecks) {
282  // FIXME: the PP callbacks skip the entire preamble.
283  // Checks that want to see #includes in the main file do not see them.
284  Check->registerPPCallbacks(*Clang);
285  Check->registerMatchers(&CTFinder);
286  }
287  }
288 
289  // Copy over the includes from the preamble, then combine with the
290  // non-preamble includes below.
291  auto Includes = Preamble ? Preamble->Includes : IncludeStructure{};
292  // Replay the preamble includes so that clang-tidy checks can see them.
293  if (Preamble)
294  ReplayPreamble::attach(Includes, *Clang);
295  // Important: collectIncludeStructure is registered *after* ReplayPreamble!
296  // Otherwise we would collect the replayed includes again...
297  // (We can't *just* use the replayed includes, they don't have Resolved path).
298  Clang->getPreprocessor().addPPCallbacks(
299  collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
300 
301  if (!Action->Execute())
302  log("Execute() failed when building AST for {0}", MainInput.getFile());
303 
304  std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls();
305  // AST traversals should exclude the preamble, to avoid performance cliffs.
306  Clang->getASTContext().setTraversalScope(ParsedDecls);
307  {
308  // Run the AST-dependent part of the clang-tidy checks.
309  // (The preprocessor part ran already, via PPCallbacks).
310  trace::Span Tracer("ClangTidyMatch");
311  CTFinder.matchAST(Clang->getASTContext());
312  }
313 
314  // UnitDiagsConsumer is local, we can not store it in CompilerInstance that
315  // has a longer lifetime.
316  Clang->getDiagnostics().setClient(new IgnoreDiagnostics);
317  // CompilerInstance won't run this callback, do it directly.
318  ASTDiags.EndSourceFile();
319  // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF.
320  // However Action->EndSourceFile() would destroy the ASTContext!
321  // So just inform the preprocessor of EOF, while keeping everything alive.
322  Clang->getPreprocessor().EndSourceFile();
323 
324  std::vector<Diag> Diags = ASTDiags.take();
325  // Add diagnostics from the preamble, if any.
326  if (Preamble)
327  Diags.insert(Diags.begin(), Preamble->Diags.begin(), Preamble->Diags.end());
328  return ParsedAST(std::move(Preamble), std::move(Clang), std::move(Action),
329  std::move(ParsedDecls), std::move(Diags),
330  std::move(Includes));
331 }
332 
333 ParsedAST::ParsedAST(ParsedAST &&Other) = default;
334 
335 ParsedAST &ParsedAST::operator=(ParsedAST &&Other) = default;
336 
338  if (Action) {
339  // We already notified the PP of end-of-file earlier, so detach it first.
340  // We must keep it alive until after EndSourceFile(), Sema relies on this.
341  auto PP = Clang->getPreprocessorPtr(); // Keep PP alive for now.
342  Clang->setPreprocessor(nullptr); // Detach so we don't send EOF again.
343  Action->EndSourceFile(); // Destroy ASTContext and Sema.
344  // Now Sema is gone, it's safe for PP to go out of scope.
345  }
346 }
347 
348 ASTContext &ParsedAST::getASTContext() { return Clang->getASTContext(); }
349 
350 const ASTContext &ParsedAST::getASTContext() const {
351  return Clang->getASTContext();
352 }
353 
354 Preprocessor &ParsedAST::getPreprocessor() { return Clang->getPreprocessor(); }
355 
356 std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
357  return Clang->getPreprocessorPtr();
358 }
359 
360 const Preprocessor &ParsedAST::getPreprocessor() const {
361  return Clang->getPreprocessor();
362 }
363 
364 llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
365  return LocalTopLevelDecls;
366 }
367 
368 const std::vector<Diag> &ParsedAST::getDiagnostics() const { return Diags; }
369 
370 std::size_t ParsedAST::getUsedBytes() const {
371  auto &AST = getASTContext();
372  // FIXME(ibiryukov): we do not account for the dynamically allocated part of
373  // Message and Fixes inside each diagnostic.
374  std::size_t Total =
375  clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
376 
377  // FIXME: the rest of the function is almost a direct copy-paste from
378  // libclang's clang_getCXTUResourceUsage. We could share the implementation.
379 
380  // Sum up variaous allocators inside the ast context and the preprocessor.
381  Total += AST.getASTAllocatedMemory();
382  Total += AST.getSideTableAllocatedMemory();
383  Total += AST.Idents.getAllocator().getTotalMemory();
384  Total += AST.Selectors.getTotalMemory();
385 
386  Total += AST.getSourceManager().getContentCacheSize();
387  Total += AST.getSourceManager().getDataStructureSizes();
388  Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
389 
390  if (ExternalASTSource *Ext = AST.getExternalSource())
391  Total += Ext->getMemoryBufferSizes().malloc_bytes;
392 
393  const Preprocessor &PP = getPreprocessor();
394  Total += PP.getTotalMemory();
395  if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
396  Total += PRec->getTotalMemory();
397  Total += PP.getHeaderSearchInfo().getTotalMemory();
398 
399  return Total;
400 }
401 
403  return Includes;
404 }
405 
407  std::vector<Diag> Diags, IncludeStructure Includes,
408  std::unique_ptr<PreambleFileStatusCache> StatCache)
409  : Preamble(std::move(Preamble)), Diags(std::move(Diags)),
410  Includes(std::move(Includes)), StatCache(std::move(StatCache)) {}
411 
412 ParsedAST::ParsedAST(std::shared_ptr<const PreambleData> Preamble,
413  std::unique_ptr<CompilerInstance> Clang,
414  std::unique_ptr<FrontendAction> Action,
415  std::vector<Decl *> LocalTopLevelDecls,
416  std::vector<Diag> Diags, IncludeStructure Includes)
417  : Preamble(std::move(Preamble)), Clang(std::move(Clang)),
418  Action(std::move(Action)), Diags(std::move(Diags)),
419  LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
420  Includes(std::move(Includes)) {
421  assert(this->Clang);
422  assert(this->Action);
423 }
424 
425 std::unique_ptr<CompilerInvocation>
427  std::vector<const char *> ArgStrs;
428  for (const auto &S : Inputs.CompileCommand.CommandLine)
429  ArgStrs.push_back(S.c_str());
430 
431  if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
432  log("Couldn't set working directory when creating compiler invocation.");
433  // We proceed anyway, our lit-tests rely on results for non-existing working
434  // dirs.
435  }
436 
437  // FIXME(ibiryukov): store diagnostics from CommandLine when we start
438  // reporting them.
440  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> CommandLineDiagsEngine =
441  CompilerInstance::createDiagnostics(new DiagnosticOptions,
442  &IgnoreDiagnostics, false);
443  std::unique_ptr<CompilerInvocation> CI = createInvocationFromCommandLine(
444  ArgStrs, CommandLineDiagsEngine, Inputs.FS);
445  if (!CI)
446  return nullptr;
447  // createInvocationFromCommandLine sets DisableFree.
448  CI->getFrontendOpts().DisableFree = false;
449  CI->getLangOpts()->CommentOpts.ParseAllComments = true;
450  return CI;
451 }
452 
453 std::shared_ptr<const PreambleData>
454 buildPreamble(PathRef FileName, CompilerInvocation &CI,
455  std::shared_ptr<const PreambleData> OldPreamble,
456  const tooling::CompileCommand &OldCompileCommand,
457  const ParseInputs &Inputs,
458  std::shared_ptr<PCHContainerOperations> PCHs, bool StoreInMemory,
459  PreambleParsedCallback PreambleCallback) {
460  // Note that we don't need to copy the input contents, preamble can live
461  // without those.
462  auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Inputs.Contents);
463  auto Bounds =
464  ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0);
465 
466  if (OldPreamble &&
467  compileCommandsAreEqual(Inputs.CompileCommand, OldCompileCommand) &&
468  OldPreamble->Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
469  Inputs.FS.get())) {
470  vlog("Reusing preamble for file {0}", llvm::Twine(FileName));
471  return OldPreamble;
472  }
473  vlog("Preamble for file {0} cannot be reused. Attempting to rebuild it.",
474  FileName);
475 
476  trace::Span Tracer("BuildPreamble");
477  SPAN_ATTACH(Tracer, "File", FileName);
478  StoreDiags PreambleDiagnostics;
479  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine =
480  CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(),
481  &PreambleDiagnostics, false);
482 
483  // Skip function bodies when building the preamble to speed up building
484  // the preamble and make it smaller.
485  assert(!CI.getFrontendOpts().SkipFunctionBodies);
486  CI.getFrontendOpts().SkipFunctionBodies = true;
487  // We don't want to write comment locations into PCH. They are racy and slow
488  // to read back. We rely on dynamic index for the comments instead.
489  CI.getPreprocessorOpts().WriteCommentListToPCH = false;
490 
491  CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback);
492  if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
493  log("Couldn't set working directory when building the preamble.");
494  // We proceed anyway, our lit-tests rely on results for non-existing working
495  // dirs.
496  }
497 
498  llvm::SmallString<32> AbsFileName(FileName);
499  Inputs.FS->makeAbsolute(AbsFileName);
500  auto StatCache = llvm::make_unique<PreambleFileStatusCache>(AbsFileName);
501  auto BuiltPreamble = PrecompiledPreamble::Build(
502  CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine,
503  StatCache->getProducingFS(Inputs.FS), PCHs, StoreInMemory,
504  SerializedDeclsCollector);
505 
506  // When building the AST for the main file, we do want the function
507  // bodies.
508  CI.getFrontendOpts().SkipFunctionBodies = false;
509 
510  if (BuiltPreamble) {
511  vlog("Built preamble of size {0} for file {1}", BuiltPreamble->getSize(),
512  FileName);
513  return std::make_shared<PreambleData>(
514  std::move(*BuiltPreamble), PreambleDiagnostics.take(),
515  SerializedDeclsCollector.takeIncludes(), std::move(StatCache));
516  } else {
517  elog("Could not build a preamble for file {0}", FileName);
518  return nullptr;
519  }
520 }
521 
522 llvm::Optional<ParsedAST>
523 buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
524  const ParseInputs &Inputs,
525  std::shared_ptr<const PreambleData> Preamble,
526  std::shared_ptr<PCHContainerOperations> PCHs) {
527  trace::Span Tracer("BuildAST");
528  SPAN_ATTACH(Tracer, "File", FileName);
529 
530  auto VFS = Inputs.FS;
531  if (Preamble && Preamble->StatCache)
532  VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
533  if (VFS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
534  log("Couldn't set working directory when building the preamble.");
535  // We proceed anyway, our lit-tests rely on results for non-existing working
536  // dirs.
537  }
538 
539  return ParsedAST::build(llvm::make_unique<CompilerInvocation>(*Invocation),
540  Preamble,
541  llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents),
542  PCHs, std::move(VFS));
543 }
544 
546  const FileID FID) {
547  const ASTContext &AST = Unit.getASTContext();
548  const SourceManager &SourceMgr = AST.getSourceManager();
549  auto Offset = positionToOffset(SourceMgr.getBufferData(FID), Pos);
550  if (!Offset) {
551  log("getBeginningOfIdentifier: {0}", Offset.takeError());
552  return SourceLocation();
553  }
554 
555  // GetBeginningOfToken(pos) is almost what we want, but does the wrong thing
556  // if the cursor is at the end of the identifier.
557  // Instead, we lex at GetBeginningOfToken(pos - 1). The cases are:
558  // 1) at the beginning of an identifier, we'll be looking at something
559  // that isn't an identifier.
560  // 2) at the middle or end of an identifier, we get the identifier.
561  // 3) anywhere outside an identifier, we'll get some non-identifier thing.
562  // We can't actually distinguish cases 1 and 3, but returning the original
563  // location is correct for both!
564  SourceLocation InputLoc = SourceMgr.getComposedLoc(FID, *Offset);
565  if (*Offset == 0) // Case 1 or 3.
566  return SourceMgr.getMacroArgExpandedLocation(InputLoc);
567  SourceLocation Before = SourceMgr.getComposedLoc(FID, *Offset - 1);
568 
569  Before = Lexer::GetBeginningOfToken(Before, SourceMgr, AST.getLangOpts());
570  Token Tok;
571  if (Before.isValid() &&
572  !Lexer::getRawToken(Before, Tok, SourceMgr, AST.getLangOpts(), false) &&
573  Tok.is(tok::raw_identifier))
574  return SourceMgr.getMacroArgExpandedLocation(Before); // Case 2.
575  return SourceMgr.getMacroArgExpandedLocation(InputLoc); // Case 1 or 3.
576 }
577 
578 } // namespace clangd
579 namespace tidy {
580 // Force the linker to link in Clang-tidy modules.
581 #define LINK_TIDY_MODULE(X) \
582  extern volatile int X##ModuleAnchorSource; \
583  static int LLVM_ATTRIBUTE_UNUSED X##ModuleAnchorDestination = \
584  X##ModuleAnchorSource
585 LINK_TIDY_MODULE(CERT);
586 LINK_TIDY_MODULE(Abseil);
587 LINK_TIDY_MODULE(Boost);
588 LINK_TIDY_MODULE(Bugprone);
589 LINK_TIDY_MODULE(LLVM);
590 LINK_TIDY_MODULE(CppCoreGuidelines);
591 LINK_TIDY_MODULE(Fuchsia);
592 LINK_TIDY_MODULE(Google);
593 LINK_TIDY_MODULE(Android);
594 LINK_TIDY_MODULE(Misc);
595 LINK_TIDY_MODULE(Modernize);
596 LINK_TIDY_MODULE(Performance);
597 LINK_TIDY_MODULE(Portability);
598 LINK_TIDY_MODULE(Readability);
599 LINK_TIDY_MODULE(ObjC);
600 LINK_TIDY_MODULE(HICPP);
601 LINK_TIDY_MODULE(Zircon);
602 #undef LINK_TIDY_MODULE
603 } // namespace tidy
604 } // namespace clang
SourceLocation Loc
&#39;#&#39; location in the include directive
StoreDiags collects the diagnostics that can later be reported by clangd.
Definition: Diagnostics.h:94
ParsedAST & operator=(ParsedAST &&Other)
std::vector< Diag > take()
Preprocessor & getPreprocessor()
Definition: ClangdUnit.cpp:354
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
llvm::Optional< ParsedAST > buildAST(PathRef FileName, std::unique_ptr< CompilerInvocation > Invocation, const ParseInputs &Inputs, std::shared_ptr< const PreambleData > Preamble, std::shared_ptr< PCHContainerOperations > PCHs)
Build an AST from provided user inputs.
Definition: ClangdUnit.cpp:523
void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS)
For testing/debugging purposes.
Definition: ClangdUnit.cpp:222
llvm::StringRef PathRef
A typedef to represent a ref to file path.
Definition: Path.h:24
static llvm::Optional< ParsedAST > build(std::unique_ptr< clang::CompilerInvocation > CI, std::shared_ptr< const PreambleData > Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, std::shared_ptr< PCHContainerOperations > PCHs, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS)
Attempts to run Clang and store parsed AST.
Definition: ClangdUnit.cpp:227
ArrayRef< Decl * > getLocalTopLevelDecls()
This function returns top-level decls present in the main file of the AST.
Definition: ClangdUnit.cpp:364
Documents should not be synced at all.
A collection of ClangTidyCheckFactory instances.
void vlog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:68
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:57
std::function< void(ASTContext &, std::shared_ptr< clang::Preprocessor >)> PreambleParsedCallback
Definition: ClangdUnit.h:136
ASTContext & getASTContext()
Note that the returned ast will not contain decls from the preamble that were not deserialized during...
Definition: ClangdUnit.cpp:348
std::size_t getUsedBytes() const
Returns the esitmated size of the AST and the accessory structures, in bytes.
Definition: ClangdUnit.cpp:370
BindArgumentKind Kind
const IncludeStructure & getIncludeStructure() const
Definition: ClangdUnit.cpp:402
std::unique_ptr< PreambleFileStatusCache > StatCache
Definition: ClangdUnit.h:60
#define LINK_TIDY_MODULE(X)
Definition: ClangdUnit.cpp:581
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
Definition: SourceCode.cpp:81
llvm::unique_function< void()> Action
void createChecks(ClangTidyContext *Context, std::vector< std::unique_ptr< ClangTidyCheck >> &Checks)
Create instances of all checks matching CheckRegexString and store them in Checks.
void log(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:63
std::shared_ptr< Preprocessor > getPreprocessorPtr()
Definition: ClangdUnit.cpp:356
std::unique_ptr< CompilerInvocation > buildCompilerInvocation(const ParseInputs &Inputs)
Builds compiler invocation that could be used to build AST or preamble.
Definition: ClangdUnit.cpp:426
tooling::CompileCommand CompileCommand
Definition: ClangdUnit.h:65
PreambleData(PrecompiledPreamble Preamble, std::vector< Diag > Diags, IncludeStructure Includes, std::unique_ptr< PreambleFileStatusCache > StatCache)
Definition: ClangdUnit.cpp:406
const Decl * D
Definition: XRefs.cpp:79
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation &CI, std::shared_ptr< const PreambleData > OldPreamble, const tooling::CompileCommand &OldCompileCommand, const ParseInputs &Inputs, std::shared_ptr< PCHContainerOperations > PCHs, bool StoreInMemory, PreambleParsedCallback PreambleCallback)
Rebuild the preamble for the new inputs unless the old one can be reused.
Definition: ClangdUnit.cpp:454
PathRef FileName
Position Pos
Stores and provides access to parsed AST.
Definition: ClangdUnit.h:71
Information required to run clang, e.g. to parse AST or do code completion.
Definition: ClangdUnit.h:64
const PreambleData * Preamble
SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, const FileID FID)
Get the beginning SourceLocation at a specified Pos.
Definition: ClangdUnit.cpp:545
std::unique_ptr< PPCallbacks > collectIncludeStructureCallback(const SourceManager &SM, IncludeStructure *Out)
Returns a PPCallback that visits all inclusions in the main file.
Definition: Headers.cpp:78
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::shared_ptr< PCHContainerOperations > PCHs
void EndSourceFile() override
std::vector< Diag > Diags
Definition: ClangdUnit.h:54
IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
Definition: ClangdUnit.h:66
PrecompiledPreamble Preamble
Definition: ClangdUnit.h:53
static ClangTidyOptions getDefaults()
These options are used for all settings that haven&#39;t been overridden by the OptionsProvider.
IncludeStructure Includes
Definition: ClangdUnit.h:57
std::unique_ptr< CompilerInstance > prepareCompilerInstance(std::unique_ptr< clang::CompilerInvocation > CI, const PrecompiledPreamble *Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, std::shared_ptr< PCHContainerOperations > PCHs, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, DiagnosticConsumer &DiagsClient)
Definition: Compiler.cpp:44
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:83
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:99
ParsedAST(ParsedAST &&Other)
const std::vector< Diag > & getDiagnostics() const
Definition: ClangdUnit.cpp:368