diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-02 00:07:54 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-02 00:07:54 +0000 |
commit | e0329acf5c9437e2086a2fb2bf7a95ae2ac96505 (patch) | |
tree | 20eca64e62fe41b8664256fa556925769fc86c51 /tools | |
parent | fcf431609769a9600c24618d1a33135caec4fef2 (diff) |
Introduce a new libclang function,
clang_getSpecializedCursorTemplate(), which determines the template
(or member thereof) that the given cursor specializes or from which it
was instantiated. This routine can be used to establish a link between
templates and their instantiations/specializations.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112780 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/c-index-test/c-index-test.c | 13 | ||||
-rw-r--r-- | tools/libclang/CIndexCXX.cpp | 47 | ||||
-rw-r--r-- | tools/libclang/libclang.darwin.exports | 1 | ||||
-rw-r--r-- | tools/libclang/libclang.exports | 1 |
4 files changed, 59 insertions, 3 deletions
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index cdf0cd06b5..58eff97ef8 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -166,7 +166,8 @@ static void PrintCursor(CXCursor Cursor) { CXString string, ks; CXCursor Referenced; unsigned line, column; - + CXCursor SpecializationOf; + ks = clang_getCursorKindSpelling(Cursor.kind); string = clang_getCursorSpelling(Cursor); printf("%s=%s", clang_getCString(ks), @@ -224,6 +225,16 @@ static void PrintCursor(CXCursor Cursor) { printf(" [access=%s isVirtual=%s]", accessStr, isVirtual ? "true" : "false"); } + + SpecializationOf = clang_getSpecializedCursorTemplate(Cursor); + if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) { + CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf); + CXString Name = clang_getCursorSpelling(SpecializationOf); + clang_getInstantiationLocation(Loc, 0, &line, &column, 0); + printf(" [Specialization of %s:%d:%d]", + clang_getCString(Name), line, column); + clang_disposeString(Name); + } } } diff --git a/tools/libclang/CIndexCXX.cpp b/tools/libclang/CIndexCXX.cpp index ee83f98722..3ade5195d8 100644 --- a/tools/libclang/CIndexCXX.cpp +++ b/tools/libclang/CIndexCXX.cpp @@ -19,6 +19,7 @@ using namespace clang; using namespace clang::cxstring; +using namespace clang::cxcursor; extern "C" { @@ -26,7 +27,7 @@ unsigned clang_isVirtualBase(CXCursor C) { if (C.kind != CXCursor_CXXBaseSpecifier) return 0; - CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); + CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); return B->isVirtual(); } @@ -34,7 +35,7 @@ enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) { if (C.kind != CXCursor_CXXBaseSpecifier) return CX_CXXInvalidAccessSpecifier; - CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C); + CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C); switch (B->getAccessSpecifier()) { case AS_public: return CX_CXXPublic; case AS_protected: return CX_CXXProtected; @@ -78,4 +79,46 @@ enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) { return CXCursor_NoDeclFound; } +CXCursor clang_getSpecializedCursorTemplate(CXCursor C) { + if (!clang_isDeclaration(C.kind)) + return clang_getNullCursor(); + + Decl *D = getCursorDecl(C); + if (!D) + return clang_getNullCursor(); + + Decl *Template = 0; + if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) { + if (ClassTemplatePartialSpecializationDecl *PartialSpec + = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) + Template = PartialSpec->getSpecializedTemplate(); + else if (ClassTemplateSpecializationDecl *ClassSpec + = dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) { + llvm::PointerUnion<ClassTemplateDecl *, + ClassTemplatePartialSpecializationDecl *> Result + = ClassSpec->getSpecializedTemplateOrPartial(); + if (Result.is<ClassTemplateDecl *>()) + Template = Result.get<ClassTemplateDecl *>(); + else + Template = Result.get<ClassTemplatePartialSpecializationDecl *>(); + + } else + Template = CXXRecord->getInstantiatedFromMemberClass(); + } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { + Template = Function->getPrimaryTemplate(); + if (!Template) + Template = Function->getInstantiatedFromMemberFunction(); + } else if (VarDecl *Var = dyn_cast<VarDecl>(D)) { + if (Var->isStaticDataMember()) + Template = Var->getInstantiatedFromStaticDataMember(); + } else if (RedeclarableTemplateDecl *Tmpl + = dyn_cast<RedeclarableTemplateDecl>(D)) + Template = Tmpl->getInstantiatedFromMemberTemplate(); + + if (!Template) + return clang_getNullCursor(); + + return MakeCXCursor(Template, getCursorASTUnit(C)); +} + } // end extern "C" diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 289026510f..d1b45a2486 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -78,6 +78,7 @@ _clang_getRange _clang_getRangeEnd _clang_getRangeStart _clang_getResultType +_clang_getSpecializedCursorTemplate _clang_getTemplateCursorKind _clang_getTokenExtent _clang_getTokenKind diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index 254ba98a73..0ea6993b21 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -78,6 +78,7 @@ clang_getRange clang_getRangeEnd clang_getRangeStart clang_getResultType +clang_getSpecializedCursorTemplate clang_getTemplateCursorKind clang_getTokenExtent clang_getTokenKind |