459 lines
12 KiB
C++
459 lines
12 KiB
C++
#ifdef GET_ATTR_ENUM
|
|
#undef GET_ATTR_ENUM
|
|
Alignment,
|
|
AllocSize,
|
|
AlwaysInline,
|
|
ArgMemOnly,
|
|
Builtin,
|
|
ByVal,
|
|
Cold,
|
|
Convergent,
|
|
Dereferenceable,
|
|
DereferenceableOrNull,
|
|
InAlloca,
|
|
InReg,
|
|
InaccessibleMemOnly,
|
|
InaccessibleMemOrArgMemOnly,
|
|
InlineHint,
|
|
JumpTable,
|
|
MinSize,
|
|
Naked,
|
|
Nest,
|
|
NoAlias,
|
|
NoBuiltin,
|
|
NoCapture,
|
|
NoDuplicate,
|
|
NoImplicitFloat,
|
|
NoInline,
|
|
NoRecurse,
|
|
NoRedZone,
|
|
NoReturn,
|
|
NoUnwind,
|
|
NonLazyBind,
|
|
NonNull,
|
|
OptimizeForSize,
|
|
OptimizeNone,
|
|
ReadNone,
|
|
ReadOnly,
|
|
Returned,
|
|
ReturnsTwice,
|
|
SExt,
|
|
SafeStack,
|
|
SanitizeAddress,
|
|
SanitizeMemory,
|
|
SanitizeThread,
|
|
StackAlignment,
|
|
StackProtect,
|
|
StackProtectReq,
|
|
StackProtectStrong,
|
|
StructRet,
|
|
SwiftError,
|
|
SwiftSelf,
|
|
UWTable,
|
|
WriteOnly,
|
|
ZExt,
|
|
#endif
|
|
#ifdef GET_ATTR_KIND_FROM_NAME
|
|
#undef GET_ATTR_KIND_FROM_NAME
|
|
static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {
|
|
return StringSwitch<Attribute::AttrKind>(AttrName)
|
|
.Case("align", Attribute::Alignment)
|
|
.Case("allocsize", Attribute::AllocSize)
|
|
.Case("alwaysinline", Attribute::AlwaysInline)
|
|
.Case("argmemonly", Attribute::ArgMemOnly)
|
|
.Case("builtin", Attribute::Builtin)
|
|
.Case("byval", Attribute::ByVal)
|
|
.Case("cold", Attribute::Cold)
|
|
.Case("convergent", Attribute::Convergent)
|
|
.Case("dereferenceable", Attribute::Dereferenceable)
|
|
.Case("dereferenceable_or_null", Attribute::DereferenceableOrNull)
|
|
.Case("inalloca", Attribute::InAlloca)
|
|
.Case("inreg", Attribute::InReg)
|
|
.Case("inaccessiblememonly", Attribute::InaccessibleMemOnly)
|
|
.Case("inaccessiblemem_or_argmemonly", Attribute::InaccessibleMemOrArgMemOnly)
|
|
.Case("inlinehint", Attribute::InlineHint)
|
|
.Case("jumptable", Attribute::JumpTable)
|
|
.Case("minsize", Attribute::MinSize)
|
|
.Case("naked", Attribute::Naked)
|
|
.Case("nest", Attribute::Nest)
|
|
.Case("noalias", Attribute::NoAlias)
|
|
.Case("nobuiltin", Attribute::NoBuiltin)
|
|
.Case("nocapture", Attribute::NoCapture)
|
|
.Case("noduplicate", Attribute::NoDuplicate)
|
|
.Case("noimplicitfloat", Attribute::NoImplicitFloat)
|
|
.Case("noinline", Attribute::NoInline)
|
|
.Case("norecurse", Attribute::NoRecurse)
|
|
.Case("noredzone", Attribute::NoRedZone)
|
|
.Case("noreturn", Attribute::NoReturn)
|
|
.Case("nounwind", Attribute::NoUnwind)
|
|
.Case("nonlazybind", Attribute::NonLazyBind)
|
|
.Case("nonnull", Attribute::NonNull)
|
|
.Case("optsize", Attribute::OptimizeForSize)
|
|
.Case("optnone", Attribute::OptimizeNone)
|
|
.Case("readnone", Attribute::ReadNone)
|
|
.Case("readonly", Attribute::ReadOnly)
|
|
.Case("returned", Attribute::Returned)
|
|
.Case("returns_twice", Attribute::ReturnsTwice)
|
|
.Case("signext", Attribute::SExt)
|
|
.Case("safestack", Attribute::SafeStack)
|
|
.Case("sanitize_address", Attribute::SanitizeAddress)
|
|
.Case("sanitize_memory", Attribute::SanitizeMemory)
|
|
.Case("sanitize_thread", Attribute::SanitizeThread)
|
|
.Case("alignstack", Attribute::StackAlignment)
|
|
.Case("ssp", Attribute::StackProtect)
|
|
.Case("sspreq", Attribute::StackProtectReq)
|
|
.Case("sspstrong", Attribute::StackProtectStrong)
|
|
.Case("sret", Attribute::StructRet)
|
|
.Case("swifterror", Attribute::SwiftError)
|
|
.Case("swiftself", Attribute::SwiftSelf)
|
|
.Case("uwtable", Attribute::UWTable)
|
|
.Case("writeonly", Attribute::WriteOnly)
|
|
.Case("zeroext", Attribute::ZExt)
|
|
.Default(Attribute::None);
|
|
}
|
|
|
|
#endif
|
|
#ifdef GET_ATTR_COMPAT_FUNC
|
|
#undef GET_ATTR_COMPAT_FUNC
|
|
struct EnumAttr {
|
|
static bool isSet(const Function &Fn,
|
|
Attribute::AttrKind Kind) {
|
|
return Fn.hasFnAttribute(Kind);
|
|
}
|
|
|
|
static void set(Function &Fn,
|
|
Attribute::AttrKind Kind, bool Val) {
|
|
if (Val)
|
|
Fn.addFnAttr(Kind);
|
|
else
|
|
Fn.removeFnAttr(Kind);
|
|
}
|
|
};
|
|
|
|
struct StrBoolAttr {
|
|
static bool isSet(const Function &Fn,
|
|
StringRef Kind) {
|
|
auto A = Fn.getFnAttribute(Kind);
|
|
return A.getValueAsString().equals("true");
|
|
}
|
|
|
|
static void set(Function &Fn,
|
|
StringRef Kind, bool Val) {
|
|
Fn.addFnAttr(Kind, Val ? "true" : "false");
|
|
}
|
|
};
|
|
|
|
// EnumAttr classes
|
|
struct AlignmentAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Alignment;
|
|
}
|
|
};
|
|
struct AllocSizeAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::AllocSize;
|
|
}
|
|
};
|
|
struct AlwaysInlineAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::AlwaysInline;
|
|
}
|
|
};
|
|
struct ArgMemOnlyAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::ArgMemOnly;
|
|
}
|
|
};
|
|
struct BuiltinAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Builtin;
|
|
}
|
|
};
|
|
struct ByValAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::ByVal;
|
|
}
|
|
};
|
|
struct ColdAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Cold;
|
|
}
|
|
};
|
|
struct ConvergentAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Convergent;
|
|
}
|
|
};
|
|
struct DereferenceableAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Dereferenceable;
|
|
}
|
|
};
|
|
struct DereferenceableOrNullAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::DereferenceableOrNull;
|
|
}
|
|
};
|
|
struct InAllocaAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::InAlloca;
|
|
}
|
|
};
|
|
struct InRegAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::InReg;
|
|
}
|
|
};
|
|
struct InaccessibleMemOnlyAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::InaccessibleMemOnly;
|
|
}
|
|
};
|
|
struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::InaccessibleMemOrArgMemOnly;
|
|
}
|
|
};
|
|
struct InlineHintAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::InlineHint;
|
|
}
|
|
};
|
|
struct JumpTableAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::JumpTable;
|
|
}
|
|
};
|
|
struct MinSizeAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::MinSize;
|
|
}
|
|
};
|
|
struct NakedAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Naked;
|
|
}
|
|
};
|
|
struct NestAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Nest;
|
|
}
|
|
};
|
|
struct NoAliasAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoAlias;
|
|
}
|
|
};
|
|
struct NoBuiltinAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoBuiltin;
|
|
}
|
|
};
|
|
struct NoCaptureAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoCapture;
|
|
}
|
|
};
|
|
struct NoDuplicateAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoDuplicate;
|
|
}
|
|
};
|
|
struct NoImplicitFloatAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoImplicitFloat;
|
|
}
|
|
};
|
|
struct NoInlineAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoInline;
|
|
}
|
|
};
|
|
struct NoRecurseAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoRecurse;
|
|
}
|
|
};
|
|
struct NoRedZoneAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoRedZone;
|
|
}
|
|
};
|
|
struct NoReturnAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoReturn;
|
|
}
|
|
};
|
|
struct NoUnwindAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NoUnwind;
|
|
}
|
|
};
|
|
struct NonLazyBindAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NonLazyBind;
|
|
}
|
|
};
|
|
struct NonNullAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::NonNull;
|
|
}
|
|
};
|
|
struct OptimizeForSizeAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::OptimizeForSize;
|
|
}
|
|
};
|
|
struct OptimizeNoneAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::OptimizeNone;
|
|
}
|
|
};
|
|
struct ReadNoneAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::ReadNone;
|
|
}
|
|
};
|
|
struct ReadOnlyAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::ReadOnly;
|
|
}
|
|
};
|
|
struct ReturnedAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::Returned;
|
|
}
|
|
};
|
|
struct ReturnsTwiceAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::ReturnsTwice;
|
|
}
|
|
};
|
|
struct SExtAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SExt;
|
|
}
|
|
};
|
|
struct SafeStackAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SafeStack;
|
|
}
|
|
};
|
|
struct SanitizeAddressAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SanitizeAddress;
|
|
}
|
|
};
|
|
struct SanitizeMemoryAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SanitizeMemory;
|
|
}
|
|
};
|
|
struct SanitizeThreadAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SanitizeThread;
|
|
}
|
|
};
|
|
struct StackAlignmentAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::StackAlignment;
|
|
}
|
|
};
|
|
struct StackProtectAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::StackProtect;
|
|
}
|
|
};
|
|
struct StackProtectReqAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::StackProtectReq;
|
|
}
|
|
};
|
|
struct StackProtectStrongAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::StackProtectStrong;
|
|
}
|
|
};
|
|
struct StructRetAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::StructRet;
|
|
}
|
|
};
|
|
struct SwiftErrorAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SwiftError;
|
|
}
|
|
};
|
|
struct SwiftSelfAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::SwiftSelf;
|
|
}
|
|
};
|
|
struct UWTableAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::UWTable;
|
|
}
|
|
};
|
|
struct WriteOnlyAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::WriteOnly;
|
|
}
|
|
};
|
|
struct ZExtAttr : EnumAttr {
|
|
static enum Attribute::AttrKind getKind() {
|
|
return llvm::Attribute::ZExt;
|
|
}
|
|
};
|
|
|
|
// StrBoolAttr classes
|
|
struct LessPreciseFPMADAttr : StrBoolAttr {
|
|
static const char *getKind() {
|
|
return "less-precise-fpmad";
|
|
}
|
|
};
|
|
struct NoInfsFPMathAttr : StrBoolAttr {
|
|
static const char *getKind() {
|
|
return "no-infs-fp-math";
|
|
}
|
|
};
|
|
struct NoJumpTablesAttr : StrBoolAttr {
|
|
static const char *getKind() {
|
|
return "no-jump-tables";
|
|
}
|
|
};
|
|
struct NoNansFPMathAttr : StrBoolAttr {
|
|
static const char *getKind() {
|
|
return "no-nans-fp-math";
|
|
}
|
|
};
|
|
struct UnsafeFPMathAttr : StrBoolAttr {
|
|
static const char *getKind() {
|
|
return "unsafe-fp-math";
|
|
}
|
|
};
|
|
|
|
static inline bool hasCompatibleFnAttrs(const Function &Caller,
|
|
const Function &Callee) {
|
|
bool Ret = true;
|
|
|
|
Ret &= isEqual<SanitizeAddressAttr>(Caller, Callee);
|
|
Ret &= isEqual<SanitizeThreadAttr>(Caller, Callee);
|
|
Ret &= isEqual<SanitizeMemoryAttr>(Caller, Callee);
|
|
Ret &= isEqual<SafeStackAttr>(Caller, Callee);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
static inline void mergeFnAttrs(Function &Caller,
|
|
const Function &Callee) {
|
|
adjustCallerSSPLevel(Caller, Callee);
|
|
setAND<LessPreciseFPMADAttr>(Caller, Callee);
|
|
setAND<NoInfsFPMathAttr>(Caller, Callee);
|
|
setAND<NoNansFPMathAttr>(Caller, Callee);
|
|
setAND<UnsafeFPMathAttr>(Caller, Callee);
|
|
setOR<NoImplicitFloatAttr>(Caller, Callee);
|
|
setOR<NoJumpTablesAttr>(Caller, Callee);
|
|
}
|
|
|
|
#endif
|