diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Expr.cpp')
| -rw-r--r-- | contrib/llvm-project/clang/lib/AST/Expr.cpp | 83 | 
1 files changed, 10 insertions, 73 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Expr.cpp b/contrib/llvm-project/clang/lib/AST/Expr.cpp index a90f92d07f86..b125fc676da8 100644 --- a/contrib/llvm-project/clang/lib/AST/Expr.cpp +++ b/contrib/llvm-project/clang/lib/AST/Expr.cpp @@ -205,85 +205,22 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {  }  bool Expr::isFlexibleArrayMemberLike( -    ASTContext &Context, +    ASTContext &Ctx,      LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,      bool IgnoreTemplateOrMacroSubstitution) const { - -  // For compatibility with existing code, we treat arrays of length 0 or -  // 1 as flexible array members. -  const auto *CAT = Context.getAsConstantArrayType(getType()); -  if (CAT) { -    llvm::APInt Size = CAT->getSize(); - -    using FAMKind = LangOptions::StrictFlexArraysLevelKind; - -    if (StrictFlexArraysLevel == FAMKind::IncompleteOnly) -      return false; - -    // GCC extension, only allowed to represent a FAM. -    if (Size == 0) -      return true; - -    if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1)) -      return false; - -    if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2)) -      return false; -  } else if (!Context.getAsIncompleteArrayType(getType())) -    return false; -    const Expr *E = IgnoreParens(); +  const Decl *D = nullptr; -  const NamedDecl *ND = nullptr; -  if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) -    ND = DRE->getDecl(); -  else if (const auto *ME = dyn_cast<MemberExpr>(E)) -    ND = ME->getMemberDecl(); +  if (const auto *ME = dyn_cast<MemberExpr>(E)) +    D = ME->getMemberDecl(); +  else if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) +    D = DRE->getDecl();    else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E)) -    return IRE->getDecl()->getNextIvar() == nullptr; - -  if (!ND) -    return false; +    D = IRE->getDecl(); -  // A flexible array member must be the last member in the class. -  // FIXME: If the base type of the member expr is not FD->getParent(), -  // this should not be treated as a flexible array member access. -  if (const auto *FD = dyn_cast<FieldDecl>(ND)) { -    // GCC treats an array memeber of a union as an FAM if the size is one or -    // zero. -    if (CAT) { -      llvm::APInt Size = CAT->getSize(); -      if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne())) -        return true; -    } - -    // Don't consider sizes resulting from macro expansions or template argument -    // substitution to form C89 tail-padded arrays. -    if (IgnoreTemplateOrMacroSubstitution) { -      TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); -      while (TInfo) { -        TypeLoc TL = TInfo->getTypeLoc(); -        // Look through typedefs. -        if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) { -          const TypedefNameDecl *TDL = TTL.getTypedefNameDecl(); -          TInfo = TDL->getTypeSourceInfo(); -          continue; -        } -        if (ConstantArrayTypeLoc CTL = TL.getAs<ConstantArrayTypeLoc>()) { -          const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr()); -          if (!SizeExpr || SizeExpr->getExprLoc().isMacroID()) -            return false; -        } -        break; -      } -    } - -    RecordDecl::field_iterator FI( -        DeclContext::decl_iterator(const_cast<FieldDecl *>(FD))); -    return ++FI == FD->getParent()->field_end(); -  } - -  return false; +  return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(), +                                         StrictFlexArraysLevel, +                                         IgnoreTemplateOrMacroSubstitution);  }  const ValueDecl *  | 
