mirror of https://github.com/microsoft/clang.git
[index] Generate class & metaclass manglings for objc
Summary: ObjC classes have two associated symbols, one for the class and one for the metaclass. This change overloads `CodegenNameGenerator::getAllManglings` to produce both class and metaclass symbols. While this function is called by `clang_Cursor_getCXXManglings`, it's only called for CXXRecordDecl and CXXMethodDecl, and so libclang's behavior is unchanged. Reviewers: arphaman, abdulras, alexshap, compnerd Reviewed By: compnerd Subscribers: compnerd Differential Revision: https://reviews.llvm.org/D37671 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313997 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
78409ae639
commit
d454549fce
|
@ -4292,6 +4292,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor);
|
||||||
*/
|
*/
|
||||||
CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor);
|
CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Retrieve the CXStrings representing the mangled symbols of the ObjC
|
||||||
|
* class interface or implementation at the cursor.
|
||||||
|
*/
|
||||||
|
CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -68,7 +68,38 @@ struct CodegenNameGenerator::Implementation {
|
||||||
return Name;
|
return Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ObjCKind {
|
||||||
|
ObjCClass,
|
||||||
|
ObjCMetaclass,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) {
|
||||||
|
StringRef ClassName;
|
||||||
|
if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD))
|
||||||
|
ClassName = OID->getObjCRuntimeNameAsString();
|
||||||
|
else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD))
|
||||||
|
ClassName = OID->getObjCRuntimeNameAsString();
|
||||||
|
|
||||||
|
if (ClassName.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string {
|
||||||
|
SmallString<40> Mangled;
|
||||||
|
auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext());
|
||||||
|
llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL);
|
||||||
|
return Mangled.str();
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
Mangle(ObjCClass, ClassName),
|
||||||
|
Mangle(ObjCMetaclass, ClassName),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> getAllManglings(const Decl *D) {
|
std::vector<std::string> getAllManglings(const Decl *D) {
|
||||||
|
if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
|
||||||
|
return getAllManglings(OCD);
|
||||||
|
|
||||||
if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
|
if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -135,12 +166,14 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
|
void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
|
||||||
OS << getClassSymbolPrefix();
|
OS << getClassSymbolPrefix(ObjCClass, D->getASTContext());
|
||||||
OS << D->getObjCRuntimeNameAsString();
|
OS << D->getObjCRuntimeNameAsString();
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringRef getClassSymbolPrefix() {
|
static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context) {
|
||||||
return "OBJC_CLASS_$_";
|
if (Context.getLangOpts().ObjCRuntime.isGNUFamily())
|
||||||
|
return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_";
|
||||||
|
return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
|
std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// RUN: c-index-test -write-pch %t.macho.ast -target i686-apple-darwin %s
|
||||||
|
// RUN: c-index-test -test-print-manglings %t.macho.ast | FileCheck --check-prefix=MACHO %s
|
||||||
|
|
||||||
|
// RUN: c-index-test -write-pch %t.itanium.ast -target i686-pc-linux-gnu %s
|
||||||
|
// RUN: c-index-test -test-print-manglings %t.itanium.ast | FileCheck --check-prefix=ITANIUM %s
|
||||||
|
|
||||||
|
@interface C
|
||||||
|
@end
|
||||||
|
|
||||||
|
// MACHO: ObjCInterfaceDecl=C{{.*}} [mangled=_OBJC_CLASS_$_C] [mangled=_OBJC_METACLASS_$_C]
|
||||||
|
// ITANIUM: ObjCInterfaceDecl=C{{.*}} [mangled=_OBJC_CLASS_C] [mangled=_OBJC_METACLASS_C]
|
||||||
|
|
||||||
|
@implementation C
|
||||||
|
@end
|
||||||
|
|
||||||
|
// MACHO: ObjCImplementationDecl=C{{.*}} (Definition) [mangled=_OBJC_CLASS_$_C] [mangled=_OBJC_METACLASS_$_C]
|
||||||
|
// ITANIUM: ObjCImplementationDecl=C{{.*}} (Definition) [mangled=_OBJC_CLASS_C] [mangled=_OBJC_METACLASS_C]
|
||||||
|
|
|
@ -1563,10 +1563,19 @@ static enum CXChildVisitResult PrintManglings(CXCursor cursor, CXCursor p,
|
||||||
return CXChildVisit_Continue;
|
return CXChildVisit_Continue;
|
||||||
PrintCursor(cursor, NULL);
|
PrintCursor(cursor, NULL);
|
||||||
Manglings = clang_Cursor_getCXXManglings(cursor);
|
Manglings = clang_Cursor_getCXXManglings(cursor);
|
||||||
|
if (Manglings) {
|
||||||
for (I = 0, E = Manglings->Count; I < E; ++I)
|
for (I = 0, E = Manglings->Count; I < E; ++I)
|
||||||
printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
|
printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
|
||||||
clang_disposeStringSet(Manglings);
|
clang_disposeStringSet(Manglings);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
}
|
||||||
|
Manglings = clang_Cursor_getObjCManglings(cursor);
|
||||||
|
if (Manglings) {
|
||||||
|
for (I = 0, E = Manglings->Count; I < E; ++I)
|
||||||
|
printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
|
||||||
|
clang_disposeStringSet(Manglings);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
return CXChildVisit_Recurse;
|
return CXChildVisit_Recurse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4639,6 +4639,20 @@ CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
|
||||||
return cxstring::createSet(Manglings);
|
return cxstring::createSet(Manglings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
|
||||||
|
if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const Decl *D = getCursorDecl(C);
|
||||||
|
if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
ASTContext &Ctx = D->getASTContext();
|
||||||
|
index::CodegenNameGenerator CGNameGen(Ctx);
|
||||||
|
std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
|
||||||
|
return cxstring::createSet(Manglings);
|
||||||
|
}
|
||||||
|
|
||||||
CXString clang_getCursorDisplayName(CXCursor C) {
|
CXString clang_getCursorDisplayName(CXCursor C) {
|
||||||
if (!clang_isDeclaration(C.kind))
|
if (!clang_isDeclaration(C.kind))
|
||||||
return clang_getCursorSpelling(C);
|
return clang_getCursorSpelling(C);
|
||||||
|
|
|
@ -23,6 +23,7 @@ clang_Cursor_getBriefCommentText
|
||||||
clang_Cursor_getCommentRange
|
clang_Cursor_getCommentRange
|
||||||
clang_Cursor_getCXXManglings
|
clang_Cursor_getCXXManglings
|
||||||
clang_Cursor_getMangling
|
clang_Cursor_getMangling
|
||||||
|
clang_Cursor_getObjCManglings
|
||||||
clang_Cursor_getParsedComment
|
clang_Cursor_getParsedComment
|
||||||
clang_Cursor_getRawCommentText
|
clang_Cursor_getRawCommentText
|
||||||
clang_Cursor_getNumArguments
|
clang_Cursor_getNumArguments
|
||||||
|
|
Loading…
Reference in New Issue