[cfe-commits] r113805 - in /cfe/trunk: include/clang-c/Index.h test/Index/TestClassDecl.m test/Index/TestClassForwardDecl.m test/Index/index-templates.cpp test/Index/load-namespaces.cpp tools/c-index-test/c-index-test.c tools/libclang/CIndex.cpp tools/libclang/CXCursor.cpp tools/libclang/CXCursor.h tools/libclang/libclang.darwin.exports tools/libclang/libclang.exports

Douglas Gregor dgregor at apple.com
Mon Sep 13 15:52:57 PDT 2010


Author: dgregor
Date: Mon Sep 13 17:52:57 2010
New Revision: 113805

URL: http://llvm.org/viewvc/llvm-project?rev=113805&view=rev
Log:
Introduce a new kind of cursor into libclang, which covers a reference
to an "overloaded" set of declarations. This cursor kind works for
unresolved references to functions/templates (e.g., a call within a
template), using declarations, and Objective-C class and protocol
forward declarations.

Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/test/Index/TestClassDecl.m
    cfe/trunk/test/Index/TestClassForwardDecl.m
    cfe/trunk/test/Index/index-templates.cpp
    cfe/trunk/test/Index/load-namespaces.cpp
    cfe/trunk/tools/c-index-test/c-index-test.c
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp
    cfe/trunk/tools/libclang/CXCursor.h
    cfe/trunk/tools/libclang/libclang.darwin.exports
    cfe/trunk/tools/libclang/libclang.exports

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Mon Sep 13 17:52:57 2010
@@ -1056,7 +1056,45 @@
    */
   CXCursor_LabelRef                      = 48,
   
-  CXCursor_LastRef                       = CXCursor_LabelRef,
+  /**
+   * \brief A reference to a set of overloaded functions or function templates
+   * that has not yet been resolved to a specific function or function template.
+   *
+   * An overloaded declaration reference cursor occurs in C++ templates where
+   * a dependent name refers to a function. For example:
+   *
+   * \code
+   * template<typename T> void swap(T&, T&);
+   *
+   * struct X { ... };
+   * void swap(X&, X&);
+   *
+   * template<typename T>
+   * void reverse(T* first, T* last) {
+   *   while (first < last - 1) {
+   *     swap(*first, *--last);
+   *     ++first;
+   *   }
+   * }
+   *
+   * struct Y { };
+   * void swap(Y&, Y&);
+   * \endcode
+   *
+   * Here, the identifier "swap" is associated with an overloaded declaration
+   * reference. In the template definition, "swap" refers to either of the two
+   * "swap" functions declared above, so both results will be available. At
+   * instantiation time, "swap" may also refer to other functions found via
+   * argument-dependent lookup (e.g., the "swap" function at the end of the
+   * example).
+   *
+   * The functions \c clang_getNumOverloadedDecls() and 
+   * \c clang_getOverloadedDecl() can be used to retrieve the definitions
+   * referenced by this cursor.
+   */
+  CXCursor_OverloadedDeclRef             = 49,
+  
+  CXCursor_LastRef                       = CXCursor_OverloadedDeclRef,
 
   /* Error conditions */
   CXCursor_FirstInvalid                  = 70,
@@ -1531,6 +1569,34 @@
 CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);
 
 /**
+ * \brief Determine the number of overloaded declarations referenced by a 
+ * \c CXCursor_OverloadedDeclRef cursor.
+ *
+ * \param cursor The cursor whose overloaded declarations are being queried.
+ *
+ * \returns The number of overloaded declarations referenced by \c cursor. If it
+ * is not a \c CXCursor_OverloadedDeclRef cursor, returns 0.
+ */
+CINDEX_LINKAGE unsigned clang_getNumOverloadedDecls(CXCursor cursor);
+
+/**
+ * \brief Retrieve a cursor for one of the overloaded declarations referenced
+ * by a \c CXCursor_OverloadedDeclRef cursor.
+ *
+ * \param cursor The cursor whose overloaded declarations are being queried.
+ *
+ * \param index The zero-based index into the set of overloaded declarations in
+ * the cursor.
+ *
+ * \returns A cursor representing the declaration referenced by the given 
+ * \c cursor at the specified \c index. If the cursor does not have an 
+ * associated set of overloaded declarations, or if the index is out of bounds,
+ * returns \c clang_getNullCursor();
+ */
+CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, 
+                                                unsigned index);
+  
+/**
  * @}
  */
   

