-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdecl-implicit.cc
122 lines (90 loc) · 3.04 KB
/
decl-implicit.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// decl-implicit.cc
// Code for decl-implicit module.
#include "decl-implicit-private.h" // private decls for this module
#include "smbase/sm-trace.h" // INIT_TRACE, TRACE1
#include "clang/Sema/Sema.h" // Sema::ForceDeclarationOfImplicitMembers
using clang::dyn_cast;
DeclareImplicitThings::DeclareImplicitThings(
clang::ASTUnit *astUnit,
bool defineAlso)
:
ClangUtil(astUnit->getASTContext()),
clang::RecursiveASTVisitor<DeclareImplicitThings>(),
m_astUnit(astUnit),
m_defineAlso(defineAlso)
{}
DeclareImplicitThings::~DeclareImplicitThings()
{}
clang::Sema &DeclareImplicitThings::getSema()
{
return m_astUnit->getSema();
}
bool DeclareImplicitThings::VisitCXXRecordDecl(clang::CXXRecordDecl *decl)
{
INIT_TRACE("DeclareImplicitThings::VisitCXXRecordDecl");
// Only force declarations when looking at the definition. Otherwise,
// the new members can end up with source locations derived from a
// forward declaration, which is wrong from a dependency point of
// view.
if (decl->isThisDeclarationADefinition()) {
TRACE1("class: " << namedDeclAtLocStr(decl));
getSema().ForceDeclarationOfImplicitMembers(decl);
}
return true;
}
bool DeclareImplicitThings::VisitCXXMethodDecl(
clang::CXXMethodDecl *decl)
{
if (!m_defineAlso) {
return true;
}
// Check the the common invariants for a method that can be implicitly
// defined.
if (!( decl->isDefaulted() &&
!decl->doesThisDeclarationHaveABody() &&
!decl->isDeleted() )) {
return true;
}
INIT_TRACE("DeclareImplicitThings::VisitCXXMethodDecl");
TRACE1("method: " << namedDeclAtLocStr(decl));
// Location to use as the 'CurrentLocation' for the calls to
// DefineImplicitXXX.
clang::SourceLocation loc = decl->getLocation();
if (auto ctor = dyn_cast<clang::CXXConstructorDecl>(decl)) {
if (ctor->isDefaultConstructor()) {
getSema().DefineImplicitDefaultConstructor(loc, ctor);
}
else if (ctor->isCopyConstructor()) {
getSema().DefineImplicitCopyConstructor(loc, ctor);
}
else if (ctor->isMoveConstructor()) {
getSema().DefineImplicitMoveConstructor(loc, ctor);
}
}
else if (auto dtor = dyn_cast<clang::CXXDestructorDecl>(decl)) {
getSema().DefineImplicitDestructor(loc, dtor);
}
// Disable the remainder to work around
// https://github.com/llvm/llvm-project/issues/67862.
else if (true) {
return true;
}
else if (decl->isCopyAssignmentOperator()) {
getSema().DefineImplicitCopyAssignment(loc, decl);
}
else if (decl->isMoveAssignmentOperator()) {
getSema().DefineImplicitMoveAssignment(loc, decl);
}
// TODO: Sema also has LambdaToFunctionPointerConversion and
// LambdaToBlockPointerConversion. I don't know what these are, so
// for now am not doing anything with them.
return true;
}
void declareImplicitThings(
clang::ASTUnit *astUnit,
bool defineAlso)
{
DeclareImplicitThings dit(astUnit, defineAlso);
dit.TraverseDecl(astUnit->getASTContext().getTranslationUnitDecl());
}
// EOF