blob: b844c5644a2332882a4020d7280ec394221ad728 [file]
//===------------------------- DeclOrExpr.h ---------------------*- 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_INTERP_DECLOREXPR_H
#define LLVM_CLANG_AST_INTERP_DECLOREXPR_H
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/TypeBase.h"
#include "llvm/ADT/PointerUnion.h"
namespace clang {
namespace interp {
struct DeclOrExpr {
llvm::PointerUnion<const Decl *, const Expr *> V;
DeclOrExpr() : V(nullptr) {}
DeclOrExpr(std::nullptr_t) : V(nullptr) {}
DeclOrExpr(const Decl *VD) : V(VD) {}
DeclOrExpr(const Expr *E) : V(E) {}
bool isExpr() const { return isa_and_nonnull<const Expr *>(V); }
bool isDecl() const { return isa_and_nonnull<const Decl *>(V); }
bool isValueDecl() const { return isa_and_nonnull<ValueDecl>(asDecl()); }
bool isVarDecl() const { return isa_and_nonnull<VarDecl>(asDecl()); }
const Expr *asExpr() const { return V.dyn_cast<const Expr *>(); }
const Decl *asDecl() const { return V.dyn_cast<const Decl *>(); }
const ValueDecl *asValueDecl() const {
return dyn_cast_if_present<ValueDecl>(asDecl());
}
const VarDecl *asVarDecl() const {
return dyn_cast_if_present<VarDecl>(asDecl());
}
const void *getOpaqueValue() const { return V.getOpaqueValue(); }
bool operator==(DeclOrExpr O) const { return O.V == V; }
bool operator!=(DeclOrExpr O) const { return O.V != V; }
explicit operator bool() const { return !V.isNull(); }
QualType getType() const {
if (const auto *VD = asValueDecl())
return VD->getType();
return asExpr()->getType();
}
SourceLocation getLocation() const {
if (const auto *VD = asValueDecl())
return VD->getLocation();
return asExpr()->getExprLoc();
}
};
static_assert(sizeof(DeclOrExpr) == sizeof(void *));
inline DeclOrExpr getSwappedBytes(DeclOrExpr F) { return F; }
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, DeclOrExpr D) {
OS << D.getOpaqueValue();
return OS;
}
} // namespace interp
} // namespace clang
#endif