зеркало из https://github.com/microsoft/clang.git
[libclang] Move the bulk of clang_getOverriddenCursors into
a cxcursor::getOverriddenCursors C++ function, because SmallVectors are groovier that malloc'ing buffers. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141276 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
d211cb7095
Коммит
b11be041e4
|
@ -5449,62 +5449,6 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
|
|||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
static void CollectOverriddenMethods(DeclContext *Ctx,
|
||||
ObjCMethodDecl *Method,
|
||||
SmallVectorImpl<ObjCMethodDecl *> &Methods) {
|
||||
if (!Ctx)
|
||||
return;
|
||||
|
||||
// If we have a class or category implementation, jump straight to the
|
||||
// interface.
|
||||
if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
|
||||
return CollectOverriddenMethods(Impl->getClassInterface(), Method, Methods);
|
||||
|
||||
ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
|
||||
if (!Container)
|
||||
return;
|
||||
|
||||
// Check whether we have a matching method at this level.
|
||||
if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
|
||||
Method->isInstanceMethod()))
|
||||
if (Method != Overridden) {
|
||||
// We found an override at this level; there is no need to look
|
||||
// into other protocols or categories.
|
||||
Methods.push_back(Overridden);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
|
||||
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
|
||||
PEnd = Protocol->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
CollectOverriddenMethods(*P, Method, Methods);
|
||||
}
|
||||
|
||||
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
|
||||
for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
|
||||
PEnd = Category->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
CollectOverriddenMethods(*P, Method, Methods);
|
||||
}
|
||||
|
||||
if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
|
||||
for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
|
||||
PEnd = Interface->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
CollectOverriddenMethods(*P, Method, Methods);
|
||||
|
||||
for (ObjCCategoryDecl *Category = Interface->getCategoryList();
|
||||
Category; Category = Category->getNextClassCategory())
|
||||
CollectOverriddenMethods(Category, Method, Methods);
|
||||
|
||||
// We only look into the superclass if we haven't found anything yet.
|
||||
if (Methods.empty())
|
||||
if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
|
||||
return CollectOverriddenMethods(Super, Method, Methods);
|
||||
}
|
||||
}
|
||||
|
||||
void clang_getOverriddenCursors(CXCursor cursor,
|
||||
CXCursor **overridden,
|
||||
unsigned *num_overridden) {
|
||||
|
@ -5515,45 +5459,12 @@ void clang_getOverriddenCursors(CXCursor cursor,
|
|||
if (!overridden || !num_overridden)
|
||||
return;
|
||||
|
||||
if (!clang_isDeclaration(cursor.kind))
|
||||
return;
|
||||
SmallVector<CXCursor, 8> Overridden;
|
||||
cxcursor::getOverriddenCursors(cursor, Overridden);
|
||||
|
||||
Decl *D = getCursorDecl(cursor);
|
||||
if (!D)
|
||||
return;
|
||||
|
||||
// Handle C++ member functions.
|
||||
CXTranslationUnit TU = getCursorTU(cursor);
|
||||
if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
|
||||
*num_overridden = CXXMethod->size_overridden_methods();
|
||||
if (!*num_overridden)
|
||||
return;
|
||||
|
||||
*overridden = new CXCursor [*num_overridden];
|
||||
unsigned I = 0;
|
||||
for (CXXMethodDecl::method_iterator
|
||||
M = CXXMethod->begin_overridden_methods(),
|
||||
MEnd = CXXMethod->end_overridden_methods();
|
||||
M != MEnd; (void)++M, ++I)
|
||||
(*overridden)[I] = MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU);
|
||||
return;
|
||||
}
|
||||
|
||||
ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
|
||||
if (!Method)
|
||||
return;
|
||||
|
||||
// Handle Objective-C methods.
|
||||
SmallVector<ObjCMethodDecl *, 4> Methods;
|
||||
CollectOverriddenMethods(Method->getDeclContext(), Method, Methods);
|
||||
|
||||
if (Methods.empty())
|
||||
return;
|
||||
|
||||
*num_overridden = Methods.size();
|
||||
*overridden = new CXCursor [Methods.size()];
|
||||
for (unsigned I = 0, N = Methods.size(); I != N; ++I)
|
||||
(*overridden)[I] = MakeCXCursor(Methods[I], TU);
|
||||
*num_overridden = Overridden.size();
|
||||
*overridden = new CXCursor [Overridden.size()];
|
||||
std::copy(Overridden.begin(), Overridden.end(), *overridden);
|
||||
}
|
||||
|
||||
void clang_disposeOverriddenCursors(CXCursor *overridden) {
|
||||
|
|
|
@ -702,6 +702,92 @@ CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
|
|||
return static_cast<CXTranslationUnit>(Cursor.data[2]);
|
||||
}
|
||||
|
||||
static void CollectOverriddenMethods(CXTranslationUnit TU,
|
||||
DeclContext *Ctx,
|
||||
ObjCMethodDecl *Method,
|
||||
SmallVectorImpl<CXCursor> &Methods) {
|
||||
if (!Ctx)
|
||||
return;
|
||||
|
||||
// If we have a class or category implementation, jump straight to the
|
||||
// interface.
|
||||
if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
|
||||
return CollectOverriddenMethods(TU, Impl->getClassInterface(),
|
||||
Method, Methods);
|
||||
|
||||
ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
|
||||
if (!Container)
|
||||
return;
|
||||
|
||||
// Check whether we have a matching method at this level.
|
||||
if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
|
||||
Method->isInstanceMethod()))
|
||||
if (Method != Overridden) {
|
||||
// We found an override at this level; there is no need to look
|
||||
// into other protocols or categories.
|
||||
Methods.push_back(MakeCXCursor(Overridden, TU));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
|
||||
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
|
||||
PEnd = Protocol->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
CollectOverriddenMethods(TU, *P, Method, Methods);
|
||||
}
|
||||
|
||||
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
|
||||
for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
|
||||
PEnd = Category->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
CollectOverriddenMethods(TU, *P, Method, Methods);
|
||||
}
|
||||
|
||||
if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
|
||||
for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
|
||||
PEnd = Interface->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
CollectOverriddenMethods(TU, *P, Method, Methods);
|
||||
|
||||
for (ObjCCategoryDecl *Category = Interface->getCategoryList();
|
||||
Category; Category = Category->getNextClassCategory())
|
||||
CollectOverriddenMethods(TU, Category, Method, Methods);
|
||||
|
||||
// We only look into the superclass if we haven't found anything yet.
|
||||
if (Methods.empty())
|
||||
if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
|
||||
return CollectOverriddenMethods(TU, Super, Method, Methods);
|
||||
}
|
||||
}
|
||||
|
||||
void cxcursor::getOverriddenCursors(CXCursor cursor,
|
||||
SmallVectorImpl<CXCursor> &overridden) {
|
||||
if (!clang_isDeclaration(cursor.kind))
|
||||
return;
|
||||
|
||||
Decl *D = getCursorDecl(cursor);
|
||||
if (!D)
|
||||
return;
|
||||
|
||||
// Handle C++ member functions.
|
||||
CXTranslationUnit TU = getCursorTU(cursor);
|
||||
if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
|
||||
for (CXXMethodDecl::method_iterator
|
||||
M = CXXMethod->begin_overridden_methods(),
|
||||
MEnd = CXXMethod->end_overridden_methods();
|
||||
M != MEnd; ++M)
|
||||
overridden.push_back(MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU));
|
||||
return;
|
||||
}
|
||||
|
||||
ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
|
||||
if (!Method)
|
||||
return;
|
||||
|
||||
// Handle Objective-C methods.
|
||||
CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
|
||||
}
|
||||
|
||||
bool cxcursor::operator==(CXCursor X, CXCursor Y) {
|
||||
return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
|
||||
X.data[2] == Y.data[2];
|
||||
|
|
|
@ -191,7 +191,10 @@ Decl *getCursorParentDecl(CXCursor Cursor);
|
|||
ASTContext &getCursorContext(CXCursor Cursor);
|
||||
ASTUnit *getCursorASTUnit(CXCursor Cursor);
|
||||
CXTranslationUnit getCursorTU(CXCursor Cursor);
|
||||
|
||||
|
||||
void getOverriddenCursors(CXCursor cursor,
|
||||
SmallVectorImpl<CXCursor> &overridden);
|
||||
|
||||
bool operator==(CXCursor X, CXCursor Y);
|
||||
|
||||
inline bool operator!=(CXCursor X, CXCursor Y) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче