[cfe-commits] r95063 - in /cfe/trunk: lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CGVtable.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.h test/CodeGenCXX/pointers-to-data-members.cpp
Anders Carlsson
andersca at mac.com
Mon Feb 1 19:37:46 PST 2010
Author: andersca
Date: Mon Feb 1 21:37:46 2010
New Revision: 95063
URL: http://llvm.org/viewvc/llvm-project?rev=95063&view=rev
Log:
Move pointer to data member emission to CodeGenModule and use it in CGExprConstant. Fixes PR5674.
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CGVtable.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Feb 1 21:37:46 2010
@@ -1093,9 +1093,12 @@
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
return EmitFunctionDeclLValue(*this, E, FD);
+ // FIXME: the qualifier check does not seem sufficient here
if (E->getQualifier()) {
- // FIXME: the qualifier check does not seem sufficient here
- return EmitPointerToDataMemberLValue(cast<FieldDecl>(ND));
+ const FieldDecl *FD = cast<FieldDecl>(ND);
+ llvm::Value *V = CGM.EmitPointerToDataMember(FD);
+
+ return LValue::MakeAddr(V, MakeQualifiers(FD->getType()));
}
assert(false && "Unhandled DeclRefExpr");
@@ -1873,20 +1876,6 @@
return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
}
-
-LValue CodeGenFunction::EmitPointerToDataMemberLValue(const FieldDecl *Field) {
- const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Field->getDeclContext());
- QualType NNSpecTy =
- getContext().getCanonicalType(
- getContext().getTypeDeclType(const_cast<CXXRecordDecl*>(ClassDecl)));
- NNSpecTy = getContext().getPointerType(NNSpecTy);
- llvm::Value *V = llvm::Constant::getNullValue(ConvertType(NNSpecTy));
- LValue MemExpLV = EmitLValueForField(V, Field, /*Qualifiers=*/0);
- const llvm::Type *ResultType = ConvertType(getContext().getPointerDiffType());
- V = Builder.CreatePtrToInt(MemExpLV.getAddress(), ResultType, "datamember");
- return LValue::MakeAddr(V, MakeQualifiers(Field->getType()));
-}
-
RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
ReturnValueSlot ReturnValue,
CallExpr::const_arg_iterator ArgBeg,
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Mon Feb 1 21:37:46 2010
@@ -438,16 +438,16 @@
if (const MemberPointerType *MPT =
E->getType()->getAs<MemberPointerType>()) {
QualType T = MPT->getPointeeType();
- if (T->isFunctionProtoType()) {
- DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
-
- return EmitMemberFunctionPointer(cast<CXXMethodDecl>(DRE->getDecl()));
- }
+ DeclRefExpr *DRE = cast<DeclRefExpr>(E->getSubExpr());
+
+ NamedDecl *ND = DRE->getDecl();
+ if (T->isFunctionProtoType())
+ return EmitMemberFunctionPointer(cast<CXXMethodDecl>(ND));
- // FIXME: Should we handle other member pointer types here too,
- // or should they be handled by Expr::Evaluate?
+ // We have a pointer to data member.
+ return CGM.EmitPointerToDataMember(cast<FieldDecl>(ND));
}
-
+
return 0;
}
@@ -959,3 +959,27 @@
return llvm::Constant::getNullValue(getTypes().ConvertTypeForMem(T));
}
+
+llvm::Constant *
+CodeGenModule::EmitPointerToDataMember(const FieldDecl *FD) {
+
+ // Itanium C++ ABI 2.3:
+ // A pointer to data member is an offset from the base address of the class
+ // object containing it, represented as a ptrdiff_t
+
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(FD->getParent());
+ QualType ClassType =
+ getContext().getTypeDeclType(const_cast<CXXRecordDecl *>(ClassDecl));
+
+ const llvm::StructType *ClassLTy =
+ cast<llvm::StructType>(getTypes().ConvertType(ClassType));
+
+ unsigned FieldNo = getTypes().getLLVMFieldNo(FD);
+ uint64_t Offset =
+ getTargetData().getStructLayout(ClassLTy)->getElementOffset(FieldNo);
+
+ const llvm::Type *PtrDiffTy =
+ getTypes().ConvertType(getContext().getPointerDiffType());
+
+ return llvm::ConstantInt::get(PtrDiffTy, Offset);
+}
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Mon Feb 1 21:37:46 2010
@@ -388,8 +388,6 @@
}
if (SrcType->isMemberPointerType()) {
- // FIXME: This is ABI specific.
-
// Compare against -1.
llvm::Value *NegativeOne = llvm::Constant::getAllOnesValue(Src->getType());
return Builder.CreateICmpNE(Src, NegativeOne, "tobool");
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Mon Feb 1 21:37:46 2010
@@ -1231,13 +1231,13 @@
void CGVtableInfo::ComputeMethodVtableIndices(const CXXRecordDecl *RD) {
// Itanium C++ ABI 2.5.2:
- // The order of the virtual function pointers in a virtual table is the
- // order of declaration of the corresponding member functions in the class.
+ // The order of the virtual function pointers in a virtual table is the
+ // order of declaration of the corresponding member functions in the class.
//
- // There is an entry for any virtual function declared in a class,
- // whether it is a new function or overrides a base class function,
- // unless it overrides a function from the primary base, and conversion
- // between their return types does not require an adjustment.
+ // There is an entry for any virtual function declared in a class,
+ // whether it is a new function or overrides a base class function,
+ // unless it overrides a function from the primary base, and conversion
+ // between their return types does not require an adjustment.
int64_t CurrentIndex = 0;
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Mon Feb 1 21:37:46 2010
@@ -1007,8 +1007,6 @@
LValue EmitCastLValue(const CastExpr *E);
LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E);
- LValue EmitPointerToDataMemberLValue(const FieldDecl *Field);
-
llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar);
LValue EmitLValueForField(llvm::Value* Base, const FieldDecl* Field,
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Feb 1 21:37:46 2010
@@ -348,6 +348,8 @@
llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
const AnnotateAttr *AA, unsigned LineNo);
+ llvm::Constant *EmitPointerToDataMember(const FieldDecl *FD);
+
/// ErrorUnsupported - Print out an error that codegen doesn't support the
/// specified stmt yet.
/// \param OmitOnError - If true, then this error should only be emitted if no
Modified: cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp?rev=95063&r1=95062&r2=95063&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/pointers-to-data-members.cpp Mon Feb 1 21:37:46 2010
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s
-struct A { int a; };
+struct A { int a; int b; };
struct B { int b; };
struct C : B, A { };
@@ -17,23 +17,12 @@
// CHECK: @_ZN8ZeroInit1bE = global i64 -1,
int A::* b = 0;
-
- void f() {
- // CHECK: icmp ne i64 {{.*}}, -1
- if (a) { }
-
- // CHECK: icmp ne i64 {{.*}}, -1
- if (a != 0) { }
-
- // CHECK: icmp ne i64 -1, {{.*}}
- if (0 != a) { }
-
- // CHECK: icmp eq i64 {{.*}}, -1
- if (a == 0) { }
+}
- // CHECK: icmp eq i64 -1, {{.*}}
- if (0 == a) { }
- }
+// PR5674
+namespace PR5674 {
+ // CHECK: @_ZN6PR56742pbE = global i64 4
+ int A::*pb = &A::b;
}
// Casts.
@@ -56,3 +45,25 @@
}
}
+
+// Comparisons
+namespace Comparisons {
+ void f() {
+ int A::*a;
+
+ // CHECK: icmp ne i64 {{.*}}, -1
+ if (a) { }
+
+ // CHECK: icmp ne i64 {{.*}}, -1
+ if (a != 0) { }
+
+ // CHECK: icmp ne i64 -1, {{.*}}
+ if (0 != a) { }
+
+ // CHECK: icmp eq i64 {{.*}}, -1
+ if (a == 0) { }
+
+ // CHECK: icmp eq i64 -1, {{.*}}
+ if (0 == a) { }
+ }
+}
More information about the cfe-commits
mailing list