Skip to content

Commit 65288ee

Browse files
committed
[Clang Importer] Cleanup and sharing of code
Adds makeStructRawValued utility function, which shares common code for raw-value-backed structs from both OptionSets and many imported enums. NFC.
1 parent 5533880 commit 65288ee

File tree

1 file changed

+75
-80
lines changed

1 file changed

+75
-80
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 75 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,73 @@ namespace {
13791379
return constructor;
13801380
}
13811381

1382+
/// Make a struct declaration into a raw-value-backed struct
1383+
///
1384+
/// \param structDecl the struct to make a raw value for
1385+
/// \param underlyingType the type of the raw value
1386+
/// \param synthesizedProtocolAttrs synthesized protocol attributes to add
1387+
/// \param protocols the protocols to make this struct conform to
1388+
/// \param setterAccessibility the accessiblity of the raw value's setter
1389+
/// \param isLet whether the raw value should be a let
1390+
/// \param makeUnlabeledValueInit whether to also create an unlabeled init
1391+
/// \param isImplicit whether to mark the rawValue as implicit
1392+
///
1393+
/// This will perform most of the work involved in making a new Swift struct
1394+
/// be backed by a raw value. This will populated derived protocols and
1395+
/// synthesized protocols, add the new variable and pattern bindings, and
1396+
/// create the inits parameterized over a raw value
1397+
///
1398+
template <unsigned N>
1399+
void makeStructRawValued(
1400+
StructDecl *structDecl,
1401+
Type underlyingType,
1402+
ArrayRef<KnownProtocolKind> synthesizedProtocolAttrs,
1403+
ProtocolDecl *const(&protocols)[N],
1404+
Accessibility setterAccessibility = Accessibility::Private,
1405+
bool isLet = true,
1406+
bool makeUnlabeledValueInit = false,
1407+
bool isImplicit = true) {
1408+
auto &cxt = Impl.SwiftContext;
1409+
populateInheritedTypes(structDecl, protocols);
1410+
1411+
// Note synthesized protocols
1412+
for (auto kind : synthesizedProtocolAttrs)
1413+
structDecl->getAttrs().add(new (cxt) SynthesizedProtocolAttr(kind));
1414+
1415+
// Create a variable to store the underlying value.
1416+
auto varName = cxt.Id_rawValue;
1417+
auto var = new (cxt) VarDecl(
1418+
/*static*/ false,
1419+
/*IsLet*/ isLet, SourceLoc(), varName, underlyingType, structDecl);
1420+
if (isImplicit)
1421+
var->setImplicit();
1422+
var->setAccessibility(Accessibility::Public);
1423+
var->setSetterAccessibility(setterAccessibility);
1424+
1425+
// Create a pattern binding to describe the variable.
1426+
Pattern *varPattern = createTypedNamedPattern(var);
1427+
1428+
auto patternBinding = PatternBindingDecl::create(
1429+
cxt, SourceLoc(), StaticSpellingKind::None, SourceLoc(), varPattern,
1430+
nullptr, structDecl);
1431+
structDecl->setHasDelayedMembers();
1432+
1433+
// Create constructors to initialize that value from a value of the
1434+
// underlying type.
1435+
if (makeUnlabeledValueInit)
1436+
structDecl->addMember(createValueConstructor(
1437+
structDecl, var,
1438+
/*wantCtorParamNames=*/false,
1439+
/*wantBody=*/!Impl.hasFinishedTypeChecking()));
1440+
structDecl->addMember(
1441+
createValueConstructor(structDecl, var,
1442+
/*wantCtorParamNames=*/true,
1443+
/*wantBody=*/!Impl.hasFinishedTypeChecking()));
1444+
1445+
structDecl->addMember(patternBinding);
1446+
structDecl->addMember(var);
1447+
}
1448+
13821449
/// \brief Create a constructor that initializes a struct from its members.
13831450
ConstructorDecl *createValueConstructor(StructDecl *structDecl,
13841451
ArrayRef<VarDecl *> members,
@@ -1625,45 +1692,10 @@ namespace {
16251692
Loc, name, Loc, None, nullptr, dc);
16261693
structDecl->computeType();
16271694

1628-
// Note that this is a raw option set type.
1629-
structDecl->getAttrs().add(
1630-
new (Impl.SwiftContext) SynthesizedProtocolAttr(
1631-
KnownProtocolKind::OptionSet));
1632-
1633-
1634-
// Create a field to store the underlying value.
1635-
auto varName = Impl.SwiftContext.Id_rawValue;
1636-
auto var = new (Impl.SwiftContext) VarDecl(/*static*/ false,
1637-
/*IsLet*/ true,
1638-
SourceLoc(), varName,
1639-
underlyingType,
1640-
structDecl);
1641-
var->setImplicit();
1642-
var->setAccessibility(Accessibility::Public);
1643-
var->setSetterAccessibility(Accessibility::Private);
1644-
1645-
// Create a pattern binding to describe the variable.
1646-
Pattern *varPattern = createTypedNamedPattern(var);
1647-
1648-
auto patternBinding =
1649-
PatternBindingDecl::create(Impl.SwiftContext, SourceLoc(),
1650-
StaticSpellingKind::None, SourceLoc(),
1651-
varPattern, nullptr, structDecl);
1652-
1653-
// Create the init(rawValue:) constructor.
1654-
auto labeledValueConstructor = createValueConstructor(
1655-
structDecl, var,
1656-
/*wantCtorParamNames=*/true,
1657-
/*wantBody=*/!Impl.hasFinishedTypeChecking());
1658-
1659-
// Build an OptionSet conformance for the type.
16601695
ProtocolDecl *protocols[]
16611696
= {cxt.getProtocol(KnownProtocolKind::OptionSet)};
1662-
populateInheritedTypes(structDecl, protocols);
1663-
1664-
structDecl->addMember(labeledValueConstructor);
1665-
structDecl->addMember(patternBinding);
1666-
structDecl->addMember(var);
1697+
makeStructRawValued(structDecl, underlyingType,
1698+
{KnownProtocolKind::OptionSet}, protocols);
16671699
return structDecl;
16681700
}
16691701

