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, 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.startswith(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) {
367 bool SuppressMissing =
370 bool SuppressUnused =
373 if (SuppressMissing && SuppressUnused)
377 Findings.MissingIncludes.clear();
379 Findings.UnusedIncludes.clear();
384tidy::ClangTidyCheckFactories
385filterFastTidyChecks(
const tidy::ClangTidyCheckFactories &
All,
390 tidy::ClangTidyCheckFactories Fast;
391 for (
const auto &Factory :
All) {
393 Fast.registerCheckFactory(Factory.first(), Factory.second);
400std::optional<ParsedAST>
402 std::unique_ptr<clang::CompilerInvocation>
CI,
403 llvm::ArrayRef<Diag> CompilerInvocationDiags,
404 std::shared_ptr<const PreambleData>
Preamble) {
409 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
411 VFS =
Preamble->StatCache->getConsumingFS(std::move(VFS));
415 if (
CI->getFrontendOpts().Inputs.size() > 0) {
416 auto Lang =
CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
417 if (
Lang == Language::Asm ||
Lang == Language::LLVM_IR) {
418 elog(
"Clangd does not support assembly or IR source files");
425 CI->getFrontendOpts().DisableFree =
false;
426 const PrecompiledPreamble *PreamblePCH =
431 CI->getLangOpts().DelayedTemplateParsing =
false;
433 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
434 if (Inputs.FeatureModules) {
435 for (
auto &
M : *Inputs.FeatureModules) {
436 if (
auto Listener =
M.astListeners())
437 ASTListeners.emplace_back(std::move(Listener));
443 for (
const auto &L : ASTListeners)
444 L->sawDiagnostic(D,
Diag);
447 std::optional<PreamblePatch>
Patch;
457 std::move(
CI), PreamblePCH,
458 llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents,
Filename), VFS,
463 std::vector<Diag> Diags(ASTDiags.
take());
464 elog(
"Failed to prepare a compiler instance: {0}",
473 dlog(
"ClangTidy configuration for file {0}: {1}",
Filename,
494 auto &Diags =
Clang->getDiagnostics();
495 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.
Checks ? *ClangTidyOpts.
Checks
496 : llvm::StringRef());
498 applyWarningOptions(*ClangTidyOpts.
ExtraArgsBefore, TidyGroups, Diags);
500 applyWarningOptions(*ClangTidyOpts.
ExtraArgs, TidyGroups, Diags);
503 auto Action = std::make_unique<ClangdFrontendAction>();
504 const FrontendInputFile &MainInput =
Clang->getFrontendOpts().Inputs[0];
505 if (!Action->BeginSourceFile(*
Clang, MainInput)) {
506 log(
"BeginSourceFile() failed when building AST for {0}",
507 MainInput.getFile());
516 const SourceManager &SM =
Clang->getSourceManager();
517 OptionalFileEntryRef MainFE = SM.getFileEntryRefForID(SM.getMainFileID());
518 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(*MainFE);
527 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
528 ast_matchers::MatchFinder CTFinder;
529 std::optional<tidy::ClangTidyContext> CTContext;
531 auto BuildDir = VFS->getCurrentWorkingDirectory();
532 std::optional<IncludeFixer> FixIncludes;
533 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
538 static const auto *AllCTFactories = [] {
540 for (
const auto &
E : tidy::ClangTidyModuleRegistry::entries())
541 E.instantiate()->addCheckFactories(*CTFactories);
545 *AllCTFactories, Cfg.Diagnostics.ClangTidy.FastCheckFilter);
546 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
548 CTContext->setDiagnosticsEngine(&
Clang->getDiagnostics());
549 CTContext->setASTContext(&
Clang->getASTContext());
550 CTContext->setCurrentFile(
Filename);
551 CTContext->setSelfContainedDiags(
true);
553 Preprocessor *PP = &
Clang->getPreprocessor();
554 for (
const auto &Check : CTChecks) {
555 Check->registerPPCallbacks(
Clang->getSourceManager(), PP, PP);
556 Check->registerMatchers(&CTFinder);
564 for (
auto ID : {diag::ext_implicit_function_decl_c99,
565 diag::ext_implicit_lib_function_decl,
566 diag::ext_implicit_lib_function_decl_c99,
567 diag::warn_implicit_function_decl}) {
568 OverriddenSeverity.try_emplace(
569 ID,
Clang->getDiagnostics().getDiagnosticLevel(
ID, SourceLocation()));
570 Clang->getDiagnostics().setSeverity(
ID, diag::Severity::Error,
575 const clang::Diagnostic &
Info) {
576 if (Cfg.Diagnostics.SuppressAll ||
578 Clang->getLangOpts()))
579 return DiagnosticsEngine::Ignored;
581 auto It = OverriddenSeverity.find(
Info.getID());
582 if (It != OverriddenSeverity.end())
583 DiagLevel = It->second;
585 if (!CTChecks.empty()) {
586 std::string CheckName = CTContext->getCheckName(Info.getID());
587 bool IsClangTidyDiag = !CheckName.empty();
588 if (IsClangTidyDiag) {
589 if (Cfg.Diagnostics.Suppress.contains(CheckName))
590 return DiagnosticsEngine::Ignored;
597 bool IsInsideMainFile =
598 Info.hasSourceManager() &&
599 isInsideMainFile(Info.getLocation(), Info.getSourceManager());
600 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors;
601 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
602 DiagLevel, Info, TidySuppressedErrors,
607 return DiagnosticsEngine::Ignored;
609 if (!CTContext->getOptions().SystemHeaders.value_or(false) &&
610 Info.hasSourceManager() &&
611 Info.getSourceManager().isInSystemMacro(Info.getLocation()))
612 return DiagnosticsEngine::Ignored;
615 if (DiagLevel == DiagnosticsEngine::Warning &&
616 CTContext->treatAsError(CheckName)) {
617 return DiagnosticsEngine::Error;
626 if (Inputs.Index && !BuildDir.getError()) {
629 auto Inserter = std::make_shared<IncludeInserter>(
630 Filename, Inputs.Contents, Style, BuildDir.get(),
631 &
Clang->getPreprocessor().getHeaderSearchInfo());
632 ArrayRef<Inclusion> MainFileIncludes;
634 MainFileIncludes =
Preamble->Includes.MainFileIncludes;
635 for (
const auto &Inc :
Preamble->Includes.MainFileIncludes)
636 Inserter->addExisting(Inc);
641 Inputs.Opts.ImportInsertions
643 MainFileIncludes, {})
645 FixIncludes.emplace(
Filename, Inserter, *Inputs.Index,
647 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
648 const clang::Diagnostic &
Info) {
649 return FixIncludes->fix(DiagLevl,
Info);
651 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
661 ReplayPreamble::attach(
Patch->preambleIncludes(), *
Clang,
662 Patch->modifiedBounds());
670 MainFileMacros Macros;
671 std::vector<PragmaMark> Marks;
673 Macros =
Patch->mainFileMacros();
674 Marks =
Patch->marks();
676 auto &PP =
Clang->getPreprocessor();
677 PP.addPPCallbacks(std::make_unique<CollectMainFileMacros>(PP, Macros));
686 syntax::TokenCollector CollectTokens(PP);
691 for (
const auto &L : ASTListeners)
692 L->beforeExecute(*
Clang);
694 if (llvm::Error Err =
Action->Execute())
695 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
701 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
703 Tokens.indexExpandedTokens();
704 std::vector<Decl *> ParsedDecls =
Action->takeTopLevelDecls();
706 Clang->getASTContext().setTraversalScope(ParsedDecls);
707 if (!CTChecks.empty()) {
710 trace::Span Tracer(
"ClangTidyMatch");
711 CTFinder.matchAST(
Clang->getASTContext());
720 Clang->getDiagnostics().setClient(
new IgnoreDiagnostics);
722 ASTDiags.EndSourceFile();
724 std::vector<Diag> Diags = CompilerInvocationDiags;
729 llvm::append_range(Diags,
Patch->patchedDiags());
732 std::vector<Diag> D = ASTDiags.take(&*CTContext);
733 Diags.insert(Diags.end(), D.begin(), D.end());
736 std::move(
Clang), std::move(
Action), std::move(Tokens),
737 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
738 std::move(Diags), std::move(Includes));
739 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents),
740 std::back_inserter(Result.Diags));
741 return std::move(Result);
744ParsedAST::ParsedAST(ParsedAST &&Other) =
default;
746ParsedAST &ParsedAST::operator=(ParsedAST &&Other) =
default;
748ParsedAST::~ParsedAST() {
752 auto PP =
Clang->getPreprocessorPtr();
753 Clang->setPreprocessor(
nullptr);
759ASTContext &ParsedAST::getASTContext() {
return Clang->getASTContext(); }
761const ASTContext &ParsedAST::getASTContext()
const {
762 return Clang->getASTContext();
765Sema &ParsedAST::getSema() {
return Clang->getSema(); }
767Preprocessor &ParsedAST::getPreprocessor() {
return Clang->getPreprocessor(); }
769std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
770 return Clang->getPreprocessorPtr();
773const Preprocessor &ParsedAST::getPreprocessor()
const {
774 return Clang->getPreprocessor();
777llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
778 return LocalTopLevelDecls;
781llvm::ArrayRef<const Decl *> ParsedAST::getLocalTopLevelDecls()
const {
782 return LocalTopLevelDecls;
786const std::vector<PragmaMark> &ParsedAST::getMarks()
const {
return Marks; }
788std::size_t ParsedAST::getUsedBytes()
const {
789 auto &AST = getASTContext();
793 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
799 Total += AST.getASTAllocatedMemory();
800 Total += AST.getSideTableAllocatedMemory();
801 Total += AST.Idents.getAllocator().getTotalMemory();
802 Total += AST.Selectors.getTotalMemory();
804 Total += AST.getSourceManager().getContentCacheSize();
805 Total += AST.getSourceManager().getDataStructureSizes();
806 Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
808 if (ExternalASTSource *Ext = AST.getExternalSource())
809 Total += Ext->getMemoryBufferSizes().malloc_bytes;
811 const Preprocessor &PP = getPreprocessor();
812 Total += PP.getTotalMemory();
813 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
814 Total += PRec->getTotalMemory();
815 Total += PP.getHeaderSearchInfo().getTotalMemory();
824ParsedAST::ParsedAST(
PathRef TUPath, llvm::StringRef Version,
825 std::shared_ptr<const PreambleData>
Preamble,
826 std::unique_ptr<CompilerInstance>
Clang,
827 std::unique_ptr<FrontendAction>
Action,
829 std::vector<PragmaMark> Marks,
830 std::vector<Decl *> LocalTopLevelDecls,
834 Tokens(std::move(Tokens)), Macros(std::move(Macros)),
835 Marks(std::move(Marks)), Diags(std::move(Diags)),
836 LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
837 Includes(std::move(Includes)) {
838 Resolver = std::make_unique<HeuristicResolver>(
getASTContext());
840 assert(this->Action);
843std::shared_ptr<const include_cleaner::PragmaIncludes>
853 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
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.
std::shared_ptr< const include_cleaner::PragmaIncludes > getPragmaIncludes() const
Returns the PramaIncludes from the preamble.
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
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.
format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, const ThreadsafeFS &TFS)
Choose the clang-format style we should apply to a certain file.
IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST)
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, 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)
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)
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
IncludeCleaner will not diagnose usages of these headers matched by these regexes.
static const Config & current()
Returns the Config of the current Context, or an empty configuration.
std::vector< std::function< bool(llvm::StringRef)> > IgnoreHeader
IncludesPolicy UnusedIncludes
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.