[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