<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>