[TypeID] Use .def files to introduce TypeID specializations.

Simplify the static registration of types for use with TypeID by introducing
a more declarative approach. Each zone provides a .def file listing the
types and templates defined by that zone. The .def file is processed by
include/swift/Basic/DefineTypeIDZone.h with its zone number, which assigns
values to each of the types/templates and introduces the TypeID
specializations.
This commit is contained in:
Doug Gregor
2018-04-24 06:47:51 -07:00
parent 4b9e3ea84b
commit cbc6289962
5 changed files with 141 additions and 49 deletions

View File

@@ -0,0 +1,37 @@
//===--- CTypeIDZone.def - Define the C++ TypeID Zone -----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This definition file describes the types in the "C++" TypeID zone,
// for use with the TypeID template.
//
//===----------------------------------------------------------------------===//
// C types.
SWIFT_TYPEID_NAMED(unsigned char, UnsignedChar)
SWIFT_TYPEID_NAMED(signed char, SignedChar)
SWIFT_TYPEID_NAMED(char, Char)
SWIFT_TYPEID_NAMED(short, Short)
SWIFT_TYPEID_NAMED(unsigned short, UnsignedShort)
SWIFT_TYPEID_NAMED(int, Int)
SWIFT_TYPEID_NAMED(unsigned int, UnsignedInt)
SWIFT_TYPEID_NAMED(long, Long)
SWIFT_TYPEID_NAMED(unsigned long, UnsignedLong)
SWIFT_TYPEID_NAMED(long long, LongLong)
SWIFT_TYPEID_NAMED(unsigned long long, UnsignedLongLong)
SWIFT_TYPEID_NAMED(float, Float)
SWIFT_TYPEID_NAMED(double, Double)
SWIFT_TYPEID_NAMED(bool, Bool)
SWIFT_TYPEID_NAMED(decltype(nullptr), NullPtr)
SWIFT_TYPEID_NAMED(void, Void)
// C++ standard library types.
SWIFT_TYPEID_TEMPLATE1_NAMED(std::vector, Vector, typename T, T)

View File

@@ -0,0 +1,74 @@
//===--- DefineTypeIDZone.h - Define a TypeID Zone --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file should be #included to define the TypeIDs for a given zone.
// Two macros should be #define'd before inclusion, and will be #undef'd at
// the end of this file:
//
// SWIFT_TYPEID_ZONE: The name of the Zone being defined, e.g.,
// SwiftAST for the Swift AST library's zone. All zones need to be defined
// a priori as
//
// SWIFT_TYPEID_HEADER: A (quoted) name of the header to be
// included to define the types in the zone.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_TYPEID_ZONE
# error Must define the value of the TypeID zone with the given name.
#endif
#ifndef SWIFT_TYPEID_HEADER
# error Must define the TypeID header name with SWIFT_TYPEID_HEADER
#endif
// Define a TypeID where the type name and internal name are the same.
#define SWIFT_TYPEID(Type) SWIFT_TYPEID_NAMED(Type, Type)
// First pass: put all of the names into an enum so we get values for them.
template<> struct TypeIDZoneTypes<SWIFT_TYPEID_ZONE> {
enum Types : uint8_t {
#define SWIFT_TYPEID_NAMED(Type, Name) Name,
#define SWIFT_TYPEID_TEMPLATE1_NAMED(Template, Name, Param1, Arg1) Name,
#include SWIFT_TYPEID_HEADER
#undef SWIFT_TYPEID_NAMED
#undef SWIFT_TYPEID_TEMPLATE1_NAMED
};
};
// Second pass: create specializations of TypeID for these types.
#define SWIFT_TYPEID_NAMED(Type, Name) \
template<> struct TypeID<Type> { \
static const uint64_t value = \
formTypeID(SWIFT_TYPEID_ZONE, \
TypeIDZoneTypes<SWIFT_TYPEID_ZONE>::Name); \
};
#define SWIFT_TYPEID_TEMPLATE1_NAMED(Template, Name, Param1, Arg1) \
template<Param1> struct TypeID<Template<Arg1>> { \
private: \
static const uint64_t templateID = \
formTypeID(SWIFT_TYPEID_ZONE, \
TypeIDZoneTypes<SWIFT_TYPEID_ZONE>::Name); \
\
public: \
static const uint64_t value = \
(TypeID<Arg1>::value << 16) | templateID; \
};
#include SWIFT_TYPEID_HEADER
#undef SWIFT_TYPEID_NAMED
#undef SWIFT_TYPEID_TEMPLATE1_NAMED
#undef SWIFT_TYPEID
#undef SWIFT_TYPEID_ZONE
#undef SWIFT_TYPEID_HEADER

