diff options
author | Anders Carlsson <andersca@mac.com> | 2009-08-22 23:33:40 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-08-22 23:33:40 +0000 |
commit | d7923c6ed7ad6692656c7413d1e5653850b7b271 (patch) | |
tree | e86d976ff874750bfdcbb6a563dc190c7cf4f595 | |
parent | ba4bd50a805a997cd73427222440560a587c75b1 (diff) | |
download | bcm5719-llvm-d7923c6ed7ad6692656c7413d1e5653850b7b271.tar.gz bcm5719-llvm-d7923c6ed7ad6692656c7413d1e5653850b7b271.zip |
Add CK_NullToMemberPointer and CK_BaseToDerivedMemberPointer cast kinds. Make -ast-dump print out the cast kinds of cast expressions.
llvm-svn: 79787
-rw-r--r-- | clang/include/clang/AST/Expr.h | 9 | ||||
-rw-r--r-- | clang/lib/AST/StmtDumper.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 12 |
5 files changed, 73 insertions, 21 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 7776e497f6f..ade37beb1e2 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1181,7 +1181,14 @@ public: CK_ToUnion, /// CK_ArrayToPointerDecay - Array to pointer decay. - CK_ArrayToPointerDecay + CK_ArrayToPointerDecay, + + /// CK_NullToMemberPointer - Null pointer to member pointer. + CK_NullToMemberPointer, + + /// CK_BaseToDerivedMemberPointer - Member pointer in base class to + /// member pointer in derived class. + CK_BaseToDerivedMemberPointer }; struct CastInfo { diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index ff6d225cdb9..18c278118f6 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -117,6 +117,7 @@ namespace { // Exprs void VisitExpr(Expr *Node); + void VisitCastExpr(CastExpr *Node); void VisitDeclRefExpr(DeclRefExpr *Node); void VisitPredefinedExpr(PredefinedExpr *Node); void VisitCharacterLiteral(CharacterLiteral *Node); @@ -298,22 +299,56 @@ void StmtDumper::VisitExpr(Expr *Node) { DumpExpr(Node); } +void StmtDumper::VisitCastExpr(CastExpr *Node) { + DumpExpr(Node); + fprintf(F, " "); + switch (Node->getCastKind()) { + case CastExpr::CK_Unknown: + fprintf(F, "<Unknown>"); + break; + case CastExpr::CK_BitCast: + fprintf(F, "<BitCast>"); + break; + case CastExpr::CK_NoOp: + fprintf(F, "<NoOp>"); + break; + case CastExpr::CK_DerivedToBase: + fprintf(F, "<DerivedToBase>"); + break; + case CastExpr::CK_Dynamic: + fprintf(F, "<Dynamic>"); + break; + case CastExpr::CK_ToUnion: + fprintf(F, "<ToUnion>"); + break; + case CastExpr::CK_ArrayToPointerDecay: + fprintf(F, "<ArrayToPointerDecay>"); + break; + case CastExpr::CK_NullToMemberPointer: + fprintf(F, "<NullToMemberPointer>"); + break; + case CastExpr::CK_BaseToDerivedMemberPointer: + fprintf(F, "<BaseToDerivedMemberPointer>"); + break; + } +} + void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { DumpExpr(Node); fprintf(F, " "); switch (Node->getDecl()->getKind()) { - case Decl::Function: fprintf(F,"FunctionDecl"); break; - case Decl::Var: fprintf(F,"Var"); break; - case Decl::ParmVar: fprintf(F,"ParmVar"); break; - case Decl::EnumConstant: fprintf(F,"EnumConstant"); break; - case Decl::Typedef: fprintf(F,"Typedef"); break; - case Decl::Record: fprintf(F,"Record"); break; - case Decl::Enum: fprintf(F,"Enum"); break; - case Decl::CXXRecord: fprintf(F,"CXXRecord"); break; - case Decl::ObjCInterface: fprintf(F,"ObjCInterface"); break; - case Decl::ObjCClass: fprintf(F,"ObjCClass"); break; - default: fprintf(F,"Decl"); break; + default: fprintf(F,"Decl"); break; + case Decl::Function: fprintf(F,"FunctionDecl"); break; + case Decl::Var: fprintf(F,"Var"); break; + case Decl::ParmVar: fprintf(F,"ParmVar"); break; + case Decl::EnumConstant: fprintf(F,"EnumConstant"); break; + case Decl::Typedef: fprintf(F,"Typedef"); break; + case Decl::Record: fprintf(F,"Record"); break; + case Decl::Enum: fprintf(F,"Enum"); break; + case Decl::CXXRecord: fprintf(F,"CXXRecord"); break; + case Decl::ObjCInterface: fprintf(F,"ObjCInterface"); break; + case Decl::ObjCClass: fprintf(F,"ObjCClass"); break; } fprintf(F, "='%s' %p", Node->getDecl()->getNameAsString().c_str(), diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 5feee650cd4..1d61992d7c1 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -735,7 +735,8 @@ public: bool CheckPointerConversion(Expr *From, QualType ToType); bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, QualType &ConvertedType); - bool CheckMemberPointerConversion(Expr *From, QualType ToType); + bool CheckMemberPointerConversion(Expr *From, QualType ToType, + CastExpr::CastKind &Kind); bool IsQualificationConversion(QualType FromType, QualType ToType); bool IsUserDefinedConversion(Expr *From, QualType ToType, UserDefinedConversionSequence& User, diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7540dff44ad..0434f304d87 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1014,12 +1014,13 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, ImpCastExprToType(From, ToType); break; - case ICK_Pointer_Member: - if (CheckMemberPointerConversion(From, ToType)) - return true; - ImpCastExprToType(From, ToType); - break; - + case ICK_Pointer_Member: { + CastExpr::CastKind Kind = CastExpr::CK_Unknown; + if (CheckMemberPointerConversion(From, ToType, Kind)) + return true; + ImpCastExprToType(From, ToType, Kind); + break; + } case ICK_Boolean_Conversion: FromType = Context.BoolTy; ImpCastExprToType(From, FromType); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index ada1a2b4328..c445144b623 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1199,11 +1199,17 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, /// for which IsMemberPointerConversion has already returned true. It returns /// true and produces a diagnostic if there was an error, or returns false /// otherwise. -bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) { +bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType, + CastExpr::CastKind &Kind) { QualType FromType = From->getType(); const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>(); - if (!FromPtrType) + if (!FromPtrType) { + // This must be a null pointer to member pointer conversion + assert(From->isNullPointerConstant(Context) && + "Expr must be null pointer constant!"); + Kind = CastExpr::CK_NullToMemberPointer; return false; + } const MemberPointerType *ToPtrType = ToType->getAs<MemberPointerType>(); assert(ToPtrType && "No member pointer cast has a target type " @@ -1245,6 +1251,8 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) { return true; } + // Must be a base to derived member conversion. + Kind = CastExpr::CK_BaseToDerivedMemberPointer; return false; } |