Add member template 'Type::getAs<T>', which converts a Type* to a respective T*.
This method is intended to eventually replace the individual
Type::getAsXXXType<> methods.
The motivation behind this change is twofold:
1) Reduce redundant implementations of Type::getAsXXXType() methods. Most of
them are basically copy-and-paste.
2) By centralizing the implementation of the getAs<Type> logic we can more
smoothly move over to Doug Gregor's proposed canonical type smart pointer
scheme.
Along with this patch:
a) Removed 'Type::getAsPointerType()'; now clients use getAs<PointerType>.
b) Removed 'Type::getAsBlockPointerTypE()'; now clients use getAs<BlockPointerType>.
llvm-svn: 76098
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index b43aadb..f30927c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1092,7 +1092,7 @@
return T;
if (T->isPointerType()) {
- QualType Pointee = T->getAsPointerType()->getPointeeType();
+ QualType Pointee = T->getAs<PointerType>()->getPointeeType();
if (Pointee->isAnyPointerType()) {
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
return getPointerType(ResultType);
@@ -2779,7 +2779,7 @@
return;
}
- if (const PointerType *PT = T->getAsPointerType()) {
+ if (const PointerType *PT = T->getAs<PointerType>()) {
QualType PointeeTy = PT->getPointeeType();
bool isReadOnly = false;
// For historical/compatibility reasons, the read-only qualifier of the
@@ -2794,8 +2794,8 @@
}
else if (OutermostType) {
QualType P = PointeeTy;
- while (P->getAsPointerType())
- P = P->getAsPointerType()->getPointeeType();
+ while (P->getAs<PointerType>())
+ P = P->getAs<PointerType>()->getPointeeType();
if (P.isConstQualified()) {
isReadOnly = true;
S += 'r';
@@ -3035,7 +3035,7 @@
TypedefDecl *TD = TT->getDecl();
// typedef struct objc_selector *SEL;
- const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
+ const PointerType *ptr = TD->getUnderlyingType()->getAs<PointerType>();
if (!ptr)
return;
const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
@@ -3159,7 +3159,7 @@
if (Ty->isObjCObjectPointerType())
GCAttrs = QualType::Strong;
else if (Ty->isPointerType())
- return getObjCGCAttrKind(Ty->getAsPointerType()->getPointeeType());
+ return getObjCGCAttrKind(Ty->getAs<PointerType>()->getPointeeType());
}
// Non-pointers have none gc'able attribute regardless of the attribute
// set on them.
@@ -3519,8 +3519,8 @@
case Type::Pointer:
{
// Merge two pointer types, while trying to preserve typedef info
- QualType LHSPointee = LHS->getAsPointerType()->getPointeeType();
- QualType RHSPointee = RHS->getAsPointerType()->getPointeeType();
+ QualType LHSPointee = LHS->getAs<PointerType>()->getPointeeType();
+ QualType RHSPointee = RHS->getAs<PointerType>()->getPointeeType();
QualType ResultType = mergeTypes(LHSPointee, RHSPointee);
if (ResultType.isNull()) return QualType();
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
@@ -3532,8 +3532,8 @@
case Type::BlockPointer:
{
// Merge two block pointer types, while trying to preserve typedef info
- QualType LHSPointee = LHS->getAsBlockPointerType()->getPointeeType();
- QualType RHSPointee = RHS->getAsBlockPointerType()->getPointeeType();
+ QualType LHSPointee = LHS->getAs<BlockPointerType>()->getPointeeType();
+ QualType RHSPointee = RHS->getAs<BlockPointerType>()->getPointeeType();
QualType ResultType = mergeTypes(LHSPointee, RHSPointee);
if (ResultType.isNull()) return QualType();
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 84ae729..55d39e5 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -90,7 +90,7 @@
while (!BaseType->isSpecifierType()) {
if (isa<TypedefType>(BaseType))
break;
- else if (const PointerType* PTy = BaseType->getAsPointerType())
+ else if (const PointerType* PTy = BaseType->getAs<PointerType>())
BaseType = PTy->getPointeeType();
else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
BaseType = ATy->getElementType();
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 5d22f38..74928bc 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -279,9 +279,9 @@
QualType CallExpr::getCallReturnType() const {
QualType CalleeType = getCallee()->getType();
- if (const PointerType *FnTypePtr = CalleeType->getAsPointerType())
+ if (const PointerType *FnTypePtr = CalleeType->getAs<PointerType>())
CalleeType = FnTypePtr->getPointeeType();
- else if (const BlockPointerType *BPT = CalleeType->getAsBlockPointerType())
+ else if (const BlockPointerType *BPT = CalleeType->getAs<BlockPointerType>())
CalleeType = BPT->getPointeeType();
const FunctionType *FnType = CalleeType->getAsFunctionType();
@@ -430,7 +430,7 @@
/// getFunctionType - Return the underlying function type for this block.
///
const FunctionType *BlockExpr::getFunctionType() const {
- return getType()->getAsBlockPointerType()->
+ return getType()->getAs<BlockPointerType>()->
getPointeeType()->getAsFunctionType();
}
@@ -991,7 +991,7 @@
QualType T = VD->getType();
// dereferencing to an object pointer is always a gc'able candidate
if (T->isPointerType() &&
- T->getAsPointerType()->getPointeeType()->isObjCObjectPointerType())
+ T->getAs<PointerType>()->getPointeeType()->isObjCObjectPointerType())
return true;
}
@@ -1419,7 +1419,7 @@
if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
if (!Ctx.getLangOptions().CPlusPlus) {
// Check that it is a cast to void*.
- if (const PointerType *PT = CE->getType()->getAsPointerType()) {
+ if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
QualType Pointee = PT->getPointeeType();
if (Pointee.getCVRQualifiers() == 0 &&
Pointee->isVoidType() && // to void*
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2c29347..9473e4f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -222,7 +222,7 @@
if (E->isArrow()) {
if (!EvaluatePointer(E->getBase(), result, Info))
return APValue();
- Ty = E->getBase()->getType()->getAsPointerType()->getPointeeType();
+ Ty = E->getBase()->getType()->getAs<PointerType>()->getPointeeType();
} else {
result = Visit(E->getBase());
if (result.isUninit())
@@ -351,7 +351,7 @@
if (!EvaluateInteger(IExp, AdditionalOffset, Info))
return APValue();
- QualType PointeeType = PExp->getType()->getAsPointerType()->getPointeeType();
+ QualType PointeeType = PExp->getType()->getAs<PointerType>()->getPointeeType();
uint64_t SizeOfPointee;
// Explicitly handle GNU void* and function pointer arithmetic extensions.
@@ -1029,7 +1029,7 @@
if (E->getOpcode() == BinaryOperator::Sub) {
const QualType Type = E->getLHS()->getType();
- const QualType ElementType = Type->getAsPointerType()->getPointeeType();
+ const QualType ElementType = Type->getAs<PointerType>()->getPointeeType();
uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
if (!ElementType->isVoidType() && !ElementType->isFunctionType())
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 18fa76b..13d0cb0 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -202,7 +202,7 @@
return false;
}
bool Type::isVoidPointerType() const {
- if (const PointerType *PT = getAsPointerType())
+ if (const PointerType *PT = getAs<PointerType>())
return PT->getPointeeType()->isVoidType();
return false;
}
@@ -296,51 +296,15 @@
}
QualType Type::getPointeeType() const {
- if (const PointerType *PT = getAsPointerType())
+ if (const PointerType *PT = getAs<PointerType>())
return PT->getPointeeType();
if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
return OPT->getPointeeType();
- if (const BlockPointerType *BPT = getAsBlockPointerType())
+ if (const BlockPointerType *BPT = getAs<BlockPointerType>())
return BPT->getPointeeType();
return QualType();
}
-const PointerType *Type::getAsPointerType() const {
- // If this is directly a pointer type, return it.
- if (const PointerType *PTy = dyn_cast<PointerType>(this))
- return PTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<PointerType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<PointerType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsPointerType();
- return 0;
- }
-
- // If this is a typedef for a pointer type, strip the typedef off without
- // losing all typedef information.
- return cast<PointerType>(getDesugaredType());
-}
-
-const BlockPointerType *Type::getAsBlockPointerType() const {
- // If this is directly a block pointer type, return it.
- if (const BlockPointerType *PTy = dyn_cast<BlockPointerType>(this))
- return PTy;
-
- // If the canonical form of this type isn't the right kind, reject it.
- if (!isa<BlockPointerType>(CanonicalType)) {
- // Look through type qualifiers
- if (isa<BlockPointerType>(CanonicalType.getUnqualifiedType()))
- return CanonicalType.getUnqualifiedType()->getAsBlockPointerType();
- return 0;
- }
-
- // If this is a typedef for a block pointer type, strip the typedef off
- // without losing all typedef information.
- return cast<BlockPointerType>(getDesugaredType());
-}
-
const ReferenceType *Type::getAsReferenceType() const {
// If this is directly a reference type, return it.
if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
@@ -429,7 +393,7 @@
// Also, C++ references and member pointers can point to a variably modified
// type, where VLAs appear as an extension to C++, and should be treated
// correctly.
- if (const PointerType *PT = getAsPointerType())
+ if (const PointerType *PT = getAs<PointerType>())
return PT->getPointeeType()->isVariablyModifiedType();
if (const ReferenceType *RT = getAsReferenceType())
return RT->getPointeeType()->isVariablyModifiedType();