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/Preprocessor.h"
54#include "clang/Sema/HeuristicResolver.h"
55#include "clang/Serialization/ASTWriter.h"
56#include "clang/Tooling/CompilationDatabase.h"
57#include "clang/Tooling/Core/Diagnostic.h"
58#include "clang/Tooling/Syntax/Tokens.h"
59#include "llvm/ADT/ArrayRef.h"
60#include "llvm/ADT/DenseMap.h"
61#include "llvm/ADT/DenseSet.h"
62#include "llvm/ADT/STLExtras.h"
63#include "llvm/ADT/STLFunctionalExtras.h"
64#include "llvm/ADT/SmallVector.h"
65#include "llvm/ADT/StringRef.h"
66#include "llvm/Support/Error.h"
67#include "llvm/Support/MemoryBuffer.h"
81#define CLANG_TIDY_DISABLE_STATIC_ANALYZER_CHECKS
89template <
class T> std::size_t getUsedBytes(
const std::vector<T> &Vec) {
90 return Vec.capacity() *
sizeof(
T);
93class DeclTrackingASTConsumer :
public ASTConsumer {
95 DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
96 : TopLevelDecls(TopLevelDecls) {}
98 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
100 auto &SM =
D->getASTContext().getSourceManager();
103 if (
const NamedDecl *ND = dyn_cast<NamedDecl>(D))
108 if (isa<ObjCMethodDecl>(D))
111 TopLevelDecls.push_back(D);
117 std::vector<Decl *> &TopLevelDecls;
120class ClangdFrontendAction :
public SyntaxOnlyAction {
122 std::vector<Decl *> takeTopLevelDecls() {
return std::move(TopLevelDecls); }
125 std::unique_ptr<ASTConsumer>
126 CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile)
override {
127 return std::make_unique<DeclTrackingASTConsumer>( TopLevelDecls);
131 std::vector<Decl *> TopLevelDecls;
140class ReplayPreamble :
private PPCallbacks {
145 static void attach(std::vector<Inclusion> Includes, CompilerInstance &Clang,
146 const PreambleBounds &PB) {
147 auto &PP = Clang.getPreprocessor();
148 auto *ExistingCallbacks = PP.getPPCallbacks();
150 if (!ExistingCallbacks)
152 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
new ReplayPreamble(
153 std::move(Includes), ExistingCallbacks, Clang.getSourceManager(), PP,
154 Clang.getLangOpts(), PB)));
157 assert(PP.getPPCallbacks() != ExistingCallbacks &&
158 "Expected chaining implementation");
162 ReplayPreamble(std::vector<Inclusion> Includes, PPCallbacks *Delegate,
163 const SourceManager &SM, Preprocessor &PP,
164 const LangOptions &LangOpts,
const PreambleBounds &PB)
165 : Includes(std::move(Includes)), Delegate(Delegate), SM(SM), PP(PP) {
168 MainFileTokens = syntax::tokenize(
169 syntax::FileRange(SM.getMainFileID(), 0, PB.Size), SM, LangOpts);
187 void FileChanged(SourceLocation Loc, FileChangeReason Reason,
188 SrcMgr::CharacteristicKind Kind, FileID PrevFID)
override {
190 if (Reason == FileChangeReason::ExitFile &&
191 SM.getBufferOrFake(PrevFID).getBufferIdentifier() ==
"<built-in>")
196 for (
const auto &Inc : Includes) {
197 OptionalFileEntryRef
File;
198 if (Inc.Resolved !=
"")
199 File = expectedToOptional(SM.getFileManager().getFileRef(Inc.Resolved));
202 auto HashLoc = SM.getComposedLoc(SM.getMainFileID(), Inc.HashOffset);
203 auto HashTok = llvm::partition_point(MainFileTokens,
204 [&HashLoc](
const syntax::Token &T) {
205 return T.location() < HashLoc;
207 assert(HashTok != MainFileTokens.end() && HashTok->kind() == tok::hash);
209 auto IncludeTok = std::next(HashTok);
210 assert(IncludeTok != MainFileTokens.end());
212 auto FileTok = std::next(IncludeTok);
213 assert(FileTok != MainFileTokens.end());
217 Token SynthesizedIncludeTok;
218 SynthesizedIncludeTok.startToken();
219 SynthesizedIncludeTok.setLocation(IncludeTok->location());
220 SynthesizedIncludeTok.setLength(IncludeTok->length());
221 SynthesizedIncludeTok.setKind(tok::raw_identifier);
222 SynthesizedIncludeTok.setRawIdentifierData(IncludeTok->text(SM).data());
223 PP.LookUpIdentifierInfo(SynthesizedIncludeTok);
226 Token SynthesizedFilenameTok;
227 SynthesizedFilenameTok.startToken();
228 SynthesizedFilenameTok.setLocation(FileTok->location());
233 SynthesizedFilenameTok.setLength(Inc.Written.length());
234 SynthesizedFilenameTok.setKind(tok::header_name);
235 SynthesizedFilenameTok.setLiteralData(Inc.Written.data());
237 llvm::StringRef WrittenFilename =
238 llvm::StringRef(Inc.Written).drop_front().drop_back();
239 Delegate->InclusionDirective(
240 HashTok->location(), SynthesizedIncludeTok, WrittenFilename,
241 Inc.Written.front() ==
'<',
242 syntax::FileRange(SM, SynthesizedFilenameTok.getLocation(),
243 SynthesizedFilenameTok.getEndLoc())
245 File,
"SearchPath",
"RelPath",
246 nullptr,
false, Inc.FileKind);
248 Delegate->FileSkipped(*
File, SynthesizedFilenameTok, Inc.FileKind);
252 const std::vector<Inclusion> Includes;
253 PPCallbacks *Delegate;
254 const SourceManager &SM;
256 std::vector<syntax::Token> MainFileTokens;
267class TidyDiagnosticGroups {
270 bool Default =
false;
273 llvm::DenseSet<unsigned> Exceptions;
276 TidyDiagnosticGroups(llvm::StringRef
Checks) {
277 constexpr llvm::StringLiteral CDPrefix =
"clang-diagnostic-";
279 llvm::StringRef Check;
282 Check = Check.trim();
287 bool Enable = !Check.consume_front(
"-");
288 bool Glob = Check.consume_back(
"*");
292 if (CDPrefix.starts_with(Check)) {
300 if (Default == Enable)
303 if (!Check.consume_front(CDPrefix))
306 if (
auto Group = DiagnosticIDs::getGroupForWarningOption(Check))
307 Exceptions.insert(
static_cast<unsigned>(*Group));
311 bool operator()(diag::Group GroupID)
const {
312 return Exceptions.contains(
static_cast<unsigned>(GroupID)) ? !Default
322void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
323 llvm::function_ref<
bool(diag::Group)> EnabledGroups,
324 DiagnosticsEngine &Diags) {
325 for (llvm::StringRef Group : ExtraArgs) {
328 llvm::SmallVector<diag::kind> Members;
329 if (!Group.consume_front(
"-W") || Group.empty())
331 bool Enable = !Group.consume_front(
"no-");
332 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
333 diag::Flavor::WarningOrError, Group, Members))
339 bool NeedsWerrorExclusion =
false;
340 for (diag::kind ID : Members) {
342 if (Diags.getDiagnosticLevel(ID, SourceLocation()) <
343 DiagnosticsEngine::Warning) {
344 auto Group = Diags.getDiagnosticIDs()->getGroupForDiag(ID);
345 if (!Group || !EnabledGroups(*Group))
347 Diags.setSeverity(ID, diag::Severity::Warning, SourceLocation());
348 if (Diags.getWarningsAsErrors())
349 NeedsWerrorExclusion =
true;
352 Diags.setSeverity(ID, diag::Severity::Ignored, SourceLocation());
355 if (NeedsWerrorExclusion) {
359 Diags.setDiagnosticGroupWarningAsError(Group,
false);
364std::vector<Diag> getIncludeCleanerDiags(
ParsedAST &
AST, llvm::StringRef Code,
367 if (Cfg.Diagnostics.SuppressAll)
369 bool SuppressMissing =
370 Cfg.Diagnostics.Suppress.contains(
"missing-includes") ||
372 bool SuppressUnused =
373 Cfg.Diagnostics.Suppress.contains(
"unused-includes") ||
375 if (SuppressMissing && SuppressUnused)
378 AST, Cfg.Diagnostics.Includes.AnalyzeAngledIncludes);
380 Findings.MissingIncludes.clear();
382 Findings.UnusedIncludes.clear();
384 AST, Code, Findings, TFS, Cfg.Diagnostics.Includes.IgnoreHeader,
385 Cfg.Style.AngledHeaders, Cfg.Style.QuotedHeaders);
388tidy::ClangTidyCheckFactories
389filterFastTidyChecks(
const tidy::ClangTidyCheckFactories &
All,
394 tidy::ClangTidyCheckFactories Fast;
395 for (
const auto &Factory :
All) {
397 Fast.registerCheckFactory(Factory.first(), Factory.second);
404std::optional<ParsedAST>
406 std::unique_ptr<clang::CompilerInvocation> CI,
407 llvm::ArrayRef<Diag> CompilerInvocationDiags,
408 std::shared_ptr<const PreambleData> Preamble) {
414 if (Preamble && Preamble->StatCache)
415 VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
419 if (CI->getFrontendOpts().Inputs.size() > 0) {
420 auto Lang = CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
421 if (Lang == Language::Asm || Lang == Language::LLVM_IR) {
422 elog(
"Clangd does not support assembly or IR source files");
429 CI->getFrontendOpts().DisableFree =
false;
430 const PrecompiledPreamble *PreamblePCH =
431 Preamble ? &Preamble->Preamble :
nullptr;
435 CI->getLangOpts().DelayedTemplateParsing =
false;
437 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
440 if (
auto Listener = M.astListeners())
441 ASTListeners.emplace_back(std::move(Listener));
447 for (
const auto &L : ASTListeners)
448 L->sawDiagnostic(D,
Diag);
453 if (Preamble && Preamble->RequiredModules)
454 Preamble->RequiredModules->adjustHeaderSearchOptions(
455 CI->getHeaderSearchOpts());
457 std::optional<PreamblePatch> Patch;
467 std::move(CI), PreamblePCH,
468 llvm::MemoryBuffer::getMemBufferCopy(Inputs.
Contents, Filename), VFS,
474 std::vector<Diag> Diags(ASTDiags.
take());
475 elog(
"Failed to prepare a compiler instance: {0}",
484 dlog(
"ClangTidy configuration for file {0}: {1}", Filename,
505 auto &Diags = Clang->getDiagnostics();
506 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.
Checks ? *ClangTidyOpts.
Checks
507 : llvm::StringRef());
509 applyWarningOptions(*ClangTidyOpts.
ExtraArgsBefore, TidyGroups, Diags);
511 applyWarningOptions(*ClangTidyOpts.
ExtraArgs, TidyGroups, Diags);
514 auto Action = std::make_unique<ClangdFrontendAction>();
515 const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
516 if (!Action->BeginSourceFile(*Clang, MainInput)) {
517 elog(
"BeginSourceFile() failed when building AST for {0}",
518 MainInput.getFile());
526 if (Preamble && Preamble->MainIsIncludeGuarded) {
527 const SourceManager &SM = Clang->getSourceManager();
528 OptionalFileEntryRef MainFE = SM.getFileEntryRefForID(SM.getMainFileID());
529 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(*MainFE);
538 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
539 ast_matchers::MatchFinder CTFinder;
540 std::optional<tidy::ClangTidyContext> CTContext;
542 auto BuildDir = VFS->getCurrentWorkingDirectory();
543 std::optional<IncludeFixer> FixIncludes;
544 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
549 static const auto *AllCTFactories = [] {
551 for (
const auto &E : tidy::ClangTidyModuleRegistry::entries())
552 E.instantiate()->addCheckFactories(*CTFactories);
557 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
560 CTContext->setDiagnosticsEngine(
nullptr, &Clang->getDiagnostics());
561 CTContext->setASTContext(&Clang->getASTContext());
562 CTContext->setCurrentFile(Filename);
563 CTContext->setSelfContainedDiags(
true);
565 Preprocessor *PP = &Clang->getPreprocessor();
566 for (
const auto &Check : CTChecks) {
567 Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
568 Check->registerMatchers(&CTFinder);
576 for (
auto ID : {diag::ext_implicit_function_decl_c99,
577 diag::ext_implicit_lib_function_decl,
578 diag::ext_implicit_lib_function_decl_c99,
579 diag::warn_implicit_function_decl}) {
580 OverriddenSeverity.try_emplace(
581 ID, Clang->getDiagnostics().getDiagnosticLevel(ID, SourceLocation()));
582 Clang->getDiagnostics().setSeverity(ID, diag::Severity::Error,
587 const clang::Diagnostic &
Info) {
590 Clang->getLangOpts()))
591 return DiagnosticsEngine::Ignored;
593 auto It = OverriddenSeverity.find(
Info.getID());
594 if (It != OverriddenSeverity.end())
595 DiagLevel = It->second;
597 if (!CTChecks.empty()) {
598 std::string CheckName = CTContext->getCheckName(
Info.getID());
599 bool IsClangTidyDiag = !CheckName.empty();
600 if (IsClangTidyDiag) {
602 return DiagnosticsEngine::Ignored;
609 bool IsInsideMainFile =
610 Info.hasSourceManager() &&
612 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors;
613 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
614 DiagLevel,
Info, TidySuppressedErrors,
619 return DiagnosticsEngine::Ignored;
621 if (!CTContext->getOptions().SystemHeaders.value_or(
false) &&
622 Info.hasSourceManager() &&
623 Info.getSourceManager().isInSystemMacro(
Info.getLocation()))
624 return DiagnosticsEngine::Ignored;
627 if (DiagLevel == DiagnosticsEngine::Warning &&
628 CTContext->treatAsError(CheckName)) {
629 return DiagnosticsEngine::Error;
638 if (Inputs.
Index && !BuildDir.getError()) {
641 auto Inserter = std::make_shared<IncludeInserter>(
642 Filename, Inputs.
Contents, Style, BuildDir.get(),
643 &Clang->getPreprocessor().getHeaderSearchInfo(),
645 ArrayRef<Inclusion> MainFileIncludes;
647 MainFileIncludes = Preamble->Includes.MainFileIncludes;
648 for (
const auto &Inc : Preamble->Includes.MainFileIncludes)
649 Inserter->addExisting(Inc);
656 MainFileIncludes, {})
658 FixIncludes.emplace(Filename, Inserter, *Inputs.
Index,
660 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
661 const clang::Diagnostic &
Info) {
662 return FixIncludes->fix(DiagLevl,
Info);
664 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
669 include_cleaner::PragmaIncludes PI;
672 Includes = Preamble->Includes;
673 Includes.MainFileIncludes = Patch->preambleIncludes();
675 ReplayPreamble::attach(Patch->preambleIncludes(), *Clang,
676 Patch->modifiedBounds());
677 PI = *Preamble->Pragmas;
689 std::vector<PragmaMark> Marks;
691 Macros = Patch->mainFileMacros();
692 Marks = Patch->marks();
694 auto &PP = Clang->getPreprocessor();
695 auto MacroCollector = std::make_unique<CollectMainFileMacros>(PP, Macros);
696 auto *MacroCollectorPtr = MacroCollector.get();
697 PP.addPPCallbacks(std::move(MacroCollector));
706 syntax::TokenCollector CollectTokens(PP);
711 for (
const auto &L : ASTListeners)
712 L->beforeExecute(*Clang);
714 if (llvm::Error Err = Action->Execute())
715 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
720 MacroCollectorPtr->doneParse();
725 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
727 Tokens.indexExpandedTokens();
728 std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls();
730 Clang->getASTContext().setTraversalScope(ParsedDecls);
731 if (!CTChecks.empty()) {
735 CTFinder.matchAST(Clang->getASTContext());
748 std::vector<Diag> Diags = CompilerInvocationDiags;
753 llvm::append_range(Diags, Patch->patchedDiags());
756 std::vector<Diag> D = ASTDiags.
take(&*CTContext);
757 Diags.insert(Diags.end(), D.begin(), D.end());
760 std::move(Clang), std::move(Action), std::move(Tokens),
761 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
762 std::move(Diags), std::move(Includes), std::move(PI));
763 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
764 std::back_inserter(Result.Diags));
765 return std::move(Result);
776 auto PP = Clang->getPreprocessorPtr();
777 Clang->setPreprocessor(
nullptr);
778 Action->EndSourceFile();
786 return Clang->getASTContext();
794 return Clang->getPreprocessorPtr();
798 return Clang->getPreprocessor();
802 return LocalTopLevelDecls;
806 return LocalTopLevelDecls;
817 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
823 Total +=
AST.getASTAllocatedMemory();
824 Total +=
AST.getSideTableAllocatedMemory();
825 Total +=
AST.Idents.getAllocator().getTotalMemory();
826 Total +=
AST.Selectors.getTotalMemory();
828 Total +=
AST.getSourceManager().getContentCacheSize();
829 Total +=
AST.getSourceManager().getDataStructureSizes();
830 Total +=
AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
832 if (ExternalASTSource *Ext =
AST.getExternalSource())
833 Total += Ext->getMemoryBufferSizes().malloc_bytes;
836 Total += PP.getTotalMemory();
837 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
838 Total += PRec->getTotalMemory();
839 Total += PP.getHeaderSearchInfo().getTotalMemory();
849 std::shared_ptr<const PreambleData>
Preamble,
850 std::unique_ptr<CompilerInstance> Clang,
851 std::unique_ptr<FrontendAction> Action,
853 std::vector<PragmaMark> Marks,
854 std::vector<Decl *> LocalTopLevelDecls,
856 include_cleaner::PragmaIncludes PI)
858 Clang(std::
move(Clang)), Action(std::
move(Action)),
859 Tokens(std::
move(Tokens)), Macros(std::
move(Macros)),
860 Marks(std::
move(Marks)), Diags(std::
move(Diags)),
861 LocalTopLevelDecls(std::
move(LocalTopLevelDecls)),
862 Includes(std::
move(Includes)), PI(std::
move(PI)),
863 Resolver(std::make_unique<HeuristicResolver>(getASTContext())) {
865 assert(this->Action);
875 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::@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
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.