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 
compileCommandsAreEqual(const tooling::CompileCommand & LHS,const tooling::CompileCommand & RHS)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 
getUsedBytes(const std::vector<T> & Vec)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:
DeclTrackingASTConsumer(std::vector<Decl * > & TopLevelDecls)56   DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
57       : TopLevelDecls(TopLevelDecls) {}
58 
HandleTopLevelDecl(DeclGroupRef DG)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:
takeTopLevelDecls()79   std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
80 
81 protected:
82   std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,llvm::StringRef InFile)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:
CppFilePreambleCallbacks(PathRef File,PreambleParsedCallback ParsedCallback)93   CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback)
94       : File(File), ParsedCallback(ParsedCallback) {}
95 
takeIncludes()96   IncludeStructure takeIncludes() { return std::move(Includes); }
97 
AfterExecute(CompilerInstance & CI)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 
BeforeExecute(CompilerInstance & CI)105   void BeforeExecute(CompilerInstance &CI) override {
106     SourceMgr = &CI.getSourceManager();
107   }
108 
createPPCallbacks()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.
attach(const IncludeStructure & Includes,CompilerInstance & Clang)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:
ReplayPreamble(const IncludeStructure & Includes,PPCallbacks * Delegate,const SourceManager & SM,Preprocessor & PP,const LangOptions & LangOpts)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.
FileChanged(SourceLocation Loc,FileChangeReason Reason,SrcMgr::CharacteristicKind Kind,FileID PrevFID)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 
replay()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 
dumpAST(ParsedAST & AST,llvm::raw_ostream & OS)222 void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
223   AST.getASTContext().getTranslationUnitDecl()->dump(OS, true);
224 }
225 
226 llvm::Optional<ParsedAST>
build(std::unique_ptr<CompilerInvocation> CI,std::shared_ptr<const PreambleData> Preamble,std::unique_ptr<llvm::MemoryBuffer> Buffer,std::shared_ptr<PCHContainerOperations> PCHs,llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS)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 
~ParsedAST()337 ParsedAST::~ParsedAST() {
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 
getASTContext()348 ASTContext &ParsedAST::getASTContext() { return Clang->getASTContext(); }
349 
getASTContext() const350 const ASTContext &ParsedAST::getASTContext() const {
351   return Clang->getASTContext();
352 }
353 
getPreprocessor()354 Preprocessor &ParsedAST::getPreprocessor() { return Clang->getPreprocessor(); }
355 
getPreprocessorPtr()356 std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
357   return Clang->getPreprocessorPtr();
358 }
359 
getPreprocessor() const360 const Preprocessor &ParsedAST::getPreprocessor() const {
361   return Clang->getPreprocessor();
362 }
363 
getLocalTopLevelDecls()364 llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
365   return LocalTopLevelDecls;
366 }
367 
getDiagnostics() const368 const std::vector<Diag> &ParsedAST::getDiagnostics() const { return Diags; }
369 
getUsedBytes() const370 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 
getIncludeStructure() const402 const IncludeStructure &ParsedAST::getIncludeStructure() const {
403   return Includes;
404 }
405 
PreambleData(PrecompiledPreamble Preamble,std::vector<Diag> Diags,IncludeStructure Includes,std::unique_ptr<PreambleFileStatusCache> StatCache)406 PreambleData::PreambleData(PrecompiledPreamble Preamble,
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 
ParsedAST(std::shared_ptr<const PreambleData> Preamble,std::unique_ptr<CompilerInstance> Clang,std::unique_ptr<FrontendAction> Action,std::vector<Decl * > LocalTopLevelDecls,std::vector<Diag> Diags,IncludeStructure Includes)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>
buildCompilerInvocation(const ParseInputs & Inputs)426 buildCompilerInvocation(const ParseInputs &Inputs) {
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.
439   IgnoreDiagnostics IgnoreDiagnostics;
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>
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)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>
buildAST(PathRef FileName,std::unique_ptr<CompilerInvocation> Invocation,const ParseInputs & Inputs,std::shared_ptr<const PreambleData> Preamble,std::shared_ptr<PCHContainerOperations> PCHs)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 
getBeginningOfIdentifier(ParsedAST & Unit,const Position & Pos,const FileID FID)545 SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos,
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
605