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 AttributeMask(AttributeSet AS)38 AttributeMask(AttributeSet AS) { 39 for (Attribute A : AS) 40 addAttribute(A); 41 } 42 43 /// Add an attribute to the mask. addAttribute(Attribute::AttrKind Val)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. addAttribute(Attribute A)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. addAttribute(StringRef A)61 AttributeMask &addAttribute(StringRef A) { 62 TargetDepAttrs.insert(A); 63 return *this; 64 } 65 66 /// Return true if the builder has the specified attribute. contains(Attribute::AttrKind A)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. contains(StringRef A)74 bool contains(StringRef A) const { return TargetDepAttrs.count(A); } 75 76 /// Return true if the mask contains the specified attribute. contains(Attribute A)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