summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-12 18:16:41 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-12 18:16:41 +0000
commit6131b4418387d55374bda7ddb211ff3e6656cb86 (patch)
tree0ab395df254a7bbf3b83b464592a532415bc1be2 /clang/lib/Sema/TreeTransform.h
parent5c9429fa474381e637a06f7b1334afc4323d9716 (diff)
downloadbcm5719-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.h70
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();
OpenPOWER on IntegriCloud