13#include "llvm/ADT/STLExtras.h"
14#include "llvm/Support/FormatVariadic.h"
15#include "llvm/Support/TimeProfiler.h"
24inline bool hasSuppression(
const Decl *D) {
27 if (
const auto *Suppression = D->
getAttr<SuppressAttr>())
28 return !Suppression->isGSL() &&
29 (Suppression->diagnosticIdentifiers().empty());
36 const auto *Suppression = dyn_cast<SuppressAttr>(A);
37 return Suppression && !Suppression->isGSL() &&
38 (Suppression->diagnosticIdentifiers().empty());
43 return Node->getSourceRange();
85 static void initialize(
const Decl *D, Ranges &ToInit) {
86 CacheInitializer(ToInit).TraverseDecl(
const_cast<Decl *
>(D));
89 bool VisitDecl(Decl *D)
override {
94 return VisitAttributedNode(D);
97 bool VisitAttributedStmt(AttributedStmt *AS)
override {
101 return VisitAttributedNode(AS);
105 template <
class NodeType>
bool VisitAttributedNode(NodeType *Node) {
106 if (hasSuppression(Node)) {
116 void addRange(SourceRange R) {
122 CacheInitializer(Ranges &R) : Result(
R) {
123 ShouldVisitTemplateInstantiations =
true;
124 ShouldWalkTypesOfTypeLocs =
false;
125 ShouldVisitImplicitCode =
false;
126 ShouldVisitLambdaBody =
true;
131std::string timeScopeName(
const Decl *DeclWithIssue) {
132 if (!llvm::timeTraceProfilerEnabled())
134 return llvm::formatv(
135 "BugSuppression::isSuppressed init suppressions cache for {0}",
140llvm::TimeTraceMetadata getDeclTimeTraceMetadata(
const Decl *DeclWithIssue) {
141 assert(DeclWithIssue);
142 assert(llvm::timeTraceProfilerEnabled());
143 std::string Name =
"<noname>";
144 if (
const auto *ND = dyn_cast<NamedDecl>(DeclWithIssue)) {
145 Name = ND->getNameAsString();
150 return llvm::TimeTraceMetadata{std::move(Name), Fname.str(),
151 static_cast<int>(
Line)};
164 const Decl *DeclWithIssue = R.getDeclWithIssue();
202 PartialSpec = MemberPS;
210 for (
const auto *Redecl : Tmpl->redecls()) {
211 if (
const T *D =
cast<T>(Redecl); D->isThisDeclarationADefinition()) {
215 assert(
false &&
"This template must have a redecl that is a definition");
248 if (
const auto *FD = dyn_cast<FunctionDecl>(D)) {
250 return Pattern->getDefinition();
253 const auto *SpecializationDecl = dyn_cast<ClassTemplateSpecializationDecl>(D);
254 if (!SpecializationDecl)
257 auto InstantiatedFrom = SpecializationDecl->getInstantiatedFrom();
258 if (!InstantiatedFrom)
261 if (
const auto *Tmpl = dyn_cast<ClassTemplateDecl *>(InstantiatedFrom)) {
271 const Decl *DeclWithIssue,
273 if (!Location.isValid())
276 if (!DeclWithIssue) {
305 DeclWithIssue = Parent;
319 auto InsertionResult = CachedSuppressionLocations.insert(
320 std::make_pair(DeclWithIssue, CachedRanges{}));
321 Ranges &SuppressionRanges = InsertionResult.first->second;
322 if (InsertionResult.second) {
323 llvm::TimeTraceScope TimeScope(
324 timeScopeName(DeclWithIssue),
325 [DeclWithIssue]() {
return getDeclTimeTraceMetadata(DeclWithIssue); });
327 CacheInitializer::initialize(DeclWithIssue, SuppressionRanges);
333 return llvm::any_of(SuppressionRanges,
335 return fullyContains(Suppression, BugRange, SM);
static const T * chooseDefinitionRedecl(const T *Tmpl)
static const ClassTemplateDecl * walkInstantiatedFromChain(const ClassTemplateDecl *Tmpl)
static const Decl * preferTemplateDefinitionForTemplateSpecializations(const Decl *D)
static CharSourceRange getRange(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeMacroExpansion)
Defines the SourceManager interface.
SourceManager & getSourceManager()
Attr - This represents one attribute.
Represents an attribute applied to a statement.
ArrayRef< const Attr * > getAttrs() const
Declaration of a class template.
ClassTemplateDecl * getInstantiatedFromMemberTemplate() const
ClassTemplatePartialSpecializationDecl * getInstantiatedFromMember() const
Retrieve the member class template partial specialization from which this particular class template p...
bool isMemberSpecialization() const
Determines whether this class template partial specialization template was a specialization of a memb...
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
const char * getDeclKindName() const
SourceLocation getBeginLoc() const LLVM_READONLY
TranslationUnitDecl * getTranslationUnitDecl()
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Represents a function declaration or definition.
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
bool isMemberSpecialization() const
Determines whether this template was a specialization of a member template.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
This class provides an interface through which checkers can create individual bug reports.
llvm::ArrayRef< llvm::StringRef > DiagnosticIdentifierList
bool isSuppressed(const BugReport &)
Return true if the given bug report was explicitly suppressed by the user.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
const FunctionProtoType * T
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)