mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 18:26:05 +00:00

The Pointer class already has the capability to be a function pointer, but we still classifed function pointers as PT_FnPtr/FunctionPointer. This means when converting from a Pointer to a FunctionPointer, we lost the information of what the original Pointer pointed to.
132 lines
3.8 KiB
C++
132 lines
3.8 KiB
C++
//===--- Context.h - Context for the constexpr VM ---------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Defines the constexpr execution context.
|
|
//
|
|
// The execution context manages cached bytecode and the global context.
|
|
// It invokes the compiler and interpreter, propagating errors.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_AST_INTERP_CONTEXT_H
|
|
#define LLVM_CLANG_AST_INTERP_CONTEXT_H
|
|
|
|
#include "InterpStack.h"
|
|
|
|
namespace clang {
|
|
class ASTContext;
|
|
class LangOptions;
|
|
class FunctionDecl;
|
|
class VarDecl;
|
|
class APValue;
|
|
class BlockExpr;
|
|
|
|
namespace interp {
|
|
class Function;
|
|
class Program;
|
|
class State;
|
|
enum PrimType : unsigned;
|
|
|
|
struct ParamOffset {
|
|
unsigned Offset;
|
|
bool IsPtr;
|
|
};
|
|
|
|
/// Holds all information required to evaluate constexpr code in a module.
|
|
class Context final {
|
|
public:
|
|
/// Initialises the constexpr VM.
|
|
Context(ASTContext &Ctx);
|
|
|
|
/// Cleans up the constexpr VM.
|
|
~Context();
|
|
|
|
/// Checks if a function is a potential constant expression.
|
|
bool isPotentialConstantExpr(State &Parent, const FunctionDecl *FnDecl);
|
|
|
|
/// Evaluates a toplevel expression as an rvalue.
|
|
bool evaluateAsRValue(State &Parent, const Expr *E, APValue &Result);
|
|
|
|
/// Like evaluateAsRvalue(), but does no implicit lvalue-to-rvalue conversion.
|
|
bool evaluate(State &Parent, const Expr *E, APValue &Result,
|
|
ConstantExprKind Kind);
|
|
|
|
/// Evaluates a toplevel initializer.
|
|
bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);
|
|
|
|
/// Returns the AST context.
|
|
ASTContext &getASTContext() const { return Ctx; }
|
|
/// Returns the language options.
|
|
const LangOptions &getLangOpts() const;
|
|
/// Returns the interpreter stack.
|
|
InterpStack &getStack() { return Stk; }
|
|
/// Returns CHAR_BIT.
|
|
unsigned getCharBit() const;
|
|
/// Return the floating-point semantics for T.
|
|
const llvm::fltSemantics &getFloatSemantics(QualType T) const;
|
|
/// Return the size of T in bits.
|
|
uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
|
|
|
|
/// Classifies a type.
|
|
std::optional<PrimType> classify(QualType T) const;
|
|
|
|
/// Classifies an expression.
|
|
std::optional<PrimType> classify(const Expr *E) const {
|
|
assert(E);
|
|
if (E->isGLValue())
|
|
return PT_Ptr;
|
|
|
|
return classify(E->getType());
|
|
}
|
|
|
|
const CXXMethodDecl *
|
|
getOverridingFunction(const CXXRecordDecl *DynamicDecl,
|
|
const CXXRecordDecl *StaticDecl,
|
|
const CXXMethodDecl *InitialFunction) const;
|
|
|
|
const Function *getOrCreateFunction(const FunctionDecl *FuncDecl);
|
|
const Function *getOrCreateObjCBlock(const BlockExpr *E);
|
|
|
|
/// Returns whether we should create a global variable for the
|
|
/// given ValueDecl.
|
|
static bool shouldBeGloballyIndexed(const ValueDecl *VD) {
|
|
if (const auto *V = dyn_cast<VarDecl>(VD))
|
|
return V->hasGlobalStorage() || V->isConstexpr();
|
|
|
|
return false;
|
|
}
|
|
|
|
/// Returns the program. This is only needed for unittests.
|
|
Program &getProgram() const { return *P.get(); }
|
|
|
|
unsigned collectBaseOffset(const RecordDecl *BaseDecl,
|
|
const RecordDecl *DerivedDecl) const;
|
|
|
|
const Record *getRecord(const RecordDecl *D) const;
|
|
|
|
unsigned getEvalID() const { return EvalID; }
|
|
|
|
private:
|
|
/// Runs a function.
|
|
bool Run(State &Parent, const Function *Func);
|
|
|
|
/// Current compilation context.
|
|
ASTContext &Ctx;
|
|
/// Interpreter stack, shared across invocations.
|
|
InterpStack Stk;
|
|
/// Constexpr program.
|
|
std::unique_ptr<Program> P;
|
|
/// ID identifying an evaluation.
|
|
unsigned EvalID = 0;
|
|
};
|
|
|
|
} // namespace interp
|
|
} // namespace clang
|
|
|
|
#endif
|