Skip to content

Commit

Permalink
demangler: add an API to check if a function has the swiftcc calling …
Browse files Browse the repository at this point in the history
…convention
  • Loading branch information
eeckstein committed Mar 1, 2017
1 parent 0939e87 commit be986d7
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 21 deletions.
7 changes: 7 additions & 0 deletions include/swift/Basic/Demangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,13 @@ class Context {
/// or ObjC-as-swift thunks.
bool isThunkSymbol(llvm::StringRef MangledName);

/// Returns true if the \p mangledName refers to a function which conforms to
/// the Swift calling convention.
///
/// The return value is unspecified if the \p MangledName does not refer to a
/// function symbol.
bool hasSwiftCallingConvention(llvm::StringRef MangledName);

/// Deallocates all nodes.
///
/// The memory which is used for nodes is not freed but recycled for the next
Expand Down
8 changes: 8 additions & 0 deletions include/swift/SwiftDemangle/SwiftDemangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ size_t swift_demangle_getSimplifiedDemangledName(const char *MangledName,
char *OutputBuffer,
size_t Length);

/// \brief Demangles a Swift function name and returns true if the function
/// conforms to the Swift calling convention.
///
/// \returns true if the function conforms to the Swift calling convention.
/// The return value is unspecified if the \p MangledName does not refer to a
/// function symbol.
int swift_demangle_hasSwiftCallingConvention(const char *MangledName);

#ifdef __cplusplus
} // extern "C"
#endif
Expand Down
26 changes: 25 additions & 1 deletion lib/Basic/Demangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,31 @@ bool Context::isThunkSymbol(llvm::StringRef MangledName) {
}
return false;
}


bool Context::hasSwiftCallingConvention(llvm::StringRef MangledName) {
Node *Global = demangleSymbolAsNode(MangledName);
if (!Global || Global->getKind() != Node::Kind::Global ||
Global->getNumChildren() == 0)
return false;

Node *TopLevel = Global->getFirstChild();
switch (TopLevel->getKind()) {
// Functions, which don't have the swift calling conventions:
case Node::Kind::TypeMetadataAccessFunction:
case Node::Kind::ValueWitness:
case Node::Kind::ProtocolWitnessTableAccessor:
case Node::Kind::GenericProtocolWitnessTableInstantiationFunction:
case Node::Kind::LazyProtocolWitnessTableAccessor:
case Node::Kind::AssociatedTypeMetadataAccessor:
case Node::Kind::AssociatedTypeWitnessTableAccessor:
case Node::Kind::ObjCAttribute:
return false;
default:
break;
}
return true;
}

NodePointer Context::createNode(Node::Kind K) {
return D->createNode(K);
}
Expand Down
7 changes: 7 additions & 0 deletions lib/SwiftDemangle/SwiftDemangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ size_t swift_demangle_getSimplifiedDemangledName(const char *MangledName,
Length, Opts);
}

int swift_demangle_hasSwiftCallingConvention(const char *MangledName) {
swift::Demangle::Context DCtx;
if (DCtx.hasSwiftCallingConvention(llvm::StringRef(MangledName)))
return 1;
return 0;
}

