10 #include "../clang-tidy/ClangTidyDiagnosticConsumer.h" 11 #include "../clang-tidy/ClangTidyModuleRegistry.h" 21 #include "clang/AST/ASTContext.h" 22 #include "clang/Basic/LangOptions.h" 23 #include "clang/Basic/SourceManager.h" 24 #include "clang/Basic/TokenKinds.h" 25 #include "clang/Frontend/CompilerInstance.h" 26 #include "clang/Frontend/CompilerInvocation.h" 27 #include "clang/Frontend/FrontendActions.h" 28 #include "clang/Frontend/Utils.h" 29 #include "clang/Index/IndexDataConsumer.h" 30 #include "clang/Index/IndexingAction.h" 31 #include "clang/Lex/Lexer.h" 32 #include "clang/Lex/MacroInfo.h" 33 #include "clang/Lex/Preprocessor.h" 34 #include "clang/Lex/PreprocessorOptions.h" 35 #include "clang/Sema/Sema.h" 36 #include "clang/Serialization/ASTWriter.h" 37 #include "clang/Serialization/PCHContainerOperations.h" 38 #include "clang/Tooling/CompilationDatabase.h" 39 #include "clang/Tooling/Syntax/Tokens.h" 40 #include "llvm/ADT/ArrayRef.h" 41 #include "llvm/ADT/STLExtras.h" 42 #include "llvm/ADT/SmallString.h" 43 #include "llvm/ADT/SmallVector.h" 44 #include "llvm/Support/raw_ostream.h" 52 bool compileCommandsAreEqual(
const tooling::CompileCommand &LHS,
53 const tooling::CompileCommand &RHS) {
55 return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
56 llvm::makeArrayRef(LHS.CommandLine).equals(RHS.CommandLine);
59 template <
class T> std::size_t getUsedBytes(
const std::vector<T> &Vec) {
60 return Vec.capacity() *
sizeof(T);
63 class DeclTrackingASTConsumer :
public ASTConsumer {
65 DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
66 : TopLevelDecls(TopLevelDecls) {}
68 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
70 auto &SM =
D->getASTContext().getSourceManager();
71 if (!SM.isWrittenInMainFile(SM.getExpansionLoc(
D->getLocation())))
75 if (isa<ObjCMethodDecl>(
D))
78 TopLevelDecls.push_back(
D);
84 std::vector<Decl *> &TopLevelDecls;
89 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
92 std::unique_ptr<ASTConsumer>
93 CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile)
override {
94 return llvm::make_unique<DeclTrackingASTConsumer>( TopLevelDecls);
98 std::vector<Decl *> TopLevelDecls;
103 explicit CollectMainFileMacros(
const SourceManager &SM,
104 std::vector<std::string> *Out)
105 : SM(SM), Out(Out) {}
107 void FileChanged(SourceLocation
Loc, FileChangeReason,
108 SrcMgr::CharacteristicKind, FileID Prev) {
109 InMainFile = SM.isWrittenInMainFile(Loc);
112 void MacroDefined(
const Token &MacroName,
const MacroDirective *
MD) {
114 MainFileMacros.insert(MacroName.getIdentifierInfo()->getName());
117 void EndOfMainFile() {
118 for (
const auto &
Entry : MainFileMacros)
119 Out->push_back(
Entry.getKey());
124 const SourceManager &SM;
125 bool InMainFile =
true;
126 llvm::StringSet<> MainFileMacros;
127 std::vector<std::string> *Out;
130 class CppFilePreambleCallbacks :
public PreambleCallbacks {
133 : File(File), ParsedCallback(ParsedCallback) {
136 IncludeStructure takeIncludes() {
return std::move(Includes); }
138 std::vector<std::string> takeMainFileMacros() {
139 return std::move(MainFileMacros);
142 CanonicalIncludes takeCanonicalIncludes() {
return std::move(CanonIncludes); }
144 void AfterExecute(CompilerInstance &CI)
override {
147 trace::Span Tracer(
"Running PreambleCallback");
148 ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr(), CanonIncludes);
151 void BeforeExecute(CompilerInstance &CI)
override {
153 SourceMgr = &CI.getSourceManager();
156 std::unique_ptr<PPCallbacks> createPPCallbacks()
override {
157 assert(SourceMgr &&
"SourceMgr must be set at this point");
158 return llvm::make_unique<PPChainedCallbacks>(
160 llvm::make_unique<CollectMainFileMacros>(*SourceMgr, &MainFileMacros));
163 CommentHandler *getCommentHandler()
override {
165 return IWYUHandler.get();
171 IncludeStructure Includes;
172 CanonicalIncludes CanonIncludes;
173 std::vector<std::string> MainFileMacros;
174 std::unique_ptr<CommentHandler> IWYUHandler =
nullptr;
175 SourceManager *SourceMgr =
nullptr;
189 static void attach(
const IncludeStructure &Includes,
190 CompilerInstance &Clang) {
191 auto &PP = Clang.getPreprocessor();
192 auto *ExistingCallbacks = PP.getPPCallbacks();
194 if (!ExistingCallbacks)
196 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
197 new ReplayPreamble(Includes, ExistingCallbacks,
198 Clang.getSourceManager(), PP, Clang.getLangOpts())));
201 assert(PP.getPPCallbacks() != ExistingCallbacks &&
202 "Expected chaining implementation");
206 ReplayPreamble(
const IncludeStructure &Includes,
PPCallbacks *Delegate,
207 const SourceManager &SM, Preprocessor &PP,
208 const LangOptions &LangOpts)
209 : Includes(Includes), Delegate(Delegate), SM(SM), PP(PP),
210 LangOpts(LangOpts) {}
227 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
228 SrcMgr::CharacteristicKind
Kind, FileID PrevFID)
override {
230 if (Reason == FileChangeReason::ExitFile &&
231 SM.getBuffer(PrevFID)->getBufferIdentifier() ==
"<built-in>")
236 for (
const auto &Inc : Includes.MainFileIncludes) {
237 const FileEntry *
File =
nullptr;
238 if (Inc.Resolved !=
"")
239 File = SM.getFileManager().getFile(Inc.Resolved);
241 llvm::StringRef WrittenFilename =
242 llvm::StringRef(Inc.Written).drop_front().drop_back();
243 bool Angled = llvm::StringRef(Inc.Written).startswith(
"<");
246 llvm::StringRef
Src = SM.getBufferData(SM.getMainFileID());
247 Lexer RawLexer(SM.getLocForStartOfFile(SM.getMainFileID()), LangOpts,
248 Src.begin(), Src.begin() + Inc.HashOffset, Src.end());
249 Token HashTok, IncludeTok, FilenameTok;
250 RawLexer.LexFromRawLexer(HashTok);
251 assert(HashTok.getKind() == tok::hash);
252 RawLexer.setParsingPreprocessorDirective(
true);
253 RawLexer.LexFromRawLexer(IncludeTok);
254 IdentifierInfo *II = PP.getIdentifierInfo(IncludeTok.getRawIdentifier());
255 IncludeTok.setIdentifierInfo(II);
256 IncludeTok.setKind(II->getTokenID());
257 RawLexer.LexIncludeFilename(FilenameTok);
259 Delegate->InclusionDirective(
260 HashTok.getLocation(), IncludeTok, WrittenFilename, Angled,
261 CharSourceRange::getCharRange(FilenameTok.getLocation(),
262 FilenameTok.getEndLoc()),
263 File,
"SearchPath",
"RelPath",
nullptr, Inc.FileKind);
265 Delegate->FileSkipped(*File, FilenameTok, Inc.FileKind);
267 llvm::SmallString<1> UnusedRecovery;
268 Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
273 const IncludeStructure &Includes;
275 const SourceManager &SM;
277 const LangOptions &LangOpts;
283 AST.
getASTContext().getTranslationUnitDecl()->dump(OS,
true);
286 llvm::Optional<ParsedAST>
288 std::shared_ptr<const PreambleData>
Preamble,
289 std::unique_ptr<llvm::MemoryBuffer> Buffer,
290 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>
VFS,
295 CI->getFrontendOpts().DisableFree =
false;
296 const PrecompiledPreamble *PreamblePCH =
297 Preamble ? &Preamble->Preamble :
nullptr;
300 std::string Content = Buffer->getBuffer();
303 std::move(Buffer), VFS, ASTDiags);
307 auto Action = llvm::make_unique<ClangdFrontendAction>();
308 const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
309 if (!
Action->BeginSourceFile(*Clang, MainInput)) {
310 log(
"BeginSourceFile() failed when building AST for {0}",
311 MainInput.getFile());
321 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
322 ast_matchers::MatchFinder CTFinder;
323 llvm::Optional<tidy::ClangTidyContext> CTContext;
326 dlog(
"ClangTidy configuration for file {0}: {1}", MainInput.getFile(),
329 for (
const auto &E : tidy::ClangTidyModuleRegistry::entries())
330 E.instantiate()->addCheckFactories(CTFactories);
331 CTContext.emplace(llvm::make_unique<tidy::DefaultOptionsProvider>(
333 CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
334 CTContext->setASTContext(&Clang->getASTContext());
335 CTContext->setCurrentFile(MainInput.getFile());
336 CTFactories.
createChecks(CTContext.getPointer(), CTChecks);
338 const clang::Diagnostic &
Info) {
340 std::string CheckName = CTContext->getCheckName(Info.getID());
341 bool IsClangTidyDiag = !CheckName.empty();
342 if (IsClangTidyDiag) {
347 CTContext->treatAsError(CheckName)) {
356 bool IsInsideMainFile =
357 Info.hasSourceManager() &&
358 Info.getSourceManager().isWrittenInMainFile(
359 Info.getSourceManager().getFileLoc(Info.getLocation()));
361 DiagLevel, Info, *CTContext,
363 return DiagnosticsEngine::Ignored;
369 Preprocessor *PP = &Clang->getPreprocessor();
370 for (
const auto &Check : CTChecks) {
373 Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
374 Check->registerMatchers(&CTFinder);
380 llvm::Optional<IncludeFixer> FixIncludes;
381 auto BuildDir = VFS->getCurrentWorkingDirectory();
384 auto Inserter = std::make_shared<IncludeInserter>(
385 MainInput.getFile(), Content, Style, BuildDir.get(),
386 &Clang->getPreprocessor().getHeaderSearchInfo());
388 for (
const auto &Inc : Preamble->Includes.MainFileIncludes)
389 Inserter->addExisting(Inc);
391 FixIncludes.emplace(MainInput.getFile(), Inserter, *
Index,
393 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
394 const clang::Diagnostic &
Info) {
395 return FixIncludes->fix(DiagLevl, Info);
397 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
405 ReplayPreamble::attach(Includes, *Clang);
409 Clang->getPreprocessor().addPPCallbacks(
416 CanonIncludes = Preamble->CanonIncludes;
419 std::unique_ptr<CommentHandler> IWYUHandler =
421 Clang->getPreprocessor().addCommentHandler(IWYUHandler.get());
424 syntax::TokenCollector CollectTokens(Clang->getPreprocessor());
427 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
433 syntax::TokenBuffer
Tokens = std::move(CollectTokens).consume();
434 std::vector<Decl *> ParsedDecls =
Action->takeTopLevelDecls();
436 Clang->getASTContext().setTraversalScope(ParsedDecls);
441 CTFinder.matchAST(Clang->getASTContext());
452 Clang->getPreprocessor().EndSourceFile();
454 std::vector<Diag> Diags = ASTDiags.
take(CTContext.getPointer());
457 Diags.insert(Diags.begin(), Preamble->Diags.begin(), Preamble->Diags.end());
458 return ParsedAST(std::move(Preamble), std::move(Clang), std::move(
Action),
459 std::move(Tokens), std::move(ParsedDecls), std::move(Diags),
460 std::move(Includes), std::move(CanonIncludes));
471 auto PP = Clang->getPreprocessorPtr();
472 Clang->setPreprocessor(
nullptr);
481 return Clang->getASTContext();
487 return Clang->getPreprocessorPtr();
491 return Clang->getPreprocessor();
495 return LocalTopLevelDecls;
501 auto &
AST = getASTContext();
505 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
511 Total +=
AST.getASTAllocatedMemory();
512 Total +=
AST.getSideTableAllocatedMemory();
513 Total +=
AST.Idents.getAllocator().getTotalMemory();
514 Total +=
AST.Selectors.getTotalMemory();
516 Total +=
AST.getSourceManager().getContentCacheSize();
517 Total +=
AST.getSourceManager().getDataStructureSizes();
518 Total +=
AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
520 if (ExternalASTSource *Ext =
AST.getExternalSource())
521 Total += Ext->getMemoryBufferSizes().malloc_bytes;
523 const Preprocessor &PP = getPreprocessor();
524 Total += PP.getTotalMemory();
525 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
526 Total += PRec->getTotalMemory();
527 Total += PP.getHeaderSearchInfo().getTotalMemory();
537 return CanonIncludes;
542 std::vector<std::string> MainFileMacros,
543 std::unique_ptr<PreambleFileStatusCache> StatCache,
545 : Preamble(std::move(Preamble)), Diags(std::move(Diags)),
546 Includes(std::move(Includes)), MainFileMacros(std::move(MainFileMacros)),
547 StatCache(std::move(StatCache)), CanonIncludes(std::move(CanonIncludes)) {
551 std::unique_ptr<CompilerInstance> Clang,
552 std::unique_ptr<FrontendAction>
Action,
553 syntax::TokenBuffer
Tokens,
554 std::vector<Decl *> LocalTopLevelDecls,
557 :
Preamble(std::move(Preamble)), Clang(std::move(Clang)),
559 Diags(std::move(Diags)),
560 LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
563 assert(this->Action);
566 std::shared_ptr<const PreambleData>
568 std::shared_ptr<const PreambleData> OldPreamble,
569 const tooling::CompileCommand &OldCompileCommand,
574 auto ContentsBuffer = llvm::MemoryBuffer::getMemBuffer(Inputs.
Contents);
576 ComputePreambleBounds(*CI.getLangOpts(), ContentsBuffer.get(), 0);
579 compileCommandsAreEqual(Inputs.
CompileCommand, OldCompileCommand) &&
580 OldPreamble->Preamble.CanReuse(CI, ContentsBuffer.get(), Bounds,
582 vlog(
"Reusing preamble for file {0}", llvm::Twine(FileName));
585 vlog(
"Preamble for file {0} cannot be reused. Attempting to rebuild it.",
591 llvm::IntrusiveRefCntPtr<DiagnosticsEngine> PreambleDiagsEngine =
592 CompilerInstance::createDiagnostics(&CI.getDiagnosticOpts(),
593 &PreambleDiagnostics,
false);
597 assert(!CI.getFrontendOpts().SkipFunctionBodies);
598 CI.getFrontendOpts().SkipFunctionBodies =
true;
601 CI.getPreprocessorOpts().WriteCommentListToPCH =
false;
603 CppFilePreambleCallbacks SerializedDeclsCollector(FileName, PreambleCallback);
604 if (Inputs.
FS->setCurrentWorkingDirectory(Inputs.
CompileCommand.Directory)) {
605 log(
"Couldn't set working directory when building the preamble.");
610 llvm::SmallString<32> AbsFileName(FileName);
611 Inputs.
FS->makeAbsolute(AbsFileName);
612 auto StatCache = llvm::make_unique<PreambleFileStatusCache>(AbsFileName);
613 auto BuiltPreamble = PrecompiledPreamble::Build(
614 CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine,
616 std::make_shared<PCHContainerOperations>(), StoreInMemory,
617 SerializedDeclsCollector);
621 CI.getFrontendOpts().SkipFunctionBodies =
false;
624 vlog(
"Built preamble of size {0} for file {1}", BuiltPreamble->getSize(),
626 std::vector<Diag> Diags = PreambleDiagnostics.
take();
627 return std::make_shared<PreambleData>(
628 std::move(*BuiltPreamble), std::move(Diags),
629 SerializedDeclsCollector.takeIncludes(),
630 SerializedDeclsCollector.takeMainFileMacros(), std::move(
StatCache),
631 SerializedDeclsCollector.takeCanonicalIncludes());
633 elog(
"Could not build a preamble for file {0}", FileName);
638 llvm::Optional<ParsedAST>
641 std::shared_ptr<const PreambleData> Preamble) {
645 auto VFS = Inputs.
FS;
646 if (Preamble && Preamble->StatCache)
647 VFS = Preamble->StatCache->getConsumingFS(std::move(
VFS));
649 log(
"Couldn't set working directory when building the preamble.");
656 llvm::MemoryBuffer::getMemBufferCopy(Inputs.
Contents),
661 const Position &Pos,
const FileID FID) {
663 const SourceManager &SourceMgr = AST.getSourceManager();
666 log(
"getBeginningOfIdentifier: {0}",
Offset.takeError());
667 return SourceLocation();
679 SourceLocation InputLoc = SourceMgr.getComposedLoc(FID, *
Offset);
681 return SourceMgr.getMacroArgExpandedLocation(InputLoc);
682 SourceLocation Before = SourceMgr.getComposedLoc(FID, *
Offset - 1);
684 Before = Lexer::GetBeginningOfToken(Before, SourceMgr, AST.getLangOpts());
686 if (Before.isValid() &&
687 !Lexer::getRawToken(Before, Tok, SourceMgr, AST.getLangOpts(),
false) &&
688 Tok.is(tok::raw_identifier))
689 return SourceMgr.getMacroArgExpandedLocation(Before);
690 return SourceMgr.getMacroArgExpandedLocation(InputLoc);
696 #define LINK_TIDY_MODULE(X) \ 697 extern volatile int X##ModuleAnchorSource; \ 698 static int LLVM_ATTRIBUTE_UNUSED X##ModuleAnchorDestination = \ 699 X##ModuleAnchorSource 717 #undef LINK_TIDY_MODULE 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
'#' location in the include directive
bool ShouldSuppressDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info, ClangTidyContext &Context, bool CheckMacroExpansion)
Check whether a given diagnostic should be suppressed due to the presence of a "NOLINT" suppression c...
StoreDiags collects the diagnostics that can later be reported by clangd.
ParsedAST & operator=(ParsedAST &&Other)
Preprocessor & getPreprocessor()
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS
void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS)
For testing/debugging purposes.
static llvm::Optional< ParsedAST > build(std::unique_ptr< clang::CompilerInvocation > CI, std::shared_ptr< const PreambleData > Preamble, std::unique_ptr< llvm::MemoryBuffer > Buffer, IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS, const SymbolIndex *Index, const ParseOptions &Opts)
Attempts to run Clang and store parsed AST.
void contributeFixes(DiagFixer Fixer)
If set, possibly adds fixes for diagnostics using Fixer.
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
bool SuggestMissingIncludes
llvm::StringRef PathRef
A typedef to represent a ref to file path.
ArrayRef< Decl * > getLocalTopLevelDecls()
This function returns top-level decls present in the main file of the AST.
void addSystemHeadersMapping(CanonicalIncludes *Includes, const LangOptions &Language)
Adds mapping for system headers and some special symbols (e.g.
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)
Documents should not be synced at all.
tidy::ClangTidyOptions ClangTidyOpts
A collection of ClangTidyCheckFactory instances.
void vlog(const char *Fmt, Ts &&... Vals)
void elog(const char *Fmt, Ts &&... Vals)
ASTContext & getASTContext()
Note that the returned ast will not contain decls from the preamble that were not deserialized during...
std::size_t getUsedBytes() const
Returns the esitmated size of the AST and the accessory structures, in bytes.
SourceLocation getBeginningOfIdentifier(const ParsedAST &Unit, const Position &Pos, const FileID FID)
Get the beginning SourceLocation at a specified Pos.
std::shared_ptr< const PreambleData > buildPreamble(PathRef FileName, CompilerInvocation &CI, std::shared_ptr< const PreambleData > OldPreamble, const tooling::CompileCommand &OldCompileCommand, const ParseInputs &Inputs, bool StoreInMemory, PreambleParsedCallback PreambleCallback)
Rebuild the preamble for the new inputs unless the old one can be reused.
Maps a definition location onto an #include file, based on a set of filename rules.
const CanonicalIncludes & getCanonicalIncludes() const
CanonicalIncludes CanonIncludes
const IncludeStructure & getIncludeStructure() const
std::unique_ptr< PreambleFileStatusCache > StatCache
#define LINK_TIDY_MODULE(X)
llvm::Expected< size_t > positionToOffset(llvm::StringRef Code, Position P, bool AllowColumnsBeyondLineLength)
Turn a [line, column] pair into an offset in Code.
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.
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
void log(const char *Fmt, Ts &&... Vals)
static const char * toString(OffsetEncoding OE)
std::shared_ptr< Preprocessor > getPreprocessorPtr()
llvm::Optional< ParsedAST > buildAST(PathRef FileName, std::unique_ptr< CompilerInvocation > Invocation, const ParseInputs &Inputs, std::shared_ptr< const PreambleData > Preamble)
Build an AST from provided user inputs.
format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, llvm::vfs::FileSystem *FS)
Choose the clang-format style we should apply to a certain file.
Stores and provides access to parsed AST.
std::function< void(ASTContext &, std::shared_ptr< clang::Preprocessor >, const CanonicalIncludes &)> PreambleParsedCallback
const PreambleData * Preamble
std::unique_ptr< PPCallbacks > collectIncludeStructureCallback(const SourceManager &SM, IncludeStructure *Out)
Returns a PPCallback that visits all inclusions in the main file.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
void EndSourceFile() override
std::vector< Diag > Diags
PrecompiledPreamble Preamble
IncludeStructure Includes
void setLevelAdjuster(LevelAdjuster Adjuster)
If set, this allows the client of this class to adjust the level of diagnostics, such as promoting wa...
Records an event whose duration is the lifetime of the Span object.
PreambleData(PrecompiledPreamble Preamble, std::vector< Diag > Diags, IncludeStructure Includes, std::vector< std::string > MainFileMacros, std::unique_ptr< PreambleFileStatusCache > StatCache, CanonicalIncludes CanonIncludes)
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
ParsedAST(ParsedAST &&Other)
std::vector< Diag > take(const clang::tidy::ClangTidyContext *Tidy=nullptr)
const std::vector< Diag > & getDiagnostics() const
const SymbolIndex * Index