Teach FunctionDecl::setPure() to (indirectly) mark the Abstract bit in
CXXRecordDecl::DefinitionData, rather than having Sema mark the bit.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114993 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 1b1b1df..3e1f4ba 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1280,7 +1280,7 @@
/// Whether this virtual function is pure, i.e. makes the containing class
/// abstract.
bool isPure() const { return IsPure; }
- void setPure(bool P = true) { IsPure = P; }
+ void setPure(bool P = true);
/// Whether this function is "trivial" in some specialized C++ senses.
/// Can only be true for default constructors, copy constructors,
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 786393c..cdc6d8c 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -412,6 +412,9 @@
/// members have been added. It will be invoked by DeclContext::addDecl()
/// whenever a member is added to this record.
void addedMember(Decl *D);
+
+ void markedVirtualFunctionPure();
+ friend void FunctionDecl::setPure(bool);
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 2f3c006..081e5ee 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -966,6 +966,13 @@
EndRangeLoc = B->getLocEnd();
}
+void FunctionDecl::setPure(bool P) {
+ IsPure = P;
+ if (P)
+ if (CXXRecordDecl *Parent = dyn_cast<CXXRecordDecl>(getDeclContext()))
+ Parent->markedVirtualFunctionPure();
+}
+
bool FunctionDecl::isMain() const {
ASTContext &Context = getASTContext();
return !Context.getLangOptions().Freestanding &&
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 7cdffb7..036292b 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -319,8 +319,13 @@
return GetBestOverloadCandidateSimple(Found);
}
-void
-CXXRecordDecl::addedMember(Decl *D) {
+void CXXRecordDecl::markedVirtualFunctionPure() {
+ // C++ [class.abstract]p2:
+ // A class is abstract if it has at least one pure virtual function.
+ data().Abstract = true;
+}
+
+void CXXRecordDecl::addedMember(Decl *D) {
// Ignore friends and invalid declarations.
if (D->getFriendObjectKind() || D->isInvalidDecl())
return;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 63acb09..425389a 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -6668,9 +6668,6 @@
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;
}