Modified: cfe/trunk/test/Index/TestClassDecl.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/TestClassDecl.m?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/test/Index/TestClassDecl.m (original)
+++ cfe/trunk/test/Index/TestClassDecl.m Mon Sep 13 17:52:57 2010
@@ -16,7 +16,7 @@
 }
 
 // CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
-// CHECK-scan: [8:1 - 8:8] UnexposedDecl=:8:1
+// CHECK-scan: [8:1 - 8:8] UnexposedDecl=[10:12]
 // CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:10:12
 // CHECK-scan: [8:11 - 10:1] Invalid Cursor => NoDeclFound
 // CHECK-scan: [10:1 - 11:5] ObjCInterfaceDecl=Foo:10:12

Modified: cfe/trunk/test/Index/TestClassForwardDecl.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/TestClassForwardDecl.m?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/test/Index/TestClassForwardDecl.m (original)
+++ cfe/trunk/test/Index/TestClassForwardDecl.m Mon Sep 13 17:52:57 2010
@@ -13,7 +13,7 @@
 }
 
 // CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
-// CHECK-scan: [8:1 - 8:8] UnexposedDecl=:8:1
+// CHECK-scan: [8:1 - 8:8] UnexposedDecl=[8:8]
 // CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:8:8
 // CHECK-scan: [8:11 - 10:6] Invalid Cursor => NoDeclFound
 // CHECK-scan: [10:6 - 10:15] FunctionDecl=function:10:6 (Definition)

Modified: cfe/trunk/test/Index/index-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-templates.cpp?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/test/Index/index-templates.cpp (original)
+++ cfe/trunk/test/Index/index-templates.cpp Mon Sep 13 17:52:57 2010
@@ -55,6 +55,23 @@
   Z4().getAs<Unsigned>();
 }
 
+template<typename T> void swap(T&, T&);
+template<typename T, typename U> void swap(Y<T, U>&, Y<T, U>&);
+void swap(Z4&, Z4&);
+
+struct Z5 {
+  int f(int);
+  float f(float);
+};
+
+template<typename T>
+void unresolved_exprs(T &x) {
+  swap(x, x);
+  Z5 z5;
+  z5.f(x);
+  swap<T>(x, x);
+}
+
 // RUN: c-index-test -test-load-source all %s | FileCheck -check-prefix=CHECK-LOAD %s
 // CHECK-LOAD: index-templates.cpp:4:6: FunctionTemplate=f:4:6 Extent=[3:1 - 4:22]
 // CHECK-LOAD: index-templates.cpp:3:19: TemplateTypeParameter=T:3:19 (Definition) Extent=[3:19 - 3:20]
@@ -119,6 +136,10 @@
 // CHECK-LOAD: index-templates.cpp:55:8: MemberRefExpr=getAs:50:26 Extent=[55:3 - 55:23]
 // CHECK-LOAD: index-templates.cpp:55:3: CallExpr= Extent=[55:3 - 55:7]
 // CHECK-LOAD: index-templates.cpp:55:14: TypeRef=Unsigned:42:18 Extent=[55:14 - 55:22]
+// CHECK-LOAD: index-templates.cpp:68:6: FunctionTemplate=unresolved_exprs:68:6 (Definition)
+// CHECK-LOAD: index-templates.cpp:69:3: OverloadedDeclRef=swap[60:6, 59:39, 58:27]
+// CHECK-LOAD: index-templates.cpp:71:6: OverloadedDeclRef=f[63:7, 64:9]
+// CHECK-LOAD: index-templates.cpp:72:3: OverloadedDeclRef=swap[58:27, 59:39]
 
 // RUN: c-index-test -test-load-source-usrs all %s | FileCheck -check-prefix=CHECK-USRS %s
 // CHECK-USRS: index-templates.cpp c:@FT@>3#T#Nt0.0#t>2#T#Nt1.0f#>t0.22t0.0# Extent=[3:1 - 4:22]

