forked from OSchip/llvm-project
AST: Move several Type::is...Type() functions to be inline.
- These functions are both (a) very commonly called and (b) excellent candidates for CSE in the callers in which they are commonly used. - That isHalfType() is hot makes me sad, but it is trivially when inlined (and a huge waste of time when not!!!). - The extra IsEnumDeclComplete() function is a hack to break the cycle between Type.h and Decl.h, I'm not sure of how to do this more cleanly, but am open to ideas. llvm-svn: 152126
This commit is contained in:
parent
f0fd55e631
commit
492488271f
|
@ -3273,6 +3273,16 @@ void Redeclarable<decl_type>::setPreviousDeclaration(decl_type *PrevDecl) {
|
|||
ND->ClearLinkageCache();
|
||||
}
|
||||
|
||||
// Inline function definitions.
|
||||
|
||||
/// \brief Check if the given decl is complete.
|
||||
///
|
||||
/// We use this function to break a cycle between the inline definitions in
|
||||
/// Type.h and Decl.h.
|
||||
inline bool IsEnumDeclComplete(EnumDecl *ED) {
|
||||
return ED->isComplete();
|
||||
}
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4816,6 +4816,55 @@ inline bool Type::isNonOverloadPlaceholderType() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
inline bool Type::isHalfType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() == BuiltinType::Half;
|
||||
// FIXME: Should we allow complex __fp16? Probably not.
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Type::isNullPtrType() const {
|
||||
if (const BuiltinType *BT = getAs<BuiltinType>())
|
||||
return BT->getKind() == BuiltinType::NullPtr;
|
||||
return false;
|
||||
}
|
||||
|
||||
extern bool IsEnumDeclComplete(EnumDecl *);
|
||||
|
||||
inline bool Type::isScalarType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() > BuiltinType::Void &&
|
||||
BT->getKind() <= BuiltinType::NullPtr;
|
||||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
// Enums are scalar types, but only if they are defined. Incomplete enums
|
||||
// are not treated as scalar types.
|
||||
return IsEnumDeclComplete(ET->getDecl());
|
||||
return isa<PointerType>(CanonicalType) ||
|
||||
isa<BlockPointerType>(CanonicalType) ||
|
||||
isa<MemberPointerType>(CanonicalType) ||
|
||||
isa<ComplexType>(CanonicalType) ||
|
||||
isa<ObjCObjectPointerType>(CanonicalType);
|
||||
}
|
||||
|
||||
inline bool Type::isIntegralOrEnumerationType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::Int128;
|
||||
|
||||
// Check for a complete enum type; incomplete enum types are not properly an
|
||||
// enumeration type in the sense required here.
|
||||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return IsEnumDeclComplete(ET->getDecl());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Type::isBooleanType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() == BuiltinType::Bool;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Determines whether this is a type for which one can define
|
||||
/// an overloaded operator.
|
||||
inline bool Type::isOverloadableType() const {
|
||||
|
|
|
@ -556,17 +556,6 @@ AutoType *Type::getContainedAutoType() const {
|
|||
return GetContainedAutoVisitor().Visit(this);
|
||||
}
|
||||
|
||||
bool Type::isIntegerType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::Int128;
|
||||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
// Incomplete enum types are not treated as integer types.
|
||||
// FIXME: In C++, enum types are never integer types.
|
||||
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::hasIntegerRepresentation() const {
|
||||
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
|
||||
return VT->getElementType()->isIntegerType();
|
||||
|
@ -605,18 +594,6 @@ bool Type::isIntegralType(ASTContext &Ctx) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Type::isIntegralOrEnumerationType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::Int128;
|
||||
|
||||
// Check for a complete enum type; incomplete enum types are not properly an
|
||||
// enumeration type in the sense required here.
|
||||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->isComplete();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::isIntegralOrUnscopedEnumerationType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
|
@ -634,9 +611,15 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
|
|||
}
|
||||
|
||||
|
||||
bool Type::isBooleanType() const {
|
||||
|
||||
bool Type::isIntegerType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() == BuiltinType::Bool;
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
BT->getKind() <= BuiltinType::Int128;
|
||||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
// Incomplete enum types are not treated as integer types.
|
||||
// FIXME: In C++, enum types are never integer types.
|
||||
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -767,13 +750,6 @@ bool Type::hasUnsignedIntegerRepresentation() const {
|
|||
return isUnsignedIntegerType();
|
||||
}
|
||||
|
||||
bool Type::isHalfType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() == BuiltinType::Half;
|
||||
// FIXME: Should we allow complex __fp16? Probably not.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::isFloatingType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() >= BuiltinType::Half &&
|
||||
|
@ -820,21 +796,6 @@ bool Type::isArithmeticType() const {
|
|||
return isa<ComplexType>(CanonicalType);
|
||||
}
|
||||
|
||||
bool Type::isScalarType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() > BuiltinType::Void &&
|
||||
BT->getKind() <= BuiltinType::NullPtr;
|
||||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
// Enums are scalar types, but only if they are defined. Incomplete enums
|
||||
// are not treated as scalar types.
|
||||
return ET->getDecl()->isComplete();
|
||||
return isa<PointerType>(CanonicalType) ||
|
||||
isa<BlockPointerType>(CanonicalType) ||
|
||||
isa<MemberPointerType>(CanonicalType) ||
|
||||
isa<ComplexType>(CanonicalType) ||
|
||||
isa<ObjCObjectPointerType>(CanonicalType);
|
||||
}
|
||||
|
||||
Type::ScalarTypeKind Type::getScalarTypeKind() const {
|
||||
assert(isScalarType());
|
||||
|
||||
|
@ -1312,12 +1273,6 @@ bool Type::isPromotableIntegerType() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Type::isNullPtrType() const {
|
||||
if (const BuiltinType *BT = getAs<BuiltinType>())
|
||||
return BT->getKind() == BuiltinType::NullPtr;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::isSpecifierType() const {
|
||||
// Note that this intentionally does not use the canonical type.
|
||||
switch (getTypeClass()) {
|
||||
|
|
Loading…
Reference in New Issue