//===-- Value.h -------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines classes for values computed by abstract interpretation
// during dataflow analysis.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H

#include "clang/AST/Decl.h"
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include <cassert>
#include <utility>

namespace clang {
namespace dataflow {

/// Base class for all values computed by abstract interpretation.
///
/// Don't use `Value` instances by value. All `Value` instances are allocated
/// and owned by `DataflowAnalysisContext`.
class Value {
public:
  enum class Kind {
    Integer,
    Reference,
    Pointer,
    Struct,

    // Synthetic boolean values are either atomic values or composites that
    // represent conjunctions, disjunctions, and negations.
    AtomicBool,
    Conjunction,
    Disjunction,
    Negation
  };

  explicit Value(Kind ValKind) : ValKind(ValKind) {}

  // Non-copyable because addresses of values are used as their identities
  // throughout framework and user code. The framework is responsible for
  // construction and destruction of values.
  Value(const Value &) = delete;
  Value &operator=(const Value &) = delete;

  virtual ~Value() = default;

  Kind getKind() const { return ValKind; }

  /// Returns the value of the synthetic property with the given `Name` or null
  /// if the property isn't assigned a value.
  Value *getProperty(llvm::StringRef Name) const {
    auto It = Properties.find(Name);
    return It == Properties.end() ? nullptr : It->second;
  }

  /// Assigns `Val` as the value of the synthetic property with the given
  /// `Name`.
  void setProperty(llvm::StringRef Name, Value &Val) {
    Properties.insert_or_assign(Name, &Val);
  }

private:
  Kind ValKind;
  llvm::StringMap<Value *> Properties;
};

/// Models a boolean.
class BoolValue : public Value {
public:
  explicit BoolValue(Kind ValueKind) : Value(ValueKind) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::AtomicBool ||
           Val->getKind() == Kind::Conjunction ||
           Val->getKind() == Kind::Disjunction ||
           Val->getKind() == Kind::Negation;
  }
};

/// Models an atomic boolean.
class AtomicBoolValue : public BoolValue {
public:
  explicit AtomicBoolValue() : BoolValue(Kind::AtomicBool) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::AtomicBool;
  }
};

/// Models a boolean conjunction.
// FIXME: Consider representing binary and unary boolean operations similar
// to how they are represented in the AST. This might become more pressing
// when such operations need to be added for other data types.
class ConjunctionValue : public BoolValue {
public:
  explicit ConjunctionValue(BoolValue &LeftSubVal, BoolValue &RightSubVal)
      : BoolValue(Kind::Conjunction), LeftSubVal(LeftSubVal),
        RightSubVal(RightSubVal) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Conjunction;
  }

  /// Returns the left sub-value of the conjunction.
  BoolValue &getLeftSubValue() const { return LeftSubVal; }

  /// Returns the right sub-value of the conjunction.
  BoolValue &getRightSubValue() const { return RightSubVal; }

private:
  BoolValue &LeftSubVal;
  BoolValue &RightSubVal;
};

/// Models a boolean disjunction.
class DisjunctionValue : public BoolValue {
public:
  explicit DisjunctionValue(BoolValue &LeftSubVal, BoolValue &RightSubVal)
      : BoolValue(Kind::Disjunction), LeftSubVal(LeftSubVal),
        RightSubVal(RightSubVal) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Disjunction;
  }

  /// Returns the left sub-value of the disjunction.
  BoolValue &getLeftSubValue() const { return LeftSubVal; }

  /// Returns the right sub-value of the disjunction.
  BoolValue &getRightSubValue() const { return RightSubVal; }

private:
  BoolValue &LeftSubVal;
  BoolValue &RightSubVal;
};

/// Models a boolean negation.
class NegationValue : public BoolValue {
public:
  explicit NegationValue(BoolValue &SubVal)
      : BoolValue(Kind::Negation), SubVal(SubVal) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Negation;
  }

  /// Returns the sub-value of the negation.
  BoolValue &getSubVal() const { return SubVal; }

private:
  BoolValue &SubVal;
};

/// Models an integer.
class IntegerValue : public Value {
public:
  explicit IntegerValue() : Value(Kind::Integer) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Integer;
  }
};

/// Models a dereferenced pointer. For example, a reference in C++ or an lvalue
/// in C.
class ReferenceValue final : public Value {
public:
  explicit ReferenceValue(StorageLocation &ReferentLoc)
      : Value(Kind::Reference), ReferentLoc(ReferentLoc) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Reference;
  }

  StorageLocation &getReferentLoc() const { return ReferentLoc; }

private:
  StorageLocation &ReferentLoc;
};

/// Models a symbolic pointer. Specifically, any value of type `T*`.
class PointerValue final : public Value {
public:
  explicit PointerValue(StorageLocation &PointeeLoc)
      : Value(Kind::Pointer), PointeeLoc(PointeeLoc) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Pointer;
  }

  StorageLocation &getPointeeLoc() const { return PointeeLoc; }

private:
  StorageLocation &PointeeLoc;
};

/// Models a value of `struct` or `class` type, with a flat map of fields to
/// child storage locations, containing all accessible members of base struct
/// and class types.
class StructValue final : public Value {
public:
  StructValue() : StructValue(llvm::DenseMap<const ValueDecl *, Value *>()) {}

  explicit StructValue(llvm::DenseMap<const ValueDecl *, Value *> Children)
      : Value(Kind::Struct), Children(std::move(Children)) {}

  static bool classof(const Value *Val) {
    return Val->getKind() == Kind::Struct;
  }

  /// Returns the child value that is assigned for `D` or null if the child is
  /// not initialized.
  Value *getChild(const ValueDecl &D) const {
    auto It = Children.find(&D);
    if (It == Children.end())
      return nullptr;
    return It->second;
  }

  /// Assigns `Val` as the child value for `D`.
  void setChild(const ValueDecl &D, Value &Val) { Children[&D] = &Val; }

private:
  llvm::DenseMap<const ValueDecl *, Value *> Children;
};

} // namespace dataflow
} // namespace clang

#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_VALUE_H