Modified: cfe/trunk/test/Index/load-namespaces.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/load-namespaces.cpp?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/test/Index/load-namespaces.cpp (original)
+++ cfe/trunk/test/Index/load-namespaces.cpp Mon Sep 13 17:52:57 2010
@@ -41,7 +41,7 @@
 // CHECK: load-namespaces.cpp:18:11: Namespace=std:18:11 (Definition) Extent=[18:11 - 20:2]
 // CHECK: load-namespaces.cpp:19:7: FunctionDecl=g:19:7 Extent=[19:7 - 19:13]
 // CHECK: load-namespaces.cpp:19:12: ParmDecl=:19:12 (Definition) Extent=[19:9 - 19:13]
-// CHECK: load-namespaces.cpp:22:12: UsingDeclaration=g:22:12 Extent=[22:1 - 22:13]
+// CHECK: load-namespaces.cpp:22:12: UsingDeclaration=g[10:8, 19:7] Extent=[22:1 - 22:13]
 // CHECK: load-namespaces.cpp:22:7: NamespaceRef=std:18:11 Extent=[22:7 - 22:10]
 // CHECK: load-namespaces.cpp:24:11: FunctionDecl=g:24:11 (Definition) Extent=[24:11 - 25:2]
 // CHECK: load-namespaces.cpp:24:6: NamespaceRef=std:18:11 Extent=[24:6 - 24:9]

Modified: cfe/trunk/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/tools/c-index-test/c-index-test.c (original)
+++ cfe/trunk/tools/c-index-test/c-index-test.c Mon Sep 13 17:52:57 2010
@@ -177,9 +177,24 @@
 
     Referenced = clang_getCursorReferenced(Cursor);
     if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
-      CXSourceLocation Loc = clang_getCursorLocation(Referenced);
-      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
-      printf(":%d:%d", line, column);
+      if (clang_getCursorKind(Referenced) == CXCursor_OverloadedDeclRef) {
+        unsigned I, N = clang_getNumOverloadedDecls(Referenced);
+        printf("[");
+        for (I = 0; I != N; ++I) {
+          CXCursor Ovl = clang_getOverloadedDecl(Referenced, I);
+          if (I)
+            printf(", ");
+          
+          CXSourceLocation Loc = clang_getCursorLocation(Ovl);
+          clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+          printf("%d:%d", line, column);          
+        }
+        printf("]");
+      } else {
+        CXSourceLocation Loc = clang_getCursorLocation(Referenced);
+        clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
+        printf(":%d:%d", line, column);
+      }
     }
 
     if (clang_isCursorDefinition(Cursor))

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Mon Sep 13 17:52:57 2010
@@ -1015,10 +1015,9 @@
     if (VisitNestedNameSpecifier(Qualifier, D->getNestedNameRange()))
       return true;
   
-  // FIXME: Provide a multi-reference of some kind for all of the declarations
-  // that the using declaration refers to. We don't have this kind of cursor
-  // yet.
-  
+  if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
+    return true;
+    
   return VisitDeclarationNameInfo(D->getNameInfo());
 }
 
@@ -1141,8 +1140,10 @@
     return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
 
   case TemplateName::OverloadedTemplate:
-    // FIXME: We need a way to return multiple lookup results in a single
-    // cursor.
+    // Visit the overloaded template set.
+    if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
+      return true;
+
     return false;
 
   case TemplateName::DependentTemplate:
@@ -1272,7 +1273,7 @@
 }
 
 bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
-  // FIXME: We can't visit the template template parameter, but there's
+  // FIXME: We can't visit the template type parameter, because there's
   // no context information with which we can match up the depth/index in the
   // type to the appropriate 
   return false;
@@ -1792,7 +1793,11 @@
   // Visit the declaration name.
   if (VisitDeclarationNameInfo(E->getNameInfo()))
     return true;
-  
+
+  // Visit the overloaded declaration reference.
+  if (Visit(MakeCursorOverloadedDeclRef(E, TU)))
+    return true;
+
   // Visit the explicitly-specified template arguments.
   if (const ExplicitTemplateArgumentList *ArgList
                                       = E->getOptionalExplicitTemplateArgs()) {
@@ -1804,8 +1809,6 @@
     }
   }
     
-  // FIXME: We don't have a way to visit all of the declarations referenced
-  // here.
   return false;
 }
 
@@ -2618,6 +2621,22 @@
       return createCXString(Label->getID()->getName());
     }
 
