================
@@ -4640,6 +4647,306 @@ class FunctionNoProtoType : public FunctionType, public 
llvm::FoldingSetNode {
   }
 };
 
+// 
------------------------------------------------------------------------------
+
+/// Represents an abstract function effect, using just an enumeration 
describing
+/// its kind.
+class FunctionEffect {
+public:
+  /// Identifies the particular effect.
+  enum class Kind : uint8_t {
+    None = 0,
+    NonBlocking = 1,
+    NonAllocating = 2,
+    Blocking = 3,
+    Allocating = 4
+  };
+
+  /// Flags describing some behaviors of the effect.
+  using Flags = unsigned;
+  enum FlagBit : Flags {
+    // Can verification inspect callees' implementations? (e.g. nonblocking:
+    // yes, tcb+types: no). This also implies the need for 2nd-pass
+    // verification.
+    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
+  };
+
+private:
+  LLVM_PREFERRED_TYPE(Kind)
+  unsigned FKind : 3;
+
+  // Expansion: for hypothetical TCB+types, there could be one Kind for TCB,
+  // then ~16(?) bits "SubKind" to map to a specific named TCB. SubKind would
+  // be considered for uniqueness.
+
+public:
+  FunctionEffect() : FKind(unsigned(Kind::None)) {}
+
+  explicit FunctionEffect(Kind K) : FKind(unsigned(K)) {}
+
+  /// The kind of the effect.
+  Kind kind() const { return Kind(FKind); }
+
+  /// Return the opposite kind, for effects which have opposites.
+  Kind oppositeKind() const;
+
+  /// For serialization.
+  uint32_t toOpaqueInt32() const { return FKind; }
+  static FunctionEffect fromOpaqueInt32(uint32_t Value) {
+    return FunctionEffect(Kind(Value));
+  }
+
+  /// Flags describing some behaviors of the effect.
+  Flags flags() const {
+    switch (kind()) {
+    case Kind::NonBlocking:
+      return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
+             FE_ExcludeObjCMessageSend | FE_ExcludeStaticLocalVars |
+             FE_ExcludeThreadLocalVars;
+    case Kind::NonAllocating:
+      // Same as NonBlocking, except without FE_ExcludeStaticLocalVars.
+      return FE_InferrableOnCallees | FE_ExcludeThrow | FE_ExcludeCatch |
+             FE_ExcludeObjCMessageSend | FE_ExcludeThreadLocalVars;
+    case Kind::Blocking:
+    case Kind::Allocating:
+      return 0;
+    case Kind::None:
+      break;
+    }
+    llvm_unreachable("unknown effect kind");
+  }
+
+  /// The description printed in diagnostics, e.g. 'nonblocking'.
+  StringRef name() const;
+
+  /// Return true if the effect is allowed to be inferred on the callee,
+  /// which is either a FunctionDecl or BlockDecl.
+  /// This is only used if the effect has FE_InferrableOnCallees flag set.
+  /// Example: This allows nonblocking(false) to prevent inference for the
+  /// function.
+  bool canInferOnFunction(const Decl &Callee) const;
----------------
Sirraide wrote:

This function from what I can tell already checks that flag (or does something 
equivalent by only checking for inference for effects for which this flag is 
set). 

I think the comment ‘This is only used if the effect has FE_InferrableOnCallees 
flag set’ should be removed because it is a bit confusing imo because it 
doesn’t make it clear whether the caller is supposed to check that flag and 
then call this or whether this checks it itself (or does something equivalent).

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

Reply via email to