xref: /openbsd-src/gnu/llvm/clang/lib/ExtractAPI/AvailabilityInfo.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1*12c85518Srobert #include "clang/ExtractAPI/AvailabilityInfo.h"
2*12c85518Srobert #include "clang/AST/Attr.h"
3*12c85518Srobert #include "llvm/ADT/STLExtras.h"
4*12c85518Srobert 
5*12c85518Srobert using namespace clang;
6*12c85518Srobert using namespace extractapi;
7*12c85518Srobert 
AvailabilitySet(const Decl * Decl)8*12c85518Srobert AvailabilitySet::AvailabilitySet(const Decl *Decl) {
9*12c85518Srobert   // Collect availability attributes from all redeclrations.
10*12c85518Srobert   for (const auto *RD : Decl->redecls()) {
11*12c85518Srobert     if (const auto *A = RD->getAttr<UnavailableAttr>()) {
12*12c85518Srobert       if (!A->isImplicit()) {
13*12c85518Srobert         this->Availabilities.clear();
14*12c85518Srobert         UnconditionallyUnavailable = true;
15*12c85518Srobert       }
16*12c85518Srobert     }
17*12c85518Srobert 
18*12c85518Srobert     if (const auto *A = RD->getAttr<DeprecatedAttr>()) {
19*12c85518Srobert       if (!A->isImplicit()) {
20*12c85518Srobert         this->Availabilities.clear();
21*12c85518Srobert         UnconditionallyDeprecated = true;
22*12c85518Srobert       }
23*12c85518Srobert     }
24*12c85518Srobert 
25*12c85518Srobert     for (const auto *Attr : RD->specific_attrs<AvailabilityAttr>()) {
26*12c85518Srobert       StringRef Domain = Attr->getPlatform()->getName();
27*12c85518Srobert       auto *Availability =
28*12c85518Srobert           llvm::find_if(Availabilities, [Domain](const AvailabilityInfo &Info) {
29*12c85518Srobert             return Domain.equals(Info.Domain);
30*12c85518Srobert           });
31*12c85518Srobert       if (Availability != Availabilities.end()) {
32*12c85518Srobert         // Get the highest introduced version for all redeclarations.
33*12c85518Srobert         if (Availability->Introduced < Attr->getIntroduced())
34*12c85518Srobert           Availability->Introduced = Attr->getIntroduced();
35*12c85518Srobert 
36*12c85518Srobert         // Get the lowest deprecated version for all redeclarations.
37*12c85518Srobert         if (Availability->Deprecated > Attr->getDeprecated())
38*12c85518Srobert           Availability->Deprecated = Attr->getDeprecated();
39*12c85518Srobert 
40*12c85518Srobert         // Get the lowest obsoleted version for all redeclarations.
41*12c85518Srobert         if (Availability->Obsoleted > Attr->getObsoleted())
42*12c85518Srobert           Availability->Obsoleted = Attr->getObsoleted();
43*12c85518Srobert       } else {
44*12c85518Srobert         Availabilities.emplace_back(Domain, Attr->getIntroduced(),
45*12c85518Srobert                                     Attr->getDeprecated(),
46*12c85518Srobert                                     Attr->getObsoleted());
47*12c85518Srobert       }
48*12c85518Srobert     }
49*12c85518Srobert   }
50*12c85518Srobert }
51