@@ -109,8 +109,10 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
109
109
void mangleCXXCtorVTable (const CXXRecordDecl *RD, int64_t Offset,
110
110
const CXXRecordDecl *Type, raw_ostream &) override ;
111
111
void mangleCXXRTTI (QualType T, raw_ostream &) override ;
112
- void mangleCXXRTTIName (QualType T, raw_ostream &) override ;
113
- void mangleTypeName (QualType T, raw_ostream &) override ;
112
+ void mangleCXXRTTIName (QualType T, raw_ostream &,
113
+ bool NormalizeIntegers) override ;
114
+ void mangleTypeName (QualType T, raw_ostream &,
115
+ bool NormalizeIntegers) override ;
114
116
115
117
void mangleCXXCtorComdat (const CXXConstructorDecl *D, raw_ostream &) override ;
116
118
void mangleCXXDtorComdat (const CXXDestructorDecl *D, raw_ostream &) override ;
@@ -215,6 +217,10 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
215
217
class CXXNameMangler {
216
218
ItaniumMangleContextImpl &Context;
217
219
raw_ostream &Out;
220
+ // / Normalize integer types for cross-language CFI support with other
221
+ // / languages that can't represent and encode C/C++ integer types.
222
+ bool NormalizeIntegers = false ;
223
+
218
224
bool NullOut = false ;
219
225
// / In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated.
220
226
// / This mode is used when mangler creates another mangler recursively to
@@ -413,6 +419,10 @@ class CXXNameMangler {
413
419
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
414
420
AbiTagsRoot(AbiTags) {}
415
421
422
+ CXXNameMangler (ItaniumMangleContextImpl &C, raw_ostream &Out_,
423
+ bool NormalizeIntegers_)
424
+ : Context(C), Out(Out_), NormalizeIntegers(NormalizeIntegers_),
425
+ NullOut(false ), Structor(nullptr ), AbiTagsRoot(AbiTags) {}
416
426
CXXNameMangler (CXXNameMangler &Outer, raw_ostream &Out_)
417
427
: Context(Outer.Context), Out(Out_), Structor(Outer.Structor),
418
428
StructorType(Outer.StructorType), SeqID(Outer.SeqID),
@@ -2937,6 +2947,85 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
2937
2947
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
2938
2948
// ::= u <source-name> # vendor extended type
2939
2949
std::string type_name;
2950
+ // Normalize integer types as vendor extended types:
2951
+ // u<length>i<type size>
2952
+ // u<length>u<type size>
2953
+ if (NormalizeIntegers && T->isInteger ()) {
2954
+ if (T->isSignedInteger ()) {
2955
+ switch (getASTContext ().getTypeSize (T)) {
2956
+ case 8 :
2957
+ // Pick a representative for each integer size in the substitution
2958
+ // dictionary. (Its actual defined size is not relevant.)
2959
+ if (mangleSubstitution (BuiltinType::SChar))
2960
+ break ;
2961
+ Out << " u2i8" ;
2962
+ addSubstitution (BuiltinType::SChar);
2963
+ break ;
2964
+ case 16 :
2965
+ if (mangleSubstitution (BuiltinType::Short))
2966
+ break ;
2967
+ Out << " u3i16" ;
2968
+ addSubstitution (BuiltinType::Short);
2969
+ break ;
2970
+ case 32 :
2971
+ if (mangleSubstitution (BuiltinType::Int))
2972
+ break ;
2973
+ Out << " u3i32" ;
2974
+ addSubstitution (BuiltinType::Int);
2975
+ break ;
2976
+ case 64 :
2977
+ if (mangleSubstitution (BuiltinType::Long))
2978
+ break ;
2979
+ Out << " u3i64" ;
2980
+ addSubstitution (BuiltinType::Long);
2981
+ break ;
2982
+ case 128 :
2983
+ if (mangleSubstitution (BuiltinType::Int128))
2984
+ break ;
2985
+ Out << " u4i128" ;
2986
+ addSubstitution (BuiltinType::Int128);
2987
+ break ;
2988
+ default :
2989
+ llvm_unreachable (" Unknown integer size for normalization" );
2990
+ }
2991
+ } else {
2992
+ switch (getASTContext ().getTypeSize (T)) {
2993
+ case 8 :
2994
+ if (mangleSubstitution (BuiltinType::UChar))
2995
+ break ;
2996
+ Out << " u2u8" ;
2997
+ addSubstitution (BuiltinType::UChar);
2998
+ break ;
2999
+ case 16 :
3000
+ if (mangleSubstitution (BuiltinType::UShort))
3001
+ break ;
3002
+ Out << " u3u16" ;
3003
+ addSubstitution (BuiltinType::UShort);
3004
+ break ;
3005
+ case 32 :
3006
+ if (mangleSubstitution (BuiltinType::UInt))
3007
+ break ;
3008
+ Out << " u3u32" ;
3009
+ addSubstitution (BuiltinType::UInt);
3010
+ break ;
3011
+ case 64 :
3012
+ if (mangleSubstitution (BuiltinType::ULong))
3013
+ break ;
3014
+ Out << " u3u64" ;
3015
+ addSubstitution (BuiltinType::ULong);
3016
+ break ;
3017
+ case 128 :
3018
+ if (mangleSubstitution (BuiltinType::UInt128))
3019
+ break ;
3020
+ Out << " u4u128" ;
3021
+ addSubstitution (BuiltinType::UInt128);
3022
+ break ;
3023
+ default :
3024
+ llvm_unreachable (" Unknown integer size for normalization" );
3025
+ }
3026
+ }
3027
+ return ;
3028
+ }
2940
3029
switch (T->getKind ()) {
2941
3030
case BuiltinType::Void:
2942
3031
Out << ' v' ;
@@ -6523,16 +6612,17 @@ void ItaniumMangleContextImpl::mangleCXXRTTI(QualType Ty, raw_ostream &Out) {
6523
6612
Mangler.mangleType (Ty);
6524
6613
}
6525
6614
6526
- void ItaniumMangleContextImpl::mangleCXXRTTIName (QualType Ty,
6527
- raw_ostream &Out ) {
6615
+ void ItaniumMangleContextImpl::mangleCXXRTTIName (
6616
+ QualType Ty, raw_ostream &Out, bool NormalizeIntegers = false ) {
6528
6617
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
6529
- CXXNameMangler Mangler (*this , Out);
6618
+ CXXNameMangler Mangler (*this , Out, NormalizeIntegers );
6530
6619
Mangler.getStream () << " _ZTS" ;
6531
6620
Mangler.mangleType (Ty);
6532
6621
}
6533
6622
6534
- void ItaniumMangleContextImpl::mangleTypeName (QualType Ty, raw_ostream &Out) {
6535
- mangleCXXRTTIName (Ty, Out);
6623
+ void ItaniumMangleContextImpl::mangleTypeName (QualType Ty, raw_ostream &Out,
6624
+ bool NormalizeIntegers = false ) {
6625
+ mangleCXXRTTIName (Ty, Out, NormalizeIntegers);
6536
6626
}
6537
6627
6538
6628
void ItaniumMangleContextImpl::mangleStringLiteral (const StringLiteral *, raw_ostream &) {
0 commit comments