summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-15 04:48:33 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-15 04:48:33 +0000
commit7cd39e07215159ed749ddd9fc1611008a2addade (patch)
treeb99e80df0f289dc9b981186267b24494a0ba3db5 /clang
parentf82f27be3fa2927dd3827fb1f3ab8ea1dbc18e52 (diff)
downloadbcm5719-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.h8
-rw-r--r--clang/include/clang/AST/ExprCXX.h6
-rw-r--r--clang/lib/AST/Expr.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp16
-rw-r--r--clang/lib/Sema/SemaCXXCast.cpp19
-rw-r--r--clang/test/CodeGenCXX/reinterpret-cast.cpp12
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
OpenPOWER on IntegriCloud