]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/utils/TableGen/Attributes.cpp
MFV r337210: 9577 remove zfs_dbuf_evict_key tsd
[FreeBSD/FreeBSD.git] / contrib / llvm / utils / TableGen / Attributes.cpp
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/MemoryBuffer.h"
11 #include "llvm/TableGen/Record.h"
12 #include <algorithm>
13 #include <string>
14 #include <vector>
15 using namespace llvm;
16
17 #define DEBUG_TYPE "attr-enum"
18
19 namespace {
20
21 class Attributes {
22 public:
23   Attributes(RecordKeeper &R) : Records(R) {}
24   void emit(raw_ostream &OS);
25
26 private:
27   void emitTargetIndependentEnums(raw_ostream &OS);
28   void emitConversionFn(raw_ostream &OS);
29   void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
30
31   void printEnumAttrClasses(raw_ostream &OS,
32                             const std::vector<Record *> &Records);
33   void printStrBoolAttrClasses(raw_ostream &OS,
34                                const std::vector<Record *> &Records);
35
36   RecordKeeper &Records;
37 };
38
39 } // End anonymous namespace.
40
41 void Attributes::emitTargetIndependentEnums(raw_ostream &OS) {
42   OS << "#ifdef GET_ATTR_ENUM\n";
43   OS << "#undef GET_ATTR_ENUM\n";
44
45   std::vector<Record*> Attrs =
46       Records.getAllDerivedDefinitions("EnumAttr");
47
48   for (auto A : Attrs)
49     OS << A->getName() << ",\n";
50
51   OS << "#endif\n";
52 }
53
54 void Attributes::emitConversionFn(raw_ostream &OS) {
55   OS << "#ifdef GET_ATTR_KIND_FROM_NAME\n";
56   OS << "#undef GET_ATTR_KIND_FROM_NAME\n";
57
58   std::vector<Record*> Attrs =
59       Records.getAllDerivedDefinitions("EnumAttr");
60
61   OS << "static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {\n";
62   OS << "  return StringSwitch<Attribute::AttrKind>(AttrName)\n";
63
64   for (auto A : Attrs) {
65     OS << "    .Case(\"" << A->getValueAsString("AttrString");
66     OS << "\", Attribute::" << A->getName() << ")\n";
67   }
68
69   OS << "    .Default(Attribute::None);\n";
70   OS << "}\n\n";
71
72   OS << "#endif\n";
73 }
74
75 void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
76   OS << "#ifdef GET_ATTR_COMPAT_FUNC\n";
77   OS << "#undef GET_ATTR_COMPAT_FUNC\n";
78
79   OS << "struct EnumAttr {\n";
80   OS << "  static bool isSet(const Function &Fn,\n";
81   OS << "                    Attribute::AttrKind Kind) {\n";
82   OS << "    return Fn.hasFnAttribute(Kind);\n";
83   OS << "  }\n\n";
84   OS << "  static void set(Function &Fn,\n";
85   OS << "                  Attribute::AttrKind Kind, bool Val) {\n";
86   OS << "    if (Val)\n";
87   OS << "      Fn.addFnAttr(Kind);\n";
88   OS << "    else\n";
89   OS << "      Fn.removeFnAttr(Kind);\n";
90   OS << "  }\n";
91   OS << "};\n\n";
92
93   OS << "struct StrBoolAttr {\n";
94   OS << "  static bool isSet(const Function &Fn,\n";
95   OS << "                    StringRef Kind) {\n";
96   OS << "    auto A = Fn.getFnAttribute(Kind);\n";
97   OS << "    return A.getValueAsString().equals(\"true\");\n";
98   OS << "  }\n\n";
99   OS << "  static void set(Function &Fn,\n";
100   OS << "                  StringRef Kind, bool Val) {\n";
101   OS << "    Fn.addFnAttr(Kind, Val ? \"true\" : \"false\");\n";
102   OS << "  }\n";
103   OS << "};\n\n";
104
105   printEnumAttrClasses(OS ,Records.getAllDerivedDefinitions("EnumAttr"));
106   printStrBoolAttrClasses(OS , Records.getAllDerivedDefinitions("StrBoolAttr"));
107
108   OS << "static inline bool hasCompatibleFnAttrs(const Function &Caller,\n"
109      << "                                        const Function &Callee) {\n";
110   OS << "  bool Ret = true;\n\n";
111
112   std::vector<Record *> CompatRules =
113       Records.getAllDerivedDefinitions("CompatRule");
114
115   for (auto *Rule : CompatRules) {
116     StringRef FuncName = Rule->getValueAsString("CompatFunc");
117     OS << "  Ret &= " << FuncName << "(Caller, Callee);\n";
118   }
119
120   OS << "\n";
121   OS << "  return Ret;\n";
122   OS << "}\n\n";
123
124   std::vector<Record *> MergeRules =
125       Records.getAllDerivedDefinitions("MergeRule");
126   OS << "static inline void mergeFnAttrs(Function &Caller,\n"
127      << "                                const Function &Callee) {\n";
128
129   for (auto *Rule : MergeRules) {
130     StringRef FuncName = Rule->getValueAsString("MergeFunc");
131     OS << "  " << FuncName << "(Caller, Callee);\n";
132   }
133
134   OS << "}\n\n";
135
136   OS << "#endif\n";
137 }
138
139 void Attributes::printEnumAttrClasses(raw_ostream &OS,
140                                       const std::vector<Record *> &Records) {
141   OS << "// EnumAttr classes\n";
142   for (const auto *R : Records) {
143     OS << "struct " << R->getName() << "Attr : EnumAttr {\n";
144     OS << "  static enum Attribute::AttrKind getKind() {\n";
145     OS << "    return llvm::Attribute::" << R->getName() << ";\n";
146     OS << "  }\n";
147     OS << "};\n";
148   }
149   OS << "\n";
150 }
151
152 void Attributes::printStrBoolAttrClasses(raw_ostream &OS,
153                                          const std::vector<Record *> &Records) {
154   OS << "// StrBoolAttr classes\n";
155   for (const auto *R : Records) {
156     OS << "struct " << R->getName() << "Attr : StrBoolAttr {\n";
157     OS << "  static StringRef getKind() {\n";
158     OS << "    return \"" << R->getValueAsString("AttrString") << "\";\n";
159     OS << "  }\n";
160     OS << "};\n";
161   }
162   OS << "\n";
163 }
164
165 void Attributes::emit(raw_ostream &OS) {
166   emitTargetIndependentEnums(OS);
167   emitConversionFn(OS);
168   emitFnAttrCompatCheck(OS, false);
169 }
170
171 namespace llvm {
172
173 void EmitAttributes(RecordKeeper &RK, raw_ostream &OS) {
174   Attributes(RK).emit(OS);
175 }
176
177 } // End llvm namespace.