From 6548e112229b523c0289c737dabb8a1481d047ed Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 7 Jul 2015 03:58:59 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241550 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/Type.cpp | 582 ++++++++++++++++++++++++----------------------- 1 file changed, 294 insertions(+), 288 deletions(-) diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 73cf60d34b..5a60655bf4 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -629,390 +629,396 @@ const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals( namespace { -/// Perform a simple type transformation that does not change the -/// semantics of the type. template -QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) { - struct Visitor : public TypeVisitor { - 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 +struct SimpleTransformVisitor + : public TypeVisitor, QualType> { + ASTContext &Ctx; + F &&TheFunc; - public: - Visitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { } + QualType recurse(QualType type) { + return simpleTransform(Ctx, type, std::move(TheFunc)); + } + +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 Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); } - QualType VisitComplexType(const ComplexType *T) { - QualType elementType = recurse(T->getElementType()); - if (elementType.isNull()) - return QualType(); + TRIVIAL_TYPE_CLASS(Builtin) - if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitComplexType(const ComplexType *T) { + QualType elementType = recurse(T->getElementType()); + if (elementType.isNull()) + return QualType(); - return Ctx.getComplexType(elementType); - } + if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitPointerType(const PointerType *T) { - QualType pointeeType = recurse(T->getPointeeType()); - if (pointeeType.isNull()) - return QualType(); + return Ctx.getComplexType(elementType); + } - if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitPointerType(const PointerType *T) { + QualType pointeeType = recurse(T->getPointeeType()); + if (pointeeType.isNull()) + return QualType(); - return Ctx.getPointerType(pointeeType); - } + if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitBlockPointerType(const BlockPointerType *T) { - QualType pointeeType = recurse(T->getPointeeType()); - if (pointeeType.isNull()) - return QualType(); + return Ctx.getPointerType(pointeeType); + } - if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitBlockPointerType(const BlockPointerType *T) { + QualType pointeeType = recurse(T->getPointeeType()); + if (pointeeType.isNull()) + return QualType(); - return Ctx.getBlockPointerType(pointeeType); - } + if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitLValueReferenceType(const LValueReferenceType *T) { - QualType pointeeType = recurse(T->getPointeeTypeAsWritten()); - if (pointeeType.isNull()) - return QualType(); + return Ctx.getBlockPointerType(pointeeType); + } - if (pointeeType.getAsOpaquePtr() - == T->getPointeeTypeAsWritten().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitLValueReferenceType(const LValueReferenceType *T) { + QualType pointeeType = recurse(T->getPointeeTypeAsWritten()); + if (pointeeType.isNull()) + return QualType(); - return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue()); - } + if (pointeeType.getAsOpaquePtr() + == T->getPointeeTypeAsWritten().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitRValueReferenceType(const RValueReferenceType *T) { - QualType pointeeType = recurse(T->getPointeeTypeAsWritten()); - if (pointeeType.isNull()) - return QualType(); + return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue()); + } - if (pointeeType.getAsOpaquePtr() - == T->getPointeeTypeAsWritten().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitRValueReferenceType(const RValueReferenceType *T) { + QualType pointeeType = recurse(T->getPointeeTypeAsWritten()); + if (pointeeType.isNull()) + return QualType(); - return Ctx.getRValueReferenceType(pointeeType); - } + if (pointeeType.getAsOpaquePtr() + == T->getPointeeTypeAsWritten().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitMemberPointerType(const MemberPointerType *T) { - QualType pointeeType = recurse(T->getPointeeType()); - if (pointeeType.isNull()) - return QualType(); + return Ctx.getRValueReferenceType(pointeeType); + } - if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitMemberPointerType(const MemberPointerType *T) { + QualType pointeeType = recurse(T->getPointeeType()); + if (pointeeType.isNull()) + return QualType(); - return Ctx.getMemberPointerType(pointeeType, T->getClass()); - } + if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitConstantArrayType(const ConstantArrayType *T) { - QualType elementType = recurse(T->getElementType()); - if (elementType.isNull()) - return QualType(); + return Ctx.getMemberPointerType(pointeeType, T->getClass()); + } - if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitConstantArrayType(const ConstantArrayType *T) { + QualType elementType = recurse(T->getElementType()); + if (elementType.isNull()) + return QualType(); - return Ctx.getConstantArrayType(elementType, T->getSize(), - T->getSizeModifier(), - T->getIndexTypeCVRQualifiers()); - } + if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitVariableArrayType(const VariableArrayType *T) { - QualType elementType = recurse(T->getElementType()); - if (elementType.isNull()) - return QualType(); + return Ctx.getConstantArrayType(elementType, T->getSize(), + T->getSizeModifier(), + T->getIndexTypeCVRQualifiers()); + } - if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitVariableArrayType(const VariableArrayType *T) { + QualType elementType = recurse(T->getElementType()); + if (elementType.isNull()) + return QualType(); - return Ctx.getVariableArrayType(elementType, T->getSizeExpr(), - T->getSizeModifier(), - T->getIndexTypeCVRQualifiers(), - T->getBracketsRange()); - } + if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitIncompleteArrayType(const IncompleteArrayType *T) { - QualType elementType = recurse(T->getElementType()); - if (elementType.isNull()) - return QualType(); + return Ctx.getVariableArrayType(elementType, T->getSizeExpr(), + T->getSizeModifier(), + T->getIndexTypeCVRQualifiers(), + T->getBracketsRange()); + } - if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitIncompleteArrayType(const IncompleteArrayType *T) { + QualType elementType = recurse(T->getElementType()); + if (elementType.isNull()) + return QualType(); - return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(), - T->getIndexTypeCVRQualifiers()); - } + if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitVectorType(const VectorType *T) { - QualType elementType = recurse(T->getElementType()); - if (elementType.isNull()) - return QualType(); + return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(), + T->getIndexTypeCVRQualifiers()); + } - if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitVectorType(const VectorType *T) { + QualType elementType = recurse(T->getElementType()); + if (elementType.isNull()) + return QualType(); - return Ctx.getVectorType(elementType, T->getNumElements(), - T->getVectorKind()); - } + if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitExtVectorType(const ExtVectorType *T) { - QualType elementType = recurse(T->getElementType()); - if (elementType.isNull()) - return QualType(); + return Ctx.getVectorType(elementType, T->getNumElements(), + T->getVectorKind()); + } - if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitExtVectorType(const ExtVectorType *T) { + QualType elementType = recurse(T->getElementType()); + if (elementType.isNull()) + return QualType(); - return Ctx.getExtVectorType(elementType, T->getNumElements()); - } + if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) { - QualType returnType = recurse(T->getReturnType()); - if (returnType.isNull()) - return QualType(); + return Ctx.getExtVectorType(elementType, T->getNumElements()); + } - if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) { + QualType returnType = recurse(T->getReturnType()); + if (returnType.isNull()) + return QualType(); - return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo()); - } + if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitFunctionProtoType(const FunctionProtoType *T) { - QualType returnType = recurse(T->getReturnType()); - if (returnType.isNull()) - return QualType(); + return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo()); + } - // Transform parameter types. - SmallVector paramTypes; - bool paramChanged = false; - for (auto paramType : T->getParamTypes()) { - QualType newParamType = recurse(paramType); - if (newParamType.isNull()) - return QualType(); + QualType VisitFunctionProtoType(const FunctionProtoType *T) { + QualType returnType = recurse(T->getReturnType()); + if (returnType.isNull()) + return QualType(); - if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr()) - paramChanged = true; + // Transform parameter types. + SmallVector paramTypes; + bool paramChanged = false; + for (auto paramType : T->getParamTypes()) { + QualType newParamType = recurse(paramType); + if (newParamType.isNull()) + return QualType(); - paramTypes.push_back(newParamType); - } + if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr()) + paramChanged = true; - // Transform extended info. - FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo(); - bool exceptionChanged = false; - if (info.ExceptionSpec.Type == EST_Dynamic) { - SmallVector exceptionTypes; - for (auto exceptionType : info.ExceptionSpec.Exceptions) { - QualType newExceptionType = recurse(exceptionType); - if (newExceptionType.isNull()) - return QualType(); - - if (newExceptionType.getAsOpaquePtr() - != exceptionType.getAsOpaquePtr()) - exceptionChanged = true; + paramTypes.push_back(newParamType); + } - exceptionTypes.push_back(newExceptionType); - } + // Transform extended info. + FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo(); + bool exceptionChanged = false; + if (info.ExceptionSpec.Type == EST_Dynamic) { + SmallVector exceptionTypes; + for (auto exceptionType : info.ExceptionSpec.Exceptions) { + QualType newExceptionType = recurse(exceptionType); + if (newExceptionType.isNull()) + return QualType(); + + if (newExceptionType.getAsOpaquePtr() + != exceptionType.getAsOpaquePtr()) + exceptionChanged = true; - if (exceptionChanged) { - unsigned size = sizeof(QualType) * exceptionTypes.size(); - void *mem = Ctx.Allocate(size, llvm::alignOf()); - memcpy(mem, exceptionTypes.data(), size); - info.ExceptionSpec.Exceptions - = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size()); - } + exceptionTypes.push_back(newExceptionType); } - if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() && - !paramChanged && !exceptionChanged) - return QualType(T, 0); - - return Ctx.getFunctionType(returnType, paramTypes, info); + if (exceptionChanged) { + unsigned size = sizeof(QualType) * exceptionTypes.size(); + void *mem = Ctx.Allocate(size, llvm::alignOf()); + memcpy(mem, exceptionTypes.data(), size); + info.ExceptionSpec.Exceptions + = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size()); + } } - QualType VisitParenType(const ParenType *T) { - QualType innerType = recurse(T->getInnerType()); - if (innerType.isNull()) - return QualType(); + if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() && + !paramChanged && !exceptionChanged) + return QualType(T, 0); - if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr()) - return QualType(T, 0); + return Ctx.getFunctionType(returnType, paramTypes, info); + } - return Ctx.getParenType(innerType); - } + QualType VisitParenType(const ParenType *T) { + QualType innerType = recurse(T->getInnerType()); + if (innerType.isNull()) + return QualType(); - TRIVIAL_TYPE_CLASS(Typedef) + if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitAdjustedType(const AdjustedType *T) { - QualType originalType = recurse(T->getOriginalType()); - if (originalType.isNull()) - return QualType(); + return Ctx.getParenType(innerType); + } - QualType adjustedType = recurse(T->getAdjustedType()); - if (adjustedType.isNull()) - return QualType(); + TRIVIAL_TYPE_CLASS(Typedef) - if (originalType.getAsOpaquePtr() - == T->getOriginalType().getAsOpaquePtr() && - adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitAdjustedType(const AdjustedType *T) { + QualType originalType = recurse(T->getOriginalType()); + if (originalType.isNull()) + return QualType(); - return Ctx.getAdjustedType(originalType, adjustedType); - } - - QualType VisitDecayedType(const DecayedType *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()) - return QualType(T, 0); + if (originalType.getAsOpaquePtr() + == T->getOriginalType().getAsOpaquePtr() && + adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr()) + return QualType(T, 0); - return Ctx.getDecayedType(originalType); - } + return Ctx.getAdjustedType(originalType, adjustedType); + } + + QualType VisitDecayedType(const DecayedType *T) { + QualType originalType = recurse(T->getOriginalType()); + if (originalType.isNull()) + return QualType(); - TRIVIAL_TYPE_CLASS(TypeOfExpr) - TRIVIAL_TYPE_CLASS(TypeOf) - TRIVIAL_TYPE_CLASS(Decltype) - TRIVIAL_TYPE_CLASS(UnaryTransform) - TRIVIAL_TYPE_CLASS(Record) - TRIVIAL_TYPE_CLASS(Enum) + if (originalType.getAsOpaquePtr() + == T->getOriginalType().getAsOpaquePtr()) + return QualType(T, 0); - // FIXME: Non-trivial to implement, but important for C++ - TRIVIAL_TYPE_CLASS(Elaborated) + return Ctx.getDecayedType(originalType); + } - QualType VisitAttributedType(const AttributedType *T) { - QualType modifiedType = recurse(T->getModifiedType()); - if (modifiedType.isNull()) - return QualType(); + TRIVIAL_TYPE_CLASS(TypeOfExpr) + TRIVIAL_TYPE_CLASS(TypeOf) + TRIVIAL_TYPE_CLASS(Decltype) + TRIVIAL_TYPE_CLASS(UnaryTransform) + TRIVIAL_TYPE_CLASS(Record) + TRIVIAL_TYPE_CLASS(Enum) - QualType equivalentType = recurse(T->getEquivalentType()); - if (equivalentType.isNull()) - return QualType(); + // FIXME: Non-trivial to implement, but important for C++ + TRIVIAL_TYPE_CLASS(Elaborated) - if (modifiedType.getAsOpaquePtr() - == T->getModifiedType().getAsOpaquePtr() && - equivalentType.getAsOpaquePtr() - == T->getEquivalentType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitAttributedType(const AttributedType *T) { + QualType modifiedType = recurse(T->getModifiedType()); + if (modifiedType.isNull()) + return QualType(); - return Ctx.getAttributedType(T->getAttrKind(), modifiedType, - equivalentType); - } + QualType equivalentType = recurse(T->getEquivalentType()); + if (equivalentType.isNull()) + return QualType(); - QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { - QualType replacementType = recurse(T->getReplacementType()); - if (replacementType.isNull()) - return QualType(); + if (modifiedType.getAsOpaquePtr() + == T->getModifiedType().getAsOpaquePtr() && + equivalentType.getAsOpaquePtr() + == T->getEquivalentType().getAsOpaquePtr()) + return QualType(T, 0); - if (replacementType.getAsOpaquePtr() - == T->getReplacementType().getAsOpaquePtr()) - return QualType(T, 0); + return Ctx.getAttributedType(T->getAttrKind(), modifiedType, + equivalentType); + } - return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(), - replacementType); - } + QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + QualType replacementType = recurse(T->getReplacementType()); + if (replacementType.isNull()) + return QualType(); - // FIXME: Non-trivial to implement, but important for C++ - TRIVIAL_TYPE_CLASS(TemplateSpecialization) + if (replacementType.getAsOpaquePtr() + == T->getReplacementType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitAutoType(const AutoType *T) { - if (!T->isDeduced()) - return QualType(T, 0); + return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(), + replacementType); + } - QualType deducedType = recurse(T->getDeducedType()); - if (deducedType.isNull()) - return QualType(); + // FIXME: Non-trivial to implement, but important for C++ + TRIVIAL_TYPE_CLASS(TemplateSpecialization) - if (deducedType.getAsOpaquePtr() - == T->getDeducedType().getAsOpaquePtr()) - return QualType(T, 0); + QualType VisitAutoType(const AutoType *T) { + if (!T->isDeduced()) + return QualType(T, 0); - return Ctx.getAutoType(deducedType, T->isDecltypeAuto(), - T->isDependentType()); - } + QualType deducedType = recurse(T->getDeducedType()); + if (deducedType.isNull()) + return QualType(); - // FIXME: Non-trivial to implement, but important for C++ - TRIVIAL_TYPE_CLASS(PackExpansion) + if (deducedType.getAsOpaquePtr() + == T->getDeducedType().getAsOpaquePtr()) + return QualType(T, 0); - QualType VisitObjCObjectType(const ObjCObjectType *T) { - QualType baseType = recurse(T->getBaseType()); - if (baseType.isNull()) - return QualType(); + return Ctx.getAutoType(deducedType, T->isDecltypeAuto(), + T->isDependentType()); + } - // Transform type arguments. - bool typeArgChanged = false; - SmallVector typeArgs; - for (auto typeArg : T->getTypeArgsAsWritten()) { - QualType newTypeArg = recurse(typeArg); - if (newTypeArg.isNull()) - return QualType(); + // FIXME: Non-trivial to implement, but important for C++ + TRIVIAL_TYPE_CLASS(PackExpansion) - if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) - typeArgChanged = true; + QualType VisitObjCObjectType(const ObjCObjectType *T) { + QualType baseType = recurse(T->getBaseType()); + if (baseType.isNull()) + return QualType(); - typeArgs.push_back(newTypeArg); - } + // Transform type arguments. + bool typeArgChanged = false; + SmallVector typeArgs; + for (auto typeArg : T->getTypeArgsAsWritten()) { + QualType newTypeArg = recurse(typeArg); + if (newTypeArg.isNull()) + return QualType(); - if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() && - !typeArgChanged) - return QualType(T, 0); + if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr()) + typeArgChanged = true; - return Ctx.getObjCObjectType(baseType, typeArgs, - llvm::makeArrayRef(T->qual_begin(), - T->getNumProtocols()), - T->isKindOfTypeAsWritten()); + typeArgs.push_back(newTypeArg); } - TRIVIAL_TYPE_CLASS(ObjCInterface) + if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() && + !typeArgChanged) + return QualType(T, 0); - QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { - QualType pointeeType = recurse(T->getPointeeType()); - if (pointeeType.isNull()) - return QualType(); + return Ctx.getObjCObjectType(baseType, typeArgs, + llvm::makeArrayRef(T->qual_begin(), + T->getNumProtocols()), + T->isKindOfTypeAsWritten()); + } - if (pointeeType.getAsOpaquePtr() - == T->getPointeeType().getAsOpaquePtr()) - return QualType(T, 0); + TRIVIAL_TYPE_CLASS(ObjCInterface) - return Ctx.getObjCObjectPointerType(pointeeType); - } + QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { + QualType pointeeType = recurse(T->getPointeeType()); + if (pointeeType.isNull()) + return QualType(); - QualType VisitAtomicType(const AtomicType *T) { - QualType valueType = recurse(T->getValueType()); - if (valueType.isNull()) - return QualType(); + if (pointeeType.getAsOpaquePtr() + == T->getPointeeType().getAsOpaquePtr()) + return QualType(T, 0); - if (valueType.getAsOpaquePtr() - == T->getValueType().getAsOpaquePtr()) - return QualType(T, 0); + return Ctx.getObjCObjectPointerType(pointeeType); + } - return Ctx.getAtomicType(valueType); - } + 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); + + return Ctx.getAtomicType(valueType); + } #undef TRIVIAL_TYPE_CLASS - }; +}; +/// Perform a simple type transformation that does not change the +/// semantics of the type. +template +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, QualType type, F &&f) { SplitQualType splitType = type.split(); // Visit the type itself. - Visitor visitor(ctx, std::move(f)); + SimpleTransformVisitor visitor(ctx, std::move(f)); QualType result = visitor.Visit(splitType.Ty); if (result.isNull()) return result; -- 2.40.0