<div dir="ltr">On Mon, Jun 24, 2013 at 10:51 AM, Reid Kleckner <span dir="ltr"><<a href="mailto:reid@kleckner.net" target="_blank">reid@kleckner.net</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Mon Jun 24 12:51:48 2013<br>
New Revision: 184763<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=184763&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=184763&view=rev</a><br>
Log:<br>
[AST] Introduce a new DecayedType sugar node<br>
<br>
The goal of this sugar node is to be able to look at an arbitrary<br>
FunctionType and tell if any of the parameters were decayed from an<br>
array or function type.  Ultimately this is necessary to implement<br>
Microsoft's C++ name mangling scheme, which mangles decayed arrays<br>
differently from normal pointers.<br>
<br>
Reviewers: rsmith<br>
<br>
Differential Revision: <a href="http://llvm-reviews.chandlerc.com/D1014" target="_blank">http://llvm-reviews.chandlerc.com/D1014</a><br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTContext.h<br>
    cfe/trunk/include/clang/AST/Decl.h<br>
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
    cfe/trunk/include/clang/AST/Type.h<br>
    cfe/trunk/include/clang/AST/TypeLoc.h<br>
    cfe/trunk/include/clang/AST/TypeNodes.def<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/AST/ASTContext.cpp<br>
    cfe/trunk/lib/AST/ASTImporter.cpp<br>
    cfe/trunk/lib/AST/Decl.cpp<br>
    cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
    cfe/trunk/lib/AST/TypePrinter.cpp<br>
    cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaType.cpp<br>
    cfe/trunk/lib/Sema/TreeTransform.h<br>
    cfe/trunk/lib/Serialization/ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
    cfe/trunk/test/Index/print-type.c<br>
    cfe/trunk/test/Sema/function.c<br>
    cfe/trunk/test/SemaCXX/function-type-qual.cpp<br>
    cfe/trunk/tools/libclang/CIndex.cpp<br>
    cfe/trunk/tools/libclang/RecursiveASTVisitor.h<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Jun 24 12:51:48 2013<br>
@@ -82,6 +82,7 @@ class ASTContext : public RefCountedBase<br>
   mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;<br>
   mutable llvm::FoldingSet<ComplexType> ComplexTypes;<br>
   mutable llvm::FoldingSet<PointerType> PointerTypes;<br>
+  mutable llvm::FoldingSet<DecayedType> DecayedTypes;<br>
   mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;<br>
   mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;<br>
   mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;<br>
@@ -889,6 +890,14 @@ public:<br>
     return CanQualType::CreateUnsafe(getPointerType((QualType) T));<br>
   }<br>
<br>
+  /// \brief Return the uniqued reference to the decayed version of the given<br>
+  /// type.  Can only be called on array and function types which decay to<br>
+  /// pointer types.<br>
+  QualType getDecayedType(QualType T) const;<br>
+  CanQualType getDecayedType(CanQualType T) const {<br>
+    return CanQualType::CreateUnsafe(getDecayedType((QualType) T));<br>
+  }<br>
+<br>
   /// \brief Return the uniqued reference to the atomic type for the specified<br>
   /// type.<br>
   QualType getAtomicType(QualType T) const;<br>
<br>
Modified: cfe/trunk/include/clang/AST/Decl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/Decl.h (original)<br>
+++ cfe/trunk/include/clang/AST/Decl.h Mon Jun 24 12:51:48 2013<br>
@@ -1337,11 +1337,7 @@ public:<br>
     ParmVarDeclBits.HasInheritedDefaultArg = I;<br>
   }<br>
<br>
-  QualType getOriginalType() const {<br>
-    if (getTypeSourceInfo())<br>
-      return getTypeSourceInfo()->getType();<br>
-    return getType();<br>
-  }<br>
+  QualType getOriginalType() const;<br>
<br>
   /// \brief Determine whether this parameter is actually a function<br>
   /// parameter pack.<br>
<br>
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon Jun 24 12:51:48 2013<br>
@@ -847,6 +847,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, {<br>
     TRY_TO(TraverseType(T->getPointeeType()));<br>
   })<br>
<br>
+DEF_TRAVERSE_TYPE(DecayedType, {<br>
+    TRY_TO(TraverseType(T->getOriginalType()));<br>
+  })<br>
+<br>
 DEF_TRAVERSE_TYPE(ConstantArrayType, {<br>
     TRY_TO(TraverseType(T->getElementType()));<br>
   })<br>
@@ -1053,6 +1057,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType,<br>
     TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));<br>
   })<br>
<br>
+DEF_TRAVERSE_TYPELOC(DecayedType, {<br>
+    TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));<br>
+  })<br>
+<br>
 template<typename Derived><br>
 bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {<br>
   // This isn't available for ArrayType, but is for the ArrayTypeLoc.<br>
<br>
Modified: cfe/trunk/include/clang/AST/Type.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/Type.h (original)<br>
+++ cfe/trunk/include/clang/AST/Type.h Mon Jun 24 12:51:48 2013<br>
@@ -1991,6 +1991,44 @@ public:<br>
   static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }<br>
 };<br>
<br>
+/// \brief Represents a pointer type decayed from an array or function type.<br>
+class DecayedType : public Type, public llvm::FoldingSetNode {<br>
+  QualType OriginalType;<br>
+  QualType DecayedPointer;<br>
+<br>
+  DecayedType(QualType OriginalType, QualType DecayedPointer,<br>
+              QualType CanonicalPtr)<br>
+      : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(),<br>
+             OriginalType->isInstantiationDependentType(),<br>
+             OriginalType->isVariablyModifiedType(),<br>
+             OriginalType->containsUnexpandedParameterPack()),<br>
+        OriginalType(OriginalType), DecayedPointer(DecayedPointer) {<br>
+    assert(isa<PointerType>(DecayedPointer));<br>
+  }<br>
+<br>
+  friend class ASTContext;  // ASTContext creates these.<br>
+<br>
+public:<br>
+  QualType getDecayedType() const { return DecayedPointer; }<br>
+  QualType getOriginalType() const { return OriginalType; }<br>
+<br>
+  QualType getPointeeType() const {<br>
+    return cast<PointerType>(DecayedPointer)->getPointeeType();<br>
+  }<br>
+<br>
+  bool isSugared() const { return true; }<br>
+  QualType desugar() const { return DecayedPointer; }<br>
+<br>
+  void Profile(llvm::FoldingSetNodeID &ID) {<br>
+    Profile(ID, OriginalType);<br>
+  }<br>
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) {<br>
+    ID.AddPointer(OriginalType.getAsOpaquePtr());<br>
+  }<br>
+<br>
+  static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }<br>
+};<br>
+<br>
 /// BlockPointerType - pointer to a block type.<br>
 /// This type is to represent types syntactically represented as<br>
 /// "void (^)(int)", etc. Pointee is required to always be a function type.<br>
<br>
Modified: cfe/trunk/include/clang/AST/TypeLoc.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)<br>
+++ cfe/trunk/include/clang/AST/TypeLoc.h Mon Jun 24 12:51:48 2013<br>
@@ -974,6 +974,40 @@ inline TypeLoc TypeLoc::IgnoreParens() c<br>
   return *this;<br>
 }<br>