+    case CXCursor_OverloadedDeclRef: {
+      OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
+      if (Decl *D = Storage.dyn_cast<Decl *>()) {
+        if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+          return createCXString(ND->getNameAsString());
+        return createCXString("");
+      }
+      if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+        return createCXString(E->getName().getAsString());
+      OverloadedTemplateStorage *Ovl
+        = Storage.get<OverloadedTemplateStorage*>();
+      if (Ovl->size() == 0)
+        return createCXString("");
+      return createCXString((*Ovl->begin())->getNameAsString());
+    }
+        
     default:
       return createCXString("<not implemented>");
     }
@@ -2712,6 +2731,8 @@
     return createCXString("MemberRef");
   case CXCursor_LabelRef:
     return createCXString("LabelRef");
+  case CXCursor_OverloadedDeclRef:
+    return createCXString("OverloadedDeclRef");
   case CXCursor_UnexposedExpr:
       return createCXString("UnexposedExpr");
   case CXCursor_BlockExpr:
@@ -2931,6 +2952,10 @@
       return cxloc::translateSourceLocation(getCursorContext(C), P.second);
     }
 
+    case CXCursor_OverloadedDeclRef:
+      return cxloc::translateSourceLocation(getCursorContext(C),
+                                          getCursorOverloadedDeclRef(C).second);
+
     default:
       // FIXME: Need a way to enumerate all non-reference cases.
       llvm_unreachable("Missed a reference kind");
@@ -3004,6 +3029,9 @@
     case CXCursor_LabelRef:
       return getCursorLabelRef(C).second;
 
+    case CXCursor_OverloadedDeclRef:
+      return getCursorOverloadedDeclRef(C).second;
+
     default:
       // FIXME: Need a way to enumerate all non-reference cases.
       llvm_unreachable("Missed a reference kind");
@@ -3046,13 +3074,28 @@
     return clang_getNullCursor();
 
   ASTUnit *CXXUnit = getCursorASTUnit(C);
-  if (clang_isDeclaration(C.kind))
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = getCursorDecl(C);
+    if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+      return MakeCursorOverloadedDeclRef(Using, D->getLocation(), CXXUnit);
+    if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
+      return MakeCursorOverloadedDeclRef(Classes, D->getLocation(), CXXUnit);
+    if (ObjCForwardProtocolDecl *Protocols
+                                        = dyn_cast<ObjCForwardProtocolDecl>(D))
+      return MakeCursorOverloadedDeclRef(Protocols, D->getLocation(), CXXUnit);
+      
     return C;
-
+  }
+  
   if (clang_isExpression(C.kind)) {
-    Decl *D = getDeclFromExpr(getCursorExpr(C));
+    Expr *E = getCursorExpr(C);
+    Decl *D = getDeclFromExpr(E);
     if (D)
       return MakeCXCursor(D, CXXUnit);
+    
+    if (OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
+      return MakeCursorOverloadedDeclRef(Ovl, CXXUnit);
+        
     return clang_getNullCursor();
   }
 
@@ -3108,6 +3151,9 @@
                           CXXUnit->getASTContext().getTranslationUnitDecl(),
                           CXXUnit);
 
+    case CXCursor_OverloadedDeclRef:
+      return C;
+
     default:
       // We would prefer to enumerate all non-reference cursor kinds here.
       llvm_unreachable("Unhandled reference cursor kind");
@@ -3223,23 +3269,9 @@
     return clang_getNullCursor();
   }
 
