@@ -27,6 +27,38 @@ using namespace clang;
2727using namespace clang ::CIRGen;
2828using namespace cir ;
2929
30+ // / Get the address of a zero-sized field within a record. The resulting address
31+ // / doesn't necessarily have the right type.
32+ Address CIRGenFunction::emitAddrOfFieldStorage (Address base,
33+ const FieldDecl *field,
34+ llvm::StringRef fieldName,
35+ unsigned fieldIndex) {
36+ if (field->isZeroSize (getContext ())) {
37+ cgm.errorNYI (field->getSourceRange (),
38+ " emitAddrOfFieldStorage: zero-sized field" );
39+ return Address::invalid ();
40+ }
41+
42+ mlir::Location loc = getLoc (field->getLocation ());
43+
44+ mlir::Type fieldType = convertType (field->getType ());
45+ auto fieldPtr = cir::PointerType::get (builder.getContext (), fieldType);
46+ // For most cases fieldName is the same as field->getName() but for lambdas,
47+ // which do not currently carry the name, so it can be passed down from the
48+ // CaptureStmt.
49+ cir::GetMemberOp memberAddr = builder.createGetMember (
50+ loc, fieldPtr, base.getPointer (), fieldName, fieldIndex);
51+
52+ // Retrieve layout information, compute alignment and return the final
53+ // address.
54+ const RecordDecl *rec = field->getParent ();
55+ const CIRGenRecordLayout &layout = cgm.getTypes ().getCIRGenRecordLayout (rec);
56+ unsigned idx = layout.getCIRFieldNo (field);
57+ CharUnits offset = CharUnits::fromQuantity (
58+ layout.getCIRType ().getElementOffset (cgm.getDataLayout ().layout , idx));
59+ return Address (memberAddr, base.getAlignment ().alignmentAtOffset (offset));
60+ }
61+
3062// / Given an expression of pointer type, try to
3163// / derive a more accurate bound on the alignment of the pointer.
3264Address CIRGenFunction::emitPointerWithAlignment (const Expr *expr,
@@ -264,6 +296,66 @@ mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src,
264296 return {};
265297}
266298
299+ LValue CIRGenFunction::emitLValueForField (LValue base, const FieldDecl *field) {
300+ LValueBaseInfo baseInfo = base.getBaseInfo ();
301+
302+ if (field->isBitField ()) {
303+ cgm.errorNYI (field->getSourceRange (), " emitLValueForField: bitfield" );
304+ return LValue ();
305+ }
306+
307+ QualType fieldType = field->getType ();
308+ const RecordDecl *rec = field->getParent ();
309+ AlignmentSource baseAlignSource = baseInfo.getAlignmentSource ();
310+ LValueBaseInfo fieldBaseInfo (getFieldAlignmentSource (baseAlignSource));
311+ assert (!cir::MissingFeatures::opTBAA ());
312+
313+ Address addr = base.getAddress ();
314+ if (auto *classDef = dyn_cast<CXXRecordDecl>(rec)) {
315+ cgm.errorNYI (field->getSourceRange (), " emitLValueForField: C++ class" );
316+ return LValue ();
317+ }
318+
319+ unsigned recordCVR = base.getVRQualifiers ();
320+ if (rec->isUnion ()) {
321+ cgm.errorNYI (field->getSourceRange (), " emitLValueForField: union" );
322+ return LValue ();
323+ }
324+
325+ assert (!cir::MissingFeatures::preservedAccessIndexRegion ());
326+ llvm::StringRef fieldName = field->getName ();
327+ const CIRGenRecordLayout &layout =
328+ cgm.getTypes ().getCIRGenRecordLayout (field->getParent ());
329+ unsigned fieldIndex = layout.getCIRFieldNo (field);
330+
331+ assert (!cir::MissingFeatures::lambdaFieldToName ());
332+
333+ addr = emitAddrOfFieldStorage (addr, field, fieldName, fieldIndex);
334+
335+ // If this is a reference field, load the reference right now.
336+ if (fieldType->isReferenceType ()) {
337+ cgm.errorNYI (field->getSourceRange (), " emitLValueForField: reference type" );
338+ return LValue ();
339+ }
340+
341+ if (field->hasAttr <AnnotateAttr>()) {
342+ cgm.errorNYI (field->getSourceRange (), " emitLValueForField: AnnotateAttr" );
343+ return LValue ();
344+ }
345+
346+ LValue lv = makeAddrLValue (addr, fieldType, fieldBaseInfo);
347+ lv.getQuals ().addCVRQualifiers (recordCVR);
348+
349+ // __weak attribute on a field is ignored.
350+ if (lv.getQuals ().getObjCGCAttr () == Qualifiers::Weak) {
351+ cgm.errorNYI (field->getSourceRange (),
352+ " emitLValueForField: __weak attribute" );
353+ return LValue ();
354+ }
355+
356+ return lv;
357+ }
358+
267359mlir::Value CIRGenFunction::emitToMemory (mlir::Value value, QualType ty) {
268360 // Bool has a different representation in memory than in registers,
269361 // but in ClangIR, it is simply represented as a cir.bool value.
@@ -608,6 +700,48 @@ CIRGenFunction::emitArraySubscriptExpr(const clang::ArraySubscriptExpr *e) {
608700 return lv;
609701}
610702
703+ LValue CIRGenFunction::emitMemberExpr (const MemberExpr *e) {
704+ if (auto *vd = dyn_cast<VarDecl>(e->getMemberDecl ())) {
705+ cgm.errorNYI (e->getSourceRange (), " emitMemberExpr: VarDecl" );
706+ return LValue ();
707+ }
708+
709+ Expr *baseExpr = e->getBase ();
710+ // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a scalar.
711+ LValue baseLV;
712+ if (e->isArrow ()) {
713+ LValueBaseInfo baseInfo;
714+ assert (!cir::MissingFeatures::opTBAA ());
715+ Address addr = emitPointerWithAlignment (baseExpr, &baseInfo);
716+ QualType ptrTy = baseExpr->getType ()->getPointeeType ();
717+ assert (!cir::MissingFeatures::typeChecks ());
718+ baseLV = makeAddrLValue (addr, ptrTy, baseInfo);
719+ } else {
720+ assert (!cir::MissingFeatures::typeChecks ());
721+ baseLV = emitLValue (baseExpr);
722+ }
723+
724+ const NamedDecl *nd = e->getMemberDecl ();
725+ if (auto *field = dyn_cast<FieldDecl>(nd)) {
726+ LValue lv = emitLValueForField (baseLV, field);
727+ assert (!cir::MissingFeatures::setObjCGCLValueClass ());
728+ if (getLangOpts ().OpenMP ) {
729+ // If the member was explicitly marked as nontemporal, mark it as
730+ // nontemporal. If the base lvalue is marked as nontemporal, mark access
731+ // to children as nontemporal too.
732+ cgm.errorNYI (e->getSourceRange (), " emitMemberExpr: OpenMP" );
733+ }
734+ return lv;
735+ }
736+
737+ if (const auto *fd = dyn_cast<FunctionDecl>(nd)) {
738+ cgm.errorNYI (e->getSourceRange (), " emitMemberExpr: FunctionDecl" );
739+ return LValue ();
740+ }
741+
742+ llvm_unreachable (" Unhandled member declaration!" );
743+ }
744+
611745LValue CIRGenFunction::emitBinaryOperatorLValue (const BinaryOperator *e) {
612746 // Comma expressions just emit their LHS then their RHS as an l-value.
613747 if (e->getOpcode () == BO_Comma) {
0 commit comments