//= OSLog.h - Analysis of calls to os_log builtins --*- 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 APIs for determining the layout of the data buffer for
// os_log() and os_trace().
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_OSLOG_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"

namespace clang {
namespace analyze_os_log {

/// An OSLogBufferItem represents a single item in the data written by a call
/// to os_log() or os_trace().
class OSLogBufferItem {
public:
  enum Kind {
    // The item is a scalar (int, float, raw pointer, etc.). No further copying
    // is required. This is the only kind allowed by os_trace().
    ScalarKind = 0,

    // The item is a count, which describes the length of the following item to
    // be copied. A count may only be followed by an item of kind StringKind,
    // WideStringKind, or PointerKind.
    CountKind,

    // The item is a pointer to a C string. If preceded by a count 'n',
    // os_log() will copy at most 'n' bytes from the pointer.
    StringKind,

    // The item is a pointer to a block of raw data. This item must be preceded
    // by a count 'n'. os_log() will copy exactly 'n' bytes from the pointer.
    PointerKind,

    // The item is a pointer to an Objective-C object. os_log() may retain the
    // object for later processing.
    ObjCObjKind,

    // The item is a pointer to wide-char string.
    WideStringKind,

    // The item is corresponding to the '%m' format specifier, no value is
    // populated in the buffer and the runtime is loading the errno value.
    ErrnoKind,

    // The item is a mask type.
    MaskKind
  };

  enum {
    // The item is marked "private" in the format string.
    IsPrivate = 0x1,

    // The item is marked "public" in the format string.
    IsPublic = 0x2,

    // The item is marked "sensitive" in the format string.
    IsSensitive = 0x4 | IsPrivate
  };

private:
  Kind TheKind = ScalarKind;
  const Expr *TheExpr = nullptr;
  CharUnits ConstValue;
  CharUnits Size; // size of the data, not including the header bytes
  unsigned Flags = 0;
  StringRef MaskType;

public:
  OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags,
                  StringRef maskType = StringRef())
      : TheKind(kind), TheExpr(expr), Size(size), Flags(flags),
        MaskType(maskType) {
    assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) ||
            (Flags == IsSensitive)) &&
           "unexpected privacy flag");
  }

  OSLogBufferItem(ASTContext &Ctx, CharUnits value, unsigned flags)
      : TheKind(CountKind), ConstValue(value),
        Size(Ctx.getTypeSizeInChars(Ctx.IntTy)), Flags(flags) {}

  unsigned char getDescriptorByte() const {
    unsigned char result = Flags;
    result |= ((unsigned)getKind()) << 4;
    return result;
  }

  unsigned char getSizeByte() const { return size().getQuantity(); }

  Kind getKind() const { return TheKind; }
  bool getIsPrivate() const { return (Flags & IsPrivate) != 0; }

  const Expr *getExpr() const { return TheExpr; }
  CharUnits getConstValue() const { return ConstValue; }
  CharUnits size() const { return Size; }

  StringRef getMaskType() const { return MaskType; }
};

class OSLogBufferLayout {
public:
  SmallVector<OSLogBufferItem, 4> Items;

  enum Flags { HasPrivateItems = 1, HasNonScalarItems = 1 << 1 };

  CharUnits size() const {
    CharUnits result;
    result += CharUnits::fromQuantity(2); // summary byte, num-args byte
    for (auto &item : Items) {
      // descriptor byte, size byte
      result += item.size() + CharUnits::fromQuantity(2);
    }
    return result;
  }

  bool hasPrivateItems() const {
    return llvm::any_of(
        Items, [](const OSLogBufferItem &Item) { return Item.getIsPrivate(); });
  }

  bool hasNonScalarOrMask() const {
    return llvm::any_of(Items, [](const OSLogBufferItem &Item) {
      return Item.getKind() != OSLogBufferItem::ScalarKind ||
             !Item.getMaskType().empty();
    });
  }

  unsigned char getSummaryByte() const {
    unsigned char result = 0;
    if (hasPrivateItems())
      result |= HasPrivateItems;
    if (hasNonScalarOrMask())
      result |= HasNonScalarItems;
    return result;
  }

  unsigned char getNumArgsByte() const { return Items.size(); }
};

// Given a call 'E' to one of the builtins __builtin_os_log_format() or
// __builtin_os_log_format_buffer_size(), compute the layout of the buffer that
// the call will write into and store it in 'layout'. Returns 'false' if there
// was some error encountered while computing the layout, and 'true' otherwise.
bool computeOSLogBufferLayout(clang::ASTContext &Ctx, const clang::CallExpr *E,
                              OSLogBufferLayout &layout);

} // namespace analyze_os_log
} // namespace clang
#endif
