================ @@ -4429,6 +4433,218 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { } }; +// ------------------------------------------------------------------------------ + +// TODO: Should FunctionEffect be located elsewhere, where Decl is not +// forward-declared? +class Decl; +class CXXMethodDecl; +class FunctionEffectSet; +class TypeSourceInfo; + +/// Represents an abstract function effect. +class FunctionEffect { +public: + /// Identifies the particular type of effect. + enum class Type { + None = 0, + NonBlocking, + NonAllocating, + }; + + /// Flags describing behaviors of the effect. + // (Why not a struct with bitfields? There's one function that would like to + // test a caller-specified bit. There are some potential optimizations that + // would OR together the bits of multiple effects.) + using Flags = unsigned; + enum FlagBit : unsigned { + // Can verification inspect callees' implementations? (e.g. nonblocking: + // yes, tcb+types: no) + FE_InferrableOnCallees = 0x1, + + // Language constructs which effects can diagnose as disallowed. + FE_ExcludeThrow = 0x2, + FE_ExcludeCatch = 0x4, + FE_ExcludeObjCMessageSend = 0x8, + FE_ExcludeStaticLocalVars = 0x10, + FE_ExcludeThreadLocalVars = 0x20 + }; + + /// Describes the result of effects differing between a base class's virtual + /// method and an overriding method in a subclass. + enum class OverrideResult { + Ignore, + Warn, + Propagate // Base method's effects are merged with those of the override. + }; + +private: + // For uniqueness, currently only Type_ is significant. + + LLVM_PREFERRED_TYPE(Type) + unsigned Type_ : 2; + Flags Flags_ : 8; // A constant function of Type but cached here. + + // Expansion: for hypothetical TCB+types, there could be one Type for TCB, + // then ~16(?) bits "Subtype" to map to a specific named TCB. Subtype would + // be considered for uniqueness. + + // Since this struct is serialized as if it were a uint32_t, it's important + // to pad and explicitly zero the extra bits. + [[maybe_unused]] unsigned Padding : 22; + +public: + using CalleeDeclOrType = + llvm::PointerUnion<const Decl *, const FunctionProtoType *>; + + FunctionEffect() : Type_(unsigned(Type::None)), Flags_(0), Padding(0) {} + + explicit FunctionEffect(Type T); + + /// The type of the effect. + Type type() const { return Type(Type_); } + + /// Flags describing behaviors of the effect. + Flags flags() const { return Flags_; } + + /// The description printed in diagnostics, e.g. 'nonblocking'. + StringRef name() const; + + /// A hashable representation. + uint32_t opaqueRepr() const { return Type_ | (Flags_ << 2u); } + + /// Return true if adding or removing the effect as part of a type conversion + /// should generate a diagnostic. + bool diagnoseConversion(bool Adding, QualType OldType, + FunctionEffectSet OldFX, QualType NewType, + FunctionEffectSet NewFX) const; ---------------- dougsonos wrote:
This ended up being a method on FunctionEffectDiff in Sema.h https://github.com/llvm/llvm-project/pull/84983 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits