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)
378 Findings.MissingIncludes.clear();
380 Findings.UnusedIncludes.clear();
385tidy::ClangTidyCheckFactories
386filterFastTidyChecks(
const tidy::ClangTidyCheckFactories &
All,
391 tidy::ClangTidyCheckFactories Fast;
392 for (
const auto &Factory :
All) {
394 Fast.registerCheckFactory(Factory.first(), Factory.second);
401std::optional<ParsedAST>
403 std::unique_ptr<clang::CompilerInvocation>
CI,
404 llvm::ArrayRef<Diag> CompilerInvocationDiags,
405 std::shared_ptr<const PreambleData>
Preamble) {
410 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
412 VFS =
Preamble->StatCache->getConsumingFS(std::move(VFS));
416 if (
CI->getFrontendOpts().Inputs.size() > 0) {
417 auto Lang =
CI->getFrontendOpts().Inputs[0].getKind().getLanguage();
418 if (
Lang == Language::Asm ||
Lang == Language::LLVM_IR) {
419 elog(
"Clangd does not support assembly or IR source files");
426 CI->getFrontendOpts().DisableFree =
false;
427 const PrecompiledPreamble *PreamblePCH =
432 CI->getLangOpts().DelayedTemplateParsing =
false;
434 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
435 if (Inputs.FeatureModules) {
436 for (
auto &
M : *Inputs.FeatureModules) {
437 if (
auto Listener =
M.astListeners())
438 ASTListeners.emplace_back(std::move(Listener));
444 for (
const auto &L : ASTListeners)
445 L->sawDiagnostic(D,
Diag);
448 std::optional<PreamblePatch>
Patch;
458 std::move(
CI), PreamblePCH,
459 llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents,
Filename), VFS,
464 std::vector<Diag> Diags(ASTDiags.
take());
465 elog(
"Failed to prepare a compiler instance: {0}",
474 dlog(
"ClangTidy configuration for file {0}: {1}",
Filename,
495 auto &Diags =
Clang->getDiagnostics();
496 TidyDiagnosticGroups TidyGroups(ClangTidyOpts.
Checks ? *ClangTidyOpts.
Checks
497 : llvm::StringRef());
499 applyWarningOptions(*ClangTidyOpts.
ExtraArgsBefore, TidyGroups, Diags);
501 applyWarningOptions(*ClangTidyOpts.
ExtraArgs, TidyGroups, Diags);
504 auto Action = std::make_unique<ClangdFrontendAction>();
505 const FrontendInputFile &MainInput =
Clang->getFrontendOpts().Inputs[0];
506 if (!Action->BeginSourceFile(*
Clang, MainInput)) {
507 log(
"BeginSourceFile() failed when building AST for {0}",
508 MainInput.getFile());
517 const SourceManager &SM =
Clang->getSourceManager();
518 OptionalFileEntryRef MainFE = SM.getFileEntryRefForID(SM.getMainFileID());
519 Clang->getPreprocessor().getHeaderSearchInfo().MarkFileIncludeOnce(*MainFE);
528 std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
529 ast_matchers::MatchFinder CTFinder;
530 std::optional<tidy::ClangTidyContext> CTContext;
532 auto BuildDir = VFS->getCurrentWorkingDirectory();
533 std::optional<IncludeFixer> FixIncludes;
534 llvm::DenseMap<diag::kind, DiagnosticsEngine::Level> OverriddenSeverity;
539 static const auto *AllCTFactories = [] {
541 for (
const auto &
E : tidy::ClangTidyModuleRegistry::entries())
542 E.instantiate()->addCheckFactories(*CTFactories);
546 *AllCTFactories, Cfg.Diagnostics.ClangTidy.FastCheckFilter);
547 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
549 CTContext->setDiagnosticsEngine(&
Clang->getDiagnostics());
550 CTContext->setASTContext(&
Clang->getASTContext());
551 CTContext->setCurrentFile(
Filename);
552 CTContext->setSelfContainedDiags(
true);
554 Preprocessor *PP = &
Clang->getPreprocessor();
555 for (
const auto &Check : CTChecks) {
556 Check->registerPPCallbacks(
Clang->getSourceManager(), PP, PP);
557 Check->registerMatchers(&CTFinder);
565 for (
auto ID : {diag::ext_implicit_function_decl_c99,
566 diag::ext_implicit_lib_function_decl,
567 diag::ext_implicit_lib_function_decl_c99,
568 diag::warn_implicit_function_decl}) {
569 OverriddenSeverity.try_emplace(
570 ID,
Clang->getDiagnostics().getDiagnosticLevel(
ID, SourceLocation()));
571 Clang->getDiagnostics().setSeverity(
ID, diag::Severity::Error,
576 const clang::Diagnostic &
Info) {
577 if (Cfg.Diagnostics.SuppressAll ||
579 Clang->getLangOpts()))
580 return DiagnosticsEngine::Ignored;
582 auto It = OverriddenSeverity.find(
Info.getID());
583 if (It != OverriddenSeverity.end())
584 DiagLevel = It->second;
586 if (!CTChecks.empty()) {
587 std::string CheckName = CTContext->getCheckName(Info.getID());
588 bool IsClangTidyDiag = !CheckName.empty();
589 if (IsClangTidyDiag) {
590 if (Cfg.Diagnostics.Suppress.contains(CheckName))
591 return DiagnosticsEngine::Ignored;
598 bool IsInsideMainFile =
599 Info.hasSourceManager() &&
600 isInsideMainFile(Info.getLocation(), Info.getSourceManager());
601 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors;
602 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
603 DiagLevel, Info, TidySuppressedErrors,
608 return DiagnosticsEngine::Ignored;
610 if (!CTContext->getOptions().SystemHeaders.value_or(false) &&
611 Info.hasSourceManager() &&
612 Info.getSourceManager().isInSystemMacro(Info.getLocation()))
613 return DiagnosticsEngine::Ignored;
616 if (DiagLevel == DiagnosticsEngine::Warning &&
617 CTContext->treatAsError(CheckName)) {
618 return DiagnosticsEngine::Error;
627 if (Inputs.Index && !
BuildDir.getError()) {
630 auto Inserter = std::make_shared<IncludeInserter>(
632 &
Clang->getPreprocessor().getHeaderSearchInfo());
633 ArrayRef<Inclusion> MainFileIncludes;
635 MainFileIncludes =
Preamble->Includes.MainFileIncludes;
636 for (
const auto &Inc :
Preamble->Includes.MainFileIncludes)
637 Inserter->addExisting(Inc);
642 Inputs.Opts.ImportInsertions
644 MainFileIncludes, {})
646 FixIncludes.emplace(
Filename, Inserter, *Inputs.Index,
648 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
649 const clang::Diagnostic &
Info) {
650 return FixIncludes->fix(DiagLevl,
Info);
652 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
657 include_cleaner::PragmaIncludes PI;
663 ReplayPreamble::attach(
Patch->preambleIncludes(), *
Clang,
664 Patch->modifiedBounds());
676 MainFileMacros Macros;
677 std::vector<PragmaMark> Marks;
679 Macros =
Patch->mainFileMacros();
680 Marks =
Patch->marks();
682 auto &PP =
Clang->getPreprocessor();
683 PP.addPPCallbacks(std::make_unique<CollectMainFileMacros>(PP, Macros));
692 syntax::TokenCollector CollectTokens(PP);
697 for (
const auto &L : ASTListeners)
698 L->beforeExecute(*
Clang);
700 if (llvm::Error Err =
Action->Execute())
701 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
707 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
709 Tokens.indexExpandedTokens();
710 std::vector<Decl *> ParsedDecls =
Action->takeTopLevelDecls();
712 Clang->getASTContext().setTraversalScope(ParsedDecls);
713 if (!CTChecks.empty()) {
716 trace::Span Tracer(
"ClangTidyMatch");
717 CTFinder.matchAST(
Clang->getASTContext());
726 Clang->getDiagnostics().setClient(
new IgnoreDiagnostics);
728 ASTDiags.EndSourceFile();
730 std::vector<Diag> Diags = CompilerInvocationDiags;
735 llvm::append_range(Diags,
Patch->patchedDiags());
738 std::vector<Diag> D = ASTDiags.take(&*CTContext);
739 Diags.insert(Diags.end(), D.begin(), D.end());
742 std::move(
Clang), std::move(
Action), std::move(Tokens),
743 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
744 std::move(Diags), std::move(Includes), std::move(PI));
745 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
746 std::back_inserter(Result.Diags));
747 return std::move(Result);
750ParsedAST::ParsedAST(ParsedAST &&Other) =
default;
752ParsedAST &ParsedAST::operator=(ParsedAST &&Other) =
default;
754ParsedAST::~ParsedAST() {
758 auto PP =
Clang->getPreprocessorPtr();
759 Clang->setPreprocessor(
nullptr);
765ASTContext &ParsedAST::getASTContext() {
return Clang->getASTContext(); }
767const ASTContext &ParsedAST::getASTContext()
const {
768 return Clang->getASTContext();
771Sema &ParsedAST::getSema() {
return Clang->getSema(); }
773Preprocessor &ParsedAST::getPreprocessor() {
return Clang->getPreprocessor(); }
775std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
776 return Clang->getPreprocessorPtr();
779const Preprocessor &ParsedAST::getPreprocessor()
const {
780 return Clang->getPreprocessor();
783llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
784 return LocalTopLevelDecls;
787llvm::ArrayRef<const Decl *> ParsedAST::getLocalTopLevelDecls()
const {
788 return LocalTopLevelDecls;
792const std::vector<PragmaMark> &ParsedAST::getMarks()
const {
return Marks; }
794std::size_t ParsedAST::getUsedBytes()
const {
795 auto &AST = getASTContext();
799 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
805 Total += AST.getASTAllocatedMemory();
806 Total += AST.getSideTableAllocatedMemory();
807 Total += AST.Idents.getAllocator().getTotalMemory();
808 Total += AST.Selectors.getTotalMemory();
810 Total += AST.getSourceManager().getContentCacheSize();
811 Total += AST.getSourceManager().getDataStructureSizes();
812 Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
814 if (ExternalASTSource *Ext = AST.getExternalSource())
815 Total += Ext->getMemoryBufferSizes().malloc_bytes;
817 const Preprocessor &PP = getPreprocessor();
818 Total += PP.getTotalMemory();
819 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
820 Total += PRec->getTotalMemory();
821 Total += PP.getHeaderSearchInfo().getTotalMemory();
830ParsedAST::ParsedAST(
PathRef TUPath, llvm::StringRef Version,
831 std::shared_ptr<const PreambleData>
Preamble,
832 std::unique_ptr<CompilerInstance>
Clang,
833 std::unique_ptr<FrontendAction>
Action,
835 std::vector<PragmaMark> Marks,
836 std::vector<Decl *> LocalTopLevelDecls,
838 include_cleaner::PragmaIncludes PI)
841 Tokens(std::move(Tokens)), Macros(std::move(Macros)),
842 Marks(std::move(Marks)), Diags(std::move(Diags)),
843 LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
844 Includes(std::move(Includes)), PI(std::move(PI)),
847 assert(this->Action);
857 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.
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.
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, 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)
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
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.