Skip to content

Commit be986d7

Browse files
committed
demangler: add an API to check if a function has the swiftcc calling convention
1 parent 0939e87 commit be986d7

File tree

6 files changed

+69
-21
lines changed

6 files changed

+69
-21
lines changed

include/swift/Basic/Demangle.h

+7
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,13 @@ class Context {
289289
/// or ObjC-as-swift thunks.
290290
bool isThunkSymbol(llvm::StringRef MangledName);
291291

292+
/// Returns true if the \p mangledName refers to a function which conforms to
293+
/// the Swift calling convention.
294+
///
295+
/// The return value is unspecified if the \p MangledName does not refer to a
296+
/// function symbol.
297+
bool hasSwiftCallingConvention(llvm::StringRef MangledName);
298+
292299
/// Deallocates all nodes.
293300
///
294301
/// The memory which is used for nodes is not freed but recycled for the next

include/swift/SwiftDemangle/SwiftDemangle.h

+8
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ size_t swift_demangle_getSimplifiedDemangledName(const char *MangledName,
5353
char *OutputBuffer,
5454
size_t Length);
5555

56+
/// \brief Demangles a Swift function name and returns true if the function
57+
/// conforms to the Swift calling convention.
58+
///
59+
/// \returns true if the function conforms to the Swift calling convention.
60+
/// The return value is unspecified if the \p MangledName does not refer to a
61+
/// function symbol.
62+
int swift_demangle_hasSwiftCallingConvention(const char *MangledName);
63+
5664
#ifdef __cplusplus
5765
} // extern "C"
5866
#endif

lib/Basic/Demangler.cpp

+25-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,31 @@ bool Context::isThunkSymbol(llvm::StringRef MangledName) {
208208
}
209209
return false;
210210
}
211-
211+
212+
bool Context::hasSwiftCallingConvention(llvm::StringRef MangledName) {
213+
Node *Global = demangleSymbolAsNode(MangledName);
214+
if (!Global || Global->getKind() != Node::Kind::Global ||
215+
Global->getNumChildren() == 0)
216+
return false;
217+
218+
Node *TopLevel = Global->getFirstChild();
219+
switch (TopLevel->getKind()) {
220+
// Functions, which don't have the swift calling conventions:
221+
case Node::Kind::TypeMetadataAccessFunction:
222+
case Node::Kind::ValueWitness:
223+
case Node::Kind::ProtocolWitnessTableAccessor:
224+
case Node::Kind::GenericProtocolWitnessTableInstantiationFunction:
225+
case Node::Kind::LazyProtocolWitnessTableAccessor:
226+
case Node::Kind::AssociatedTypeMetadataAccessor:
227+
case Node::Kind::AssociatedTypeWitnessTableAccessor:
228+
case Node::Kind::ObjCAttribute:
229+
return false;
230+
default:
231+
break;
232+
}
233+
return true;
234+
}
235+
212236
NodePointer Context::createNode(Node::Kind K) {
213237
return D->createNode(K);
214238
}

lib/SwiftDemangle/SwiftDemangle.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,13 @@ size_t swift_demangle_getSimplifiedDemangledName(const char *MangledName,
5454
Length, Opts);
5555
}
5656