View File

@@ -32,58 +32,19 @@ namespace swift {
template<typename T>
struct TypeID;
/// Each type "zone" can contain 256 separate types for use in typeid,
/// which should be enumerated.
struct TypeIdZones {
enum ZoneValues : uint8_t {
/// C/C++ language and standard library types.
C = 0,
/// A zone used only for unit testing.
UnitTests = 1,
};
};
/// Template whose specializations provide the set of type IDs within a
/// given zone.
template<uint8_t Zone> struct TypeIDZoneTypes;
/// Form a type ID given a zone and type value.
constexpr uint64_t formTypeID(uint8_t zone, uint8_t type) {
return (uint64_t(zone) << 8) | uint64_t(type);
}
/// Assign the given type a particular value in the zone.
#define SWIFT_TYPEID(Zone, Type, Value) \
template<> struct TypeID<Type> { \
static const uint64_t value = formTypeID(TypeIdZones::Zone, Value); \
}
/// Assign the given single-param template a particular value in the zone.
#define SWIFT_TYPEID_TEMPLATE1(Zone, Template, Value, Param1, Arg1) \
template<Param1> struct TypeID<Template<Arg1>> { \
static const uint64_t templateID = formTypeID(TypeIdZones::Zone, Value); \
\
public: \
static const uint64_t value = (TypeID<Arg1>::value << 16) | templateID; \
}
// C types.
SWIFT_TYPEID(C, unsigned char, 1);
SWIFT_TYPEID(C, signed char, 2);
SWIFT_TYPEID(C, char, 3);
SWIFT_TYPEID(C, short, 4);
SWIFT_TYPEID(C, unsigned short, 5);
SWIFT_TYPEID(C, int, 6);
SWIFT_TYPEID(C, unsigned int, 7);
SWIFT_TYPEID(C, long, 8);
SWIFT_TYPEID(C, unsigned long, 9);
SWIFT_TYPEID(C, long long, 10);
SWIFT_TYPEID(C, unsigned long long, 11);
SWIFT_TYPEID(C, float, 12);
SWIFT_TYPEID(C, double, 13);
SWIFT_TYPEID(C, bool, 14);
SWIFT_TYPEID(C, decltype(nullptr), 15);
SWIFT_TYPEID(C, void, 16);
// C++ standard library types.
SWIFT_TYPEID_TEMPLATE1(C, std::vector, 100, typename T, T);
// Define the C type zone (zone 0).
#define SWIFT_TYPEID_ZONE 0
#define SWIFT_TYPEID_HEADER "swift/Basic/CTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
} // end namespace swift

View File

@@ -169,10 +169,11 @@ struct ExternallyCachedEvaluationRule :
: EvaluationRule{expr} { }
};
// Define the arithmetic evaluator's zone.
namespace swift {
SWIFT_TYPEID(UnitTests, UncachedEvaluationRule, 1);
SWIFT_TYPEID(UnitTests, InternallyCachedEvaluationRule, 2);
SWIFT_TYPEID(UnitTests, ExternallyCachedEvaluationRule, 3);
#define SWIFT_TYPEID_ZONE 255
#define SWIFT_TYPEID_HEADER "ArithmeticEvaluatorTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
}
TEST(ArithmeticEvaluator, Simple) {

View File

@@ -0,0 +1,19 @@
//===--- ArithmeticEvaluatorTypeIDZone.def - --------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This definition file describes the types in the "arithmetic evaluatior"
// TypeID zone, for use with the TypeID template.
//
//===----------------------------------------------------------------------===//
SWIFT_TYPEID(UncachedEvaluationRule)
SWIFT_TYPEID(InternallyCachedEvaluationRule)
SWIFT_TYPEID(ExternallyCachedEvaluationRule)