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 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 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 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 << " static enum Attribute::AttrKind getKind() {\n"; 125 OS << " return llvm::Attribute::" << R->getName() << ";\n"; 126 OS << " }\n"; 127 OS << "};\n"; 128 } 129 OS << "\n"; 130 } 131 132 void Attributes::printStrBoolAttrClasses(raw_ostream &OS, 133 const std::vector<Record *> &Records) { 134 OS << "// StrBoolAttr classes\n"; 135 for (const auto *R : Records) { 136 OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n"; 137 OS << " static const char *getKind() {\n"; 138 OS << " return \"" << R->getValueAsString("AttrString") << "\";\n"; 139 OS << " }\n"; 140 OS << "};\n"; 141 } 142 OS << "\n"; 143 } 144 145 void Attributes::emit(raw_ostream &OS) { 146 emitTargetIndependentEnums(OS); 147 emitFnAttrCompatCheck(OS, false); 148 } 149 150 namespace llvm { 151 152 void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) { 153 Attributes(RK).emit(OS); 154 } 155 156 } // End llvm namespace. 157