57+
int swift_demangle_hasSwiftCallingConvention(const char *MangledName) {
58+
swift::Demangle::Context DCtx;
59+
if (DCtx.hasSwiftCallingConvention(llvm::StringRef(MangledName)))
60+
return 1;
61+
return 0;
62+
}
63+
5764
size_t fnd_get_demangled_name(const char *MangledName, char *OutputBuffer,
5865
size_t Length) {
5966
return swift_demangle_getDemangledName(MangledName, OutputBuffer, Length);

test/Demangle/Inputs/manglings.txt

+20-20
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@ _TF3foolp3barSi ---> foo.bar.nativePinningAddressor : Swift.Int
7777
_TF3foog3barSi ---> foo.bar.getter : Swift.Int
7878
_TF3foos3barSi ---> foo.bar.setter : Swift.Int
7979
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas (zim : foo.zim) -> ()
80-
_TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> {T} @objc foo.bar.bas (zim : foo.zim) -> ()
80+
_TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> {TC} @objc foo.bar.bas (zim : foo.zim) -> ()
8181
_TTOFSC3fooFTSdSd_Sd ---> {T} @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
82-
_T03foo3barC3basyAA3zimCAE_tFTo ---> {T} @objc foo.bar.bas (zim : foo.zim) -> ()
82+
_T03foo3barC3basyAA3zimCAE_tFTo ---> {TC} @objc foo.bar.bas (zim : foo.zim) -> ()
8383
_T0SC3fooSdSd_SdtFTO ---> {T} @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
8484
_TTDFC3foo3bar3basfT3zimCS_3zim_T_ ---> dynamic foo.bar.bas (zim : foo.zim) -> ()
8585
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas (zim : foo.zim) -> ()
@@ -94,31 +94,31 @@ _TMnC3foo3bar ---> nominal type descriptor for foo.bar
9494
_TMmC3foo3bar ---> metaclass for foo.bar
9595
_TMC3foo3bar ---> type metadata for foo.bar
9696
_TMfC3foo3bar ---> full type metadata for foo.bar
97-
_TwalC3foo3bar ---> allocateBuffer value witness for foo.bar
98-
_TwcaC3foo3bar ---> assignWithCopy value witness for foo.bar
99-
_TwtaC3foo3bar ---> assignWithTake value witness for foo.bar
100-
_TwdeC3foo3bar ---> deallocateBuffer value witness for foo.bar
101-
_TwxxC3foo3bar ---> destroy value witness for foo.bar
102-
_TwXXC3foo3bar ---> destroyBuffer value witness for foo.bar
103-
_TwCPC3foo3bar ---> initializeBufferWithCopyOfBuffer value witness for foo.bar
104-
_TwCpC3foo3bar ---> initializeBufferWithCopy value witness for foo.bar
105-
_TwcpC3foo3bar ---> initializeWithCopy value witness for foo.bar
106-
_TwTKC3foo3bar ---> initializeBufferWithTakeOfBuffer value witness for foo.bar
107-
_TwTkC3foo3bar ---> initializeBufferWithTake value witness for foo.bar
108-
_TwtkC3foo3bar ---> initializeWithTake value witness for foo.bar
109-
_TwprC3foo3bar ---> projectBuffer value witness for foo.bar
97+
_TwalC3foo3bar ---> {C} allocateBuffer value witness for foo.bar
98+
_TwcaC3foo3bar ---> {C} assignWithCopy value witness for foo.bar
99+
_TwtaC3foo3bar ---> {C} assignWithTake value witness for foo.bar
100+
_TwdeC3foo3bar ---> {C} deallocateBuffer value witness for foo.bar
101+
_TwxxC3foo3bar ---> {C} destroy value witness for foo.bar
102+
_TwXXC3foo3bar ---> {C} destroyBuffer value witness for foo.bar
103+
_TwCPC3foo3bar ---> {C} initializeBufferWithCopyOfBuffer value witness for foo.bar
104+
_TwCpC3foo3bar ---> {C} initializeBufferWithCopy value witness for foo.bar
105+
_TwcpC3foo3bar ---> {C} initializeWithCopy value witness for foo.bar
106+
_TwTKC3foo3bar ---> {C} initializeBufferWithTakeOfBuffer value witness for foo.bar
107+
_TwTkC3foo3bar ---> {C} initializeBufferWithTake value witness for foo.bar
108+
_TwtkC3foo3bar ---> {C} initializeWithTake value witness for foo.bar
109+
_TwprC3foo3bar ---> {C} projectBuffer value witness for foo.bar
110110
_TWVC3foo3bar ---> value witness table for foo.bar
111111
_TWoFC3foo3bar3basFSiSi ---> witness table offset for foo.bar.bas (Swift.Int) -> Swift.Int
112112
_TWvdvC3foo3bar3basSi ---> direct field offset for foo.bar.bas : Swift.Int
113113
_TWvivC3foo3bar3basSi ---> indirect field offset for foo.bar.bas : Swift.Int
114114
_TWPC3foo3barS_8barrables ---> protocol witness table for foo.bar : foo.barrable in Swift
115-
_TWaC3foo3barS_8barrableS_ ---> protocol witness table accessor for foo.bar : foo.barrable in foo
116-
_TWlC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table accessor for type foo.bar and conformance foo.bar : foo.barrable in foo
115+
_TWaC3foo3barS_8barrableS_ ---> {C} protocol witness table accessor for foo.bar : foo.barrable in foo
116+
_TWlC3foo3barS0_S_8barrableS_ ---> {C} lazy protocol witness table accessor for type foo.bar and conformance foo.bar : foo.barrable in foo
117117
_TWLC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table cache variable for type foo.bar and conformance foo.bar : foo.barrable in foo
118118
_TWGC3foo3barS_8barrableS_ ---> generic protocol witness table for foo.bar : foo.barrable in foo
119-
_TWIC3foo3barS_8barrableS_ ---> instantiation function for generic protocol witness table for foo.bar : foo.barrable in foo
120-
_TWtC3foo3barS_8barrableS_4fred ---> associated type metadata accessor for fred in foo.bar : foo.barrable in foo
121-
_TWTC3foo3barS_8barrableS_4fredS_6thomas ---> associated type witness table accessor for fred : foo.thomas in foo.bar : foo.barrable in foo
119+
_TWIC3foo3barS_8barrableS_ ---> {C} instantiation function for generic protocol witness table for foo.bar : foo.barrable in foo
120+
_TWtC3foo3barS_8barrableS_4fred ---> {C} associated type metadata accessor for fred in foo.bar : foo.barrable in foo
121+
_TWTC3foo3barS_8barrableS_4fredS_6thomas ---> {C} associated type witness table accessor for fred : foo.thomas in foo.bar : foo.barrable in foo
122122
_TFSCg5greenVSC5Color ---> __C.green.getter : __C.Color
123123
_TIF1t1fFT1iSi1sSS_T_A_ ---> t.(f (i : Swift.Int, s : Swift.String) -> ()).(default argument 0)
124124
_TIF1t1fFT1iSi1sSS_T_A0_ ---> t.(f (i : Swift.Int, s : Swift.String) -> ()).(default argument 1)

tools/swift-demangle/swift-demangle.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ static void demangle(llvm::raw_ostream &os, llvm::StringRef name,
132132
Classifications += 'N';
133133
if (DCtx.isThunkSymbol(name))
134134
Classifications += 'T';
135+
if (pointer && !DCtx.hasSwiftCallingConvention(name))
136+
Classifications += 'C';
135137
if (!Classifications.empty())
136138
llvm::outs() << '{' << Classifications << "} ";
137139
}

0 commit comments

Comments
 (0)