Thanks!
On 4 December 2013 20:23, Reid Kleckner <[email protected]> wrote: > Author: rnk > Date: Wed Dec 4 19:23:43 2013 > New Revision: 196451 > > URL: http://llvm.org/viewvc/llvm-project?rev=196451&view=rev > Log: > Add an AdjustedType sugar node for adjusting calling conventions > > Summary: > In general, this type node can be used to represent any type adjustment > that occurs implicitly without losing type sugar. The immediate use of > this is to adjust the calling conventions of member function pointer > types without breaking template instantiation. > > Fixes PR17996. > > Reviewers: rsmith > > Differential Revision: http://llvm-reviews.chandlerc.com/D2332 > > Modified: > cfe/trunk/include/clang/AST/ASTContext.h > cfe/trunk/include/clang/AST/RecursiveASTVisitor.h > cfe/trunk/include/clang/AST/Type.h > cfe/trunk/include/clang/AST/TypeLoc.h > cfe/trunk/include/clang/AST/TypeNodes.def > cfe/trunk/include/clang/Serialization/ASTBitCodes.h > cfe/trunk/lib/AST/ASTContext.cpp > cfe/trunk/lib/AST/ASTDiagnostic.cpp > cfe/trunk/lib/AST/ASTImporter.cpp > cfe/trunk/lib/AST/Comment.cpp > cfe/trunk/lib/AST/Decl.cpp > cfe/trunk/lib/AST/DeclPrinter.cpp > cfe/trunk/lib/AST/ItaniumMangle.cpp > cfe/trunk/lib/AST/Type.cpp > cfe/trunk/lib/AST/TypePrinter.cpp > cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > cfe/trunk/lib/CodeGen/CodeGenFunction.cpp > cfe/trunk/lib/Sema/SemaType.cpp > cfe/trunk/lib/Sema/TreeTransform.h > cfe/trunk/lib/Serialization/ASTReader.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/test/SemaCXX/calling-conv-compat.cpp > cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp > cfe/trunk/tools/libclang/CIndex.cpp > cfe/trunk/tools/libclang/RecursiveASTVisitor.h > > Modified: cfe/trunk/include/clang/AST/ASTContext.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/ASTContext.h (original) > +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Dec 4 19:23:43 2013 > @@ -82,7 +82,7 @@ class ASTContext : public RefCountedBase > mutable llvm::FoldingSet<ExtQuals> ExtQualNodes; > mutable llvm::FoldingSet<ComplexType> ComplexTypes; > mutable llvm::FoldingSet<PointerType> PointerTypes; > - mutable llvm::FoldingSet<DecayedType> DecayedTypes; > + mutable llvm::FoldingSet<AdjustedType> AdjustedTypes; > mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes; > mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes; > mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes; > @@ -915,6 +915,14 @@ public: > return CanQualType::CreateUnsafe(getPointerType((QualType) T)); > } > > + /// \brief Return the uniqued reference to a type adjusted from the > original > + /// type to a new type. > + QualType getAdjustedType(QualType Orig, QualType New) const; > + CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const { > + return CanQualType::CreateUnsafe( > + getAdjustedType((QualType)Orig, (QualType)New)); > + } > + > /// \brief Return the uniqued reference to the decayed version of the given > /// type. Can only be called on array and function types which decay to > /// pointer types. > > Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) > +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Dec 4 19:23:43 2013 > @@ -874,6 +874,10 @@ DEF_TRAVERSE_TYPE(MemberPointerType, { > TRY_TO(TraverseType(T->getPointeeType())); > }) > > +DEF_TRAVERSE_TYPE(AdjustedType, { > + TRY_TO(TraverseType(T->getOriginalType())); > + }) > + > DEF_TRAVERSE_TYPE(DecayedType, { > TRY_TO(TraverseType(T->getOriginalType())); > }) > @@ -1084,6 +1088,10 @@ DEF_TRAVERSE_TYPELOC(MemberPointerType, > TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); > }) > > +DEF_TRAVERSE_TYPELOC(AdjustedType, { > + TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); > + }) > + > DEF_TRAVERSE_TYPELOC(DecayedType, { > TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); > }) > > Modified: cfe/trunk/include/clang/AST/Type.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/Type.h (original) > +++ cfe/trunk/include/clang/AST/Type.h Wed Dec 4 19:23:43 2013 > @@ -1996,39 +1996,59 @@ public: > static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } > }; > > -/// \brief Represents a pointer type decayed from an array or function type. > -class DecayedType : public Type, public llvm::FoldingSetNode { > - QualType OriginalType; > - QualType DecayedPointer; > - > - DecayedType(QualType OriginalType, QualType DecayedPointer, > - QualType CanonicalPtr) > - : Type(Decayed, CanonicalPtr, OriginalType->isDependentType(), > - OriginalType->isInstantiationDependentType(), > - OriginalType->isVariablyModifiedType(), > - OriginalType->containsUnexpandedParameterPack()), > - OriginalType(OriginalType), DecayedPointer(DecayedPointer) { > - assert(isa<PointerType>(DecayedPointer)); > - } > +/// \brief Represents a type which was implicitly adjusted by the semantic > +/// engine for arbitrary reasons. For example, array and function types can > +/// decay, and function types can have their calling conventions adjusted. > +class AdjustedType : public Type, public llvm::FoldingSetNode { > + QualType OriginalTy; > + QualType AdjustedTy; > + > +protected: > + AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, > + QualType CanonicalPtr) > + : Type(TC, CanonicalPtr, OriginalTy->isDependentType(), > + OriginalTy->isInstantiationDependentType(), > + OriginalTy->isVariablyModifiedType(), > + OriginalTy->containsUnexpandedParameterPack()), > + OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} > > friend class ASTContext; // ASTContext creates these. > > public: > - QualType getDecayedType() const { return DecayedPointer; } > - QualType getOriginalType() const { return OriginalType; } > - > - QualType getPointeeType() const { > - return cast<PointerType>(DecayedPointer)->getPointeeType(); > - } > + QualType getOriginalType() const { return OriginalTy; } > + QualType getAdjustedType() const { return AdjustedTy; } > > bool isSugared() const { return true; } > - QualType desugar() const { return DecayedPointer; } > + QualType desugar() const { return AdjustedTy; } > > void Profile(llvm::FoldingSetNodeID &ID) { > - Profile(ID, OriginalType); > + Profile(ID, OriginalTy, AdjustedTy); > } > - static void Profile(llvm::FoldingSetNodeID &ID, QualType OriginalType) { > - ID.AddPointer(OriginalType.getAsOpaquePtr()); > + static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType > New) { > + ID.AddPointer(Orig.getAsOpaquePtr()); > + ID.AddPointer(New.getAsOpaquePtr()); > + } > + > + static bool classof(const Type *T) { > + return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed; > + } > +}; > + > +/// \brief Represents a pointer type decayed from an array or function type. > +class DecayedType : public AdjustedType { > + > + DecayedType(QualType OriginalType, QualType DecayedPtr, QualType > CanonicalPtr) > + : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) { > + assert(isa<PointerType>(getAdjustedType())); > + } > + > + friend class ASTContext; // ASTContext creates these. > + > +public: > + QualType getDecayedType() const { return getAdjustedType(); } > + > + QualType getPointeeType() const { > + return cast<PointerType>(getDecayedType())->getPointeeType(); > } > > static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } > > Modified: cfe/trunk/include/clang/AST/TypeLoc.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/TypeLoc.h (original) > +++ cfe/trunk/include/clang/AST/TypeLoc.h Wed Dec 4 19:23:43 2013 > @@ -978,12 +978,10 @@ inline TypeLoc TypeLoc::IgnoreParens() c > } > > > -struct DecayedLocInfo { }; // Nothing. > +struct AdjustedLocInfo { }; // Nothing. > > -/// \brief Wrapper for source info for pointers decayed from arrays and > -/// functions. > -class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc, > - DecayedType, DecayedLocInfo> { > +class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, > AdjustedTypeLoc, > + AdjustedType, > AdjustedLocInfo> { > public: > TypeLoc getOriginalLoc() const { > return getInnerTypeLoc(); > @@ -1004,12 +1002,17 @@ public: > } > > unsigned getLocalDataSize() const { > - // sizeof(DecayedLocInfo) is 1, but we don't need its address to be > unique > + // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be > unique > // anyway. TypeLocBuilder can't handle data sizes of 1. > return 0; // No data. > } > }; > > +/// \brief Wrapper for source info for pointers decayed from arrays and > +/// functions. > +class DecayedTypeLoc : public InheritingConcreteTypeLoc< > + AdjustedTypeLoc, DecayedTypeLoc, DecayedType> { > +}; > > struct PointerLikeLocInfo { > SourceLocation StarLoc; > > Modified: cfe/trunk/include/clang/AST/TypeNodes.def > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/TypeNodes.def (original) > +++ cfe/trunk/include/clang/AST/TypeNodes.def Wed Dec 4 19:23:43 2013 > @@ -81,7 +81,8 @@ TYPE(FunctionNoProto, FunctionType) > DEPENDENT_TYPE(UnresolvedUsing, Type) > NON_CANONICAL_TYPE(Paren, Type) > NON_CANONICAL_TYPE(Typedef, Type) > -NON_CANONICAL_TYPE(Decayed, Type) > +NON_CANONICAL_TYPE(Adjusted, Type) > +NON_CANONICAL_TYPE(Decayed, AdjustedType) > NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) > NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type) > NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type) > > Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) > +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Dec 4 19:23:43 > 2013 > @@ -841,7 +841,9 @@ namespace clang { > /// \brief An AtomicType record. > TYPE_ATOMIC = 40, > /// \brief A DecayedType record. > - TYPE_DECAYED = 41 > + TYPE_DECAYED = 41, > + /// \brief An AdjustedType record. > + TYPE_ADJUSTED = 42 > }; > > /// \brief The type IDs for special types constructed by semantic > > Modified: cfe/trunk/lib/AST/ASTContext.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTContext.cpp (original) > +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Dec 4 19:23:43 2013 > @@ -1632,8 +1632,9 @@ ASTContext::getTypeInfoImpl(const Type * > } > case Type::ObjCObject: > return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr()); > + case Type::Adjusted: > case Type::Decayed: > - return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr()); > + return > getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr()); > case Type::ObjCInterface: { > const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T); > const ASTRecordLayout &Layout = > getASTObjCInterfaceLayout(ObjCI->getDecl()); > @@ -2163,14 +2164,29 @@ QualType ASTContext::getPointerType(Qual > return QualType(New, 0); > } > > -QualType ASTContext::getDecayedType(QualType T) const { > - assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); > - > +QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const { > llvm::FoldingSetNodeID ID; > - DecayedType::Profile(ID, T); > + AdjustedType::Profile(ID, Orig, New); > void *InsertPos = 0; > - if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos)) > - return QualType(DT, 0); > + AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); > + if (AT) > + return QualType(AT, 0); > + > + QualType Canonical = getCanonicalType(New); > + > + // Get the new insert position for the node we care about. > + AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); > + assert(AT == 0 && "Shouldn't be in the map!"); > + > + AT = new (*this, TypeAlignment) > + AdjustedType(Type::Adjusted, Orig, New, Canonical); > + Types.push_back(AT); > + AdjustedTypes.InsertNode(AT, InsertPos); > + return QualType(AT, 0); > +} > + > +QualType ASTContext::getDecayedType(QualType T) const { > + assert((T->isArrayType() || T->isFunctionType()) && "T does not decay"); > > QualType Decayed; > > @@ -2189,17 +2205,23 @@ QualType ASTContext::getDecayedType(Qual > if (T->isFunctionType()) > Decayed = getPointerType(T); > > + llvm::FoldingSetNodeID ID; > + AdjustedType::Profile(ID, T, Decayed); > + void *InsertPos = 0; > + AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); > + if (AT) > + return QualType(AT, 0); > + > QualType Canonical = getCanonicalType(Decayed); > > // Get the new insert position for the node we care about. > - DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos); > - assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP; > + AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos); > + assert(AT == 0 && "Shouldn't be in the map!"); > > - DecayedType *New = > - new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); > - Types.push_back(New); > - DecayedTypes.InsertNode(New, InsertPos); > - return QualType(New, 0); > + AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical); > + Types.push_back(AT); > + AdjustedTypes.InsertNode(AT, InsertPos); > + return QualType(AT, 0); > } > > /// getBlockPointerType - Return the uniqued reference to the type for > > Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original) > +++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Wed Dec 4 19:23:43 2013 > @@ -51,6 +51,11 @@ static QualType Desugar(ASTContext &Cont > QT = AT->desugar(); > continue; > } > + // ...or an adjusted type... > + if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) { > + QT = AT->desugar(); > + continue; > + } > // ... or an auto type. > if (const AutoType *AT = dyn_cast<AutoType>(Ty)) { > if (!AT->isSugared()) > > Modified: cfe/trunk/lib/AST/ASTImporter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ASTImporter.cpp (original) > +++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Dec 4 19:23:43 2013 > @@ -407,10 +407,11 @@ static bool IsStructurallyEquivalent(Str > return false; > break; > > + case Type::Adjusted: > case Type::Decayed: > if (!IsStructurallyEquivalent(Context, > - cast<DecayedType>(T1)->getPointeeType(), > - cast<DecayedType>(T2)->getPointeeType())) > + cast<AdjustedType>(T1)->getOriginalType(), > + cast<AdjustedType>(T2)->getOriginalType())) > return false; > break; > > > Modified: cfe/trunk/lib/AST/Comment.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Comment.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Comment.cpp (original) > +++ cfe/trunk/lib/AST/Comment.cpp Wed Dec 4 19:23:43 2013 > @@ -251,6 +251,11 @@ void DeclInfo::fill() { > TL = PointerTL.getPointeeLoc().getUnqualifiedLoc(); > continue; > } > + // Look through adjusted types. > + if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) { > + TL = ATL.getOriginalLoc(); > + continue; > + } > if (BlockPointerTypeLoc BlockPointerTL = > TL.getAs<BlockPointerTypeLoc>()) { > TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc(); > > Modified: cfe/trunk/lib/AST/Decl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Decl.cpp (original) > +++ cfe/trunk/lib/AST/Decl.cpp Wed Dec 4 19:23:43 2013 > @@ -2508,11 +2508,8 @@ unsigned FunctionDecl::getBuiltinID() co > /// based on its FunctionType. This is the length of the ParamInfo array > /// after it has been created. > unsigned FunctionDecl::getNumParams() const { > - const FunctionType *FT = getType()->castAs<FunctionType>(); > - if (isa<FunctionNoProtoType>(FT)) > - return 0; > - return cast<FunctionProtoType>(FT)->getNumArgs(); > - > + const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>(); > + return FPT ? FPT->getNumArgs() : 0; > } > > void FunctionDecl::setParams(ASTContext &C, > > Modified: cfe/trunk/lib/AST/DeclPrinter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/DeclPrinter.cpp (original) > +++ cfe/trunk/lib/AST/DeclPrinter.cpp Wed Dec 4 19:23:43 2013 > @@ -423,8 +423,7 @@ void DeclPrinter::VisitFunctionDecl(Func > Ty = PT->getInnerType(); > } > > - if (isa<FunctionType>(Ty)) { > - const FunctionType *AFT = Ty->getAs<FunctionType>(); > + if (const FunctionType *AFT = Ty->getAs<FunctionType>()) { > const FunctionProtoType *FT = 0; > if (D->hasWrittenPrototype()) > FT = dyn_cast<FunctionProtoType>(AFT); > > Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original) > +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Dec 4 19:23:43 2013 > @@ -833,6 +833,7 @@ void CXXNameMangler::mangleUnresolvedPre > switch (type->getTypeClass()) { > case Type::Builtin: > case Type::Complex: > + case Type::Adjusted: > case Type::Decayed: > case Type::Pointer: > case Type::BlockPointer: > > Modified: cfe/trunk/lib/AST/Type.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/Type.cpp (original) > +++ cfe/trunk/lib/AST/Type.cpp Wed Dec 4 19:23:43 2013 > @@ -593,6 +593,9 @@ namespace { > AutoType *VisitAttributedType(const AttributedType *T) { > return Visit(T->getModifiedType()); > } > + AutoType *VisitAdjustedType(const AdjustedType *T) { > + return Visit(T->getOriginalType()); > + } > }; > } > > > Modified: cfe/trunk/lib/AST/TypePrinter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/TypePrinter.cpp (original) > +++ cfe/trunk/lib/AST/TypePrinter.cpp Wed Dec 4 19:23:43 2013 > @@ -204,6 +204,7 @@ bool TypePrinter::canPrefixQualifiers(co > NeedARCStrongQualifier = true; > // Fall through > > + case Type::Adjusted: > case Type::Decayed: > case Type::Pointer: > case Type::BlockPointer: > @@ -471,12 +472,21 @@ void TypePrinter::printVariableArrayAfte > printAfter(T->getElementType(), OS); > } > > +void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream > &OS) { > + // Print the adjusted representation, otherwise the adjustment will be > + // invisible. > + printBefore(T->getAdjustedType(), OS); > +} > +void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) > { > + printAfter(T->getAdjustedType(), OS); > +} > + > void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) { > // Print as though it's a pointer. > - printBefore(T->getDecayedType(), OS); > + printAdjustedBefore(T, OS); > } > void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) { > - printAfter(T->getDecayedType(), OS); > + printAdjustedAfter(T, OS); > } > > void TypePrinter::printDependentSizedArrayBefore( > > Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Dec 4 19:23:43 2013 > @@ -2123,10 +2123,11 @@ llvm::DIType CGDebugInfo::CreateTypeNode > return CreateType(cast<ComplexType>(Ty)); > case Type::Pointer: > return CreateType(cast<PointerType>(Ty), Unit); > + case Type::Adjusted: > case Type::Decayed: > - // Decayed types are just pointers in LLVM and DWARF. > + // Decayed and adjusted types use the adjusted type in LLVM and DWARF. > return CreateType( > - cast<PointerType>(cast<DecayedType>(Ty)->getDecayedType()), Unit); > + cast<PointerType>(cast<AdjustedType>(Ty)->getAdjustedType()), Unit); > case Type::BlockPointer: > return CreateType(cast<BlockPointerType>(Ty), Unit); > case Type::Typedef: > > Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Dec 4 19:23:43 2013 > @@ -1308,6 +1308,10 @@ void CodeGenFunction::EmitVariablyModifi > case Type::ObjCObjectPointer: > llvm_unreachable("type class is never variably-modified!"); > > + case Type::Adjusted: > + type = cast<AdjustedType>(ty)->getAdjustedType(); > + break; > + > case Type::Decayed: > type = cast<DecayedType>(ty)->getPointeeType(); > break; > > Modified: cfe/trunk/lib/Sema/SemaType.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Dec 4 19:23:43 2013 > @@ -1812,7 +1812,10 @@ QualType Sema::BuildMemberPointerType(Qu > } > } > > - // FIXME: Adjust member function pointer calling conventions. > + // Adjust the default free function calling convention to the default > method > + // calling convention. > + if (T->isFunctionType()) > + adjustMemberFunctionCC(T, /*IsStatic=*/false); > > return Context.getMemberPointerType(T, Class.getTypePtr()); > } > @@ -3681,6 +3684,9 @@ namespace { > void VisitAttributedTypeLoc(AttributedTypeLoc TL) { > fillAttributedTypeLoc(TL, Chunk.getAttrs()); > } > + void VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { > + // nothing > + } > void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { > assert(Chunk.Kind == DeclaratorChunk::BlockPointer); > TL.setCaretLoc(Chunk.Loc); > @@ -3836,6 +3842,10 @@ Sema::GetTypeSourceInfoForDeclarator(Dec > CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); > } > > + // FIXME: Ordering here? > + while (AdjustedTypeLoc TL = CurrTL.getAs<AdjustedTypeLoc>()) > + CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc(); > + > DeclaratorLocFiller(Context, D.getTypeObject(i)).Visit(CurrTL); > CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); > } > @@ -4589,14 +4599,15 @@ void Sema::adjustMemberFunctionCC(QualTy > const FunctionType *FT = T->castAs<FunctionType>(); > bool IsVariadic = (isa<FunctionProtoType>(FT) && > cast<FunctionProtoType>(FT)->isVariadic()); > - CallingConv CC = FT->getCallConv(); > > // Only adjust types with the default convention. For example, on Windows > we > // should adjust a __cdecl type to __thiscall for instance methods, and a > // __thiscall type to __cdecl for static methods. > - CallingConv DefaultCC = > + CallingConv CurCC = FT->getCallConv(); > + CallingConv FromCC = > Context.getDefaultCallingConvention(IsVariadic, IsStatic); > - if (CC != DefaultCC) > + CallingConv ToCC = Context.getDefaultCallingConvention(IsVariadic, > !IsStatic); > + if (CurCC != FromCC || FromCC == ToCC) > return; > > // Check if there was an explicit attribute, but only look through parens. > @@ -4609,12 +4620,8 @@ void Sema::adjustMemberFunctionCC(QualTy > R = AT->getModifiedType().IgnoreParens(); > } > > - // FIXME: This loses sugar. This should probably be fixed with an implicit > - // AttributedType node that adjusts the convention. > - CC = Context.getDefaultCallingConvention(IsVariadic, !IsStatic); > - FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC)); > - FunctionTypeUnwrapper Unwrapped(*this, T); > - T = Unwrapped.wrap(*this, FT); > + FT = Context.adjustFunctionType(FT, > FT->getExtInfo().withCallingConv(ToCC)); > + T = Context.getAdjustedType(T, QualType(FT, T.getQualifiers())); > } > > /// Handle OpenCL image access qualifiers: read_only, write_only, read_write > > Modified: cfe/trunk/lib/Sema/TreeTransform.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/TreeTransform.h (original) > +++ cfe/trunk/lib/Sema/TreeTransform.h Wed Dec 4 19:23:43 2013 > @@ -3664,6 +3664,13 @@ QualType TreeTransform<Derived>::Transfo > return TransformTypeSpecType(TLB, T); > } > > +template <typename Derived> > +QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB, > + AdjustedTypeLoc TL) { > + // Adjustments applied during transformation are handled elsewhere. > + return getDerived().TransformType(TLB, TL.getOriginalLoc()); > +} > + > template<typename Derived> > QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB, > DecayedTypeLoc TL) { > @@ -3832,6 +3839,14 @@ TreeTransform<Derived>::TransformMemberP > return QualType(); > } > > + // If we had to adjust the pointee type when building a member pointer, > make > + // sure to push TypeLoc info for it. > + const MemberPointerType *MPT = Result->getAs<MemberPointerType>(); > + if (MPT && PointeeType != MPT->getPointeeType()) { > + assert(isa<AdjustedType>(MPT->getPointeeType())); > + TLB.push<AdjustedTypeLoc>(MPT->getPointeeType()); > + } > + > MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result); > NewTL.setSigilLoc(TL.getSigilLoc()); > NewTL.setClassTInfo(NewClsTInfo); > @@ -9391,8 +9406,8 @@ QualType > TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType, > QualType ClassType, > SourceLocation Sigil) { > - return SemaRef.BuildMemberPointerType(PointeeType, ClassType, > - Sigil, getDerived().getBaseEntity()); > + return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil, > + getDerived().getBaseEntity()); > } > > template<typename Derived> > > Modified: cfe/trunk/lib/Serialization/ASTReader.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Dec 4 19:23:43 2013 > @@ -4548,6 +4548,16 @@ QualType ASTReader::readTypeRecord(unsig > return DT; > } > > + case TYPE_ADJUSTED: { > + if (Record.size() != 2) { > + Error("Incorrect encoding of adjusted type"); > + return QualType(); > + } > + QualType OriginalTy = readType(*Loc.F, Record, Idx); > + QualType AdjustedTy = readType(*Loc.F, Record, Idx); > + return Context.getAdjustedType(OriginalTy, AdjustedTy); > + } > + > case TYPE_BLOCK_POINTER: { > if (Record.size() != 1) { > Error("Incorrect encoding of block pointer type"); > @@ -4997,6 +5007,9 @@ void TypeLocReader::VisitPointerTypeLoc( > void TypeLocReader::VisitDecayedTypeLoc(DecayedTypeLoc TL) { > // nothing to do > } > +void TypeLocReader::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { > + // nothing to do > +} > void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { > TL.setCaretLoc(ReadSourceLocation(Record, Idx)); > } > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Dec 4 19:23:43 2013 > @@ -113,6 +113,12 @@ void ASTTypeWriter::VisitDecayedType(con > Code = TYPE_DECAYED; > } > > +void ASTTypeWriter::VisitAdjustedType(const AdjustedType *T) { > + Writer.AddTypeRef(T->getOriginalType(), Record); > + Writer.AddTypeRef(T->getAdjustedType(), Record); > + Code = TYPE_ADJUSTED; > +} > + > void ASTTypeWriter::VisitBlockPointerType(const BlockPointerType *T) { > Writer.AddTypeRef(T->getPointeeType(), Record); > Code = TYPE_BLOCK_POINTER; > @@ -455,6 +461,9 @@ void TypeLocWriter::VisitPointerTypeLoc( > void TypeLocWriter::VisitDecayedTypeLoc(DecayedTypeLoc TL) { > // nothing to do > } > +void TypeLocWriter::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { > + // nothing to do > +} > void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { > Writer.AddSourceLocation(TL.getCaretLoc(), Record); > } > > Modified: cfe/trunk/test/SemaCXX/calling-conv-compat.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/calling-conv-compat.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/test/SemaCXX/calling-conv-compat.cpp (original) > +++ cfe/trunk/test/SemaCXX/calling-conv-compat.cpp Wed Dec 4 19:23:43 2013 > @@ -351,24 +351,25 @@ typedef void (__cdecl fun_cdecl)(); > typedef void (__stdcall fun_stdcall)(); > typedef void (__fastcall fun_fastcall)(); > > -// FIXME: Adjust cdecl to thiscall when forming a member pointer. > -//fun_default A::*td1 = &A::method_thiscall; > -fun_cdecl A::*td2 = &A::method_cdecl; > +fun_default A::*td1 = &A::method_thiscall; > +fun_cdecl A::*td2 = &A::method_thiscall; > fun_stdcall A::*td3 = &A::method_stdcall; > fun_fastcall A::*td4 = &A::method_fastcall; > > // Round trip the function type through a template, and verify that only > cdecl > // gets adjusted. > -template<typename Fn> struct X { > - typedef Fn A::*p; > -}; > - > -// FIXME: Adjust cdecl to thiscall when forming a member pointer. > -//X<void ()>::p tmpl1 = &A::method_thiscall; > -//X<void __cdecl ()>::p tmpl2 = &A::method_thiscall; > +template<typename Fn> struct X { typedef Fn A::*p; }; > + > +X<void ()>::p tmpl1 = &A::method_thiscall; > +X<void __cdecl ()>::p tmpl2 = &A::method_thiscall; > X<void __stdcall ()>::p tmpl3 = &A::method_stdcall; > X<void __fastcall ()>::p tmpl4 = &A::method_fastcall; > > +X<fun_default >::p tmpl5 = &A::method_thiscall; > +X<fun_cdecl >::p tmpl6 = &A::method_thiscall; > +X<fun_stdcall >::p tmpl7 = &A::method_stdcall; > +X<fun_fastcall>::p tmpl8 = &A::method_fastcall; > + > } // end namespace MemberPointers > > // Test that lambdas that capture nothing convert to cdecl function pointers. > > Modified: cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp (original) > +++ cfe/trunk/test/SemaCXX/decl-microsoft-call-conv.cpp Wed Dec 4 19:23:43 > 2013 > @@ -191,3 +191,15 @@ namespace test5 { > }; > extern template void valarray<int>::bar(); > } > + > +namespace test6 { > + struct foo { > + int bar(); > + }; > + typedef int bar_t(); > + void zed(bar_t foo::*) { > + } > + void baz() { > + zed(&foo::bar); > + } > +} > > Modified: cfe/trunk/tools/libclang/CIndex.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/tools/libclang/CIndex.cpp (original) > +++ cfe/trunk/tools/libclang/CIndex.cpp Wed Dec 4 19:23:43 2013 > @@ -1542,6 +1542,10 @@ bool CursorVisitor::VisitDecayedTypeLoc( > return Visit(TL.getOriginalLoc()); > } > > +bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) { > + return Visit(TL.getOriginalLoc()); > +} > + > bool CursorVisitor::VisitTemplateSpecializationTypeLoc( > TemplateSpecializationTypeLoc > TL) { > // Visit the template name. > > Modified: cfe/trunk/tools/libclang/RecursiveASTVisitor.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=196451&r1=196450&r2=196451&view=diff > ============================================================================== > --- cfe/trunk/tools/libclang/RecursiveASTVisitor.h (original) > +++ cfe/trunk/tools/libclang/RecursiveASTVisitor.h Wed Dec 4 19:23:43 2013 > @@ -799,6 +799,10 @@ DEF_TRAVERSE_TYPE(DecayedType, { > TRY_TO(TraverseType(T->getOriginalType())); > }) > > +DEF_TRAVERSE_TYPE(AdjustedType, { > + TRY_TO(TraverseType(T->getOriginalType())); > + }) > + > DEF_TRAVERSE_TYPE(ConstantArrayType, { > TRY_TO(TraverseType(T->getElementType())); > }) > @@ -1009,6 +1013,10 @@ DEF_TRAVERSE_TYPELOC(DecayedType, { > TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); > }) > > +DEF_TRAVERSE_TYPELOC(AdjustedType, { > + TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); > + }) > + > template<typename Derived> > bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc > TL) { > // This isn't available for ArrayType, but is for the ArrayTypeLoc. > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
