aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-12-21 07:55:45 +0000
committerDouglas Gregor <dgregor@apple.com>2010-12-21 07:55:45 +0000
commit3910cfd17fcd99ac80158e625fc63e4784d26435 (patch)
treee10b62355d12ac5f6b960c629b5d07b229ceb094
parent6fb0729241ab204e9bed9a5ff2f5bd396db111d4 (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.h5
-rw-r--r--tools/libclang/CIndex.cpp32
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));
}
}