1 //===- llvm/AttributeMask.h - Mask for Attributes ---------------*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 // This file declares the AttributeMask class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_IR_ATTRIBUTEMASK_H
15 #define LLVM_IR_ATTRIBUTEMASK_H
16 
17 #include "llvm/ADT/SmallString.h"
18 #include "llvm/IR/Attributes.h"
19 #include <bitset>
20 #include <cassert>
21 #include <set>
22 
23 namespace llvm {
24 
25 //===----------------------------------------------------------------------===//
26 /// \class
27 /// This class stores enough information to efficiently remove some attributes
28 /// from an existing AttrBuilder, AttributeSet or AttributeList.
29 class AttributeMask {
30   std::bitset<Attribute::EndAttrKinds> Attrs;
31   std::set<SmallString<32>, std::less<>> TargetDepAttrs;
32 
33 public:
34   AttributeMask() = default;
35   AttributeMask(const AttributeMask &) = delete;
36   AttributeMask(AttributeMask &&) = default;
37 
38   AttributeMask(AttributeSet AS) {
39     for (Attribute A : AS)
40       addAttribute(A);
41   }
42 
43   /// Add an attribute to the mask.
44   AttributeMask &addAttribute(Attribute::AttrKind Val) {
45     assert((unsigned)Val < Attribute::EndAttrKinds &&
46            "Attribute out of range!");
47     Attrs[Val] = true;
48     return *this;
49   }
50 
51   /// Add the Attribute object to the builder.
52   AttributeMask &addAttribute(Attribute A) {
53     if (A.isStringAttribute())
54       addAttribute(A.getKindAsString());
55     else
56       addAttribute(A.getKindAsEnum());
57     return *this;
58   }
59 
60   /// Add the target-dependent attribute to the builder.
61   AttributeMask &addAttribute(StringRef A) {
62     TargetDepAttrs.insert(A);
63     return *this;
64   }
65 
66   /// Return true if the builder has the specified attribute.
67   bool contains(Attribute::AttrKind A) const {
68     assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
69     return Attrs[A];
70   }
71 
72   /// Return true if the builder has the specified target-dependent
73   /// attribute.
74   bool contains(StringRef A) const { return TargetDepAttrs.count(A); }
75 
76   /// Return true if the mask contains the specified attribute.
77   bool contains(Attribute A) const {
78     if (A.isStringAttribute())
79       return contains(A.getKindAsString());
80     return contains(A.getKindAsEnum());
81   }
82 };
83 
84 } // end namespace llvm
85 
86 #endif // LLVM_IR_ATTRIBUTEMASK_H
87