35  while (RD && (RD->isAnonymousStructOrUnion() ||
 
   36                (!RD->isCompleteDefinition() && RD->getName().empty()))) {
 
   37    const auto *Parent = dyn_cast<RecordDecl>(RD->getParent());
 
 
   65  const auto FieldTy = FD->
getType();
 
   66  if (FieldTy->isArrayType() && (CountInBytes || OrNull)) {
 
   68         diag::err_count_attr_not_on_ptr_or_flexible_array_member)
 
   72  if (!FieldTy->isArrayType() && !FieldTy->isPointerType()) {
 
   74         diag::err_count_attr_not_on_ptr_or_flexible_array_member)
 
   81  if (FieldTy->isArrayType() &&
 
   83                                       StrictFlexArraysLevel, 
true)) {
 
   85         diag::err_counted_by_attr_on_array_not_flexible_array_member)
 
   93  int SelectPtrOrArr = 0;
 
   94  if (FieldTy->isPointerType()) {
 
   98    assert(FieldTy->isArrayType());
 
  106  bool ShouldWarn = 
false;
 
  143    if (FieldTy->isArrayType() && !
getLangOpts().BoundsSafety) {
 
  156    unsigned DiagID = ShouldWarn
 
  157                          ? diag::warn_counted_by_attr_elt_type_unknown_size
 
  158                          : diag::err_counted_by_attr_pointee_unknown_size;
 
  160        << SelectPtrOrArr << PointeeTy << (
int)InvalidTypeKind
 
  173  auto *DRE = dyn_cast<DeclRefExpr>(E);
 
  176         diag::err_count_attr_only_support_simple_decl_reference)
 
  181  auto *CountDecl = DRE->getDecl();
 
  182  FieldDecl *CountFD = dyn_cast<FieldDecl>(CountDecl);
 
  183  if (
auto *IFD = dyn_cast<IndirectFieldDecl>(CountDecl)) {
 
  184    CountFD = IFD->getAnonField();
 
  190    Diag(CountDecl->getBeginLoc(),
 
  191         diag::note_flexible_array_counted_by_attr_field)
 
  192        << CountDecl << CountDecl->getSourceRange();
 
  210          << CountFD << Kind << FieldTy->isArrayType() << E->
getSourceRange();
 
  212           diag::note_flexible_array_counted_by_attr_field)
 
 
  223  assert(IncompleteTyDecl == 
nullptr || 
isa<TypeDecl>(IncompleteTyDecl));
 
  225  if (IncompleteTyDecl) {
 
  238           diag::note_counted_by_consider_completing_pointee_ty)
 
  254  S.
Diag(AttrSrcRange.
getBegin(), diag::note_counted_by_consider_using_sized_by)
 
  255      << CATy->
isOrNull() << AttrSrcRange;
 
 
  258static std::tuple<const CountAttributedType *, QualType>
 
  263  if (!CATy || CATy->isCountInBytes())
 
  267  if (PointeeTy.isNull()) {
 
  272  if (!PointeeTy->isIncompleteType(ND))
 
  275  return {CATy, PointeeTy};
 
 
  299    bool ShowFullyQualifiedAssigneeName) {
 
  301  auto [CATy, PointeeTy] =
 
  306  std::string AssigneeStr;
 
  308    if (ShowFullyQualifiedAssigneeName) {
 
  315  S.
Diag(Loc, diag::err_counted_by_on_incomplete_type_on_assign)
 
  316      << 
static_cast<int>(Action) << AssigneeStr << (AssigneeStr.size() > 0)
 
  318      << CATy->getAttributeName(
true) << PointeeTy
 
 
  327    const ValueDecl *Assignee, 
bool ShowFullyQualifiedAssigneeName) {
 
  329      *
this, LHSTy, RHSExpr, Action, Loc, Assignee,
 
  330      ShowFullyQualifiedAssigneeName);
 
 
  337  auto SL = Kind.getLocation();
 
  351            *
this, LHSType, RHSExpr, Action, SL,
 
  352            dyn_cast_or_null<ValueDecl>(Entity.
getDecl()),
 
 
  363  if (!
T->isPointerType())
 
  367  auto [CATy, PointeeTy] =
 
  376  bool IsDirectCall = 
false;
 
  377  if (
const auto *CE = dyn_cast<CallExpr>(E->
IgnoreParens())) {
 
  378    if (
const auto *FD = CE->getDirectCallee()) {
 
  379      UseStr = FD->getName();
 
  385    llvm::raw_svector_ostream SS(UseStr);
 
  390      << IsDirectCall << UseStr << 
T << PointeeTy
 
  391      << CATy->getAttributeName(
true) << CATy->isOrNull()
 
 
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
 
Represents an array type, per C99 6.7.5.2 - Array Declarators.
 
QualType getElementType() const
 
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
 
Expr * getCountExpr() const
 
static bool isFlexibleArrayMemberLike(const ASTContext &Context, const Decl *D, QualType Ty, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution)
Whether it resembles a flexible array member.
 
SourceLocation getLocation() const
 
SourceLocation getBeginLoc() const LLVM_READONLY
 
SourceLocation getBeginLoc() const LLVM_READONLY
 
This represents one expression.
 
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
 
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.
 
Describes the kind of initialization being performed, along with location information for tokens rela...
 
Describes an entity that is being initialized.
 
EntityKind getKind() const
Determine the kind of initialization.
 
ValueDecl * getDecl() const
Retrieve the variable, parameter, or field being initialized.
 
@ EK_Variable
The entity being initialized is a variable.
 
StrictFlexArraysLevelKind
 
@ IncompleteOnly
Any trailing array member of undefined size is a FAM.
 
This represents a decl that may have a name.
 
std::string getQualifiedNameAsString() const
 
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
 
A (possibly-)qualified type.
 
Represents a struct/union/class.
 
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
 
Sema - This implements semantic analysis and AST building for C.
 
bool BoundsSafetyCheckAssignmentToCountAttrPtr(QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, SourceLocation Loc, const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName)
Perform Bounds Safety Semantic checks for assigning to a __counted_by or __counted_by_or_null pointer...
 
bool BoundsSafetyCheckUseOfCountAttrPtr(const Expr *E)
Perform Bounds Safety semantic checks for uses of invalid uses counted_by or counted_by_or_null point...
 
ASTContext & getASTContext() const
 
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
 
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 BoundsSafetyCheckInitialization(const InitializedEntity &Entity, const InitializationKind &Kind, AssignmentAction Action, QualType LHSType, Expr *RHSExpr)
Perform Bounds Safety Semantic checks for initializing a Bounds Safety pointer.
 
Encodes a location in the source.
 
A trivial tuple used to represent a source range.
 
SourceLocation getBegin() const
 
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
 
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
 
SourceLocation getBeginLoc() const LLVM_READONLY
 
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
 
bool isBooleanType() const
 
bool isAlwaysIncompleteType() const
 
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
 
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
 
bool isFunctionType() const
 
bool isStructureTypeWithFlexibleArrayMember() const
 
const T * getAs() const
Member-template getAs<specific type>'.
 
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
 
The JSON file list parser is used to communicate input to InstallAPI.
 
bool isa(CodeGen::Address addr)
 
static CountAttributedType::DynamicCountPointerKind getCountAttrKind(bool CountInBytes, bool OrNull)
 
CountedByInvalidPointeeTypeKind
 
static bool CheckAssignmentToCountAttrPtrWithIncompletePointeeTy(Sema &S, QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, SourceLocation Loc, const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName)
Perform Checks for assigning to a __counted_by or __counted_by_or_null pointer type.
 
static const RecordDecl * GetEnclosingNamedOrTopAnonRecord(const FieldDecl *FD)
 
static void EmitIncompleteCountedByPointeeNotes(Sema &S, const CountAttributedType *CATy, NamedDecl *IncompleteTyDecl)
 
static std::tuple< const CountAttributedType *, QualType > GetCountedByAttrOnIncompletePointee(QualType Ty, NamedDecl **ND)
 
const FunctionProtoType * T