================ @@ -0,0 +1,343 @@ +//===- unittests/Analysis/Scalable/ASTEntityMappingTest.cpp --------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/Scalable/ASTEntityMapping.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::ast_matchers; + +namespace clang { +namespace ssaf { +namespace { + +// Helper function to find a declaration by name +template <typename DeclType> +const DeclType *findDecl(ASTContext &Ctx, StringRef Name) { + auto Matcher = namedDecl(hasName(Name)).bind("decl"); + auto Matches = match(Matcher, Ctx); + if (Matches.empty()) + return nullptr; + return Matches[0].getNodeAs<DeclType>("decl"); +} + +TEST(ASTEntityMappingTest, FunctionDecl) { + auto AST = tooling::buildASTFromCode("void foo() {}"); + auto &Ctx = AST->getASTContext(); + + const auto *FD = findDecl<FunctionDecl>(Ctx, "foo"); + ASSERT_NE(FD, nullptr); + + auto EntityName = getLocalEntityNameForDecl(FD); + EXPECT_TRUE(EntityName.has_value()); +} + +TEST(ASTEntityMappingTest, VarDecl) { + auto AST = tooling::buildASTFromCode("int x = 42;"); + auto &Ctx = AST->getASTContext(); + + const auto *VD = findDecl<VarDecl>(Ctx, "x"); + ASSERT_NE(VD, nullptr); + + auto EntityName = getLocalEntityNameForDecl(VD); + EXPECT_TRUE(EntityName.has_value()); +} + +TEST(ASTEntityMappingTest, ParmVarDecl) { + auto AST = tooling::buildASTFromCode("void foo(int x) {}"); + auto &Ctx = AST->getASTContext(); + + const auto *FD = findDecl<FunctionDecl>(Ctx, "foo"); + ASSERT_NE(FD, nullptr); + ASSERT_GT(FD->param_size(), 0u); + + const auto *PVD = FD->getParamDecl(0); + ASSERT_NE(PVD, nullptr); + + auto EntityName = getLocalEntityNameForDecl(PVD); + EXPECT_TRUE(EntityName.has_value()); +} + +TEST(ASTEntityMappingTest, RecordDecl) { + auto AST = tooling::buildASTFromCode("struct S {};"); + auto &Ctx = AST->getASTContext(); + + const auto *RD = findDecl<RecordDecl>(Ctx, "S"); + ASSERT_NE(RD, nullptr); + + auto EntityName = getLocalEntityNameForDecl(RD); + EXPECT_TRUE(EntityName.has_value()); +} + +TEST(ASTEntityMappingTest, FieldDecl) { + auto AST = tooling::buildASTFromCode("struct S { int field; };"); + auto &Ctx = AST->getASTContext(); + + const auto *FD = findDecl<FieldDecl>(Ctx, "field"); + ASSERT_NE(FD, nullptr); + + auto EntityName = getLocalEntityNameForDecl(FD); + EXPECT_TRUE(EntityName.has_value()); +} + +TEST(ASTEntityMappingTest, NullDecl) { + auto EntityName = getLocalEntityNameForDecl(nullptr); + EXPECT_FALSE(EntityName.has_value()); +} + +TEST(ASTEntityMappingTest, ImplicitDecl) { + auto AST = tooling::buildASTFromCode(R"( + struct S { + S() = default; + }; + )", "test.cpp", std::make_shared<PCHContainerOperations>()); + auto &Ctx = AST->getASTContext(); + + const auto *RD = findDecl<CXXRecordDecl>(Ctx, "S"); + ASSERT_NE(RD, nullptr); + + // Find the implicitly-declared copy constructor + for (const auto *Ctor : RD->ctors()) { + if (Ctor->isCopyConstructor() && Ctor->isImplicit()) { + auto EntityName = getLocalEntityNameForDecl(Ctor); + EXPECT_FALSE(EntityName.has_value()); + return; + } + } ---------------- steakhal wrote:
I dislike the early return. It makes me think about the control-flow and the loop. I wonder if using `llvm::find_singleton` would make this more declarative? Having a predicate for selecting the desired constructor and then apply the test. https://github.com/llvm/llvm-project/pull/169131 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
