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