diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 13 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 126 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 2 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.h | 5 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 4 |
9 files changed, 166 insertions, 8 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index ef136f8..9049a01 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -190,6 +190,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, assert(!cir::MissingFeatures::builtinCheckKind()); return emitBuiltinBitOp<cir::BitClzOp>(*this, e, /*poisonZero=*/true); + case Builtin::BI__builtin_ffs: + case Builtin::BI__builtin_ffsl: + case Builtin::BI__builtin_ffsll: + return emitBuiltinBitOp<cir::BitFfsOp>(*this, e); + case Builtin::BI__builtin_parity: case Builtin::BI__builtin_parityl: case Builtin::BI__builtin_parityll: diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 7ff5f26..64dc1ce 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -949,7 +949,6 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) { case CK_Dynamic: case CK_ToUnion: case CK_BaseToDerived: - case CK_LValueBitCast: case CK_AddressSpaceConversion: case CK_ObjCObjectLValueCast: case CK_VectorSplat: @@ -965,6 +964,18 @@ LValue CIRGenFunction::emitCastLValue(const CastExpr *e) { return {}; } + case CK_LValueBitCast: { + // This must be a reinterpret_cast (or c-style equivalent). + const auto *ce = cast<ExplicitCastExpr>(e); + + cgm.emitExplicitCastExprType(ce, this); + LValue LV = emitLValue(e->getSubExpr()); + Address V = LV.getAddress().withElementType( + builder, convertTypeForMem(ce->getTypeAsWritten()->getPointeeType())); + + return makeAddrLValue(V, e->getType(), LV.getBaseInfo()); + } + case CK_NoOp: { // CK_NoOp can model a qualification conversion, which can remove an array // bound and change the IR type. diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index d8459b4..51aab95 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -438,8 +438,7 @@ void AggExprEmitter::visitCXXParenListOrInitListExpr( // Push a destructor if necessary. // FIXME: if we have an array of structures, all explicitly // initialized, we can end up pushing a linear number of cleanups. - if (QualType::DestructionKind dtorKind = - field->getType().isDestructedType()) { + if (field->getType().isDestructedType()) { cgf.cgm.errorNYI(e->getSourceRange(), "visitCXXParenListOrInitListExpr destructor"); return; diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 02685a3..a09d739 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -189,8 +189,11 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op, } case CK_LValueBitCast: { - cgf.cgm.errorNYI("ComplexExprEmitter::emitCast CK_LValueBitCast"); - return {}; + LValue origLV = cgf.emitLValue(op); + Address addr = + origLV.getAddress().withElementType(builder, cgf.convertType(destTy)); + LValue destLV = cgf.makeAddrLValue(addr, destTy); + return emitLoadOfLValue(destLV, op->getExprLoc()); } case CK_LValueToRValueBitCast: { diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index b4b95d6..c65d025 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -923,4 +923,130 @@ CIRGenFunction::emitArrayLength(const clang::ArrayType *origArrayType, return builder.getConstInt(*currSrcLoc, SizeTy, countFromCLAs); } +// TODO(cir): Most of this function can be shared between CIRGen +// and traditional LLVM codegen +void CIRGenFunction::emitVariablyModifiedType(QualType type) { + assert(type->isVariablyModifiedType() && + "Must pass variably modified type to EmitVLASizes!"); + + // We're going to walk down into the type and look for VLA + // expressions. + do { + assert(type->isVariablyModifiedType()); + + const Type *ty = type.getTypePtr(); + switch (ty->getTypeClass()) { + case Type::CountAttributed: + case Type::PackIndexing: + case Type::ArrayParameter: + case Type::HLSLAttributedResource: + case Type::HLSLInlineSpirv: + case Type::PredefinedSugar: + cgm.errorNYI("CIRGenFunction::emitVariablyModifiedType"); + +#define TYPE(Class, Base) +#define ABSTRACT_TYPE(Class, Base) +#define NON_CANONICAL_TYPE(Class, Base) +#define DEPENDENT_TYPE(Class, Base) case Type::Class: +#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) +#include "clang/AST/TypeNodes.inc" + llvm_unreachable( + "dependent type must be resolved before the CIR codegen"); + + // These types are never variably-modified. + case Type::Builtin: + case Type::Complex: + case Type::Vector: + case Type::ExtVector: + case Type::ConstantMatrix: + case Type::Record: + case Type::Enum: + case Type::Using: + case Type::TemplateSpecialization: + case Type::ObjCTypeParam: + case Type::ObjCObject: + case Type::ObjCInterface: + case Type::ObjCObjectPointer: + case Type::BitInt: + llvm_unreachable("type class is never variably-modified!"); + + case Type::Elaborated: + type = cast<clang::ElaboratedType>(ty)->getNamedType(); + break; + + case Type::Adjusted: + type = cast<clang::AdjustedType>(ty)->getAdjustedType(); + break; + + case Type::Decayed: + type = cast<clang::DecayedType>(ty)->getPointeeType(); + break; + + case Type::Pointer: + type = cast<clang::PointerType>(ty)->getPointeeType(); + break; + + case Type::BlockPointer: + type = cast<clang::BlockPointerType>(ty)->getPointeeType(); + break; + + case Type::LValueReference: + case Type::RValueReference: + type = cast<clang::ReferenceType>(ty)->getPointeeType(); + break; + + case Type::MemberPointer: + type = cast<clang::MemberPointerType>(ty)->getPointeeType(); + break; + + case Type::ConstantArray: + case Type::IncompleteArray: + // Losing element qualification here is fine. + type = cast<clang::ArrayType>(ty)->getElementType(); + break; + + case Type::VariableArray: { + cgm.errorNYI("CIRGenFunction::emitVariablyModifiedType VLA"); + break; + } + + case Type::FunctionProto: + case Type::FunctionNoProto: + type = cast<clang::FunctionType>(ty)->getReturnType(); + break; + + case Type::Paren: + case Type::TypeOf: + case Type::UnaryTransform: + case Type::Attributed: + case Type::BTFTagAttributed: + case Type::SubstTemplateTypeParm: + case Type::MacroQualified: + // Keep walking after single level desugaring. + type = type.getSingleStepDesugaredType(getContext()); + break; + + case Type::Typedef: + case Type::Decltype: + case Type::Auto: + case Type::DeducedTemplateSpecialization: + // Stop walking: nothing to do. + return; + + case Type::TypeOfExpr: + // Stop walking: emit typeof expression. + emitIgnoredExpr(cast<clang::TypeOfExprType>(ty)->getUnderlyingExpr()); + return; + + case Type::Atomic: + type = cast<clang::AtomicType>(ty)->getValueType(); + break; + + case Type::Pipe: + type = cast<clang::PipeType>(ty)->getElementType(); + break; + } + } while (type->isVariablyModifiedType()); +} + } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 4891c74..77539d7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1201,6 +1201,8 @@ public: /// inside a function, including static vars etc. void emitVarDecl(const clang::VarDecl &d); + void emitVariablyModifiedType(QualType ty); + mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s); /// Given an assignment `*lhs = rhs`, emit a test that checks if \p rhs is diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 3502705..0724cb1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1208,6 +1208,15 @@ cir::GlobalOp CIRGenModule::getGlobalForStringLiteral(const StringLiteral *s, return gv; } +void CIRGenModule::emitExplicitCastExprType(const ExplicitCastExpr *e, + CIRGenFunction *cgf) { + if (cgf && e->getType()->isVariablyModifiedType()) + cgf->emitVariablyModifiedType(e->getType()); + + assert(!cir::MissingFeatures::generateDebugInfo() && + "emitExplicitCastExprType"); +} + void CIRGenModule::emitDeclContext(const DeclContext *dc) { for (Decl *decl : dc->decls()) { // Unlike other DeclContexts, the contents of an ObjCImplDecl at TU scope diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index 16922b1..22519ff 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -252,6 +252,11 @@ public: getAddrOfGlobal(clang::GlobalDecl gd, ForDefinition_t isForDefinition = NotForDefinition); + /// Emit type info if type of an expression is a variably modified + /// type. Also emit proper debug info for cast types. + void emitExplicitCastExprType(const ExplicitCastExpr *e, + CIRGenFunction *cgf = nullptr); + /// Emit code for a single global function or variable declaration. Forward /// declarations are emitted lazily. void emitGlobal(clang::GlobalDecl gd); diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 05e8848..e4ec380 100644 --- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp @@ -438,9 +438,7 @@ CIRRecordLowering::accumulateBitFields(RecordDecl::field_iterator field, } else if (cirGenTypes.getCGModule() .getCodeGenOpts() .FineGrainedBitfieldAccesses) { - assert(!cir::MissingFeatures::nonFineGrainedBitfields()); - cirGenTypes.getCGModule().errorNYI(field->getSourceRange(), - "NYI FineGrainedBitfield"); + installBest = true; } else { // Otherwise, we're not installing. Update the bit size // of the current span to go all the way to limitOffset, which is |