28#include "clang-include-cleaner/Record.h"
33#include "clang/AST/ASTContext.h"
34#include "clang/AST/Decl.h"
35#include "clang/AST/DeclGroup.h"
36#include "clang/AST/ExternalASTSource.h"
37#include "clang/ASTMatchers/ASTMatchFinder.h"
38#include "clang/Basic/Diagnostic.h"
39#include "clang/Basic/DiagnosticIDs.h"
40#include "clang/Basic/DiagnosticSema.h"
41#include "clang/Basic/FileEntry.h"
42#include "clang/Basic/LLVM.h"
43#include "clang/Basic/LangOptions.h"
44#include "clang/Basic/SourceLocation.h"
45#include "clang/Basic/SourceManager.h"
46#include "clang/Basic/TokenKinds.h"
47#include "clang/Frontend/CompilerInstance.h"
48#include "clang/Frontend/CompilerInvocation.h"
49#include "clang/Frontend/FrontendActions.h"
50#include "clang/Frontend/FrontendOptions.h"
51#include "clang/Frontend/PrecompiledPreamble.h"
52#include "clang/Lex/Lexer.h"
53#include "clang/Lex/PPCallbacks.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
90template <
class T> std::size_t getUsedBytes(
const std::vector<T> &Vec) {
91 return Vec.capacity() *
sizeof(
T);
94class DeclTrackingASTConsumer :
public ASTConsumer {
96 DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
97 : TopLevelDecls(TopLevelDecls) {}
99 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
101 auto &SM =
D->getASTContext().getSourceManager();
104 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D))
109 if (isa<ObjCMethodDecl>(D))
112 TopLevelDecls.push_back(D);
118 std::vector<Decl *> &TopLevelDecls;
121class ClangdFrontendAction :
public SyntaxOnlyAction {
123 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
126 std::unique_ptr<ASTConsumer>
127 CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile)
override {
128 return std::make_unique<DeclTrackingASTConsumer>( TopLevelDecls);
132 std::vector<Decl *> TopLevelDecls;
141class ReplayPreamble :
private PPCallbacks {
146 static void attach(std::vector<Inclusion> Includes, CompilerInstance &Clang,
147 const PreambleBounds &PB) {
148 auto &PP = Clang.getPreprocessor();
149 auto *ExistingCallbacks = PP.getPPCallbacks();
151 if (!ExistingCallbacks)
153 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
new ReplayPreamble(
154 std::move(Includes), ExistingCallbacks, Clang.getSourceManager(), PP,
155 Clang.getLangOpts(), PB)));
158 assert(PP.getPPCallbacks() != ExistingCallbacks &&
159 "Expected chaining implementation");
163 ReplayPreamble(std::vector<Inclusion> Includes, PPCallbacks *Delegate,
164 const SourceManager &SM, Preprocessor &PP,
165 const LangOptions &LangOpts,
const PreambleBounds &PB)
166 : Includes(std::move(Includes)), Delegate(Delegate), SM(SM), PP(PP) {
169 MainFileTokens = syntax::tokenize(
170 syntax::FileRange(SM.getMainFileID(), 0, PB.Size), SM, LangOpts);
188 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
189 SrcMgr::CharacteristicKind Kind, FileID PrevFID)
override {
191 if (Reason == FileChangeReason::ExitFile &&
192 SM.getBufferOrFake(PrevFID).getBufferIdentifier() ==
"<built-in>")
197 for (
const auto &Inc : Includes) {
198 OptionalFileEntryRef
File;
199 if (Inc.Resolved !=
"")
200 File = expectedToOptional(SM.getFileManager().getFileRef(Inc.Resolved));
203 auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset);
204 auto HashTok = llvm::partition_point(MainFileTokens,
205 [&HashLoc](
const syntax::Token &T) {
206 return T.location() < HashLoc;
208 assert(HashTok != MainFileTokens.end() && HashTok->kind() == tok::hash);
210 auto IncludeTok = std::next(HashTok);
211 assert(IncludeTok != MainFileTokens.end());
213 auto FileTok = std::next(IncludeTok);
214 assert(FileTok != MainFileTokens.end());
218 Token SynthesizedIncludeTok;
219 SynthesizedIncludeTok.startToken();
220 SynthesizedIncludeTok.setLocation(IncludeTok->location());
221 SynthesizedIncludeTok.setLength(IncludeTok->length());
222 SynthesizedIncludeTok.setKind(tok::raw_identifier);
223 SynthesizedIncludeTok.setRawIdentifierData(IncludeTok->text(SM).data());
224 PP.LookUpIdentifierInfo(SynthesizedIncludeTok);
227 Token SynthesizedFilenameTok;
228 SynthesizedFilenameTok.startToken();
229 SynthesizedFilenameTok.setLocation(FileTok->location());
234 SynthesizedFilenameTok.setLength(Inc.Written.length());
235 SynthesizedFilenameTok.setKind(tok::header_name);
236 SynthesizedFilenameTok.setLiteralData(Inc.Written.data());
238 llvm::StringRef WrittenFilename =
239 llvm::StringRef(Inc.Written).drop_front().drop_back();
240 Delegate->InclusionDirective(
241 HashTok->location(), SynthesizedIncludeTok, WrittenFilename,
242 Inc.Written.front() ==
'<',
243 syntax::FileRange(SM, SynthesizedFilenameTok.getLocation(),
244 SynthesizedFilenameTok.getEndLoc())
246 File,
"SearchPath",
"RelPath",
247 nullptr,
false, Inc.FileKind);
249 Delegate->FileSkipped(*
File, SynthesizedFilenameTok, Inc.FileKind);
253 const std::vector<Inclusion> Includes;
254 PPCallbacks *Delegate;
255 const SourceManager &SM;
257 std::vector<syntax::Token> MainFileTokens;
268class TidyDiagnosticGroups {
271 bool Default =
false;
274 llvm::DenseSet<unsigned> Exceptions;
277 TidyDiagnosticGroups(llvm::StringRef
Checks) {
278 constexpr llvm::StringLiteral CDPrefix =
"clang-diagnostic-";
280 llvm::StringRef Check;
283 Check = Check.trim();
288 bool Enable = !Check.consume_front(
"-");
289 bool Glob = Check.consume_back(
"*");
293 if (CDPrefix.starts_with(Check)) {
301 if (Default == Enable)
304 if (!Check.consume_front(CDPrefix))
307 if (
auto Group = DiagnosticIDs::getGroupForWarningOption(Check))
308 Exceptions.insert(
static_cast<unsigned>(*Group));
312 bool operator()(diag::Group GroupID)
const {
313 return Exceptions.contains(
static_cast<unsigned>(GroupID)) ? !Default
323void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
324 llvm::function_ref<
bool(diag::Group)> EnabledGroups,
325 DiagnosticsEngine &Diags) {
326 for (llvm::StringRef Group : ExtraArgs) {
329 llvm::SmallVector<diag::kind> Members;
330 if (!Group.consume_front(
"-W") || Group.empty())
332 bool Enable = !Group.consume_front(
"no-");
333 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
334 diag::Flavor::WarningOrError, Group, Members))
340 bool NeedsWerrorExclusion =
false;
341 for (diag::kind ID : Members) {
343 if (Diags.getDiagnosticLevel(ID, SourceLocation()) <
344 DiagnosticsEngine::Warning) {
345 auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID);
346 if (!Group || !EnabledGroups(*Group))
348 Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation());
349 if (Diags.getWarningsAsErrors())
350 NeedsWerrorExclusion =
true;
353 Diags.setSeverity(ID, diag::Severity::Ignored, SourceLocation());
356 if (NeedsWerrorExclusion) {
360 Diags.setDiagnosticGroupWarningAsError(Group,
false);
365std::vector<Diag> getIncludeCleanerDiags(
ParsedAST &
AST, llvm::StringRef Code,
368 if (Cfg.Diagnostics.SuppressAll)
370 bool SuppressMissing =
371 Cfg.Diagnostics.Suppress.contains(
"missing-includes") ||
373 bool SuppressUnused =
374 Cfg.Diagnostics.Suppress.contains(
"unused-includes") ||
376 if (SuppressMissing && SuppressUnused)
379 AST, Cfg.Diagnostics.Includes.AnalyzeAngledIncludes);
381 Findings.MissingIncludes.clear();
383 Findings.UnusedIncludes.clear();
385 AST, Code, Findings, TFS, Cfg.Diagnostics.Includes.IgnoreHeader,
386 Cfg.Style.AngledHeaders, Cfg.Style.QuotedHeaders);
389tidy::ClangTidyCheckFactories
390filterFastTidyChecks(
const tidy::ClangTidyCheckFactories &
All,
395 tidy::ClangTidyCheckFactories Fast;
396 for (
const auto &Factory :
All) {
398 Fast.registerCheckFactory(Factory.first(), Factory.second);
405std::optional<ParsedAST>
407 std::unique_ptr<clang::CompilerInvocation> CI,
408 llvm::ArrayRef<Diag> CompilerInvocationDiags,
409 std::shared_ptr<const PreambleData> Preamble) {
415 if (Preamble && Preamble->StatCache)
416 VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
420 if (CI->getFrontendOpts().Inputs.size() > 0) {
421 auto Lang = CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
422 if (Lang == Language::Asm || Lang == Language::LLVM_IR) {
423 elog(
"Clangd does not support assembly or IR source files");
430 CI->getFrontendOpts().DisableFree =
false;
431 const PrecompiledPreamble *PreamblePCH =
432 Preamble ? &Preamble->Preamble :
nullptr;
436 CI->getLangOpts().DelayedTemplateParsing =
false;
438 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
441 if (
auto Listener = M.astListeners())
442 ASTListeners.emplace_back(std::move(Listener));
448 for (
const auto &L : ASTListeners)
449 L->sawDiagnostic(D,
Diag);
454 if (Preamble && Preamble->RequiredModules)
455 Preamble->RequiredModules->adjustHeaderSearchOptions(
456 CI->getHeaderSearchOpts());
458 std::optional<PreamblePatch> Patch;
468 std::move(CI), PreamblePCH,
469 llvm::MemoryBuffer::getMemBufferCopy(Inputs.
Contents, Filename), VFS,
475 std::vector<Diag> Diags(ASTDiags.
take());
476 elog(
"Failed to prepare a compiler instance: {0}",
485 dlog(
"ClangTidy configuration for file {0}: {1}", Filename,
506 auto &Diags = Clang->getDiagnostics();
507 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.
Checks ? *ClangTidyOpts.
Checks
508 : llvm::StringRef());
510 applyWarningOptions(*ClangTidyOpts.
ExtraArgsBefore, TidyGroups, Diags);
512 applyWarningOptions(*ClangTidyOpts.
ExtraArgs, TidyGroups, Diags);
515 auto Action = std::make_unique<ClangdFrontendAction>();
516 const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
517 if (!Action->BeginSourceFile(*Clang, MainInput)) {
518 elog(
"BeginSourceFile() failed when building AST for {0}",
519 MainInput.getFile());
527 if (Preamble && Preamble->MainIsIncludeGuarded) {
528 const SourceManager &SM = Clang->getSourceManager();
529 OptionalFileEntryRef MainFE = SM.getFileEntryRefForID(SM.getMainFileID());
530 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(*MainFE);
539 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
540 ast_matchers::MatchFinder CTFinder;
541 std::optional<tidy::ClangTidyContext> CTContext;
543 auto BuildDir = VFS->getCurrentWorkingDirectory();
544 std::optional<IncludeFixer> FixIncludes;
545 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
550 static const auto *AllCTFactories = [] {
552 for (
const auto &E : tidy::ClangTidyModuleRegistry::entries())
553 E.instantiate()->addCheckFactories(*CTFactories);
558 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
561 CTContext->setDiagnosticsEngine(
nullptr, &Clang->getDiagnostics());
562 CTContext->setASTContext(&Clang->getASTContext());
563 CTContext->setCurrentFile(Filename);
564 CTContext->setSelfContainedDiags(
true);
566 Preprocessor *PP = &Clang->getPreprocessor();
567 for (
const auto &Check : CTChecks) {
568 Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
569 Check->registerMatchers(&CTFinder);
577 for (
auto ID : {diag::ext_implicit_function_decl_c99,
578 diag::ext_implicit_lib_function_decl,
579 diag::ext_implicit_lib_function_decl_c99,
580 diag::warn_implicit_function_decl}) {
581 OverriddenSeverity.try_emplace(
582 ID, Clang->getDiagnostics().getDiagnosticLevel(ID, SourceLocation()));
583 Clang->getDiagnostics().setSeverity(ID, diag::Severity::Error,
588 const clang::Diagnostic &
Info) {
591 Clang->getLangOpts()))
592 return DiagnosticsEngine::Ignored;
594 auto It = OverriddenSeverity.find(
Info.getID());
595 if (It != OverriddenSeverity.end())
596 DiagLevel = It->second;
598 if (!CTChecks.empty()) {
599 std::string CheckName = CTContext->getCheckName(
Info.getID());
600 bool IsClangTidyDiag = !CheckName.empty();
601 if (IsClangTidyDiag) {
603 return DiagnosticsEngine::Ignored;
610 bool IsInsideMainFile =
611 Info.hasSourceManager() &&
613 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors;
614 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
615 DiagLevel,
Info, TidySuppressedErrors,
620 return DiagnosticsEngine::Ignored;
622 if (!CTContext->getOptions().SystemHeaders.value_or(
false) &&
623 Info.hasSourceManager() &&
624 Info.getSourceManager().isInSystemMacro(
Info.getLocation()))
625 return DiagnosticsEngine::Ignored;
628 if (DiagLevel == DiagnosticsEngine::Warning &&
629 CTContext->treatAsError(CheckName)) {
630 return DiagnosticsEngine::Error;
639 if (Inputs.
Index && !BuildDir.getError()) {
642 auto Inserter = std::make_shared<IncludeInserter>(
643 Filename, Inputs.
Contents, Style, BuildDir.get(),
644 &Clang->getPreprocessor().getHeaderSearchInfo(),
646 ArrayRef<Inclusion> MainFileIncludes;
648 MainFileIncludes = Preamble->Includes.MainFileIncludes;
649 for (
const auto &Inc : Preamble->Includes.MainFileIncludes)
650 Inserter->addExisting(Inc);
657 MainFileIncludes, {})
659 FixIncludes.emplace(Filename, Inserter, *Inputs.
Index,
661 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
662 const clang::Diagnostic &
Info) {
663 return FixIncludes->fix(DiagLevl,
Info);
665 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
670 include_cleaner::PragmaIncludes PI;
673 Includes = Preamble->Includes;
674 Includes.MainFileIncludes = Patch->preambleIncludes();
676 ReplayPreamble::attach(Patch->preambleIncludes(), *Clang,
677 Patch->modifiedBounds());
678 PI = *Preamble->Pragmas;
690 std::vector<PragmaMark> Marks;
692 Macros = Patch->mainFileMacros();
693 Marks = Patch->marks();
695 auto &PP = Clang->getPreprocessor();
696 auto MacroCollector = std::make_unique<CollectMainFileMacros>(PP, Macros);
697 auto *MacroCollectorPtr = MacroCollector.get();
698 PP.addPPCallbacks(std::move(MacroCollector));
707 syntax::TokenCollector CollectTokens(PP);
712 for (
const auto &L : ASTListeners)
713 L->beforeExecute(*Clang);
715 if (llvm::Error Err = Action->Execute())
716 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
721 MacroCollectorPtr->doneParse();
726 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
728 Tokens.indexExpandedTokens();
729 std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls();
731 Clang->getASTContext().setTraversalScope(ParsedDecls);
732 if (!CTChecks.empty()) {
736 CTFinder.matchAST(Clang->getASTContext());
749 std::vector<Diag> Diags = CompilerInvocationDiags;
754 llvm::append_range(Diags, Patch->patchedDiags());
757 std::vector<Diag> D = ASTDiags.
take(&*CTContext);
758 Diags.insert(Diags.end(), D.begin(), D.end());
761 std::move(Clang), std::move(Action), std::move(Tokens),
762 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
763 std::move(Diags), std::move(Includes), std::move(PI));
764 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
765 std::back_inserter(Result.Diags));
766 return std::move(Result);
777 auto PP = Clang->getPreprocessorPtr();
778 Clang->setPreprocessor(
nullptr);
779 Action->EndSourceFile();
787 return Clang->getASTContext();
795 return Clang->getPreprocessorPtr();
799 return Clang->getPreprocessor();
803 return LocalTopLevelDecls;
807 return LocalTopLevelDecls;
818 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
824 Total +=
AST.getASTAllocatedMemory();
825 Total +=
AST.getSideTableAllocatedMemory();
826 Total +=
AST.Idents.getAllocator().getTotalMemory();
827 Total +=
AST.Selectors.getTotalMemory();
829 Total +=
AST.getSourceManager().getContentCacheSize();
830 Total +=
AST.getSourceManager().getDataStructureSizes();
831 Total +=
AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
833 if (ExternalASTSource *Ext =
AST.getExternalSource())
834 Total += Ext->getMemoryBufferSizes().malloc_bytes;
837 Total += PP.getTotalMemory();
838 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
839 Total += PRec->getTotalMemory();
840 Total += PP.getHeaderSearchInfo().getTotalMemory();
850 std::shared_ptr<const PreambleData>
Preamble,
851 std::unique_ptr<CompilerInstance> Clang,
852 std::unique_ptr<FrontendAction> Action,
854 std::vector<PragmaMark> Marks,
855 std::vector<Decl *> LocalTopLevelDecls,
857 include_cleaner::PragmaIncludes PI)
859 Clang(std::
move(Clang)), Action(std::
move(Action)),
860 Tokens(std::
move(Tokens)), Macros(std::
move(Macros)),
861 Marks(std::
move(Marks)), Diags(std::
move(Diags)),
862 LocalTopLevelDecls(std::
move(LocalTopLevelDecls)),
863 Includes(std::
move(Includes)), PI(std::
move(PI)),
864 Resolver(std::make_unique<HeuristicResolver>(getASTContext())) {
866 assert(this->Action);
876 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...
#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 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 every time a diagnostics is completely formed.
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.
bool isDiagnosticSuppressed(const clang::Diagnostic &Diag, const llvm::StringSet<> &Suppress, const LangOptions &LangOpts)
Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
@ 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.
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::@224206046260313204212274150166346126315121140114::@177170157270305170147304143303331271375010045063 ClangTidy
Configures what clang-tidy checks to run and options to use with them.
FastCheckPolicy FastCheckFilter
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
std::vector< std::function< bool(llvm::StringRef)> > QuotedHeaders
struct clang::clangd::Config::@224206046260313204212274150166346126315121140114 Diagnostics
Controls warnings and errors when parsing code.
std::vector< std::function< bool(llvm::StringRef)> > AngledHeaders
struct clang::clangd::Config::@365336221326264215251130354321073040111277322060 Style
Style of the codebase.
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.