================
@@ -7,11 +7,125 @@
 
//===----------------------------------------------------------------------===//
 
 #include "clang/APINotes/Types.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace clang {
 namespace api_notes {
 
+// Conservatively detect spellings where cv-qualification belongs to an
+// indirect/declarator layer rather than the by-value parameter itself.
+static bool
+hasTopLevelIndirectParameterSelectorSpelling(llvm::StringRef Spelling) {
+  unsigned Depth = 0;
+
+  for (char C : Spelling) {
+    switch (C) {
+    case '*':
+    case '&':
+      if (Depth == 0)
+        return true;
+      break;
+
+    case '[':
+    case '(':
+      if (Depth == 0)
+        return true;
+      ++Depth;
+      break;
+
+    case '<':
+      ++Depth;
+      break;
+
+    case '>':
+    case ']':
+    case ')':
+      if (Depth != 0)
+        --Depth;
+      break;
+
+    default:
+      break;
+    }
+  }
+
+  return false;
+}
+
+static bool shouldDropParameterSelectorSpace(char Previous, char Next) {
+  if (Previous == '<' || Previous == ',' || Next == '>' || Next == ',' ||
+      Next == '<')
+    return true;
+
+  if (Next == '*' || Next == '&')
+    return true;
+
+  if (Previous == '&' && Next == '&')
+    return true;
+
+  return false;
+}
+
+static std::string
+collapseParameterSelectorWhitespace(llvm::StringRef Spelling) {
+  llvm::SmallVector<llvm::StringRef, 4> Tokens;
+  llvm::SplitString(Spelling, Tokens);
+  return llvm::join(Tokens, " ");
+}
+
+static llvm::StringRef normalizeUnsignedIntSpelling(llvm::StringRef Spelling) {
+  if (Spelling == "unsigned")
+    return "unsigned int";
+  return Spelling;
+}
+
+static llvm::StringRef stripTopLevelValueConst(llvm::StringRef Spelling) {
+  if (hasTopLevelIndirectParameterSelectorSpelling(Spelling))
+    return Spelling;
+
+  Spelling.consume_front("const ");
+  Spelling.consume_back(" const");
+  return Spelling;
+}
+
+// Remove spaces around selector punctuation while preserving token-separating
+// spaces such as the one in "unsigned int".
+static void removeParameterSelectorPunctuationSpaces(
+    llvm::StringRef Spelling, llvm::SmallVectorImpl<char> &Normalized) {
+  Normalized.clear();
+  for (unsigned I = 0, E = Spelling.size(); I != E; ++I) {
+    char C = Spelling[I];
+    if (C == ' ' && I != 0 && I + 1 != E &&
+        shouldDropParameterSelectorSpace(Spelling[I - 1], Spelling[I + 1]))
+      continue;
+
+    Normalized.push_back(C);
+  }
+}
+
+static std::string stripTopLevelPointerConst(llvm::StringRef Spelling) {
+  if (!Spelling.consume_back("*const") && !Spelling.consume_back("* const"))
+    return Spelling.str();
+
+  std::string WithoutTopLevelConst = Spelling.str();
+  WithoutTopLevelConst += '*';
+  return WithoutTopLevelConst;
+}
+
+std::string normalizeAPINotesParameterSelector(llvm::StringRef Spelling) {
----------------
j-hui wrote:

I think it might be helpful to include a comment that shows how a particular 
example gets normalized through each of these helper functions.

https://github.com/llvm/llvm-project/pull/213043
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to