<br>
+<br>
+struct DecayedLocInfo { }; // Nothing.<br>
+<br>
+/// \brief Wrapper for source info for pointers decayed from arrays and<br>
+/// funcitons.<br></blockquote><div><br></div><div style>Typo "funcitons".</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc,<br>
+                                              DecayedType, DecayedLocInfo> {<br>
+public:<br>
+  TypeLoc getOriginalLoc() const {<br>
+    return getInnerTypeLoc();<br>
+  }<br>
+<br>
+  void initializeLocal(ASTContext &Context, SourceLocation Loc) {<br>
+    // do nothing<br>
+  }<br>
+<br>
+  QualType getInnerType() const {<br>
+    // The inner type is the undecayed type, since that's what we have source<br>
+    // location information for.<br>
+    return getTypePtr()->getOriginalType();<br>
+  }<br>
+<br>
+  SourceRange getLocalSourceRange() const {<br>
+    return SourceRange();<br>
+  }<br>
+<br>
+  unsigned getLocalDataSize() const {<br>
+    // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique<br>
+    // anyway.  TypeLocBuilder can't handle data sizes of 1.<br>
+    return 0;  // No data.<br>
+  }<br>
+};<br>
+<br>
+<br>
 struct PointerLikeLocInfo {<br>
   SourceLocation StarLoc;<br>
 };<br>
<br>
Modified: cfe/trunk/include/clang/AST/TypeNodes.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)<br>
+++ cfe/trunk/include/clang/AST/TypeNodes.def Mon Jun 24 12:51:48 2013<br>
@@ -81,6 +81,7 @@ TYPE(FunctionNoProto, FunctionType)<br>
 DEPENDENT_TYPE(UnresolvedUsing, Type)<br>
 NON_CANONICAL_TYPE(Paren, Type)<br>
 NON_CANONICAL_TYPE(Typedef, Type)<br>
+NON_CANONICAL_TYPE(Decayed, Type)<br>
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)<br>
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type)<br>
 NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type)<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Jun 24 12:51:48 2013<br>
@@ -836,7 +836,9 @@ namespace clang {<br>
       /// \brief A UnaryTransformType record.<br>
       TYPE_UNARY_TRANSFORM       = 39,<br>
       /// \brief An AtomicType record.<br>
-      TYPE_ATOMIC                = 40<br>
+      TYPE_ATOMIC                = 40,<br>
+      /// \brief A DecayedType record.<br>
+      TYPE_DECAYED               = 41<br>
     };<br>
<br>
     /// \brief The type IDs for special types constructed by semantic<br>
<br>
Modified: cfe/trunk/lib/AST/ASTContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ASTContext.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Jun 24 12:51:48 2013<br>
@@ -1615,6 +1615,8 @@ ASTContext::getTypeInfoImpl(const Type *<br>
   }<br>
   case Type::ObjCObject:<br>
     return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());<br>
+  case Type::Decayed:<br>
+    return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());<br>
   case Type::ObjCInterface: {<br>
     const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);<br>
     const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());<br>
@@ -2167,6 +2169,45 @@ QualType ASTContext::getPointerType(Qual<br>
   return QualType(New, 0);<br>
 }<br>
<br>
+QualType ASTContext::getDecayedType(QualType T) const {<br>
+  assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");<br>
+<br>
+  llvm::FoldingSetNodeID ID;<br>
+  DecayedType::Profile(ID, T);<br>
+  void *InsertPos = 0;<br>
+  if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos))<br>
+    return QualType(DT, 0);<br>
+<br>
+  QualType Decayed;<br>
+<br>
+  // C99 6.7.5.3p7:<br>
+  //   A declaration of a parameter as "array of type" shall be<br>
+  //   adjusted to "qualified pointer to type", where the type<br>
+  //   qualifiers (if any) are those specified within the [ and ] of<br>
+  //   the array type derivation.<br>
+  if (T->isArrayType())<br>
+    Decayed = getArrayDecayedType(T);<br>
+<br>
+  // C99 6.7.5.3p8:<br>
+  //   A declaration of a parameter as "function returning type"<br>
+  //   shall be adjusted to "pointer to function returning type", as<br>
+  //   in 6.3.2.1.<br>
+  if (T->isFunctionType())<br>
+    Decayed = getPointerType(T);<br>
+<br>
+  QualType Canonical = getCanonicalType(Decayed);<br>
+<br>
+  // Get the new insert position for the node we care about.<br>
+  DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos);<br>
+  assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;<br>
+<br>
+  DecayedType *New =<br>
+      new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);<br>
+  Types.push_back(New);<br>
+  DecayedTypes.InsertNode(New, InsertPos);<br>
+  return QualType(New, 0);<br>
+}<br>
+<br>
 /// getBlockPointerType - Return the uniqued reference to the type for<br>
 /// a pointer to the specified block.<br>
 QualType ASTContext::getBlockPointerType(QualType T) const {<br>
@@ -4154,22 +4195,9 @@ const ArrayType *ASTContext::getAsArrayT<br>
 }<br>
