33 while (RD && (RD->isAnonymousStructOrUnion() ||
34 (!RD->isCompleteDefinition() && RD->getName().empty()))) {
35 const auto *
Parent = dyn_cast<RecordDecl>(RD->getParent());
63 const auto FieldTy = FD->
getType();
64 if (FieldTy->isArrayType() && (CountInBytes || OrNull)) {
66 diag::err_count_attr_not_on_ptr_or_flexible_array_member)
70 if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) {
72 diag::err_count_attr_not_on_ptr_or_flexible_array_member)
79 if (FieldTy->isArrayType() &&
81 StrictFlexArraysLevel,
true)) {
83 diag::err_counted_by_attr_on_array_not_flexible_array_member)
91 int SelectPtrOrArr = 0;
92 if (FieldTy->isPointerType()) {
96 assert(FieldTy->isArrayType());
104 bool ShouldWarn =
false;
112 if (FieldTy->isArrayType() && !
getLangOpts().BoundsSafety) {
125 unsigned DiagID = ShouldWarn
126 ? diag::warn_counted_by_attr_elt_type_unknown_size
127 : diag::err_counted_by_attr_pointee_unknown_size;
129 << SelectPtrOrArr << PointeeTy << (
int)InvalidTypeKind
136 if (!
E->getType()->isIntegerType() ||
E->getType()->isBooleanType()) {
137 Diag(
E->getBeginLoc(), diag::err_count_attr_argument_not_integer)
138 <<
Kind <<
E->getSourceRange();
142 auto *DRE = dyn_cast<DeclRefExpr>(
E);
144 Diag(
E->getBeginLoc(),
145 diag::err_count_attr_only_support_simple_decl_reference)
146 <<
Kind <<
E->getSourceRange();
150 auto *CountDecl = DRE->getDecl();
151 FieldDecl *CountFD = dyn_cast<FieldDecl>(CountDecl);
152 if (
auto *IFD = dyn_cast<IndirectFieldDecl>(CountDecl)) {
153 CountFD = IFD->getAnonField();
156 Diag(
E->getBeginLoc(), diag::err_count_attr_must_be_in_structure)
157 << CountDecl <<
Kind <<
E->getSourceRange();
159 Diag(CountDecl->getBeginLoc(),
160 diag::note_flexible_array_counted_by_attr_field)
161 << CountDecl << CountDecl->getSourceRange();
178 Diag(
E->getBeginLoc(), diag::err_count_attr_param_not_in_same_struct)
179 << CountFD <<
Kind << FieldTy->isArrayType() <<
E->getSourceRange();
181 diag::note_flexible_array_counted_by_attr_field)
enum clang::sema::@1655::IndirectLocalPathEntry::EntryKind Kind
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
SourceLocation getLocation() const
static bool isFlexibleArrayMemberLike(ASTContext &Context, const Decl *D, QualType Ty, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution)
Whether it resembles a flexible array member.
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
Represents a member of a struct/union/class.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
StrictFlexArraysLevelKind
@ IncompleteOnly
Any trailing array member of undefined size is a FAM.
A (possibly-)qualified type.
Represents a struct/union/class.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
ASTContext & getASTContext() const
const LangOptions & getLangOpts() const
bool CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes, bool OrNull)
Check if applying the specified attribute variant from the "counted by" family of attributes to Field...
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isStructureTypeWithFlexibleArrayMember() const
The JSON file list parser is used to communicate input to InstallAPI.
static CountAttributedType::DynamicCountPointerKind getCountAttrKind(bool CountInBytes, bool OrNull)
CountedByInvalidPointeeTypeKind
static const RecordDecl * GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD)