diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index f5669f7fc05a..7b284bad5f23 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -538,6 +538,10 @@ class InjectedClassNameTypeLoc : public InheritingConcreteTypeLoc { +public: + CXXRecordDecl *getDecl() const { + return getTypePtr()->getDecl(); + } }; /// \brief Wrapper for source info for unresolved typename using decls. @@ -1408,6 +1412,8 @@ public: class DecltypeTypeLoc : public InheritingConcreteTypeLoc { +public: + Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } }; struct UnaryTransformTypeLocInfo { diff --git a/clang/test/Index/annotate-tokens-cxx0x.cpp b/clang/test/Index/annotate-tokens-cxx0x.cpp index 5dea3514c2b8..bf86f325fbfa 100644 --- a/clang/test/Index/annotate-tokens-cxx0x.cpp +++ b/clang/test/Index/annotate-tokens-cxx0x.cpp @@ -3,6 +3,14 @@ int f(Args ...args) { return sizeof...(args) + sizeof...(Args); } +void test() { + int a; + decltype(a) b; +} + // 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 + +// RUN: c-index-test -test-annotate-tokens=%s:8:1:9:1 -std=c++0x %s | FileCheck -check-prefix=CHECK-DECLTYPE %s +// CHECK-DECLTYPE: Identifier: "a" [8:12 - 8:13] DeclRefExpr=a:7:7 diff --git a/clang/test/Index/recursive-cxx-member-calls.cpp b/clang/test/Index/recursive-cxx-member-calls.cpp index 7502c8f47b42..f42e6a363700 100644 --- a/clang/test/Index/recursive-cxx-member-calls.cpp +++ b/clang/test/Index/recursive-cxx-member-calls.cpp @@ -846,7 +846,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) { // CHECK-tokens: Keyword: "unsigned" [88:14 - 88:22] NonTypeTemplateParameter=N:88:23 (Definition) // CHECK-tokens: Identifier: "N" [88:23 - 88:24] NonTypeTemplateParameter=N:88:23 (Definition) // CHECK-tokens: Punctuation: ">" [88:25 - 88:26] FunctionTemplate=Case:88:42 (Definition) -// CHECK-tokens: Identifier: "StringSwitch" [88:27 - 88:39] FunctionTemplate=Case:88:42 (Definition) +// CHECK-tokens: Identifier: "StringSwitch" [88:27 - 88:39] TypeRef=StringSwitch:83:47 // CHECK-tokens: Punctuation: "&" [88:40 - 88:41] FunctionTemplate=Case:88:42 (Definition) // CHECK-tokens: Identifier: "Case" [88:42 - 88:46] FunctionTemplate=Case:88:42 (Definition) // CHECK-tokens: Punctuation: "(" [88:46 - 88:47] FunctionTemplate=Case:88:42 (Definition) diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index bd3cac336087..404b9d3488b0 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -333,36 +333,15 @@ public: bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL); // Type visitors - bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL); - bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL); - bool VisitTypedefTypeLoc(TypedefTypeLoc TL); - bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL); +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); +#include "clang/AST/TypeLocNodes.def" + bool VisitTagTypeLoc(TagTypeLoc TL); - bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL); - bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); - bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL); - bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); - bool VisitParenTypeLoc(ParenTypeLoc TL); - bool VisitPointerTypeLoc(PointerTypeLoc TL); - bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL); - bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL); - bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL); - bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL); - bool VisitAttributedTypeLoc(AttributedTypeLoc TL); - bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); bool VisitArrayTypeLoc(ArrayTypeLoc TL); - bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL); - // FIXME: Implement visitors here when the unimplemented TypeLocs get - // implemented - bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); - bool VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL); - bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); - bool VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL); - bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL); - bool VisitDependentTemplateSpecializationTypeLoc( - DependentTemplateSpecializationTypeLoc TL); - bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TL); - + bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false); + // Data-recursive visitor functions. bool IsInRegionOfInterest(CXCursor C); bool RunVisitorWorkList(VisitorWorkList &WL); @@ -1615,6 +1594,38 @@ bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) { return Visit(TL.getPatternLoc()); } +bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + if (Expr *E = TL.getUnderlyingExpr()) + return Visit(MakeCXCursor(E, StmtParent, TU)); + + return false; +} + +bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) { + return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); +} + +#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \ +bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ + return Visit##PARENT##Loc(TL); \ +} + +DEFAULT_TYPELOC_IMPL(Complex, Type) +DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType) +DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType) +DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType) +DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType) +DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type) +DEFAULT_TYPELOC_IMPL(Vector, Type) +DEFAULT_TYPELOC_IMPL(ExtVector, VectorType) +DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType) +DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType) +DEFAULT_TYPELOC_IMPL(Record, TagType) +DEFAULT_TYPELOC_IMPL(Enum, TagType) +DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type) +DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type) +DEFAULT_TYPELOC_IMPL(Auto, Type) + bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) { // Visit the nested-name-specifier, if present. if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())