|
3 | 3 |
|
4 | 4 | #include "converter/converter_lib.h" |
5 | 5 |
|
| 6 | +#include <clang/AST/DeclFriend.h> |
6 | 7 | #include <clang/AST/DeclTemplate.h> |
7 | 8 | #include <clang/AST/ExprCXX.h> |
8 | 9 | #include <clang/AST/ExprConcepts.h> |
@@ -1460,6 +1461,52 @@ bool IsComparisonOperator(const clang::FunctionDecl *fn) { |
1460 | 1461 | } |
1461 | 1462 | } |
1462 | 1463 |
|
| 1464 | +void DefineImplicitMembers(clang::Sema &sema, clang::CXXRecordDecl *decl) { |
| 1465 | + clang::Scope tu_scope(nullptr, clang::Scope::DeclScope, |
| 1466 | + sema.getDiagnostics()); |
| 1467 | + tu_scope.setEntity(sema.Context.getTranslationUnitDecl()); |
| 1468 | + auto *saved_tu_scope = std::exchange(sema.TUScope, &tu_scope); |
| 1469 | + sema.ForceDeclarationOfImplicitMembers(decl); |
| 1470 | + for (auto ctor : decl->ctors()) { |
| 1471 | + if (ctor->isCopyConstructor() && ctor->isImplicit() && |
| 1472 | + !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted()) { |
| 1473 | + sema.DefineImplicitCopyConstructor(decl->getLocation(), ctor); |
| 1474 | + } |
| 1475 | + if (ctor->isMoveConstructor() && !ctor->isUserProvided() && |
| 1476 | + !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted() && |
| 1477 | + !HasDefaultedCopyConstructor(decl)) { |
| 1478 | + sema.DefineImplicitMoveConstructor(decl->getLocation(), ctor); |
| 1479 | + } |
| 1480 | + } |
| 1481 | + for (auto *method : decl->methods()) { |
| 1482 | + if (method->isMoveAssignmentOperator() && !method->isUserProvided() && |
| 1483 | + !method->doesThisDeclarationHaveABody() && !method->isDeleted() && |
| 1484 | + !HasDefaultedCopyAssignment(decl)) { |
| 1485 | + sema.DefineImplicitMoveAssignment(decl->getLocation(), method); |
| 1486 | + } |
| 1487 | + } |
| 1488 | + auto define_defaulted_comparison = [&](clang::FunctionDecl *fn) { |
| 1489 | + if (!fn || !IsComparisonOperator(fn) || !fn->isDefaulted() || |
| 1490 | + fn->doesThisDeclarationHaveABody()) { |
| 1491 | + return; |
| 1492 | + } |
| 1493 | +#if CLANG_VERSION_MAJOR >= 24 |
| 1494 | + auto kind = fn->getDefaultedComparisonKind(); |
| 1495 | +#else |
| 1496 | + auto kind = sema.getDefaultedComparisonKind(fn); |
| 1497 | +#endif |
| 1498 | + sema.DefineDefaultedComparison(decl->getLocation(), fn, kind); |
| 1499 | + }; |
| 1500 | + for (auto *method : decl->methods()) { |
| 1501 | + define_defaulted_comparison(method); |
| 1502 | + } |
| 1503 | + for (auto *friend_decl : decl->friends()) { |
| 1504 | + define_defaulted_comparison(clang::dyn_cast_or_null<clang::FunctionDecl>( |
| 1505 | + friend_decl->getFriendDecl())); |
| 1506 | + } |
| 1507 | + sema.TUScope = saved_tu_scope; |
| 1508 | +} |
| 1509 | + |
1463 | 1510 | bool IsEmittableMethod(clang::CXXMethodDecl *method) { |
1464 | 1511 | if (method->isDeleted()) { |
1465 | 1512 | return false; |
|
0 commit comments