1#ifdef GET_ATTR_ENUM
2#undef GET_ATTR_ENUM
3Alignment,
4AllocSize,
5AlwaysInline,
6ArgMemOnly,
7Builtin,
8ByVal,
9Cold,
10Convergent,
11Dereferenceable,
12DereferenceableOrNull,
13InAlloca,
14InReg,
15InaccessibleMemOnly,
16InaccessibleMemOrArgMemOnly,
17InlineHint,
18JumpTable,
19MinSize,
20Naked,
21Nest,
22NoAlias,
23NoBuiltin,
24NoCapture,
25NoDuplicate,
26NoImplicitFloat,
27NoInline,
28NoRecurse,
29NoRedZone,
30NoReturn,
31NoUnwind,
32NonLazyBind,
33NonNull,
34OptimizeForSize,
35OptimizeNone,
36ReadNone,
37ReadOnly,
38Returned,
39ReturnsTwice,
40SExt,
41SafeStack,
42SanitizeAddress,
43SanitizeMemory,
44SanitizeThread,
45StackAlignment,
46StackProtect,
47StackProtectReq,
48StackProtectStrong,
49StructRet,
50SwiftError,
51SwiftSelf,
52UWTable,
53WriteOnly,
54ZExt,
55#endif
56#ifdef GET_ATTR_KIND_FROM_NAME
57#undef GET_ATTR_KIND_FROM_NAME
58static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {
59  return StringSwitch<Attribute::AttrKind>(AttrName)
60    .Case("align", Attribute::Alignment)
61    .Case("allocsize", Attribute::AllocSize)
62    .Case("alwaysinline", Attribute::AlwaysInline)
63    .Case("argmemonly", Attribute::ArgMemOnly)
64    .Case("builtin", Attribute::Builtin)
65    .Case("byval", Attribute::ByVal)
66    .Case("cold", Attribute::Cold)
67    .Case("convergent", Attribute::Convergent)
68    .Case("dereferenceable", Attribute::Dereferenceable)
69    .Case("dereferenceable_or_null", Attribute::DereferenceableOrNull)
70    .Case("inalloca", Attribute::InAlloca)
71    .Case("inreg", Attribute::InReg)
72    .Case("inaccessiblememonly", Attribute::InaccessibleMemOnly)
73    .Case("inaccessiblemem_or_argmemonly", Attribute::InaccessibleMemOrArgMemOnly)
74    .Case("inlinehint", Attribute::InlineHint)
75    .Case("jumptable", Attribute::JumpTable)
76    .Case("minsize", Attribute::MinSize)
77    .Case("naked", Attribute::Naked)
78    .Case("nest", Attribute::Nest)
79    .Case("noalias", Attribute::NoAlias)
80    .Case("nobuiltin", Attribute::NoBuiltin)
81    .Case("nocapture", Attribute::NoCapture)
82    .Case("noduplicate", Attribute::NoDuplicate)
83    .Case("noimplicitfloat", Attribute::NoImplicitFloat)
84    .Case("noinline", Attribute::NoInline)
85    .Case("norecurse", Attribute::NoRecurse)
86    .Case("noredzone", Attribute::NoRedZone)
87    .Case("noreturn", Attribute::NoReturn)
88    .Case("nounwind", Attribute::NoUnwind)
89    .Case("nonlazybind", Attribute::NonLazyBind)
90    .Case("nonnull", Attribute::NonNull)
91    .Case("optsize", Attribute::OptimizeForSize)
92    .Case("optnone", Attribute::OptimizeNone)
93    .Case("readnone", Attribute::ReadNone)
94    .Case("readonly", Attribute::ReadOnly)
95    .Case("returned", Attribute::Returned)
96    .Case("returns_twice", Attribute::ReturnsTwice)
97    .Case("signext", Attribute::SExt)
98    .Case("safestack", Attribute::SafeStack)
99    .Case("sanitize_address", Attribute::SanitizeAddress)
100    .Case("sanitize_memory", Attribute::SanitizeMemory)
101    .Case("sanitize_thread", Attribute::SanitizeThread)
102    .Case("alignstack", Attribute::StackAlignment)
103    .Case("ssp", Attribute::StackProtect)
104    .Case("sspreq", Attribute::StackProtectReq)
105    .Case("sspstrong", Attribute::StackProtectStrong)
106    .Case("sret", Attribute::StructRet)
107    .Case("swifterror", Attribute::SwiftError)
108    .Case("swiftself", Attribute::SwiftSelf)
109    .Case("uwtable", Attribute::UWTable)
110    .Case("writeonly", Attribute::WriteOnly)
111    .Case("zeroext", Attribute::ZExt)
112    .Default(Attribute::None);
113}
114
115#endif
116#ifdef GET_ATTR_COMPAT_FUNC
117#undef GET_ATTR_COMPAT_FUNC
118struct EnumAttr {
119  static bool isSet(const Function &Fn,
120                    Attribute::AttrKind Kind) {
121    return Fn.hasFnAttribute(Kind);
122  }
123
124  static void set(Function &Fn,
125                  Attribute::AttrKind Kind, bool Val) {
126    if (Val)
127      Fn.addFnAttr(Kind);
128    else
129      Fn.removeFnAttr(Kind);
130  }
131};
132
133struct StrBoolAttr {
134  static bool isSet(const Function &Fn,
135                    StringRef Kind) {
136    auto A = Fn.getFnAttribute(Kind);
137    return A.getValueAsString().equals("true");
138  }
139
140  static void set(Function &Fn,
141                  StringRef Kind, bool Val) {
142    Fn.addFnAttr(Kind, Val ? "true" : "false");
143  }
144};
145
146// EnumAttr classes
147struct AlignmentAttr : EnumAttr {
148  static enum Attribute::AttrKind getKind() {
149    return llvm::Attribute::Alignment;
150  }
151};
152struct AllocSizeAttr : EnumAttr {
153  static enum Attribute::AttrKind getKind() {
154    return llvm::Attribute::AllocSize;
155  }
156};
157struct AlwaysInlineAttr : EnumAttr {
158  static enum Attribute::AttrKind getKind() {
159    return llvm::Attribute::AlwaysInline;
160  }
161};
162struct ArgMemOnlyAttr : EnumAttr {
163  static enum Attribute::AttrKind getKind() {
164    return llvm::Attribute::ArgMemOnly;
165  }
166};
167struct BuiltinAttr : EnumAttr {
168  static enum Attribute::AttrKind getKind() {
169    return llvm::Attribute::Builtin;
170  }
171};
172struct ByValAttr : EnumAttr {
173  static enum Attribute::AttrKind getKind() {
174    return llvm::Attribute::ByVal;
175  }
176};
177struct ColdAttr : EnumAttr {
178  static enum Attribute::AttrKind getKind() {
179    return llvm::Attribute::Cold;
180  }
181};
182struct ConvergentAttr : EnumAttr {
183  static enum Attribute::AttrKind getKind() {
184    return llvm::Attribute::Convergent;
185  }
186};
187struct DereferenceableAttr : EnumAttr {
188  static enum Attribute::AttrKind getKind() {
189    return llvm::Attribute::Dereferenceable;
190  }
191};
192struct DereferenceableOrNullAttr : EnumAttr {
193  static enum Attribute::AttrKind getKind() {
194    return llvm::Attribute::DereferenceableOrNull;
195  }
196};
197struct InAllocaAttr : EnumAttr {
198  static enum Attribute::AttrKind getKind() {
199    return llvm::Attribute::InAlloca;
200  }
201};
202struct InRegAttr : EnumAttr {
203  static enum Attribute::AttrKind getKind() {
204    return llvm::Attribute::InReg;
205  }
206};
207struct InaccessibleMemOnlyAttr : EnumAttr {
208  static enum Attribute::AttrKind getKind() {
209    return llvm::Attribute::InaccessibleMemOnly;
210  }
211};
212struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr {
213  static enum Attribute::AttrKind getKind() {
214    return llvm::Attribute::InaccessibleMemOrArgMemOnly;
215  }
216};
217struct InlineHintAttr : EnumAttr {
218  static enum Attribute::AttrKind getKind() {
219    return llvm::Attribute::InlineHint;
220  }
221};
222struct JumpTableAttr : EnumAttr {
223  static enum Attribute::AttrKind getKind() {
224    return llvm::Attribute::JumpTable;
225  }
226};
227struct MinSizeAttr : EnumAttr {
228  static enum Attribute::AttrKind getKind() {
229    return llvm::Attribute::MinSize;
230  }
231};
232struct NakedAttr : EnumAttr {
233  static enum Attribute::AttrKind getKind() {
234    return llvm::Attribute::Naked;
235  }
236};
237struct NestAttr : EnumAttr {
238  static enum Attribute::AttrKind getKind() {
239    return llvm::Attribute::Nest;
240  }
241};
242struct NoAliasAttr : EnumAttr {
243  static enum Attribute::AttrKind getKind() {
244    return llvm::Attribute::NoAlias;
245  }
246};
247struct NoBuiltinAttr : EnumAttr {
248  static enum Attribute::AttrKind getKind() {
249    return llvm::Attribute::NoBuiltin;
250  }
251};
252struct NoCaptureAttr : EnumAttr {
253  static enum Attribute::AttrKind getKind() {
254    return llvm::Attribute::NoCapture;
255  }
256};
257struct NoDuplicateAttr : EnumAttr {
258  static enum Attribute::AttrKind getKind() {
259    return llvm::Attribute::NoDuplicate;
260  }
261};
262struct NoImplicitFloatAttr : EnumAttr {
263  static enum Attribute::AttrKind getKind() {
264    return llvm::Attribute::NoImplicitFloat;
265  }
266};
267struct NoInlineAttr : EnumAttr {
268  static enum Attribute::AttrKind getKind() {
269    return llvm::Attribute::NoInline;
270  }
271};
272struct NoRecurseAttr : EnumAttr {
273  static enum Attribute::AttrKind getKind() {
274    return llvm::Attribute::NoRecurse;
275  }
276};
277struct NoRedZoneAttr : EnumAttr {
278  static enum Attribute::AttrKind getKind() {
279    return llvm::Attribute::NoRedZone;
280  }
281};
282struct NoReturnAttr : EnumAttr {
283  static enum Attribute::AttrKind getKind() {
284    return llvm::Attribute::NoReturn;
285  }
286};
287struct NoUnwindAttr : EnumAttr {
288  static enum Attribute::AttrKind getKind() {
289    return llvm::Attribute::NoUnwind;
290  }
291};
292struct NonLazyBindAttr : EnumAttr {
293  static enum Attribute::AttrKind getKind() {
294    return llvm::Attribute::NonLazyBind;
295  }
296};
297struct NonNullAttr : EnumAttr {
298  static enum Attribute::AttrKind getKind() {
299    return llvm::Attribute::NonNull;
300  }
301};
302struct OptimizeForSizeAttr : EnumAttr {
303  static enum Attribute::AttrKind getKind() {
304    return llvm::Attribute::OptimizeForSize;
305  }
306};
307struct OptimizeNoneAttr : EnumAttr {
308  static enum Attribute::AttrKind getKind() {
309    return llvm::Attribute::OptimizeNone;
310  }
311};
312struct ReadNoneAttr : EnumAttr {
313  static enum Attribute::AttrKind getKind() {
314    return llvm::Attribute::ReadNone;
315  }
316};
317struct ReadOnlyAttr : EnumAttr {
318  static enum Attribute::AttrKind getKind() {
319    return llvm::Attribute::ReadOnly;
320  }
321};
322struct ReturnedAttr : EnumAttr {
323  static enum Attribute::AttrKind getKind() {
324    return llvm::Attribute::Returned;
325  }
326};
327struct ReturnsTwiceAttr : EnumAttr {
328  static enum Attribute::AttrKind getKind() {
329    return llvm::Attribute::ReturnsTwice;
330  }
331};
332struct SExtAttr : EnumAttr {
333  static enum Attribute::AttrKind getKind() {
334    return llvm::Attribute::SExt;
335  }
336};
337struct SafeStackAttr : EnumAttr {
338  static enum Attribute::AttrKind getKind() {
339    return llvm::Attribute::SafeStack;
340  }
341};
342struct SanitizeAddressAttr : EnumAttr {
343  static enum Attribute::AttrKind getKind() {
344    return llvm::Attribute::SanitizeAddress;
345  }
346};
347struct SanitizeMemoryAttr : EnumAttr {
348  static enum Attribute::AttrKind getKind() {
349    return llvm::Attribute::SanitizeMemory;
350  }
351};
352struct SanitizeThreadAttr : EnumAttr {
353  static enum Attribute::AttrKind getKind() {
354    return llvm::Attribute::SanitizeThread;
355  }
356};
357struct StackAlignmentAttr : EnumAttr {
358  static enum Attribute::AttrKind getKind() {
359    return llvm::Attribute::StackAlignment;
360  }
361};
362struct StackProtectAttr : EnumAttr {
363  static enum Attribute::AttrKind getKind() {
364    return llvm::Attribute::StackProtect;
365  }
366};
367struct StackProtectReqAttr : EnumAttr {
368  static enum Attribute::AttrKind getKind() {
369    return llvm::Attribute::StackProtectReq;
370  }
371};
372struct StackProtectStrongAttr : EnumAttr {
373  static enum Attribute::AttrKind getKind() {
374    return llvm::Attribute::StackProtectStrong;
375  }
376};
377struct StructRetAttr : EnumAttr {
378  static enum Attribute::AttrKind getKind() {
379    return llvm::Attribute::StructRet;
380  }
381};
382struct SwiftErrorAttr : EnumAttr {
383  static enum Attribute::AttrKind getKind() {
384    return llvm::Attribute::SwiftError;
385  }
386};
387struct SwiftSelfAttr : EnumAttr {
388  static enum Attribute::AttrKind getKind() {
389    return llvm::Attribute::SwiftSelf;
390  }
391};
392struct UWTableAttr : EnumAttr {
393  static enum Attribute::AttrKind getKind() {
394    return llvm::Attribute::UWTable;
395  }
396};
397struct WriteOnlyAttr : EnumAttr {
398  static enum Attribute::AttrKind getKind() {
399    return llvm::Attribute::WriteOnly;
400  }
401};
402struct ZExtAttr : EnumAttr {
403  static enum Attribute::AttrKind getKind() {
404    return llvm::Attribute::ZExt;
405  }
406};
407
408// StrBoolAttr classes
409struct LessPreciseFPMADAttr : StrBoolAttr {
410  static const char *getKind() {
411    return "less-precise-fpmad";
412  }
413};
414struct NoInfsFPMathAttr : StrBoolAttr {
415  static const char *getKind() {
416    return "no-infs-fp-math";
417  }
418};
419struct NoJumpTablesAttr : StrBoolAttr {
420  static const char *getKind() {
421    return "no-jump-tables";
422  }
423};
424struct NoNansFPMathAttr : StrBoolAttr {
425  static const char *getKind() {
426    return "no-nans-fp-math";
427  }
428};
429struct UnsafeFPMathAttr : StrBoolAttr {
430  static const char *getKind() {
431    return "unsafe-fp-math";
432  }
433};
434
435static inline bool hasCompatibleFnAttrs(const Function &Caller,
436                                        const Function &Callee) {
437  bool Ret = true;
438
439  Ret &= isEqual<SanitizeAddressAttr>(Caller, Callee);
440  Ret &= isEqual<SanitizeThreadAttr>(Caller, Callee);
441  Ret &= isEqual<SanitizeMemoryAttr>(Caller, Callee);
442  Ret &= isEqual<SafeStackAttr>(Caller, Callee);
443
444  return Ret;
445}
446
447static inline void mergeFnAttrs(Function &Caller,
448                                const Function &Callee) {
449  adjustCallerSSPLevel(Caller, Callee);
450  setAND<LessPreciseFPMADAttr>(Caller, Callee);
451  setAND<NoInfsFPMathAttr>(Caller, Callee);
452  setAND<NoNansFPMathAttr>(Caller, Callee);
453  setAND<UnsafeFPMathAttr>(Caller, Callee);
454  setOR<NoImplicitFloatAttr>(Caller, Callee);
455  setOR<NoJumpTablesAttr>(Caller, Callee);
456}
457
458#endif
459