================
@@ -2457,9 +2457,167 @@ FunctionDecl *Sema::CreateBuiltin(IdentifierInfo *II, 
QualType Type,
   return New;
 }
 
+/// Return true if the builtin type descriptor string \p Str contains a struct
+/// tag ('r<len><name>') or typedef ('t<len><name>') that must be looked up in
+/// the translation unit.
+static bool hasTargetDependentBuiltinType(const char *Str) {
+  for (const char *P = Str; *P; ++P) {
+    if (*P == 'Q' && P[1]) {
+      ++P;
+      continue;
+    }
+    if (*P == 'r' || *P == 't') {
+      char *End;
+      (void)strtoul(P + 1, &End, 10);
+      if (End != P + 1)
+        return true;
+    }
+  }
+  return false;
+}
+
+/// Decode a single return or parameter type from \p TypeStr into \p BuiltinTy.
+/// Sets \p IsTargetTypedef if the descriptor is a typedef ('t<len><name>' or
+/// 'z' for size_t) whose underlying integer type may vary across targets.
+///
+/// If a 't<len><name>' typedef has not been declared in the translation unit
+/// (e.g., when a translation unit or non-POSIX header like Winsock declares
+/// `int recv(...)` or `int recvfrom(..., int *fromlen)` without defining
+/// `ssize_t` or `socklen_t`), falls back to `int` and applies any trailing
+/// pointer/reference/qualifier modifiers so integer compatibility checks still
+/// succeed.
+static bool decodeNextBuiltinType(ASTContext &Context, const char *&TypeStr,
+                                  QualType &BuiltinTy, bool &IsTargetTypedef) {
+  IsTargetTypedef = (*TypeStr == 't' || *TypeStr == 'z');
+
+  bool RequireICE = false;
+  ASTContext::GetBuiltinTypeError Error = ASTContext::GE_None;
+  BuiltinTy = Context.DecodeTypeStr(TypeStr, Context, Error, RequireICE,
+                                    /*AllowTypeModifiers=*/true);
+  if (Error == ASTContext::GE_None)
+    return true;
+  if (!IsTargetTypedef || Error != ASTContext::GE_Missing_type)
+    return false;
+
+  // The 't<len><name>' typedef was not declared in the translation unit.
+  // Substitute `int` as a placeholder integer base type and consume any
+  // trailing pointer/reference/qualifier modifiers on this descriptor.
+  BuiltinTy = Context.IntTy;
+  while (*TypeStr) {
+    char C = *TypeStr;
+    if (C == '*' || C == '&') {
+      BuiltinTy = (C == '*') ? Context.getPointerType(BuiltinTy)
+                             : Context.getLValueReferenceType(BuiltinTy);
+      ++TypeStr;
+      char *End;
+      (void)strtoul(TypeStr, &End, 10);
+      TypeStr = End;
+    } else if (C == 'C' || C == 'D' || C == 'R') {
+      ++TypeStr;
+    } else {
+      break;
+    }
+  }
+  return true;
+}
+
+/// Return true if a declared parameter or return type \p DeclTy is compatible
+/// with the expected builtin type \p BuiltinTy, accounting for platform
+/// variations in integer typedefs, transparent_union pointer wrappers, and
+/// char*/void* buffer pointers.
+static bool isCompatibleBuiltinParamOrReturnType(ASTContext &Context,
+                                                 QualType DeclTy,
+                                                 QualType BuiltinTy,
+                                                 bool IsTargetTypedef) {
+  if (Context.hasSameUnqualifiedType(DeclTy, BuiltinTy))
+    return true;
+
+  // Target-dependent typedefs (e.g. mode_t, ssize_t, size_t, nfds_t, off_t)
+  // may vary in integer rank or signedness across targets and headers (e.g.
+  // Winsock's recv uses int instead of size_t/ssize_t).
+  if (IsTargetTypedef && DeclTy->isIntegerType() && BuiltinTy->isIntegerType())
+    return true;
+
+  // Allow transparent_union wrappers (such as glibc's __SOCKADDR_ARG for
+  // struct sockaddr * in recvfrom) when the builtin expects a pointer.
+  if (BuiltinTy->isPointerType()) {
+    if (const auto *RT = DeclTy->getAs<RecordType>())
+      if (RT->getDecl()->hasAttr<TransparentUnionAttr>())
+        return true;
+  }
----------------
nickdesaulniers wrote:

Back in my day, we just cast everything to `void*` (_and we liked it_)!

Thanks for explanation (makes sense), and triple checking this. Will update 
this PR to incorporate that later.

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

Reply via email to