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