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:
Daniel Dunbar 2012-03-06 18:20:20 +00:00
parent f0fd55e631
commit 492488271f
3 changed files with 67 additions and 53 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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()) {