[cfe-commits] r62003 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/Basic/DiagnosticKinds.def lib/Sema/SemaDeclCXX.cpp test/SemaCXX/virtuals.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Fri Jan 9 11:57:07 PST 2009
Author: cornedbee
Date: Fri Jan 9 13:57:06 2009
New Revision: 62003
URL: http://llvm.org/viewvc/llvm-project?rev=62003&view=rev
Log:
Very basic support for pure virtual functions.
Added:
cfe/trunk/test/SemaCXX/virtuals.cpp
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=62003&r1=62002&r2=62003&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Jan 9 13:57:06 2009
@@ -648,6 +648,8 @@
// NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
unsigned SClass : 2;
bool IsInline : 1;
+ bool IsVirtual : 1;
+ bool IsPure : 1;
// Move to DeclGroup when it is implemented.
SourceLocation TypeSpecStartLoc;
@@ -659,7 +661,8 @@
: ValueDecl(DK, DC, L, N, T, PrevDecl),
DeclContext(DK),
ParamInfo(0), Body(0), PreviousDeclaration(0),
- SClass(S), IsInline(isInline), TypeSpecStartLoc(TSSL) {}
+ SClass(S), IsInline(isInline), IsVirtual(false), IsPure(false),
+ TypeSpecStartLoc(TSSL) {}
virtual ~FunctionDecl();
virtual void Destroy(ASTContext& C);
@@ -692,7 +695,13 @@
bool isThisDeclarationADefinition() const { return Body != 0; }
void setBody(Stmt *B) { Body = B; }
-
+
+ bool isVirtual() { return IsVirtual; }
+ void setVirtual() { IsVirtual = true; }
+
+ bool isPure() { return IsPure; }
+ void setPure() { IsPure = true; }
+
/// getPreviousDeclaration - Return the previous declaration of this
/// function.
const FunctionDecl *getPreviousDeclaration() const {
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=62003&r1=62002&r2=62003&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Jan 9 13:57:06 2009
@@ -753,6 +753,10 @@
"bit-field %0 with non-integral type")
DIAG(err_member_initialization, ERROR,
"%0 can only be initialized if it is a static const integral data member")
+DIAG(err_member_function_initialization, ERROR,
+ "initializer on function does not look like a pure-specifier")
+DIAG(err_non_virtual_pure, ERROR,
+ "%0 is not virtual and cannot be declared pure")
DIAG(err_implicit_object_parameter_init, ERROR,
"cannot initialize object parameter of type %0 with an expression of type %1")
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=62003&r1=62002&r2=62003&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Jan 9 13:57:06 2009
@@ -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;
+ }
}
}
Added: cfe/trunk/test/SemaCXX/virtuals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/virtuals.cpp?rev=62003&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/virtuals.cpp (added)
+++ cfe/trunk/test/SemaCXX/virtuals.cpp Fri Jan 9 13:57:06 2009
@@ -0,0 +1,33 @@
+// RUN: clang -fsyntax-only -verify %s
+
+class A {
+ virtual void f();
+ virtual void g() = 0;
+
+ void h() = 0; // expected-error {{'h' is not virtual and cannot be declared pure}}
+ void i() = 1; // expected-error {{initializer on function does not look like a pure-specifier}}
+ void j() = 0u; // expected-error {{initializer on function does not look like a pure-specifier}}
+
+public:
+ A(int);
+};
+
+class B : public A {
+ // Needs to recognize that overridden function is virtual.
+ //void g() = 0;
+
+ // Needs to recognize that function does not override.
+ //void g(int) = 0;
+};
+
+// Needs to recognize invalid uses of abstract classes.
+/*
+A fn(A)
+{
+ A a;
+ static_cast<A>(0);
+ try {
+ } catch(A) {
+ }
+}
+*/
More information about the cfe-commits
mailing list