r196451 - Add an AdjustedType sugar node for adjusting calling conventions

Rafael EspĂ­ndola rafael.espindola at gmail.com
Wed Dec 4 20:35:23 PST 2013


Thanks!

On 4 December 2013 20:23, Reid Kleckner <reid at kleckner.net> 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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list