================
@@ -2469,9 +2469,171 @@ 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,
----------------
nickdesaulniers wrote:
I've reworked most of the patch in cf873fa4f74fc4a4f0f8516bdd72b9a115301f98.
PTAL
https://github.com/llvm/llvm-project/pull/231696
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits