1 //===- Attributes.cpp - Generate attributes -------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Support/SourceMgr.h" 11 #include "llvm/Support/MemoryBuffer.h" 12 #include "llvm/TableGen/Error.h" 13 #include "llvm/TableGen/Record.h" 14 #include <algorithm> 15 #include <string> 16 #include <vector> 17 using namespace llvm; 18 19 #define DEBUG_TYPE "attr-enum" 20 21 namespace { 22 23 class Attributes { 24 public: 25 Attributes(RecordKeeper &R) : Records(R) {} 26 void emit(raw_ostream &OS); 27 28 private: 29 void emitTargetIndependentEnums(raw_ostream &OS); 30 void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr); 31 32 void printEnumAttrClasses(raw_ostream &OS, 33 const std::vector<Record *> &Records); 34 void printStrBoolAttrClasses(raw_ostream &OS, 35 const std::vector<Record *> &Records); 36 37 RecordKeeper &Records; 38 }; 39 40 } // End anonymous namespace. 41 42 void Attributes::emitTargetIndependentEnums(raw_ostream &OS) { 43 OS << "#ifdef GET_ATTR_ENUM\n"; 44 OS << "#undef GET_ATTR_ENUM\n"; 45 46 const std::vector<Record*> &Attrs = 47 Records.getAllDerivedDefinitions("EnumAttr"); 48 49 for (auto A : Attrs) 50 OS << A->getName() << ",\n"; 51 52 OS << "#endif\n"; 53 } 54 55 void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) { 56 OS << "#ifdef GET_ATTR_COMPAT_FUNC\n"; 57 OS << "#undef GET_ATTR_COMPAT_FUNC\n"; 58 59 OS << "struct EnumAttr {\n"; 60 OS << " static bool isSet(const Function &Fn,\n"; 61 OS << " Attribute::AttrKind Kind) {\n"; 62 OS << " return Fn.hasFnAttribute(Kind);\n"; 63 OS << " }\n\n"; 64 OS << " static void set(Function &Fn,\n"; 65 OS << " Attribute::AttrKind Kind, bool Val) {\n"; 66 OS << " if (Val)\n"; 67 OS << " Fn.addFnAttr(Kind);\n"; 68 OS << " else\n"; 69 OS << " Fn.removeFnAttr(Kind);\n"; 70 OS << " }\n"; 71 OS << "};\n\n"; 72 73 OS << "struct StrBoolAttr {\n"; 74 OS << " static bool isSet(const Function &Fn,\n"; 75 OS << " StringRef Kind) {\n"; 76 OS << " auto A = Fn.getFnAttribute(Kind);\n"; 77 OS << " return A.getValueAsString().equals(\"true\");\n"; 78 OS << " }\n\n"; 79 OS << " static void set(Function &Fn,\n"; 80 OS << " StringRef Kind, bool Val) {\n"; 81 OS << " Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n"; 82 OS << " }\n"; 83 OS << "};\n\n"; 84 85 printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr")); 86 printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr")); 87 88 OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n" 89 << " const Function &Callee) {\n"; 90 OS << " bool Ret = true;\n\n"; 91 92 const std::vector<Record *> &CompatRules = 93 Records.getAllDerivedDefinitions("CompatRule"); 94 95 for (auto *Rule : CompatRules) { 96 std::string FuncName = Rule->getValueAsString("CompatFunc"); 97 OS << " Ret &= " << FuncName << "(Caller, Callee);\n"; 98 } 99 100 OS << "\n"; 101 OS << " return Ret;\n"; 102 OS << "}\n\n"; 103 104 const std::vector<Record *> &MergeRules = 105 Records.getAllDerivedDefinitions("MergeRule"); 106 OS << "static inline void mergeFnAttrs(Function &Caller,\n" 107 << " const Function &Callee) {\n"; 108 109 for (auto *Rule : MergeRules) { 110 std::string FuncName = Rule->getValueAsString("MergeFunc"); 111 OS << " " << FuncName << "(Caller, Callee);\n"; 112 } 113 114 OS << "}\n\n"; 115 116 OS << "#endif\n"; 117 } 118 119 void Attributes::printEnumAttrClasses(raw_ostream &OS, 120 const std::vector<Record *> &Records) { 121 OS << "// EnumAttr classes\n"; 122 for (const auto *R : Records) { 123 OS << "struct " << R->getName() << "Attr : EnumAttr {\n"; 124 OS << " constexpr static const enum Attribute::AttrKind Kind = "; 125 OS << "Attribute::" << R->getName() << ";\n"; 126 OS << "};\n"; 127 } 128 OS << "\n"; 129 } 130 131 void Attributes::printStrBoolAttrClasses(raw_ostream &OS, 132 const std::vector<Record *> &Records) { 133 OS << "// StrBoolAttr classes\n"; 134 for (const auto *R : Records) { 135 OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n"; 136 OS << " constexpr static const char * const Kind = \""; 137 OS << R->getValueAsString("AttrString") << "\";\n"; 138 OS << "};\n"; 139 } 140 OS << "\n"; 141 } 142 143 void Attributes::emit(raw_ostream &OS) { 144 emitTargetIndependentEnums(OS); 145 emitFnAttrCompatCheck(OS, false); 146 } 147 148 namespace llvm { 149 150 void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) { 151 Attributes(RK).emit(OS); 152 } 153 154 } // End llvm namespace. 155