aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/Interp/Context.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/clang/lib/AST/Interp/Context.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/Interp/Context.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/Context.cpp67
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;
+}