|
11 | 11 | #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
|
12 | 12 | #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
|
13 | 13 | #include "Plugins/ExpressionParser/Clang/ClangUtil.h"
|
| 14 | +#include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" |
14 | 15 | #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
|
15 | 16 | #include "TestingSupport/SubsystemRAII.h"
|
16 | 17 | #include "TestingSupport/Symbol/ClangTestUtils.h"
|
@@ -276,3 +277,56 @@ TEST_F(TestClangASTImporter, RecordLayout) {
|
276 | 277 | EXPECT_EQ(0U, base_offsets.size());
|
277 | 278 | EXPECT_EQ(0U, vbase_offsets.size());
|
278 | 279 | }
|
| 280 | + |
| 281 | +TEST_F(TestClangASTImporter, RecordLayoutFromOrigin) { |
| 282 | + // Tests that we can retrieve the layout of a record that has |
| 283 | + // an origin with an already existing LayoutInfo. We expect |
| 284 | + // the layout to be retrieved from the ClangASTImporter of the |
| 285 | + // origin decl. |
| 286 | + |
| 287 | + clang_utils::SourceASTWithRecord source; |
| 288 | + |
| 289 | + auto *dwarf_parser = |
| 290 | + static_cast<DWARFASTParserClang *>(source.ast->GetDWARFParser()); |
| 291 | + auto &importer = dwarf_parser->GetClangASTImporter(); |
| 292 | + |
| 293 | + // Set the layout for the origin decl in the origin ClangASTImporter. |
| 294 | + ClangASTImporter::LayoutInfo layout_info; |
| 295 | + layout_info.bit_size = 32; |
| 296 | + layout_info.alignment = 16; |
| 297 | + layout_info.field_offsets[source.field_decl] = 1; |
| 298 | + importer.SetRecordLayout(source.record_decl, layout_info); |
| 299 | + |
| 300 | + auto holder = |
| 301 | + std::make_unique<clang_utils::TypeSystemClangHolder>("target ast"); |
| 302 | + auto *target_ast = holder->GetAST(); |
| 303 | + |
| 304 | + // Import the decl into a new TypeSystemClang. |
| 305 | + CompilerType imported = importer.CopyType(*target_ast, source.record_type); |
| 306 | + ASSERT_TRUE(imported.IsValid()); |
| 307 | + |
| 308 | + auto *imported_decl = cast<CXXRecordDecl>(ClangUtil::GetAsTagDecl(imported)); |
| 309 | + ClangASTImporter::DeclOrigin origin = importer.GetDeclOrigin(imported_decl); |
| 310 | + ASSERT_TRUE(origin.Valid()); |
| 311 | + ASSERT_EQ(origin.decl, source.record_decl); |
| 312 | + |
| 313 | + uint64_t bit_size; |
| 314 | + uint64_t alignment; |
| 315 | + llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; |
| 316 | + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; |
| 317 | + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets; |
| 318 | + |
| 319 | + // Make sure we correctly read out the layout (despite not Having |
| 320 | + // called SetRecordLayout on the new TypeSystem's ClangASTImporter). |
| 321 | + auto success = |
| 322 | + importer.LayoutRecordType(imported_decl, bit_size, alignment, |
| 323 | + field_offsets, base_offsets, vbase_offsets); |
| 324 | + EXPECT_TRUE(success); |
| 325 | + |
| 326 | + EXPECT_EQ(32U, bit_size); |
| 327 | + EXPECT_EQ(16U, alignment); |
| 328 | + EXPECT_EQ(1U, field_offsets.size()); |
| 329 | + EXPECT_EQ(1U, field_offsets[*imported_decl->field_begin()]); |
| 330 | + EXPECT_EQ(0U, base_offsets.size()); |
| 331 | + EXPECT_EQ(0U, vbase_offsets.size()); |
| 332 | +} |
0 commit comments