Is there a particular reason you're using lowerCamelCase for local variables in this patch set?
-- Sean Silva On Mon, Jul 6, 2015 at 8:58 PM, Douglas Gregor <[email protected]> wrote: > 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; > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
