Skip to content

Commit 63542d5

Browse files
committed
meat and potatoes
1 parent b90f4ff commit 63542d5

File tree

8 files changed

+61
-47
lines changed

8 files changed

+61
-47
lines changed

clang/include/clang/AST/Type.h

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2929,8 +2929,31 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
29292929
///
29302930
/// There are some specializations of this member template listed
29312931
/// immediately following this class.
2932+
///
2933+
/// If you are interested only in the canonical properties of this type,
2934+
/// consider using getAsCanonical instead, as that is much faster.
29322935
template <typename T> const T *getAs() const;
29332936

2937+
/// If this type is canonically the specified type, return its canonical type
2938+
/// cast to that specified type, otherwise returns null.
2939+
template <typename T> const T *getAsCanonical() const {
2940+
return dyn_cast<T>(CanonicalType);
2941+
}
2942+
2943+
/// Return this type's canonical type cast to the specified type.
2944+
/// If the type is not canonically that specified type, the behaviour is
2945+
/// undefined.
2946+
template <typename T> const T *castAsCanonical() const {
2947+
return cast<T>(CanonicalType);
2948+
}
2949+
2950+
// It is not helpful to use these on types which are never canonical
2951+
#define TYPE(Class, Base)
2952+
#define NEVER_CANONICAL_TYPE(Class) \
2953+
template <> inline const Class##Type *Type::getAsCanonical() const = delete; \
2954+
template <> inline const Class##Type *Type::castAsCanonical() const = delete;
2955+
#include "clang/AST/TypeNodes.inc"
2956+
29342957
/// Look through sugar for an instance of TemplateSpecializationType which
29352958
/// is not a type alias, or null if there is no such type.
29362959
/// This is used when you want as-written template arguments or the template
@@ -3142,16 +3165,16 @@ template <> const BoundsAttributedType *Type::getAs() const;
31423165
/// sugar until it reaches an CountAttributedType or a non-sugared type.
31433166
template <> const CountAttributedType *Type::getAs() const;
31443167

3145-
// We can do canonical leaf types faster, because we don't have to
3146-
// worry about preserving child type decoration.
3168+
// We can do always canonical types faster, because we don't have to
3169+
// worry about preserving decoration.
31473170
#define TYPE(Class, Base)
3148-
#define LEAF_TYPE(Class) \
3149-
template <> inline const Class##Type *Type::getAs() const { \
3150-
return dyn_cast<Class##Type>(CanonicalType); \
3151-
} \
3152-
template <> inline const Class##Type *Type::castAs() const { \
3153-
return cast<Class##Type>(CanonicalType); \
3154-
}
3171+
#define ALWAYS_CANONICAL_TYPE(Class) \
3172+
template <> inline const Class##Type *Type::getAs() const { \
3173+
return dyn_cast<Class##Type>(CanonicalType); \
3174+
} \
3175+
template <> inline const Class##Type *Type::castAs() const { \
3176+
return cast<Class##Type>(CanonicalType); \
3177+
}
31553178
#include "clang/AST/TypeNodes.inc"
31563179

31573180
/// This class is used for builtin types like 'int'. Builtin

clang/include/clang/Basic/TypeNodes.td

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,12 @@ class NeverCanonical {}
3737
/// canonical types can ignore these nodes.
3838
class NeverCanonicalUnlessDependent {}
3939

40-
/// A type node which never has component type structure. Some code may be
41-
/// able to operate on leaf types faster than they can on non-leaf types.
42-
///
43-
/// For example, the function type `void (int)` is not a leaf type because it
44-
/// is structurally composed of component types (`void` and `int`).
45-
///
46-
/// A struct type is a leaf type because its field types are not part of its
47-
/// type-expression.
48-
///
49-
/// Nodes like `TypedefType` which are syntactically leaves but can desugar
50-
/// to types that may not be leaves should not declare this.
51-
class LeafType {}
40+
/// A type node which is always a canonical type, that is, types for which
41+
/// `T.getCanonicalType() == T` always holds.
42+
class AlwaysCanonical {}
5243

