brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · cf040fc Raw
120 lines · cpp
1//===- Availability.cpp --------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the Availability information for Decls.10//11//===----------------------------------------------------------------------===//12 13#include "clang/AST/Availability.h"14#include "clang/AST/ASTContext.h"15#include "clang/AST/Attr.h"16#include "clang/AST/Decl.h"17#include "clang/Basic/TargetInfo.h"18 19namespace {20 21/// Represents the availability of a symbol across platforms.22struct AvailabilitySet {23  bool UnconditionallyDeprecated = false;24  bool UnconditionallyUnavailable = false;25 26  void insert(clang::AvailabilityInfo &&Availability) {27    auto *Found = getForPlatform(Availability.Domain);28    if (Found)29      Found->mergeWith(std::move(Availability));30    else31      Availabilities.emplace_back(std::move(Availability));32  }33 34  clang::AvailabilityInfo *getForPlatform(llvm::StringRef Domain) {35    auto *It = llvm::find_if(Availabilities,36                             [Domain](const clang::AvailabilityInfo &Info) {37                               return Domain.compare(Info.Domain) == 0;38                             });39    return It == Availabilities.end() ? nullptr : It;40  }41 42private:43  llvm::SmallVector<clang::AvailabilityInfo> Availabilities;44};45 46static void createInfoForDecl(const clang::Decl *Decl,47                              AvailabilitySet &Availabilities) {48  // Collect availability attributes from all redeclarations.49  for (const auto *RD : Decl->redecls()) {50    for (const auto *A : RD->specific_attrs<clang::AvailabilityAttr>()) {51      Availabilities.insert(clang::AvailabilityInfo(52          A->getPlatform()->getName(), A->getIntroduced(), A->getDeprecated(),53          A->getObsoleted(), A->getUnavailable(), false, false));54    }55 56    if (const auto *A = RD->getAttr<clang::UnavailableAttr>())57      if (!A->isImplicit())58        Availabilities.UnconditionallyUnavailable = true;59 60    if (const auto *A = RD->getAttr<clang::DeprecatedAttr>())61      if (!A->isImplicit())62        Availabilities.UnconditionallyDeprecated = true;63  }64}65 66} // namespace67 68namespace clang {69 70void AvailabilityInfo::mergeWith(AvailabilityInfo Other) {71  if (isDefault() && Other.isDefault())72    return;73 74  if (Domain.empty())75    Domain = Other.Domain;76 77  UnconditionallyUnavailable |= Other.UnconditionallyUnavailable;78  UnconditionallyDeprecated |= Other.UnconditionallyDeprecated;79  Unavailable |= Other.Unavailable;80 81  Introduced = std::max(Introduced, Other.Introduced);82 83  // Default VersionTuple is 0.0.0 so if both are non default let's pick the84  // smallest version number, otherwise select the one that is non-zero if there85  // is one.86  if (!Deprecated.empty() && !Other.Deprecated.empty())87    Deprecated = std::min(Deprecated, Other.Deprecated);88  else89    Deprecated = std::max(Deprecated, Other.Deprecated);90 91  if (!Obsoleted.empty() && !Other.Obsoleted.empty())92    Obsoleted = std::min(Obsoleted, Other.Obsoleted);93  else94    Obsoleted = std::max(Obsoleted, Other.Obsoleted);95}96 97AvailabilityInfo AvailabilityInfo::createFromDecl(const Decl *D) {98  AvailabilitySet Availabilities;99  // Walk DeclContexts upwards starting from D to find the combined availability100  // of the symbol.101  for (const auto *Ctx = D; Ctx;102       Ctx = llvm::cast_or_null<Decl>(Ctx->getDeclContext()))103    createInfoForDecl(Ctx, Availabilities);104 105  if (auto *Avail = Availabilities.getForPlatform(106          D->getASTContext().getTargetInfo().getPlatformName())) {107    Avail->UnconditionallyDeprecated = Availabilities.UnconditionallyDeprecated;108    Avail->UnconditionallyUnavailable =109        Availabilities.UnconditionallyUnavailable;110    return std::move(*Avail);111  }112 113  AvailabilityInfo Avail;114  Avail.UnconditionallyDeprecated = Availabilities.UnconditionallyDeprecated;115  Avail.UnconditionallyUnavailable = Availabilities.UnconditionallyUnavailable;116  return Avail;117}118 119} // namespace clang120