10#include "../clang-tidy/ClangTidyCheck.h"
11#include "../clang-tidy/ClangTidyDiagnosticConsumer.h"
12#include "../clang-tidy/ClangTidyModule.h"
13#include "../clang-tidy/ClangTidyModuleRegistry.h"
14#include "../clang-tidy/ClangTidyOptions.h"
29#include "clang-include-cleaner/Record.h"
34#include "clang/AST/ASTContext.h"
35#include "clang/AST/Decl.h"
36#include "clang/AST/DeclGroup.h"
37#include "clang/AST/ExternalASTSource.h"
38#include "clang/ASTMatchers/ASTMatchFinder.h"
39#include "clang/Basic/Diagnostic.h"
40#include "clang/Basic/DiagnosticIDs.h"
41#include "clang/Basic/DiagnosticSema.h"
42#include "clang/Basic/FileEntry.h"
43#include "clang/Basic/LLVM.h"
44#include "clang/Basic/LangOptions.h"
45#include "clang/Basic/SourceLocation.h"
46#include "clang/Basic/SourceManager.h"
47#include "clang/Basic/TokenKinds.h"
48#include "clang/Frontend/CompilerInstance.h"
49#include "clang/Frontend/CompilerInvocation.h"
50#include "clang/Frontend/FrontendActions.h"
51#include "clang/Frontend/FrontendOptions.h"
52#include "clang/Frontend/PrecompiledPreamble.h"
53#include "clang/Lex/Lexer.h"
54#include "clang/Lex/PPCallbacks.h"
55#include "clang/Lex/Preprocessor.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
83#include "../clang-tidy/ClangTidyForceLinker.h"
90template <
class T> std::size_t getUsedBytes(
const std::vector<T> &Vec) {
91 return Vec.capacity() *
sizeof(
T);
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;
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;
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;
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;
281 while (!Checks.empty()) {
282 std::tie(Check, Checks) = Checks.split(
',');
286 bool Enable = !Check.consume_front(
"-");
287 bool Glob = Check.consume_back(
"*");
291 if (CDPrefix.starts_with(Check)) {
299 if (Default == Enable)
302 if (!Check.consume_front(CDPrefix))
305 if (
auto Group = DiagnosticIDs::getGroupForWarningOption(Check))
306 Exceptions.insert(
static_cast<unsigned>(*Group));
310 bool operator()(diag::Group GroupID)
const {
311 return Exceptions.contains(
static_cast<unsigned>(GroupID)) ? !Default
321void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
322 llvm::function_ref<
bool(diag::Group)> EnabledGroups,
323 DiagnosticsEngine &Diags) {
324 for (llvm::StringRef Group : ExtraArgs) {
327 llvm::SmallVector<diag::kind> Members;
328 if (!Group.consume_front(
"-W") || Group.empty())
330 bool Enable = !Group.consume_front(
"no-");
331 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
332 diag::Flavor::WarningOrError, Group, Members))
338 bool NeedsWerrorExclusion =
false;
339 for (diag::kind
ID : Members) {
341 if (Diags.getDiagnosticLevel(
ID, SourceLocation()) <
342 DiagnosticsEngine::Warning) {
343 auto Group = DiagnosticIDs::getGroupForDiag(
ID);
344 if (!Group || !EnabledGroups(*Group))
346 Diags.setSeverity(
ID, diag::Severity::Warning, SourceLocation());
347 if (Diags.getWarningsAsErrors())
348 NeedsWerrorExclusion =
true;
351 Diags.setSeverity(
ID, diag::Severity::Ignored, SourceLocation());
354 if (NeedsWerrorExclusion) {
358 Diags.setDiagnosticGroupWarningAsError(Group,
false);
363std::vector<Diag> getIncludeCleanerDiags(ParsedAST &
AST, llvm::StringRef
Code,
364 const ThreadsafeFS &TFS) {
368 bool SuppressMissing =
371 bool SuppressUnused =
374 if (SuppressMissing && SuppressUnused)
379 Findings.MissingIncludes.clear();
381 Findings.UnusedIncludes.clear();
386tidy::ClangTidyCheckFactories
387filterFastTidyChecks(
const tidy::ClangTidyCheckFactories &
All,
392 tidy::ClangTidyCheckFactories Fast;
393 for (
const auto &Factory :
All) {
395 Fast.registerCheckFactory(Factory.first(), Factory.second);
402std::optional<ParsedAST>
404 std::unique_ptr<clang::CompilerInvocation>
CI,
405 llvm::ArrayRef<Diag> CompilerInvocationDiags,
406 std::shared_ptr<const PreambleData>
Preamble) {
411 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
413 VFS =
Preamble->StatCache->getConsumingFS(std::move(VFS));
417 if (
CI->getFrontendOpts().Inputs.size() > 0) {
418 auto Lang =
CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
419 if (
Lang == Language::Asm ||
Lang == Language::LLVM_IR) {
420 elog(
"Clangd does not support assembly or IR source files");
427 CI->getFrontendOpts().DisableFree =
false;
428 const PrecompiledPreamble *PreamblePCH =
433 CI->getLangOpts().DelayedTemplateParsing =
false;
435 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
436 if (Inputs.FeatureModules) {
437 for (
auto &
M : *Inputs.FeatureModules) {
438 if (
auto Listener =
M.astListeners())
439 ASTListeners.emplace_back(std::move(Listener));
445 for (
const auto &L : ASTListeners)
446 L->sawDiagnostic(D,
Diag);
452 Preamble->RequiredModules->adjustHeaderSearchOptions(
453 CI->getHeaderSearchOpts());
455 std::optional<PreamblePatch>
Patch;
465 std::move(
CI), PreamblePCH,
466 llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents,
Filename), VFS,
472 std::vector<Diag> Diags(ASTDiags.
take());
473 elog(
"Failed to prepare a compiler instance: {0}",
482 dlog(
"ClangTidy configuration for file {0}: {1}",
Filename,
503 auto &Diags =
Clang->getDiagnostics();
504 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.
Checks ? *ClangTidyOpts.
Checks
505 : llvm::StringRef());
507 applyWarningOptions(*ClangTidyOpts.
ExtraArgsBefore, TidyGroups, Diags);
509 applyWarningOptions(*ClangTidyOpts.
ExtraArgs, TidyGroups, Diags);
512 auto Action = std::make_unique<ClangdFrontendAction>();
513 const FrontendInputFile &MainInput =
Clang->getFrontendOpts().Inputs[0];
514 if (!Action->BeginSourceFile(*
Clang, MainInput)) {
515 elog(
"BeginSourceFile() failed when building AST for {0}",
516 MainInput.getFile());
525 const SourceManager &SM =
Clang->getSourceManager();
526 OptionalFileEntryRef MainFE = SM.getFileEntryRefForID(SM.getMainFileID());
527 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(*MainFE);
536 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
537 ast_matchers::MatchFinder CTFinder;
538 std::optional<tidy::ClangTidyContext> CTContext;
540 auto BuildDir = VFS->getCurrentWorkingDirectory();
541 std::optional<IncludeFixer> FixIncludes;
542 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
547 static const auto *AllCTFactories = [] {
549 for (
const auto &
E : tidy::ClangTidyModuleRegistry::entries())
550 E.instantiate()->addCheckFactories(*CTFactories);
554 *AllCTFactories, Cfg.Diagnostics.ClangTidy.FastCheckFilter);
555 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
557 CTContext->setDiagnosticsEngine(&
Clang->getDiagnostics());
558 CTContext->setASTContext(&
Clang->getASTContext());
559 CTContext->setCurrentFile(
Filename);
560 CTContext->setSelfContainedDiags(
true);
562 Preprocessor *PP = &
Clang->getPreprocessor();
563 for (
const auto &Check : CTChecks) {
564 Check->registerPPCallbacks(
Clang->getSourceManager(), PP, PP);
565 Check->registerMatchers(&CTFinder);
573 for (
auto ID : {diag::ext_implicit_function_decl_c99,
574 diag::ext_implicit_lib_function_decl,
575 diag::ext_implicit_lib_function_decl_c99,
576 diag::warn_implicit_function_decl}) {
577 OverriddenSeverity.try_emplace(
578 ID,
Clang->getDiagnostics().getDiagnosticLevel(
ID, SourceLocation()));
579 Clang->getDiagnostics().setSeverity(
ID, diag::Severity::Error,
584 const clang::Diagnostic &
Info) {
585 if (Cfg.Diagnostics.SuppressAll ||
587 Clang->getLangOpts()))
588 return DiagnosticsEngine::Ignored;
590 auto It = OverriddenSeverity.find(
Info.getID());
591 if (It != OverriddenSeverity.end())
592 DiagLevel = It->second;
594 if (!CTChecks.empty()) {
595 std::string CheckName = CTContext->getCheckName(Info.getID());
596 bool IsClangTidyDiag = !CheckName.empty();
597 if (IsClangTidyDiag) {
598 if (Cfg.Diagnostics.Suppress.contains(CheckName))
599 return DiagnosticsEngine::Ignored;
606 bool IsInsideMainFile =
607 Info.hasSourceManager() &&
608 isInsideMainFile(Info.getLocation(), Info.getSourceManager());
609 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors;
610 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
611 DiagLevel, Info, TidySuppressedErrors,
616 return DiagnosticsEngine::Ignored;
618 if (!CTContext->getOptions().SystemHeaders.value_or(false) &&
619 Info.hasSourceManager() &&
620 Info.getSourceManager().isInSystemMacro(Info.getLocation()))
621 return DiagnosticsEngine::Ignored;
624 if (DiagLevel == DiagnosticsEngine::Warning &&
625 CTContext->treatAsError(CheckName)) {
626 return DiagnosticsEngine::Error;
635 if (Inputs.Index && !
BuildDir.getError()) {
638 auto Inserter = std::make_shared<IncludeInserter>(
640 &
Clang->getPreprocessor().getHeaderSearchInfo());
641 ArrayRef<Inclusion> MainFileIncludes;
643 MainFileIncludes =
Preamble->Includes.MainFileIncludes;
644 for (
const auto &Inc :
Preamble->Includes.MainFileIncludes)
645 Inserter->addExisting(Inc);
650 Inputs.Opts.ImportInsertions
652 MainFileIncludes, {})
654 FixIncludes.emplace(
Filename, Inserter, *Inputs.Index,
656 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
657 const clang::Diagnostic &
Info) {
658 return FixIncludes->fix(DiagLevl,
Info);
660 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
665 include_cleaner::PragmaIncludes PI;
671 ReplayPreamble::attach(
Patch->preambleIncludes(), *
Clang,
672 Patch->modifiedBounds());
684 MainFileMacros Macros;
685 std::vector<PragmaMark> Marks;
687 Macros =
Patch->mainFileMacros();
688 Marks =
Patch->marks();
690 auto &PP =
Clang->getPreprocessor();
691 PP.addPPCallbacks(std::make_unique<CollectMainFileMacros>(PP, Macros));
700 syntax::TokenCollector CollectTokens(PP);
705 for (
const auto &L : ASTListeners)
706 L->beforeExecute(*
Clang);
708 if (llvm::Error Err =
Action->Execute())
709 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
715 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
717 Tokens.indexExpandedTokens();
718 std::vector<Decl *> ParsedDecls =
Action->takeTopLevelDecls();
720 Clang->getASTContext().setTraversalScope(ParsedDecls);
721 if (!CTChecks.empty()) {
724 trace::Span Tracer(
"ClangTidyMatch");
725 CTFinder.matchAST(
Clang->getASTContext());
734 Clang->getDiagnostics().setClient(
new IgnoreDiagnostics);
736 ASTDiags.EndSourceFile();
738 std::vector<Diag> Diags = CompilerInvocationDiags;
743 llvm::append_range(Diags,
Patch->patchedDiags());
746 std::vector<Diag> D = ASTDiags.take(&*CTContext);
747 Diags.insert(Diags.end(), D.begin(), D.end());
750 std::move(
Clang), std::move(
Action), std::move(Tokens),
751 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
752 std::move(Diags), std::move(Includes), std::move(PI));
753 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
754 std::back_inserter(Result.Diags));
755 return std::move(Result);
758ParsedAST::ParsedAST(ParsedAST &&Other) =
default;
760ParsedAST &ParsedAST::operator=(ParsedAST &&Other) =
default;
762ParsedAST::~ParsedAST() {
766 auto PP =
Clang->getPreprocessorPtr();
767 Clang->setPreprocessor(
nullptr);
773ASTContext &ParsedAST::getASTContext() {
return Clang->getASTContext(); }
775const ASTContext &ParsedAST::getASTContext()
const {
776 return Clang->getASTContext();
779Sema &ParsedAST::getSema() {
return Clang->getSema(); }
781Preprocessor &ParsedAST::getPreprocessor() {
return Clang->getPreprocessor(); }
783std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
784 return Clang->getPreprocessorPtr();
787const Preprocessor &ParsedAST::getPreprocessor()
const {
788 return Clang->getPreprocessor();
791llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
792 return LocalTopLevelDecls;
795llvm::ArrayRef<const Decl *> ParsedAST::getLocalTopLevelDecls()
const {
796 return LocalTopLevelDecls;
800const std::vector<PragmaMark> &ParsedAST::getMarks()
const {
return Marks; }
802std::size_t ParsedAST::getUsedBytes()
const {
803 auto &AST = getASTContext();
807 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
813 Total += AST.getASTAllocatedMemory();
814 Total += AST.getSideTableAllocatedMemory();
815 Total += AST.Idents.getAllocator().getTotalMemory();
816 Total += AST.Selectors.getTotalMemory();
818 Total += AST.getSourceManager().getContentCacheSize();
819 Total += AST.getSourceManager().getDataStructureSizes();
820 Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
822 if (ExternalASTSource *Ext = AST.getExternalSource())
823 Total += Ext->getMemoryBufferSizes().malloc_bytes;
825 const Preprocessor &PP = getPreprocessor();
826 Total += PP.getTotalMemory();
827 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
828 Total += PRec->getTotalMemory();
829 Total += PP.getHeaderSearchInfo().getTotalMemory();
838ParsedAST::ParsedAST(
PathRef TUPath, llvm::StringRef Version,
839 std::shared_ptr<const PreambleData>
Preamble,
840 std::unique_ptr<CompilerInstance>
Clang,
841 std::unique_ptr<FrontendAction>
Action,
843 std::vector<PragmaMark> Marks,
844 std::vector<Decl *> LocalTopLevelDecls,
846 include_cleaner::PragmaIncludes PI)
849 Tokens(std::move(Tokens)), Macros(std::move(Macros)),
850 Marks(std::move(Marks)), Diags(std::move(Diags)),
851 LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
852 Includes(std::move(Includes)), PI(std::move(PI)),
855 assert(this->Action);
865 return llvm::StringRef(Preamble->Version);
const FunctionDecl * Decl
const std::optional< PreamblePatch > Patch
const PreambleData & Preamble
Include Cleaner is clangd functionality for providing diagnostics for misuse of transitive headers an...
std::string Filename
Filename as a string.
const MacroDirective * Directive
DiagnosticConsumer DiagConsumer
const google::protobuf::Message & M
std::unique_ptr< CompilerInvocation > CI
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
std::vector< Inclusion > MainFileIncludes
void collect(const CompilerInstance &CI)
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.
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
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.
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.
@ 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)
bool isBuiltinDiagnosticSuppressed(unsigned ID, const llvm::StringSet<> &Suppress, const LangOptions &LangOpts)
Determine whether a (non-clang-tidy) diagnostic is suppressed by config.
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::vector< Diag > issueIncludeCleanerDiagnostics(ParsedAST &AST, llvm::StringRef Code, const IncludeCleanerFindings &Findings, const ThreadsafeFS &TFS, HeaderFilter IgnoreHeaders)
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)
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....
llvm::StringRef PathRef
A typedef to represent a ref to file path.
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::@4::@13 Includes
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
std::vector< std::function< bool(llvm::StringRef)> > IgnoreHeader
IncludeCleaner will not diagnose usages of these headers matched by these regexes.
IncludesPolicy UnusedIncludes
bool AnalyzeAngledIncludes
IncludesPolicy MissingIncludes
struct clang::clangd::Config::@4 Diagnostics
Controls warnings and errors when parsing code.
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.