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