NewFD->setAccess(AS_public);
}
- if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD))
- AddOverriddenMethods(cast<CXXRecordDecl>(DC), NewMD);
-
if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
!CurContext->isRecord()) {
// C++ [class.static]p1:
// FIXME: C++0x: don't do this for "= default" destructors
Record->setHasTrivialDestructor(false);
} else if (CXXConversionDecl *Conversion
- = dyn_cast<CXXConversionDecl>(NewFD))
+ = dyn_cast<CXXConversionDecl>(NewFD)) {
ActOnConversionDeclarator(Conversion);
+ }
+
+ // Find any virtual functions that this function overrides.
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD))
+ AddOverriddenMethods(Method->getParent(), Method);
// Extra checking for C++ overloaded operators (C++ [over.oper]).
if (NewFD->isOverloadedOperator() &&
IntegerLiteral *IL;
Expr *Init = static_cast<Expr *>(init.get());
if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
- Context.getCanonicalType(IL->getType()) == Context.IntTy) {
- if (Method->isVirtual()) {
- Method->setPure();
-
- // A class is abstract if at least one function is pure virtual.
- cast<CXXRecordDecl>(CurContext)->setAbstract(true);
- } else if (!Method->isInvalidDecl()) {
- Diag(Method->getLocation(), diag::err_non_virtual_pure)
- << Method->getDeclName() << Init->getSourceRange();
- Method->setInvalidDecl();
- }
- } else {
+ Context.getCanonicalType(IL->getType()) == Context.IntTy)
+ CheckPureMethod(Method, Init->getSourceRange());
+ else {
Diag(Method->getLocation(), diag::err_member_function_initialization)
<< Method->getDeclName() << Init->getSourceRange();
Method->setInvalidDecl();
return false;
}
+/// \brief Mark the given method pure.
+///
+/// \param Method the method to be marked pure.
+///
+/// \param InitRange the source range that covers the "0" initializer.
+bool Sema::CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange) {
+ if (Method->isVirtual() || Method->getParent()->isDependentContext()) {
+ Method->setPure();
+
+ // A class is abstract if at least one function is pure virtual.
+ Method->getParent()->setAbstract(true);
+ return false;
+ }
+
+ if (!Method->isInvalidDecl())
+ Diag(Method->getLocation(), diag::err_non_virtual_pure)
+ << Method->getDeclName() << InitRange;
+ return true;
+}
+
/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
/// initializer for the declaration 'Dcl'.
/// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
SemaRef.CheckFunctionDeclaration(Method, Previous, false, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
+ if (D->isPure())
+ SemaRef.CheckPureMethod(Method, SourceRange());
+
if (!FunctionTemplate && (!Method->isInvalidDecl() || Previous.empty()) &&
!Method->getFriendObjectKind())
Owner->addDecl(Method);
Record->setEmpty(false);
Record->setPolymorphic(true);
}
- if (Tmpl->isPure()) {
- New->setPure();
- Record->setAbstract(true);
- }
// FIXME: attributes
// FIXME: New needs a pointer to Tmpl