[clang] 5d7d6ad - [clang][Interp] Add toAPValue unittests

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 9 04:12:48 PDT 2024


Author: Timm Bäder
Date: 2024-04-09T12:36:28+02:00
New Revision: 5d7d6ad663f80fbc6161da1175476bb663301c46

URL: https://github.com/llvm/llvm-project/commit/5d7d6ad663f80fbc6161da1175476bb663301c46
DIFF: https://github.com/llvm/llvm-project/commit/5d7d6ad663f80fbc6161da1175476bb663301c46.diff

LOG: [clang][Interp] Add toAPValue unittests

Added: 
    clang/unittests/AST/Interp/toAPValue.cpp

Modified: 
    clang/unittests/AST/Interp/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/unittests/AST/Interp/CMakeLists.txt b/clang/unittests/AST/Interp/CMakeLists.txt
index 8fa5c85064dbce..ea727cdd4412be 100644
--- a/clang/unittests/AST/Interp/CMakeLists.txt
+++ b/clang/unittests/AST/Interp/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_clang_unittest(InterpTests
   Descriptor.cpp
+  toAPValue.cpp
   )
 
 clang_target_link_libraries(InterpTests

diff  --git a/clang/unittests/AST/Interp/toAPValue.cpp b/clang/unittests/AST/Interp/toAPValue.cpp
new file mode 100644
index 00000000000000..d0dfb40d514953
--- /dev/null
+++ b/clang/unittests/AST/Interp/toAPValue.cpp
@@ -0,0 +1,90 @@
+#include "../../../lib/AST/Interp/Context.h"
+#include "../../../lib/AST/Interp/Descriptor.h"
+#include "../../../lib/AST/Interp/Program.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace clang::interp;
+using namespace clang::ast_matchers;
+
+/// Test the various toAPValue implementations.
+TEST(ToAPValue, Pointers) {
+  constexpr char Code[] =
+      "struct A { bool a; bool z; };\n"
+      "struct S {\n"
+      "  A a[3];\n"
+      "};\n"
+      "constexpr S d = {{{true, false}, {false, true}, {false, false}}};\n"
+      "constexpr const bool *b = &d.a[1].z;\n";
+
+  auto AST = tooling::buildASTFromCodeWithArgs(
+      Code, {"-fexperimental-new-constant-interpreter"});
+
+  auto &Ctx = AST->getASTContext().getInterpContext();
+  Program &Prog = Ctx.getProgram();
+
+  auto getDecl = [&](const char *Name) -> const ValueDecl * {
+    auto Nodes =
+        match(valueDecl(hasName(Name)).bind("var"), AST->getASTContext());
+    assert(Nodes.size() == 1);
+    const auto *D = Nodes[0].getNodeAs<ValueDecl>("var");
+    assert(D);
+    return D;
+  };
+  auto getGlobalPtr = [&](const char *Name) -> Pointer {
+    const VarDecl *D = cast<VarDecl>(getDecl(Name));
+    return Prog.getPtrGlobal(*Prog.getGlobal(D));
+  };
+
+  const Pointer &GP = getGlobalPtr("b");
+  const Pointer &P = GP.deref<Pointer>();
+  ASSERT_TRUE(P.isLive());
+  APValue A = P.toAPValue();
+  ASSERT_TRUE(A.isLValue());
+  ASSERT_TRUE(A.hasLValuePath());
+  const auto &Path = A.getLValuePath();
+  ASSERT_EQ(Path.size(), 3u);
+  ASSERT_EQ(A.getLValueBase(), getDecl("d"));
+}
+
+TEST(ToAPValue, FunctionPointers) {
+  constexpr char Code[] = " constexpr bool foo() { return true; }\n"
+                          " constexpr bool (*func)() = foo;\n";
+
+  auto AST = tooling::buildASTFromCodeWithArgs(
+      Code, {"-fexperimental-new-constant-interpreter"});
+
+  auto &Ctx = AST->getASTContext().getInterpContext();
+  Program &Prog = Ctx.getProgram();
+
+  auto getDecl = [&](const char *Name) -> const ValueDecl * {
+    auto Nodes =
+        match(valueDecl(hasName(Name)).bind("var"), AST->getASTContext());
+    assert(Nodes.size() == 1);
+    const auto *D = Nodes[0].getNodeAs<ValueDecl>("var");
+    assert(D);
+    return D;
+  };
+
+  auto getGlobalPtr = [&](const char *Name) -> Pointer {
+    const VarDecl *D = cast<VarDecl>(getDecl(Name));
+    return Prog.getPtrGlobal(*Prog.getGlobal(D));
+  };
+
+  const Pointer &GP = getGlobalPtr("func");
+  const FunctionPointer &FP = GP.deref<FunctionPointer>();
+  ASSERT_FALSE(FP.isZero());
+  APValue A = FP.toAPValue();
+  ASSERT_TRUE(A.hasValue());
+  ASSERT_TRUE(A.isLValue());
+  ASSERT_TRUE(A.hasLValuePath());
+  const auto &Path = A.getLValuePath();
+  ASSERT_EQ(Path.size(), 0u);
+  ASSERT_FALSE(A.getLValueBase().isNull());
+  ASSERT_EQ(A.getLValueBase().dyn_cast<const ValueDecl *>(), getDecl("foo"));
+}


        


More information about the cfe-commits mailing list