diff options
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/AST/StmtPrinter.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/AST/StmtSerialization.cpp | 28 |
4 files changed, 48 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index ce0856033d6..86a2f2902e9 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -437,6 +437,9 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const { if (cast<ExplicitCastExpr>(this)->getTypeAsWritten()->isReferenceType()) return LV_Valid; break; + case CXXTypeidExprClass: + // C++ 5.2.8p1: The result of a typeid expression is an lvalue of ... + return LV_Valid; case CXXThisExprClass: return LV_InvalidExpression; default: diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 0eead3ca552..ff97e688b8d 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -24,6 +24,13 @@ void CXXConditionDeclExpr::Destroy(ASTContext& C) { // Child Iterators for iterating over subexpressions/substatements //===----------------------------------------------------------------------===// +// CXXTypeidExpr - has child iterators if the operand is an expression +Stmt::child_iterator CXXTypeidExpr::child_begin() { + return isTypeOperand() ? child_iterator() : (Stmt**)&Operand; +} +Stmt::child_iterator CXXTypeidExpr::child_end() { + return isTypeOperand() ? child_iterator() : (Stmt**)&Operand+1; +} // CXXBoolLiteralExpr Stmt::child_iterator CXXBoolLiteralExpr::child_begin() { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 420bdbdee90..cc861cc6b4e 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -832,6 +832,16 @@ void StmtPrinter::VisitCXXConstCastExpr(CXXConstCastExpr *Node) { VisitCXXNamedCastExpr(Node); } +void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) { + OS << "typeid("; + if (Node->isTypeOperand()) { + OS << Node->getTypeOperand().getAsString(); + } else { + PrintExpr(Node->getExprOperand()); + } + OS << ")"; +} + void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { OS << (Node->getValue() ? "true" : "false"); } diff --git a/clang/lib/AST/StmtSerialization.cpp b/clang/lib/AST/StmtSerialization.cpp index 09aaceffda4..39828815769 100644 --- a/clang/lib/AST/StmtSerialization.cpp +++ b/clang/lib/AST/StmtSerialization.cpp @@ -216,6 +216,9 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { case CXXConstCastExprClass: return CXXConstCastExpr::CreateImpl(D, C, SC); + case CXXTypeidExprClass: + return CXXTypeidExpr::CreateImpl(D, C); + case CXXThisExprClass: return CXXThisExpr::CreateImpl(D, C); @@ -1346,6 +1349,31 @@ CXXNamedCastExpr::CreateImpl(Deserializer& D, ASTContext& C, StmtClass SC) { } } +void CXXTypeidExpr::EmitImpl(llvm::Serializer& S) const { + S.Emit(getType()); + S.Emit(isTypeOperand()); + if (isTypeOperand()) { + S.Emit(getTypeOperand()); + } else { + S.EmitOwnedPtr(getExprOperand()); + } + S.Emit(Range); +} + +CXXTypeidExpr* +CXXTypeidExpr::CreateImpl(llvm::Deserializer& D, ASTContext& C) { + QualType Ty = QualType::ReadVal(D); + bool isTypeOp = D.ReadBool(); + void *Operand; + if (isTypeOp) { + Operand = QualType::ReadVal(D).getAsOpaquePtr(); + } else { + Operand = D.ReadOwnedPtr<Expr>(C); + } + SourceRange Range = SourceRange::ReadVal(D); + return new CXXTypeidExpr(isTypeOp, Operand, Ty, Range); +} + void CXXThisExpr::EmitImpl(llvm::Serializer& S) const { S.Emit(getType()); S.Emit(Loc); |

