Skip to content

Commit

Permalink
Merge pull request #2895 from yebblies/issue11616
Browse files Browse the repository at this point in the history
Issue 11616 - Introduce virtual keyword
  • Loading branch information
AndrejMitrovic committed Feb 25, 2014
2 parents 53bec85 + b900262 commit 28acc4a
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/attrib.c
Expand Up @@ -392,6 +392,8 @@ void StorageClassDeclaration::setScope(Scope *sc)
scstc &= ~(STCgshared | STCshared | STCtls);
if (stc & (STCsafe | STCtrusted | STCsystem))
scstc &= ~(STCsafe | STCtrusted | STCsystem);
if (stc & (STCfinal | STCvirtual))
scstc &= ~(STCfinal | STCvirtual);
scstc |= stc;
//printf("scstc = x%llx\n", scstc);

Expand Down Expand Up @@ -448,6 +450,7 @@ const char *StorageClassDeclaration::stcToChars(char tmp[], StorageClass& stc)
{ STCextern, TOKextern },
{ STCconst, TOKconst },
{ STCfinal, TOKfinal },
{ STCvirtual, TOKvirtual },
{ STCabstract, TOKabstract },
{ STCsynchronized, TOKsynchronized },
{ STCdeprecated, TOKdeprecated },
Expand Down
3 changes: 2 additions & 1 deletion src/declaration.h
Expand Up @@ -85,10 +85,11 @@ enum PURE;
#define STCnodefaultctor 0x8000000000LL // must be set inside constructor
#define STCtemp 0x10000000000LL // temporary variable
#define STCrvalue 0x20000000000LL // force rvalue for variables
#define STCvirtual 0x40000000000LL

const StorageClass STCStorageClass = (STCauto | STCscope | STCstatic | STCextern | STCconst | STCfinal |
STCabstract | STCsynchronized | STCdeprecated | STCoverride | STClazy | STCalias |
STCout | STCin |
STCout | STCin | STCvirtual |
STCmanifest | STCimmutable | STCshared | STCwild | STCnothrow | STCpure | STCref | STCtls |
STCgshared | STCproperty | STCsafe | STCtrusted | STCsystem | STCdisable);

Expand Down
10 changes: 9 additions & 1 deletion src/func.c
Expand Up @@ -582,6 +582,14 @@ void FuncDeclaration::semantic(Scope *sc)
if (storage_class & STCscope)
error("functions cannot be scope");

if (storage_class & STCvirtual)
{
if (ad && ad->isStructDeclaration())
error("struct member functions cannot be virtual");
else if (isStatic())
error("static member functions cannot be virtual");
}

if (isAbstract() && !isVirtual())
{
const char *sfunc;
Expand Down Expand Up @@ -1248,7 +1256,7 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2->fes = fes;
sc2->linkage = LINKd;
sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract |
STCdeprecated | STCoverride |
STCdeprecated | STCoverride | STCvirtual |
STC_TYPECTOR | STCfinal | STCtls | STCgshared | STCref |
STCproperty | STCsafe | STCtrusted | STCsystem);
sc2->protection = PROTpublic;
Expand Down
1 change: 1 addition & 0 deletions src/lexer.c
Expand Up @@ -2788,6 +2788,7 @@ static Keyword keywords[] =
{ "import", TOKimport },
{ "mixin", TOKmixin },
{ "static", TOKstatic },
{ "virtual", TOKvirtual },
{ "final", TOKfinal },
{ "const", TOKconst },
{ "typedef", TOKtypedef },
Expand Down
2 changes: 1 addition & 1 deletion src/lexer.h
Expand Up @@ -135,7 +135,7 @@ enum TOK
TOKmixin,

TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKstatic, TOKvirtual, TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
TOKauto, TOKpackage, TOKmanifest, TOKimmutable,

Expand Down
4 changes: 4 additions & 0 deletions src/parse.c
Expand Up @@ -415,6 +415,7 @@ Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl)
goto Lstc;

case TOKfinal: stc = STCfinal; goto Lstc;
case TOKvirtual: stc = STCvirtual; goto Lstc;
case TOKauto: stc = STCauto; goto Lstc;
case TOKscope: stc = STCscope; goto Lstc;
case TOKoverride: stc = STCoverride; goto Lstc;
Expand Down Expand Up @@ -478,6 +479,7 @@ Dsymbols *Parser::parseDeclDefs(int once, Dsymbol **pLastDecl)
stc = STCdeprecated;
goto Lstc;
case TOKfinal: stc = STCfinal; goto Lstc;
case TOKvirtual: stc = STCvirtual; goto Lstc;
case TOKauto: stc = STCauto; goto Lstc;
case TOKscope: stc = STCscope; goto Lstc;
case TOKoverride: stc = STCoverride; goto Lstc;
Expand Down Expand Up @@ -3124,6 +3126,7 @@ Dsymbols *Parser::parseDeclarations(StorageClass storage_class, const utf8_t *co

case TOKstatic: stc = STCstatic; goto L1;
case TOKfinal: stc = STCfinal; goto L1;
case TOKvirtual: stc = STCvirtual; goto L1;
case TOKauto: stc = STCauto; goto L1;
case TOKscope: stc = STCscope; goto L1;
case TOKoverride: stc = STCoverride; goto L1;
Expand Down Expand Up @@ -5692,6 +5695,7 @@ int Parser::skipAttributes(Token *t, Token **pt)
case TOKshared:
case TOKwild:
case TOKfinal:
case TOKvirtual:
case TOKauto:
case TOKscope:
case TOKoverride:
Expand Down
30 changes: 30 additions & 0 deletions test/fail_compilation/fail11616.d
@@ -0,0 +1,30 @@
/*
PERMUTE_ARGS:
TEST_OUTPUT:
---
fail_compilation/fail11616.d(22): Error: function fail11616.D.a cannot override final function fail11616.C.a
fail_compilation/fail11616.d(22): Error: function fail11616.D.a does not override any function
fail_compilation/fail11616.d(23): Error: function fail11616.D.b cannot override final function fail11616.C.b
fail_compilation/fail11616.d(24): Error: function fail11616.D.c static member functions cannot be virtual
fail_compilation/fail11616.d(29): Error: function fail11616.S.x struct member functions cannot be virtual
---
*/

class C
{
virtual:
final void a();
final void b();
}

class D : C
{
override void a() {}
void b() {}
static virtual void c();
}

struct S
{
virtual void x() {}
}
19 changes: 19 additions & 0 deletions test/runnable/xtest46.d
Expand Up @@ -2130,6 +2130,25 @@ void test103()

/***************************************************/

class C11616
{
virtual void a() {}
virtual { void b() {} }
virtual:
final void c() {}
final:
virtual void d() {}
}

class D11616 : C11616
{
final override void a() {}
final override void b() {}
final override void d() {}
}

/***************************************************/

int foo104(int x)
{
int* p = &(x += 1);
Expand Down

0 comments on commit 28acc4a

Please sign in to comment.