27#include "clang-include-cleaner/Record.h"
32#include "clang/AST/ASTContext.h"
33#include "clang/AST/Decl.h"
34#include "clang/AST/DeclGroup.h"
35#include "clang/AST/ExternalASTSource.h"
36#include "clang/ASTMatchers/ASTMatchFinder.h"
37#include "clang/Basic/Diagnostic.h"
38#include "clang/Basic/DiagnosticIDs.h"
39#include "clang/Basic/DiagnosticSema.h"
40#include "clang/Basic/FileEntry.h"
41#include "clang/Basic/LLVM.h"
42#include "clang/Basic/LangOptions.h"
43#include "clang/Basic/SourceLocation.h"
44#include "clang/Basic/SourceManager.h"
45#include "clang/Basic/TokenKinds.h"
46#include "clang/Frontend/CompilerInstance.h"
47#include "clang/Frontend/CompilerInvocation.h"
48#include "clang/Frontend/FrontendActions.h"
49#include "clang/Frontend/FrontendOptions.h"
50#include "clang/Frontend/PrecompiledPreamble.h"
51#include "clang/Lex/Lexer.h"
52#include "clang/Lex/PPCallbacks.h"
53#include "clang/Lex/PreprocessingRecord.h"
54#include "clang/Lex/Preprocessor.h"
55#include "clang/Sema/HeuristicResolver.h"
56#include "clang/Serialization/ASTWriter.h"
57#include "clang/Tooling/CompilationDatabase.h"
58#include "clang/Tooling/Core/Diagnostic.h"
59#include "clang/Tooling/Syntax/Tokens.h"
60#include "llvm/ADT/ArrayRef.h"
61#include "llvm/ADT/DenseMap.h"
62#include "llvm/ADT/DenseSet.h"
63#include "llvm/ADT/STLExtras.h"
64#include "llvm/ADT/STLFunctionalExtras.h"
65#include "llvm/ADT/SmallVector.h"
66#include "llvm/ADT/StringRef.h"
67#include "llvm/Support/Error.h"
68#include "llvm/Support/MemoryBuffer.h"
82#define CLANG_TIDY_DISABLE_STATIC_ANALYZER_CHECKS
86#if CLANG_TIDY_ENABLE_QUERY_BASED_CUSTOM_CHECKS
95template <
class T> std::size_t getUsedBytes(
const std::vector<T> &Vec) {
96 return Vec.capacity() *
sizeof(
T);
99class DeclTrackingASTConsumer :
public ASTConsumer {
101 DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
102 : TopLevelDecls(TopLevelDecls) {}
104 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
106 auto &SM =
D->getASTContext().getSourceManager();
109 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D))
114 if (isa<ObjCMethodDecl>(D))
117 TopLevelDecls.push_back(D);
123 std::vector<Decl *> &TopLevelDecls;
126class ClangdFrontendAction :
public SyntaxOnlyAction {
128 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
131 std::unique_ptr<ASTConsumer>
132 CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile)
override {
133 return std::make_unique<DeclTrackingASTConsumer>( TopLevelDecls);
137 std::vector<Decl *> TopLevelDecls;
146class ReplayPreamble :
private PPCallbacks {
151 static void attach(std::vector<Inclusion> Includes,
152 const MainFileMacros Macros, CompilerInstance &Clang,
153 const PreambleBounds &PB) {
154 auto &PP = Clang.getPreprocessor();
155 auto *ExistingCallbacks = PP.getPPCallbacks();
157 if (!ExistingCallbacks)
159 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
new ReplayPreamble(
160 std::move(Includes), std::move(Macros), ExistingCallbacks,
161 Clang.getSourceManager(), PP, Clang.getLangOpts(), PB)));
164 assert(PP.getPPCallbacks() != ExistingCallbacks &&
165 "Expected chaining implementation");
169 ReplayPreamble(std::vector<Inclusion> Includes, MainFileMacros Macros,
170 PPCallbacks *Delegate,
const SourceManager &SM,
171 Preprocessor &PP,
const LangOptions &LangOpts,
172 const PreambleBounds &PB)
173 : Includes(std::move(Includes)), Macros(std::move(Macros)),
174 Delegate(Delegate), SM(SM), PP(PP) {
177 MainFileTokens = syntax::tokenize(
178 syntax::FileRange(SM.getMainFileID(), 0, PB.Size), SM, LangOpts);
196 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
197 SrcMgr::CharacteristicKind Kind, FileID PrevFID)
override {
199 if (Reason == FileChangeReason::ExitFile &&
200 SM.getBufferOrFake(PrevFID).getBufferIdentifier() ==
"<built-in>")
207 for (
const auto &[SID, Refs] : Macros.MacroRefs) {
208 for (
const auto &Ref : Refs) {
209 if (!Ref.IsDefinition)
211 auto Loc = SM.getComposedLoc(SM.getMainFileID(), Ref.StartOffset);
213 if (Lexer::getRawToken(Loc, Tok, SM, PP.getLangOpts(),
false))
215 if (
auto *II = PP.getIdentifierInfo(Tok.getRawIdentifier())) {
216 Tok.setIdentifierInfo(II);
217 Tok.setKind(tok::identifier);
218 if (
auto *
MD = PP.getLocalMacroDirective(II))
219 Delegate->MacroDefined(Tok,
MD);
223 for (
const auto &Inc : Includes) {
224 OptionalFileEntryRef
File;
225 if (Inc.Resolved !=
"")
226 File = expectedToOptional(SM.getFileManager().getFileRef(Inc.Resolved));
229 auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset);
230 auto HashTok = llvm::partition_point(MainFileTokens,
231 [&HashLoc](
const syntax::Token &T) {
232 return T.location() < HashLoc;
234 assert(HashTok != MainFileTokens.end() && HashTok->kind() == tok::hash);
236 auto IncludeTok = std::next(HashTok);
237 assert(IncludeTok != MainFileTokens.end());
239 auto FileTok = std::next(IncludeTok);
240 assert(FileTok != MainFileTokens.end());
244 Token SynthesizedIncludeTok;
245 SynthesizedIncludeTok.startToken();
246 SynthesizedIncludeTok.setLocation(IncludeTok->location());
247 SynthesizedIncludeTok.setLength(IncludeTok->length());
248 SynthesizedIncludeTok.setKind(tok::raw_identifier);
249 SynthesizedIncludeTok.setRawIdentifierData(IncludeTok->text(SM).data());
250 PP.LookUpIdentifierInfo(SynthesizedIncludeTok);
253 Token SynthesizedFilenameTok;
254 SynthesizedFilenameTok.startToken();
255 SynthesizedFilenameTok.setLocation(FileTok->location());
260 SynthesizedFilenameTok.setLength(Inc.Written.length());
261 SynthesizedFilenameTok.setKind(tok::header_name);
262 SynthesizedFilenameTok.setLiteralData(Inc.Written.data());
264 llvm::StringRef WrittenFilename =
265 llvm::StringRef(Inc.Written).drop_front().drop_back();
266 Delegate->InclusionDirective(
267 HashTok->location(), SynthesizedIncludeTok, WrittenFilename,
268 Inc.Written.front() ==
'<',
269 syntax::FileRange(SM, SynthesizedFilenameTok.getLocation(),
270 SynthesizedFilenameTok.getEndLoc())
272 File,
"SearchPath",
"RelPath",
273 nullptr,
false, Inc.FileKind);
275 Delegate->FileSkipped(*
File, SynthesizedFilenameTok, Inc.FileKind);
279 const std::vector<Inclusion> Includes;
280 const MainFileMacros Macros;
281 PPCallbacks *Delegate;
282 const SourceManager &SM;
284 std::vector<syntax::Token> MainFileTokens;
295class TidyDiagnosticGroups {
298 bool Default =
false;
301 llvm::DenseSet<unsigned> Exceptions;
304 TidyDiagnosticGroups(llvm::StringRef
Checks) {
305 constexpr llvm::StringLiteral CDPrefix =
"clang-diagnostic-";
307 llvm::StringRef Check;
310 Check = Check.trim();
315 bool Enable = !Check.consume_front(
"-");
316 bool Glob = Check.consume_back(
"*");
320 if (CDPrefix.starts_with(Check)) {
328 if (Default == Enable)
331 if (!Check.consume_front(CDPrefix))
334 if (
auto Group = DiagnosticIDs::getGroupForWarningOption(Check))
335 Exceptions.insert(
static_cast<unsigned>(*Group));
339 bool operator()(diag::Group GroupID)
const {
340 return Exceptions.contains(
static_cast<unsigned>(GroupID)) ? !Default
350void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
351 llvm::function_ref<
bool(diag::Group)> EnabledGroups,
352 DiagnosticsEngine &Diags) {
353 for (llvm::StringRef Group : ExtraArgs) {
356 llvm::SmallVector<diag::kind> Members;
357 if (!Group.consume_front(
"-W") || Group.empty())
359 bool Enable = !Group.consume_front(
"no-");
360 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
361 diag::Flavor::WarningOrError, Group, Members))
367 bool NeedsWerrorExclusion =
false;
368 for (diag::kind ID : Members) {
370 if (Diags.getDiagnosticLevel(ID, SourceLocation()) <
371 DiagnosticsEngine::Warning) {
372 auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID);
373 if (!Group || !EnabledGroups(*Group))
375 Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation());
376 if (Diags.getWarningsAsErrors())
377 NeedsWerrorExclusion =
true;
380 Diags.setSeverity(ID, diag::Severity::Ignored, SourceLocation());
383 if (NeedsWerrorExclusion) {
387 Diags.setDiagnosticGroupWarningAsError(Group,
false);
392std::vector<Diag> getIncludeCleanerDiags(
ParsedAST &
AST, llvm::StringRef Code,
395 if (Cfg.Diagnostics.SuppressAll)
397 bool SuppressMissing =
398 Cfg.Diagnostics.Suppress.contains(
"missing-includes") ||
400 bool SuppressUnused =
401 Cfg.Diagnostics.Suppress.contains(
"unused-includes") ||
403 if (SuppressMissing && SuppressUnused)
406 AST, Cfg.Diagnostics.Includes.AnalyzeAngledIncludes);
408 Findings.MissingIncludes.clear();
410 Findings.UnusedIncludes.clear();
412 AST, Code, Findings, TFS, Cfg.Diagnostics.Includes.IgnoreHeader,
413 Cfg.Style.AngledHeaders, Cfg.Style.QuotedHeaders);
416tidy::ClangTidyCheckFactories
417filterFastTidyChecks(
const tidy::ClangTidyCheckFactories &
All,
422 tidy::ClangTidyCheckFactories Fast;
423 for (
const auto &Factory :
All) {
425 Fast.registerCheckFactory(Factory.first(), Factory.second);
432std::optional<ParsedAST>
434 std::unique_ptr<clang::CompilerInvocation> CI,
435 llvm::ArrayRef<Diag> CompilerInvocationDiags,
436 std::shared_ptr<const PreambleData> Preamble) {
442 if (Preamble && Preamble->StatCache)
443 VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
447 if (CI->getFrontendOpts().Inputs.size() > 0) {
448 auto Lang = CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
449 if (Lang == Language::Asm || Lang == Language::LLVM_IR) {
450 elog(
"Clangd does not support assembly or IR source files");
457 CI->getFrontendOpts().DisableFree =
false;
458 const PrecompiledPreamble *PreamblePCH =
459 Preamble ? &Preamble->Preamble :
nullptr;
463 CI->getLangOpts().DelayedTemplateParsing =
false;
465 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
468 if (
auto Listener = M.astListeners())
469 ASTListeners.emplace_back(std::move(Listener));
475 for (
const auto &L : ASTListeners)
476 L->sawDiagnostic(D,
Diag);
479 for (
const auto &L : ASTListeners)
480 L->finalizeDiagnostic(
Diag);
485 if (Preamble && Preamble->RequiredModules)
486 Preamble->RequiredModules->adjustHeaderSearchOptions(
487 CI->getHeaderSearchOpts());
489 std::optional<PreamblePatch> Patch;
500 llvm::MemoryBuffer::getMemBufferCopy(Inputs.
Contents, Filename), VFS,
506 std::vector<Diag> Diags(ASTDiags.
take());
507 elog(
"Failed to prepare a compiler instance: {0}",
516 dlog(
"ClangTidy configuration for file {0}: {1}", Filename,
537 auto &Diags = Clang->getDiagnostics();
538 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.
Checks ? *ClangTidyOpts.
Checks
539 : llvm::StringRef());
541 applyWarningOptions(*ClangTidyOpts.
ExtraArgsBefore, TidyGroups, Diags);
543 applyWarningOptions(*ClangTidyOpts.
ExtraArgs, TidyGroups, Diags);
546 auto Action = std::make_unique<ClangdFrontendAction>();
547 for (
const auto &L : ASTListeners)
548 L->beforeBeginSourceFile(*Clang);
549 const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
550 if (!Action->BeginSourceFile(*Clang, MainInput)) {
551 elog(
"BeginSourceFile() failed when building AST for {0}",
552 MainInput.getFile());
560 if (Preamble && Preamble->MainIsIncludeGuarded) {
561 const SourceManager &SM = Clang->getSourceManager();
562 OptionalFileEntryRef MainFE = SM.getFileEntryRefForID(SM.getMainFileID());
563 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(*MainFE);
572 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
573 ast_matchers::MatchFinder CTFinder;
574 std::optional<tidy::ClangTidyContext> CTContext;
576 auto BuildDir = VFS->getCurrentWorkingDirectory();
577 std::optional<IncludeFixer> FixIncludes;
578 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
583 static const auto *AllCTFactories = [] {
585 for (
const auto &E : tidy::ClangTidyModuleRegistry::entries())
586 E.instantiate()->addCheckFactories(*CTFactories);
589 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
595 CTContext->setDiagnosticsEngine(
nullptr, &Clang->getDiagnostics());
596 CTContext->setASTContext(&Clang->getASTContext());
597 CTContext->setCurrentFile(Filename);
598 CTContext->setSelfContainedDiags(
true);
600#if CLANG_TIDY_ENABLE_QUERY_BASED_CUSTOM_CHECKS
601 if (CTContext->canExperimentalCustomChecks() &&
605 static std::mutex CustomChecksMu;
606 std::lock_guard<std::mutex> Lock(CustomChecksMu);
614 Preprocessor *PP = &Clang->getPreprocessor();
615 for (
const auto &Check : CTChecks) {
616 Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
617 Check->registerMatchers(&CTFinder);
625 for (
auto ID : {diag::ext_implicit_function_decl_c99,
626 diag::ext_implicit_lib_function_decl,
627 diag::ext_implicit_lib_function_decl_c99,
628 diag::warn_implicit_function_decl}) {
629 OverriddenSeverity.try_emplace(
630 ID, Clang->getDiagnostics().getDiagnosticLevel(ID, SourceLocation()));
631 Clang->getDiagnostics().setSeverity(ID, diag::Severity::Error,
636 const clang::Diagnostic &
Info) {
637 auto It = OverriddenSeverity.find(
Info.getID());
638 if (It != OverriddenSeverity.end())
639 DiagLevel = It->second;
641 if (!CTChecks.empty()) {
642 std::string CheckName = CTContext->getCheckName(
Info.getID());
643 bool IsClangTidyDiag = !CheckName.empty();
644 if (IsClangTidyDiag) {
646 return DiagnosticsEngine::Ignored;
653 bool IsInsideMainFile =
654 Info.hasSourceManager() &&
657 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
658 DiagLevel,
Info, TidySuppressedErrors,
663 return DiagnosticsEngine::Ignored;
665 if (!CTContext->getOptions().SystemHeaders.value_or(
false) &&
666 Info.hasSourceManager() &&
667 Info.getSourceManager().isInSystemMacro(
Info.getLocation()))
668 return DiagnosticsEngine::Ignored;
671 if (DiagLevel == DiagnosticsEngine::Warning &&
672 CTContext->treatAsError(CheckName)) {
673 return DiagnosticsEngine::Error;
682 if (Inputs.
Index && !BuildDir.getError()) {
685 auto Inserter = std::make_shared<IncludeInserter>(
686 Filename, Inputs.
Contents, Style, BuildDir.get(),
687 &Clang->getPreprocessor().getHeaderSearchInfo(),
689 ArrayRef<Inclusion> MainFileIncludes;
691 MainFileIncludes = Preamble->Includes.MainFileIncludes;
692 for (
const auto &Inc : Preamble->Includes.MainFileIncludes)
693 Inserter->addExisting(Inc);
700 MainFileIncludes, {})
702 FixIncludes.emplace(Filename, Inserter, *Inputs.
Index,
704 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
705 const clang::Diagnostic &
Info) {
706 return FixIncludes->fix(DiagLevl,
Info);
708 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
713 for (
const auto &L : ASTListeners)
714 L->beforePPCallbacks(*Clang);
717 include_cleaner::PragmaIncludes PI;
720 Includes = Preamble->Includes;
721 Includes.MainFileIncludes = Patch->preambleIncludes();
723 ReplayPreamble::attach(Patch->preambleIncludes(), Patch->mainFileMacros(),
724 *Clang, Patch->modifiedBounds());
725 PI = *Preamble->Pragmas;
737 std::vector<PragmaMark> Marks;
739 Macros = Patch->mainFileMacros();
740 Marks = Patch->marks();
742 auto &PP = Clang->getPreprocessor();
743 auto MacroCollector = std::make_unique<CollectMainFileMacros>(PP, Macros);
744 auto *MacroCollectorPtr = MacroCollector.get();
745 PP.addPPCallbacks(std::move(MacroCollector));
754 syntax::TokenCollector CollectTokens(PP);
759 for (
const auto &L : ASTListeners)
760 L->beforeExecute(*Clang);
762 if (llvm::Error Err = Action->Execute())
763 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
768 MacroCollectorPtr->doneParse();
773 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
775 Tokens.indexExpandedTokens();
776 std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls();
778 Clang->getASTContext().setTraversalScope(ParsedDecls);
779 if (!CTChecks.empty()) {
783 CTFinder.matchAST(Clang->getASTContext());
785 for (
const auto &L : ASTListeners)
786 L->afterExecute(*Clang);
798 std::vector<Diag> Diags = CompilerInvocationDiags;
803 llvm::append_range(Diags, Patch->patchedDiags());
806 std::vector<Diag> D = ASTDiags.
take(&*CTContext);
807 Diags.insert(Diags.end(), D.begin(), D.end());
810 std::move(Clang), std::move(Action), std::move(Tokens),
811 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
812 std::move(Diags), std::move(Includes), std::move(PI));
813 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
814 std::back_inserter(Result.Diags));
815 return std::move(Result);
826 auto PP = Clang->getPreprocessorPtr();
827 Clang->setPreprocessor(
nullptr);
828 Action->EndSourceFile();
836 return Clang->getASTContext();
844 return Clang->getPreprocessorPtr();
848 return Clang->getPreprocessor();
852 return LocalTopLevelDecls;
856 return LocalTopLevelDecls;
867 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
873 Total +=
AST.getASTAllocatedMemory();
874 Total +=
AST.getSideTableAllocatedMemory();
875 Total +=
AST.Idents.getAllocator().getTotalMemory();
876 Total +=
AST.Selectors.getTotalMemory();
878 Total +=
AST.getSourceManager().getContentCacheSize();
879 Total +=
AST.getSourceManager().getDataStructureSizes();
880 Total +=
AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
882 if (ExternalASTSource *Ext =
AST.getExternalSource())
883 Total += Ext->getMemoryBufferSizes().malloc_bytes;
886 Total += PP.getTotalMemory();
887 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
888 Total += PRec->getTotalMemory();
889 Total += PP.getHeaderSearchInfo().getTotalMemory();
899 std::shared_ptr<const PreambleData>
Preamble,
900 std::unique_ptr<CompilerInstance> Clang,
901 std::unique_ptr<FrontendAction> Action,
903 std::vector<PragmaMark> Marks,
904 std::vector<Decl *> LocalTopLevelDecls,
906 include_cleaner::PragmaIncludes PI)
908 Clang(std::
move(Clang)), Action(std::
move(Action)),
909 Tokens(std::
move(Tokens)), Macros(std::
move(Macros)),
910 Marks(std::
move(Marks)), Diags(std::
move(Diags)),
911 LocalTopLevelDecls(std::
move(LocalTopLevelDecls)),
912 Includes(std::
move(Includes)), PI(std::
move(PI)),
913 Resolver(std::make_unique<HeuristicResolver>(getASTContext())) {
915 assert(this->Action);
925 return llvm::StringRef(Preamble->Version);
static cl::opt< std::string > Checks("checks", desc(R"(
Comma-separated list of globs with optional '-'
prefix. Globs are processed in order of
appearance in the list. Globs without '-'
prefix add checks with matching names to the
set, globs with the '-' prefix remove checks
with matching names from the set of enabled
checks. This option's value is appended to the
value of the 'Checks' option in .clang-tidy
file, if any.
)"), cl::init(""), cl::cat(ClangTidyCategory))
Include Cleaner is clangd functionality for providing diagnostics for misuse of transitive headers an...
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for Markdown output.")
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
void collect(const CompilerInstance &CI)
Stores and provides access to parsed AST.
std::size_t getUsedBytes() const
Returns the estimated size of the AST and the accessory structures, in bytes.
std::optional< llvm::StringRef > preambleVersion() const
Returns the version of the ParseInputs used to build Preamble part of this AST.
const include_cleaner::PragmaIncludes & getPragmaIncludes() const
Returns the PramaIncludes for preamble + main file includes.
const std::vector< PragmaMark > & getMarks() const
Gets all pragma marks in the main file.
ASTContext & getASTContext()
Note that the returned ast will not contain decls from the preamble that were not deserialized during...
static std::optional< ParsedAST > build(llvm::StringRef Filename, const ParseInputs &Inputs, std::unique_ptr< clang::CompilerInvocation > CI, llvm::ArrayRef< Diag > CompilerInvocationDiags, std::shared_ptr< const PreambleData > Preamble)
Attempts to run Clang and store the parsed AST.
llvm::ArrayRef< Diag > getDiagnostics() const
std::shared_ptr< Preprocessor > getPreprocessorPtr()
Preprocessor & getPreprocessor()
ArrayRef< Decl * > getLocalTopLevelDecls()
This function returns top-level decls present in the main file of the AST.
ParsedAST & operator=(ParsedAST &&Other)
const IncludeStructure & getIncludeStructure() const
ParsedAST(ParsedAST &&Other)
const MainFileMacros & getMacros() const
Gets all macro references (definition, expansions) present in the main file, including those in the p...
static PreamblePatch createFullPatch(llvm::StringRef FileName, const ParseInputs &Modified, const PreambleData &Baseline)
Builds a patch that contains new PP directives introduced to the preamble section of Modified compare...
StoreDiags collects the diagnostics that can later be reported by clangd.
void contributeFixes(DiagFixer Fixer)
If set, possibly adds fixes for diagnostics using Fixer.
void setDiagFinalizer(DiagFinalizer F)
Invokes a callback after notes and fixes have been attached.
void setLevelAdjuster(LevelAdjuster Adjuster)
If set, this allows the client of this class to adjust the level of diagnostics, such as promoting wa...
std::vector< Diag > take(const clang::tidy::ClangTidyContext *Tidy=nullptr)
void setDiagCallback(DiagCallback CB)
Invokes a callback when a main diagnostic is first formed, before notes and fixes are attached.
void EndSourceFile() override
Wrapper for vfs::FileSystem for use in multithreaded programs like clangd.
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > view(std::nullopt_t CWD) const
Obtain a vfs::FileSystem with an arbitrary initial working directory.
Records an event whose duration is the lifetime of the Span object.
A collection of ClangTidyCheckFactory instances.
std::vector< std::unique_ptr< ClangTidyCheck > > createChecksForLanguage(ClangTidyContext *Context) const
Create instances of checks that are enabled for the current Language.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
@ Info
An information message.
bool isInsideMainFile(SourceLocation Loc, const SourceManager &SM)
Returns true iff Loc is inside the main file.
static const char * toString(OffsetEncoding OE)
std::unique_ptr< PPCallbacks > collectPragmaMarksCallback(const SourceManager &SM, std::vector< PragmaMark > &Out)
Collect all pragma marks from the main file.
std::optional< bool > isFastTidyCheck(llvm::StringRef Check)
Returns if Check is known-fast, known-slow, or its speed is unknown.
Symbol::IncludeDirective preferredIncludeDirective(llvm::StringRef FileName, const LangOptions &LangOpts, ArrayRef< Inclusion > MainFileIncludes, ArrayRef< const Decl * > TopLevelDecls)
Infer the include directive to use for the given FileName.
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)
void log(const char *Fmt, Ts &&... Vals)
IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST, bool AnalyzeAngledIncludes)
llvm::StringRef PathRef
A typedef to represent a ref to file path.
tidy::ClangTidyOptions getTidyOptionsForFile(TidyProviderRef Provider, llvm::StringRef Filename)
bool isImplicitTemplateInstantiation(const NamedDecl *D)
Indicates if D is a template instantiation implicitly generated by the compiler, e....
std::vector< Diag > issueIncludeCleanerDiagnostics(ParsedAST &AST, llvm::StringRef Code, const IncludeCleanerFindings &Findings, const ThreadsafeFS &TFS, HeaderFilter IgnoreHeaders, HeaderFilter AngledHeaders, HeaderFilter QuotedHeaders)
void elog(const char *Fmt, Ts &&... Vals)
format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, const ThreadsafeFS &TFS, bool FormatFile)
Choose the clang-format style we should apply to a certain file.
void(* RegisterCustomChecks)(const ClangTidyOptions &O, ClangTidyCheckFactories &Factories)
std::string configurationAsText(const ClangTidyOptions &Options)
Serializes configuration to a YAML-encoded string.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Settings that express user/project preferences and control clangd behavior.
struct clang::clangd::Config::@314053012031341203055315320366267371313202370174 Style
Style of the codebase.
FastCheckPolicy FastCheckFilter
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
struct clang::clangd::Config::@343034053122374337352226322054223376344037116252 Diagnostics
Controls warnings and errors when parsing code.
struct clang::clangd::Config::@343034053122374337352226322054223376344037116252::@107156241027253143221327255130274177352007274355 ClangTidy
Configures what clang-tidy checks to run and options to use with them.
std::vector< std::function< bool(llvm::StringRef)> > QuotedHeaders
bool ExperimentalCustomChecks
std::vector< std::function< bool(llvm::StringRef)> > AngledHeaders
Contains basic information about a diagnostic.
A top-level diagnostic that may have Notes and Fixes.
@ Include
#include "header.h"
Contains options for clang-tidy.
std::optional< std::string > Checks
Checks filter.
std::optional< ArgList > ExtraArgsBefore
Add extra compilation arguments to the start of the list.
std::optional< ArgList > ExtraArgs
Add extra compilation arguments to the end of the list.