================ @@ -7074,6 +7117,86 @@ bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C, return TrackAbiTags.AbiTagsRoot.getUsedAbiTags().size(); } +namespace { + +class RISCVZicfilpFuncSigLabelMangler : public CXXNameMangler { + bool IsTopLevelAndCXXVirtualMethod; + +public: + RISCVZicfilpFuncSigLabelMangler(ItaniumMangleContextImpl &C, raw_ostream &Out, + const bool IsCXXVirtualMethod) + : CXXNameMangler(C, Out), + IsTopLevelAndCXXVirtualMethod(/*IsTopLevel=*/true && + IsCXXVirtualMethod) {} + + void mangleTypeImpl(const BuiltinType *T) override { + if (T->getKind() == BuiltinType::WChar_S || + T->getKind() == BuiltinType::WChar_U) { + const Type *const OverrideT = + getASTContext().getWCharTypeInC().getTypePtr(); + assert(isa<BuiltinType>(OverrideT) && + "`wchar_t' in C is expected to be defined to a built-in type"); + T = static_cast<const BuiltinType *>(OverrideT); + } + return CXXNameMangler::mangleTypeImpl(T); + } + + // This <function-type> is the RISC-V psABI modified version + // <function-type> ::= [<CV-qualifiers>] [Dx] F <bare-function-type> + // [<ref-qualifier>] E + void mangleTypeImpl(const FunctionProtoType *T) override { + const bool WasTopLevelAndCXXVirtualMethod = IsTopLevelAndCXXVirtualMethod; + IsTopLevelAndCXXVirtualMethod = false; // Not top-level anymore + + // Mangle CV-qualifiers, if present. These are 'this' qualifiers, + // e.g. "const" in "int (A::*)() const". + mangleQualifiers(T->getMethodQuals()); + + getStream() << 'F'; + + bool MangleReturnType = true; + if (const Type &RetT = *T->getReturnType().getTypePtr(); + WasTopLevelAndCXXVirtualMethod && mayBeCovariant(RetT)) { + // Possible covariant types mangle dummy cv-unqualified `class v` as its + // class type + if (RetT.isPointerType()) + getStream() << "P1v"; + else if (RetT.isLValueReferenceType()) + getStream() << "R1v"; + else { + assert(RetT.isRValueReferenceType() && + "Expect an r-value ref for covariant return type that is not a " + "pointer or an l-value ref"); + getStream() << "O1v"; + } + MangleReturnType = false; + } + mangleBareFunctionType(T, MangleReturnType); + + // Mangle the ref-qualifier, if present. + mangleRefQualifier(T->getRefQualifier()); + + getStream() << 'E'; + } + + void mangleTypeImpl(const FunctionNoProtoType *T) override { + return CXXNameMangler::mangleTypeImpl(toFunctionProtoType(T)); + } + +private: + const FunctionProtoType * + toFunctionProtoType(const FunctionNoProtoType *const T) { + FunctionProtoType::ExtProtoInfo EPI; + EPI.ExtInfo = T->getExtInfo(); + const Type *const NewT = getASTContext() + .getFunctionType(T->getReturnType(), {}, EPI) + .getTypePtr(); + return static_cast<const FunctionProtoType *>(NewT); ---------------- efriedma-quic wrote:
This is pretty broken if you actually have code using pre-C23 semantics. If you don't want to think about it, just require that everyone use C23, and you won't see any FunctionNoProtoType. Otherwise, you need to actually do something reasonable, like using the type of the call arguments. https://github.com/llvm/llvm-project/pull/111661 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits