<div dir="ltr"><div>Is there a particular reason you're using lowerCamelCase for local variables in this patch set?<br><br></div>-- Sean Silva<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 6, 2015 at 8:58 PM, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com" target="_blank">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dgregor<br>
Date: Mon Jul 6 22:58:59 2015<br>
New Revision: 241550<br>
<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D241550-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=_mwsfj8FywjHaaoythmQQKKGvwMLUH5zChTuMFdHDDw&s=Ps8zXl-5cuZrnBcZ_22OJoEnUNnZleMXhNZ09gz75UM&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=241550&view=rev</a><br>
Log:<br>
Factor the simpleTransform() visitor so that it is not a local class.<br>
<br>
Older versions of Clang cannot handle such local classes properly<br>
rdar://problem/19386032.<br>
<br>
Modified:<br>
cfe/trunk/lib/AST/Type.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/Type.cpp<br>
URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_AST_Type.cpp-3Frev-3D241550-26r1-3D241549-26r2-3D241550-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=_mwsfj8FywjHaaoythmQQKKGvwMLUH5zChTuMFdHDDw&s=9_4k1MKVe34stZjBzoFvm44mW-gNV5mR9iijQ4hQbsA&e=" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=241550&r1=241549&r2=241550&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/Type.cpp (original)<br>
+++ cfe/trunk/lib/AST/Type.cpp Mon Jul 6 22:58:59 2015<br>
@@ -629,390 +629,396 @@ const ObjCObjectPointerType *ObjCObjectP<br>
<br>
namespace {<br>
<br>
-/// Perform a simple type transformation that does not change the<br>
-/// semantics of the type.<br>
template<typename F><br>
-QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {<br>
- struct Visitor : public TypeVisitor<Visitor, QualType> {<br>
- ASTContext &Ctx;<br>
- F &&TheFunc;<br>
+QualType simpleTransform(ASTContext &ctx, QualType type, F &&f);<br>
<br>
- QualType recurse(QualType type) {<br>
- return simpleTransform(Ctx, type, std::move(TheFunc));<br>
- }<br>
+/// Visitor used by simpleTransform() to perform the transformation.<br>
+template<typename F><br>
+struct SimpleTransformVisitor<br>
+ : public TypeVisitor<SimpleTransformVisitor<F>, QualType> {<br>
+ ASTContext &Ctx;<br>
+ F &&TheFunc;<br>
+<br>
+ QualType recurse(QualType type) {<br>
+ return simpleTransform(Ctx, type, std::move(TheFunc));<br>
+ }<br>
<br>
- public:<br>
- Visitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { }<br>
+public:<br>
+ SimpleTransformVisitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { }<br>
<br>
- // None of the clients of this transformation can occur where<br>
- // there are dependent types, so skip dependent types.<br>
+ // None of the clients of this transformation can occur where<br>
+ // there are dependent types, so skip dependent types.<br>
#define TYPE(Class, Base)<br>
#define DEPENDENT_TYPE(Class, Base) \<br>
- QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }<br>
+ QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }<br>
#include "clang/AST/TypeNodes.def"<br>
<br>
#define TRIVIAL_TYPE_CLASS(Class) \<br>
- QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }<br>
-<br>
- TRIVIAL_TYPE_CLASS(Builtin)<br>
-<br>
- QualType VisitComplexType(const ComplexType *T) {<br>
- QualType elementType = recurse(T->getElementType());<br>
- if (elementType.isNull())<br>
- return QualType();<br>
-<br>
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getComplexType(elementType);<br>
- }<br>
-<br>
- QualType VisitPointerType(const PointerType *T) {<br>
- QualType pointeeType = recurse(T->getPointeeType());<br>
- if (pointeeType.isNull())<br>
- return QualType();<br>
-<br>
- if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getPointerType(pointeeType);<br>
- }<br>
-<br>
- QualType VisitBlockPointerType(const BlockPointerType *T) {<br>
- QualType pointeeType = recurse(T->getPointeeType());<br>
- if (pointeeType.isNull())<br>
- return QualType();<br>
-<br>
- if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getBlockPointerType(pointeeType);<br>
- }<br>
-<br>
- QualType VisitLValueReferenceType(const LValueReferenceType *T) {<br>
- QualType pointeeType = recurse(T->getPointeeTypeAsWritten());<br>
- if (pointeeType.isNull())<br>
- return QualType();<br>
+ QualType Visit##Class##Type(const Class##Type *T) { return QualType(T, 0); }<br>
<br>
- if (pointeeType.getAsOpaquePtr()<br>
- == T->getPointeeTypeAsWritten().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ TRIVIAL_TYPE_CLASS(Builtin)<br>
<br>
- return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue());<br>
- }<br>
+ QualType VisitComplexType(const ComplexType *T) {<br>
+ QualType elementType = recurse(T->getElementType());<br>
+ if (elementType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitRValueReferenceType(const RValueReferenceType *T) {<br>
- QualType pointeeType = recurse(T->getPointeeTypeAsWritten());<br>
- if (pointeeType.isNull())<br>
- return QualType();<br>
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (pointeeType.getAsOpaquePtr()<br>
- == T->getPointeeTypeAsWritten().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getComplexType(elementType);<br>
+ }<br>
<br>
- return Ctx.getRValueReferenceType(pointeeType);<br>
- }<br>
+ QualType VisitPointerType(const PointerType *T) {<br>
+ QualType pointeeType = recurse(T->getPointeeType());<br>
+ if (pointeeType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitMemberPointerType(const MemberPointerType *T) {<br>
- QualType pointeeType = recurse(T->getPointeeType());<br>
- if (pointeeType.isNull())<br>
- return QualType();<br>
+ if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getPointerType(pointeeType);<br>
+ }<br>
<br>
- return Ctx.getMemberPointerType(pointeeType, T->getClass());<br>
- }<br>
+ QualType VisitBlockPointerType(const BlockPointerType *T) {<br>
+ QualType pointeeType = recurse(T->getPointeeType());<br>
+ if (pointeeType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitConstantArrayType(const ConstantArrayType *T) {<br>
- QualType elementType = recurse(T->getElementType());<br>
- if (elementType.isNull())<br>
- return QualType();<br>
+ if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getBlockPointerType(pointeeType);<br>
+ }<br>
<br>
- return Ctx.getConstantArrayType(elementType, T->getSize(),<br>
- T->getSizeModifier(),<br>
- T->getIndexTypeCVRQualifiers());<br>
- }<br>
+ QualType VisitLValueReferenceType(const LValueReferenceType *T) {<br>
+ QualType pointeeType = recurse(T->getPointeeTypeAsWritten());<br>
+ if (pointeeType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitVariableArrayType(const VariableArrayType *T) {<br>
- QualType elementType = recurse(T->getElementType());<br>
- if (elementType.isNull())<br>
- return QualType();<br>
+ if (pointeeType.getAsOpaquePtr()<br>
+ == T->getPointeeTypeAsWritten().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getLValueReferenceType(pointeeType, T->isSpelledAsLValue());<br>
+ }<br>
<br>
- return Ctx.getVariableArrayType(elementType, T->getSizeExpr(),<br>
- T->getSizeModifier(),<br>
- T->getIndexTypeCVRQualifiers(),<br>
- T->getBracketsRange());<br>
- }<br>
+ QualType VisitRValueReferenceType(const RValueReferenceType *T) {<br>
+ QualType pointeeType = recurse(T->getPointeeTypeAsWritten());<br>
+ if (pointeeType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitIncompleteArrayType(const IncompleteArrayType *T) {<br>
- QualType elementType = recurse(T->getElementType());<br>
- if (elementType.isNull())<br>
- return QualType();<br>
+ if (pointeeType.getAsOpaquePtr()<br>
+ == T->getPointeeTypeAsWritten().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getRValueReferenceType(pointeeType);<br>
+ }<br>
<br>
- return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(),<br>
- T->getIndexTypeCVRQualifiers());<br>
- }<br>
+ QualType VisitMemberPointerType(const MemberPointerType *T) {<br>
+ QualType pointeeType = recurse(T->getPointeeType());<br>
+ if (pointeeType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitVectorType(const VectorType *T) {<br>
- QualType elementType = recurse(T->getElementType());<br>
- if (elementType.isNull())<br>
- return QualType();<br>
+ if (pointeeType.getAsOpaquePtr() == T->getPointeeType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getMemberPointerType(pointeeType, T->getClass());<br>
+ }<br>
<br>
- return Ctx.getVectorType(elementType, T->getNumElements(),<br>
- T->getVectorKind());<br>
- }<br>
+ QualType VisitConstantArrayType(const ConstantArrayType *T) {<br>
+ QualType elementType = recurse(T->getElementType());<br>
+ if (elementType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitExtVectorType(const ExtVectorType *T) {<br>
- QualType elementType = recurse(T->getElementType());<br>
- if (elementType.isNull())<br>
- return QualType();<br>
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getConstantArrayType(elementType, T->getSize(),<br>
+ T->getSizeModifier(),<br>
+ T->getIndexTypeCVRQualifiers());<br>
+ }<br>
<br>
- return Ctx.getExtVectorType(elementType, T->getNumElements());<br>
- }<br>
+ QualType VisitVariableArrayType(const VariableArrayType *T) {<br>
+ QualType elementType = recurse(T->getElementType());<br>
+ if (elementType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) {<br>
- QualType returnType = recurse(T->getReturnType());<br>
- if (returnType.isNull())<br>
- return QualType();<br>
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ return Ctx.getVariableArrayType(elementType, T->getSizeExpr(),<br>
+ T->getSizeModifier(),<br>
+ T->getIndexTypeCVRQualifiers(),<br>
+ T->getBracketsRange());<br>
+ }<br>
<br>
- return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo());<br>
- }<br>
+ QualType VisitIncompleteArrayType(const IncompleteArrayType *T) {<br>
+ QualType elementType = recurse(T->getElementType());<br>
+ if (elementType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitFunctionProtoType(const FunctionProtoType *T) {<br>
- QualType returnType = recurse(T->getReturnType());<br>
- if (returnType.isNull())<br>
- return QualType();<br>
-<br>
- // Transform parameter types.<br>
- SmallVector<QualType, 4> paramTypes;<br>
- bool paramChanged = false;<br>
- for (auto paramType : T->getParamTypes()) {<br>
- QualType newParamType = recurse(paramType);<br>
- if (newParamType.isNull())<br>
- return QualType();<br>
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr())<br>
- paramChanged = true;<br>
-<br>
- paramTypes.push_back(newParamType);<br>
- }<br>
+ return Ctx.getIncompleteArrayType(elementType, T->getSizeModifier(),<br>
+ T->getIndexTypeCVRQualifiers());<br>
+ }<br>
<br>
- // Transform extended info.<br>
- FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo();<br>
- bool exceptionChanged = false;<br>
- if (info.ExceptionSpec.Type == EST_Dynamic) {<br>
- SmallVector<QualType, 4> exceptionTypes;<br>
- for (auto exceptionType : info.ExceptionSpec.Exceptions) {<br>
- QualType newExceptionType = recurse(exceptionType);<br>
- if (newExceptionType.isNull())<br>
- return QualType();<br>
-<br>
- if (newExceptionType.getAsOpaquePtr()<br>
- != exceptionType.getAsOpaquePtr())<br>
- exceptionChanged = true;<br>
-<br>
- exceptionTypes.push_back(newExceptionType);<br>
- }<br>
-<br>
- if (exceptionChanged) {<br>
- unsigned size = sizeof(QualType) * exceptionTypes.size();<br>
- void *mem = Ctx.Allocate(size, llvm::alignOf<QualType>());<br>
- memcpy(mem, exceptionTypes.data(), size);<br>
- info.ExceptionSpec.Exceptions<br>
- = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size());<br>
- }<br>
- }<br>
+ QualType VisitVectorType(const VectorType *T) {<br>
+ QualType elementType = recurse(T->getElementType());<br>
+ if (elementType.isNull())<br>
+ return QualType();<br>
<br>
- if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() &&<br>
- !paramChanged && !exceptionChanged)<br>
- return QualType(T, 0);<br>
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- return Ctx.getFunctionType(returnType, paramTypes, info);<br>
- }<br>
+ return Ctx.getVectorType(elementType, T->getNumElements(),<br>
+ T->getVectorKind());<br>
+ }<br>
<br>
- QualType VisitParenType(const ParenType *T) {<br>
- QualType innerType = recurse(T->getInnerType());<br>
- if (innerType.isNull())<br>
- return QualType();<br>
+ QualType VisitExtVectorType(const ExtVectorType *T) {<br>
+ QualType elementType = recurse(T->getElementType());<br>
+ if (elementType.isNull())<br>
+ return QualType();<br>
<br>
- if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ if (elementType.getAsOpaquePtr() == T->getElementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- return Ctx.getParenType(innerType);<br>
- }<br>
+ return Ctx.getExtVectorType(elementType, T->getNumElements());<br>
+ }<br>
<br>
- TRIVIAL_TYPE_CLASS(Typedef)<br>
+ QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T) {<br>
+ QualType returnType = recurse(T->getReturnType());<br>
+ if (returnType.isNull())<br>
+ return QualType();<br>
<br>
- QualType VisitAdjustedType(const AdjustedType *T) {<br>
- QualType originalType = recurse(T->getOriginalType());<br>
- if (originalType.isNull())<br>
- return QualType();<br>
+ if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- QualType adjustedType = recurse(T->getAdjustedType());<br>
- if (adjustedType.isNull())<br>
- return QualType();<br>
+ return Ctx.getFunctionNoProtoType(returnType, T->getExtInfo());<br>
+ }<br>
<br>
- if (originalType.getAsOpaquePtr()<br>
- == T->getOriginalType().getAsOpaquePtr() &&<br>
- adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ QualType VisitFunctionProtoType(const FunctionProtoType *T) {<br>
+ QualType returnType = recurse(T->getReturnType());<br>
+ if (returnType.isNull())<br>
+ return QualType();<br>
<br>
- return Ctx.getAdjustedType(originalType, adjustedType);<br>
- }<br>
-<br>
- QualType VisitDecayedType(const DecayedType *T) {<br>
- QualType originalType = recurse(T->getOriginalType());<br>
- if (originalType.isNull())<br>
+ // Transform parameter types.<br>
+ SmallVector<QualType, 4> paramTypes;<br>
+ bool paramChanged = false;<br>
+ for (auto paramType : T->getParamTypes()) {<br>
+ QualType newParamType = recurse(paramType);<br>
+ if (newParamType.isNull())<br>
return QualType();<br>
<br>
- if (originalType.getAsOpaquePtr()<br>
- == T->getOriginalType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
+ if (newParamType.getAsOpaquePtr() != paramType.getAsOpaquePtr())<br>
+ paramChanged = true;<br>
<br>
- return Ctx.getDecayedType(originalType);<br>
+ paramTypes.push_back(newParamType);<br>
}<br>
<br>
- TRIVIAL_TYPE_CLASS(TypeOfExpr)<br>
- TRIVIAL_TYPE_CLASS(TypeOf)<br>
- TRIVIAL_TYPE_CLASS(Decltype)<br>
- TRIVIAL_TYPE_CLASS(UnaryTransform)<br>
- TRIVIAL_TYPE_CLASS(Record)<br>
- TRIVIAL_TYPE_CLASS(Enum)<br>
-<br>
- // FIXME: Non-trivial to implement, but important for C++<br>
- TRIVIAL_TYPE_CLASS(Elaborated)<br>
-<br>
- QualType VisitAttributedType(const AttributedType *T) {<br>
- QualType modifiedType = recurse(T->getModifiedType());<br>
- if (modifiedType.isNull())<br>
- return QualType();<br>
-<br>
- QualType equivalentType = recurse(T->getEquivalentType());<br>
- if (equivalentType.isNull())<br>
- return QualType();<br>
-<br>
- if (modifiedType.getAsOpaquePtr()<br>
- == T->getModifiedType().getAsOpaquePtr() &&<br>
- equivalentType.getAsOpaquePtr()<br>
- == T->getEquivalentType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getAttributedType(T->getAttrKind(), modifiedType,<br>
- equivalentType);<br>
- }<br>
-<br>
- QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {<br>
- QualType replacementType = recurse(T->getReplacementType());<br>
- if (replacementType.isNull())<br>
- return QualType();<br>
-<br>
- if (replacementType.getAsOpaquePtr()<br>
- == T->getReplacementType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),<br>
- replacementType);<br>
- }<br>
-<br>
- // FIXME: Non-trivial to implement, but important for C++<br>
- TRIVIAL_TYPE_CLASS(TemplateSpecialization)<br>
-<br>
- QualType VisitAutoType(const AutoType *T) {<br>
- if (!T->isDeduced())<br>
- return QualType(T, 0);<br>
-<br>
- QualType deducedType = recurse(T->getDeducedType());<br>
- if (deducedType.isNull())<br>
- return QualType();<br>
-<br>
- if (deducedType.getAsOpaquePtr()<br>
- == T->getDeducedType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getAutoType(deducedType, T->isDecltypeAuto(),<br>
- T->isDependentType());<br>
- }<br>
-<br>
- // FIXME: Non-trivial to implement, but important for C++<br>
- TRIVIAL_TYPE_CLASS(PackExpansion)<br>
-<br>
- QualType VisitObjCObjectType(const ObjCObjectType *T) {<br>
- QualType baseType = recurse(T->getBaseType());<br>
- if (baseType.isNull())<br>
- return QualType();<br>
-<br>
- // Transform type arguments.<br>
- bool typeArgChanged = false;<br>
- SmallVector<QualType, 4> typeArgs;<br>
- for (auto typeArg : T->getTypeArgsAsWritten()) {<br>
- QualType newTypeArg = recurse(typeArg);<br>
- if (newTypeArg.isNull())<br>
+ // Transform extended info.<br>
+ FunctionProtoType::ExtProtoInfo info = T->getExtProtoInfo();<br>
+ bool exceptionChanged = false;<br>
+ if (info.ExceptionSpec.Type == EST_Dynamic) {<br>
+ SmallVector<QualType, 4> exceptionTypes;<br>
+ for (auto exceptionType : info.ExceptionSpec.Exceptions) {<br>
+ QualType newExceptionType = recurse(exceptionType);<br>
+ if (newExceptionType.isNull())<br>
return QualType();<br>
+<br>
+ if (newExceptionType.getAsOpaquePtr()<br>
+ != exceptionType.getAsOpaquePtr())<br>
+ exceptionChanged = true;<br>
<br>
- if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr())<br>
- typeArgChanged = true;<br>
-<br>
- typeArgs.push_back(newTypeArg);<br>
+ exceptionTypes.push_back(newExceptionType);<br>
}<br>
<br>
- if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() &&<br>
- !typeArgChanged)<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getObjCObjectType(baseType, typeArgs,<br>
- llvm::makeArrayRef(T->qual_begin(),<br>
- T->getNumProtocols()),<br>
- T->isKindOfTypeAsWritten());<br>
- }<br>
-<br>
- TRIVIAL_TYPE_CLASS(ObjCInterface)<br>
-<br>
- QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {<br>
- QualType pointeeType = recurse(T->getPointeeType());<br>
- if (pointeeType.isNull())<br>
- return QualType();<br>
-<br>
- if (pointeeType.getAsOpaquePtr()<br>
- == T->getPointeeType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getObjCObjectPointerType(pointeeType);<br>
+ if (exceptionChanged) {<br>
+ unsigned size = sizeof(QualType) * exceptionTypes.size();<br>
+ void *mem = Ctx.Allocate(size, llvm::alignOf<QualType>());<br>
+ memcpy(mem, exceptionTypes.data(), size);<br>
+ info.ExceptionSpec.Exceptions<br>
+ = llvm::makeArrayRef((QualType *)mem, exceptionTypes.size());<br>
+ }<br>
}<br>
<br>
- QualType VisitAtomicType(const AtomicType *T) {<br>
- QualType valueType = recurse(T->getValueType());<br>
- if (valueType.isNull())<br>
- return QualType();<br>
+ if (returnType.getAsOpaquePtr() == T->getReturnType().getAsOpaquePtr() &&<br>
+ !paramChanged && !exceptionChanged)<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getFunctionType(returnType, paramTypes, info);<br>
+ }<br>
+<br>
+ QualType VisitParenType(const ParenType *T) {<br>
+ QualType innerType = recurse(T->getInnerType());<br>
+ if (innerType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (innerType.getAsOpaquePtr() == T->getInnerType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getParenType(innerType);<br>
+ }<br>
+<br>
+ TRIVIAL_TYPE_CLASS(Typedef)<br>
+<br>
+ QualType VisitAdjustedType(const AdjustedType *T) {<br>
+ QualType originalType = recurse(T->getOriginalType());<br>
+ if (originalType.isNull())<br>
+ return QualType();<br>
+<br>
+ QualType adjustedType = recurse(T->getAdjustedType());<br>
+ if (adjustedType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (originalType.getAsOpaquePtr()<br>
+ == T->getOriginalType().getAsOpaquePtr() &&<br>
+ adjustedType.getAsOpaquePtr() == T->getAdjustedType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getAdjustedType(originalType, adjustedType);<br>
+ }<br>
+<br>
+ QualType VisitDecayedType(const DecayedType *T) {<br>
+ QualType originalType = recurse(T->getOriginalType());<br>
+ if (originalType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (originalType.getAsOpaquePtr()<br>
+ == T->getOriginalType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getDecayedType(originalType);<br>
+ }<br>
+<br>
+ TRIVIAL_TYPE_CLASS(TypeOfExpr)<br>
+ TRIVIAL_TYPE_CLASS(TypeOf)<br>
+ TRIVIAL_TYPE_CLASS(Decltype)<br>
+ TRIVIAL_TYPE_CLASS(UnaryTransform)<br>
+ TRIVIAL_TYPE_CLASS(Record)<br>
+ TRIVIAL_TYPE_CLASS(Enum)<br>
+<br>
+ // FIXME: Non-trivial to implement, but important for C++<br>
+ TRIVIAL_TYPE_CLASS(Elaborated)<br>
+<br>
+ QualType VisitAttributedType(const AttributedType *T) {<br>
+ QualType modifiedType = recurse(T->getModifiedType());<br>
+ if (modifiedType.isNull())<br>
+ return QualType();<br>
+<br>
+ QualType equivalentType = recurse(T->getEquivalentType());<br>
+ if (equivalentType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (modifiedType.getAsOpaquePtr()<br>
+ == T->getModifiedType().getAsOpaquePtr() &&<br>
+ equivalentType.getAsOpaquePtr()<br>
+ == T->getEquivalentType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getAttributedType(T->getAttrKind(), modifiedType,<br>
+ equivalentType);<br>
+ }<br>
+<br>
+ QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {<br>
+ QualType replacementType = recurse(T->getReplacementType());<br>
+ if (replacementType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (replacementType.getAsOpaquePtr()<br>
+ == T->getReplacementType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(),<br>
+ replacementType);<br>
+ }<br>
+<br>
+ // FIXME: Non-trivial to implement, but important for C++<br>
+ TRIVIAL_TYPE_CLASS(TemplateSpecialization)<br>
+<br>
+ QualType VisitAutoType(const AutoType *T) {<br>
+ if (!T->isDeduced())<br>
+ return QualType(T, 0);<br>
+<br>
+ QualType deducedType = recurse(T->getDeducedType());<br>
+ if (deducedType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (deducedType.getAsOpaquePtr()<br>
+ == T->getDeducedType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getAutoType(deducedType, T->isDecltypeAuto(),<br>
+ T->isDependentType());<br>
+ }<br>
+<br>
+ // FIXME: Non-trivial to implement, but important for C++<br>
+ TRIVIAL_TYPE_CLASS(PackExpansion)<br>
+<br>
+ QualType VisitObjCObjectType(const ObjCObjectType *T) {<br>
+ QualType baseType = recurse(T->getBaseType());<br>
+ if (baseType.isNull())<br>
+ return QualType();<br>
+<br>
+ // Transform type arguments.<br>
+ bool typeArgChanged = false;<br>
+ SmallVector<QualType, 4> typeArgs;<br>
+ for (auto typeArg : T->getTypeArgsAsWritten()) {<br>
+ QualType newTypeArg = recurse(typeArg);<br>
+ if (newTypeArg.isNull())<br>
+ return QualType();<br>
+<br>
+ if (newTypeArg.getAsOpaquePtr() != typeArg.getAsOpaquePtr())<br>
+ typeArgChanged = true;<br>
+<br>
+ typeArgs.push_back(newTypeArg);<br>
+ }<br>
+<br>
+ if (baseType.getAsOpaquePtr() == T->getBaseType().getAsOpaquePtr() &&<br>
+ !typeArgChanged)<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getObjCObjectType(baseType, typeArgs,<br>
+ llvm::makeArrayRef(T->qual_begin(),<br>
+ T->getNumProtocols()),<br>
+ T->isKindOfTypeAsWritten());<br>
+ }<br>
+<br>
+ TRIVIAL_TYPE_CLASS(ObjCInterface)<br>
+<br>
+ QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {<br>
+ QualType pointeeType = recurse(T->getPointeeType());<br>
+ if (pointeeType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (pointeeType.getAsOpaquePtr()<br>
+ == T->getPointeeType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
+<br>
+ return Ctx.getObjCObjectPointerType(pointeeType);<br>
+ }<br>
+<br>
+ QualType VisitAtomicType(const AtomicType *T) {<br>
+ QualType valueType = recurse(T->getValueType());<br>
+ if (valueType.isNull())<br>
+ return QualType();<br>
+<br>
+ if (valueType.getAsOpaquePtr()<br>
+ == T->getValueType().getAsOpaquePtr())<br>
+ return QualType(T, 0);<br>
<br>
- if (valueType.getAsOpaquePtr()<br>
- == T->getValueType().getAsOpaquePtr())<br>
- return QualType(T, 0);<br>
-<br>
- return Ctx.getAtomicType(valueType);<br>
- }<br>
+ return Ctx.getAtomicType(valueType);<br>
+ }<br>
<br>
#undef TRIVIAL_TYPE_CLASS<br>
- };<br>
+};<br>
<br>
+/// Perform a simple type transformation that does not change the<br>
+/// semantics of the type.<br>
+template<typename F><br>
+QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {<br>
// Transform the type. If it changed, return the transformed result.<br>
QualType transformed = f(type);<br>
if (transformed.getAsOpaquePtr() != type.getAsOpaquePtr())<br>
@@ -1022,7 +1028,7 @@ QualType simpleTransform(ASTContext &ctx<br>
SplitQualType splitType = type.split();<br>
<br>
// Visit the type itself.<br>
- Visitor visitor(ctx, std::move(f));<br>
+ SimpleTransformVisitor<F> visitor(ctx, std::move(f));<br>
QualType result = visitor.Visit(splitType.Ty);<br>
if (result.isNull())<br>
return result;<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>