diff options
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index e1ac3225d2d..b029a379671 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -461,6 +461,10 @@ public: /// \brief Build a new unprototyped function type. QualType RebuildFunctionNoProtoType(QualType ResultType); + /// \brief Rebuild an unresolved typename type, given the decl that + /// the UnresolvedUsingTypenameDecl was transformed to. + QualType RebuildUnresolvedUsingType(Decl *D); + /// \brief Build a new typedef type. QualType RebuildTypedefType(TypedefDecl *Typedef) { return SemaRef.Context.getTypeDeclType(Typedef); @@ -2578,6 +2582,29 @@ QualType TreeTransform<Derived>::TransformFunctionNoProtoType( return Result; } +template<typename Derived> QualType +TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB, + UnresolvedUsingTypeLoc TL) { + UnresolvedUsingType *T = TL.getTypePtr(); + Decl *D = getDerived().TransformDecl(T->getDecl()); + if (!D) + return QualType(); + + QualType Result = TL.getType(); + if (getDerived().AlwaysRebuild() || D != T->getDecl()) { + Result = getDerived().RebuildUnresolvedUsingType(D); + if (Result.isNull()) + return QualType(); + } + + // We might get an arbitrary type spec type back. We should at + // least always get a type spec type, though. + TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result); + NewTL.setNameLoc(TL.getNameLoc()); + + return Result; +} + template<typename Derived> QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) { @@ -5318,6 +5345,30 @@ QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) { } template<typename Derived> +QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) { + assert(D && "no decl found"); + if (D->isInvalidDecl()) return QualType(); + + TypeDecl *Ty; + if (isa<UsingDecl>(D)) { + UsingDecl *Using = cast<UsingDecl>(D); + assert(Using->isTypeName() && + "UnresolvedUsingTypenameDecl transformed to non-typename using"); + + // A valid resolved using typename decl points to exactly one type decl. + assert(++Using->shadow_begin() == Using->shadow_end()); + Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl()); + + } else { + assert(isa<UnresolvedUsingTypenameDecl>(D) && + "UnresolvedUsingTypenameDecl transformed to non-using decl"); + Ty = cast<UnresolvedUsingTypenameDecl>(D); + } + + return SemaRef.Context.getTypeDeclType(Ty); +} + +template<typename Derived> QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) { return SemaRef.BuildTypeofExprType(E.takeAs<Expr>()); } |