1 //===- Attributes.cpp - Generate attributes -------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Support/SourceMgr.h"
11 #include "llvm/Support/MemoryBuffer.h"
12 #include "llvm/TableGen/Error.h"
13 #include "llvm/TableGen/Record.h"
19 #define DEBUG_TYPE "attr-enum"
25 Attributes(RecordKeeper &R) : Records(R) {}
26 void emit(raw_ostream &OS);
29 void emitTargetIndependentEnums(raw_ostream &OS);
30 void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
32 void printEnumAttrClasses(raw_ostream &OS,
33 const std::vector<Record *> &Records);
34 void printStrBoolAttrClasses(raw_ostream &OS,
35 const std::vector<Record *> &Records);
37 RecordKeeper &Records;
40 } // End anonymous namespace.
42 void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
43 OS << "#ifdef GET_ATTR_ENUM\n";
44 OS << "#undef GET_ATTR_ENUM\n";
46 std::vector<Record*> Attrs =
47 Records.getAllDerivedDefinitions("EnumAttr");
50 OS << A->getName() << ",\n";
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";
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";
64 OS << " static void set(Function &Fn,\n";
65 OS << " Attribute::AttrKind Kind, bool Val) {\n";
67 OS << " Fn.addFnAttr(Kind);\n";
69 OS << " Fn.removeFnAttr(Kind);\n";
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";
79 OS << " static void set(Function &Fn,\n";
80 OS << " StringRef Kind, bool Val) {\n";
81 OS << " Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
85 printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
86 printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
88 OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
89 << " const Function &Callee) {\n";
90 OS << " bool Ret = true;\n\n";
92 std::vector<Record *> CompatRules =
93 Records.getAllDerivedDefinitions("CompatRule");
95 for (auto *Rule : CompatRules) {
96 std::string FuncName = Rule->getValueAsString("CompatFunc");
97 OS << " Ret &= " << FuncName << "(Caller, Callee);\n";
101 OS << " return Ret;\n";
104 std::vector<Record *> MergeRules =
105 Records.getAllDerivedDefinitions("MergeRule");
106 OS << "static inline void mergeFnAttrs(Function &Caller,\n"
107 << " const Function &Callee) {\n";
109 for (auto *Rule : MergeRules) {
110 std::string FuncName = Rule->getValueAsString("MergeFunc");
111 OS << " " << FuncName << "(Caller, Callee);\n";
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";
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";
145 void Attributes::emit(raw_ostream &OS) {
146 emitTargetIndependentEnums(OS);
147 emitFnAttrCompatCheck(OS, false);
152 void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
153 Attributes(RK).emit(OS);
156 } // End llvm namespace.