forked from OSchip/llvm-project
parent
8a88026ae3
commit
f9172946be
|
@ -3629,7 +3629,9 @@ def warn_explicit_conversion_functions : Warning<
|
|||
def err_defaulted_default_ctor_params : Error<
|
||||
"an explicitly-defaulted default constructor must have no parameters">;
|
||||
def err_incorrect_defaulted_exception_spec : Error<
|
||||
"exception specification of explicitly defaulted function is incorrect">;
|
||||
"exception specification of explicitly defaulted %select{default constructor|"
|
||||
"copy constructor|copy assignment operator|destructor}0 does not match the "
|
||||
"calculated one">;
|
||||
def err_out_of_line_default_deletes : Error<
|
||||
"defaulting this %select{default constructor|copy constructor|copy "
|
||||
"assignment operator|destructor}0 would delete it after its first "
|
||||
|
|
|
@ -2582,9 +2582,17 @@ public:
|
|||
ImplicitExceptionSpecification
|
||||
ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl);
|
||||
|
||||
/// \brief Determine what sort of exception specification a defaulted
|
||||
/// destructor of a class will have.
|
||||
ImplicitExceptionSpecification
|
||||
ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl);
|
||||
|
||||
/// \brief Determine if a defaulted default constructor ought to be
|
||||
/// deleted.
|
||||
bool ShouldDeleteDefaultConstructor(CXXConstructorDecl *RD);
|
||||
bool ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD);
|
||||
|
||||
/// \brief Determine if a defaulted destructor ought to be deleted.
|
||||
bool ShouldDeleteDestructor(CXXDestructorDecl *DD);
|
||||
|
||||
/// \brief Declare the implicit default constructor for the given class.
|
||||
///
|
||||
|
@ -2794,7 +2802,8 @@ public:
|
|||
bool addMallocAttr = false);
|
||||
|
||||
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||
DeclarationName Name, FunctionDecl* &Operator);
|
||||
DeclarationName Name, FunctionDecl* &Operator,
|
||||
bool AllowMissing = false);
|
||||
|
||||
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
|
||||
ExprResult ActOnCXXDelete(SourceLocation StartLoc,
|
||||
|
@ -3259,6 +3268,7 @@ public:
|
|||
|
||||
void CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record);
|
||||
void CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *Ctor);
|
||||
void CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *Dtor);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C++ Derived Classes
|
||||
|
@ -3347,7 +3357,8 @@ public:
|
|||
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
|
||||
SourceRange PlacementRange,
|
||||
CXXRecordDecl *NamingClass,
|
||||
DeclAccessPair FoundDecl);
|
||||
DeclAccessPair FoundDecl,
|
||||
bool Diagnose = true);
|
||||
AccessResult CheckConstructorAccess(SourceLocation Loc,
|
||||
CXXConstructorDecl *D,
|
||||
const InitializedEntity &Entity,
|
||||
|
|
|
@ -1463,7 +1463,8 @@ Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
|
|||
Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
|
||||
SourceRange PlacementRange,
|
||||
CXXRecordDecl *NamingClass,
|
||||
DeclAccessPair Found) {
|
||||
DeclAccessPair Found,
|
||||
bool Diagnose) {
|
||||
if (!getLangOptions().AccessControl ||
|
||||
!NamingClass ||
|
||||
Found.getAccess() == AS_public)
|
||||
|
@ -1471,8 +1472,9 @@ Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
|
|||
|
||||
AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
|
||||
QualType());
|
||||
Entity.setDiag(diag::err_access)
|
||||
<< PlacementRange;
|
||||
if (Diagnose)
|
||||
Entity.setDiag(diag::err_access)
|
||||
<< PlacementRange;
|
||||
|
||||
return CheckAccess(*this, OpLoc, Entity);
|
||||
}
|
||||
|
|
|
@ -2998,19 +2998,31 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
|
|||
}
|
||||
|
||||
void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record) {
|
||||
for (CXXRecordDecl::ctor_iterator CI = Record->ctor_begin(),
|
||||
CE = Record->ctor_end();
|
||||
CI != CE; ++CI) {
|
||||
if (!CI->isInvalidDecl() && CI->isExplicitlyDefaulted()) {
|
||||
if (CI->isDefaultConstructor()) {
|
||||
CheckExplicitlyDefaultedDefaultConstructor(*CI);
|
||||
}
|
||||
for (CXXRecordDecl::method_iterator MI = Record->method_begin(),
|
||||
ME = Record->method_end();
|
||||
MI != ME; ++MI) {
|
||||
if (!MI->isInvalidDecl() && MI->isExplicitlyDefaulted()) {
|
||||
switch (getSpecialMember(*MI)) {
|
||||
case CXXDefaultConstructor:
|
||||
CheckExplicitlyDefaultedDefaultConstructor(
|
||||
cast<CXXConstructorDecl>(*MI));
|
||||
break;
|
||||
|
||||
// FIXME: Do copy and move constructors
|
||||
case CXXDestructor:
|
||||
CheckExplicitlyDefaultedDestructor(cast<CXXDestructorDecl>(*MI));
|
||||
break;
|
||||
|
||||
case CXXCopyConstructor:
|
||||
case CXXCopyAssignment:
|
||||
// FIXME: Do copy and move constructors and assignment operators
|
||||
break;
|
||||
|
||||
default:
|
||||
llvm_unreachable("non-special member explicitly defaulted!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Do copy and move assignment and destructors
|
||||
}
|
||||
|
||||
void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) {
|
||||
|
@ -3038,7 +3050,8 @@ void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) {
|
|||
|
||||
if (CtorType->hasExceptionSpec()) {
|
||||
if (CheckEquivalentExceptionSpec(
|
||||
PDiag(diag::err_incorrect_defaulted_exception_spec),
|
||||
PDiag(diag::err_incorrect_defaulted_exception_spec)
|
||||
<< 0 /* default constructor */,
|
||||
PDiag(),
|
||||
ExceptionType, SourceLocation(),
|
||||
CtorType, CD->getLocation())) {
|
||||
|
@ -3056,10 +3069,50 @@ void Sema::CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *CD) {
|
|||
CD->setDeletedAsWritten();
|
||||
else
|
||||
Diag(CD->getLocation(), diag::err_out_of_line_default_deletes)
|
||||
<< getSpecialMember(CD);
|
||||
<< 0 /* default constructor */;
|
||||
}
|
||||
}
|
||||
|
||||
void Sema::CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *DD) {
|
||||
assert(DD->isExplicitlyDefaulted());
|
||||
|
||||
// Whether this was the first-declared instance of the destructor.
|
||||
bool First = DD == DD->getCanonicalDecl();
|
||||
|
||||
ImplicitExceptionSpecification Spec
|
||||
= ComputeDefaultedDtorExceptionSpec(DD->getParent());
|
||||
FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
|
||||
const FunctionProtoType *DtorType = DD->getType()->getAs<FunctionProtoType>(),
|
||||
*ExceptionType = Context.getFunctionType(
|
||||
Context.VoidTy, 0, 0, EPI)->getAs<FunctionProtoType>();
|
||||
|
||||
if (DtorType->hasExceptionSpec()) {
|
||||
if (CheckEquivalentExceptionSpec(
|
||||
PDiag(diag::err_incorrect_defaulted_exception_spec)
|
||||
<< 3 /* destructor */,
|
||||
PDiag(),
|
||||
ExceptionType, SourceLocation(),
|
||||
DtorType, DD->getLocation())) {
|
||||
DD->setInvalidDecl();
|
||||
return;
|
||||
}
|
||||
} else if (First) {
|
||||
// We set the declaration to have the computed exception spec here.
|
||||
// There are no parameters.
|
||||
DD->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
|
||||
}
|
||||
|
||||
if (ShouldDeleteDestructor(DD)) {
|
||||
if (First)
|
||||
DD->setDeletedAsWritten();
|
||||
else
|
||||
Diag(DD->getLocation(), diag::err_out_of_line_default_deletes)
|
||||
<< 3 /* destructor */;
|
||||
}
|
||||
|
||||
CheckDestructor(DD);
|
||||
}
|
||||
|
||||
bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
|
||||
CXXRecordDecl *RD = CD->getParent();
|
||||
assert(!RD->isDependentType() && "do deletion after instantiation");
|
||||
|
@ -3072,8 +3125,6 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
|
|||
bool Union = RD->isUnion();
|
||||
bool AllConst = true;
|
||||
|
||||
DiagnosticErrorTrap Trap(Diags);
|
||||
|
||||
// We do this because we should never actually use an anonymous
|
||||
// union's constructor.
|
||||
if (Union && RD->isAnonymousStructOrUnion())
|
||||
|
@ -3087,6 +3138,10 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
|
|||
for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
|
||||
BE = RD->bases_end();
|
||||
BI != BE; ++BI) {
|
||||
// We'll handle this one later
|
||||
if (BI->isVirtual())
|
||||
continue;
|
||||
|
||||
CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
|
||||
assert(BaseDecl && "base isn't a CXXRecordDecl");
|
||||
|
||||
|
@ -3099,10 +3154,6 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
|
|||
AR_accessible)
|
||||
return true;
|
||||
|
||||
// We'll handle this one later
|
||||
if (BI->isVirtual())
|
||||
continue;
|
||||
|
||||
// -- any [direct base class either] has no default constructor or
|
||||
// overload resolution as applied to [its] default constructor
|
||||
// results in an ambiguity or in a function that is deleted or
|
||||
|
@ -3234,6 +3285,109 @@ bool Sema::ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Sema::ShouldDeleteDestructor(CXXDestructorDecl *DD) {
|
||||
CXXRecordDecl *RD = DD->getParent();
|
||||
assert(!RD->isDependentType() && "do deletion after instantiation");
|
||||
if (!LangOpts.CPlusPlus0x)
|
||||
return false;
|
||||
|
||||
// Do access control from the destructor
|
||||
ContextRAII CtorContext(*this, DD);
|
||||
|
||||
bool Union = RD->isUnion();
|
||||
|
||||
// C++0x [class.dtor]p5
|
||||
// A defaulted destructor for a class X is defined as deleted if:
|
||||
for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
|
||||
BE = RD->bases_end();
|
||||
BI != BE; ++BI) {
|
||||
// We'll handle this one later
|
||||
if (BI->isVirtual())
|
||||
continue;
|
||||
|
||||
CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
|
||||
CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl);
|
||||
assert(BaseDtor && "base has no destructor");
|
||||
|
||||
// -- any direct or virtual base class has a deleted destructor or
|
||||
// a destructor that is inaccessible from the defaulted destructor
|
||||
if (BaseDtor->isDeleted())
|
||||
return true;
|
||||
if (CheckDestructorAccess(SourceLocation(), BaseDtor, PDiag()) !=
|
||||
AR_accessible)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
|
||||
BE = RD->vbases_end();
|
||||
BI != BE; ++BI) {
|
||||
CXXRecordDecl *BaseDecl = BI->getType()->getAsCXXRecordDecl();
|
||||
CXXDestructorDecl *BaseDtor = LookupDestructor(BaseDecl);
|
||||
assert(BaseDtor && "base has no destructor");
|
||||
|
||||
// -- any direct or virtual base class has a deleted destructor or
|
||||
// a destructor that is inaccessible from the defaulted destructor
|
||||
if (BaseDtor->isDeleted())
|
||||
return true;
|
||||
if (CheckDestructorAccess(SourceLocation(), BaseDtor, PDiag()) !=
|
||||
AR_accessible)
|
||||
return true;
|
||||
}
|
||||
|
||||
for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
|
||||
FE = RD->field_end();
|
||||
FI != FE; ++FI) {
|
||||
QualType FieldType = Context.getBaseElementType(FI->getType());
|
||||
CXXRecordDecl *FieldRecord = FieldType->getAsCXXRecordDecl();
|
||||
if (FieldRecord) {
|
||||
if (FieldRecord->isUnion() && FieldRecord->isAnonymousStructOrUnion()) {
|
||||
for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
|
||||
UE = FieldRecord->field_end();
|
||||
UI != UE; ++UI) {
|
||||
QualType UnionFieldType = Context.getBaseElementType(FI->getType());
|
||||
CXXRecordDecl *UnionFieldRecord =
|
||||
UnionFieldType->getAsCXXRecordDecl();
|
||||
|
||||
// -- X is a union-like class that has a variant member with a non-
|
||||
// trivial destructor.
|
||||
if (UnionFieldRecord && !UnionFieldRecord->hasTrivialDestructor())
|
||||
return true;
|
||||
}
|
||||
// Technically we are supposed to do this next check unconditionally.
|
||||
// But that makes absolutely no sense.
|
||||
} else {
|
||||
CXXDestructorDecl *FieldDtor = LookupDestructor(FieldRecord);
|
||||
|
||||
// -- any of the non-static data members has class type M (or array
|
||||
// thereof) and M has a deleted destructor or a destructor that is
|
||||
// inaccessible from the defaulted destructor
|
||||
if (FieldDtor->isDeleted())
|
||||
return true;
|
||||
if (CheckDestructorAccess(SourceLocation(), FieldDtor, PDiag()) !=
|
||||
AR_accessible)
|
||||
return true;
|
||||
|
||||
// -- X is a union-like class that has a variant member with a non-
|
||||
// trivial destructor.
|
||||
if (Union && !FieldDtor->isTrivial())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DD->isVirtual()) {
|
||||
FunctionDecl *OperatorDelete = 0;
|
||||
DeclarationName Name =
|
||||
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
|
||||
if (FindDeallocationFunction(SourceLocation(), RD, Name, OperatorDelete,
|
||||
false))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Data used with FindHiddenVirtualMethod
|
||||
namespace {
|
||||
struct FindHiddenVirtualMethodData {
|
||||
|
@ -5480,12 +5634,8 @@ void Sema::DeclareInheritedConstructors(CXXRecordDecl *ClassDecl) {
|
|||
}
|
||||
}
|
||||
|
||||
CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
|
||||
// C++ [class.dtor]p2:
|
||||
// If a class has no user-declared destructor, a destructor is
|
||||
// declared implicitly. An implicitly-declared destructor is an
|
||||
// inline public member of its class.
|
||||
|
||||
Sema::ImplicitExceptionSpecification
|
||||
Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) {
|
||||
// C++ [except.spec]p14:
|
||||
// An implicitly declared special member function (Clause 12) shall have
|
||||
// an exception-specification.
|
||||
|
@ -5522,11 +5672,20 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
|
|||
LookupDestructor(cast<CXXRecordDecl>(RecordTy->getDecl())));
|
||||
}
|
||||
|
||||
return ExceptSpec;
|
||||
}
|
||||
|
||||
CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
|
||||
// C++ [class.dtor]p2:
|
||||
// If a class has no user-declared destructor, a destructor is
|
||||
// declared implicitly. An implicitly-declared destructor is an
|
||||
// inline public member of its class.
|
||||
|
||||
ImplicitExceptionSpecification Spec =
|
||||
ComputeDefaultedDtorExceptionSpec(ClassDecl);
|
||||
FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
|
||||
|
||||
// Create the actual destructor declaration.
|
||||
FunctionProtoType::ExtProtoInfo EPI;
|
||||
EPI.ExceptionSpecType = ExceptSpec.getExceptionSpecType();
|
||||
EPI.NumExceptions = ExceptSpec.size();
|
||||
EPI.Exceptions = ExceptSpec.data();
|
||||
QualType Ty = Context.getFunctionType(Context.VoidTy, 0, 0, EPI);
|
||||
|
||||
CanQualType ClassType
|
||||
|
@ -5540,6 +5699,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
|
|||
/*isInline=*/true,
|
||||
/*isImplicitlyDeclared=*/true);
|
||||
Destructor->setAccess(AS_public);
|
||||
Destructor->setDefaulted();
|
||||
Destructor->setImplicit();
|
||||
Destructor->setTrivial(ClassDecl->hasTrivialDestructor());
|
||||
|
||||
|
@ -5553,6 +5713,9 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
|
|||
|
||||
// This could be uniqued if it ever proves significant.
|
||||
Destructor->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(Ty));
|
||||
|
||||
if (ShouldDeleteDestructor(Destructor))
|
||||
Destructor->setDeletedAsWritten();
|
||||
|
||||
AddOverriddenMethods(ClassDecl, Destructor);
|
||||
|
||||
|
@ -5561,7 +5724,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
|
|||
|
||||
void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
|
||||
CXXDestructorDecl *Destructor) {
|
||||
assert((Destructor->isImplicit() && !Destructor->isUsed(false)) &&
|
||||
assert((Destructor->isDefaulted() && !Destructor->isUsed(false)) &&
|
||||
"DefineImplicitDestructor - call it for implicit default dtor");
|
||||
CXXRecordDecl *ClassDecl = Destructor->getParent();
|
||||
assert(ClassDecl && "DefineImplicitDestructor - invalid destructor");
|
||||
|
@ -7882,6 +8045,14 @@ void Sema::SetDeclDefaulted(Decl *Dcl, SourceLocation DefaultLoc) {
|
|||
DefineImplicitDefaultConstructor(DefaultLoc, CD);
|
||||
break;
|
||||
}
|
||||
|
||||
case CXXDestructor: {
|
||||
CXXDestructorDecl *DD = cast<CXXDestructorDecl>(MD);
|
||||
CheckExplicitlyDefaultedDestructor(DD);
|
||||
DefineImplicitDestructor(DefaultLoc, DD);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// FIXME: Do the rest once we have functions
|
||||
break;
|
||||
|
|
|
@ -9866,7 +9866,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
|
|||
|
||||
MarkVTableUsed(Loc, Constructor->getParent());
|
||||
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
|
||||
if (Destructor->isImplicit() && !Destructor->isUsed(false))
|
||||
if (Destructor->isDefaulted() && !Destructor->isUsed(false))
|
||||
DefineImplicitDestructor(Loc, Destructor);
|
||||
if (Destructor->isVirtual())
|
||||
MarkVTableUsed(Loc, Destructor->getParent());
|
||||
|
|
|
@ -1569,7 +1569,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
|
|||
|
||||
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||
DeclarationName Name,
|
||||
FunctionDecl* &Operator) {
|
||||
FunctionDecl* &Operator, bool AllowMissing) {
|
||||
LookupResult Found(*this, Name, StartLoc, LookupOrdinaryName);
|
||||
// Try to find operator delete/operator delete[] in class scope.
|
||||
LookupQualifiedName(Found, RD);
|
||||
|
@ -1597,32 +1597,35 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
|||
if (Matches.size() == 1) {
|
||||
Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
|
||||
CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
|
||||
Matches[0]);
|
||||
Matches[0], !AllowMissing);
|
||||
return false;
|
||||
|
||||
// We found multiple suitable operators; complain about the ambiguity.
|
||||
} else if (!Matches.empty()) {
|
||||
Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
|
||||
<< Name << RD;
|
||||
if (!AllowMissing) {
|
||||
Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
|
||||
<< Name << RD;
|
||||
|
||||
for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
|
||||
F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
|
||||
Diag((*F)->getUnderlyingDecl()->getLocation(),
|
||||
diag::note_member_declared_here) << Name;
|
||||
for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
|
||||
F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
|
||||
Diag((*F)->getUnderlyingDecl()->getLocation(),
|
||||
diag::note_member_declared_here) << Name;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// We did find operator delete/operator delete[] declarations, but
|
||||
// none of them were suitable.
|
||||
if (!Found.empty()) {
|
||||
Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
|
||||
<< Name << RD;
|
||||
|
||||
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
||||
F != FEnd; ++F)
|
||||
Diag((*F)->getUnderlyingDecl()->getLocation(),
|
||||
diag::note_member_declared_here) << Name;
|
||||
if (!AllowMissing) {
|
||||
Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
|
||||
<< Name << RD;
|
||||
|
||||
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
||||
F != FEnd; ++F)
|
||||
Diag((*F)->getUnderlyingDecl()->getLocation(),
|
||||
diag::note_member_declared_here) << Name;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1634,7 +1637,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
|||
Expr* DeallocArgs[1];
|
||||
DeallocArgs[0] = &Null;
|
||||
if (FindAllocationOverload(StartLoc, SourceRange(), Name,
|
||||
DeallocArgs, 1, TUDecl, /*AllowMissing=*/false,
|
||||
DeallocArgs, 1, TUDecl, AllowMissing,
|
||||
Operator))
|
||||
return true;
|
||||
|
||||
|
|
Loading…
Reference in New Issue