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