diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 25 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 |
4 files changed, 33 insertions, 20 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b594eceaf3..f961406e3e 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2208,6 +2208,7 @@ public: bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New, const CXXMethodDecl *Old); + bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange); //===--------------------------------------------------------------------===// // C++ Access Control // diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 2087f8b8c6..49be340873 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2865,9 +2865,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, 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: @@ -3257,8 +3254,13 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, // 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() && @@ -3392,18 +3394,9 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { 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(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index e27b82d800..df27679a5a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4890,6 +4890,26 @@ bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New, 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 diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index a1258572cc..615c6f9456 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -863,6 +863,9 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, 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); @@ -1359,10 +1362,6 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, Record->setEmpty(false); Record->setPolymorphic(true); } - if (Tmpl->isPure()) { - New->setPure(); - Record->setAbstract(true); - } // FIXME: attributes // FIXME: New needs a pointer to Tmpl |