@@ -29,6 +29,54 @@ namespace
2929 ZeroPadFlag = 1 << 4
3030 };
3131
32+ bool IsWindowsPlatform (Platform* platform)
33+ {
34+ return platform && (platform->GetName ().find (" windows" ) != string::npos);
35+ }
36+
37+ bool IsApplePlatform (Platform* platform)
38+ {
39+ if (!platform)
40+ return false ;
41+ const string name = platform->GetName ();
42+ return name.starts_with (" mac-" ) || name.starts_with (" ios-" ) || name.starts_with (" tvos-" )
43+ || name.starts_with (" watchos-" );
44+ }
45+
46+ optional<size_t > GetAddressSize (Platform* platform)
47+ {
48+ if (!platform)
49+ return nullopt ;
50+ auto arch = platform->GetArchitecture ();
51+ if (!arch)
52+ return nullopt ;
53+ return arch->GetAddressSize ();
54+ }
55+
56+ optional<size_t > GetPlatformTypeWidth (const string& name, Platform* platform)
57+ {
58+ auto addressSize = GetAddressSize (platform);
59+ if (!addressSize.has_value ())
60+ return nullopt ;
61+
62+ if ((name == " long" ) || (name == " unsigned long" ))
63+ return IsWindowsPlatform (platform) ? 4 : *addressSize;
64+ if ((name == " ssize_t" ) || (name == " size_t" ) || (name == " ptrdiff_t" )
65+ || (name == " unsigned ptrdiff_t" ))
66+ {
67+ return *addressSize;
68+ }
69+ if (name == " wchar_t" )
70+ return IsWindowsPlatform (platform) ? 2 : 4 ;
71+ if (name == " long double" )
72+ {
73+ if (IsWindowsPlatform (platform) || IsApplePlatform (platform))
74+ return 8 ;
75+ return *addressSize == 4 ? 12 : 16 ;
76+ }
77+ return nullopt ;
78+ }
79+
3280 Confidence<Ref<Type>> IntegerArgument (
3381 size_t width, bool isSigned, uint8_t confidence = BN_FULL_CONFIDENCE ,
3482 uint8_t signednessConfidence = BN_FULL_CONFIDENCE )
@@ -38,26 +86,32 @@ namespace
3886 }
3987
4088 Confidence<Ref<Type>> PlatformIntegerArgument (
41- const string& name, bool isSigned, uint8_t confidence = BN_FULL_CONFIDENCE ,
89+ Platform* platform, const string& name, bool isSigned, uint8_t confidence = BN_FULL_CONFIDENCE ,
4290 uint8_t signednessConfidence = BN_FULL_CONFIDENCE )
4391 {
92+ auto width = GetPlatformTypeWidth (name, platform);
93+ if (!width.has_value ())
94+ return nullptr ;
4495 return Confidence<Ref<Type>>(
45- Type::IntegerType (0 , Confidence<bool >(isSigned, signednessConfidence), name ), confidence);
96+ Type::IntegerType (*width , Confidence<bool >(isSigned, signednessConfidence)), confidence);
4697 }
4798
48- Confidence<Ref<Type>> FloatArgument (size_t width, const string& name = " " ,
49- uint8_t confidence = BN_FULL_CONFIDENCE )
99+ Confidence<Ref<Type>> FloatArgument (size_t width, uint8_t confidence = BN_FULL_CONFIDENCE )
50100 {
51- return Confidence<Ref<Type>>(Type::FloatType (width, name ), confidence);
101+ return Confidence<Ref<Type>>(Type::FloatType (width), confidence);
52102 }
53103
54104 Confidence<Ref<Type>> PointerArgument (
55- const Confidence<Ref<Type>>& child, uint8_t confidence = BN_FULL_CONFIDENCE )
105+ Platform* platform, const Confidence<Ref<Type>>& child,
106+ uint8_t confidence = BN_FULL_CONFIDENCE )
56107 {
57- return Confidence<Ref<Type>>(Type::PointerType (static_cast <size_t >(0 ), child), confidence);
108+ auto width = GetAddressSize (platform);
109+ if (!width.has_value () || !child.GetValue ())
110+ return nullptr ;
111+ return Confidence<Ref<Type>>(Type::PointerType (*width, child), confidence);
58112 }
59113
60- Confidence<Ref<Type>> SignedIntegerArgument (LengthModifier length)
114+ Confidence<Ref<Type>> SignedIntegerArgument (LengthModifier length, Platform* platform )
61115 {
62116 switch (length)
63117 {
@@ -67,20 +121,20 @@ namespace
67121 // Signed char and signed short always promote to int.
68122 return IntegerArgument (4 , true );
69123 case LengthModifier::L:
70- return PlatformIntegerArgument (" long" , true );
124+ return PlatformIntegerArgument (platform, " long" , true );
71125 case LengthModifier::LL :
72126 case LengthModifier::J:
73127 return IntegerArgument (8 , true );
74128 case LengthModifier::Z:
75- return PlatformIntegerArgument (" ssize_t" , true );
129+ return PlatformIntegerArgument (platform, " ssize_t" , true );
76130 case LengthModifier::T:
77- return PlatformIntegerArgument (" ptrdiff_t" , true );
131+ return PlatformIntegerArgument (platform, " ptrdiff_t" , true );
78132 default :
79133 return nullptr ;
80134 }
81135 }
82136
83- Confidence<Ref<Type>> UnsignedIntegerArgument (LengthModifier length)
137+ Confidence<Ref<Type>> UnsignedIntegerArgument (LengthModifier length, Platform* platform )
84138 {
85139 switch (length)
86140 {
@@ -91,20 +145,20 @@ namespace
91145 // The promotion is int when it can represent every value, and unsigned int otherwise.
92146 return IntegerArgument (4 , true , BN_HEURISTIC_CONFIDENCE , 0 );
93147 case LengthModifier::L:
94- return PlatformIntegerArgument (" unsigned long" , false );
148+ return PlatformIntegerArgument (platform, " unsigned long" , false );
95149 case LengthModifier::LL :
96150 case LengthModifier::J:
97151 return IntegerArgument (8 , false );
98152 case LengthModifier::Z:
99- return PlatformIntegerArgument (" size_t" , false );
153+ return PlatformIntegerArgument (platform, " size_t" , false );
100154 case LengthModifier::T:
101- return PlatformIntegerArgument (" unsigned ptrdiff_t" , false );
155+ return PlatformIntegerArgument (platform, " unsigned ptrdiff_t" , false );
102156 default :
103157 return nullptr ;
104158 }
105159 }
106160
107- Confidence<Ref<Type>> CountPointerArgument (LengthModifier length)
161+ Confidence<Ref<Type>> CountPointerArgument (LengthModifier length, Platform* platform )
108162 {
109163 Confidence<Ref<Type>> child;
110164 switch (length)
@@ -119,22 +173,39 @@ namespace
119173 child = IntegerArgument (2 , true );
120174 break ;
121175 case LengthModifier::L:
122- child = PlatformIntegerArgument (" long" , true );
176+ child = PlatformIntegerArgument (platform, " long" , true );
123177 break ;
124178 case LengthModifier::LL :
125179 case LengthModifier::J:
126180 child = IntegerArgument (8 , true );
127181 break ;
128182 case LengthModifier::Z:
129- child = PlatformIntegerArgument (" ssize_t" , true );
183+ child = PlatformIntegerArgument (platform, " ssize_t" , true );
130184 break ;
131185 case LengthModifier::T:
132- child = PlatformIntegerArgument (" ptrdiff_t" , true );
186+ child = PlatformIntegerArgument (platform, " ptrdiff_t" , true );
133187 break ;
134188 default :
135189 return nullptr ;
136190 }
137- return PointerArgument (child);
191+ return PointerArgument (platform, child);
192+ }
193+
194+ Confidence<Ref<Type>> LongDoubleArgument (Platform* platform)
195+ {
196+ auto width = GetPlatformTypeWidth (" long double" , platform);
197+ if (!width.has_value ())
198+ return nullptr ;
199+ return FloatArgument (*width);
200+ }
201+
202+ bool AppendArgument (
203+ vector<Confidence<Ref<Type>>>& result, const Confidence<Ref<Type>>& argument)
204+ {
205+ if (!argument.GetValue ())
206+ return false ;
207+ result.push_back (argument);
208+ return true ;
138209 }
139210
140211 bool ValidateFlags (char conversion, uint8_t flags)
@@ -214,7 +285,8 @@ namespace
214285 return true ;
215286 }
216287
217- optional<vector<Confidence<Ref<Type>>>> ResolveCStyleFormatString (const string& format)
288+ optional<vector<Confidence<Ref<Type>>>> ResolveCStyleFormatString (
289+ const string& format, Platform* platform)
218290 {
219291 vector<Confidence<Ref<Type>>> result;
220292 for (size_t i = 0 ; i < format.size (); i++)
@@ -319,13 +391,15 @@ namespace
319391 {
320392 case ' d' :
321393 case ' i' :
322- result.push_back (SignedIntegerArgument (length));
394+ if (!AppendArgument (result, SignedIntegerArgument (length, platform)))
395+ return nullopt ;
323396 break ;
324397 case ' o' :
325398 case ' u' :
326399 case ' x' :
327400 case ' X' :
328- result.push_back (UnsignedIntegerArgument (length));
401+ if (!AppendArgument (result, UnsignedIntegerArgument (length, platform)))
402+ return nullopt ;
329403 break ;
330404 case ' f' :
331405 case ' F' :
@@ -335,33 +409,57 @@ namespace
335409 case ' G' :
336410 case ' a' :
337411 case ' A' :
338- result.push_back (length == LengthModifier::CapitalL
339- ? FloatArgument (0 , " long double" ) : FloatArgument (8 ));
412+ if (!AppendArgument (result, length == LengthModifier::CapitalL
413+ ? LongDoubleArgument (platform) : FloatArgument (8 )))
414+ {
415+ return nullopt ;
416+ }
340417 break ;
341418 case ' c' :
342419 if (length == LengthModifier::L)
343- result.push_back (IntegerArgument (4 , true , BN_HEURISTIC_CONFIDENCE , 0 ));
420+ {
421+ if (!AppendArgument (
422+ result, IntegerArgument (4 , true , BN_HEURISTIC_CONFIDENCE , 0 )))
423+ {
424+ return nullopt ;
425+ }
426+ }
344427 else
345- result.push_back (IntegerArgument (4 , true ));
428+ {
429+ if (!AppendArgument (result, IntegerArgument (4 , true )))
430+ return nullopt ;
431+ }
346432 break ;
347433 case ' s' :
348434 if (length == LengthModifier::L)
349435 {
350- result.push_back (PointerArgument (
351- Confidence<Ref<Type>>(Type::WideCharType (0 , " wchar_t" ), BN_FULL_CONFIDENCE )));
436+ auto width = GetPlatformTypeWidth (" wchar_t" , platform);
437+ if (!width.has_value () || !AppendArgument (result, PointerArgument (platform,
438+ Confidence<Ref<Type>>(
439+ Type::WideCharType (*width, " wchar_t" ), BN_FULL_CONFIDENCE ))))
440+ {
441+ return nullopt ;
442+ }
352443 }
353444 else
354445 {
355- result.push_back (PointerArgument (Confidence<Ref<Type>>(
356- Type::IntegerType (1 , Confidence<bool >(true , 0 ), " char" ), BN_FULL_CONFIDENCE )));
446+ if (!AppendArgument (result, PointerArgument (platform, Confidence<Ref<Type>>(
447+ Type::IntegerType (1 , Confidence<bool >(true , 0 ), " char" ), BN_FULL_CONFIDENCE ))))
448+ {
449+ return nullopt ;
450+ }
357451 }
358452 break ;
359453 case ' p' :
360- result.push_back (PointerArgument (
361- Confidence<Ref<Type>>(Type::VoidType (), BN_FULL_CONFIDENCE )));
454+ if (!AppendArgument (result, PointerArgument (platform,
455+ Confidence<Ref<Type>>(Type::VoidType (), BN_FULL_CONFIDENCE ))))
456+ {
457+ return nullopt ;
458+ }
362459 break ;
363460 case ' n' :
364- result.push_back (CountPointerArgument (length));
461+ if (!AppendArgument (result, CountPointerArgument (length, platform)))
462+ return nullopt ;
365463 break ;
366464 case ' %' :
367465 break ;
@@ -379,9 +477,10 @@ CStyleFormatStringResolutionProvider::CStyleFormatStringResolutionProvider() :
379477{}
380478
381479
382- optional<vector<Confidence<Ref<Type>>>> CStyleFormatStringResolutionProvider::IsValid (const string& format)
480+ optional<vector<Confidence<Ref<Type>>>> CStyleFormatStringResolutionProvider::IsValid (
481+ const string& format, Platform* platform)
383482{
384- return ResolveCStyleFormatString (format);
483+ return ResolveCStyleFormatString (format, platform );
385484}
386485
387486
0 commit comments