[cfe-commits] r162371 - in /cfe/trunk: lib/AST/ASTContext.cpp test/Index/complete-documentation-templates.cpp
Dmitri Gribenko
gribozavr at gmail.com
Wed Aug 22 10:44:32 PDT 2012
Author: gribozavr
Date: Wed Aug 22 12:44:32 2012
New Revision: 162371
URL: http://llvm.org/viewvc/llvm-project?rev=162371&view=rev
Log:
Attaching comments to declarations: when documentation is requested for an
implicit instantiation, look for documentation attached to the template.
Added:
cfe/trunk/test/Index/complete-documentation-templates.cpp
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=162371&r1=162370&r2=162371&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 22 12:44:32 2012
@@ -214,15 +214,72 @@
namespace {
/// If we have a 'templated' declaration for a template, adjust 'D' to
/// refer to the actual template.
+/// If we have an implicit instantiation, adjust 'D' to refer to template.
const Decl *adjustDeclToTemplate(const Decl *D) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // Is this function declaration part of a function template?
if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
- D = FTD;
- } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
- if (const ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
- D = CTD;
+ return FTD;
+
+ // Nothing to do if function is not an implicit instantiation.
+ if (FD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
+ return D;
+
+ // Function is an implicit instantiation of a function template?
+ if (const FunctionTemplateDecl *FTD = FD->getPrimaryTemplate())
+ return FTD;
+
+ // Function is instantiated from a member definition of a class template?
+ if (const FunctionDecl *MemberDecl =
+ FD->getInstantiatedFromMemberFunction())
+ return MemberDecl;
+
+ return D;
+ }
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ // Static data member is instantiated from a member definition of a class
+ // template?
+ if (VD->isStaticDataMember())
+ if (const VarDecl *MemberDecl = VD->getInstantiatedFromStaticDataMember())
+ return MemberDecl;
+
+ return D;
+ }
+ if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
+ // Is this class declaration part of a class template?
+ if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
+ return CTD;
+
+ // Class is an implicit instantiation of a class template or partial
+ // specialization?
+ if (const ClassTemplateSpecializationDecl *CTSD =
+ dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
+ if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
+ return D;
+ llvm::PointerUnion<ClassTemplateDecl *,
+ ClassTemplatePartialSpecializationDecl *>
+ PU = CTSD->getSpecializedTemplateOrPartial();
+ return PU.is<ClassTemplateDecl*>() ?
+ static_cast<const Decl*>(PU.get<ClassTemplateDecl *>()) :
+ static_cast<const Decl*>(
+ PU.get<ClassTemplatePartialSpecializationDecl *>());
+ }
+
+ // Class is instantiated from a member definition of a class template?
+ if (const MemberSpecializationInfo *Info =
+ CRD->getMemberSpecializationInfo())
+ return Info->getInstantiatedFrom();
+
+ return D;
+ }
+ if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+ // Enum is instantiated from a member definition of a class template?
+ if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
+ return MemberDecl;
+
+ return D;
}
- // FIXME: Alias templates?
+ // FIXME: Adjust alias templates?
return D;
}
} // unnamed namespace
Added: cfe/trunk/test/Index/complete-documentation-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/complete-documentation-templates.cpp?rev=162371&view=auto
==============================================================================
--- cfe/trunk/test/Index/complete-documentation-templates.cpp (added)
+++ cfe/trunk/test/Index/complete-documentation-templates.cpp Wed Aug 22 12:44:32 2012
@@ -0,0 +1,151 @@
+// Note: the run lines follow their respective tests, since line/column numbers
+// matter in this test.
+
+/// This is T1.
+template<typename T>
+void T1(T t) { }
+
+/// This is T2.
+template<typename T>
+void T2(T t) { }
+
+/// This is T2<int>.
+template<>
+void T2(int t) { }
+
+void test_CC1() {
+
+}
+
+// Check that implicit instantiations of class templates and members pick up
+// comments from class templates and specializations.
+
+/// This is T3.
+template<typename T>
+class T3 {
+public:
+ /// This is T4.
+ static void T4();
+
+ /// This is T5.
+ static int T5;
+
+ /// This is T6.
+ void T6();
+
+ /// This is T7.
+ int T7;
+
+ /// This is T8.
+ class T8 {};
+
+ /// This is T9.
+ enum T9 {
+ /// This is T10.
+ T10
+ };
+
+ /// This is T11.
+ template<typename U>
+ void T11(U t) {}
+
+ typedef T3<double> T12;
+};
+
+void test_CC2_CC3_CC4() {
+ T3<int>::T4();
+ T3<int> t3;
+ t3.T6();
+ T3<int>::T8 t8;
+}
+
+/// This is T100.
+template<typename T, typename U>
+class T100 {
+};
+
+/// This is T100<int, T>.
+template<typename T>
+class T100<int, T> {
+public:
+ /// This is T101.
+ static void T101();
+
+ /// This is T102.
+ static int T102;
+
+ /// This is T103.
+ void T103();
+
+ /// This is T104.
+ int T104;
+
+ /// This is T105.
+ class T105 {};
+
+ /// This is T106.
+ enum T106 {
+ /// This is T107.
+ T107
+ };
+
+ /// This is T108.
+ template<typename U>
+ void T108(U t) {}
+
+ typedef T100<double, T> T109;
+
+ typedef T100<double, double> T110;
+};
+
+void test_CC5_CC6_CC7() {
+ T100<int, long>::T101();
+ T100<int, long> t100;
+ t100.T103();
+ T100<int, long>::T105 t105;
+}
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:17:1 %s | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: FunctionTemplate:{ResultType void}{TypedText T1}{{.*}}(brief comment: This is T1.)
+// CHECK-CC1: FunctionTemplate:{ResultType void}{TypedText T2}{{.*}}(brief comment: This is T2.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:56:12 %s | FileCheck -check-prefix=CC2 %s
+// CHECK-CC2: CXXMethod:{ResultType void}{TypedText T4}{{.*}}(brief comment: This is T4.)
+// CHECK-CC2: VarDecl:{ResultType int}{TypedText T5}{{.*}}(brief comment: This is T5.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:58:6 %s | FileCheck -check-prefix=CC3 %s
+// CHECK-CC3: FunctionTemplate:{ResultType void}{TypedText T11}{{.*}}(brief comment: This is T11.)
+// CHECK-CC3: CXXMethod:{ResultType void}{TypedText T6}{{.*}}(brief comment: This is T6.)
+// CHECK-CC3: FieldDecl:{ResultType int}{TypedText T7}{{.*}}(brief comment: This is T7.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:59:12 %s | FileCheck -check-prefix=CC4 %s
+// CHECK-CC4: EnumConstantDecl:{ResultType T3<int>::T9}{TypedText T10}{{.*}}(brief comment: This is T10.)
+// FIXME: after we implement propagating comments through typedefs, this
+// typedef for implicit instantiation should pick up the documentation
+// comment from class template.
+// CHECK-CC4: TypedefDecl:{TypedText T12}
+// CHECK-CC4-SHOULD-BE: TypedefDecl:{TypedText T12}{{.*}}(brief comment: This is T3.)
+// CHECK-CC4: ClassDecl:{TypedText T8}{{.*}}(brief comment: This is T8.)
+// CHECK-CC4: EnumDecl:{TypedText T9}{{.*}}(brief comment: This is T9.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:102:20 %s | FileCheck -check-prefix=CC5 %s
+// CHECK-CC5: CXXMethod:{ResultType void}{TypedText T101}{{.*}}(brief comment: This is T101.)
+// CHECK-CC5: VarDecl:{ResultType int}{TypedText T102}{{.*}}(brief comment: This is T102.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:104:8 %s | FileCheck -check-prefix=CC6 %s
+// CHECK-CC6: CXXMethod:{ResultType void}{TypedText T103}{{.*}}(brief comment: This is T103.)
+// CHECK-CC6: FieldDecl:{ResultType int}{TypedText T104}{{.*}}(brief comment: This is T104.)
+// CHECK-CC6: FunctionTemplate:{ResultType void}{TypedText T108}{{.*}}(brief comment: This is T108.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:105:20 %s | FileCheck -check-prefix=CC7 %s
+// CHECK-CC7: ClassDecl:{TypedText T105}{{.*}}(brief comment: This is T105.)
+// CHECK-CC7: EnumDecl:{TypedText T106}{{.*}}(brief comment: This is T106.)
+// CHECK-CC7: EnumConstantDecl:{ResultType T100<int, long>::T106}{TypedText T107}{{.*}}(brief comment: This is T107.)
+// FIXME: after we implement propagating comments through typedefs, these two
+// typedefs for implicit instantiations should pick up the documentation
+// comment from class template.
+// CHECK-CC7: TypedefDecl:{TypedText T109}
+// CHECK-CC7: TypedefDecl:{TypedText T110}
+// CHECK-CC7-SHOULD-BE: TypedefDecl:{TypedText T109}{{.*}}(brief comment: This is T100.)
+// CHECK-CC7-SHOULD-BE: TypedefDecl:{TypedText T110}{{.*}}(brief comment: This is T100.)
+
More information about the cfe-commits
mailing list