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