aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-01-09 19:57:06 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-01-09 19:57:06 +0000
commit9ba73ad65446f6bc876f40cced866d85dff754da (patch)
tree1f32df925afb62417374517f770931dda5a00258 /lib
parent6037fcba3431b47de1a994c9b286feac17894eff (diff)
Very basic support for pure virtual functions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62003 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index dea3688bdb..ba4a47d63e 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -535,6 +535,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
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 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
}
}
+ // 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 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
}
} 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;
+ }
}
}