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::@1659::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.
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...
ASTContext & getASTContext() const
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)