size_t fnd_get_demangled_name(const char *MangledName, char *OutputBuffer,
size_t Length) {
return swift_demangle_getDemangledName(MangledName, OutputBuffer, Length);
Expand Down
40 changes: 20 additions & 20 deletions test/Demangle/Inputs/manglings.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ _TF3foolp3barSi ---> foo.bar.nativePinningAddressor : Swift.Int
_TF3foog3barSi ---> foo.bar.getter : Swift.Int
_TF3foos3barSi ---> foo.bar.setter : Swift.Int
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas (zim : foo.zim) -> ()
_TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> {T} @objc foo.bar.bas (zim : foo.zim) -> ()
_TToFC3foo3bar3basfT3zimCS_3zim_T_ ---> {TC} @objc foo.bar.bas (zim : foo.zim) -> ()
_TTOFSC3fooFTSdSd_Sd ---> {T} @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
_T03foo3barC3basyAA3zimCAE_tFTo ---> {T} @objc foo.bar.bas (zim : foo.zim) -> ()
_T03foo3barC3basyAA3zimCAE_tFTo ---> {TC} @objc foo.bar.bas (zim : foo.zim) -> ()
_T0SC3fooSdSd_SdtFTO ---> {T} @nonobjc __C.foo (Swift.Double, Swift.Double) -> Swift.Double
_TTDFC3foo3bar3basfT3zimCS_3zim_T_ ---> dynamic foo.bar.bas (zim : foo.zim) -> ()
_TFC3foo3bar3basfT3zimCS_3zim_T_ ---> foo.bar.bas (zim : foo.zim) -> ()
Expand All @@ -94,31 +94,31 @@ _TMnC3foo3bar ---> nominal type descriptor for foo.bar
_TMmC3foo3bar ---> metaclass for foo.bar
_TMC3foo3bar ---> type metadata for foo.bar
_TMfC3foo3bar ---> full type metadata for foo.bar
_TwalC3foo3bar ---> allocateBuffer value witness for foo.bar
_TwcaC3foo3bar ---> assignWithCopy value witness for foo.bar
_TwtaC3foo3bar ---> assignWithTake value witness for foo.bar
_TwdeC3foo3bar ---> deallocateBuffer value witness for foo.bar
_TwxxC3foo3bar ---> destroy value witness for foo.bar
_TwXXC3foo3bar ---> destroyBuffer value witness for foo.bar
_TwCPC3foo3bar ---> initializeBufferWithCopyOfBuffer value witness for foo.bar
_TwCpC3foo3bar ---> initializeBufferWithCopy value witness for foo.bar
_TwcpC3foo3bar ---> initializeWithCopy value witness for foo.bar
_TwTKC3foo3bar ---> initializeBufferWithTakeOfBuffer value witness for foo.bar
_TwTkC3foo3bar ---> initializeBufferWithTake value witness for foo.bar
_TwtkC3foo3bar ---> initializeWithTake value witness for foo.bar
_TwprC3foo3bar ---> projectBuffer value witness for foo.bar
_TwalC3foo3bar ---> {C} allocateBuffer value witness for foo.bar
_TwcaC3foo3bar ---> {C} assignWithCopy value witness for foo.bar
_TwtaC3foo3bar ---> {C} assignWithTake value witness for foo.bar
_TwdeC3foo3bar ---> {C} deallocateBuffer value witness for foo.bar
_TwxxC3foo3bar ---> {C} destroy value witness for foo.bar
_TwXXC3foo3bar ---> {C} destroyBuffer value witness for foo.bar
_TwCPC3foo3bar ---> {C} initializeBufferWithCopyOfBuffer value witness for foo.bar
_TwCpC3foo3bar ---> {C} initializeBufferWithCopy value witness for foo.bar
_TwcpC3foo3bar ---> {C} initializeWithCopy value witness for foo.bar
_TwTKC3foo3bar ---> {C} initializeBufferWithTakeOfBuffer value witness for foo.bar
_TwTkC3foo3bar ---> {C} initializeBufferWithTake value witness for foo.bar
_TwtkC3foo3bar ---> {C} initializeWithTake value witness for foo.bar
_TwprC3foo3bar ---> {C} projectBuffer value witness for foo.bar
_TWVC3foo3bar ---> value witness table for foo.bar
_TWoFC3foo3bar3basFSiSi ---> witness table offset for foo.bar.bas (Swift.Int) -> Swift.Int
_TWvdvC3foo3bar3basSi ---> direct field offset for foo.bar.bas : Swift.Int
_TWvivC3foo3bar3basSi ---> indirect field offset for foo.bar.bas : Swift.Int
_TWPC3foo3barS_8barrables ---> protocol witness table for foo.bar : foo.barrable in Swift
_TWaC3foo3barS_8barrableS_ ---> protocol witness table accessor for foo.bar : foo.barrable in foo
_TWlC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table accessor for type foo.bar and conformance foo.bar : foo.barrable in foo
_TWaC3foo3barS_8barrableS_ ---> {C} protocol witness table accessor for foo.bar : foo.barrable in foo
_TWlC3foo3barS0_S_8barrableS_ ---> {C} lazy protocol witness table accessor for type foo.bar and conformance foo.bar : foo.barrable in foo
_TWLC3foo3barS0_S_8barrableS_ ---> lazy protocol witness table cache variable for type foo.bar and conformance foo.bar : foo.barrable in foo
_TWGC3foo3barS_8barrableS_ ---> generic protocol witness table for foo.bar : foo.barrable in foo
_TWIC3foo3barS_8barrableS_ ---> instantiation function for generic protocol witness table for foo.bar : foo.barrable in foo
_TWtC3foo3barS_8barrableS_4fred ---> associated type metadata accessor for fred in foo.bar : foo.barrable in foo
_TWTC3foo3barS_8barrableS_4fredS_6thomas ---> associated type witness table accessor for fred : foo.thomas in foo.bar : foo.barrable in foo
_TWIC3foo3barS_8barrableS_ ---> {C} instantiation function for generic protocol witness table for foo.bar : foo.barrable in foo
_TWtC3foo3barS_8barrableS_4fred ---> {C} associated type metadata accessor for fred in foo.bar : foo.barrable in foo
_TWTC3foo3barS_8barrableS_4fredS_6thomas ---> {C} associated type witness table accessor for fred : foo.thomas in foo.bar : foo.barrable in foo
_TFSCg5greenVSC5Color ---> __C.green.getter : __C.Color
_TIF1t1fFT1iSi1sSS_T_A_ ---> t.(f (i : Swift.Int, s : Swift.String) -> ()).(default argument 0)
_TIF1t1fFT1iSi1sSS_T_A0_ ---> t.(f (i : Swift.Int, s : Swift.String) -> ()).(default argument 1)
Expand Down
2 changes: 2 additions & 0 deletions tools/swift-demangle/swift-demangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ static void demangle(llvm::raw_ostream &os, llvm::StringRef name,
Classifications += 'N';
if (DCtx.isThunkSymbol(name))
Classifications += 'T';
if (pointer && !DCtx.hasSwiftCallingConvention(name))
Classifications += 'C';
if (!Classifications.empty())
llvm::outs() << '{' << Classifications << "} ";
}
Expand Down

0 comments on commit be986d7

Please sign in to comment.