28#include "llvm/ADT/StringRef.h" 
   35                                         const AvailabilityAttr *AA) {
 
   37  auto Environment = Context.getTargetInfo().getTriple().getEnvironment();
 
   38  if (!IIEnvironment || Environment == llvm::Triple::UnknownEnvironment)
 
   41  llvm::Triple::EnvironmentType ET =
 
   42      AvailabilityAttr::getEnvironmentType(IIEnvironment->
getName());
 
   43  return Environment == ET;
 
 
   48  AvailabilityAttr 
const *PartialMatch = 
nullptr;
 
   54  if (
const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
 
   55    D = FTD->getTemplatedDecl();
 
   56  for (
const auto *A : D->
attrs()) {
 
   57    if (
const auto *Avail = dyn_cast<AvailabilityAttr>(A)) {
 
   63      StringRef ActualPlatform = Avail->getPlatform()->getName();
 
   64      StringRef RealizedPlatform = ActualPlatform;
 
   65      if (Context.getLangOpts().AppExt) {
 
   66        size_t suffix = RealizedPlatform.rfind(
"_app_extension");
 
   67        if (suffix != StringRef::npos)
 
   68          RealizedPlatform = RealizedPlatform.slice(0, suffix);
 
   71      StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
 
   74      if (RealizedPlatform == TargetPlatform) {
 
 
   93std::pair<AvailabilityResult, const NamedDecl *>
 
  100  while (
const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
 
  103    for (
const Type *
T = TD->getUnderlyingType().getTypePtr(); ; ) {
 
  104      if (
auto *TT = dyn_cast<TagType>(
T)) {
 
  105        D = TT->getDecl()->getDefinitionOrSelf();
 
  113            T->getLocallyUnqualifiedSingleStepDesugaredType().getTypePtr();
 
  125  if (
const auto *ADecl = dyn_cast<TypeAliasTemplateDecl>(D)) {
 
  126    D = ADecl->getTemplatedDecl();
 
  131  if (
const auto *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
 
  132    if (IDecl->getDefinition()) {
 
  133      D = IDecl->getDefinition();
 
  138  if (
const auto *ECD = dyn_cast<EnumConstantDecl>(D))
 
  141      if (
const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
 
  142        Result = TheEnumDecl->getAvailability(Message);
 
  148  if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
 
  149    if (
ObjC().NSAPIObj && ClassReceiver) {
 
  151          ObjC().NSAPIObj->getInitSelector());
 
  153          MD->getSelector() == 
ObjC().NSAPIObj->getNewSelector() &&
 
 
  170  assert(K != 
AR_Available && 
"Expected an unavailable declaration here!");
 
  175  if (DeclLoc.isMacroID() && S.
getLangOpts().CPlusPlus &&
 
  178    if (MacroName == 
"CF_OPTIONS" || MacroName == 
"OBJC_OPTIONS" ||
 
  179        MacroName == 
"SWIFT_OPTIONS" || MacroName == 
"NS_OPTIONS") {
 
  194        (DeclEnv != 
nullptr &&
 
  196             llvm::Triple::EnvironmentType::Library))
 
  201    if (
const auto *VD = dyn_cast<VarDecl>(OffendingDecl))
 
  202      if (VD->isLocalVarDeclOrParm() && VD->isDeprecated())
 
  207  auto CheckContext = [&](
const Decl *
C) {
 
  210        if (AA->getIntroduced() >= DeclVersion &&
 
  211            AA->getEnvironment() == DeclEnv)
 
  214      if (
C->isDeprecated())
 
  220      if (
const auto *MD = dyn_cast<ObjCMethodDecl>(OffendingDecl)) {
 
  221        if (
const auto *Impl = dyn_cast<ObjCImplDecl>(
C)) {
 
  222          if (MD->getClassInterface() == Impl->getClassInterface())
 
  228    if (
C->isUnavailable())
 
  234    if (CheckContext(Ctx))
 
  239    if (
const auto *MethodD = dyn_cast<ObjCMethodDecl>(Ctx))
 
  240      if (MethodD->isClassMethod() &&
 
  241          MethodD->getSelector().getAsString() == 
"load")
 
  244    if (
const auto *CatOrImpl = dyn_cast<ObjCImplDecl>(Ctx)) {
 
  250    else if (
const auto *CatD = dyn_cast<ObjCCategoryDecl>(Ctx))
 
 
  260    const ASTContext &Context, 
const VersionTuple &DeploymentVersion,
 
  261    const VersionTuple &DeclVersion, 
bool HasMatchingEnv) {
 
  262  const auto &Triple = Context.getTargetInfo().getTriple();
 
  263  VersionTuple ForceAvailabilityFromVersion;
 
  264  switch (Triple.getOS()) {
 
  269  case llvm::Triple::IOS:
 
  270  case llvm::Triple::TvOS:
 
  271    ForceAvailabilityFromVersion = VersionTuple(11);
 
  273  case llvm::Triple::WatchOS:
 
  274    ForceAvailabilityFromVersion = VersionTuple(4);
 
  276  case llvm::Triple::Darwin:
 
  277  case llvm::Triple::MacOSX:
 
  278    ForceAvailabilityFromVersion = VersionTuple(10, 13);
 
  284  case llvm::Triple::ShaderModel:
 
  285    return HasMatchingEnv ? diag::warn_hlsl_availability
 
  286                          : diag::warn_hlsl_availability_unavailable;
 
  289    ForceAvailabilityFromVersion =
 
  290        (Triple.getVendor() == llvm::Triple::Apple)
 
  292            : VersionTuple((
unsigned)-1, (
unsigned)-1);
 
  294  if (DeploymentVersion >= ForceAvailabilityFromVersion ||
 
  295      DeclVersion >= ForceAvailabilityFromVersion)
 
  296    return HasMatchingEnv ? diag::warn_unguarded_availability_new
 
  297                          : diag::warn_unguarded_availability_unavailable_new;
 
  298  return HasMatchingEnv ? diag::warn_unguarded_availability
 
  299                        : diag::warn_unguarded_availability_unavailable;
 
 
  303  for (
Decl *Ctx = OrigCtx; Ctx;
 
  304       Ctx = cast_or_null<Decl>(Ctx->getDeclContext())) {
 
  307    if (
auto *CD = dyn_cast<ObjCContainerDecl>(Ctx)) {
 
  308      if (
auto *Imp = dyn_cast<ObjCImplDecl>(Ctx))
 
  309        return Imp->getClassInterface();
 
  314  return dyn_cast<NamedDecl>(OrigCtx);
 
 
  319struct AttributeInsertion {
 
  324  static AttributeInsertion createInsertionAfter(
const NamedDecl *D) {
 
  327  static AttributeInsertion createInsertionAfter(SourceLocation Loc) {
 
  328    return {
" ", Loc, 
""};
 
  330  static AttributeInsertion createInsertionBefore(
const NamedDecl *D) {
 
  345static std::optional<unsigned>
 
  349  if (!Name.empty() && (Name.front() == 
'-' || Name.front() == 
'+'))
 
  350    Name = Name.drop_front(1);
 
  353  Name.split(SlotNames, 
':');
 
  355  if (Name.back() == 
':') {
 
  357    SlotNames.pop_back();
 
  358    NumParams = SlotNames.size();
 
  360    if (SlotNames.size() != 1)
 
  366  bool AllowDollar = LangOpts.DollarIdents;
 
  367  for (StringRef S : SlotNames) {
 
 
  378static std::optional<AttributeInsertion>
 
  382    return AttributeInsertion::createInsertionAfter(D);
 
  383  if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
 
  386    return AttributeInsertion::createInsertionAfter(D);
 
  388  if (
const auto *TD = dyn_cast<TagDecl>(D)) {
 
  394    return AttributeInsertion::createInsertionAfter(Loc);
 
  396  return AttributeInsertion::createInsertionBefore(D);
 
 
  416                                      bool ObjCPropertyAccess) {
 
  418  unsigned diag, diag_message, diag_fwdclass_message;
 
  419  unsigned diag_available_here = diag::note_availability_specified_here;
 
  423  unsigned property_note_select;
 
  426  unsigned available_here_select_kind;
 
  428  VersionTuple DeclVersion;
 
  432    DeclVersion = AA->getIntroduced();
 
  433    IIEnv = AA->getEnvironment();
 
  444  if (AA && AA->isInherited()) {
 
  447      const AvailabilityAttr *AForRedecl =
 
  449      if (AForRedecl && !AForRedecl->isInherited()) {
 
  452        NoteLocation = Redecl->getLocation();
 
  464    assert(AA != 
nullptr && 
"expecting valid availability attribute");
 
  465    VersionTuple Introduced = AA->getIntroduced();
 
  466    bool EnvironmentMatchesOrNone =
 
  470    std::string PlatformName(
 
  472    llvm::StringRef TargetEnvironment(
 
  473        llvm::Triple::getEnvironmentTypeName(TI.
getTriple().getEnvironment()));
 
  474    llvm::StringRef AttrEnvironment =
 
  475        AA->getEnvironment() ? AA->getEnvironment()->getName() : 
"";
 
  476    bool UseEnvironment =
 
  477        (!AttrEnvironment.empty() && !TargetEnvironment.empty());
 
  481        Introduced, EnvironmentMatchesOrNone);
 
  483    S.
Diag(Loc, DiagKind) << OffendingDecl << PlatformName
 
  484                          << Introduced.getAsString() << UseEnvironment
 
  485                          << TargetEnvironment;
 
  488           diag::note_partial_availability_specified_here)
 
  489        << OffendingDecl << PlatformName << Introduced.getAsString()
 
  491        << UseEnvironment << AttrEnvironment << TargetEnvironment;
 
  498      if (
const auto *TD = dyn_cast<TagDecl>(Enclosing))
 
  499        if (TD->getDeclName().isEmpty()) {
 
  500          S.
Diag(TD->getLocation(),
 
  501                 diag::note_decl_unguarded_availability_silence)
 
  502              <<  1 << TD->getKindName();
 
  506          S.
Diag(Enclosing->getLocation(),
 
  507                 diag::note_decl_unguarded_availability_silence)
 
  510      if (Enclosing->hasAttr<AvailabilityAttr>())
 
  519      StringRef PlatformName =
 
  532      std::vector<StringRef> EquivalentPlatforms =
 
  533          AvailabilityAttr::equivalentPlatformNames(PlatformName);
 
  534      llvm::Twine MacroPrefix = 
"__API_AVAILABLE_PLATFORM_";
 
  535      auto AvailablePlatform =
 
  536          llvm::find_if(EquivalentPlatforms, [&](StringRef EquivalentPlatform) {
 
  537            return PP.
isMacroDefined((MacroPrefix + EquivalentPlatform).str());
 
  539      if (AvailablePlatform == EquivalentPlatforms.end())
 
  541      std::string Introduced =
 
  545          (llvm::Twine(Insertion->Prefix) + 
"API_AVAILABLE(" +
 
  546           *AvailablePlatform + 
"(" + Introduced + 
"))" + Insertion->Suffix)
 
  555        FD && FD->isImplicit())
 
  558    if (ObjCPropertyAccess)
 
  559      diag = diag::warn_property_method_deprecated;
 
  561      diag = diag::warn_deprecated_switch_case;
 
  563      diag = diag::warn_deprecated;
 
  565    diag_message = diag::warn_deprecated_message;
 
  566    diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
 
  567    property_note_select =  0;
 
  568    available_here_select_kind =  2;
 
  569    if (
const auto *AL = OffendingDecl->
getAttr<DeprecatedAttr>())
 
  570      NoteLocation = AL->getLocation();
 
  574    diag = !ObjCPropertyAccess ? diag::err_unavailable
 
  575                               : diag::err_property_method_unavailable;
 
  576    diag_message = diag::err_unavailable_message;
 
  577    diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
 
  578    property_note_select =  1;
 
  579    available_here_select_kind =  0;
 
  581    if (
auto AL = OffendingDecl->
getAttr<UnavailableAttr>()) {
 
  582      if (AL->isImplicit() && AL->getImplicitReason()) {
 
  585        auto flagARCError = [&] {
 
  589            diag = diag::err_unavailable_in_arc;
 
  592        switch (AL->getImplicitReason()) {
 
  593        case UnavailableAttr::IR_None: 
break;
 
  595        case UnavailableAttr::IR_ARCForbiddenType:
 
  597          diag_available_here = diag::note_arc_forbidden_type;
 
  600        case UnavailableAttr::IR_ForbiddenWeak:
 
  602            diag_available_here = diag::note_arc_weak_disabled;
 
  604            diag_available_here = diag::note_arc_weak_no_runtime;
 
  607        case UnavailableAttr::IR_ARCForbiddenConversion:
 
  609          diag_available_here = diag::note_performs_forbidden_arc_conversion;
 
  612        case UnavailableAttr::IR_ARCInitReturnsUnrelated:
 
  614          diag_available_here = diag::note_arc_init_returns_unrelated;
 
  617        case UnavailableAttr::IR_ARCFieldWithOwnership:
 
  619          diag_available_here = diag::note_arc_field_with_ownership;
 
  627    llvm_unreachable(
"Warning for availability of available declaration?");
 
  632    StringRef Replacement;
 
  633    if (
auto AL = OffendingDecl->
getAttr<DeprecatedAttr>())
 
  634      Replacement = AL->getReplacement();
 
  636      Replacement = AL->getReplacement();
 
  639    if (!Replacement.empty())
 
  643      if (
const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(ReferringDecl)) {
 
  644        Selector Sel = MethodDecl->getSelector();
 
  648        if (NumParams && *NumParams == Sel.
getNumArgs()) {
 
  649          assert(SelectorSlotNames.size() == Locs.size());
 
  650          for (
unsigned I = 0; I < Locs.size(); ++I) {
 
  655                  NameRange, SelectorSlotNames[I]));
 
  673  bool ShouldAllowWarningInSystemHeader =
 
  674      InstantiationLoc != Loc &&
 
  676  struct AllowWarningInSystemHeaders {
 
  678                                bool AllowWarningInSystemHeaders)
 
  682    ~AllowWarningInSystemHeaders() { Engine.setSuppressSystemWarnings(Prev); }
 
  688                              ShouldAllowWarningInSystemHeader);
 
  690  if (!Message.empty()) {
 
  691    S.
Diag(Loc, diag_message) << ReferringDecl << Message << FixIts;
 
  694          << ObjCProperty->
getDeclName() << property_note_select;
 
  695  } 
else if (!UnknownObjCClass) {
 
  696    S.
Diag(Loc, 
diag) << ReferringDecl << FixIts;
 
  699          << ObjCProperty->
getDeclName() << property_note_select;
 
  701    S.
Diag(Loc, diag_fwdclass_message) << ReferringDecl << FixIts;
 
  705  S.
Diag(NoteLocation, diag_available_here)
 
  706    << OffendingDecl << available_here_select_kind;
 
 
  711         "Expected an availability diagnostic here");
 
 
  728                                    bool ObjCPropertyAccess) {
 
  733            AR, Locs, ReferringDecl, OffendingDecl, UnknownObjCClass,
 
  734            ObjCProperty, Message, ObjCPropertyAccess));
 
  740                            Message, Locs, UnknownObjCClass, ObjCProperty,
 
 
  747bool isBodyLikeChildStmt(
const Stmt *S, 
const Stmt *Parent) {
 
  749  case Stmt::IfStmtClass:
 
  752  case Stmt::WhileStmtClass:
 
  754  case Stmt::DoStmtClass:
 
  756  case Stmt::ForStmtClass:
 
  758  case Stmt::CXXForRangeStmtClass:
 
  760  case Stmt::ObjCForCollectionStmtClass:
 
  762  case Stmt::CaseStmtClass:
 
  763  case Stmt::DefaultStmtClass:
 
  774  bool VisitStmt(Stmt *S)
 override { 
return S != 
Target; }
 
  777  static bool isContained(
const Stmt *
Target, 
const Decl *D) {
 
  778    StmtUSEFinder Visitor;
 
  780    return !Visitor.TraverseDecl(
const_cast<Decl *
>(D));
 
  790  bool VisitDeclRefExpr(DeclRefExpr *DRE)
 override {
 
  796  static const Stmt *findLastStmtThatUsesDecl(
const Decl *D,
 
  798    LastDeclUSEFinder Visitor;
 
  800    for (
const Stmt *S : llvm::reverse(Scope->
body())) {
 
  801      if (!Visitor.TraverseStmt(
const_cast<Stmt *
>(S)))
 
  819  SmallVector<VersionTuple, 8> AvailabilityStack;
 
  820  SmallVector<const Stmt *, 16> StmtStack;
 
  822  void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range,
 
  823                                ObjCInterfaceDecl *ClassReceiver = 
nullptr);
 
  826  DiagnoseUnguardedAvailability(Sema &SemaRef, Decl *Ctx)
 
  827      : SemaRef(SemaRef), Ctx(Ctx) {
 
  828    AvailabilityStack.push_back(
 
  832  bool TraverseStmt(Stmt *S)
 override {
 
  835    StmtStack.push_back(S);
 
  837    StmtStack.pop_back();
 
  841  void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
 
  843  bool TraverseIfStmt(IfStmt *
If) 
override;
 
  847  bool TraverseCaseStmt(CaseStmt *CS)
 override {
 
  851  bool VisitObjCMessageExpr(ObjCMessageExpr *Msg)
 override {
 
  853      ObjCInterfaceDecl *
ID = 
nullptr;
 
  858      DiagnoseDeclAvailability(
 
  864  bool VisitDeclRefExpr(DeclRefExpr *DRE)
 override {
 
  865    DiagnoseDeclAvailability(DRE->
getDecl(),
 
  870  bool VisitMemberExpr(MemberExpr *ME)
 override {
 
  876  bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E)
 override {
 
  882  bool VisitTypeLoc(TypeLoc Ty) 
override;
 
  885void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
 
  889  std::tie(
Result, OffendingDecl) =
 
  897    const AvailabilityAttr *AA =
 
  899    assert(AA != 
nullptr && 
"expecting valid availability attribute");
 
  900    bool EnvironmentMatchesOrNone =
 
  902    VersionTuple Introduced = AA->getIntroduced();
 
  904    if (EnvironmentMatchesOrNone && AvailabilityStack.back() >= Introduced)
 
  910                                             AA->getEnvironment(), Ctx,
 
  915    std::string PlatformName(
 
  917    llvm::StringRef TargetEnvironment(TI.
getTriple().getEnvironmentName());
 
  918    llvm::StringRef AttrEnvironment =
 
  919        AA->getEnvironment() ? AA->getEnvironment()->getName() : 
"";
 
  920    bool UseEnvironment =
 
  921        (!AttrEnvironment.empty() && !TargetEnvironment.empty());
 
  926        EnvironmentMatchesOrNone);
 
  929        << 
Range << D << PlatformName << Introduced.getAsString()
 
  930        << UseEnvironment << TargetEnvironment;
 
  933                 diag::note_partial_availability_specified_here)
 
  934        << OffendingDecl << PlatformName << Introduced.getAsString()
 
  936        << UseEnvironment << AttrEnvironment << TargetEnvironment;
 
  943        SemaRef.
Diag(
Range.getBegin(), diag::note_unguarded_available_silence)
 
  949    if (StmtStack.empty())
 
  951    const Stmt *StmtOfUse = StmtStack.back();
 
  953    for (
const Stmt *S : llvm::reverse(StmtStack)) {
 
  954      if (
const auto *CS = dyn_cast<CompoundStmt>(S)) {
 
  958      if (isBodyLikeChildStmt(StmtOfUse, S)) {
 
  966    const Stmt *LastStmtOfUse = 
nullptr;
 
  969        if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
 
  970          LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D, 
Scope);
 
  980        SM.getExpansionRange(
 
  981              (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getEndLoc())
 
  983    if (
SM.getFileID(IfInsertionLoc) != 
SM.getFileID(StmtEndLoc))
 
  987    const char *ExtraIndentation = 
"    ";
 
  988    std::string FixItString;
 
  989    llvm::raw_string_ostream FixItOS(FixItString);
 
  991                                                     : 
"__builtin_available")
 
  993            << AvailabilityAttr::getPlatformNameSourceSpelling(
 
  995            << 
" " << Introduced.getAsString() << 
", *)) {\n" 
  996            << Indentation << ExtraIndentation;
 
 1004    FixItOS.str().clear();
 
 1006            << Indentation << 
"} else {\n" 
 1007            << Indentation << ExtraIndentation
 
 1008            << 
"// Fallback on earlier versions\n" 
 1009            << Indentation << 
"}";
 
 1014bool DiagnoseUnguardedAvailability::VisitTypeLoc(
TypeLoc Ty) {
 
 1018  if (
Range.isInvalid())
 
 1021  if (
const auto *TT = dyn_cast<TagType>(TyPtr)) {
 
 1023    DiagnoseDeclAvailability(TD, Range);
 
 1025  } 
else if (
const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
 
 1027    DiagnoseDeclAvailability(D, Range);
 
 1029  } 
else if (
const auto *ObjCO = dyn_cast<ObjCObjectType>(TyPtr)) {
 
 1030    if (
NamedDecl *D = ObjCO->getInterface())
 
 1031      DiagnoseDeclAvailability(D, Range);
 
 1037struct ExtractedAvailabilityExpr {
 
 1038  const ObjCAvailabilityCheckExpr *E = 
nullptr;
 
 1039  bool isNegated = 
false;
 
 1042ExtractedAvailabilityExpr extractAvailabilityExpr(
const Expr *IfCond) {
 
 1043  const auto *E = IfCond;
 
 1044  bool IsNegated = 
false;
 
 1047    if (
const auto *AE = dyn_cast<ObjCAvailabilityCheckExpr>(E)) {
 
 1048      return ExtractedAvailabilityExpr{AE, IsNegated};
 
 1051    const auto *UO = dyn_cast<UnaryOperator>(E);
 
 1052    if (!UO || UO->getOpcode() != UO_LNot) {
 
 1053      return ExtractedAvailabilityExpr{};
 
 1055    E = UO->getSubExpr();
 
 1056    IsNegated = !IsNegated;
 
 1060bool DiagnoseUnguardedAvailability::TraverseIfStmt(
IfStmt *
If) {
 
 1061  ExtractedAvailabilityExpr IfCond = extractAvailabilityExpr(
If->getCond());
 
 1064    return DynamicRecursiveASTVisitor::TraverseIfStmt(
If);
 
 1067  VersionTuple CondVersion = IfCond.E->
getVersion();
 
 1070  if (CondVersion.empty() || CondVersion <= AvailabilityStack.back()) {
 
 1071    return TraverseStmt(
If->getThen()) && TraverseStmt(
If->getElse());
 
 1074  auto *Guarded = 
If->getThen();
 
 1075  auto *Unguarded = 
If->getElse();
 
 1076  if (IfCond.isNegated) {
 
 1077    std::swap(Guarded, Unguarded);
 
 1080  AvailabilityStack.push_back(CondVersion);
 
 1081  bool ShouldContinue = TraverseStmt(Guarded);
 
 1082  AvailabilityStack.pop_back();
 
 1084  return ShouldContinue && TraverseStmt(Unguarded);
 
 1090  Stmt *Body = 
nullptr;
 
 1093    Body = FD->getBody();
 
 1095    if (
auto *CD = dyn_cast<CXXConstructorDecl>(FD))
 
 1097        DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(CI->getInit());
 
 1099  } 
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(D))
 
 1100    Body = MD->getBody();
 
 1101  else if (
auto *BD = dyn_cast<BlockDecl>(D))
 
 1102    Body = BD->getBody();
 
 1104  assert(Body && 
"Need a body here!");
 
 1106  DiagnoseUnguardedAvailability(*
this, D).IssueDiagnostics(Body);
 
 
 1123                                      bool ObjCPropertyAccess,
 
 1124                                      bool AvoidPartialAvailabilityChecks,
 
 1127  std::string Message;
 
 1131  std::tie(
Result, OffendingDecl) =
 
 1137    if (AvoidPartialAvailabilityChecks)
 
 1144      Context->HasPotentialAvailabilityViolations = 
true;
 
 1150  if (
const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
 
 1153      if (PDeclResult == 
Result)
 
 1159                          UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);
 
 
Defines the C++ template declaration subclasses.
Defines the classes clang::DelayedDiagnostic and clang::AccessedEntity.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Defines the clang::LangOptions interface.
llvm::MachO::Target Target
Defines the clang::Preprocessor interface.
static unsigned getAvailabilityDiagnosticKind(const ASTContext &Context, const VersionTuple &DeploymentVersion, const VersionTuple &DeclVersion, bool HasMatchingEnv)
static bool hasMatchingEnvironmentOrNone(const ASTContext &Context, const AvailabilityAttr *AA)
static std::optional< AttributeInsertion > createAttributeInsertion(const NamedDecl *D, const SourceManager &SM, const LangOptions &LangOpts)
Returns a source location in which it's appropriate to insert a new attribute for the given declarati...
static void EmitAvailabilityWarning(Sema &S, AvailabilityResult AR, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, StringRef Message, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess)
static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, Decl *Ctx, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, StringRef Message, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess)
Actually emit an availability diagnostic for a reference to an unavailable decl.
static NamedDecl * findEnclosingDeclToAnnotate(Decl *OrigCtx)
static std::optional< unsigned > tryParseObjCMethodName(StringRef Name, SmallVectorImpl< StringRef > &SlotNames, const LangOptions &LangOpts)
Tries to parse a string as ObjC method name.
static const AvailabilityAttr * getAttrForPlatform(ASTContext &Context, const Decl *D)
static bool ShouldDiagnoseAvailabilityInContext(Sema &S, AvailabilityResult K, VersionTuple DeclVersion, const IdentifierInfo *DeclEnv, Decl *Ctx, const NamedDecl *OffendingDecl)
whether we should emit a diagnostic for K and DeclVersion in the context of Ctx.
This file declares semantic analysis for Objective-C.
Defines the Objective-C statement AST node classes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const TargetInfo & getTargetInfo() const
Represents a C++ base or member initializer.
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
CompoundStmt - This represents a group of statements like { stmt stmt }.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
SourceLocation getEndLoc() const LLVM_READONLY
AvailabilityResult getAvailability(std::string *Message=nullptr, VersionTuple EnclosingVersion=VersionTuple(), StringRef *RealizedPlatform=nullptr) const
Determine the availability of the given declaration.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
VersionTuple getVersionIntroduced() const
Retrieve the version of the target platform in which this declaration was introduced.
Concrete class used by the front-end to report problems and issues.
void setSuppressSystemWarnings(bool Val)
When set to true mask warnings that come from system headers.
bool getSuppressSystemWarnings() const
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
IfStmt - This represents an if/then/else.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static SourceLocation findLocationAfterToken(SourceLocation loc, tok::TokenKind TKind, const SourceManager &SM, const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine)
Checks that the given token is the first token that occurs after the given location (this excludes co...
static StringRef getIndentationForLine(SourceLocation Loc, const SourceManager &SM)
Returns the leading whitespace for line that corresponds to the given location Loc.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getBeginLoc() const LLVM_READONLY
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
NamedDecl * getMostRecentDecl()
SourceLocation getBeginLoc() const
VersionTuple getVersion() const
Represents an ObjC class declaration.
ObjCMethodDecl * lookupInstanceMethod(Selector Sel) const
Lookup an instance method for a given selector.
QualType getClassReceiver() const
Returns the type of a class message send, or NULL if the message is not a class message.
const ObjCMethodDecl * getMethodDecl() const
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation getSelectorStartLoc() const
ObjCMethodDecl - Represents an instance or class method declaration.
Represents one property declaration in an Objective-C interface.
static ObjCPropertyDecl * findPropertyDecl(const DeclContext *DC, const IdentifierInfo *propertyID, ObjCPropertyQueryKind queryKind)
Lookup a property by name in the specified DeclContext.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
bool isMacroDefined(StringRef Id)
StringRef getImmediateMacroName(SourceLocation Loc)
Retrieve the name of the immediate macro expansion.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Scope - A scope is a transient data structure that is used while parsing the program.
Smart pointer class that efficiently represents Objective-C method names.
StringRef getNameForSlot(unsigned argIndex) const
Retrieve the name at a given position in the selector.
unsigned getNumArgs() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool shouldDelayDiagnostics()
Determines whether diagnostics should be delayed.
void add(const sema::DelayedDiagnostic &diag)
Adds a delayed diagnostic.
Sema - This implements semantic analysis and AST building for C.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Preprocessor & getPreprocessor() const
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
class clang::Sema::DelayedDiagnostics DelayedDiagnostics
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
DiagnosticsEngine & getDiagnostics() const
ASTContext & getASTContext() const
void DiagnoseUnguardedAvailabilityViolations(Decl *FD)
Issue any -Wunguarded-availability warnings in FD.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
DeclContext * getCurLexicalContext() const
SourceManager & getSourceManager() const
void DiagnoseAvailabilityOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass, bool ObjCPropertyAccess, bool AvoidPartialAvailabilityChecks, ObjCInterfaceDecl *ClassReceiver)
std::pair< AvailabilityResult, const NamedDecl * > ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message, ObjCInterfaceDecl *ClassReceiver)
The diagnostic we should emit for D, and the declaration that originated it, or AR_Available.
sema::FunctionScopeInfo * getCurFunctionAvailabilityContext()
Retrieve the current function, if any, that should be analyzed for potential availability violations.
SourceLocation getTopMostPointOfInstantiation(const NamedDecl *) const
Returns the top most location responsible for the definition of N.
void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx)
Encodes a location in the source.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents the declaration of a struct/union/class/enum.
TagDecl * getDefinitionOrSelf() const
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
StringRef getPlatformName() const
Retrieve the name of the platform as it is used in the availability attribute.
VersionTuple getPlatformMinVersion() const
Retrieve the minimum desired version of the platform, to which the program should be compiled.
Base wrapper for a particular "section" of type source info.
SourceLocation getEndLoc() const
Get the end source location.
SourceLocation getBeginLoc() const
Get the begin source location.
const Type * getTypePtr() const
The base class of the type hierarchy.
const ObjCObjectType * getAsObjCInterfaceType() const
Base class for declarations which introduce a typedef-name.
A diagnostic message which has been conditionally emitted pending the complete parsing of the current...
static DelayedDiagnostic makeAvailability(AvailabilityResult AR, ArrayRef< SourceLocation > Locs, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, StringRef Msg, bool ObjCPropertyAccess)
const ObjCInterfaceDecl * getUnknownObjCClass() const
const NamedDecl * getAvailabilityOffendingDecl() const
const ObjCPropertyDecl * getObjCProperty() const
StringRef getAvailabilityMessage() const
ArrayRef< SourceLocation > getAvailabilitySelectorLocs() const
AvailabilityResult getAvailabilityResult() const
const NamedDecl * getAvailabilityReferringDecl() const
Retains information about a function, method, or block that is currently being parsed.
Defines the clang::TargetInfo interface.
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.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
LLVM_READONLY bool isValidAsciiIdentifier(StringRef S, bool AllowDollar=false)
Return true if this is a valid ASCII identifier.
@ Result
The result type of a method or function.
const FunctionProtoType * T
AvailabilityResult
Captures the result of checking the availability of a declaration.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
bool IsCaseExpr
Whether evaluating an expression for a switch case label.