-  case Decl::Using: {
-    UsingDecl *Using = cast<UsingDecl>(D);
-    CXCursor Def = clang_getNullCursor();
-    for (UsingDecl::shadow_iterator S = Using->shadow_begin(),
-                                 SEnd = Using->shadow_end();
-         S != SEnd; ++S) {
-      if (Def != clang_getNullCursor()) {
-        // FIXME: We have no way to return multiple results.
-        return clang_getNullCursor();
-      }
-
-      Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl(),
-                                                   CXXUnit));
-    }
-
-    return Def;
-  }
+  case Decl::Using:
+    return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), 
+                                       D->getLocation(), CXXUnit);
 
   case Decl::UsingShadow:
     return clang_getCursorDefinition(
@@ -3303,29 +3335,13 @@
 
     return clang_getNullCursor();
 
-  case Decl::ObjCForwardProtocol: {
-    ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D);
-    if (Forward->protocol_size() == 1)
-      return clang_getCursorDefinition(
-                                     MakeCXCursor(*Forward->protocol_begin(),
-                                                  CXXUnit));
-
-    // FIXME: Cannot return multiple definitions.
-    return clang_getNullCursor();
-  }
-
-  case Decl::ObjCClass: {
-    ObjCClassDecl *Class = cast<ObjCClassDecl>(D);
-    if (Class->size() == 1) {
-      ObjCInterfaceDecl *IFace = Class->begin()->getInterface();
-      if (!IFace->isForwardDecl())
-        return MakeCXCursor(IFace, CXXUnit);
-      return clang_getNullCursor();
-    }
-
-    // FIXME: Cannot return multiple definitions.
-    return clang_getNullCursor();
-  }
+  case Decl::ObjCForwardProtocol:
+    return MakeCursorOverloadedDeclRef(cast<ObjCForwardProtocolDecl>(D), 
+                                       D->getLocation(), CXXUnit);
+
+  case Decl::ObjCClass:
+    return MakeCursorOverloadedDeclRef(cast<ObjCClassDecl>(D), D->getLocation(), 
+                                       CXXUnit);
 
   case Decl::Friend:
     if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
@@ -3348,6 +3364,62 @@
   return clang_getCursorDefinition(C) == C;
 }
 
+unsigned clang_getNumOverloadedDecls(CXCursor C) {
+  if (!C.kind == CXCursor_OverloadedDeclRef)
+    return 0;
+  
+  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
+  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+    return E->getNumDecls();
+  
+  if (OverloadedTemplateStorage *S
+                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
+    return S->size();
+  
+  Decl *D = Storage.get<Decl*>();
+  if (UsingDecl *Using = dyn_cast<UsingDecl>(D))
+    return Using->getNumShadowDecls();
+  if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
+    return Classes->size();
+  if (ObjCForwardProtocolDecl *Protocols =dyn_cast<ObjCForwardProtocolDecl>(D))
+    return Protocols->protocol_size();
+  
+  return 0;
+}
+
+CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
+  if (!cursor.kind == CXCursor_OverloadedDeclRef)
+    return clang_getNullCursor();
+
+  if (index >= clang_getNumOverloadedDecls(cursor))
+    return clang_getNullCursor();
+  
+  ASTUnit *Unit = getCursorASTUnit(cursor);
+  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
+  if (OverloadExpr *E = Storage.dyn_cast<OverloadExpr *>())
+    return MakeCXCursor(E->decls_begin()[index], Unit);
+  
+  if (OverloadedTemplateStorage *S
+                              = Storage.dyn_cast<OverloadedTemplateStorage*>())
+    return MakeCXCursor(S->begin()[index], Unit);
+  
+  Decl *D = Storage.get<Decl*>();
+  if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
+    // FIXME: This is, unfortunately, linear time.
+    UsingDecl::shadow_iterator Pos = Using->shadow_begin();
+    std::advance(Pos, index);
+    return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), Unit);
+  }
+  
+  if (ObjCClassDecl *Classes = dyn_cast<ObjCClassDecl>(D))
+    return MakeCXCursor(Classes->begin()[index].getInterface(), Unit);
+  
+  if (ObjCForwardProtocolDecl *Protocols = dyn_cast<ObjCForwardProtocolDecl>(D))
+    return MakeCXCursor(Protocols->protocol_begin()[index], Unit);
+  
+  return clang_getNullCursor();
+}
+  
 void clang_getDefinitionSpellingAndExtent(CXCursor C,
                                           const char **startBuf,
                                           const char **endBuf,

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Mon Sep 13 17:52:57 2010
@@ -19,9 +19,11 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "llvm/Support/ErrorHandling.h"
 
 using namespace clang;
+using namespace cxcursor;
 
 CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) {
   assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
@@ -379,6 +381,52 @@
                                        reinterpret_cast<uintptr_t>(C.data[1])));  
 }
 
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E, 
+                                               ASTUnit *TU) {
+  assert(E && TU && "Invalid arguments!");
+  OverloadedDeclRefStorage Storage(E);
+  void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
+  CXCursor C = { 
+                 CXCursor_OverloadedDeclRef, 
+                 { Storage.getOpaqueValue(), RawLoc, TU } 
+               };
+  return C;    
+}
+
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D, 
+                                               SourceLocation Loc,
+                                               ASTUnit *TU) {
+  assert(D && TU && "Invalid arguments!");
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  OverloadedDeclRefStorage Storage(D);
+  CXCursor C = { 
+    CXCursor_OverloadedDeclRef, 
+    { Storage.getOpaqueValue(), RawLoc, TU }
+  };
+  return C;    
+}
+
+CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name, 
+                                               SourceLocation Loc,
+                                               ASTUnit *TU) {
+  assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
+  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
+  OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
+  CXCursor C = { 
+    CXCursor_OverloadedDeclRef, 
+    { Storage.getOpaqueValue(), RawLoc, TU } 
+  };
+  return C;    
+}
+
+std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
+cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
+  assert(C.kind == CXCursor_OverloadedDeclRef);
+  return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(C.data[0]),
+                        SourceLocation::getFromRawEncoding(
+                                       reinterpret_cast<uintptr_t>(C.data[1])));
+}
+
 Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
   return (Decl *)Cursor.data[0];
 }

