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 ArrayRef<Inclusion> MainFileIncludes;
645 MainFileIncludes =
Preamble->Includes.MainFileIncludes;
646 for (
const auto &Inc :
Preamble->Includes.MainFileIncludes)
647 Inserter->addExisting(Inc);
652 Inputs.Opts.ImportInsertions
654 MainFileIncludes, {})
656 FixIncludes.emplace(
Filename, Inserter, *Inputs.Index,
658 ASTDiags.
contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
659 const clang::Diagnostic &
Info) {
660 return FixIncludes->fix(DiagLevl,
Info);
662 Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
667 include_cleaner::PragmaIncludes PI;
673 ReplayPreamble::attach(
Patch->preambleIncludes(), *
Clang,
674 Patch->modifiedBounds());
686 MainFileMacros Macros;
687 std::vector<PragmaMark> Marks;
689 Macros =
Patch->mainFileMacros();
690 Marks =
Patch->marks();
692 auto &PP =
Clang->getPreprocessor();
693 auto MacroCollector = std::make_unique<CollectMainFileMacros>(PP, Macros);
694 auto *MacroCollectorPtr = MacroCollector.get();
695 PP.addPPCallbacks(std::move(MacroCollector));
704 syntax::TokenCollector CollectTokens(PP);
709 for (
const auto &L : ASTListeners)
710 L->beforeExecute(*
Clang);
712 if (llvm::Error Err =
Action->Execute())
713 log(
"Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
718 MacroCollectorPtr->doneParse();
723 syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
725 Tokens.indexExpandedTokens();
726 std::vector<Decl *> ParsedDecls =
Action->takeTopLevelDecls();
728 Clang->getASTContext().setTraversalScope(ParsedDecls);
729 if (!CTChecks.empty()) {
732 trace::Span Tracer(
"ClangTidyMatch");
733 CTFinder.matchAST(
Clang->getASTContext());
742 Clang->getDiagnostics().setClient(
new IgnoreDiagnostics);
744 ASTDiags.EndSourceFile();
746 std::vector<Diag> Diags = CompilerInvocationDiags;
751 llvm::append_range(Diags,
Patch->patchedDiags());
754 std::vector<Diag> D = ASTDiags.take(&*CTContext);
755 Diags.insert(Diags.end(), D.begin(), D.end());
758 std::move(
Clang), std::move(
Action), std::move(Tokens),
759 std::move(Macros), std::move(Marks), std::move(ParsedDecls),
760 std::move(Diags), std::move(Includes), std::move(PI));
761 llvm::move(getIncludeCleanerDiags(Result, Inputs.
Contents, *Inputs.
TFS),
762 std::back_inserter(Result.Diags));
763 return std::move(Result);
766ParsedAST::ParsedAST(ParsedAST &&Other) =
default;
768ParsedAST &ParsedAST::operator=(ParsedAST &&Other) =
default;
770ParsedAST::~ParsedAST() {
774 auto PP =
Clang->getPreprocessorPtr();
775 Clang->setPreprocessor(
nullptr);
781ASTContext &ParsedAST::getASTContext() {
return Clang->getASTContext(); }
783const ASTContext &ParsedAST::getASTContext()
const {
784 return Clang->getASTContext();
787Sema &ParsedAST::getSema() {
return Clang->getSema(); }
789Preprocessor &ParsedAST::getPreprocessor() {
return Clang->getPreprocessor(); }
791std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
792 return Clang->getPreprocessorPtr();
795const Preprocessor &ParsedAST::getPreprocessor()
const {
796 return Clang->getPreprocessor();
799llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
800 return LocalTopLevelDecls;
803llvm::ArrayRef<const Decl *> ParsedAST::getLocalTopLevelDecls()
const {
804 return LocalTopLevelDecls;
808const std::vector<PragmaMark> &ParsedAST::getMarks()
const {
return Marks; }
810std::size_t ParsedAST::getUsedBytes()
const {
811 auto &AST = getASTContext();
815 clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
821 Total += AST.getASTAllocatedMemory();
822 Total += AST.getSideTableAllocatedMemory();
823 Total += AST.Idents.getAllocator().getTotalMemory();
824 Total += AST.Selectors.getTotalMemory();
826 Total += AST.getSourceManager().getContentCacheSize();
827 Total += AST.getSourceManager().getDataStructureSizes();
828 Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
830 if (ExternalASTSource *Ext = AST.getExternalSource())
831 Total += Ext->getMemoryBufferSizes().malloc_bytes;
833 const Preprocessor &PP = getPreprocessor();
834 Total += PP.getTotalMemory();
835 if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
836 Total += PRec->getTotalMemory();
837 Total += PP.getHeaderSearchInfo().getTotalMemory();
846ParsedAST::ParsedAST(
PathRef TUPath, llvm::StringRef Version,
847 std::shared_ptr<const PreambleData>
Preamble,
848 std::unique_ptr<CompilerInstance>
Clang,
849 std::unique_ptr<FrontendAction>
Action,
851 std::vector<PragmaMark> Marks,
852 std::vector<Decl *> LocalTopLevelDecls,
854 include_cleaner::PragmaIncludes PI)
857 Tokens(std::move(Tokens)), Macros(std::move(Macros)),
858 Marks(std::move(Marks)), Diags(std::move(Diags)),
859 LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
860 Includes(std::move(Includes)), PI(std::move(PI)),
863 assert(this->Action);
873 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.