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);
|
||||
|
||||
/**
|
||||
* \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;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D))
|
||||
return getAllManglings(OCD);
|
||||
|
||||
if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
|
||||
return {};
|
||||
|
||||
|
@ -135,12 +166,14 @@ private:
|
|||
}
|
||||
|
||||
void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) {
|
||||
OS << getClassSymbolPrefix();
|
||||
OS << getClassSymbolPrefix(ObjCClass, D->getASTContext());
|
||||
OS << D->getObjCRuntimeNameAsString();
|
||||
}
|
||||
|
||||
static StringRef getClassSymbolPrefix() {
|
||||
return "OBJC_CLASS_$_";
|
||||
static StringRef getClassSymbolPrefix(ObjCKind Kind, const ASTContext &Context) {
|
||||
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) {
|
||||
|
|
|
@ -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;
|
||||
PrintCursor(cursor, NULL);
|
||||
Manglings = clang_Cursor_getCXXManglings(cursor);
|
||||
for (I = 0, E = Manglings->Count; I < E; ++I)
|
||||
printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
|
||||
clang_disposeStringSet(Manglings);
|
||||
printf("\n");
|
||||
if (Manglings) {
|
||||
for (I = 0, E = Manglings->Count; I < E; ++I)
|
||||
printf(" [mangled=%s]", clang_getCString(Manglings->Strings[I]));
|
||||
clang_disposeStringSet(Manglings);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -4639,6 +4639,20 @@ CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
|
|||
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) {
|
||||
if (!clang_isDeclaration(C.kind))
|
||||
return clang_getCursorSpelling(C);
|
||||
|
|
|
@ -23,6 +23,7 @@ clang_Cursor_getBriefCommentText
|
|||
clang_Cursor_getCommentRange
|
||||
clang_Cursor_getCXXManglings
|
||||
clang_Cursor_getMangling
|
||||
clang_Cursor_getObjCManglings
|
||||
clang_Cursor_getParsedComment
|
||||
clang_Cursor_getRawCommentText
|
||||
clang_Cursor_getNumArguments
|
||||
|
|
Loading…
Reference in New Issue