summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index bec595c..a567218 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)));
OpenPOWER on IntegriCloud