Very basic support for pure virtual functions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62003 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index dea3688..ba4a47d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -535,6 +535,7 @@
Diag(DS.getVirtualSpecLoc(), diag::err_virtual_non_function);
InvalidDecl = true;
} else {
+ cast<CXXMethodDecl>(Member)->setVirtual();
CXXRecordDecl *CurClass = cast<CXXRecordDecl>(CurContext);
CurClass->setAggregate(false);
CurClass->setPOD(false);
@@ -542,6 +543,10 @@
}
}
+ // FIXME: The above definition of virtual is not sufficient. A function is
+ // also virtual if it overrides an already virtual function. This is important
+ // to do here because it decides the validity of a pure specifier.
+
if (BitWidth) {
// C++ 9.6p2: Only when declaring an unnamed bit-field may the
// constant-expression be a value equal to zero.
@@ -608,10 +613,28 @@
}
} else {
- // not static member.
- Diag(Loc, diag::err_member_initialization)
- << Name << Init->getSourceRange();
- InvalidDecl = true;
+ // not static member. perhaps virtual function?
+ if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+ IntegerLiteral *IL;
+ if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
+ Context.getCanonicalType(IL->getType()) == Context.IntTy) {
+ if (MD->isVirtual())
+ MD->setPure();
+ else {
+ Diag(Loc, diag::err_non_virtual_pure)
+ << Name << Init->getSourceRange();
+ InvalidDecl = true;
+ }
+ } else {
+ Diag(Loc, diag::err_member_function_initialization)
+ << Name << Init->getSourceRange();
+ InvalidDecl = true;
+ }
+ } else {
+ Diag(Loc, diag::err_member_initialization)
+ << Name << Init->getSourceRange();
+ InvalidDecl = true;
+ }
}
}