diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-09 19:57:06 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-01-09 19:57:06 +0000 |
commit | 607952559179dd641bcbf96673df2d6516bc808f (patch) | |
tree | 3c82a5f78862f387decd5bacdf2a278206f182da /clang/lib | |
parent | b302377dc334d61c8395c913c06d44aec86d8845 (diff) | |
download | bcm5719-llvm-607952559179dd641bcbf96673df2d6516bc808f.tar.gz bcm5719-llvm-607952559179dd641bcbf96673df2d6516bc808f.zip |
Very basic support for pure virtual functions.
llvm-svn: 62003
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index dea3688bdbf..ba4a47d63ec 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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; + } } } |