Skip to content

Commit

Permalink
Emit TypeNodes.def with tblgen.
Browse files Browse the repository at this point in the history
The primary goal here is to make the type node hierarchy available to
other tblgen backends, although it should also make it easier to generate
more selective x-macros in the future.

Because tblgen doesn't seem to allow backends to preserve the source
order of defs, this is not NFC because it significantly re-orders IDs.
I've fixed the one (fortunately obvious) place where we relied on
the old order.  Unfortunately, I wasn't able to share code with the
existing AST-node x-macro generators because the x-macro schema we use
for types is different in a number of ways.  The main loss is that
subclasses aren't ordered together, which doesn't seem important for
types because the hierarchy is generally very shallow with little
clustering.

llvm-svn: 373407
  • Loading branch information
rjmccall committed Oct 1, 2019
1 parent c45f8d4 commit a82d2fe
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 138 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ clang_tablegen(DeclNodes.inc -gen-clang-decl-nodes
SOURCE ../Basic/DeclNodes.td
TARGET ClangDeclNodes)

clang_tablegen(TypeNodes.def -gen-clang-type-nodes
SOURCE ../Basic/TypeNodes.td
TARGET ClangTypeNodes)

clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes
SOURCE ../Basic/CommentNodes.td
TARGET ClangCommentNodes)
Expand Down
5 changes: 2 additions & 3 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1437,10 +1437,9 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
public:
enum TypeClass {
#define TYPE(Class, Base) Class,
#define LAST_TYPE(Class) TypeLast = Class,
#define LAST_TYPE(Class) TypeLast = Class
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
TagFirst = Record, TagLast = Enum
};

private:
Expand Down Expand Up @@ -4436,7 +4435,7 @@ class TagType : public Type {
bool isBeingDefined() const;

static bool classof(const Type *T) {
return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast;
return T->getTypeClass() == Enum || T->getTypeClass() == Record;
}
};

Expand Down
135 changes: 0 additions & 135 deletions clang/include/clang/AST/TypeNodes.def

This file was deleted.

106 changes: 106 additions & 0 deletions clang/include/clang/Basic/TypeNodes.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
class Type<bit abstract = 0> {
bit Abstract = abstract;
}

class DerivedType<Type base, bit abstract = 0> : Type<abstract> {
Type Base = base;
}

/// A type node that is only used to represent dependent types in C++. For
/// example, DependentTemplateSpecializationType is used to represent types
/// where the base template-id is dependent (such as `T::foo<U>`). Code
/// that only works with non-dependent types can ignore these type nodes.
class AlwaysDependent {}

/// A type node that is never used to represent a canonical type, which is to
/// say that it always represents some sort of type "sugar" which can
/// (supposedly) be erased without affecting the formal behavior of the
/// language. For example, in standard C/C++, typedefs do not introduce new
/// types and do not affect the semantics of the program. Code that only
/// works with canonical types can ignore these type nodes.
///
/// Note that this simple story about non-canonical types is not the whole
/// truth. Languages and extensions often have formation rules which differ
/// based on how a type is spelled and which therefore are not consistent
/// with immediately stipping away type sugar. More critically, attributes on
/// typedefs can have semantic impacts in ways that are only reflected in our
/// AST by preserving the typedef sugar; for example, we do not otherwise
/// represent the alignment attribute on typedefs, and so it is necessary to
/// preserve typedef structure into most parts of IR generation.
class NeverCanonical {}

/// A type node that only represents a canonical type in some dependent cases.
/// For example, `std::vector<int>` (a TemplateSpecializationType) is
/// considered to be a non-canonical representation for the RecordType
/// referencing the concrete ClassTemplateSpecializationDecl; but
/// `std::vector<T>` cannot be resolved to a concrete specialization
/// and so remains canonical. Code which only works with non-dependent
/// canonical types can ignore these nodes.
class NeverCanonicalUnlessDependent {}

/// A type node which never has component type structure. Some code may be
/// able to operate on leaf types faster than they can on non-leaf types.
///
/// For example, the function type `void (int)` is not a leaf type because it
/// is structurally composed of component types (`void` and `int`).
///
/// A struct type is a leaf type because its field types are not part of its
/// type-expression.
///
/// Nodes like `TypedefType` which are syntactically leaves but can desugar
/// to types that may not be leaves should not declare this.
class LeafType {}

def BuiltinType : Type, LeafType;
def ComplexType : Type;
def PointerType : Type;
def BlockPointerType : Type;
def ReferenceType : Type<1>;
def LValueReferenceType : DerivedType<ReferenceType>;
def RValueReferenceType : DerivedType<ReferenceType>;
def MemberPointerType : Type;
def ArrayType : Type<1>;
def ConstantArrayType : DerivedType<ArrayType>;
def IncompleteArrayType : DerivedType<ArrayType>;
def VariableArrayType : DerivedType<ArrayType>;
def DependentSizedArrayType : DerivedType<ArrayType>, AlwaysDependent;
def DependentSizedExtVectorType : Type, AlwaysDependent;
def DependentAddressSpaceType : Type, AlwaysDependent;
def VectorType : Type;
def DependentVectorType : Type, AlwaysDependent;
def ExtVectorType : DerivedType<VectorType>;
def FunctionType : Type<1>;
def FunctionProtoType : DerivedType<FunctionType>;
def FunctionNoProtoType : DerivedType<FunctionType>;
def UnresolvedUsingType : Type, AlwaysDependent;
def ParenType : Type, NeverCanonical;
def TypedefType : Type, NeverCanonical;
def MacroQualifiedType : Type, NeverCanonical;
def AdjustedType : Type, NeverCanonical;
def DecayedType : DerivedType<AdjustedType>, NeverCanonical;
def TypeOfExprType : Type, NeverCanonicalUnlessDependent;
def TypeOfType : Type, NeverCanonicalUnlessDependent;
def DecltypeType : Type, NeverCanonicalUnlessDependent;
def UnaryTransformType : Type, NeverCanonicalUnlessDependent;
def TagType : Type<1>;
def RecordType : DerivedType<TagType>, LeafType;
def EnumType : DerivedType<TagType>, LeafType;
def ElaboratedType : Type, NeverCanonical;
def AttributedType : Type, NeverCanonical;
def TemplateTypeParmType : Type, AlwaysDependent, LeafType;
def SubstTemplateTypeParmType : Type, NeverCanonical;
def SubstTemplateTypeParmPackType : Type, AlwaysDependent;
def TemplateSpecializationType : Type, NeverCanonicalUnlessDependent;
def DeducedType : Type<1>;
def AutoType : DerivedType<DeducedType>;
def DeducedTemplateSpecializationType : DerivedType<DeducedType>;
def InjectedClassNameType : Type, AlwaysDependent, LeafType;
def DependentNameType : Type, AlwaysDependent;
def DependentTemplateSpecializationType : Type, AlwaysDependent;
def PackExpansionType : Type, NeverCanonicalUnlessDependent;
def ObjCTypeParamType : Type, NeverCanonical;
def ObjCObjectType : Type;
def ObjCInterfaceType : DerivedType<ObjCObjectType>, LeafType;
def ObjCObjectPointerType : Type;
def PipeType : Type;
def AtomicType : Type;
1 change: 1 addition & 0 deletions clang/utils/TableGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ add_tablegen(clang-tblgen CLANG
ClangOpenCLBuiltinEmitter.cpp
ClangOptionDocEmitter.cpp
ClangSACheckersEmitter.cpp
ClangTypeNodesEmitter.cpp
NeonEmitter.cpp
TableGen.cpp
)
Expand Down
Loading

0 comments on commit a82d2fe

Please sign in to comment.