diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-12-21 07:55:45 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-12-21 07:55:45 +0000 |
commit | 3910cfd17fcd99ac80158e625fc63e4784d26435 (patch) | |
tree | e10b62355d12ac5f6b960c629b5d07b229ceb094 | |
parent | 6fb0729241ab204e9bed9a5ff2f5bd396db111d4 (diff) |
Teach clang_getCursorSemanticParent() and
clang_getCursorLexicalParent() to cope with class and function
templates, along with the parent of the translation unit. Fixes PR8761
and PR8766.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122324 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang-c/Index.h | 5 | ||||
-rw-r--r-- | tools/libclang/CIndex.cpp | 32 |
2 files changed, 34 insertions, 3 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 0be4d4a02c..9bf492d5f8 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1522,6 +1522,8 @@ CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset, * In the example above, both declarations of \c C::f have \c C as their * semantic context, while the lexical context of the first \c C::f is \c C * and the lexical context of the second \c C::f is the translation unit. + * + * For global declarations, the semantic parent is the translation unit. */ CINDEX_LINKAGE CXCursor clang_getCursorSemanticParent(CXCursor cursor); @@ -1555,6 +1557,9 @@ CINDEX_LINKAGE CXCursor clang_getCursorSemanticParent(CXCursor cursor); * In the example above, both declarations of \c C::f have \c C as their * semantic context, while the lexical context of the first \c C::f is \c C * and the lexical context of the second \c C::f is the translation unit. + * + * For declarations written in the global scope, the lexical parent is + * the translation unit. */ CINDEX_LINKAGE CXCursor clang_getCursorLexicalParent(CXCursor cursor); diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index b6b5922feb..38b58e0068 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -4505,12 +4505,34 @@ CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { return CXLanguage_Invalid; } - + + /// \brief If the given cursor is the "templated" declaration + /// descibing a class or function template, return the class or + /// function template. +static Decl *maybeGetTemplateCursor(Decl *D) { + if (!D) + return 0; + + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate()) + return FunTmpl; + + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) + if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate()) + return ClassTmpl; + + return D; +} + CXCursor clang_getCursorSemanticParent(CXCursor cursor) { if (clang_isDeclaration(cursor.kind)) { if (Decl *D = getCursorDecl(cursor)) { DeclContext *DC = D->getDeclContext(); - return MakeCXCursor(cast<Decl>(DC), getCursorTU(cursor)); + if (!DC) + return clang_getNullCursor(); + + return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), + getCursorTU(cursor)); } } @@ -4526,7 +4548,11 @@ CXCursor clang_getCursorLexicalParent(CXCursor cursor) { if (clang_isDeclaration(cursor.kind)) { if (Decl *D = getCursorDecl(cursor)) { DeclContext *DC = D->getLexicalDeclContext(); - return MakeCXCursor(cast<Decl>(DC), getCursorTU(cursor)); + if (!DC) + return clang_getNullCursor(); + + return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)), + getCursorTU(cursor)); } } |