Modified: cfe/trunk/tools/libclang/CXCursor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.h?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.h (original)
+++ cfe/trunk/tools/libclang/CXCursor.h Mon Sep 13 17:52:57 2010
@@ -16,6 +16,7 @@
 
 #include "clang-c/Index.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerUnion.h"
 #include <utility>
 
 namespace clang {
@@ -33,10 +34,13 @@
 class NamedDecl;
 class ObjCInterfaceDecl;
 class ObjCProtocolDecl;
+class OverloadedTemplateStorage;
+class OverloadExpr;
 class Stmt;
 class TemplateDecl;
+class TemplateName;
 class TypeDecl;
-
+  
 namespace cxcursor {
   
 CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU);
@@ -135,6 +139,27 @@
 /// \brief Unpack a label reference into the label statement it refers to and
 /// the location of the reference.
 std::pair<LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
+
+/// \brief Create a overloaded declaration reference cursor for an expression.
+CXCursor MakeCursorOverloadedDeclRef(OverloadExpr *E, ASTUnit *TU);
+
+/// \brief Create a overloaded declaration reference cursor for a declaration.
+CXCursor MakeCursorOverloadedDeclRef(Decl *D, SourceLocation Location,
+                                     ASTUnit *TU);
+
+/// \brief Create a overloaded declaration reference cursor for a template name.
+CXCursor MakeCursorOverloadedDeclRef(TemplateName Template, 
+                                     SourceLocation Location, ASTUnit *TU);
+
+/// \brief Internal storage for an overloaded declaration reference cursor;
+typedef llvm::PointerUnion3<OverloadExpr *, Decl *, 
+                            OverloadedTemplateStorage *>
+  OverloadedDeclRefStorage;
+  
+/// \brief Unpack an overloaded declaration reference into an expression,
+/// declaration, or template name along with the source location.
+std::pair<OverloadedDeclRefStorage, SourceLocation>
+  getCursorOverloadedDeclRef(CXCursor C);
   
 Decl *getCursorDecl(CXCursor Cursor);
 Expr *getCursorExpr(CXCursor Cursor);

Modified: cfe/trunk/tools/libclang/libclang.darwin.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.darwin.exports?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.darwin.exports (original)
+++ cfe/trunk/tools/libclang/libclang.darwin.exports Mon Sep 13 17:52:57 2010
@@ -73,6 +73,8 @@
 _clang_getNullRange
 _clang_getNumCompletionChunks
 _clang_getNumDiagnostics
+_clang_getNumOverloadedDecls
+_clang_getOverloadedDecl
 _clang_getPointeeType
 _clang_getRange
 _clang_getRangeEnd

Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=113805&r1=113804&r2=113805&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Mon Sep 13 17:52:57 2010
@@ -73,6 +73,8 @@
 clang_getNullRange
 clang_getNumCompletionChunks
 clang_getNumDiagnostics
+clang_getNumOverloadedDecls
+clang_getOverloadedDecl
 clang_getPointeeType
 clang_getRange
 clang_getRangeEnd





More information about the cfe-commits mailing list