@@ -1714,49 +1746,12 @@ namespace {
17141746
ProtocolDecl *protocols[]
17151747
= {cxt.getProtocol(KnownProtocolKind::RawRepresentable),
17161748
cxt.getProtocol(KnownProtocolKind::Equatable)};
1717-
populateInheritedTypes(structDecl, protocols);
1718-
1719-
// Note that this is a raw representable type.
1720-
structDecl->getAttrs().add(
1721-
new (Impl.SwiftContext) SynthesizedProtocolAttr(
1722-
KnownProtocolKind::RawRepresentable));
1723-
1724-
// Create a variable to store the underlying value.
1725-
auto varName = Impl.SwiftContext.Id_rawValue;
1726-
auto var = new (Impl.SwiftContext) VarDecl(/*static*/ false,
1727-
/*IsLet*/ false,
1728-
SourceLoc(), varName,
1729-
underlyingType,
1730-
structDecl);
1731-
var->setAccessibility(Accessibility::Public);
1732-
var->setSetterAccessibility(Accessibility::Public);
1733-
1734-
// Create a pattern binding to describe the variable.
1735-
Pattern *varPattern = createTypedNamedPattern(var);
1736-
1737-
auto patternBinding =
1738-
PatternBindingDecl::create(Impl.SwiftContext, SourceLoc(),
1739-
StaticSpellingKind::None, SourceLoc(),
1740-
varPattern, nullptr, structDecl);
1741-
1742-
// Create a constructor to initialize that value from a value of the
1743-
// underlying type.
1744-
auto valueConstructor =
1745-
createValueConstructor(structDecl, var,
1746-
/*wantCtorParamNames=*/false,
1747-
/*wantBody=*/!Impl.hasFinishedTypeChecking());
1748-
auto labeledValueConstructor =
1749-
createValueConstructor(structDecl, var,
1750-
/*wantCtorParamNames=*/true,
1751-
/*wantBody=*/!Impl.hasFinishedTypeChecking());
1752-
1753-
structDecl->setHasDelayedMembers();
1754-
1755-
// Set the members of the struct.
1756-
structDecl->addMember(valueConstructor);
1757-
structDecl->addMember(labeledValueConstructor);
1758-
structDecl->addMember(patternBinding);
1759-
structDecl->addMember(var);
1749+
makeStructRawValued(structDecl, underlyingType,
1750+
{KnownProtocolKind::RawRepresentable}, protocols,
1751+
/*setterAccessibility=*/Accessibility::Public,
1752+
/*isLet=*/false,
1753+
/*makeUnlabeledValueInit=*/true,
1754+
/*isImplicit=*/false);
17601755

17611756
result = structDecl;
17621757
break;

0 commit comments

Comments
 (0)