diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-12-14 19:27:10 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-12-14 19:27:10 +0000 |
commit | d196a58b557ba388241547c06d76f3a30085f4fc (patch) | |
tree | 8352b5ba414d88211590ced4d864b3a3ecad885f /clang/lib/AST/Expr.cpp | |
parent | fed3d088cee8a369817cd2baf96605887642f7c9 (diff) | |
download | bcm5719-llvm-d196a58b557ba388241547c06d76f3a30085f4fc.tar.gz bcm5719-llvm-d196a58b557ba388241547c06d76f3a30085f4fc.zip |
Improve template instantiation for object constructions in several ways:
- During instantiation, drop default arguments from constructor and
call expressions; they'll be recomputed anyway, and we don't want
to instantiate them twice.
- Rewrote the instantiation of variable initializers to cope with
non-dependent forms properly.
Together, these fix a handful of problems I introduced with the switch
to always rebuild expressions from the source code "as written."
llvm-svn: 91315
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r-- | clang/lib/AST/Expr.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6d9a2689933..139e04b2ed5 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -568,6 +568,30 @@ const char *CastExpr::getCastKindName() const { return 0; } +Expr *CastExpr::getSubExprAsWritten() { + Expr *SubExpr = 0; + CastExpr *E = this; + do { + SubExpr = E->getSubExpr(); + + // Skip any temporary bindings; they're implicit. + if (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(SubExpr)) + SubExpr = Binder->getSubExpr(); + + // 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 the subexpression we're left with is an implicit cast, look + // through that, too. + } while ((E = dyn_cast<ImplicitCastExpr>(SubExpr))); + + return SubExpr; +} + /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it /// corresponds to, e.g. "<<=". const char *BinaryOperator::getOpcodeStr(Opcode Op) { @@ -1347,6 +1371,13 @@ Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) { } } +bool Expr::isDefaultArgument() const { + const Expr *E = this; + while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) + E = ICE->getSubExprAsWritten(); + + return isa<CXXDefaultArgExpr>(E); +} /// hasAnyTypeDependentArguments - Determines if any of the expressions /// in Exprs is type-dependent. |