diff options
| author | Ed Schouten <ed@FreeBSD.org> | 2009-06-23 14:50:21 +0000 |
|---|---|---|
| committer | Ed Schouten <ed@FreeBSD.org> | 2009-06-23 14:50:21 +0000 |
| commit | d6aff018d446f22be4e4e0277080ebfa5b157288 (patch) | |
| tree | 64b43af65e97f7659637c9ac028e39af2e26b841 /lib/Sema/SemaExprCXX.cpp | |
| parent | b897c8660c4ff7037dde81b9645737bc1c992abe (diff) | |
Notes
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
| -rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index bec595ca9cf9..a567218eaa88 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -71,6 +71,31 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl); + if (!isType) { + // C++0x [expr.typeid]p3: + // When typeid is applied to an expression other than an lvalue of a + // polymorphic class type [...] [the] expression is an unevaluated + // operand. + + // FIXME: if the type of the expression is a class type, the class + // shall be completely defined. + bool isUnevaluatedOperand = true; + Expr *E = static_cast<Expr *>(TyOrExpr); + if (E && !E->isTypeDependent() && E->isLvalue(Context) == Expr::LV_Valid) { + QualType T = E->getType(); + if (const RecordType *RecordT = T->getAsRecordType()) { + CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl()); + if (RecordD->isPolymorphic()) + isUnevaluatedOperand = false; + } + } + + // If this is an unevaluated operand, clear out the set of declaration + // references we have been computing. + if (isUnevaluatedOperand) + PotentiallyReferencedDeclStack.back().clear(); + } + return Owned(new (Context) CXXTypeidExpr(isType, TyOrExpr, TypeInfoType.withConst(), SourceRange(OpLoc, RParenLoc))); |
