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(
',');
283 Check = Check.trim();
288 bool Enable = !Check.consume_front(
"-");
289 bool Glob = Check.consume_back(
"*");
293 if (CDPrefix.starts_with(Check)) {
301 if (Default == Enable)
304 if (!Check.consume_front(CDPrefix))
307 if (
auto Group = DiagnosticIDs::getGroupForWarningOption(Check))
308 Exceptions.insert(
static_cast<unsigned>(*Group));
312 bool operator()(diag::Group GroupID)
const {
313 return Exceptions.contains(
static_cast<unsigned>(GroupID)) ? !Default
323void applyWarningOptions(llvm::ArrayRef<std::string> ExtraArgs,
324 llvm::function_ref<
bool(diag::Group)> EnabledGroups,
325 DiagnosticsEngine &Diags) {
326 for (llvm::StringRef Group : ExtraArgs) {
329 llvm::SmallVector<diag::kind> Members;
330 if (!Group.consume_front(
"-W") || Group.empty())
332 bool Enable = !Group.consume_front(
"no-");
333 if (Diags.getDiagnosticIDs()->getDiagnosticsInGroup(
334 diag::Flavor::WarningOrError, Group, Members))
340 bool NeedsWerrorExclusion =
false;
341 for (diag::kind
ID : Members) {
343 if (Diags.getDiagnosticLevel(
ID, SourceLocation()) <
344 DiagnosticsEngine::Warning) {
345 auto Group = DiagnosticIDs::getGroupForDiag(
ID);
346 if (!Group || !EnabledGroups(*Group))
348 Diags.setSeverity(
ID, diag::Severity::Warning, SourceLocation());
349 if (Diags.getWarningsAsErrors())
350 NeedsWerrorExclusion =
true;
353 Diags.setSeverity(
ID, diag::Severity::Ignored, SourceLocation());
356 if (NeedsWerrorExclusion) {
360 Diags.setDiagnosticGroupWarningAsError(Group,
false);
365std::vector<Diag> getIncludeCleanerDiags(ParsedAST &
AST, llvm::StringRef Code,
366 const ThreadsafeFS &TFS) {
370 bool SuppressMissing =
373 bool SuppressUnused =
376 if (SuppressMissing && SuppressUnused)
381 Findings.MissingIncludes.clear();
383 Findings.UnusedIncludes.clear();
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) {
413 auto VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
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 =
435 CI->getLangOpts().DelayedTemplateParsing =
false;
437 std::vector<std::unique_ptr<FeatureModule::ASTListener>> ASTListeners;
438 if (Inputs.FeatureModules) {
439 for (
auto &
M : *Inputs.FeatureModules) {
440 if (
auto Listener =
M.astListeners())
441 ASTListeners.emplace_back(std::move(Listener));
447 for (
const auto &L : ASTListeners)
448 L->sawDiagnostic(D,
Diag);
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());
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);
556 *AllCTFactories, Cfg.Diagnostics.ClangTidy.FastCheckFilter);
557 CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
559 CTContext->setDiagnosticsEngine(&
Clang->getDiagnostics());
560 CTContext->setASTContext(&
Clang->getASTContext());
561 CTContext->setCurrentFile(
Filename);
562 CTContext->setSelfContainedDiags(
true);
564 Preprocessor *PP = &
Clang->getPreprocessor();
565 for (
const auto &Check : CTChecks) {
566 Check->registerPPCallbacks(
Clang->getSourceManager(), PP, PP);
567 Check->registerMatchers(&CTFinder);
575 for (
auto ID : {diag::ext_implicit_function_decl_c99,
576 diag::ext_implicit_lib_function_decl,
577 diag::ext_implicit_lib_function_decl_c99,
578 diag::warn_implicit_function_decl}) {
579 OverriddenSeverity.try_emplace(
580 ID,
Clang->getDiagnostics().getDiagnosticLevel(
ID, SourceLocation()));
581 Clang->getDiagnostics().setSeverity(
ID, diag::Severity::Error,
586 const clang::Diagnostic &
Info) {
587 if (Cfg.Diagnostics.SuppressAll ||
589 Clang->getLangOpts()))
590 return DiagnosticsEngine::Ignored;
592 auto It = OverriddenSeverity.find(
Info.getID());
593 if (It != OverriddenSeverity.end())
594 DiagLevel = It->second;
596 if (!CTChecks.empty()) {
597 std::string CheckName = CTContext->getCheckName(Info.getID());
598 bool IsClangTidyDiag = !CheckName.empty();
599 if (IsClangTidyDiag) {
600 if (Cfg.Diagnostics.Suppress.contains(CheckName))
601 return DiagnosticsEngine::Ignored;
608 bool IsInsideMainFile =
609 Info.hasSourceManager() &&
610 isInsideMainFile(Info.getLocation(), Info.getSourceManager());
611 SmallVector<tooling::Diagnostic, 1> TidySuppressedErrors;
612 if (IsInsideMainFile && CTContext->shouldSuppressDiagnostic(
613 DiagLevel, Info, TidySuppressedErrors,
618 return DiagnosticsEngine::Ignored;
620 if (!CTContext->getOptions().SystemHeaders.value_or(false) &&
621 Info.hasSourceManager() &&
622 Info.getSourceManager().isInSystemMacro(Info.getLocation()))
623 return DiagnosticsEngine::Ignored;
626 if (DiagLevel == DiagnosticsEngine::Warning &&
627 CTContext->treatAsError(CheckName)) {
628 return DiagnosticsEngine::Error;
637 if (Inputs.Index && !
BuildDir.getError()) {
640 auto Inserter = std::make_shared<IncludeInserter>(
642 &
Clang->getPreprocessor().getHeaderSearchInfo(),
643 Cfg.Style.QuotedHeaders, Cfg.Style.AngledHeaders);
644 ArrayRef<Inclusion> MainFileIncludes;
646 MainFileIncludes =
Preamble->Includes.MainFileIncludes;
647 for (
const auto &Inc :
Preamble->Includes.MainFileIncludes)
648 Inserter->addExisting(Inc);
653 Inputs.Opts.ImportInsertions
655 MainFileIncludes, {})
657 FixIncludes.emplace(
Filename, Inserter, *Inputs.Index,
659 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
660 const clang::Diagnostic &
Info) {
661 return FixIncludes->fix(DiagLevl,
Info);
663 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
668 include_cleaner::PragmaIncludes PI;
674 ReplayPreamble::attach(
Patch->preambleIncludes(), *
Clang,
675 Patch->modifiedBounds());
687 MainFileMacros Macros;
688 std::vector<PragmaMark> Marks;
690 Macros =
Patch->mainFileMacros();
691 Marks =
Patch->marks();
693 auto &PP =
Clang->getPreprocessor();
694 auto MacroCollector = std::make_unique<CollectMainFileMacros>(PP, Macros);
695 auto *MacroCollectorPtr = MacroCollector.get();
696 PP.addPPCallbacks(std::move(MacroCollector));
705 syntax::TokenCollector CollectTokens(PP);
710 for (
const auto &L : ASTListeners)
711 L->beforeExecute(*
Clang);
713 if (llvm::Error Err =
Action->Execute())
714 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
719 MacroCollectorPtr->doneParse();
724 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
726 Tokens.indexExpandedTokens();
727 std::vector<Decl *> ParsedDecls =
Action->takeTopLevelDecls();
729 Clang->getASTContext().setTraversalScope(ParsedDecls);
730 if (!CTChecks.empty()) {
733 trace::Span Tracer(
"ClangTidyMatch");
734 CTFinder.matchAST(
Clang->getASTContext());
743 Clang->getDiagnostics().setClient(
new IgnoreDiagnostics);
745 ASTDiags.EndSourceFile();
747 std::vector<Diag> Diags = CompilerInvocationDiags;
752 llvm::append_range(Diags,
Patch->patchedDiags());
755 std::vector<Diag> D = ASTDiags.take(&*CTContext);
756 Diags.insert(Diags.end(), D.begin(), D.end());
759 std::move(
Clang), std::move(
Action), std::move(Tokens),
760 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
761 std::move(Diags), std::move(Includes), std::move(PI));
762 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
763 std::back_inserter(Result.Diags));
764 return std::move(Result);
767ParsedAST::ParsedAST(ParsedAST &&Other) =
default;
769ParsedAST &ParsedAST::operator=(ParsedAST &&Other) =
default;
771ParsedAST::~ParsedAST() {
775 auto PP =
Clang->getPreprocessorPtr();
776 Clang->setPreprocessor(
nullptr);
782ASTContext &ParsedAST::getASTContext() {
return Clang->getASTContext(); }
784const ASTContext &ParsedAST::getASTContext()
const {
785 return Clang->getASTContext();
788Sema &ParsedAST::getSema() {
return Clang->getSema(); }
790Preprocessor &ParsedAST::getPreprocessor() {
return Clang->getPreprocessor(); }
792std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
793 return Clang->getPreprocessorPtr();
796const Preprocessor &ParsedAST::getPreprocessor()
const {
797 return Clang->getPreprocessor();
800llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
801 return LocalTopLevelDecls;
804llvm::ArrayRef<const Decl *> ParsedAST::getLocalTopLevelDecls()
const {
805 return LocalTopLevelDecls;
809const std::vector<PragmaMark> &ParsedAST::getMarks()
const {
return Marks; }
811std::size_t ParsedAST::getUsedBytes()
const {
812 auto &AST = getASTContext();
816 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
822 Total += AST.getASTAllocatedMemory();
823 Total += AST.getSideTableAllocatedMemory();
824 Total += AST.Idents.getAllocator().getTotalMemory();
825 Total += AST.Selectors.getTotalMemory();
827 Total += AST.getSourceManager().getContentCacheSize();
828 Total += AST.getSourceManager().getDataStructureSizes();
829 Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
831 if (ExternalASTSource *Ext = AST.getExternalSource())
832 Total += Ext->getMemoryBufferSizes().malloc_bytes;
834 const Preprocessor &PP = getPreprocessor();
835 Total += PP.getTotalMemory();
836 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
837 Total += PRec->getTotalMemory();
838 Total += PP.getHeaderSearchInfo().getTotalMemory();
847ParsedAST::ParsedAST(
PathRef TUPath, llvm::StringRef Version,
848 std::shared_ptr<const PreambleData>
Preamble,
849 std::unique_ptr<CompilerInstance>
Clang,
850 std::unique_ptr<FrontendAction>
Action,
852 std::vector<PragmaMark> Marks,
853 std::vector<Decl *> LocalTopLevelDecls,
855 include_cleaner::PragmaIncludes PI)
858 Tokens(std::move(Tokens)), Macros(std::move(Macros)),
859 Marks(std::move(Marks)), Diags(std::move(Diags)),
860 LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
861 Includes(std::move(Includes)), PI(std::move(PI)),
864 assert(this->Action);
874 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.