5344
def Type : TypeNode<?, 1>;
54-
def BuiltinType : TypeNode<Type>, LeafType;
45+
def BuiltinType : TypeNode<Type>, AlwaysCanonical;
5546
def ComplexType : TypeNode<Type>;
5647
def PointerType : TypeNode<Type>;
5748
def BlockPointerType : TypeNode<Type>;
@@ -88,14 +79,14 @@ def TypeOfType : TypeNode<Type>, NeverCanonicalUnlessDependent;
8879
def DecltypeType : TypeNode<Type>, NeverCanonicalUnlessDependent;
8980
def UnaryTransformType : TypeNode<Type>, NeverCanonicalUnlessDependent;
9081
def TagType : TypeNode<Type, 1>;
91-
def RecordType : TypeNode<TagType>, LeafType;
92-
def EnumType : TypeNode<TagType>, LeafType;
93-
def InjectedClassNameType : TypeNode<TagType>, AlwaysDependent, LeafType;
82+
def RecordType : TypeNode<TagType>;
83+
def EnumType : TypeNode<TagType>;
84+
def InjectedClassNameType : TypeNode<TagType>, AlwaysDependent;
9485
def AttributedType : TypeNode<Type>, NeverCanonical;
9586
def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
9687
def HLSLAttributedResourceType : TypeNode<Type>;
9788
def HLSLInlineSpirvType : TypeNode<Type>;
98-
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
89+
def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent;
9990
def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
10091
def SubstPackType : TypeNode<Type, 1>;
10192
def SubstTemplateTypeParmPackType : TypeNode<SubstPackType>, AlwaysDependent;
@@ -110,7 +101,7 @@ def PackExpansionType : TypeNode<Type>, AlwaysDependent;
110101
def PackIndexingType : TypeNode<Type>, NeverCanonicalUnlessDependent;
111102
def ObjCTypeParamType : TypeNode<Type>, NeverCanonical;
112103
def ObjCObjectType : TypeNode<Type>;
113-
def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType;
104+
def ObjCInterfaceType : TypeNode<ObjCObjectType>, AlwaysCanonical;
114105
def ObjCObjectPointerType : TypeNode<Type>;
115106
def BoundsAttributedType : TypeNode<Type, 1>;
116107
def CountAttributedType : TypeNode<BoundsAttributedType>, NeverCanonical;

clang/lib/AST/Type.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -704,10 +704,8 @@ bool Type::isInterfaceType() const {
704704
}
705705

706706
bool Type::isStructureOrClassType() const {
707-
if (const auto *RT = getAs<RecordType>()) {
708-
RecordDecl *RD = RT->getOriginalDecl();
709-
return RD->isStruct() || RD->isClass() || RD->isInterface();
710-
}
707+
if (const auto *RT = getAsCanonical<RecordType>())
708+
return RT->getOriginalDecl()->isStructureOrClass();
711709
return false;
712710
}
713711

clang/test/CXX/drs/cwg0xx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ namespace cwg16 { // cwg16: 2.8
244244
// expected-error@#cwg16-A-f-call {{'A' is a private member of 'cwg16::A'}}
245245
// expected-note@#cwg16-B {{constrained by implicitly private inheritance here}}
246246
// expected-note@#cwg16-A {{member is declared here}}
247-
// expected-error@#cwg16-A-f-call {{cannot cast 'cwg16::C' to its private base class 'cwg16::A'}}
247+
// expected-error@#cwg16-A-f-call {{cannot cast 'cwg16::C' to its private base class 'A'}}
248248
// expected-note@#cwg16-B {{implicitly declared private here}}
249249
}
250250
};
@@ -838,7 +838,7 @@ namespace cwg52 { // cwg52: 2.8
838838
// expected-error@#cwg52-k {{'A' is a private member of 'cwg52::A'}}
839839
// expected-note@#cwg52-B {{constrained by private inheritance here}}
840840
// expected-note@#cwg52-A {{member is declared here}}
841-
// expected-error@#cwg52-k {{cannot cast 'struct B' to its private base class 'cwg52::A'}}
841+
// expected-error@#cwg52-k {{cannot cast 'struct B' to its private base class 'A'}}
842842
// expected-note@#cwg52-B {{declared private here}}
843843
} // namespace cwg52
844844

