diff options
author | John McCall <rjmccall@apple.com> | 2009-12-04 22:46:56 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-12-04 22:46:56 +0000 |
commit | b96ec568715450106b4f1dd4a20c1c14e9bca6c4 (patch) | |
tree | 19500320eb1cc921c8936202a066855f39921959 /clang/lib/Sema/TreeTransform.h | |
parent | 9e2792690bd41191442cf3a65ad591a32ee9ab10 (diff) | |
download | bcm5719-llvm-b96ec568715450106b4f1dd4a20c1c14e9bca6c4.tar.gz bcm5719-llvm-b96ec568715450106b4f1dd4a20c1c14e9bca6c4.zip |
Fix "using typename" and the instantiation of non-dependent using declarations.
llvm-svn: 90614
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>()); } |