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