@@ -73,21 +73,54 @@ Address CIRGenFunction::emitPointerWithAlignment(const Expr *expr,
7373
7474 // Casts:
7575 if (auto const *ce = dyn_cast<CastExpr>(expr)) {
76- if (isa<ExplicitCastExpr>(ce)) {
77- cgm.errorNYI (expr->getSourceRange (),
78- " emitPointerWithAlignment: explicit cast" );
79- return Address::invalid ();
80- }
76+ if (const auto *ece = dyn_cast<ExplicitCastExpr>(ce))
77+ cgm.emitExplicitCastExprType (ece);
8178
8279 switch (ce->getCastKind ()) {
8380 // Non-converting casts (but not C's implicit conversion from void*).
8481 case CK_BitCast:
8582 case CK_NoOp:
8683 case CK_AddressSpaceConversion: {
87- cgm.errorNYI (expr->getSourceRange (),
88- " emitPointerWithAlignment: noop cast" );
89- return Address::invalid ();
90- } break ;
84+ if (const auto *ptrTy =
85+ ce->getSubExpr ()->getType ()->getAs <PointerType>()) {
86+ if (ptrTy->getPointeeType ()->isVoidType ())
87+ break ;
88+
89+ LValueBaseInfo innerBaseInfo;
90+ assert (!cir::MissingFeatures::opTBAA ());
91+ Address addr =
92+ emitPointerWithAlignment (ce->getSubExpr (), &innerBaseInfo);
93+ if (baseInfo)
94+ *baseInfo = innerBaseInfo;
95+
96+ if (isa<ExplicitCastExpr>(ce)) {
97+ LValueBaseInfo targetTypeBaseInfo;
98+
99+ const QualType pointeeType = expr->getType ()->getPointeeType ();
100+ const CharUnits align =
101+ cgm.getNaturalTypeAlignment (pointeeType, &targetTypeBaseInfo);
102+
103+ // If the source l-value is opaque, honor the alignment of the
104+ // casted-to type.
105+ if (innerBaseInfo.getAlignmentSource () != AlignmentSource::Decl) {
106+ if (baseInfo)
107+ baseInfo->mergeForCast (targetTypeBaseInfo);
108+ addr = Address (addr.getPointer (), addr.getElementType (), align);
109+ }
110+ }
111+
112+ assert (!cir::MissingFeatures::sanitizers ());
113+
114+ const mlir::Type eltTy =
115+ convertTypeForMem (expr->getType ()->getPointeeType ());
116+ addr = getBuilder ().createElementBitCast (getLoc (expr->getSourceRange ()),
117+ addr, eltTy);
118+ assert (!cir::MissingFeatures::addressSpace ());
119+
120+ return addr;
121+ }
122+ break ;
123+ }
91124
92125 // Array-to-pointer decay. TODO(cir): BaseInfo and TBAAInfo.
93126 case CK_ArrayToPointerDecay:
@@ -551,6 +584,37 @@ RValue CIRGenFunction::emitLoadOfLValue(LValue lv, SourceLocation loc) {
551584 return RValue::get (nullptr );
552585}
553586
587+ static cir::FuncOp emitFunctionDeclPointer (CIRGenModule &cgm, GlobalDecl gd) {
588+ assert (!cir::MissingFeatures::weakRefReference ());
589+ return cgm.getAddrOfFunction (gd);
590+ }
591+
592+ static LValue emitFunctionDeclLValue (CIRGenFunction &cgf, const Expr *e,
593+ GlobalDecl gd) {
594+ const FunctionDecl *fd = cast<FunctionDecl>(gd.getDecl ());
595+ cir::FuncOp funcOp = emitFunctionDeclPointer (cgf.cgm , gd);
596+ mlir::Location loc = cgf.getLoc (e->getSourceRange ());
597+ CharUnits align = cgf.getContext ().getDeclAlign (fd);
598+
599+ assert (!cir::MissingFeatures::sanitizers ());
600+
601+ mlir::Type fnTy = funcOp.getFunctionType ();
602+ mlir::Type ptrTy = cir::PointerType::get (fnTy);
603+ mlir::Value addr = cgf.getBuilder ().create <cir::GetGlobalOp>(
604+ loc, ptrTy, funcOp.getSymName ());
605+
606+ if (funcOp.getFunctionType () != cgf.convertType (fd->getType ())) {
607+ fnTy = cgf.convertType (fd->getType ());
608+ ptrTy = cir::PointerType::get (fnTy);
609+
610+ addr = cir::CastOp::create (cgf.getBuilder (), addr.getLoc (), ptrTy,
611+ cir::CastKind::bitcast, addr);
612+ }
613+
614+ return cgf.makeAddrLValue (Address (addr, fnTy, align), e->getType (),
615+ AlignmentSource::Decl);
616+ }
617+
554618LValue CIRGenFunction::emitDeclRefLValue (const DeclRefExpr *e) {
555619 const NamedDecl *nd = e->getDecl ();
556620 QualType ty = e->getType ();
@@ -607,6 +671,16 @@ LValue CIRGenFunction::emitDeclRefLValue(const DeclRefExpr *e) {
607671 return emitLValue (bd->getBinding ());
608672 }
609673
674+ if (const auto *fd = dyn_cast<FunctionDecl>(nd)) {
675+ LValue lv = emitFunctionDeclLValue (*this , e, fd);
676+
677+ // Emit debuginfo for the function declaration if the target wants to.
678+ if (getContext ().getTargetInfo ().allowDebugInfoForExternalRef ())
679+ assert (!cir::MissingFeatures::generateDebugInfo ());
680+
681+ return lv;
682+ }
683+
610684 cgm.errorNYI (e->getSourceRange (), " emitDeclRefLValue: unhandled decl type" );
611685 return LValue ();
612686}
@@ -1401,11 +1475,6 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e, AggValueSlot aggSlot) {
14011475 llvm_unreachable (" bad evaluation kind" );
14021476}
14031477
1404- static cir::FuncOp emitFunctionDeclPointer (CIRGenModule &cgm, GlobalDecl gd) {
1405- assert (!cir::MissingFeatures::weakRefReference ());
1406- return cgm.getAddrOfFunction (gd);
1407- }
1408-
14091478// Detect the unusual situation where an inline version is shadowed by a
14101479// non-inline version. In that case we should pick the external one
14111480// everywhere. That's GCC behavior too.
0 commit comments