Home | History | Annotate | Line # | Download | only in Interp
      1 //===--- Boolean.h - Wrapper for boolean types for the VM -------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #ifndef LLVM_CLANG_AST_INTERP_BOOLEAN_H
     10 #define LLVM_CLANG_AST_INTERP_BOOLEAN_H
     11 
     12 #include <cstddef>
     13 #include <cstdint>
     14 #include "Integral.h"
     15 #include "clang/AST/APValue.h"
     16 #include "clang/AST/ComparisonCategories.h"
     17 #include "llvm/ADT/APSInt.h"
     18 #include "llvm/Support/MathExtras.h"
     19 #include "llvm/Support/raw_ostream.h"
     20 
     21 namespace clang {
     22 namespace interp {
     23 
     24 /// Wrapper around boolean types.
     25 class Boolean {
     26  private:
     27   /// Underlying boolean.
     28   bool V;
     29 
     30   /// Construct a wrapper from a boolean.
     31   explicit Boolean(bool V) : V(V) {}
     32 
     33  public:
     34   /// Zero-initializes a boolean.
     35   Boolean() : V(false) {}
     36 
     37   bool operator<(Boolean RHS) const { return V < RHS.V; }
     38   bool operator>(Boolean RHS) const { return V > RHS.V; }
     39   bool operator<=(Boolean RHS) const { return V <= RHS.V; }
     40   bool operator>=(Boolean RHS) const { return V >= RHS.V; }
     41   bool operator==(Boolean RHS) const { return V == RHS.V; }
     42   bool operator!=(Boolean RHS) const { return V != RHS.V; }
     43 
     44   bool operator>(unsigned RHS) const { return static_cast<unsigned>(V) > RHS; }
     45 
     46   Boolean operator-() const { return Boolean(V); }
     47   Boolean operator~() const { return Boolean(true); }
     48 
     49   explicit operator unsigned() const { return V; }
     50   explicit operator int64_t() const { return V; }
     51   explicit operator uint64_t() const { return V; }
     52 
     53   APSInt toAPSInt() const {
     54     return APSInt(APInt(1, static_cast<uint64_t>(V), false), true);
     55   }
     56   APSInt toAPSInt(unsigned NumBits) const {
     57     return APSInt(toAPSInt().zextOrTrunc(NumBits), true);
     58   }
     59   APValue toAPValue() const { return APValue(toAPSInt()); }
     60 
     61   Boolean toUnsigned() const { return *this; }
     62 
     63   constexpr static unsigned bitWidth() { return true; }
     64   bool isZero() const { return !V; }
     65   bool isMin() const { return isZero(); }
     66 
     67   constexpr static bool isMinusOne() { return false; }
     68 
     69   constexpr static bool isSigned() { return false; }
     70 
     71   constexpr static bool isNegative() { return false; }
     72   constexpr static bool isPositive() { return !isNegative(); }
     73 
     74   ComparisonCategoryResult compare(const Boolean &RHS) const {
     75     return Compare(V, RHS.V);
     76   }
     77 
     78   unsigned countLeadingZeros() const { return V ? 0 : 1; }
     79 
     80   Boolean truncate(unsigned TruncBits) const { return *this; }
     81 
     82   void print(llvm::raw_ostream &OS) const { OS << (V ? "true" : "false"); }
     83 
     84   static Boolean min(unsigned NumBits) { return Boolean(false); }
     85   static Boolean max(unsigned NumBits) { return Boolean(true); }
     86 
     87   template <typename T>
     88   static std::enable_if_t<std::is_integral<T>::value, Boolean> from(T Value) {
     89     return Boolean(Value != 0);
     90   }
     91 
     92   template <unsigned SrcBits, bool SrcSign>
     93   static std::enable_if_t<SrcBits != 0, Boolean>
     94   from(Integral<SrcBits, SrcSign> Value) {
     95     return Boolean(!Value.isZero());
     96   }
     97 
     98   template <bool SrcSign>
     99   static Boolean from(Integral<0, SrcSign> Value) {
    100     return Boolean(!Value.isZero());
    101   }
    102 
    103   static Boolean zero() { return from(false); }
    104 
    105   template <typename T>
    106   static Boolean from(T Value, unsigned NumBits) {
    107     return Boolean(Value);
    108   }
    109 
    110   static bool inRange(int64_t Value, unsigned NumBits) {
    111     return Value == 0 || Value == 1;
    112   }
    113 
    114   static bool increment(Boolean A, Boolean *R) {
    115     *R = Boolean(true);
    116     return false;
    117   }
    118 
    119   static bool decrement(Boolean A, Boolean *R) {
    120     llvm_unreachable("Cannot decrement booleans");
    121   }
    122 
    123   static bool add(Boolean A, Boolean B, unsigned OpBits, Boolean *R) {
    124     *R = Boolean(A.V || B.V);
    125     return false;
    126   }
    127 
    128   static bool sub(Boolean A, Boolean B, unsigned OpBits, Boolean *R) {
    129     *R = Boolean(A.V ^ B.V);
    130     return false;
    131   }
    132 
    133   static bool mul(Boolean A, Boolean B, unsigned OpBits, Boolean *R) {
    134     *R = Boolean(A.V && B.V);
    135     return false;
    136   }
    137 };
    138 
    139 inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Boolean &B) {
    140   B.print(OS);
    141   return OS;
    142 }
    143 
    144 }  // namespace interp
    145 }  // namespace clang
    146 
    147 #endif
    148