diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-12-12 18:16:41 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-12-12 18:16:41 +0000 |
commit | 6131b4418387d55374bda7ddb211ff3e6656cb86 (patch) | |
tree | 0ab395df254a7bbf3b83b464592a532415bc1be2 /clang/lib/Sema/TreeTransform.h | |
parent | 5c9429fa474381e637a06f7b1334afc4323d9716 (diff) | |
download | bcm5719-llvm-6131b4418387d55374bda7ddb211ff3e6656cb86.tar.gz bcm5719-llvm-6131b4418387d55374bda7ddb211ff3e6656cb86.zip |
Rework the way we handle template instantiation for
implicitly-generated AST nodes. We previously built instantiated nodes
for each of these AST nodes, then passed them on to Sema, which was
not prepared to see already-type-checked nodes (see PR5755). In some
places, we had ugly workarounds to try to avoid re-type-checking
(e.g., in VarDecl initializer instantiation).
Now, we skip implicitly-generated nodes when performing instantiation,
preferring instead to build just the AST nodes that directly reflect
what was written in the source code. This has several advantages:
- We don't need to instantiate anything that doesn't have a direct
correlation to the source code, so we can have better location
information.
- Semantic analysis sees the same thing at template instantiation
time that it would see for a non-template.
- At least one ugly hack (VarDecl initializers) goes away.
Fixes PR5755.
llvm-svn: 91218
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 70 |
1 files changed, 35 insertions, 35 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 643489fa374..f8e8f947be3 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -993,19 +993,6 @@ public: move(LHS), move(RHS)); } - /// \brief Build a new implicit cast expression. - /// - /// By default, builds a new implicit cast without any semantic analysis. - /// Subclasses may override this routine to provide different behavior. - OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind, - ExprArg SubExpr, bool isLvalue) { - ImplicitCastExpr *ICE - = new (getSema().Context) ImplicitCastExpr(T, Kind, - (Expr *)SubExpr.release(), - isLvalue); - return getSema().Owned(ICE); - } - /// \brief Build a new C-style cast expression. /// /// By default, performs semantic analysis to build the new expression. @@ -3779,29 +3766,39 @@ TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) { move(RHS)); } -template<typename Derived> -Sema::OwningExprResult -TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) { - TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName()); +/// \brief Given a cast expression, extract the subexpression of the +/// cast, looking through intermediate AST nodes that were generated +/// as part of type checking. +static Expr *getCastSubExprAsWritten(CastExpr *E) { + Expr *SubExpr = 0; + do { + SubExpr = E->getSubExpr(); - // FIXME: Will we ever have type information here? It seems like we won't, - // so do we even need to transform the type? - QualType T = getDerived().TransformType(E->getType()); - if (T.isNull()) - return SemaRef.ExprError(); + // Temporaries will be re-bound when rebuilding the original cast + // expression. + if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(SubExpr)) + SubExpr = Binder->getSubExpr(); - OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return SemaRef.ExprError(); + // Conversions by constructor and conversion functions have a + // subexpression describing the call; strip it off. + if (E->getCastKind() == CastExpr::CK_ConstructorConversion) + SubExpr = cast<CXXConstructExpr>(SubExpr)->getArg(0); + else if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) + SubExpr = cast<CXXMemberCallExpr>(SubExpr)->getImplicitObjectArgument(); - if (!getDerived().AlwaysRebuild() && - T == E->getType() && - SubExpr.get() == E->getSubExpr()) - return SemaRef.Owned(E->Retain()); + // If the subexpression we're left with is an implicit cast, look + // through that, too. + } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr))); - return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(), - move(SubExpr), - E->isLvalueCast()); + return SubExpr; +} + +template<typename Derived> +Sema::OwningExprResult +TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) { + // Implicit casts are eliminated during transformation, since they + // will be recomputed by semantic analysis after transformation. + return getDerived().TransformExpr(getCastSubExprAsWritten(E)); } template<typename Derived> @@ -3826,7 +3823,8 @@ TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) { return SemaRef.ExprError(); } - OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); + OwningExprResult SubExpr + = getDerived().TransformExpr(getCastSubExprAsWritten(E)); if (SubExpr.isInvalid()) return SemaRef.ExprError(); @@ -4182,7 +4180,8 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) { return SemaRef.ExprError(); } - OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); + OwningExprResult SubExpr + = getDerived().TransformExpr(getCastSubExprAsWritten(E)); if (SubExpr.isInvalid()) return SemaRef.ExprError(); @@ -4246,7 +4245,8 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr( return SemaRef.ExprError(); } - OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); + OwningExprResult SubExpr + = getDerived().TransformExpr(getCastSubExprAsWritten(E)); if (SubExpr.isInvalid()) return SemaRef.ExprError(); |