/// Offset of the next local variable.
unsigned NextLocalOffset = 0;
/// Location of a failure.
- llvm::Optional<SourceLocation> BailLocation;
+ std::optional<SourceLocation> BailLocation;
/// Label information for linker.
llvm::DenseMap<LabelTy, unsigned> LabelOffsets;
/// Location of label relocations.
using APSInt = llvm::APSInt;
template <typename T> using Expected = llvm::Expected<T>;
-template <typename T> using Optional = llvm::Optional<T>;
namespace clang {
namespace interp {
: Ctx(Ctx), OldDiscardResult(Ctx->DiscardResult),
OldInitFn(std::move(Ctx->InitFn)) {
Ctx->DiscardResult = NewDiscardResult;
- Ctx->InitFn = llvm::Optional<InitFnRef>{};
+ Ctx->InitFn = std::optional<InitFnRef>{};
}
/// Root constructor, setting up compilation state.
/// Old discard flag to restore.
bool OldDiscardResult;
/// Old pointer emitter to restore.
- llvm::Optional<InitFnRef> OldInitFn;
+ std::optional<InitFnRef> OldInitFn;
};
} // namespace interp
case CK_IntegralToBoolean:
case CK_IntegralCast: {
- Optional<PrimType> FromT = classify(SubExpr->getType());
- Optional<PrimType> ToT = classify(CE->getType());
+ std::optional<PrimType> FromT = classify(SubExpr->getType());
+ std::optional<PrimType> ToT = classify(CE->getType());
if (!FromT || !ToT)
return false;
}
// Typecheck the args.
- Optional<PrimType> LT = classify(LHS->getType());
- Optional<PrimType> RT = classify(RHS->getType());
- Optional<PrimType> T = classify(BO->getType());
+ std::optional<PrimType> LT = classify(LHS->getType());
+ std::optional<PrimType> RT = classify(RHS->getType());
+ std::optional<PrimType> T = classify(BO->getType());
if (!LT || !RT || !T) {
return this->bail(BO);
}
(!LHS->getType()->isPointerType() && !RHS->getType()->isPointerType()))
return false;
- Optional<PrimType> LT = classify(LHS);
- Optional<PrimType> RT = classify(RHS);
+ std::optional<PrimType> LT = classify(LHS);
+ std::optional<PrimType> RT = classify(RHS);
if (!LT || !RT)
return false;
template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
- if (Optional<PrimType> T = classify(E))
+ if (std::optional<PrimType> T = classify(E))
return this->emitZero(*T, E);
return false;
const CompoundAssignOperator *E) {
const Expr *LHS = E->getLHS();
const Expr *RHS = E->getRHS();
- Optional<PrimType> LT = classify(E->getLHS()->getType());
- Optional<PrimType> RT = classify(E->getRHS()->getType());
+ std::optional<PrimType> LT = classify(E->getLHS()->getType());
+ std::optional<PrimType> RT = classify(E->getRHS()->getType());
if (!LT || !RT)
return false;
template <class Emitter>
bool ByteCodeExprGen<Emitter>::visitBool(const Expr *E) {
- if (Optional<PrimType> T = classify(E->getType())) {
+ if (std::optional<PrimType> T = classify(E->getType())) {
return visit(E);
} else {
return this->bail(E);
bool ByteCodeExprGen<Emitter>::dereference(
const Expr *LV, DerefKind AK, llvm::function_ref<bool(PrimType)> Direct,
llvm::function_ref<bool(PrimType)> Indirect) {
- if (Optional<PrimType> T = classify(LV->getType())) {
+ if (std::optional<PrimType> T = classify(LV->getType())) {
if (!LV->refersToBitField()) {
// Only primitive, non bit-field types can be dereferenced directly.
if (auto *DE = dyn_cast<DeclRefExpr>(LV)) {
}
template <class Emitter>
-llvm::Optional<unsigned>
+std::optional<unsigned>
ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) {
QualType Ty;
if (const auto *InitList = dyn_cast<InitListExpr>(Initializer)) {
unsigned ElementIndex = 0;
for (const Expr *Init : InitList->inits()) {
- if (Optional<PrimType> T = classify(Init->getType())) {
+ if (std::optional<PrimType> T = classify(Init->getType())) {
// Visit the primitive element like normal.
if (!this->emitDupPtr(Init))
return false;
// the AILE's Common expr.
const Expr *SubExpr = AILE->getSubExpr();
size_t Size = AILE->getArraySize().getZExtValue();
- Optional<PrimType> ElemT = classify(SubExpr->getType());
+ std::optional<PrimType> ElemT = classify(SubExpr->getType());
// So, every iteration, we execute an assignment here
// where the LHS is on the stack (the target array)
const auto *CAT = cast<ConstantArrayType>(AT);
size_t NumElems = CAT->getSize().getZExtValue();
- if (Optional<PrimType> ElemT = classify(CAT->getElementType())) {
+ if (std::optional<PrimType> ElemT = classify(CAT->getElementType())) {
// TODO(perf): For int and bool types, we can probably just skip this
// since we memset our Block*s to 0 and so we have the desired value
// without this.
if (!this->emitDupPtr(Initializer))
return false;
- if (Optional<PrimType> T = classify(Init)) {
+ if (std::optional<PrimType> T = classify(Init)) {
if (!this->visit(Init))
return false;
if (!visit(Exp))
return false;
- if (Optional<PrimType> T = classify(Exp))
+ if (std::optional<PrimType> T = classify(Exp))
return this->emitRet(*T, Exp);
else
return this->emitRetValue(Exp);
bool ByteCodeExprGen<Emitter>::visitDecl(const VarDecl *VD) {
const Expr *Init = VD->getInit();
- if (Optional<unsigned> I = P.createGlobal(VD, Init)) {
- if (Optional<PrimType> T = classify(VD->getType())) {
+ if (std::optional<unsigned> I = P.createGlobal(VD, Init)) {
+ if (std::optional<PrimType> T = classify(VD->getType())) {
{
// Primitive declarations - compute the value and set it.
DeclScope<Emitter> LocalScope(this, VD);
return false;
QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
- Optional<PrimType> T = classify(ReturnType);
+ std::optional<PrimType> T = classify(ReturnType);
if (Func->hasRVO() && DiscardResult) {
// If we need to discard the return value but the function returns its
// value via an RVO pointer, we need to create one such pointer just
// for this call.
- if (Optional<unsigned> LocalIndex = allocateLocal(E)) {
+ if (std::optional<unsigned> LocalIndex = allocateLocal(E)) {
if (!this->emitGetPtrLocal(*LocalIndex, E))
return false;
}
template <class Emitter>
bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
const Expr *SubExpr = E->getSubExpr();
- Optional<PrimType> T = classify(SubExpr->getType());
+ std::optional<PrimType> T = classify(SubExpr->getType());
// TODO: Support pointers for inc/dec operators.
switch (E->getOpcode()) {
#include "clang/AST/Expr.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/Optional.h"
namespace clang {
class QualType;
}
/// Classifies a type.
- llvm::Optional<PrimType> classify(const Expr *E) const {
+ std::optional<PrimType> classify(const Expr *E) const {
return E->isGLValue() ? PT_Ptr : classify(E->getType());
}
- llvm::Optional<PrimType> classify(QualType Ty) const {
+ std::optional<PrimType> classify(QualType Ty) const {
return Ctx.classify(Ty);
}
bool IsExtended = false);
/// Allocates a space storing a local given its type.
- llvm::Optional<unsigned> allocateLocal(DeclTy &&Decl,
- bool IsExtended = false);
+ std::optional<unsigned> allocateLocal(DeclTy &&Decl, bool IsExtended = false);
private:
friend class VariableScope<Emitter>;
VariableScope<Emitter> *VarScope = nullptr;
/// Current argument index. Needed to emit ArrayInitIndexExpr.
- llvm::Optional<uint64_t> ArrayIndex;
+ std::optional<uint64_t> ArrayIndex;
/// Flag indicating if return value is to be discarded.
bool DiscardResult = false;
/// Expression being initialized.
- llvm::Optional<InitFnRef> InitFn = {};
+ std::optional<InitFnRef> InitFn = {};
};
extern template class ByteCodeExprGen<ByteCodeEmitter>;
protected:
/// Index of the scope in the chain.
- Optional<unsigned> Idx;
+ std::optional<unsigned> Idx;
};
/// Scope for storage declared in a compound statement.
private:
ByteCodeExprGen<Emitter> *Ctx;
- Optional<uint64_t> OldArrayIndex;
+ std::optional<uint64_t> OldArrayIndex;
};
} // namespace interp
if (const FieldDecl *Member = Init->getMember()) {
const Record::Field *F = R->getField(Member);
- if (Optional<PrimType> T = this->classify(InitExpr)) {
+ if (std::optional<PrimType> T = this->classify(InitExpr)) {
if (!this->emitThis(InitExpr))
return false;
}
// Integers, pointers, primitives.
- if (Optional<PrimType> T = this->classify(VD->getType())) {
+ if (std::optional<PrimType> T = this->classify(VD->getType())) {
const Expr *Init = VD->getInit();
if (!Init)
}
// Composite types - allocate storage and initialize it.
- if (Optional<unsigned> Offset = this->allocateLocal(VD))
+ if (std::optional<unsigned> Offset = this->allocateLocal(VD))
return this->visitLocalInitializer(VD->getInit(), *Offset);
return this->bail(VD);
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtVisitor.h"
-#include "llvm/ADT/Optional.h"
namespace clang {
namespace interp {
class ByteCodeStmtGen final : public ByteCodeExprGen<Emitter> {
using LabelTy = typename Emitter::LabelTy;
using AddrTy = typename Emitter::AddrTy;
- using OptLabelTy = llvm::Optional<LabelTy>;
+ using OptLabelTy = std::optional<LabelTy>;
using CaseMap = llvm::DenseMap<const SwitchCase *, LabelTy>;
public:
private:
/// Type of the expression returned by the function.
- llvm::Optional<PrimType> ReturnType;
+ std::optional<PrimType> ReturnType;
/// Switch case mapping.
CaseMap CaseLabels;
const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); }
-llvm::Optional<PrimType> Context::classify(QualType T) const {
+std::optional<PrimType> Context::classify(QualType T) const {
if (T->isReferenceType() || T->isPointerType()) {
return PT_Ptr;
}
unsigned getCharBit() const;
/// Classifies an expression.
- llvm::Optional<PrimType> classify(QualType T) const;
+ std::optional<PrimType> classify(QualType T) const;
private:
/// Runs a function.
const Pointer &FP = Ptr.atField(F.Offset);
QualType FieldTy = F.Decl->getType();
if (FP.isActive()) {
- if (llvm::Optional<PrimType> T = Ctx.classify(FieldTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(FP.deref<T>(), Value));
} else {
Ok &= Composite(FieldTy, FP, Value);
const Pointer &FP = Ptr.atField(FD->Offset);
APValue &Value = R.getStructField(I);
- if (llvm::Optional<PrimType> T = Ctx.classify(FieldTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(FieldTy)) {
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(FP.deref<T>(), Value));
} else {
Ok &= Composite(FieldTy, FP, Value);
for (unsigned I = 0; I < NumElems; ++I) {
APValue &Slot = R.getArrayInitializedElt(I);
const Pointer &EP = Ptr.atIndex(I);
- if (llvm::Optional<PrimType> T = Ctx.classify(ElemTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
TYPE_SWITCH(*T, Ok &= ReturnValue<T>(EP.deref<T>(), Slot));
} else {
Ok &= Composite(ElemTy, EP.narrow(), Slot);
// value which is mapped to the location of the opcode being evaluated.
CodePtr OpPC;
/// Location of a failure.
- llvm::Optional<SourceLocation> BailLocation;
+ std::optional<SourceLocation> BailLocation;
/// Location of the current instruction.
SourceInfo CurrentSource;
class Block final {
public:
// Creates a new block.
- Block(const llvm::Optional<unsigned> &DeclID, Descriptor *Desc,
+ Block(const std::optional<unsigned> &DeclID, Descriptor *Desc,
bool IsStatic = false, bool IsExtern = false)
: DeclID(DeclID), IsStatic(IsStatic), IsExtern(IsExtern), Desc(Desc) {}
/// Returns the size of the block.
InterpSize getSize() const { return Desc->getAllocSize(); }
/// Returns the declaration ID.
- llvm::Optional<unsigned> getDeclID() const { return DeclID; }
+ std::optional<unsigned> getDeclID() const { return DeclID; }
/// Returns a pointer to the stored data.
char *data() { return reinterpret_cast<char *>(this + 1); }
/// Start of the chain of pointers.
Pointer *Pointers = nullptr;
/// Unique identifier of the declaration.
- llvm::Optional<unsigned> DeclID;
+ std::optional<unsigned> DeclID;
/// Flag indicating if the block has static storage duration.
bool IsStatic = false;
/// Flag indicating if the block is an extern.
}
/// Returns the declaration ID.
- llvm::Optional<unsigned> getDeclID() const { return Pointee->getDeclID(); }
+ std::optional<unsigned> getDeclID() const { return Pointee->getDeclID(); }
/// Returns the byte offset from the start.
unsigned getByteOffset() const {
return Pointer(Globals[Idx]->block());
}
-llvm::Optional<unsigned> Program::getGlobal(const ValueDecl *VD) {
+std::optional<unsigned> Program::getGlobal(const ValueDecl *VD) {
auto It = GlobalIndices.find(VD);
if (It != GlobalIndices.end())
return It->second;
// Find any previous declarations which were already evaluated.
- llvm::Optional<unsigned> Index;
+ std::optional<unsigned> Index;
for (const Decl *P = VD; P; P = P->getPreviousDecl()) {
auto It = GlobalIndices.find(P);
if (It != GlobalIndices.end()) {
return Index;
}
-llvm::Optional<unsigned> Program::getOrCreateGlobal(const ValueDecl *VD) {
+std::optional<unsigned> Program::getOrCreateGlobal(const ValueDecl *VD) {
if (auto Idx = getGlobal(VD))
return Idx;
return {};
}
-llvm::Optional<unsigned> Program::getOrCreateDummy(const ParmVarDecl *PD) {
+std::optional<unsigned> Program::getOrCreateDummy(const ParmVarDecl *PD) {
auto &ASTCtx = Ctx.getASTContext();
// Create a pointer to an incomplete array of the specified elements.
return {};
}
-llvm::Optional<unsigned> Program::createGlobal(const ValueDecl *VD,
- const Expr *Init) {
+std::optional<unsigned> Program::createGlobal(const ValueDecl *VD,
+ const Expr *Init) {
bool IsStatic, IsExtern;
if (auto *Var = dyn_cast<VarDecl>(VD)) {
IsStatic = !Var->hasLocalStorage();
return {};
}
-llvm::Optional<unsigned> Program::createGlobal(const Expr *E) {
+std::optional<unsigned> Program::createGlobal(const Expr *E) {
return createGlobal(E, E->getType(), /*isStatic=*/true, /*isExtern=*/false);
}
-llvm::Optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty,
- bool IsStatic, bool IsExtern,
- const Expr *Init) {
+std::optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty,
+ bool IsStatic, bool IsExtern,
+ const Expr *Init) {
// Create a descriptor for the global.
Descriptor *Desc;
const bool IsConst = Ty.isConstQualified();
const bool IsConst = FT.isConstQualified();
const bool IsMutable = FD->isMutable();
Descriptor *Desc;
- if (llvm::Optional<PrimType> T = Ctx.classify(FT)) {
+ if (std::optional<PrimType> T = Ctx.classify(FT)) {
Desc = createDescriptor(FD, *T, IsConst, /*isTemporary=*/false,
IsMutable);
} else {
// Array of well-known bounds.
if (auto CAT = dyn_cast<ConstantArrayType>(ArrayType)) {
size_t NumElems = CAT->getSize().getZExtValue();
- if (llvm::Optional<PrimType> T = Ctx.classify(ElemTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
// Arrays of primitives.
unsigned ElemSize = primSize(*T);
if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems) {
// Array of unknown bounds - cannot be accessed and pointer arithmetic
// is forbidden on pointers to such objects.
if (isa<IncompleteArrayType>(ArrayType)) {
- if (llvm::Optional<PrimType> T = Ctx.classify(ElemTy)) {
+ if (std::optional<PrimType> T = Ctx.classify(ElemTy)) {
return allocateDescriptor(D, *T, IsTemporary,
Descriptor::UnknownSize{});
} else {
}
/// Finds a global's index.
- llvm::Optional<unsigned> getGlobal(const ValueDecl *VD);
+ std::optional<unsigned> getGlobal(const ValueDecl *VD);
/// Returns or creates a global an creates an index to it.
- llvm::Optional<unsigned> getOrCreateGlobal(const ValueDecl *VD);
+ std::optional<unsigned> getOrCreateGlobal(const ValueDecl *VD);
/// Returns or creates a dummy value for parameters.
- llvm::Optional<unsigned> getOrCreateDummy(const ParmVarDecl *PD);
+ std::optional<unsigned> getOrCreateDummy(const ParmVarDecl *PD);
/// Creates a global and returns its index.
- llvm::Optional<unsigned> createGlobal(const ValueDecl *VD, const Expr *E);
+ std::optional<unsigned> createGlobal(const ValueDecl *VD, const Expr *E);
/// Creates a global from a lifetime-extended temporary.
- llvm::Optional<unsigned> createGlobal(const Expr *E);
+ std::optional<unsigned> createGlobal(const Expr *E);
/// Creates a new function from a code range.
template <typename... Ts>
};
/// Returns the current declaration ID.
- llvm::Optional<unsigned> getCurrentDecl() const {
+ std::optional<unsigned> getCurrentDecl() const {
if (CurrentDeclaration == NoDeclaration)
- return llvm::Optional<unsigned>{};
+ return std::optional<unsigned>{};
return LastDeclaration;
}
private:
friend class DeclScope;
- llvm::Optional<unsigned> createGlobal(const DeclTy &D, QualType Ty,
- bool IsStatic, bool IsExtern,
- const Expr *Init = nullptr);
+ std::optional<unsigned> createGlobal(const DeclTy &D, QualType Ty,
+ bool IsStatic, bool IsExtern,
+ const Expr *Init = nullptr);
/// Reference to the VM context.
Context &Ctx;