clang/test/CXX/drs/cwg3xx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1321,7 +1321,7 @@ namespace cwg381 { // cwg381: 2.7
13211321
void f() {
13221322
E e;
13231323
e.B::a = 0;
1324-
/* expected-error@-1 {{ambiguous conversion from derived class 'E' to base class 'cwg381::B':
1324+
/* expected-error@-1 {{ambiguous conversion from derived class 'E' to base class 'B':
13251325
struct cwg381::E -> C -> B
13261326
struct cwg381::E -> D -> B}} */
13271327
F f;

clang/test/ExtractAPI/class_template_param_inheritance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ template<typename T> class Foo : public T {};
4444
{
4545
"kind": "inheritsFrom",
4646
"source": "c:@ST>1#T@Foo",
47-
"target": "",
47+
"target": "c:input.h@9",
4848
"targetFallback": "T"
4949
}
5050
],

clang/utils/TableGen/ASTTableGen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
#define AlwaysDependentClassName "AlwaysDependent"
3939
#define NeverCanonicalClassName "NeverCanonical"
4040
#define NeverCanonicalUnlessDependentClassName "NeverCanonicalUnlessDependent"
41-
#define LeafTypeClassName "LeafType"
41+
#define AlwaysCanonicalTypeClassName "AlwaysCanonical"
4242

4343
// Cases of various non-ASTNode structured types like DeclarationName.
4444
#define TypeKindClassName "PropertyTypeKind"

clang/utils/TableGen/ClangTypeNodesEmitter.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@
4040
// There is a sixth macro, independent of the others. Most clients
4141
// will not need to use it.
4242
//
43-
// LEAF_TYPE(Class) - A type that never has inner types. Clients
44-
// which can operate on such types more efficiently may wish to do so.
43+
// ALWAYS_CANONICAL_TYPE(Class) - A type which is always identical to its
44+
// canonical type. Clients which can operate on such types more efficiently
45+
// may wish to do so.
4546
//
4647
//===----------------------------------------------------------------------===//
4748

@@ -66,7 +67,7 @@ using namespace clang::tblgen;
6667
#define NonCanonicalUnlessDependentTypeMacroName "NON_CANONICAL_UNLESS_DEPENDENT_TYPE"
6768
#define TypeMacroArgs "(Class, Base)"
6869
#define LastTypeMacroName "LAST_TYPE"
69-
#define LeafTypeMacroName "LEAF_TYPE"
70+
#define AlwaysCanonicalTypeMacroName "ALWAYS_CANONICAL_TYPE"
7071

7172
#define TypeClassName "Type"
7273

@@ -90,7 +91,7 @@ class TypeNodeEmitter {
9091

9192
void emitNodeInvocations();
9293
void emitLastNodeInvocation(TypeNode lastType);
93-
void emitLeafNodeInvocations();
94+
void emitAlwaysCanonicalNodeInvocations();
9495

9596
void addMacroToUndef(StringRef macroName);
9697
void emitUndefs();
@@ -109,12 +110,12 @@ void TypeNodeEmitter::emit() {
109110
emitFallbackDefine(AbstractTypeMacroName, TypeMacroName, TypeMacroArgs);
110111
emitFallbackDefine(NonCanonicalTypeMacroName, TypeMacroName, TypeMacroArgs);
111112
emitFallbackDefine(DependentTypeMacroName, TypeMacroName, TypeMacroArgs);
112-
emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
113+
emitFallbackDefine(NonCanonicalUnlessDependentTypeMacroName, TypeMacroName,
113114
TypeMacroArgs);
114115

115116
// Invocations.
116117
emitNodeInvocations();
117-
emitLeafNodeInvocations();
118+
emitAlwaysCanonicalNodeInvocations();
118119

119120
// Postmatter
120121
emitUndefs();
@@ -178,15 +179,16 @@ void TypeNodeEmitter::emitLastNodeInvocation(TypeNode type) {
178179
"#endif\n";
179180
}
180181

181-
void TypeNodeEmitter::emitLeafNodeInvocations() {
182-
Out << "#ifdef " LeafTypeMacroName "\n";
182+
void TypeNodeEmitter::emitAlwaysCanonicalNodeInvocations() {
183+
Out << "#ifdef " AlwaysCanonicalTypeMacroName "\n";
183184

184185
for (TypeNode type : Types) {
185-
if (!type.isSubClassOf(LeafTypeClassName)) continue;
186-
Out << LeafTypeMacroName "(" << type.getId() << ")\n";
186+
if (!type.isSubClassOf(AlwaysCanonicalTypeClassName))
187+
continue;
188+
Out << AlwaysCanonicalTypeMacroName "(" << type.getId() << ")\n";
187189
}
188190

189-
Out << "#undef " LeafTypeMacroName "\n"
191+
Out << "#undef " AlwaysCanonicalTypeMacroName "\n"
190192
"#endif\n";
191193
}
192194

0 commit comments

Comments
 (0)