[Lldb-commits] [lldb] 22caa3c - [lldb] Add unit test for ClangASTImporter

Raphael Isemann via lldb-commits lldb-commits at lists.llvm.org
Mon Dec 16 03:44:36 PST 2019


Author: Raphael Isemann
Date: 2019-12-16T12:43:55+01:00
New Revision: 22caa3cfbcf5762a47acc40c425d9fe0c40da621

URL: https://github.com/llvm/llvm-project/commit/22caa3cfbcf5762a47acc40c425d9fe0c40da621
DIFF: https://github.com/llvm/llvm-project/commit/22caa3cfbcf5762a47acc40c425d9fe0c40da621.diff

LOG: [lldb] Add unit test for ClangASTImporter

Added: 
    lldb/unittests/Symbol/TestClangASTImporter.cpp

Modified: 
    lldb/unittests/Symbol/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/lldb/unittests/Symbol/CMakeLists.txt b/lldb/unittests/Symbol/CMakeLists.txt
index aa86986f4e0e..02875b8b53c1 100644
--- a/lldb/unittests/Symbol/CMakeLists.txt
+++ b/lldb/unittests/Symbol/CMakeLists.txt
@@ -2,6 +2,7 @@ add_lldb_unittest(SymbolTests
   LocateSymbolFileTest.cpp
   PostfixExpressionTest.cpp
   TestClangASTContext.cpp
+  TestClangASTImporter.cpp
   TestDWARFCallFrameInfo.cpp
   TestType.cpp
   TestLineEntry.cpp

diff  --git a/lldb/unittests/Symbol/TestClangASTImporter.cpp b/lldb/unittests/Symbol/TestClangASTImporter.cpp
new file mode 100644
index 000000000000..17a0dfb6a348
--- /dev/null
+++ b/lldb/unittests/Symbol/TestClangASTImporter.cpp
@@ -0,0 +1,220 @@
+//===-- TestClangASTImporter.cpp --------------------------------*- C++ -*-===//
+//
+// 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 "gtest/gtest.h"
+
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/ClangASTImporter.h"
+#include "lldb/Symbol/ClangASTMetadata.h"
+#include "lldb/Symbol/ClangUtil.h"
+#include "lldb/Symbol/Declaration.h"
+#include "clang/AST/DeclCXX.h"
+
+using namespace clang;
+using namespace lldb;
+using namespace lldb_private;
+
+class TestClangASTImporter : public testing::Test {
+public:
+  static void SetUpTestCase() {
+    FileSystem::Initialize();
+    HostInfo::Initialize();
+  }
+
+  static void TearDownTestCase() {
+    HostInfo::Terminate();
+    FileSystem::Terminate();
+  }
+
+protected:
+  std::unique_ptr<ClangASTContext> createAST() {
+    return std::make_unique<ClangASTContext>(HostInfo::GetTargetTriple());
+  }
+
+  CompilerType createRecord(ClangASTContext &ast, const char *name) {
+    return ast.CreateRecordType(ast.getASTContext()->getTranslationUnitDecl(),
+                                lldb::AccessType::eAccessPublic, name, 0,
+                                lldb::LanguageType::eLanguageTypeC);
+  }
+};
+
+TEST_F(TestClangASTImporter, CanImportInvalidType) {
+  ClangASTImporter importer;
+  EXPECT_FALSE(importer.CanImport(CompilerType()));
+}
+
+TEST_F(TestClangASTImporter, ImportInvalidType) {
+  ClangASTImporter importer;
+  EXPECT_FALSE(importer.Import(CompilerType()));
+}
+
+TEST_F(TestClangASTImporter, CopyDeclTagDecl) {
+  // Tests that the ClangASTImporter::CopyDecl can copy TagDecls.
+  std::unique_ptr<ClangASTContext> source_ast = createAST();
+  CompilerType source_type = createRecord(*source_ast, "Source");
+  clang::TagDecl *source = ClangUtil::GetAsTagDecl(source_type);
+
+  std::unique_ptr<ClangASTContext> target_ast = createAST();
+
+  ClangASTImporter importer;
+  clang::Decl *imported = importer.CopyDecl(
+      target_ast->getASTContext(), source_ast->getASTContext(), source);
+  ASSERT_NE(nullptr, imported);
+
+  // Check that we got the correct decl by just comparing their qualified name.
+  clang::TagDecl *imported_tag_decl = llvm::cast<clang::TagDecl>(imported);
+  EXPECT_EQ(source->getQualifiedNameAsString(),
+            imported_tag_decl->getQualifiedNameAsString());
+
+  // Check that origin was set for the imported declaration.
+  ClangASTImporter::DeclOrigin origin = importer.GetDeclOrigin(imported);
+  EXPECT_TRUE(origin.Valid());
+  EXPECT_EQ(origin.ctx, source_ast->getASTContext());
+  EXPECT_EQ(origin.decl, source);
+}
+
+TEST_F(TestClangASTImporter, CopyTypeTagDecl) {
+  // Tests that the ClangASTImporter::CopyType can copy TagDecls types.
+  std::unique_ptr<ClangASTContext> source_ast = createAST();
+  CompilerType source_type = createRecord(*source_ast, "Source");
+  clang::TagDecl *source = ClangUtil::GetAsTagDecl(source_type);
+
+  std::unique_ptr<ClangASTContext> target_ast = createAST();
+
+  ClangASTImporter importer;
+  CompilerType imported = importer.CopyType(*target_ast, source_type);
+  ASSERT_TRUE(imported.IsValid());
+
+  // Check that we got the correct decl by just comparing their qualified name.
+  clang::TagDecl *imported_tag_decl = ClangUtil::GetAsTagDecl(imported);
+  EXPECT_EQ(source->getQualifiedNameAsString(),
+            imported_tag_decl->getQualifiedNameAsString());
+
+  // Check that origin was set for the imported declaration.
+  ClangASTImporter::DeclOrigin origin =
+      importer.GetDeclOrigin(imported_tag_decl);
+  EXPECT_TRUE(origin.Valid());
+  EXPECT_EQ(origin.ctx, source_ast->getASTContext());
+  EXPECT_EQ(origin.decl, source);
+}
+
+TEST_F(TestClangASTImporter, MetadataPropagation) {
+  // Tests that AST metadata is propagated when copying declarations.
+
+  std::unique_ptr<ClangASTContext> source_ast = createAST();
+  CompilerType source_type = createRecord(*source_ast, "Source");
+  clang::TagDecl *source = ClangUtil::GetAsTagDecl(source_type);
+  const lldb::user_id_t metadata = 123456;
+  source_ast->SetMetadataAsUserID(source, metadata);
+
+  std::unique_ptr<ClangASTContext> target_ast = createAST();
+
+  ClangASTImporter importer;
+  clang::Decl *imported = importer.CopyDecl(
+      target_ast->getASTContext(), source_ast->getASTContext(), source);
+  ASSERT_NE(nullptr, imported);
+
+  // Check that we got the same Metadata.
+  ASSERT_NE(nullptr, importer.GetDeclMetadata(imported));
+  EXPECT_EQ(metadata, importer.GetDeclMetadata(imported)->GetUserID());
+}
+
+TEST_F(TestClangASTImporter, MetadataPropagationIndirectImport) {
+  // Tests that AST metadata is propagated when copying declarations when
+  // importing one declaration into a temporary context and then to the
+  // actual destination context.
+
+  std::unique_ptr<ClangASTContext> source_ast = createAST();
+  CompilerType source_type = createRecord(*source_ast, "Source");
+  clang::TagDecl *source = ClangUtil::GetAsTagDecl(source_type);
+  const lldb::user_id_t metadata = 123456;
+  source_ast->SetMetadataAsUserID(source, metadata);
+
+  std::unique_ptr<ClangASTContext> temporary_ast = createAST();
+
+  ClangASTImporter importer;
+  clang::Decl *temporary_imported = importer.CopyDecl(
+      temporary_ast->getASTContext(), source_ast->getASTContext(), source);
+  ASSERT_NE(nullptr, temporary_imported);
+
+  std::unique_ptr<ClangASTContext> target_ast = createAST();
+  clang::Decl *imported =
+      importer.CopyDecl(target_ast->getASTContext(),
+                        temporary_ast->getASTContext(), temporary_imported);
+  ASSERT_NE(nullptr, imported);
+
+  // Check that we got the same Metadata.
+  ASSERT_NE(nullptr, importer.GetDeclMetadata(imported));
+  EXPECT_EQ(metadata, importer.GetDeclMetadata(imported)->GetUserID());
+}
+
+TEST_F(TestClangASTImporter, MetadataPropagationAfterCopying) {
+  // Tests that AST metadata is propagated when copying declarations even
+  // when the metadata was set after the declaration has already been copied.
+
+  std::unique_ptr<ClangASTContext> source_ast = createAST();
+  CompilerType source_type = createRecord(*source_ast, "Source");
+  clang::TagDecl *source = ClangUtil::GetAsTagDecl(source_type);
+  const lldb::user_id_t metadata = 123456;
+
+  std::unique_ptr<ClangASTContext> target_ast = createAST();
+
+  ClangASTImporter importer;
+  clang::Decl *imported = importer.CopyDecl(
+      target_ast->getASTContext(), source_ast->getASTContext(), source);
+  ASSERT_NE(nullptr, imported);
+
+  // The TagDecl has been imported. Now set the metadata of the source and
+  // make sure the imported one will directly see it.
+  source_ast->SetMetadataAsUserID(source, metadata);
+
+  // Check that we got the same Metadata.
+  ASSERT_NE(nullptr, importer.GetDeclMetadata(imported));
+  EXPECT_EQ(metadata, importer.GetDeclMetadata(imported)->GetUserID());
+}
+
+TEST_F(TestClangASTImporter, RecordLayout) {
+  // Test that it is possible to register RecordDecl layouts and then later
+  // correctly retrieve them.
+
+  std::unique_ptr<ClangASTContext> source_ast = createAST();
+  CompilerType source_type = createRecord(*source_ast, "Source");
+  ClangASTContext::StartTagDeclarationDefinition(source_type);
+  clang::FieldDecl *field = source_ast->AddFieldToRecordType(
+      source_type, "a_field",
+      source_ast->GetBasicType(lldb::BasicType::eBasicTypeChar),
+      lldb::AccessType::eAccessPublic, 7);
+  ClangASTContext::CompleteTagDeclarationDefinition(source_type);
+
+  clang::TagDecl *source_tag = ClangUtil::GetAsTagDecl(source_type);
+  clang::RecordDecl *source_record = llvm::cast<clang::RecordDecl>(source_tag);
+
+  ClangASTImporter importer;
+  ClangASTImporter::LayoutInfo layout_info;
+  layout_info.bit_size = 15;
+  layout_info.alignment = 2;
+  layout_info.field_offsets[field] = 1;
+  importer.InsertRecordDecl(source_record, layout_info);
+
+  uint64_t bit_size;
+  uint64_t alignment;
+  llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets;
+  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets;
+  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets;
+  importer.LayoutRecordType(source_record, bit_size, alignment, field_offsets,
+                            base_offsets, vbase_offsets);
+
+  EXPECT_EQ(15U, bit_size);
+  EXPECT_EQ(2U, alignment);
+  EXPECT_EQ(1U, field_offsets.size());
+  EXPECT_EQ(1U, field_offsets[field]);
+  EXPECT_EQ(0U, base_offsets.size());
+  EXPECT_EQ(0U, vbase_offsets.size());
+}


        


More information about the lldb-commits mailing list