diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/clang/lib/AST/Interp/Context.cpp | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) |
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/Context.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/Interp/Context.cpp | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp b/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp index 16471242f328..eeb7fa9379f5 100644 --- a/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp +++ b/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp @@ -42,6 +42,11 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { } } + APValue DummyResult; + if (!Run(Parent, Func, DummyResult)) { + return false; + } + return Func->isConstexpr(); } @@ -50,6 +55,11 @@ bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); if (Check(Parent, C.interpretExpr(E))) { assert(Stk.empty()); +#ifndef NDEBUG + // Make sure we don't rely on some value being still alive in + // InterpStack memory. + Stk.clear(); +#endif return true; } @@ -63,6 +73,11 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, ByteCodeExprGen<EvalEmitter> C(*this, *P, Parent, Stk, Result); if (Check(Parent, C.interpretDecl(VD))) { assert(Stk.empty()); +#ifndef NDEBUG + // Make sure we don't rely on some value being still alive in + // InterpStack memory. + Stk.clear(); +#endif return true; } @@ -73,9 +88,11 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD, const LangOptions &Context::getLangOpts() const { return Ctx.getLangOpts(); } std::optional<PrimType> Context::classify(QualType T) const { - if (T->isReferenceType() || T->isPointerType()) { + if (T->isFunctionPointerType() || T->isFunctionReferenceType()) + return PT_FnPtr; + + if (T->isReferenceType() || T->isPointerType()) return PT_Ptr; - } if (T->isBooleanType()) return PT_Bool; @@ -113,6 +130,9 @@ std::optional<PrimType> Context::classify(QualType T) const { if (T->isNullPtrType()) return PT_Ptr; + if (T->isFloatingType()) + return PT_Float; + if (auto *AT = dyn_cast<AtomicType>(T)) return classify(AT->getValueType()); @@ -123,7 +143,13 @@ unsigned Context::getCharBit() const { return Ctx.getTargetInfo().getCharWidth(); } -bool Context::Run(State &Parent, Function *Func, APValue &Result) { +/// Simple wrapper around getFloatTypeSemantics() to make code a +/// little shorter. +const llvm::fltSemantics &Context::getFloatSemantics(QualType T) const { + return Ctx.getFloatTypeSemantics(T); +} + +bool Context::Run(State &Parent, const Function *Func, APValue &Result) { InterpState State(Parent, *P, Stk, *this); State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, {}); if (Interpret(State, Result)) @@ -142,3 +168,38 @@ bool Context::Check(State &Parent, llvm::Expected<bool> &&Flag) { }); return false; } + +// TODO: Virtual bases? +const CXXMethodDecl * +Context::getOverridingFunction(const CXXRecordDecl *DynamicDecl, + const CXXRecordDecl *StaticDecl, + const CXXMethodDecl *InitialFunction) const { + + const CXXRecordDecl *CurRecord = DynamicDecl; + const CXXMethodDecl *FoundFunction = InitialFunction; + for (;;) { + const CXXMethodDecl *Overrider = + FoundFunction->getCorrespondingMethodDeclaredInClass(CurRecord, false); + if (Overrider) + return Overrider; + + // Common case of only one base class. + if (CurRecord->getNumBases() == 1) { + CurRecord = CurRecord->bases_begin()->getType()->getAsCXXRecordDecl(); + continue; + } + + // Otherwise, go to the base class that will lead to the StaticDecl. + for (const CXXBaseSpecifier &Spec : CurRecord->bases()) { + const CXXRecordDecl *Base = Spec.getType()->getAsCXXRecordDecl(); + if (Base == StaticDecl || Base->isDerivedFrom(StaticDecl)) { + CurRecord = Base; + break; + } + } + } + + llvm_unreachable( + "Couldn't find an overriding function in the class hierarchy?"); + return nullptr; +} |