forked from OSchip/llvm-project
Factor finding a deallocation function for a record type out into a separate function.
llvm-svn: 88857
This commit is contained in:
parent
a46efbb857
commit
e1d34ba0e4
|
@ -2112,6 +2112,9 @@ public:
|
||||||
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
|
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
|
||||||
QualType Argument);
|
QualType Argument);
|
||||||
|
|
||||||
|
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||||
|
DeclarationName Name, FunctionDecl* &Operator);
|
||||||
|
|
||||||
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
|
/// ActOnCXXDelete - Parsed a C++ 'delete' expression
|
||||||
virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
|
virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
|
||||||
bool UseGlobal, bool ArrayForm,
|
bool UseGlobal, bool ArrayForm,
|
||||||
|
|
|
@ -753,6 +753,59 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
|
||||||
((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
|
((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
|
||||||
|
DeclarationName Name,
|
||||||
|
FunctionDecl* &Operator) {
|
||||||
|
LookupResult Found;
|
||||||
|
// Try to find operator delete/operator delete[] in class scope.
|
||||||
|
LookupQualifiedName(Found, RD, Name, LookupOrdinaryName);
|
||||||
|
|
||||||
|
if (Found.isAmbiguous()) {
|
||||||
|
DiagnoseAmbiguousLookup(Found, Name, StartLoc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
||||||
|
F != FEnd; ++F) {
|
||||||
|
if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
|
||||||
|
if (Delete->isUsualDeallocationFunction()) {
|
||||||
|
Operator = Delete;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)->getLocation(),
|
||||||
|
diag::note_delete_member_function_declared_here)
|
||||||
|
<< Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for a global declaration.
|
||||||
|
DeclareGlobalNewDelete();
|
||||||
|
DeclContext *TUDecl = Context.getTranslationUnitDecl();
|
||||||
|
|
||||||
|
CXXNullPtrLiteralExpr Null(Context.VoidPtrTy, SourceLocation());
|
||||||
|
Expr* DeallocArgs[1];
|
||||||
|
DeallocArgs[0] = &Null;
|
||||||
|
if (FindAllocationOverload(StartLoc, SourceRange(), Name,
|
||||||
|
DeallocArgs, 1, TUDecl, /*AllowMissing=*/false,
|
||||||
|
Operator))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
assert(Operator && "Did not find a deallocation function!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
|
/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
|
||||||
/// @code ::delete ptr; @endcode
|
/// @code ::delete ptr; @endcode
|
||||||
/// or
|
/// or
|
||||||
|
@ -844,52 +897,21 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
|
||||||
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
|
DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
|
||||||
ArrayForm ? OO_Array_Delete : OO_Delete);
|
ArrayForm ? OO_Array_Delete : OO_Delete);
|
||||||
|
|
||||||
LookupResult Found;
|
if (const RecordType *RT = Pointee->getAs<RecordType>()) {
|
||||||
if (Pointee->isRecordType() && !UseGlobal) {
|
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
|
||||||
CXXRecordDecl *Record
|
|
||||||
= cast<CXXRecordDecl>(Pointee->getAs<RecordType>()->getDecl());
|
if (!UseGlobal &&
|
||||||
|
FindDeallocationFunction(StartLoc, RD, DeleteName, OperatorDelete))
|
||||||
// Try to find operator delete/operator delete[] in class scope.
|
|
||||||
LookupQualifiedName(Found, Record, DeleteName, LookupOrdinaryName);
|
|
||||||
|
|
||||||
if (Found.isAmbiguous()) {
|
|
||||||
DiagnoseAmbiguousLookup(Found, DeleteName, StartLoc);
|
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Diagnose ambiguity properly
|
if (!RD->hasTrivialDestructor())
|
||||||
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
if (const CXXDestructorDecl *Dtor = RD->getDestructor(Context))
|
||||||
F != FEnd; ++F) {
|
|
||||||
if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
|
|
||||||
if (Delete->isUsualDeallocationFunction()) {
|
|
||||||
OperatorDelete = Delete;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!OperatorDelete && !Found.empty()) {
|
|
||||||
// We did find operator delete/operator delete[] declarations, but
|
|
||||||
// none of them were suitable.
|
|
||||||
Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
|
|
||||||
<< DeleteName << Record;
|
|
||||||
|
|
||||||
for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
|
|
||||||
F != FEnd; ++F) {
|
|
||||||
Diag((*F)->getLocation(),
|
|
||||||
diag::note_delete_member_function_declared_here)
|
|
||||||
<< DeleteName;
|
|
||||||
}
|
|
||||||
return ExprError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Record->hasTrivialDestructor())
|
|
||||||
if (const CXXDestructorDecl *Dtor = Record->getDestructor(Context))
|
|
||||||
MarkDeclarationReferenced(StartLoc,
|
MarkDeclarationReferenced(StartLoc,
|
||||||
const_cast<CXXDestructorDecl*>(Dtor));
|
const_cast<CXXDestructorDecl*>(Dtor));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!OperatorDelete) {
|
if (!OperatorDelete) {
|
||||||
// Didn't find a member overload. Look for a global one.
|
// Look for a global declaration.
|
||||||
DeclareGlobalNewDelete();
|
DeclareGlobalNewDelete();
|
||||||
DeclContext *TUDecl = Context.getTranslationUnitDecl();
|
DeclContext *TUDecl = Context.getTranslationUnitDecl();
|
||||||
if (FindAllocationOverload(StartLoc, SourceRange(), DeleteName,
|
if (FindAllocationOverload(StartLoc, SourceRange(), DeleteName,
|
||||||
|
|
Loading…
Reference in New Issue