Files
swift-mirror/include/swift/Remote/RemoteAddress.h
tbkka 3c8fde7885 Implement MultiPayloadEnum support for projectEnumValue (#30635)
This code rearchitects and simplifies the projectEnumValue support by
introducing a new `TypeInfo` subclass for each kind of enum, including trivial,
no-payload, single-payload, and three different classes for multi-payload enums:

* "UnsupportedEnum" that we don't understand.  This returns "don't know" answers for all requests in cases where the runtime lacks enough information to accurately handle a particular enum.

* MP Enums that only use a separate tag value.  This includes generic enums and other dynamic layouts, as well as enums whose payloads have no spare bits.

* MP Enums that use spare bits, possibly in addition to a separate tag.  This logic can only be used, of course, if we can in fact compute a spare bit mask that agrees with the compiler.

The final challenge is to choose one of the above three handlings for every MPE.  Currently, we do not have an accurate source of information for the spare bit mask, so we never choose the third option above.  We use the second option for dynamic MPE layouts (including generics) and the first for everything else.

TODO: Once we can arrange for the compiler to expose spare bit mask data, we'll be able to use that to drive more MPE cases.
2020-03-31 15:12:44 -07:00

103 lines
2.7 KiB
C++

//===--- RemoteAddress.h - Address of remote memory -------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the RemoteAddress type, which abstracts over an
// address in a remote process.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_REMOTE_REMOTEADDRESS_H
#define SWIFT_REMOTE_REMOTEADDRESS_H
#include <cstdint>
#include <string>
#include <llvm/ADT/StringRef.h>
#include <cassert>
namespace swift {
namespace remote {
/// An abstract address in the remote process's address space.
class RemoteAddress {
uint64_t Data;
public:
explicit RemoteAddress(const void *localPtr)
: Data(reinterpret_cast<uintptr_t>(localPtr)) {}
explicit RemoteAddress(uint64_t addressData) : Data(addressData) {}
explicit operator bool() const {
return Data != 0;
}
template <class T>
const T *getLocalPointer() const {
return reinterpret_cast<const T*>(static_cast<uintptr_t>(Data));
}
uint64_t getAddressData() const {
return Data;
}
template<typename IntegerType>
RemoteAddress& operator+=(const IntegerType& rhs) {
Data += rhs;
return *this;
}
template<typename IntegerType>
friend RemoteAddress operator+(RemoteAddress lhs,
const IntegerType& rhs) {
return lhs += rhs;
}
};
/// A symbolic relocated absolute pointer value.
class RemoteAbsolutePointer {
/// The symbol name that the pointer refers to. Empty if the value is absolute.
std::string Symbol;
/// The offset from the symbol, or the resolved remote address if \c Symbol is empty.
int64_t Offset;
public:
RemoteAbsolutePointer()
: Symbol(), Offset(0)
{}
RemoteAbsolutePointer(std::nullptr_t)
: RemoteAbsolutePointer()
{}
RemoteAbsolutePointer(llvm::StringRef Symbol, int64_t Offset)
: Symbol(Symbol), Offset(Offset)
{}
bool isResolved() const { return Symbol.empty(); }
llvm::StringRef getSymbol() const { return Symbol; }
int64_t getOffset() const { return Offset; }
RemoteAddress getResolvedAddress() const {
assert(isResolved());
return RemoteAddress(Offset);
}
explicit operator bool() const {
return Offset != 0 || !Symbol.empty();
}
};
} // end namespace remote
} // end namespace swift
#endif // SWIFT_REMOTE_REMOTEADDRESS_H