Skip to content

Commit

Permalink
Better anonymous enum support, by mapping their members to manifest c…
Browse files Browse the repository at this point in the history
…onstants.

Add enum.d test.
  • Loading branch information
Syniurge committed Nov 2, 2019
1 parent 6b8ca11 commit a31e55b
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 9 deletions.
34 changes: 25 additions & 9 deletions dmd/cpp/cppmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1193,19 +1193,35 @@ Dsymbols *DeclMapper::VisitEnumConstantDecl(const clang::EnumConstantDecl *D)
auto loc = fromLoc(D->getLocation());
auto ident = fromIdentifier(D->getIdentifier());

auto parent = dsymForDecl(cast<clang::Decl>(D->getDeclContext()));
assert(parent->isEnumDeclaration());
auto value = ExprMapper(*this).fromAPInt(loc, D->getInitVal(), clang::QualType());

auto em = new EnumMember(loc, ident, value, nullptr, D);
setDsym(D, em);
auto parent = dsymForDecl(cast<clang::Decl>(getDeclContextOpaque(D)));
if (auto e = parent->isEnumDeclaration())
{
auto em = new EnumMember(loc, ident, value, nullptr, D);
setDsym(D, em);

em->ed = e;
em->storage_class |= STCmanifest;
em->type = em->ed->type;
em->semanticRun = PASSsemantic3done;

return oneSymbol(em);
}
else
{
auto AnonEnum = cast<clang::EnumDecl>(D->getDeclContext());
auto t = fromType(AnonEnum->getPromotionType(), loc);
auto ie = new_ExpInitializer(loc, value);

em->ed = static_cast<EnumDeclaration*>(parent);
em->storage_class |= STCmanifest;
em->type = em->ed->type;
em->semanticRun = PASSsemantic3done;
auto v = new VarDeclaration(loc, ident, D, t, ie);
setDsym(D, v);

return oneSymbol(em);
v->storage_class |= STCmanifest;
v->semanticRun = PASSsemantic3done;

return oneSymbol(v);
}
}

/*****/
Expand Down
38 changes: 38 additions & 0 deletions tests/calypso/enum.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: %ldc -cpp-args -std=c++11 -cpp-cachedir=%t.cache -of %t %s
// RUN: %t > %t.out
// RUN: FileCheck %s < %t.out

pragma (cppmap, "enum.h");

import std.stdio, std.conv, std.traits;
import (C++) *;

void main()
{
// CHECK: fullname of AAA_1 = ℂcpp.EnumAAA.EnumAAA.AAA_1
writeln("fullname of AAA_1 = ", fullyQualifiedName!AAA_1);

enum E5121 = BBB_5;
// CHECK: typeof(E5121) = EnumBBB
writeln("typeof(E5121) = ", typeof(E5121).stringof);

// CHECK: Anon_2 = 4444
writeln("Anon_2 = ", Anon_2);
// CHECK: EnumClass.EC_1 = EC_1
writeln("EnumClass.EC_1 = ", EnumClass.EC_1);
static assert(!__traits(compiles, EC_2));

EnumTypedef tdef = TDEF_1;
tdef = EnumTypedef.TDEF_2;
// CHECK: tdef = TDEF_2
writeln("tdef = ", tdef);

// CH_CK: test:: members => []
writeln("test:: members => ", [ __traits(allMembers, test) ]);

// CHECK: Struct.AnonInStruct_2 = 1
writeln("Struct.AnonInStruct_2 = ", Struct.AnonInStruct_2);

// CH_CK: Struct2 members => []
writeln("Struct2 members => ", [ __traits(allMembers, Struct2) ]);
}
71 changes: 71 additions & 0 deletions tests/calypso/enum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once

enum EnumAAA
{
AAA_1,
AAA_2 = 512,
AAA_3 = 8192,
};

enum EnumBBB : char
{
BBB_1 = 'a',
BBB_2,
BBB_3,
BBB_4,
BBB_5,
};

enum
{
Anon_1 = 2222,
Anon_2 = 4444
};

enum class EnumClass
{
EC_1,
EC_2,
EC_3
};

typedef enum
{
TDEF_1,
TDEF_2
} EnumTypedef;

namespace test
{
enum EnumInner
{
EInn_1,
EInn_2,
EInn_3
};

enum class EnumClassInner
{
CI_1,
CI_2,
CI_3
};
}

struct Struct
{
enum
{
AnonInStruct_1,
AnonInStruct_2
};
};

struct Struct2
{
enum
{
AIS_1,
AIS_2
};
};

0 comments on commit a31e55b

Please sign in to comment.