blob: 976641f51e03f06f77e4f97e56fdeb392989e016 [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 "src/developer/debug/zxdb/expr/expr_value_source.h"
#include "src/lib/fxl/memory/ref_ptr.h"
namespace zxdb {
class Err;
class ExprValue;
class Type;
// Our casting rules are somewhat different than C++. In a debugger, we want to
// be as permissive as reasonable given the rules of the requested cast. When
// the user is interactively assigning or converting values, they usually don't
// want the warnings and errors that come with C++.
enum class CastType {
// Implicit casts are for expressions like "double d = (float)f";
//
// Any number can be converted to any other number, even if the sign is
// different, it is truncated, or there is a float/integer mismatch. Pointers
// can be converted back-and-forth to integers as long as the sizes match.
// Composite types can be copied if the type names and sizes match (the
// type objects don't necessarily need to point to the same thing because
// we can easily get different definitions of the same type).
kImplicit,
// A C-style cast: "(int)foo;".
//
// This attempts a static_cast and falls back to reinterpret_cast.
kC,
// Converts pointer types.
//
// Our rules are more lax than C++, allowing any conversion that can be
// reasonable executed. C++ will, for example, prohibit conversion of a
// 32-bit integer to a 64-bit pointer, but if the user types
// "reinterpret_cast<char*>(0x12343567)" we want the debugger to be able to
// execute.
kReinterpret,
// Compared to C++, the debugger's implicit cast is so powerful that the only
// thing that static_cast adds is conversions to derived classes for pointers
// and references.
kStatic
// We don't bother implementing const_cast and dynamic_cast yet because
// they're less useful in a debugger.
};
const char* CastTypeToString(CastType);
// Casts to a given type using a specific set of casting rules.
//
// This function is synchronous so can not follow references to evaluate the
// referenced data for casting. This means that the source data must already
// be in the correct form.
//
// Some types of casts requires that references be followed (e.g.
// int& -> long), while others require that they not be followed (e.g.
// BaseClass& -> DerivedClass&). Calling code should use
// CastShouldFollowReferences to determine if the source should have references
// followed (ExprNode::EvalFollowReferences) or not (ExprNode::Eval) before
// calling this function.
//
// The dest_source is an optional specification of what "source location" the
// returned value should have.
Err CastExprValue(CastType cast_type, const ExprValue& source,
const fxl::RefPtr<Type>& dest_type, ExprValue* result,
const ExprValueSource& dest_source = ExprValueSource());
// See comment for CastExprValue. This determines whether the source should
// have references expanded to the referenced data before executing the given
// cast.
bool CastShouldFollowReferences(CastType cast_type, const ExprValue& source,
const fxl::RefPtr<Type>& dest_type);
} // namespace zxdb