diff options
| author | Anders Carlsson <andersca@mac.com> | 2009-09-15 04:48:33 +0000 | 
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2009-09-15 04:48:33 +0000 | 
| commit | 7cd39e07215159ed749ddd9fc1611008a2addade (patch) | |
| tree | b99e80df0f289dc9b981186267b24494a0ba3db5 /clang | |
| parent | f82f27be3fa2927dd3827fb1f3ab8ea1dbc18e52 (diff) | |
| download | bcm5719-llvm-7cd39e07215159ed749ddd9fc1611008a2addade.tar.gz bcm5719-llvm-7cd39e07215159ed749ddd9fc1611008a2addade.zip  | |
Handle reinterpret_cast between integral types and pointer types.
llvm-svn: 81837
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/Expr.h | 8 | ||||
| -rw-r--r-- | clang/include/clang/AST/ExprCXX.h | 6 | ||||
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 16 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 19 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/reinterpret-cast.cpp | 12 | 
6 files changed, 54 insertions, 11 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 81aecf7f31e..3e122c1f53a 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1368,7 +1368,13 @@ public:      CK_UserDefinedConversion,      /// CK_ConstructorConversion - Conversion by constructor -    CK_ConstructorConversion +    CK_ConstructorConversion, +     +    /// CK_IntegralToPointer - Integral to pointer +    CK_IntegralToPointer, +     +    /// CK_PointerToIntegral - Pointer to integral +    CK_PointerToIntegral    };    struct CastInfo { diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 871014d6c81..5e3dec77057 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -185,9 +185,9 @@ public:  /// @c reinterpret_cast<int>(VoidPtr).  class CXXReinterpretCastExpr : public CXXNamedCastExpr {  public: -  CXXReinterpretCastExpr(QualType ty, Expr *op, QualType writtenTy, -                         SourceLocation l) -    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, CK_BitCast, op, +  CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op,  +                         QualType writtenTy, SourceLocation l) +    : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op,                         writtenTy, l) {}    static bool classof(const Stmt *T) { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 620b5b89016..0ac896c7838 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -422,6 +422,10 @@ const char *CastExpr::getCastKindName() const {      return "UserDefinedConversion";    case CastExpr::CK_ConstructorConversion:      return "ConstructorConversion"; +  case CastExpr::CK_IntegralToPointer: +    return "IntegralToPointer"; +  case CastExpr::CK_PointerToIntegral: +    return "PointerToIntegral";    }    assert(0 && "Unhandled cast kind!"); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 7f9b66468b8..682d14ca2e5 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -625,6 +625,12 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,    switch (Kind) {    default: +    // FIXME: Assert here. +    // assert(0 && "Unhandled cast kind!"); +    break; +  case CastExpr::CK_Unknown: +    // FIXME: We should really assert here - Unknown casts should never get +    // as far as to codegen.      break;    case CastExpr::CK_BitCast: {      Value *Src = Visit(const_cast<Expr*>(E)); @@ -685,6 +691,16 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy,                                          NullCheckValue);    } +  case CastExpr::CK_IntegralToPointer: { +    Value *Src = Visit(const_cast<Expr*>(E)); +    return Builder.CreateIntToPtr(Src, ConvertType(DestTy)); +  } + +  case CastExpr::CK_PointerToIntegral: { +    Value *Src = Visit(const_cast<Expr*>(E)); +    return Builder.CreatePtrToInt(Src, ConvertType(DestTy)); +  } +      }    // Handle cases where the source is an non-complex type. diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index 0ae5d343cad..dbd6c6fde5c 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/lib/Sema/SemaCXXCast.cpp @@ -41,7 +41,8 @@ static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,                             const SourceRange &DestRange);  static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,                                   const SourceRange &OpRange, -                                 const SourceRange &DestRange); +                                 const SourceRange &DestRange, +                                 CastExpr::CastKind &Kind);  static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,                              const SourceRange &OpRange,                              CastExpr::CastKind &Kind, @@ -135,13 +136,14 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,      return Owned(new (Context)CXXDynamicCastExpr(DestType.getNonReferenceType(),                                                   Kind, Ex, DestType, OpLoc));    } -  case tok::kw_reinterpret_cast: +  case tok::kw_reinterpret_cast: { +    CastExpr::CastKind Kind = CastExpr::CK_Unknown;      if (!TypeDependent) -      CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange); +      CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);      return Owned(new (Context) CXXReinterpretCastExpr(                                    DestType.getNonReferenceType(), -                                  Ex, DestType, OpLoc)); - +                                  Kind, Ex, DestType, OpLoc)); +  }    case tok::kw_static_cast: {      CastExpr::CastKind Kind = CastExpr::CK_Unknown;      if (!TypeDependent) { @@ -355,11 +357,11 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,  /// char *bytes = reinterpret_cast\<char*\>(int_ptr);  void  CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, -                     const SourceRange &OpRange, const SourceRange &DestRange) { +                     const SourceRange &OpRange, const SourceRange &DestRange, +                     CastExpr::CastKind &Kind) {    if (!DestType->isLValueReferenceType())      Self.DefaultFunctionArrayConversion(SrcExpr); -  CastExpr::CastKind Kind = CastExpr::CK_Unknown;    unsigned msg = diag::err_bad_cxx_cast_generic;    if (TryReinterpretCast(Self, SrcExpr, DestType, /*CStyle*/false, Kind,                           OpRange, msg) @@ -950,6 +952,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,        msg = diag::err_bad_reinterpret_cast_small_int;        return TC_Failed;      } +    Kind = CastExpr::CK_PointerToIntegral;      return TC_Success;    } @@ -982,6 +985,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,        msg = diag::err_bad_reinterpret_cast_small_int;        return TC_Failed;      } +    Kind = CastExpr::CK_PointerToIntegral;      return TC_Success;    } @@ -989,6 +993,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,      assert(destIsPtr && "One type must be a pointer");      // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly      //   converted to a pointer. +    Kind = CastExpr::CK_IntegralToPointer;      return TC_Success;    } diff --git a/clang/test/CodeGenCXX/reinterpret-cast.cpp b/clang/test/CodeGenCXX/reinterpret-cast.cpp new file mode 100644 index 00000000000..ae3ab2f8b0d --- /dev/null +++ b/clang/test/CodeGenCXX/reinterpret-cast.cpp @@ -0,0 +1,12 @@ +// RUN: clang-cc -emit-llvm -o - %s -std=c++0x +void *f1(unsigned long l) { +  return reinterpret_cast<void *>(l); +} + +unsigned long f2() { +  return reinterpret_cast<unsigned long>(nullptr); +} + +unsigned long f3(void *p) { +  return reinterpret_cast<unsigned long>(p); +}
\ No newline at end of file  | 

