[cfe-commits] r122324 - in /cfe/trunk: include/clang-c/Index.h tools/libclang/CIndex.cpp

Douglas Gregor dgregor at apple.com
Mon Dec 20 23:55:45 PST 2010


Author: dgregor
Date: Tue Dec 21 01:55:45 2010
New Revision: 122324

URL: http://llvm.org/viewvc/llvm-project?rev=122324&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=122324&r1=122323&r2=122324&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Tue Dec 21 01:55:45 2010
@@ -1522,6 +1522,8 @@
  * 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 @@
  * 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);
 

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=122324&r1=122323&r2=122324&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Dec 21 01:55:45 2010
@@ -4505,12 +4505,34 @@
 
   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 @@
   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));
     }
   }
 





More information about the cfe-commits mailing list