diff options
Diffstat (limited to 'clang/lib/CodeGen/Address.h')
| -rw-r--r-- | clang/lib/CodeGen/Address.h | 117 | 
1 files changed, 117 insertions, 0 deletions
| diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h new file mode 100644 index 000000000000..6a8e57f8db33 --- /dev/null +++ b/clang/lib/CodeGen/Address.h @@ -0,0 +1,117 @@ +//===-- Address.h - An aligned address -------------------------*- 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 class provides a simple wrapper for a pair of a pointer and an +// alignment. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_ADDRESS_H +#define LLVM_CLANG_LIB_CODEGEN_ADDRESS_H + +#include "llvm/IR/Constants.h" +#include "clang/AST/CharUnits.h" + +namespace clang { +namespace CodeGen { + +/// An aligned address. +class Address { +  llvm::Value *Pointer; +  CharUnits Alignment; +public: +  Address(llvm::Value *pointer, CharUnits alignment) +      : Pointer(pointer), Alignment(alignment) { +    assert((!alignment.isZero() || pointer == nullptr) && +           "creating valid address with invalid alignment"); +  } + +  static Address invalid() { return Address(nullptr, CharUnits()); } +  bool isValid() const { return Pointer != nullptr; } + +  llvm::Value *getPointer() const { +    assert(isValid()); +    return Pointer; +  } + +  /// Return the type of the pointer value. +  llvm::PointerType *getType() const { +    return llvm::cast<llvm::PointerType>(getPointer()->getType()); +  } + +  /// Return the type of the values stored in this address. +  /// +  /// When IR pointer types lose their element type, we should simply +  /// store it in Address instead for the convenience of writing code. +  llvm::Type *getElementType() const { +    return getType()->getElementType(); +  } + +  /// Return the address space that this address resides in. +  unsigned getAddressSpace() const { +    return getType()->getAddressSpace(); +  } + +  /// Return the IR name of the pointer value. +  llvm::StringRef getName() const { +    return getPointer()->getName(); +  } + +  /// Return the alignment of this pointer. +  CharUnits getAlignment() const { +    assert(isValid()); +    return Alignment; +  } +}; + +/// A specialization of Address that requires the address to be an +/// LLVM Constant. +class ConstantAddress : public Address { +public: +  ConstantAddress(llvm::Constant *pointer, CharUnits alignment) +    : Address(pointer, alignment) {} + +  static ConstantAddress invalid() { +    return ConstantAddress(nullptr, CharUnits()); +  } + +  llvm::Constant *getPointer() const { +    return llvm::cast<llvm::Constant>(Address::getPointer()); +  } + +  ConstantAddress getBitCast(llvm::Type *ty) const { +    return ConstantAddress(llvm::ConstantExpr::getBitCast(getPointer(), ty), +                           getAlignment()); +  } + +  ConstantAddress getElementBitCast(llvm::Type *ty) const { +    return getBitCast(ty->getPointerTo(getAddressSpace())); +  } + +  static bool isaImpl(Address addr) { +    return llvm::isa<llvm::Constant>(addr.getPointer()); +  } +  static ConstantAddress castImpl(Address addr) { +    return ConstantAddress(llvm::cast<llvm::Constant>(addr.getPointer()), +                           addr.getAlignment()); +  } +}; + +} + +// Present a minimal LLVM-like casting interface. +template <class U> inline U cast(CodeGen::Address addr) { +  return U::castImpl(addr); +} +template <class U> inline bool isa(CodeGen::Address addr) { +  return U::isaImpl(addr); +} + +} + +#endif | 
