@@ -1914,14 +1914,20 @@ namespace {
19141914// / that normally happen during l-value emission.
19151915struct ConstantLValue {
19161916 llvm::Constant *Value;
1917+ llvm::Type *ElementTy;
19171918 bool HasOffsetApplied;
19181919
19191920 /* implicit*/ ConstantLValue(llvm::Constant *value,
19201921 bool hasOffsetApplied = false )
1921- : Value(value), HasOffsetApplied(hasOffsetApplied) {}
1922+ : Value(value), ElementTy(nullptr ), HasOffsetApplied(hasOffsetApplied) {}
1923+
1924+ /* implicit*/ ConstantLValue(llvm::Constant *value,
1925+ llvm::Type *elementTy,
1926+ bool hasOffsetApplied = false )
1927+ : Value(value), ElementTy(elementTy), HasOffsetApplied(hasOffsetApplied) {}
19221928
19231929 /* implicit*/ ConstantLValue(ConstantAddress address)
1924- : ConstantLValue(address.getPointer()) {}
1930+ : ConstantLValue(address.getPointer(), address.getElementType() ) {}
19251931};
19261932
19271933// / A helper class for emitting constant l-values.
@@ -1961,6 +1967,12 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
19611967 ConstantLValue VisitMaterializeTemporaryExpr (
19621968 const MaterializeTemporaryExpr *E);
19631969
1970+ llvm::Type *ConvertBlockType (QualType Ty) {
1971+ if (CGM.getLangOpts ().OpenCL )
1972+ return CGM.getGenericBlockLiteralType ();
1973+ return CGM.getTypes ().ConvertType (Ty);
1974+ }
1975+
19641976 bool hasNonZeroOffset () const {
19651977 return !Value.getLValueOffset ().isZero ();
19661978 }
@@ -1972,14 +1984,16 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
19721984 }
19731985
19741986 // / Apply the value offset to the given constant.
1975- llvm::Constant *applyOffset (llvm::Constant *C) {
1987+ llvm::Constant *applyOffset (llvm::Constant *C, llvm::Type *BaseElementTy ) {
19761988 uint64_t OffsetVal = Value.getLValueOffset ().getQuantity ();
19771989
19781990 llvm::SmallVector<llvm::Constant*, 4 > Indexes;
19791991 Indexes.push_back (llvm::ConstantInt::get (CGM.Int32Ty , 0 ));
19801992 llvm::Type* DestTy = CGM.getTypes ().ConvertTypeForMem (DestType);
19811993 llvm::Type* DestElemTy = nullptr ;
1982- if (DestTy->isPointerTy ())
1994+ if (isa<BlockPointerType>(DestType.getCanonicalType ().getTypePtr ()))
1995+ DestElemTy = ConvertBlockType (DestType->getPointeeType ());
1996+ else if (DestTy->isPointerTy ())
19831997 DestElemTy = CGM.getTypes ().ConvertTypeForMem (DestType->getPointeeType ());
19841998 QualType CurType;
19851999 const APValue::LValueBase &base = Value.getLValueBase ();
@@ -1990,13 +2004,19 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
19902004 else
19912005 CurType = base.getTypeInfoType ();
19922006
1993- llvm::Type* CurrentType = CGM.getTypes ().ConvertTypeForMem (CurType);
1994- llvm::Type* CElementType = CurrentType;
2007+ llvm::Type* CurrentType = BaseElementTy;
19952008
1996- if (!C->getType ()->isOpaquePointerTy ())
2009+ if (!CurrentType)
2010+ CurrentType = CGM.getTypes ().ConvertTypeForMem (CurType);
2011+
2012+ if (C->getType ()->isOpaquePointerTy ())
2013+ CurrentType = nullptr ;
2014+ else
19972015 assert (CurrentType == C->getType ()->getNonOpaquePointerElementType ());
19982016
1999- if (Value.hasLValuePath ()) {
2017+ llvm::Type* CElementType = CurrentType;
2018+
2019+ if (Value.hasLValuePath () && CGM.getTypes ().ConvertTypeForMem (CurType) == CurrentType) {
20002020 ArrayRef<APValue::LValuePathEntry> Path = Value.getLValuePath ();
20012021 for (unsigned I = 0 ; I != Path.size (); ++I) {
20022022 if (const RecordType* CurClass = CurType->getAs <RecordType>()) {
@@ -2043,7 +2063,7 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
20432063 Indexes.back () = llvm::ConstantInt::get (CGM.Int32Ty , cast<llvm::ConstantInt>(Indexes.back ())->getZExtValue ()+1 );
20442064 }
20452065 OffsetVal = 0 ;
2046- } else {
2066+ } else if (CurrentType) {
20472067 // Try to build a naturally looking GEP from the returned expression to the
20482068 // required type
20492069 while (DestTy->isPointerTy () && (OffsetVal || CurrentType!=DestElemTy))
@@ -2132,7 +2152,7 @@ llvm::Constant *ConstantLValueEmitter::tryEmit() {
21322152
21332153 // Apply the offset if necessary and not already done.
21342154 if (!result.HasOffsetApplied ) {
2135- value = applyOffset (value);
2155+ value = applyOffset (value, result. ElementTy );
21362156 }
21372157
21382158 // Convert to the appropriate type; this could be an lvalue for
@@ -2279,7 +2299,7 @@ ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *E) {
22792299 llvm::Constant *Ptr = Emitter.CGF ->GetAddrOfLabel (E->getLabel ());
22802300 Ptr = llvm::ConstantExpr::getBitCast (Ptr,
22812301 CGM.getTypes ().ConvertType (E->getType ()));
2282- return Ptr;
2302+ return ConstantLValue ( Ptr, CGM. getTypes (). ConvertTypeForMem (E-> getType ()-> getPointeeType ())) ;
22832303}
22842304
22852305ConstantLValue
@@ -2309,7 +2329,7 @@ ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *E) {
23092329 else
23102330 functionName = " global" ;
23112331
2312- return CGM.GetAddrOfGlobalBlock (E, functionName);
2332+ return ConstantLValue ( CGM.GetAddrOfGlobalBlock (E, functionName), ConvertBlockType (E-> getType ()-> getPointeeType ()) );
23132333}
23142334
23152335ConstantLValue
0 commit comments