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 StackAlignment, 46 StackProtect, 47 StackProtectReq, 48 StackProtectStrong, 49 StructRet, 50 SwiftError, 51 SwiftSelf, 52 UWTable, 53 WriteOnly, 54 ZExt, 55 #endif 56 #ifdef GET_ATTR_KIND_FROM_NAME 57 #undef GET_ATTR_KIND_FROM_NAME 58 static 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 118 struct 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 133 struct 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 147 struct AlignmentAttr : EnumAttr { 148 static enum Attribute::AttrKind getKind() { 149 return llvm::Attribute::Alignment; 150 } 151 }; 152 struct AllocSizeAttr : EnumAttr { 153 static enum Attribute::AttrKind getKind() { 154 return llvm::Attribute::AllocSize; 155 } 156 }; 157 struct AlwaysInlineAttr : EnumAttr { 158 static enum Attribute::AttrKind getKind() { 159 return llvm::Attribute::AlwaysInline; 160 } 161 }; 162 struct ArgMemOnlyAttr : EnumAttr { 163 static enum Attribute::AttrKind getKind() { 164 return llvm::Attribute::ArgMemOnly; 165 } 166 }; 167 struct BuiltinAttr : EnumAttr { 168 static enum Attribute::AttrKind getKind() { 169 return llvm::Attribute::Builtin; 170 } 171 }; 172 struct ByValAttr : EnumAttr { 173 static enum Attribute::AttrKind getKind() { 174 return llvm::Attribute::ByVal; 175 } 176 }; 177 struct ColdAttr : EnumAttr { 178 static enum Attribute::AttrKind getKind() { 179 return llvm::Attribute::Cold; 180 } 181 }; 182 struct ConvergentAttr : EnumAttr { 183 static enum Attribute::AttrKind getKind() { 184 return llvm::Attribute::Convergent; 185 } 186 }; 187 struct DereferenceableAttr : EnumAttr { 188 static enum Attribute::AttrKind getKind() { 189 return llvm::Attribute::Dereferenceable; 190 } 191 }; 192 struct DereferenceableOrNullAttr : EnumAttr { 193 static enum Attribute::AttrKind getKind() { 194 return llvm::Attribute::DereferenceableOrNull; 195 } 196 }; 197 struct InAllocaAttr : EnumAttr { 198 static enum Attribute::AttrKind getKind() { 199 return llvm::Attribute::InAlloca; 200 } 201 }; 202 struct InRegAttr : EnumAttr { 203 static enum Attribute::AttrKind getKind() { 204 return llvm::Attribute::InReg; 205 } 206 }; 207 struct InaccessibleMemOnlyAttr : EnumAttr { 208 static enum Attribute::AttrKind getKind() { 209 return llvm::Attribute::InaccessibleMemOnly; 210 } 211 }; 212 struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr { 213 static enum Attribute::AttrKind getKind() { 214 return llvm::Attribute::InaccessibleMemOrArgMemOnly; 215 } 216 }; 217 struct InlineHintAttr : EnumAttr { 218 static enum Attribute::AttrKind getKind() { 219 return llvm::Attribute::InlineHint; 220 } 221 }; 222 struct JumpTableAttr : EnumAttr { 223 static enum Attribute::AttrKind getKind() { 224 return llvm::Attribute::JumpTable; 225 } 226 }; 227 struct MinSizeAttr : EnumAttr { 228 static enum Attribute::AttrKind getKind() { 229 return llvm::Attribute::MinSize; 230 } 231 }; 232 struct NakedAttr : EnumAttr { 233 static enum Attribute::AttrKind getKind() { 234 return llvm::Attribute::Naked; 235 } 236 }; 237 struct NestAttr : EnumAttr { 238 static enum Attribute::AttrKind getKind() { 239 return llvm::Attribute::Nest; 240 } 241 }; 242 struct NoAliasAttr : EnumAttr { 243 static enum Attribute::AttrKind getKind() { 244 return llvm::Attribute::NoAlias; 245 } 246 }; 247 struct NoBuiltinAttr : EnumAttr { 248 static enum Attribute::AttrKind getKind() { 249 return llvm::Attribute::NoBuiltin; 250 } 251 }; 252 struct NoCaptureAttr : EnumAttr { 253 static enum Attribute::AttrKind getKind() { 254 return llvm::Attribute::NoCapture; 255 } 256 }; 257 struct NoDuplicateAttr : EnumAttr { 258 static enum Attribute::AttrKind getKind() { 259 return llvm::Attribute::NoDuplicate; 260 } 261 }; 262 struct NoImplicitFloatAttr : EnumAttr { 263 static enum Attribute::AttrKind getKind() { 264 return llvm::Attribute::NoImplicitFloat; 265 } 266 }; 267 struct NoInlineAttr : EnumAttr { 268 static enum Attribute::AttrKind getKind() { 269 return llvm::Attribute::NoInline; 270 } 271 }; 272 struct NoRecurseAttr : EnumAttr { 273 static enum Attribute::AttrKind getKind() { 274 return llvm::Attribute::NoRecurse; 275 } 276 }; 277 struct NoRedZoneAttr : EnumAttr { 278 static enum Attribute::AttrKind getKind() { 279 return llvm::Attribute::NoRedZone; 280 } 281 }; 282 struct NoReturnAttr : EnumAttr { 283 static enum Attribute::AttrKind getKind() { 284 return llvm::Attribute::NoReturn; 285 } 286 }; 287 struct NoUnwindAttr : EnumAttr { 288 static enum Attribute::AttrKind getKind() { 289 return llvm::Attribute::NoUnwind; 290 } 291 }; 292 struct NonLazyBindAttr : EnumAttr { 293 static enum Attribute::AttrKind getKind() { 294 return llvm::Attribute::NonLazyBind; 295 } 296 }; 297 struct NonNullAttr : EnumAttr { 298 static enum Attribute::AttrKind getKind() { 299 return llvm::Attribute::NonNull; 300 } 301 }; 302 struct OptimizeForSizeAttr : EnumAttr { 303 static enum Attribute::AttrKind getKind() { 304 return llvm::Attribute::OptimizeForSize; 305 } 306 }; 307 struct OptimizeNoneAttr : EnumAttr { 308 static enum Attribute::AttrKind getKind() { 309 return llvm::Attribute::OptimizeNone; 310 } 311 }; 312 struct ReadNoneAttr : EnumAttr { 313 static enum Attribute::AttrKind getKind() { 314 return llvm::Attribute::ReadNone; 315 } 316 }; 317 struct ReadOnlyAttr : EnumAttr { 318 static enum Attribute::AttrKind getKind() { 319 return llvm::Attribute::ReadOnly; 320 } 321 }; 322 struct ReturnedAttr : EnumAttr { 323 static enum Attribute::AttrKind getKind() { 324 return llvm::Attribute::Returned; 325 } 326 }; 327 struct ReturnsTwiceAttr : EnumAttr { 328 static enum Attribute::AttrKind getKind() { 329 return llvm::Attribute::ReturnsTwice; 330 } 331 }; 332 struct SExtAttr : EnumAttr { 333 static enum Attribute::AttrKind getKind() { 334 return llvm::Attribute::SExt; 335 } 336 }; 337 struct SafeStackAttr : EnumAttr { 338 static enum Attribute::AttrKind getKind() { 339 return llvm::Attribute::SafeStack; 340 } 341 }; 342 struct SanitizeAddressAttr : EnumAttr { 343 static enum Attribute::AttrKind getKind() { 344 return llvm::Attribute::SanitizeAddress; 345 } 346 }; 347 struct SanitizeMemoryAttr : EnumAttr { 348 static enum Attribute::AttrKind getKind() { 349 return llvm::Attribute::SanitizeMemory; 350 } 351 }; 352 struct SanitizeThreadAttr : EnumAttr { 353 static enum Attribute::AttrKind getKind() { 354 return llvm::Attribute::SanitizeThread; 355 } 356 }; 357 struct StackAlignmentAttr : EnumAttr { 358 static enum Attribute::AttrKind getKind() { 359 return llvm::Attribute::StackAlignment; 360 } 361 }; 362 struct StackProtectAttr : EnumAttr { 363 static enum Attribute::AttrKind getKind() { 364 return llvm::Attribute::StackProtect; 365 } 366 }; 367 struct StackProtectReqAttr : EnumAttr { 368 static enum Attribute::AttrKind getKind() { 369 return llvm::Attribute::StackProtectReq; 370 } 371 }; 372 struct StackProtectStrongAttr : EnumAttr { 373 static enum Attribute::AttrKind getKind() { 374 return llvm::Attribute::StackProtectStrong; 375 } 376 }; 377 struct StructRetAttr : EnumAttr { 378 static enum Attribute::AttrKind getKind() { 379 return llvm::Attribute::StructRet; 380 } 381 }; 382 struct SwiftErrorAttr : EnumAttr { 383 static enum Attribute::AttrKind getKind() { 384 return llvm::Attribute::SwiftError; 385 } 386 }; 387 struct SwiftSelfAttr : EnumAttr { 388 static enum Attribute::AttrKind getKind() { 389 return llvm::Attribute::SwiftSelf; 390 } 391 }; 392 struct UWTableAttr : EnumAttr { 393 static enum Attribute::AttrKind getKind() { 394 return llvm::Attribute::UWTable; 395 } 396 }; 397 struct WriteOnlyAttr : EnumAttr { 398 static enum Attribute::AttrKind getKind() { 399 return llvm::Attribute::WriteOnly; 400 } 401 }; 402 struct ZExtAttr : EnumAttr { 403 static enum Attribute::AttrKind getKind() { 404 return llvm::Attribute::ZExt; 405 } 406 }; 407 408 // StrBoolAttr classes 409 struct LessPreciseFPMADAttr : StrBoolAttr { 410 static StringRef getKind() { 411 return "less-precise-fpmad"; 412 } 413 }; 414 struct NoInfsFPMathAttr : StrBoolAttr { 415 static StringRef getKind() { 416 return "no-infs-fp-math"; 417 } 418 }; 419 struct NoJumpTablesAttr : StrBoolAttr { 420 static StringRef getKind() { 421 return "no-jump-tables"; 422 } 423 }; 424 struct NoNansFPMathAttr : StrBoolAttr { 425 static StringRef getKind() { 426 return "no-nans-fp-math"; 427 } 428 }; 429 struct UnsafeFPMathAttr : StrBoolAttr { 430 static StringRef getKind() { 431 return "unsafe-fp-math"; 432 } 433 }; 434 435 static 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 447 static 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