//===-- ubsan_diag.h --------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Diagnostics emission for Clang's undefined behavior sanitizer.
//
//===----------------------------------------------------------------------===//
#ifndef UBSAN_DIAG_H
#define UBSAN_DIAG_H

#include "ubsan_value.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_symbolizer.h"

namespace __ubsan {

class SymbolizedStackHolder {
  SymbolizedStack *Stack;

  void clear() {
    if (Stack)
      Stack->ClearAll();
  }

public:
  explicit SymbolizedStackHolder(SymbolizedStack *Stack = nullptr)
      : Stack(Stack) {}
  ~SymbolizedStackHolder() { clear(); }
  void reset(SymbolizedStack *S) {
    if (Stack != S)
      clear();
    Stack = S;
  }
  const SymbolizedStack *get() const { return Stack; }
};

SymbolizedStack *getSymbolizedLocation(uptr PC);

inline SymbolizedStack *getCallerLocation(uptr CallerPC) {
  CHECK(CallerPC);
  uptr PC = StackTrace::GetPreviousInstructionPc(CallerPC);
  return getSymbolizedLocation(PC);
}

/// A location of some data within the program's address space.
typedef uptr MemoryLocation;

/// \brief Location at which a diagnostic can be emitted. Either a
/// SourceLocation, a MemoryLocation, or a SymbolizedStack.
class Location {
public:
  enum LocationKind { LK_Null, LK_Source, LK_Memory, LK_Symbolized };

private:
  LocationKind Kind;
  // FIXME: In C++11, wrap these in an anonymous union.
  SourceLocation SourceLoc;
  MemoryLocation MemoryLoc;
  const SymbolizedStack *SymbolizedLoc;  // Not owned.

public:
  Location() : Kind(LK_Null) {}
  Location(SourceLocation Loc) :
    Kind(LK_Source), SourceLoc(Loc) {}
  Location(MemoryLocation Loc) :
    Kind(LK_Memory), MemoryLoc(Loc) {}
  // SymbolizedStackHolder must outlive Location object.
  Location(const SymbolizedStackHolder &Stack) :
    Kind(LK_Symbolized), SymbolizedLoc(Stack.get()) {}

  LocationKind getKind() const { return Kind; }

  bool isSourceLocation() const { return Kind == LK_Source; }
  bool isMemoryLocation() const { return Kind == LK_Memory; }
  bool isSymbolizedStack() const { return Kind == LK_Symbolized; }

  SourceLocation getSourceLocation() const {
    CHECK(isSourceLocation());
    return SourceLoc;
  }
  MemoryLocation getMemoryLocation() const {
    CHECK(isMemoryLocation());
    return MemoryLoc;
  }
  const SymbolizedStack *getSymbolizedStack() const {
    CHECK(isSymbolizedStack());
    return SymbolizedLoc;
  }
};

/// A diagnostic severity level.
enum DiagLevel {
  DL_Error, ///< An error.
  DL_Note   ///< A note, attached to a prior diagnostic.
};

/// \brief Annotation for a range of locations in a diagnostic.
class Range {
  Location Start, End;
  const char *Text;

public:
  Range() : Start(), End(), Text() {}
  Range(MemoryLocation Start, MemoryLocation End, const char *Text)
    : Start(Start), End(End), Text(Text) {}
  Location getStart() const { return Start; }
  Location getEnd() const { return End; }
  const char *getText() const { return Text; }
};

/// \brief A mangled C++ name. Really just a strong typedef for 'const char*'.
class MangledName {
  const char *Name;
public:
  MangledName(const char *Name) : Name(Name) {}
  const char *getName() const { return Name; }
};

/// \brief Representation of an in-flight diagnostic.
///
/// Temporary \c Diag instances are created by the handler routines to
/// accumulate arguments for a diagnostic. The destructor emits the diagnostic
/// message.
class Diag {
  /// The location at which the problem occurred.
  Location Loc;

  /// The diagnostic level.
  DiagLevel Level;

  /// The message which will be emitted, with %0, %1, ... placeholders for
  /// arguments.
  const char *Message;

public:
  /// Kinds of arguments, corresponding to members of \c Arg's union.
  enum ArgKind {
    AK_String, ///< A string argument, displayed as-is.
    AK_Mangled,///< A C++ mangled name, demangled before display.
    AK_UInt,   ///< An unsigned integer argument.
    AK_SInt,   ///< A signed integer argument.
    AK_Float,  ///< A floating-point argument.
    AK_Pointer ///< A pointer argument, displayed in hexadecimal.
  };

  /// An individual diagnostic message argument.
  struct Arg {
    Arg() {}
    Arg(const char *String) : Kind(AK_String), String(String) {}
    Arg(MangledName MN) : Kind(AK_Mangled), String(MN.getName()) {}
    Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
    Arg(SIntMax SInt) : Kind(AK_SInt), SInt(SInt) {}
    Arg(FloatMax Float) : Kind(AK_Float), Float(Float) {}
    Arg(const void *Pointer) : Kind(AK_Pointer), Pointer(Pointer) {}

    ArgKind Kind;
    union {
      const char *String;
      UIntMax UInt;
      SIntMax SInt;
      FloatMax Float;
      const void *Pointer;
    };
  };

private:
  static const unsigned MaxArgs = 5;
  static const unsigned MaxRanges = 1;

  /// The arguments which have been added to this diagnostic so far.
  Arg Args[MaxArgs];
  unsigned NumArgs;

  /// The ranges which have been added to this diagnostic so far.
  Range Ranges[MaxRanges];
  unsigned NumRanges;

  Diag &AddArg(Arg A) {
    CHECK(NumArgs != MaxArgs);
    Args[NumArgs++] = A;
    return *this;
  }

  Diag &AddRange(Range A) {
    CHECK(NumRanges != MaxRanges);
    Ranges[NumRanges++] = A;
    return *this;
  }

  /// \c Diag objects are not copyable.
  Diag(const Diag &); // NOT IMPLEMENTED
  Diag &operator=(const Diag &);

public:
  Diag(Location Loc, DiagLevel Level, const char *Message)
    : Loc(Loc), Level(Level), Message(Message), NumArgs(0), NumRanges(0) {}
  ~Diag();

  Diag &operator<<(const char *Str) { return AddArg(Str); }
  Diag &operator<<(MangledName MN) { return AddArg(MN); }
  Diag &operator<<(unsigned long long V) { return AddArg(UIntMax(V)); }
  Diag &operator<<(const void *V) { return AddArg(V); }
  Diag &operator<<(const TypeDescriptor &V);
  Diag &operator<<(const Value &V);
  Diag &operator<<(const Range &R) { return AddRange(R); }
};

struct ReportOptions {
  /// If DieAfterReport is specified, UBSan will terminate the program after the
  /// report is printed.
  bool DieAfterReport;
  /// pc/bp are used to unwind the stack trace.
  uptr pc;
  uptr bp;
};

#define GET_REPORT_OPTIONS(die_after_report) \
    GET_CALLER_PC_BP; \
    ReportOptions Opts = {die_after_report, pc, bp}

/// \brief Instantiate this class before printing diagnostics in the error
/// report. This class ensures that reports from different threads and from
/// different sanitizers won't be mixed.
class ScopedReport {
  ReportOptions Opts;
  Location SummaryLoc;

public:
  ScopedReport(ReportOptions Opts, Location SummaryLoc);
  ~ScopedReport();
};

void InitializeSuppressions();
bool IsVptrCheckSuppressed(const char *TypeName);

} // namespace __ubsan

#endif // UBSAN_DIAG_H
