diff --git a/clang/test/Index/annotate-tokens-cxx0x.cpp b/clang/test/Index/annotate-tokens-cxx0x.cpp new file mode 100644 index 000000000000..5dea3514c2b8 --- /dev/null +++ b/clang/test/Index/annotate-tokens-cxx0x.cpp @@ -0,0 +1,8 @@ +template +int f(Args ...args) { + return sizeof...(args) + sizeof...(Args); +} + +// RUN: c-index-test -test-annotate-tokens=%s:1:1:5:1 -std=c++0x %s | FileCheck %s +// CHECK: Identifier: "args" [3:20 - 3:24] UnexposedExpr=args:2:15 +// CHECK: Identifier: "Args" [3:38 - 3:42] TypeRef=Args:1:22 diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 1f46b07ebdb3..ec0f54fa1a16 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -141,7 +141,7 @@ public: ExplicitTemplateArgsVisitKind, NestedNameSpecifierVisitKind, DeclarationNameInfoVisitKind, - MemberRefVisitKind }; + MemberRefVisitKind, SizeOfPackExprPartsKind }; protected: void *data[3]; CXCursor parent; @@ -1497,6 +1497,7 @@ DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind) DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind) DEF_JOB(ExplicitTemplateArgsVisit, ExplicitTemplateArgumentList, ExplicitTemplateArgsVisitKind) +DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind) #undef DEF_JOB class DeclVisit : public VisitorJob { @@ -1637,7 +1638,7 @@ public: void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E); void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U); void VisitVAArgExpr(VAArgExpr *E); - // FIXME: Variadic templates SizeOfPackExpr! + void VisitSizeOfPackExpr(SizeOfPackExpr *E); private: void AddDeclarationNameInfo(Stmt *S); @@ -1929,6 +1930,9 @@ void EnqueueVisitor::VisitVAArgExpr(VAArgExpr *E) { AddStmt(E->getSubExpr()); AddTypeLoc(E->getWrittenTypeInfo()); } +void EnqueueVisitor::VisitSizeOfPackExpr(SizeOfPackExpr *E) { + WL.push_back(SizeOfPackExprParts(E, Parent)); +} void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, Stmt *S) { EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU)).Visit(S); @@ -2074,6 +2078,29 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { return true; continue; } + case VisitorJob::SizeOfPackExprPartsKind: { + SizeOfPackExpr *E = cast(&LI)->get(); + NamedDecl *Pack = E->getPack(); + if (isa(Pack)) { + if (Visit(MakeCursorTypeRef(cast(Pack), + E->getPackLoc(), TU))) + return true; + + continue; + } + + if (isa(Pack)) { + if (Visit(MakeCursorTemplateRef(cast(Pack), + E->getPackLoc(), TU))) + return true; + + continue; + } + + // Non-type template parameter packs and function parameter packs are + // treated like DeclRefExpr cursors. + continue; + } } } return false; @@ -2658,6 +2685,10 @@ static Decl *getDeclFromExpr(Stmt *E) { if (SubstNonTypeTemplateParmPackExpr *NTTP = dyn_cast(E)) return NTTP->getParameterPack(); + if (SizeOfPackExpr *SizeOfPack = dyn_cast(E)) + if (isa(SizeOfPack->getPack()) || + isa(SizeOfPack->getPack())) + return SizeOfPack->getPack(); return 0; } @@ -2673,6 +2704,9 @@ static SourceLocation getLocationFromExpr(Expr *E) { return Member->getMemberLoc(); if (ObjCIvarRefExpr *Ivar = dyn_cast(E)) return Ivar->getLocation(); + if (SizeOfPackExpr *SizeOfPack = dyn_cast(E)) + return SizeOfPack->getPackLoc(); + return E->getLocStart(); }