================
@@ -993,6 +993,87 @@ UnwindTagContext(TagDecl *DC, api_notes::APINotesManager
&APINotes) {
return std::nullopt;
}
+static void stripAPINotesParameterNullability(QualType &ParamType) {
+ while (true) {
+ if (!AttributedType::stripOuterNullability(ParamType))
+ return;
+ }
+}
+
+// Print the APINotes selector spelling for one parameter. The source-spelled
+// selector is tried first. The desugared spelling is only a permissive
+// fallback.
+static std::string getAPINotesParameterSelectorSpelling(
+ QualType ParamType, const ASTContext &Context, const PrintingPolicy
&Policy,
+ bool Desugar) {
+ ParamType.removeLocalConst();
+ stripAPINotesParameterNullability(ParamType);
+
+ if (Desugar) {
+ ParamType = ParamType.getDesugaredType(Context);
+ ParamType.removeLocalConst();
+ stripAPINotesParameterNullability(ParamType);
+ }
+
+ return ParamType.getAsString(Policy);
+}
+
+static std::optional<SmallVector<SmallVector<std::string, 4>, 2>>
+getAPINotesParameterSelectorCandidates(const Sema &S, const FunctionDecl *FD) {
+ const auto *FPT = FD->getType()->getAs<FunctionProtoType>();
+ if (!FPT)
+ return std::nullopt;
+
+ SmallVector<std::string, 4> SourceParameters;
+ SmallVector<std::string, 4> DesugaredParameters;
+ SourceParameters.reserve(FPT->getNumParams());
+ DesugaredParameters.reserve(FPT->getNumParams());
+
+ const PrintingPolicy &Policy = S.Context.getPrintingPolicy();
+ for (QualType ParamType : FPT->param_types()) {
+ SourceParameters.push_back(getAPINotesParameterSelectorSpelling(
+ ParamType, S.Context, Policy, /*Desugar=*/false));
+ DesugaredParameters.push_back(getAPINotesParameterSelectorSpelling(
+ ParamType, S.Context, Policy, /*Desugar=*/true));
+ }
+
+ SmallVector<SmallVector<std::string, 4>, 2> Candidates;
+ Candidates.push_back(std::move(SourceParameters));
+ if (Candidates.front() != DesugaredParameters)
+ Candidates.push_back(std::move(DesugaredParameters));
+
+ return Candidates;
+}
+
+static SmallVector<StringRef, 4>
+getAPINotesParameterSelectorRefs(ArrayRef<std::string> Strings) {
----------------
j-hui wrote:
This helper is only used in one place, and all it seems to be doing is
massaging between values and references of strings and arrays.
Echoing what @Xazax-hun suggested about defining a struct with named fields, it
might be nice to encapsulate the "shape" of a function's parameter selectors
behind some kind of struct. Then this kind of helper can be exposed as a method
rather than a static helper.
https://github.com/llvm/llvm-project/pull/205307
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits