================ @@ -635,3 +638,496 @@ bool clang::api_notes::parseAndDumpAPINotes(StringRef YI, return false; } + +namespace { +using namespace api_notes; + +class YAMLConverter { + const Module &TheModule; + APINotesWriter Writer; + llvm::raw_ostream &OS; + llvm::SourceMgr::DiagHandlerTy DiagHandler; + void *DiagHandlerCtxt; + bool ErrorOccured; + + /// Emit a diagnostic + bool emitError(llvm::Twine Message) { + DiagHandler( + llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error, Message.str()), + DiagHandlerCtxt); + ErrorOccured = true; + return true; + } + +public: + YAMLConverter(const Module &TheModule, const FileEntry *SourceFile, + llvm::raw_ostream &OS, + llvm::SourceMgr::DiagHandlerTy DiagHandler, + void *DiagHandlerCtxt) + : TheModule(TheModule), Writer(TheModule.Name, SourceFile), OS(OS), + DiagHandler(DiagHandler), DiagHandlerCtxt(DiagHandlerCtxt), + ErrorOccured(false) {} + + bool convertAvailability(const AvailabilityItem &In, + CommonEntityInfo &OutInfo, llvm::StringRef APIName) { + // Populate the unavailability information. + OutInfo.Unavailable = (In.Mode == APIAvailability::None); + OutInfo.UnavailableInSwift = (In.Mode == APIAvailability::NonSwift); + if (OutInfo.Unavailable || OutInfo.UnavailableInSwift) { + OutInfo.UnavailableMsg = std::string(In.Msg); + } else { + if (!In.Msg.empty()) { + emitError("availability message for available API '" + APIName + + "' will not be used"); + } + } + return false; + } + + void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo) { + for (const auto &P : Params) { + ParamInfo PI; + if (P.Nullability) + PI.setNullabilityAudited(*P.Nullability); + PI.setNoEscape(P.NoEscape); + PI.setType(std::string(P.Type)); + PI.setRetainCountConvention(P.RetainCountConvention); + while (OutInfo.Params.size() <= P.Position) { + OutInfo.Params.push_back(ParamInfo()); + } + OutInfo.Params[P.Position] |= PI; + } + } + + void convertNullability(const NullabilitySeq &Nullability, + std::optional<NullabilityKind> NullabilityOfRet, + FunctionInfo &OutInfo, llvm::StringRef APIName) { + if (Nullability.size() > FunctionInfo::getMaxNullabilityIndex()) { + emitError("nullability info for " + APIName + " does not fit"); + return; + } + + bool audited = false; + unsigned int idx = 1; + for (auto i = Nullability.begin(), e = Nullability.end(); i != e; + ++i, ++idx) { + OutInfo.addTypeInfo(idx, *i); + audited = true; + } + if (NullabilityOfRet) { + OutInfo.addTypeInfo(0, *NullabilityOfRet); + audited = true; + } else if (audited) { + OutInfo.addTypeInfo(0, NullabilityKind::NonNull); + } + if (audited) { + OutInfo.NullabilityAudited = audited; + OutInfo.NumAdjustedNullable = idx; + } + } + + /// Convert the common parts of an entity from YAML. + template <typename T> + bool convertCommon(const T &Common, CommonEntityInfo &Info, + StringRef APIName) { + convertAvailability(Common.Availability, Info, APIName); + Info.setSwiftPrivate(Common.SwiftPrivate); + Info.SwiftName = std::string(Common.SwiftName); + return false; + } + + /// Convert the common parts of a type entity from YAML. + template <typename T> + bool convertCommonType(const T &Common, CommonTypeInfo &Info, + StringRef APIName) { + if (convertCommon(Common, Info, APIName)) + return true; + + if (Common.SwiftBridge) + Info.setSwiftBridge(std::string(*Common.SwiftBridge)); + Info.setNSErrorDomain(Common.NSErrorDomain); + return false; + } + + // Translate from Method into ObjCMethodInfo and write it out. + void convertMethod(const Method &TheMethod, ContextID ClassID, ---------------- egorzhdan wrote:
Done https://github.com/llvm/llvm-project/pull/71413 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits