r241550 - Factor the simpleTransform() visitor so that it is not a local class.
Douglas Gregor
dgregor at apple.com
Mon Jul 6 20:58:59 PDT 2015
Author: dgregor
Date: Mon Jul 6 22:58:59 2015
New Revision: 241550
URL: http://llvm.org/viewvc/llvm-project?rev=241550&view=rev
Log:
Factor the simpleTransform() visitor so that it is not a local class.
Older versions of Clang cannot handle such local classes properly
rdar://problem/19386032.
Modified:
cfe/trunk/lib/AST/Type.cpp
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=241550&r1=241549&r2=241550&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Jul 6 22:58:59 2015
@@ -629,390 +629,396 @@ const ObjCObjectPointerType *ObjCObjectP
namespace {
-/// Perform a simple type transformation that does not change the
-/// semantics of the type.
template<typename F>
-QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {
- struct Visitor : public TypeVisitor<Visitor, QualType> {
- ASTContext &Ctx;
- F &&TheFunc;
+QualType simpleTransform(ASTContext &ctx, QualType type, F &&f);
- QualType recurse(QualType type) {
- return simpleTransform(Ctx, type, std::move(TheFunc));
- }
+/// Visitor used by simpleTransform() to perform the transformation.
+template<typename F>
+struct SimpleTransformVisitor
+ : public TypeVisitor<SimpleTransformVisitor<F>, QualType> {
+ ASTContext &Ctx;
+ F &&TheFunc;
+
+ QualType recurse(QualType type) {
+ return simpleTransform(Ctx, type, std::move(TheFunc));
+ }
- public:
- Visitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { }
+public:
+ SimpleTransformVisitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { }
- // None of the clients of this transformation can occur where
- // there are dependent types, so skip dependent types.
+ // None of the clients of this transformation can occur where
+ // there are dependent types, so skip dependent types.
#define TYPE(Class, Base)
#define DEPENDENT_TYPE(Class, Base) \
- QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
+ QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
#include "clang/AST/TypeNodes.def"
#define TRIVIAL_TYPE_CLASS(Class) \
- QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
-
- TRIVIAL_TYPE_CLASS(Builtin)
-
- QualType VisitComplexType(const ComplexType *T) {
- QualType elementType = recurse(T->getElementType());
- if (elementType.isNull())
- return QualType();
-
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getComplexType(elementType);
- }
-
- QualType VisitPointerType(const PointerType *T) {
- QualType pointeeType = recurse(T->getPointeeType());
- if (pointeeType.isNull())
- return QualType();
-
- if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getPointerType(pointeeType);
- }
-
- QualType VisitBlockPointerType(const BlockPointerType *T) {
- QualType pointeeType = recurse(T->getPointeeType());
- if (pointeeType.isNull())
- return QualType();
-
- if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getBlockPointerType(pointeeType);
- }
-
- QualType VisitLValueReferenceType(const LValueReferenceType *T) {
- QualType pointeeType = recurse(T->getPointeeTypeAsWritten());
- if (pointeeType.isNull())
- return QualType();
+ QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }
- if (pointeeType.getAsOpaquePtr()
- == T->getPointeeTypeAsWritten().getAsOpaquePtr())
- return QualType(T, 0);
+ TRIVIAL_TYPE_CLASS(Builtin)
- return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue());
- }
+ QualType VisitComplexType(const ComplexType *T) {
+ QualType elementType = recurse(T->getElementType());
+ if (elementType.isNull())
+ return QualType();
- QualType VisitRValueReferenceType(const RValueReferenceType *T) {
- QualType pointeeType = recurse(T->getPointeeTypeAsWritten());
- if (pointeeType.isNull())
- return QualType();
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (pointeeType.getAsOpaquePtr()
- == T->getPointeeTypeAsWritten().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getComplexType(elementType);
+ }
- return Ctx.getRValueReferenceType(pointeeType);
- }
+ QualType VisitPointerType(const PointerType *T) {
+ QualType pointeeType = recurse(T->getPointeeType());
+ if (pointeeType.isNull())
+ return QualType();
- QualType VisitMemberPointerType(const MemberPointerType *T) {
- QualType pointeeType = recurse(T->getPointeeType());
- if (pointeeType.isNull())
- return QualType();
+ if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getPointerType(pointeeType);
+ }
- return Ctx.getMemberPointerType(pointeeType, T->getClass());
- }
+ QualType VisitBlockPointerType(const BlockPointerType *T) {
+ QualType pointeeType = recurse(T->getPointeeType());
+ if (pointeeType.isNull())
+ return QualType();
- QualType VisitConstantArrayType(const ConstantArrayType *T) {
- QualType elementType = recurse(T->getElementType());
- if (elementType.isNull())
- return QualType();
+ if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getBlockPointerType(pointeeType);
+ }
- return Ctx.getConstantArrayType(elementType, T->getSize(),
- T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers());
- }
+ QualType VisitLValueReferenceType(const LValueReferenceType *T) {
+ QualType pointeeType = recurse(T->getPointeeTypeAsWritten());
+ if (pointeeType.isNull())
+ return QualType();
- QualType VisitVariableArrayType(const VariableArrayType *T) {
- QualType elementType = recurse(T->getElementType());
- if (elementType.isNull())
- return QualType();
+ if (pointeeType.getAsOpaquePtr()
+ == T->getPointeeTypeAsWritten().getAsOpaquePtr())
+ return QualType(T, 0);
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue());
+ }
- return Ctx.getVariableArrayType(elementType, T->getSizeExpr(),
- T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers(),
- T->getBracketsRange());
- }
+ QualType VisitRValueReferenceType(const RValueReferenceType *T) {
+ QualType pointeeType = recurse(T->getPointeeTypeAsWritten());
+ if (pointeeType.isNull())
+ return QualType();
- QualType VisitIncompleteArrayType(const IncompleteArrayType *T) {
- QualType elementType = recurse(T->getElementType());
- if (elementType.isNull())
- return QualType();
+ if (pointeeType.getAsOpaquePtr()
+ == T->getPointeeTypeAsWritten().getAsOpaquePtr())
+ return QualType(T, 0);
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getRValueReferenceType(pointeeType);
+ }
- return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers());
- }
+ QualType VisitMemberPointerType(const MemberPointerType *T) {
+ QualType pointeeType = recurse(T->getPointeeType());
+ if (pointeeType.isNull())
+ return QualType();
- QualType VisitVectorType(const VectorType *T) {
- QualType elementType = recurse(T->getElementType());
- if (elementType.isNull())
- return QualType();
+ if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getMemberPointerType(pointeeType, T->getClass());
+ }
- return Ctx.getVectorType(elementType, T->getNumElements(),
- T->getVectorKind());
- }
+ QualType VisitConstantArrayType(const ConstantArrayType *T) {
+ QualType elementType = recurse(T->getElementType());
+ if (elementType.isNull())
+ return QualType();
- QualType VisitExtVectorType(const ExtVectorType *T) {
- QualType elementType = recurse(T->getElementType());
- if (elementType.isNull())
- return QualType();
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getConstantArrayType(elementType, T->getSize(),
+ T->getSizeModifier(),
+ T->getIndexTypeCVRQualifiers());
+ }
- return Ctx.getExtVectorType(elementType, T->getNumElements());
- }
+ QualType VisitVariableArrayType(const VariableArrayType *T) {
+ QualType elementType = recurse(T->getElementType());
+ if (elementType.isNull())
+ return QualType();
- QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
- QualType returnType = recurse(T->getReturnType());
- if (returnType.isNull())
- return QualType();
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr())
- return QualType(T, 0);
+ return Ctx.getVariableArrayType(elementType, T->getSizeExpr(),
+ T->getSizeModifier(),
+ T->getIndexTypeCVRQualifiers(),
+ T->getBracketsRange());
+ }
- return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo());
- }
+ QualType VisitIncompleteArrayType(const IncompleteArrayType *T) {
+ QualType elementType = recurse(T->getElementType());
+ if (elementType.isNull())
+ return QualType();
- QualType VisitFunctionProtoType(const FunctionProtoType *T) {
- QualType returnType = recurse(T->getReturnType());
- if (returnType.isNull())
- return QualType();
-
- // Transform parameter types.
- SmallVector<QualType, 4> paramTypes;
- bool paramChanged = false;
- for (auto paramType : T->getParamTypes()) {
- QualType newParamType = recurse(paramType);
- if (newParamType.isNull())
- return QualType();
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr())
- paramChanged = true;
-
- paramTypes.push_back(newParamType);
- }
+ return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(),
+ T->getIndexTypeCVRQualifiers());
+ }
- // Transform extended info.
- FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo();
- bool exceptionChanged = false;
- if (info.ExceptionSpec.Type == EST_Dynamic) {
- SmallVector<QualType, 4> exceptionTypes;
- for (auto exceptionType : info.ExceptionSpec.Exceptions) {
- QualType newExceptionType = recurse(exceptionType);
- if (newExceptionType.isNull())
- return QualType();
-
- if (newExceptionType.getAsOpaquePtr()
- != exceptionType.getAsOpaquePtr())
- exceptionChanged = true;
-
- exceptionTypes.push_back(newExceptionType);
- }
-
- if (exceptionChanged) {
- unsigned size = sizeof(QualType) * exceptionTypes.size();
- void *mem = Ctx.Allocate(size, llvm::alignOf<QualType>());
- memcpy(mem, exceptionTypes.data(), size);
- info.ExceptionSpec.Exceptions
- = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size());
- }
- }
+ QualType VisitVectorType(const VectorType *T) {
+ QualType elementType = recurse(T->getElementType());
+ if (elementType.isNull())
+ return QualType();
- if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() &&
- !paramChanged && !exceptionChanged)
- return QualType(T, 0);
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
+ return QualType(T, 0);
- return Ctx.getFunctionType(returnType, paramTypes, info);
- }
+ return Ctx.getVectorType(elementType, T->getNumElements(),
+ T->getVectorKind());
+ }
- QualType VisitParenType(const ParenType *T) {
- QualType innerType = recurse(T->getInnerType());
- if (innerType.isNull())
- return QualType();
+ QualType VisitExtVectorType(const ExtVectorType *T) {
+ QualType elementType = recurse(T->getElementType());
+ if (elementType.isNull())
+ return QualType();
- if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr())
- return QualType(T, 0);
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())
+ return QualType(T, 0);
- return Ctx.getParenType(innerType);
- }
+ return Ctx.getExtVectorType(elementType, T->getNumElements());
+ }
- TRIVIAL_TYPE_CLASS(Typedef)
+ QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
+ QualType returnType = recurse(T->getReturnType());
+ if (returnType.isNull())
+ return QualType();
- QualType VisitAdjustedType(const AdjustedType *T) {
- QualType originalType = recurse(T->getOriginalType());
- if (originalType.isNull())
- return QualType();
+ if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr())
+ return QualType(T, 0);
- QualType adjustedType = recurse(T->getAdjustedType());
- if (adjustedType.isNull())
- return QualType();
+ return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo());
+ }
- if (originalType.getAsOpaquePtr()
- == T->getOriginalType().getAsOpaquePtr() &&
- adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr())
- return QualType(T, 0);
+ QualType VisitFunctionProtoType(const FunctionProtoType *T) {
+ QualType returnType = recurse(T->getReturnType());
+ if (returnType.isNull())
+ return QualType();
- return Ctx.getAdjustedType(originalType, adjustedType);
- }
-
- QualType VisitDecayedType(const DecayedType *T) {
- QualType originalType = recurse(T->getOriginalType());
- if (originalType.isNull())
+ // Transform parameter types.
+ SmallVector<QualType, 4> paramTypes;
+ bool paramChanged = false;
+ for (auto paramType : T->getParamTypes()) {
+ QualType newParamType = recurse(paramType);
+ if (newParamType.isNull())
return QualType();
- if (originalType.getAsOpaquePtr()
- == T->getOriginalType().getAsOpaquePtr())
- return QualType(T, 0);
+ if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr())
+ paramChanged = true;
- return Ctx.getDecayedType(originalType);
+ paramTypes.push_back(newParamType);
}
- TRIVIAL_TYPE_CLASS(TypeOfExpr)
- TRIVIAL_TYPE_CLASS(TypeOf)
- TRIVIAL_TYPE_CLASS(Decltype)
- TRIVIAL_TYPE_CLASS(UnaryTransform)
- TRIVIAL_TYPE_CLASS(Record)
- TRIVIAL_TYPE_CLASS(Enum)
-
- // FIXME: Non-trivial to implement, but important for C++
- TRIVIAL_TYPE_CLASS(Elaborated)
-
- QualType VisitAttributedType(const AttributedType *T) {
- QualType modifiedType = recurse(T->getModifiedType());
- if (modifiedType.isNull())
- return QualType();
-
- QualType equivalentType = recurse(T->getEquivalentType());
- if (equivalentType.isNull())
- return QualType();
-
- if (modifiedType.getAsOpaquePtr()
- == T->getModifiedType().getAsOpaquePtr() &&
- equivalentType.getAsOpaquePtr()
- == T->getEquivalentType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
- equivalentType);
- }
-
- QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- QualType replacementType = recurse(T->getReplacementType());
- if (replacementType.isNull())
- return QualType();
-
- if (replacementType.getAsOpaquePtr()
- == T->getReplacementType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),
- replacementType);
- }
-
- // FIXME: Non-trivial to implement, but important for C++
- TRIVIAL_TYPE_CLASS(TemplateSpecialization)
-
- QualType VisitAutoType(const AutoType *T) {
- if (!T->isDeduced())
- return QualType(T, 0);
-
- QualType deducedType = recurse(T->getDeducedType());
- if (deducedType.isNull())
- return QualType();
-
- if (deducedType.getAsOpaquePtr()
- == T->getDeducedType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getAutoType(deducedType, T->isDecltypeAuto(),
- T->isDependentType());
- }
-
- // FIXME: Non-trivial to implement, but important for C++
- TRIVIAL_TYPE_CLASS(PackExpansion)
-
- QualType VisitObjCObjectType(const ObjCObjectType *T) {
- QualType baseType = recurse(T->getBaseType());
- if (baseType.isNull())
- return QualType();
-
- // Transform type arguments.
- bool typeArgChanged = false;
- SmallVector<QualType, 4> typeArgs;
- for (auto typeArg : T->getTypeArgsAsWritten()) {
- QualType newTypeArg = recurse(typeArg);
- if (newTypeArg.isNull())
+ // Transform extended info.
+ FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo();
+ bool exceptionChanged = false;
+ if (info.ExceptionSpec.Type == EST_Dynamic) {
+ SmallVector<QualType, 4> exceptionTypes;
+ for (auto exceptionType : info.ExceptionSpec.Exceptions) {
+ QualType newExceptionType = recurse(exceptionType);
+ if (newExceptionType.isNull())
return QualType();
+
+ if (newExceptionType.getAsOpaquePtr()
+ != exceptionType.getAsOpaquePtr())
+ exceptionChanged = true;
- if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr())
- typeArgChanged = true;
-
- typeArgs.push_back(newTypeArg);
+ exceptionTypes.push_back(newExceptionType);
}
- if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() &&
- !typeArgChanged)
- return QualType(T, 0);
-
- return Ctx.getObjCObjectType(baseType, typeArgs,
- llvm::makeArrayRef(T->qual_begin(),
- T->getNumProtocols()),
- T->isKindOfTypeAsWritten());
- }
-
- TRIVIAL_TYPE_CLASS(ObjCInterface)
-
- QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
- QualType pointeeType = recurse(T->getPointeeType());
- if (pointeeType.isNull())
- return QualType();
-
- if (pointeeType.getAsOpaquePtr()
- == T->getPointeeType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getObjCObjectPointerType(pointeeType);
+ if (exceptionChanged) {
+ unsigned size = sizeof(QualType) * exceptionTypes.size();
+ void *mem = Ctx.Allocate(size, llvm::alignOf<QualType>());
+ memcpy(mem, exceptionTypes.data(), size);
+ info.ExceptionSpec.Exceptions
+ = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size());
+ }
}
- QualType VisitAtomicType(const AtomicType *T) {
- QualType valueType = recurse(T->getValueType());
- if (valueType.isNull())
- return QualType();
+ if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() &&
+ !paramChanged && !exceptionChanged)
+ return QualType(T, 0);
+
+ return Ctx.getFunctionType(returnType, paramTypes, info);
+ }
+
+ QualType VisitParenType(const ParenType *T) {
+ QualType innerType = recurse(T->getInnerType());
+ if (innerType.isNull())
+ return QualType();
+
+ if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getParenType(innerType);
+ }
+
+ TRIVIAL_TYPE_CLASS(Typedef)
+
+ QualType VisitAdjustedType(const AdjustedType *T) {
+ QualType originalType = recurse(T->getOriginalType());
+ if (originalType.isNull())
+ return QualType();
+
+ QualType adjustedType = recurse(T->getAdjustedType());
+ if (adjustedType.isNull())
+ return QualType();
+
+ if (originalType.getAsOpaquePtr()
+ == T->getOriginalType().getAsOpaquePtr() &&
+ adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getAdjustedType(originalType, adjustedType);
+ }
+
+ QualType VisitDecayedType(const DecayedType *T) {
+ QualType originalType = recurse(T->getOriginalType());
+ if (originalType.isNull())
+ return QualType();
+
+ if (originalType.getAsOpaquePtr()
+ == T->getOriginalType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getDecayedType(originalType);
+ }
+
+ TRIVIAL_TYPE_CLASS(TypeOfExpr)
+ TRIVIAL_TYPE_CLASS(TypeOf)
+ TRIVIAL_TYPE_CLASS(Decltype)
+ TRIVIAL_TYPE_CLASS(UnaryTransform)
+ TRIVIAL_TYPE_CLASS(Record)
+ TRIVIAL_TYPE_CLASS(Enum)
+
+ // FIXME: Non-trivial to implement, but important for C++
+ TRIVIAL_TYPE_CLASS(Elaborated)
+
+ QualType VisitAttributedType(const AttributedType *T) {
+ QualType modifiedType = recurse(T->getModifiedType());
+ if (modifiedType.isNull())
+ return QualType();
+
+ QualType equivalentType = recurse(T->getEquivalentType());
+ if (equivalentType.isNull())
+ return QualType();
+
+ if (modifiedType.getAsOpaquePtr()
+ == T->getModifiedType().getAsOpaquePtr() &&
+ equivalentType.getAsOpaquePtr()
+ == T->getEquivalentType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
+ equivalentType);
+ }
+
+ QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+ QualType replacementType = recurse(T->getReplacementType());
+ if (replacementType.isNull())
+ return QualType();
+
+ if (replacementType.getAsOpaquePtr()
+ == T->getReplacementType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),
+ replacementType);
+ }
+
+ // FIXME: Non-trivial to implement, but important for C++
+ TRIVIAL_TYPE_CLASS(TemplateSpecialization)
+
+ QualType VisitAutoType(const AutoType *T) {
+ if (!T->isDeduced())
+ return QualType(T, 0);
+
+ QualType deducedType = recurse(T->getDeducedType());
+ if (deducedType.isNull())
+ return QualType();
+
+ if (deducedType.getAsOpaquePtr()
+ == T->getDeducedType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getAutoType(deducedType, T->isDecltypeAuto(),
+ T->isDependentType());
+ }
+
+ // FIXME: Non-trivial to implement, but important for C++
+ TRIVIAL_TYPE_CLASS(PackExpansion)
+
+ QualType VisitObjCObjectType(const ObjCObjectType *T) {
+ QualType baseType = recurse(T->getBaseType());
+ if (baseType.isNull())
+ return QualType();
+
+ // Transform type arguments.
+ bool typeArgChanged = false;
+ SmallVector<QualType, 4> typeArgs;
+ for (auto typeArg : T->getTypeArgsAsWritten()) {
+ QualType newTypeArg = recurse(typeArg);
+ if (newTypeArg.isNull())
+ return QualType();
+
+ if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr())
+ typeArgChanged = true;
+
+ typeArgs.push_back(newTypeArg);
+ }
+
+ if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() &&
+ !typeArgChanged)
+ return QualType(T, 0);
+
+ return Ctx.getObjCObjectType(baseType, typeArgs,
+ llvm::makeArrayRef(T->qual_begin(),
+ T->getNumProtocols()),
+ T->isKindOfTypeAsWritten());
+ }
+
+ TRIVIAL_TYPE_CLASS(ObjCInterface)
+
+ QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
+ QualType pointeeType = recurse(T->getPointeeType());
+ if (pointeeType.isNull())
+ return QualType();
+
+ if (pointeeType.getAsOpaquePtr()
+ == T->getPointeeType().getAsOpaquePtr())
+ return QualType(T, 0);
+
+ return Ctx.getObjCObjectPointerType(pointeeType);
+ }
+
+ QualType VisitAtomicType(const AtomicType *T) {
+ QualType valueType = recurse(T->getValueType());
+ if (valueType.isNull())
+ return QualType();
+
+ if (valueType.getAsOpaquePtr()
+ == T->getValueType().getAsOpaquePtr())
+ return QualType(T, 0);
- if (valueType.getAsOpaquePtr()
- == T->getValueType().getAsOpaquePtr())
- return QualType(T, 0);
-
- return Ctx.getAtomicType(valueType);
- }
+ return Ctx.getAtomicType(valueType);
+ }
#undef TRIVIAL_TYPE_CLASS
- };
+};
+/// Perform a simple type transformation that does not change the
+/// semantics of the type.
+template<typename F>
+QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {
// Transform the type. If it changed, return the transformed result.
QualType transformed = f(type);
if (transformed.getAsOpaquePtr() != type.getAsOpaquePtr())
@@ -1022,7 +1028,7 @@ QualType simpleTransform(ASTContext &ctx
SplitQualType splitType = type.split();
// Visit the type itself.
- Visitor visitor(ctx, std::move(f));
+ SimpleTransformVisitor<F> visitor(ctx, std::move(f));
QualType result = visitor.Visit(splitType.Ty);
if (result.isNull())
return result;
More information about the cfe-commits
mailing list