Changeset View
Changeset View
Standalone View
Standalone View
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 7,965 Lines • ▼ Show 20 Lines | |||||
/// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared | /// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared | ||||
/// special functions, such as the default constructor, copy | /// special functions, such as the default constructor, copy | ||||
/// constructor, or destructor, to the given C++ class (C++ | /// constructor, or destructor, to the given C++ class (C++ | ||||
/// [special]p1). This routine can only be executed just before the | /// [special]p1). This routine can only be executed just before the | ||||
/// definition of the class is complete. | /// definition of the class is complete. | ||||
void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { | void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { | ||||
if (ClassDecl->needsImplicitDefaultConstructor()) { | if (ClassDecl->needsImplicitDefaultConstructor()) { | ||||
++ASTContext::NumImplicitDefaultConstructors; | ++getASTContext().NumImplicitDefaultConstructors; | ||||
if (ClassDecl->hasInheritedConstructor()) | if (ClassDecl->hasInheritedConstructor()) | ||||
DeclareImplicitDefaultConstructor(ClassDecl); | DeclareImplicitDefaultConstructor(ClassDecl); | ||||
} | } | ||||
if (ClassDecl->needsImplicitCopyConstructor()) { | if (ClassDecl->needsImplicitCopyConstructor()) { | ||||
++ASTContext::NumImplicitCopyConstructors; | ++getASTContext().NumImplicitCopyConstructors; | ||||
// If the properties or semantics of the copy constructor couldn't be | // If the properties or semantics of the copy constructor couldn't be | ||||
// determined while the class was being declared, force a declaration | // determined while the class was being declared, force a declaration | ||||
// of it now. | // of it now. | ||||
if (ClassDecl->needsOverloadResolutionForCopyConstructor() || | if (ClassDecl->needsOverloadResolutionForCopyConstructor() || | ||||
ClassDecl->hasInheritedConstructor()) | ClassDecl->hasInheritedConstructor()) | ||||
DeclareImplicitCopyConstructor(ClassDecl); | DeclareImplicitCopyConstructor(ClassDecl); | ||||
// For the MS ABI we need to know whether the copy ctor is deleted. A | // For the MS ABI we need to know whether the copy ctor is deleted. A | ||||
// prerequisite for deleting the implicit copy ctor is that the class has a | // prerequisite for deleting the implicit copy ctor is that the class has a | ||||
// move ctor or move assignment that is either user-declared or whose | // move ctor or move assignment that is either user-declared or whose | ||||
// semantics are inherited from a subobject. FIXME: We should provide a more | // semantics are inherited from a subobject. FIXME: We should provide a more | ||||
// direct way for CodeGen to ask whether the constructor was deleted. | // direct way for CodeGen to ask whether the constructor was deleted. | ||||
else if (Context.getTargetInfo().getCXXABI().isMicrosoft() && | else if (Context.getTargetInfo().getCXXABI().isMicrosoft() && | ||||
(ClassDecl->hasUserDeclaredMoveConstructor() || | (ClassDecl->hasUserDeclaredMoveConstructor() || | ||||
ClassDecl->needsOverloadResolutionForMoveConstructor() || | ClassDecl->needsOverloadResolutionForMoveConstructor() || | ||||
ClassDecl->hasUserDeclaredMoveAssignment() || | ClassDecl->hasUserDeclaredMoveAssignment() || | ||||
ClassDecl->needsOverloadResolutionForMoveAssignment())) | ClassDecl->needsOverloadResolutionForMoveAssignment())) | ||||
DeclareImplicitCopyConstructor(ClassDecl); | DeclareImplicitCopyConstructor(ClassDecl); | ||||
} | } | ||||
if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveConstructor()) { | if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveConstructor()) { | ||||
++ASTContext::NumImplicitMoveConstructors; | ++getASTContext().NumImplicitMoveConstructors; | ||||
if (ClassDecl->needsOverloadResolutionForMoveConstructor() || | if (ClassDecl->needsOverloadResolutionForMoveConstructor() || | ||||
ClassDecl->hasInheritedConstructor()) | ClassDecl->hasInheritedConstructor()) | ||||
DeclareImplicitMoveConstructor(ClassDecl); | DeclareImplicitMoveConstructor(ClassDecl); | ||||
} | } | ||||
if (ClassDecl->needsImplicitCopyAssignment()) { | if (ClassDecl->needsImplicitCopyAssignment()) { | ||||
++ASTContext::NumImplicitCopyAssignmentOperators; | ++getASTContext().NumImplicitCopyAssignmentOperators; | ||||
// If we have a dynamic class, then the copy assignment operator may be | // If we have a dynamic class, then the copy assignment operator may be | ||||
// virtual, so we have to declare it immediately. This ensures that, e.g., | // virtual, so we have to declare it immediately. This ensures that, e.g., | ||||
// it shows up in the right place in the vtable and that we diagnose | // it shows up in the right place in the vtable and that we diagnose | ||||
// problems with the implicit exception specification. | // problems with the implicit exception specification. | ||||
if (ClassDecl->isDynamicClass() || | if (ClassDecl->isDynamicClass() || | ||||
ClassDecl->needsOverloadResolutionForCopyAssignment() || | ClassDecl->needsOverloadResolutionForCopyAssignment() || | ||||
ClassDecl->hasInheritedAssignment()) | ClassDecl->hasInheritedAssignment()) | ||||
DeclareImplicitCopyAssignment(ClassDecl); | DeclareImplicitCopyAssignment(ClassDecl); | ||||
} | } | ||||
if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveAssignment()) { | if (getLangOpts().CPlusPlus11 && ClassDecl->needsImplicitMoveAssignment()) { | ||||
++ASTContext::NumImplicitMoveAssignmentOperators; | ++getASTContext().NumImplicitMoveAssignmentOperators; | ||||
// Likewise for the move assignment operator. | // Likewise for the move assignment operator. | ||||
if (ClassDecl->isDynamicClass() || | if (ClassDecl->isDynamicClass() || | ||||
ClassDecl->needsOverloadResolutionForMoveAssignment() || | ClassDecl->needsOverloadResolutionForMoveAssignment() || | ||||
ClassDecl->hasInheritedAssignment()) | ClassDecl->hasInheritedAssignment()) | ||||
DeclareImplicitMoveAssignment(ClassDecl); | DeclareImplicitMoveAssignment(ClassDecl); | ||||
} | } | ||||
if (ClassDecl->needsImplicitDestructor()) { | if (ClassDecl->needsImplicitDestructor()) { | ||||
++ASTContext::NumImplicitDestructors; | ++getASTContext().NumImplicitDestructors; | ||||
// If we have a dynamic class, then the destructor may be virtual, so we | // If we have a dynamic class, then the destructor may be virtual, so we | ||||
// have to declare the destructor immediately. This ensures that, e.g., it | // have to declare the destructor immediately. This ensures that, e.g., it | ||||
// shows up in the right place in the vtable and that we diagnose problems | // shows up in the right place in the vtable and that we diagnose problems | ||||
// with the implicit exception specification. | // with the implicit exception specification. | ||||
if (ClassDecl->isDynamicClass() || | if (ClassDecl->isDynamicClass() || | ||||
ClassDecl->needsOverloadResolutionForDestructor()) | ClassDecl->needsOverloadResolutionForDestructor()) | ||||
DeclareImplicitDestructor(ClassDecl); | DeclareImplicitDestructor(ClassDecl); | ||||
▲ Show 20 Lines • Show All 2,965 Lines • ▼ Show 20 Lines | CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor( | ||||
setupImplicitSpecialMemberType(DefaultCon, Context.VoidTy, None); | setupImplicitSpecialMemberType(DefaultCon, Context.VoidTy, None); | ||||
// We don't need to use SpecialMemberIsTrivial here; triviality for default | // We don't need to use SpecialMemberIsTrivial here; triviality for default | ||||
// constructors is easy to compute. | // constructors is easy to compute. | ||||
DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor()); | DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor()); | ||||
// Note that we have declared this constructor. | // Note that we have declared this constructor. | ||||
++ASTContext::NumImplicitDefaultConstructorsDeclared; | ++getASTContext().NumImplicitDefaultConstructorsDeclared; | ||||
Scope *S = getScopeForContext(ClassDecl); | Scope *S = getScopeForContext(ClassDecl); | ||||
CheckImplicitSpecialMemberDeclaration(S, DefaultCon); | CheckImplicitSpecialMemberDeclaration(S, DefaultCon); | ||||
if (ShouldDeleteSpecialMember(DefaultCon, CXXDefaultConstructor)) | if (ShouldDeleteSpecialMember(DefaultCon, CXXDefaultConstructor)) | ||||
SetDeclDeleted(DefaultCon, ClassLoc); | SetDeclDeleted(DefaultCon, ClassLoc); | ||||
if (S) | if (S) | ||||
▲ Show 20 Lines • Show All 256 Lines • ▼ Show 20 Lines | CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) { | ||||
// We don't need to use SpecialMemberIsTrivial here; triviality for | // We don't need to use SpecialMemberIsTrivial here; triviality for | ||||
// destructors is easy to compute. | // destructors is easy to compute. | ||||
Destructor->setTrivial(ClassDecl->hasTrivialDestructor()); | Destructor->setTrivial(ClassDecl->hasTrivialDestructor()); | ||||
Destructor->setTrivialForCall(ClassDecl->hasAttr<TrivialABIAttr>() || | Destructor->setTrivialForCall(ClassDecl->hasAttr<TrivialABIAttr>() || | ||||
ClassDecl->hasTrivialDestructorForCall()); | ClassDecl->hasTrivialDestructorForCall()); | ||||
// Note that we have declared this destructor. | // Note that we have declared this destructor. | ||||
++ASTContext::NumImplicitDestructorsDeclared; | ++getASTContext().NumImplicitDestructorsDeclared; | ||||
Scope *S = getScopeForContext(ClassDecl); | Scope *S = getScopeForContext(ClassDecl); | ||||
CheckImplicitSpecialMemberDeclaration(S, Destructor); | CheckImplicitSpecialMemberDeclaration(S, Destructor); | ||||
// We can't check whether an implicit destructor is deleted before we complete | // We can't check whether an implicit destructor is deleted before we complete | ||||
// the definition of the class, because its validity depends on the alignment | // the definition of the class, because its validity depends on the alignment | ||||
// of the class. We'll check this from ActOnFields once the class is complete. | // of the class. We'll check this from ActOnFields once the class is complete. | ||||
if (ClassDecl->isCompleteDefinition() && | if (ClassDecl->isCompleteDefinition() && | ||||
▲ Show 20 Lines • Show All 593 Lines • ▼ Show 20 Lines | CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) { | ||||
CopyAssignment->setParams(FromParam); | CopyAssignment->setParams(FromParam); | ||||
CopyAssignment->setTrivial( | CopyAssignment->setTrivial( | ||||
ClassDecl->needsOverloadResolutionForCopyAssignment() | ClassDecl->needsOverloadResolutionForCopyAssignment() | ||||
? SpecialMemberIsTrivial(CopyAssignment, CXXCopyAssignment) | ? SpecialMemberIsTrivial(CopyAssignment, CXXCopyAssignment) | ||||
: ClassDecl->hasTrivialCopyAssignment()); | : ClassDecl->hasTrivialCopyAssignment()); | ||||
// Note that we have added this copy-assignment operator. | // Note that we have added this copy-assignment operator. | ||||
++ASTContext::NumImplicitCopyAssignmentOperatorsDeclared; | ++getASTContext().NumImplicitCopyAssignmentOperatorsDeclared; | ||||
Scope *S = getScopeForContext(ClassDecl); | Scope *S = getScopeForContext(ClassDecl); | ||||
CheckImplicitSpecialMemberDeclaration(S, CopyAssignment); | CheckImplicitSpecialMemberDeclaration(S, CopyAssignment); | ||||
if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) | if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment)) | ||||
SetDeclDeleted(CopyAssignment, ClassLoc); | SetDeclDeleted(CopyAssignment, ClassLoc); | ||||
if (S) | if (S) | ||||
▲ Show 20 Lines • Show All 306 Lines • ▼ Show 20 Lines | CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) { | ||||
MoveAssignment->setParams(FromParam); | MoveAssignment->setParams(FromParam); | ||||
MoveAssignment->setTrivial( | MoveAssignment->setTrivial( | ||||
ClassDecl->needsOverloadResolutionForMoveAssignment() | ClassDecl->needsOverloadResolutionForMoveAssignment() | ||||
? SpecialMemberIsTrivial(MoveAssignment, CXXMoveAssignment) | ? SpecialMemberIsTrivial(MoveAssignment, CXXMoveAssignment) | ||||
: ClassDecl->hasTrivialMoveAssignment()); | : ClassDecl->hasTrivialMoveAssignment()); | ||||
// Note that we have added this copy-assignment operator. | // Note that we have added this copy-assignment operator. | ||||
++ASTContext::NumImplicitMoveAssignmentOperatorsDeclared; | ++getASTContext().NumImplicitMoveAssignmentOperatorsDeclared; | ||||
Scope *S = getScopeForContext(ClassDecl); | Scope *S = getScopeForContext(ClassDecl); | ||||
CheckImplicitSpecialMemberDeclaration(S, MoveAssignment); | CheckImplicitSpecialMemberDeclaration(S, MoveAssignment); | ||||
if (ShouldDeleteSpecialMember(MoveAssignment, CXXMoveAssignment)) { | if (ShouldDeleteSpecialMember(MoveAssignment, CXXMoveAssignment)) { | ||||
ClassDecl->setImplicitMoveAssignmentIsDeleted(); | ClassDecl->setImplicitMoveAssignmentIsDeleted(); | ||||
SetDeclDeleted(MoveAssignment, ClassLoc); | SetDeclDeleted(MoveAssignment, ClassLoc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor( | ||||
CopyConstructor->setTrivialForCall( | CopyConstructor->setTrivialForCall( | ||||
ClassDecl->hasAttr<TrivialABIAttr>() || | ClassDecl->hasAttr<TrivialABIAttr>() || | ||||
(ClassDecl->needsOverloadResolutionForCopyConstructor() | (ClassDecl->needsOverloadResolutionForCopyConstructor() | ||||
? SpecialMemberIsTrivial(CopyConstructor, CXXCopyConstructor, | ? SpecialMemberIsTrivial(CopyConstructor, CXXCopyConstructor, | ||||
TAH_ConsiderTrivialABI) | TAH_ConsiderTrivialABI) | ||||
: ClassDecl->hasTrivialCopyConstructorForCall())); | : ClassDecl->hasTrivialCopyConstructorForCall())); | ||||
// Note that we have declared this constructor. | // Note that we have declared this constructor. | ||||
++ASTContext::NumImplicitCopyConstructorsDeclared; | ++getASTContext().NumImplicitCopyConstructorsDeclared; | ||||
Scope *S = getScopeForContext(ClassDecl); | Scope *S = getScopeForContext(ClassDecl); | ||||
CheckImplicitSpecialMemberDeclaration(S, CopyConstructor); | CheckImplicitSpecialMemberDeclaration(S, CopyConstructor); | ||||
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) { | if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) { | ||||
ClassDecl->setImplicitCopyConstructorIsDeleted(); | ClassDecl->setImplicitCopyConstructorIsDeleted(); | ||||
SetDeclDeleted(CopyConstructor, ClassLoc); | SetDeclDeleted(CopyConstructor, ClassLoc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor( | ||||
MoveConstructor->setTrivialForCall( | MoveConstructor->setTrivialForCall( | ||||
ClassDecl->hasAttr<TrivialABIAttr>() || | ClassDecl->hasAttr<TrivialABIAttr>() || | ||||
(ClassDecl->needsOverloadResolutionForMoveConstructor() | (ClassDecl->needsOverloadResolutionForMoveConstructor() | ||||
? SpecialMemberIsTrivial(MoveConstructor, CXXMoveConstructor, | ? SpecialMemberIsTrivial(MoveConstructor, CXXMoveConstructor, | ||||
TAH_ConsiderTrivialABI) | TAH_ConsiderTrivialABI) | ||||
: ClassDecl->hasTrivialMoveConstructorForCall())); | : ClassDecl->hasTrivialMoveConstructorForCall())); | ||||
// Note that we have declared this constructor. | // Note that we have declared this constructor. | ||||
++ASTContext::NumImplicitMoveConstructorsDeclared; | ++getASTContext().NumImplicitMoveConstructorsDeclared; | ||||
Scope *S = getScopeForContext(ClassDecl); | Scope *S = getScopeForContext(ClassDecl); | ||||
CheckImplicitSpecialMemberDeclaration(S, MoveConstructor); | CheckImplicitSpecialMemberDeclaration(S, MoveConstructor); | ||||
if (ShouldDeleteSpecialMember(MoveConstructor, CXXMoveConstructor)) { | if (ShouldDeleteSpecialMember(MoveConstructor, CXXMoveConstructor)) { | ||||
ClassDecl->setImplicitMoveConstructorIsDeleted(); | ClassDecl->setImplicitMoveConstructorIsDeleted(); | ||||
SetDeclDeleted(MoveConstructor, ClassLoc); | SetDeclDeleted(MoveConstructor, ClassLoc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,933 Lines • Show Last 20 Lines |