================
@@ -0,0 +1,390 @@
+//===- SummaryDataTest.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 "../TestFixture.h"
+#include "clang/Analysis/Scalable/EntityLinker/LUSummary.h"
+#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
+#include "clang/Analysis/Scalable/Model/EntityId.h"
+#include "clang/Analysis/Scalable/Model/EntityIdTable.h"
+#include "clang/Analysis/Scalable/Model/EntityLinkage.h"
+#include "clang/Analysis/Scalable/Model/EntityName.h"
+#include "clang/Analysis/Scalable/Model/SummaryName.h"
+#include "clang/Analysis/Scalable/SummaryData/LUSummaryConsumer.h"
+#include "clang/Analysis/Scalable/SummaryData/SummaryDataBuilderRegistry.h"
+#include "clang/Analysis/Scalable/TUSummary/EntitySummary.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+#include <algorithm>
+#include <memory>
+#include <utility>
+#include <vector>
+
+using namespace clang;
+using namespace ssaf;
+
+namespace {
+
+// ---------------------------------------------------------------------------
+// Instance counter
+// ---------------------------------------------------------------------------
+
+static int NextSummaryInstanceId = 0;
+
+// ---------------------------------------------------------------------------
+// Entity summaries
+// ---------------------------------------------------------------------------
+
+class Analysis1EntitySummary : public EntitySummary {
+public:
+ int InstanceId = NextSummaryInstanceId++;
+ SummaryName getSummaryName() const override {
+ return SummaryName("Analysis1");
+ }
+};
+
+class Analysis2EntitySummary : public EntitySummary {
+public:
+ int InstanceId = NextSummaryInstanceId++;
+ SummaryName getSummaryName() const override {
+ return SummaryName("Analysis2");
+ }
+};
+
+class Analysis4EntitySummary : public EntitySummary {
+public:
+ int InstanceId = NextSummaryInstanceId++;
+ SummaryName getSummaryName() const override {
+ return SummaryName("Analysis4");
+ }
+};
+
+// ---------------------------------------------------------------------------
+// Data
+// ---------------------------------------------------------------------------
+
+class Analysis1Data : public SummaryData {
+public:
+ static SummaryName summaryName() { return SummaryName("Analysis1"); }
+ std::vector<std::pair<EntityId, int>> Entries;
+ bool WasFinalized = false;
+};
+
+class Analysis2Data : public SummaryData {
+public:
+ static SummaryName summaryName() { return SummaryName("Analysis2"); }
+ std::vector<std::pair<EntityId, int>> Entries;
+ bool WasFinalized = false;
+};
+
+// No builder or registration for Analysis3. Data for Analysis3 is inserted
+// into the LUSummary to verify the consumer silently skips it.
+class Analysis3Data : public SummaryData {
+public:
+ static SummaryName summaryName() { return SummaryName("Analysis3"); }
+};
+
+// Analysis4 has a registered builder but no data is inserted into the
+// LUSummary, so the builder is never invoked and getData returns nullptr.
+class Analysis4Data : public SummaryData {
+public:
+ static SummaryName summaryName() { return SummaryName("Analysis4"); }
+ std::vector<std::pair<EntityId, int>> Entries;
+ bool WasFinalized = false;
+};
+
+// ---------------------------------------------------------------------------
+// Builder destruction flags (reset in SetUp)
+// ---------------------------------------------------------------------------
+
+static bool Analysis1BuilderWasDestroyed = false;
+static bool Analysis2BuilderWasDestroyed = false;
+static bool Analysis4BuilderWasDestroyed = false;
+
+// ---------------------------------------------------------------------------
+// Builders
+// ---------------------------------------------------------------------------
+
+class Analysis1Builder
+ : public SummaryDataBuilder<Analysis1Data, Analysis1EntitySummary> {
+public:
+ ~Analysis1Builder() { Analysis1BuilderWasDestroyed = true; }
+
+ void addSummary(EntityId Id,
+ std::unique_ptr<Analysis1EntitySummary> S) override {
+ getData().Entries.push_back({Id, S->InstanceId});
+ }
+
+ void finalize() override { getData().WasFinalized = true; }
+};
+
+static SummaryDataBuilderRegistry::Add<Analysis1Builder>
+ RegAnalysis1("Builder for Analysis1");
+
+class Analysis2Builder
+ : public SummaryDataBuilder<Analysis2Data, Analysis2EntitySummary> {
+public:
+ ~Analysis2Builder() { Analysis2BuilderWasDestroyed = true; }
+
+ void addSummary(EntityId Id,
+ std::unique_ptr<Analysis2EntitySummary> S) override {
+ getData().Entries.push_back({Id, S->InstanceId});
+ }
+
+ void finalize() override { getData().WasFinalized = true; }
+};
+
+static SummaryDataBuilderRegistry::Add<Analysis2Builder>
+ RegAnalysis2("Builder for Analysis2");
+
+class Analysis4Builder
+ : public SummaryDataBuilder<Analysis4Data, Analysis4EntitySummary> {
+public:
+ ~Analysis4Builder() { Analysis4BuilderWasDestroyed = true; }
+
+ void addSummary(EntityId Id,
+ std::unique_ptr<Analysis4EntitySummary> S) override {
+ getData().Entries.push_back({Id, S->InstanceId});
+ }
+
+ void finalize() override { getData().WasFinalized = true; }
+};
+
+static SummaryDataBuilderRegistry::Add<Analysis4Builder>
+ RegAnalysis4("Builder for Analysis4");
+
+// ---------------------------------------------------------------------------
+// Fixture
+// ---------------------------------------------------------------------------
+
+class LUSummaryConsumerTest : public TestFixture {
+protected:
+ static constexpr EntityLinkage ExternalLinkage =
+ EntityLinkage(EntityLinkageType::External);
+
+ void SetUp() override {
+ NextSummaryInstanceId = 0;
+ Analysis1BuilderWasDestroyed = false;
+ Analysis2BuilderWasDestroyed = false;
+ Analysis4BuilderWasDestroyed = false;
+ }
+
+ std::unique_ptr<LUSummary> makeLUSummary() {
+ NestedBuildNamespace NS(
+ {BuildNamespace(BuildNamespaceKind::LinkUnit, "TestLU")});
+ return std::make_unique<LUSummary>(std::move(NS));
+ }
+
+ EntityId addEntity(LUSummary &LU, llvm::StringRef USR) {
+ NestedBuildNamespace NS(
+ {BuildNamespace(BuildNamespaceKind::LinkUnit, "TestLU")});
+ EntityName Name(USR.str(), "", NS);
+ EntityId Id = getIdTable(LU).getId(Name);
+ getLinkageTable(LU).insert({Id, ExternalLinkage});
+ return Id;
+ }
+
+ static bool hasEntry(const std::vector<std::pair<EntityId, int>> &Entries,
+ EntityId Id, int InstanceId) {
+ return std::find(Entries.begin(), Entries.end(),
+ std::make_pair(Id, InstanceId)) != Entries.end();
+ }
+
+ /// Inserts a freshly constructed SummaryT for the given entity and returns
+ /// the summary's InstanceId so the test can verify delivery later.
+ template <typename SummaryT>
+ int insertSummary(LUSummary &LU, llvm::StringRef SN, EntityId Id) {
+ auto S = std::make_unique<SummaryT>();
+ int InstanceId = S->InstanceId;
+ getData(LU)[SummaryName(SN.str())][Id] = std::move(S);
+ return InstanceId;
+ }
+};
+
+// ---------------------------------------------------------------------------
+// Tests
+// ---------------------------------------------------------------------------
+
+TEST(SummaryDataBuilderRegistryTest, BuilderIsRegistered) {
+ EXPECT_FALSE(SummaryDataBuilderRegistry::contains("Analysis10"));
+ EXPECT_TRUE(SummaryDataBuilderRegistry::contains("Analysis1"));
+ EXPECT_TRUE(SummaryDataBuilderRegistry::contains("Analysis2"));
+ EXPECT_TRUE(SummaryDataBuilderRegistry::contains("Analysis4"));
+}
+
+TEST(SummaryDataBuilderRegistryTest, BuilderCanBeInstantiated) {
+ EXPECT_EQ(SummaryDataBuilderRegistry::instantiate("Analysis10"), nullptr);
----------------
steakhal wrote:
```suggestion
EXPECT_EQ(SummaryDataBuilderRegistry::instantiate("Analysis-non-existing"),
nullptr);
```
https://github.com/llvm/llvm-project/pull/185803
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits