blob: a6dc78b8c0fc1b6c2318bd039b8ba2ec27d4a543 [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <inttypes.h>
#include <vector>
#include "garnet/bin/zxdb/expr/expr_value_source.h"
#include "garnet/bin/zxdb/symbols/type.h"
#include "lib/fxl/memory/ref_ptr.h"
namespace zxdb {
class Err;
class Type;
// Holds a value for an expression. This could be the value of a variable in
// memory (e.g. the value of "a" when you type "print a"), or it could be
// a temporary that the debugger has computed as part of an expression.
class ExprValue {
public:
ExprValue();
// Constructs a value from the corresponding C++ value. A Type will be
// created to represent the value.
explicit ExprValue(bool value);
explicit ExprValue(int8_t value);
explicit ExprValue(uint8_t value);
explicit ExprValue(int16_t value);
explicit ExprValue(uint16_t value);
explicit ExprValue(int32_t value);
explicit ExprValue(uint32_t value);
explicit ExprValue(int64_t value);
explicit ExprValue(uint64_t value);
// Full constructor.
ExprValue(fxl::RefPtr<Type> symbol_type, std::vector<uint8_t> data,
const ExprValueSource& source = ExprValueSource());
~ExprValue();
// Used for tests. If a SymbolType is defined, the string representation is
// compared since the pointers may not match in practice.
bool operator==(const ExprValue& other) const;
// May be null if there's no symbol type.
Type* type() const { return type_.get(); }
const fxl::RefPtr<Type>& type_ref() const { return type_; }
// Indicates the location where this value came from.
const ExprValueSource& source() const { return source_; }
const std::vector<uint8_t>& data() const { return data_; }
// Determines which base type the Value's Type is.
//
// TODO(brettw) the base type should probably be turned into a proper enum.
int GetBaseType() const;
// Returns an error if the size of the data doesn't match the parameter.
Err EnsureSizeIs(size_t size) const;
// These return the data casted to the corresponding value (specializations
// below class declaration). It will assert if the internal type and data
// size doesn't match the requested type.
template <typename T>
T GetAs() const;
// Gets the result as a [u]int64_t, promoting all shorter values to the
// longer ones. If the data size is empty or greater than 64 bits it will
// return an error.
Err PromoteTo64(int64_t* output) const;
Err PromoteTo64(uint64_t* output) const;
// Gets the result as a double. This will convert floats and doubles to
// doubles.
Err PromoteToDouble(double* output) const;
private:
// Internal constructor for the primitive types that constructs an on-the-fly
// type definition for the built-in type.
ExprValue(int base_type, const char* type_name, void* data,
uint32_t data_size);
// Application-defined type from the symbols.
fxl::RefPtr<Type> type_;
ExprValueSource source_;
std::vector<uint8_t> data_;
};
template <>
int8_t ExprValue::GetAs<int8_t>() const;
template <>
uint8_t ExprValue::GetAs<uint8_t>() const;
template <>
int16_t ExprValue::GetAs<int16_t>() const;
template <>
uint16_t ExprValue::GetAs<uint16_t>() const;
template <>
int32_t ExprValue::GetAs<int32_t>() const;
template <>
uint32_t ExprValue::GetAs<uint32_t>() const;
template <>
int64_t ExprValue::GetAs<int64_t>() const;
template <>
uint64_t ExprValue::GetAs<uint64_t>() const;
template <>
float ExprValue::GetAs<float>() const;
template <>
double ExprValue::GetAs<double>() const;
} // namespace zxdb