<br>
 QualType ASTContext::getAdjustedParameterType(QualType T) const {<br>
-  // C99 6.7.5.3p7:<br>
-  //   A declaration of a parameter as "array of type" shall be<br>
-  //   adjusted to "qualified pointer to type", where the type<br>
-  //   qualifiers (if any) are those specified within the [ and ] of<br>
-  //   the array type derivation.<br>
-  if (T->isArrayType())<br>
-    return getArrayDecayedType(T);<br>
-<br>
-  // C99 6.7.5.3p8:<br>
-  //   A declaration of a parameter as "function returning type"<br>
-  //   shall be adjusted to "pointer to function returning type", as<br>
-  //   in 6.3.2.1.<br>
-  if (T->isFunctionType())<br>
-    return getPointerType(T);<br>
-<br>
-  return T;<br>
+  if (T->isArrayType() || T->isFunctionType())<br>
+    return getDecayedType(T);<br>
+  return T;<br>
 }<br>
<br>
 QualType ASTContext::getSignatureParameterType(QualType T) const {<br>
<br>
Modified: cfe/trunk/lib/AST/ASTImporter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)<br>
+++ cfe/trunk/lib/AST/ASTImporter.cpp Mon Jun 24 12:51:48 2013<br>
@@ -400,6 +400,13 @@ static bool IsStructurallyEquivalent(Str<br>
       return false;<br>
     break;<br>
<br>
+  case Type::Decayed:<br>
+    if (!IsStructurallyEquivalent(Context,<br>
+                                  cast<DecayedType>(T1)->getPointeeType(),<br>
+                                  cast<DecayedType>(T2)->getPointeeType()))<br>
+      return false;<br>
+    break;<br>
+<br>
   case Type::Pointer:<br>
     if (!IsStructurallyEquivalent(Context,<br>
                                   cast<PointerType>(T1)->getPointeeType(),<br>
<br>
Modified: cfe/trunk/lib/AST/Decl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/Decl.cpp (original)<br>
+++ cfe/trunk/lib/AST/Decl.cpp Mon Jun 24 12:51:48 2013<br>
@@ -1995,6 +1995,14 @@ ParmVarDecl *ParmVarDecl::Create(ASTCont<br>
                              S, DefArg);<br>
 }<br>
<br>
+QualType ParmVarDecl::getOriginalType() const {<br>
+  TypeSourceInfo *TSI = getTypeSourceInfo();<br>
+  QualType T = TSI ? TSI->getType() : getType();<br>
+  if (const DecayedType *DT = dyn_cast<DecayedType>(T))<br>
+    return DT->getOriginalType();<br>
+  return T;<br>
+}<br>
+<br>
 ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {<br>
   void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ParmVarDecl));<br>
   return new (Mem) ParmVarDecl(ParmVar, 0, SourceLocation(), SourceLocation(),<br>
<br>
Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)<br>
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon Jun 24 12:51:48 2013<br>
@@ -828,6 +828,7 @@ void CXXNameMangler::mangleUnresolvedPre<br>
     switch (type->getTypeClass()) {<br>
     case Type::Builtin:<br>
     case Type::Complex:<br>
+    case Type::Decayed:<br>
     case Type::Pointer:<br>
     case Type::BlockPointer:<br>
     case Type::LValueReference:<br>
<br>
Modified: cfe/trunk/lib/AST/TypePrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/TypePrinter.cpp Mon Jun 24 12:51:48 2013<br>
@@ -201,6 +201,7 @@ bool TypePrinter::canPrefixQualifiers(co<br>
       NeedARCStrongQualifier = true;<br>
       // Fall through<br>
<br>
+    case Type::Decayed:<br>
     case Type::Pointer:<br>
     case Type::BlockPointer:<br>
     case Type::LValueReference:<br>
@@ -468,6 +469,14 @@ void TypePrinter::printVariableArrayAfte<br>
   printAfter(T->getElementType(), OS);<br>
 }<br>
<br>
+void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {<br>
+  // Print as though it's a pointer.<br>
+  printBefore(T->getDecayedType(), OS);<br>
+}<br>
+void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {<br>
+  printAfter(T->getDecayedType(), OS);<br>
+}<br>
+<br>
 void TypePrinter::printDependentSizedArrayBefore(<br>
                                                const DependentSizedArrayType *T,<br>
                                                raw_ostream &OS) {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Jun 24 12:51:48 2013<br>
@@ -2069,6 +2069,10 @@ llvm::DIType CGDebugInfo::CreateTypeNode<br>
     return CreateType(cast<ComplexType>(Ty));<br>
   case Type::Pointer:<br>
     return CreateType(cast<PointerType>(Ty), Unit);<br>
+  case Type::Decayed:<br>
+    // Decayed types are just pointers in LLVM and DWARF.<br>
+    return CreateType(<br>
+        cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit);<br>
   case Type::BlockPointer:<br>
     return CreateType(cast<BlockPointerType>(Ty), Unit);<br>
   case Type::Typedef:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon Jun 24 12:51:48 2013<br>
@@ -1273,6 +1273,10 @@ void CodeGenFunction::EmitVariablyModifi<br>
     case Type::ObjCObjectPointer:<br>
       llvm_unreachable("type class is never variably-modified!");<br>
<br>
+    case Type::Decayed:<br>
+      type = cast<DecayedType>(ty)->getPointeeType();<br>
+      break;<br>
+<br>
     case Type::Pointer:<br>
       type = cast<PointerType>(ty)->getPointeeType();<br>
       break;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 24 12:51:48 2013<br>
@@ -4021,6 +4021,8 @@ bool Sema::GatherArgumentsForCall(Source<br>
<br>
 static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) {<br>
   TypeLoc TL = PVD->getTypeSourceInfo()->getTypeLoc();<br>
+  if (DecayedTypeLoc DTL = TL.getAs<DecayedTypeLoc>())<br>
+    TL = DTL.getOriginalLoc();<br>
   if (ArrayTypeLoc ATL = TL.getAs<ArrayTypeLoc>())<br>
     S.Diag(PVD->getLocation(), diag::note_callee_static_array)<br>
       << ATL.getLocalSourceRange();<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Jun 24 12:51:48 2013<br>
@@ -2844,10 +2844,6 @@ static TypeSourceInfo *GetFullTypeForDec<br>
           QualType ArgTy = Param->getType();<br>
           assert(!ArgTy.isNull() && "Couldn't parse type?");<br>
<br>
-          // Adjust the parameter type.<br>
-          assert((ArgTy == Context.getAdjustedParameterType(ArgTy)) &&<br>
-                 "Unadjusted type?");<br>
-<br>
           // Look for 'void'.  void is allowed only as a single argument to a<br>
           // function with no other parameters (C99 6.7.5.3p10).  We record<br>
           // int(void) as a FunctionProtoType with an empty argument list.<br>
@@ -3577,6 +3573,9 @@ namespace {<br>
     void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {<br>
       llvm_unreachable("qualified type locs not expected here!");<br>
     }<br>
+    void VisitDecayedTypeLoc(DecayedTypeLoc TL) {<br>
+      llvm_unreachable("decayed type locs not expected here!");<br>
+    }<br>
<br>
     void VisitAttributedTypeLoc(AttributedTypeLoc TL) {<br>
       fillAttributedTypeLoc(TL, Chunk.getAttrs());<br>
<br>
Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Jun 24 12:51:48 2013<br>
@@ -3586,6 +3586,22 @@ QualType TreeTransform<Derived>::Transfo<br>
 }<br>
<br>
 template<typename Derived><br>
+QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,<br>
+                                                      DecayedTypeLoc TL) {<br>
+  QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());<br>
+  if (OriginalType.isNull())<br>
+    return QualType();<br>
+<br>
+  QualType Result = TL.getType();<br>
+  if (getDerived().AlwaysRebuild() ||<br>
+      OriginalType != TL.getOriginalLoc().getType())<br>
+    Result = SemaRef.Context.getDecayedType(OriginalType);<br>
+  TLB.push<DecayedTypeLoc>(Result);<br>
+  // Nothing to set for DecayedTypeLoc.<br>
+  return Result;<br>
+}<br>
+<br>
+template<typename Derived><br>
 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,<br>
                                                       PointerTypeLoc TL) {<br>
   QualType PointeeType<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Jun 24 12:51:48 2013<br>
@@ -4531,6 +4531,18 @@ QualType ASTReader::readTypeRecord(unsig<br>
     return Context.getPointerType(PointeeType);<br>
   }<br>
<br>
+  case TYPE_DECAYED: {<br>
+    if (Record.size() != 1) {<br>
+      Error("Incorrect encoding of decayed type");<br>
+      return QualType();<br>
+    }<br>
+    QualType OriginalType = readType(*Loc.F, Record, Idx);<br>
+    QualType DT = Context.getAdjustedParameterType(OriginalType);<br>
+    if (!isa<DecayedType>(DT))<br>
+      Error("Decayed type does not decay");<br>
+    return DT;<br>
+  }<br>
+<br>
   case TYPE_BLOCK_POINTER: {<br>
     if (Record.size() != 1) {<br>
       Error("Incorrect encoding of block pointer type");<br>
@@ -4977,6 +4989,9 @@ void TypeLocReader::VisitComplexTypeLoc(<br>
 void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) {<br>
   TL.setStarLoc(ReadSourceLocation(Record, Idx));<br>
 }<br>
+void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) {<br>
+  // nothing to do<br>
+}<br>
 void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {<br>
   TL.setCaretLoc(ReadSourceLocation(Record, Idx));<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Jun 24 12:51:48 2013<br>
@@ -108,6 +108,11 @@ void ASTTypeWriter::VisitPointerType(con<br>
   Code = TYPE_POINTER;<br>
 }<br>
<br>
+void ASTTypeWriter::VisitDecayedType(const DecayedType *T) {<br>
+  Writer.AddTypeRef(T->getOriginalType(), Record);<br>
+  Code = TYPE_DECAYED;<br>
+}<br>
+<br>
 void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) {<br>
   Writer.AddTypeRef(T->getPointeeType(), Record);<br>
   Code = TYPE_BLOCK_POINTER;<br>
@@ -447,6 +452,9 @@ void TypeLocWriter::VisitComplexTypeLoc(<br>
 void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) {<br>
   Writer.AddSourceLocation(TL.getStarLoc(), Record);<br>
 }<br>
+void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) {<br>
+  // nothing to do<br>
+}<br>
 void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {<br>
   Writer.AddSourceLocation(TL.getCaretLoc(), Record);<br>
 }<br>
<br>
Modified: cfe/trunk/test/Index/print-type.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type.c?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/print-type.c?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Index/print-type.c (original)<br>
+++ cfe/trunk/test/Index/print-type.c Mon Jun 24 12:51:48 2013<br>
@@ -35,7 +35,7 @@ typedef int __attribute__((vector_size(1<br>
 // CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1]<br>
 // CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]<br>
 // CHECK: ArraySubscriptExpr= [type=int] [typekind=Int] [isPOD=1]<br>
-// CHECK: DeclRefExpr=arr:3:40 [type=int *] [typekind=Pointer] [isPOD=1]<br>
+// CHECK: UnexposedExpr=arr:3:40 [type=int *] [typekind=Unexposed] [canonicaltype=int *] [canonicaltypekind=Pointer] [isPOD=1]<br>
 // CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]<br>
 // CHECK: TypedefDecl=OtherType:8:16 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]<br>
 // CHECK: TypedefDecl=ArrayType:9:13 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int [5]] [canonicaltypekind=ConstantArray] [isPOD=1]<br>
<br>
Modified: cfe/trunk/test/Sema/function.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/function.c?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/function.c?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/function.c (original)<br>
+++ cfe/trunk/test/Sema/function.c Mon Jun 24 12:51:48 2013<br>
@@ -103,3 +103,13 @@ int func_e(int x) {<br>
   }<br>
   return x + 3;<br>
 }<br>
+<br>
+void decays(int a[3][3]);   // expected-note {{passing argument to parameter 'a' here}}<br>
+void no_decay(int (*a)[3]); // expected-note {{passing argument to parameter 'a' here}}<br>
+<br>
+void t22(int *ptr, int (*array)[3]) {<br>
+  decays(ptr);   // expected-warning {{incompatible pointer types passing 'int *' to parameter of type 'int (*)[3]'}}<br>
+  no_decay(ptr); // expected-warning {{incompatible pointer types passing 'int *' to parameter of type 'int (*)[3]'}}<br>
+  decays(array);<br>
+  no_decay(array);<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/function-type-qual.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-type-qual.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/function-type-qual.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/SemaCXX/function-type-qual.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/function-type-qual.cpp Mon Jun 24 12:51:48 2013<br>
@@ -29,3 +29,11 @@ cfn C::*mpg;<br>
<br>
 // Don't crash!<br>
 void (PR14171)() const; // expected-error {{non-member function cannot have 'const' qualifier}}<br>
+<br>
+// Test template instantiation of decayed array types.  Not really related to<br>
+// type quals.<br>
+template <typename T> void arrayDecay(const T a[]) { }<br>
+void instantiateArrayDecay() {<br>
+  int a[1];<br>
+  arrayDecay(a);<br>
+}<br>
<br>
Modified: cfe/trunk/tools/libclang/CIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/CIndex.cpp (original)<br>
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Jun 24 12:51:48 2013<br>
@@ -1546,6 +1546,10 @@ bool CursorVisitor::VisitArrayTypeLoc(Ar<br>
   return false;<br>
 }<br>
<br>
+bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {<br>
+  return Visit(TL.getOriginalLoc());<br>
+}<br>
+<br>
 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(<br>
                                              TemplateSpecializationTypeLoc TL) {<br>
   // Visit the template name.<br>
<br>
Modified: cfe/trunk/tools/libclang/RecursiveASTVisitor.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=184763&r1=184762&r2=184763&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=184763&r1=184762&r2=184763&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/tools/libclang/RecursiveASTVisitor.h (original)<br>
+++ cfe/trunk/tools/libclang/RecursiveASTVisitor.h Mon Jun 24 12:51:48 2013<br>
@@ -786,6 +786,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, {<br>
     TRY_TO(TraverseType(T->getPointeeType()));<br>
   })<br>
<br>
+DEF_TRAVERSE_TYPE(DecayedType, {<br>
+    TRY_TO(TraverseType(T->getOriginalType()));<br>
+  })<br>
+<br>
 DEF_TRAVERSE_TYPE(ConstantArrayType, {<br>
     TRY_TO(TraverseType(T->getElementType()));<br>
   })<br>
@@ -992,6 +996,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType,<br>
     TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));<br>
   })<br>
<br>
+DEF_TRAVERSE_TYPELOC(DecayedType, {<br>
+    TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));<br>
+  })<br>
+<br>
 template<typename Derived><br>
 bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {<br>
   // This isn't available for ArrayType, but is for the ArrayTypeLoc.<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" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>