From fec4dc9418842bced4a0eea6b48b0601840210f6 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 19 Nov 2010 23:44:15 +0000 Subject: [PATCH] Implement clang_getCanonicalCursor() in libclang, which does the obvious thing. llvm-svn: 119874 --- clang/include/clang-c/Index.h | 26 ++++++++++++++++++++ clang/tools/libclang/CIndex.cpp | 10 ++++++++ clang/tools/libclang/libclang.darwin.exports | 1 + clang/tools/libclang/libclang.exports | 1 + 4 files changed, 38 insertions(+) diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 2fc408973542..ebe74e2d2fc5 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2074,6 +2074,32 @@ CINDEX_LINKAGE CXCursor clang_getCursorDefinition(CXCursor); */ CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor); +/** + * \brief Retrieve the canonical cursor corresponding to the given cursor. + * + * In the C family of languages, many kinds of entities can be declared several + * times within a single translation unit. For example, a structure type can + * be forward-declared (possibly multiple times) and later defined: + * + * \code + * struct X; + * struct X; + * struct X { + * int member; + * }; + * \endcode + * + * The declarations and the definition of \c X are represented by three + * different cursors, all of which are declarations of the same underlying + * entity. One of these cursor is considered the "canonical" cursor, which + * is effectively the representative for the underlying entity. One can + * determine if two cursors are declarations of the same underlying entity by + * comparing their canonical cursors. + * + * \returns The canonical cursor for the entity referred to by the given cursor. + */ +CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor); + /** * @} */ diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 9137172daf88..9116667ec74a 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3717,6 +3717,16 @@ unsigned clang_isCursorDefinition(CXCursor C) { return clang_getCursorDefinition(C) == C; } +CXCursor clang_getCanonicalCursor(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return C; + + if (Decl *D = getCursorDecl(C)) + return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C)); + + return C; +} + unsigned clang_getNumOverloadedDecls(CXCursor C) { if (C.kind != CXCursor_OverloadedDeclRef) return 0; diff --git a/clang/tools/libclang/libclang.darwin.exports b/clang/tools/libclang/libclang.darwin.exports index 5e8abf25333b..e132f7f9aab1 100644 --- a/clang/tools/libclang/libclang.darwin.exports +++ b/clang/tools/libclang/libclang.darwin.exports @@ -32,6 +32,7 @@ _clang_equalTypes _clang_formatDiagnostic _clang_getCString _clang_getCXXAccessSpecifier +_clang_getCanonicalCursor _clang_getCanonicalType _clang_getClangVersion _clang_getCompletionAvailability diff --git a/clang/tools/libclang/libclang.exports b/clang/tools/libclang/libclang.exports index ca9a9d1016dd..fce89ca87bc0 100644 --- a/clang/tools/libclang/libclang.exports +++ b/clang/tools/libclang/libclang.exports @@ -32,6 +32,7 @@ clang_equalTypes clang_formatDiagnostic clang_getCString clang_getCXXAccessSpecifier +clang_getCanonicalCursor clang_getCanonicalType clang_getClangVersion clang_getCompletionAvailability