diff options
| author | Douglas Gregor <dgregor@apple.com> | 2012-02-15 00:54:55 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2012-02-15 00:54:55 +0000 |
| commit | 3009383b9f3c4dd66a52684d33dedc654760c0a0 (patch) | |
| tree | 38d244709e5f555d23f0592e75e7359c4879396c /clang/tools | |
| parent | fdc06e32cf35feb454ea2228277b2e62c040a552 (diff) | |
| download | bcm5719-llvm-3009383b9f3c4dd66a52684d33dedc654760c0a0.tar.gz bcm5719-llvm-3009383b9f3c4dd66a52684d33dedc654760c0a0.zip | |
Implement indexing support for lambdas in libclang (both kinds), as
well as improving the RecursiveASTVisitor's walk of lambda
expressions.
llvm-svn: 150549
Diffstat (limited to 'clang/tools')
| -rw-r--r-- | clang/tools/libclang/CIndex.cpp | 67 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.cpp | 22 | ||||
| -rw-r--r-- | clang/tools/libclang/CXCursor.h | 9 | ||||
| -rw-r--r-- | clang/tools/libclang/CXType.cpp | 13 | ||||
| -rw-r--r-- | clang/tools/libclang/CursorVisitor.h | 3 | ||||
| -rw-r--r-- | clang/tools/libclang/IndexBody.cpp | 11 | ||||
| -rw-r--r-- | clang/tools/libclang/IndexingContext.cpp | 4 |
7 files changed, 122 insertions, 7 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 90bccc55e1d..beec4d2352f 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -1615,6 +1615,7 @@ DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind) DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo, ExplicitTemplateArgsVisitKind) DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind) +DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind) #undef DEF_JOB class DeclVisit : public VisitorJob { @@ -1761,6 +1762,7 @@ public: void VisitSizeOfPackExpr(SizeOfPackExpr *E); void VisitPseudoObjectExpr(PseudoObjectExpr *E); void VisitOpaqueValueExpr(OpaqueValueExpr *E); + void VisitLambdaExpr(LambdaExpr *E); private: void AddDeclarationNameInfo(Stmt *S); @@ -2081,6 +2083,10 @@ void EnqueueVisitor::VisitOpaqueValueExpr(OpaqueValueExpr *E) { if (Expr *SourceExpr = E->getSourceExpr()) return Visit(SourceExpr); } +void EnqueueVisitor::VisitLambdaExpr(LambdaExpr *E) { + AddStmt(E->getBody()); + WL.push_back(LambdaExprParts(E, Parent)); +} void EnqueueVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *E) { // Treat the expression like its syntactic form. Visit(E->getSyntacticForm()); @@ -2258,6 +2264,45 @@ bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) { // treated like DeclRefExpr cursors. continue; } + + case VisitorJob::LambdaExprPartsKind: { + // Visit captures. + LambdaExpr *E = cast<LambdaExprParts>(&LI)->get(); + for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(), + CEnd = E->explicit_capture_end(); + C != CEnd; ++C) { + if (C->capturesThis()) + continue; + + if (Visit(MakeCursorVariableRef(C->getCapturedVar(), + C->getLocation(), + TU))) + return true; + } + + // Visit parameters and return type, if present. + if (E->hasExplicitParameters() || E->hasExplicitResultType()) { + TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); + if (E->hasExplicitParameters() && E->hasExplicitResultType()) { + // Visit the whole type. + if (Visit(TL)) + return true; + } else if (isa<FunctionProtoTypeLoc>(TL)) { + FunctionProtoTypeLoc Proto = cast<FunctionProtoTypeLoc>(TL); + if (E->hasExplicitParameters()) { + // Visit parameters. + for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I) + if (Visit(MakeCXCursor(Proto.getArg(I), TU))) + return true; + } else { + // Visit result type. + if (Visit(Proto.getResultLoc())) + return true; + } + } + } + break; + } } } return false; @@ -2980,6 +3025,13 @@ CXString clang_getCursorSpelling(CXCursor C) { return createCXString((*Ovl->begin())->getNameAsString()); } + case CXCursor_VariableRef: { + VarDecl *Var = getCursorVariableRef(C).first; + assert(Var && "Missing variable decl"); + + return createCXString(Var->getNameAsString()); + } + default: return createCXString("<not implemented>"); } @@ -3173,6 +3225,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("LabelRef"); case CXCursor_OverloadedDeclRef: return createCXString("OverloadedDeclRef"); + case CXCursor_VariableRef: + return createCXString("VariableRef"); case CXCursor_IntegerLiteral: return createCXString("IntegerLiteral"); case CXCursor_FloatingLiteral: @@ -3251,6 +3305,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("PackExpansionExpr"); case CXCursor_SizeOfPackExpr: return createCXString("SizeOfPackExpr"); + case CXCursor_LambdaExpr: + return createCXString("LambdaExpr"); case CXCursor_UnexposedExpr: return createCXString("UnexposedExpr"); case CXCursor_DeclRefExpr: @@ -3626,6 +3682,11 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); } + case CXCursor_VariableRef: { + std::pair<VarDecl *, SourceLocation> P = getCursorVariableRef(C); + return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); + } + case CXCursor_CXXBaseSpecifier: { CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C); if (!BaseSpec) @@ -3768,6 +3829,9 @@ static SourceRange getRawCursorExtent(CXCursor C) { case CXCursor_OverloadedDeclRef: return getCursorOverloadedDeclRef(C).second; + case CXCursor_VariableRef: + return getCursorVariableRef(C).second; + default: // FIXME: Need a way to enumerate all non-reference cases. llvm_unreachable("Missed a reference kind"); @@ -3975,6 +4039,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) { case CXCursor_OverloadedDeclRef: return C; + + case CXCursor_VariableRef: + return MakeCXCursor(getCursorVariableRef(C).first, tu); default: // We would prefer to enumerate all non-reference cursor kinds here. diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index af640bd7ab4..531e70e17ad 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -226,7 +226,6 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU, case Stmt::UnaryExprOrTypeTraitExprClass: case Stmt::UnaryTypeTraitExprClass: case Stmt::VAArgExprClass: - case Stmt::LambdaExprClass: K = CXCursor_UnexposedExpr; break; @@ -441,6 +440,10 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU, K = CXCursor_CallExpr; break; + case Stmt::LambdaExprClass: + K = CXCursor_LambdaExpr; + break; + case Stmt::ObjCMessageExprClass: { K = CXCursor_ObjCMessageExpr; int SelectorIdIndex = -1; @@ -573,6 +576,23 @@ cxcursor::getCursorNamespaceRef(CXCursor C) { reinterpret_cast<uintptr_t>(C.data[1]))); } +CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc, + CXTranslationUnit TU) { + + assert(Var && TU && "Invalid arguments!"); + void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); + CXCursor C = { CXCursor_VariableRef, 0, { (void*)Var, RawLoc, TU } }; + return C; +} + +std::pair<VarDecl *, SourceLocation> +cxcursor::getCursorVariableRef(CXCursor C) { + assert(C.kind == CXCursor_VariableRef); + return std::make_pair(static_cast<VarDecl *>(C.data[0]), + SourceLocation::getFromRawEncoding( + reinterpret_cast<uintptr_t>(C.data[1]))); +} + CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc, CXTranslationUnit TU) { diff --git a/clang/tools/libclang/CXCursor.h b/clang/tools/libclang/CXCursor.h index 7423560085c..947b0a3eede 100644 --- a/clang/tools/libclang/CXCursor.h +++ b/clang/tools/libclang/CXCursor.h @@ -41,6 +41,7 @@ class Stmt; class TemplateDecl; class TemplateName; class TypeDecl; +class VarDecl; namespace cxcursor { @@ -111,6 +112,14 @@ CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc, /// it references and the location where the reference occurred. std::pair<NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C); +/// \brief Create a reference to a variable at the given location. +CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc, + CXTranslationUnit TU); + +/// \brief Unpack a VariableRef cursor into the variable it references and the +/// location where the where the reference occurred. +std::pair<VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C); + /// \brief Create a reference to a field at the given location. CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc, CXTranslationUnit TU); diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp index eba0405994e..0d4a5195abe 100644 --- a/clang/tools/libclang/CXType.cpp +++ b/clang/tools/libclang/CXType.cpp @@ -160,12 +160,17 @@ CXType clang_getCursorType(CXCursor C) { case CXCursor_CXXBaseSpecifier: return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU); - - case CXCursor_ObjCProtocolRef: + + case CXCursor_MemberRef: + return cxtype::MakeCXType(getCursorMemberRef(C).first->getType(), TU); + + case CXCursor_VariableRef: + return cxtype::MakeCXType(getCursorVariableRef(C).first->getType(), TU); + + case CXCursor_ObjCProtocolRef: case CXCursor_TemplateRef: case CXCursor_NamespaceRef: - case CXCursor_MemberRef: - case CXCursor_OverloadedDeclRef: + case CXCursor_OverloadedDeclRef: default: break; } diff --git a/clang/tools/libclang/CursorVisitor.h b/clang/tools/libclang/CursorVisitor.h index f1258cb6666..88b70a490eb 100644 --- a/clang/tools/libclang/CursorVisitor.h +++ b/clang/tools/libclang/CursorVisitor.h @@ -31,7 +31,8 @@ public: ExplicitTemplateArgsVisitKind, NestedNameSpecifierLocVisitKind, DeclarationNameInfoVisitKind, - MemberRefVisitKind, SizeOfPackExprPartsKind }; + MemberRefVisitKind, SizeOfPackExprPartsKind, + LambdaExprPartsKind }; protected: void *data[3]; CXCursor parent; diff --git a/clang/tools/libclang/IndexBody.cpp b/clang/tools/libclang/IndexBody.cpp index 684d5ce3854..77ff843525c 100644 --- a/clang/tools/libclang/IndexBody.cpp +++ b/clang/tools/libclang/IndexBody.cpp @@ -101,6 +101,17 @@ public: IndexCtx.indexDeclGroupRef(S->getDeclGroup()); return true; } + + bool TraverseLambdaCapture(LambdaExpr::Capture C) { + if (C.capturesThis()) + return true; + + if (IndexCtx.indexFunctionLocalSymbols()) + IndexCtx.handleReference(C.getCapturedVar(), C.getLocation(), + Parent, ParentDC); + return true; + } + }; } // anonymous namespace diff --git a/clang/tools/libclang/IndexingContext.cpp b/clang/tools/libclang/IndexingContext.cpp index 75184dd3b0b..2963f3b9453 100644 --- a/clang/tools/libclang/IndexingContext.cpp +++ b/clang/tools/libclang/IndexingContext.cpp @@ -1035,7 +1035,9 @@ CXCursor IndexingContext::getRefCursor(const NamedDecl *D, SourceLocation Loc) { return MakeCursorNamespaceRef(Namespace, Loc, CXTU); if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) return MakeCursorMemberRef(Field, Loc, CXTU); - + if (const VarDecl *Var = dyn_cast<VarDecl>(D)) + return MakeCursorVariableRef(Var, Loc, CXTU); + return clang_getNullCursor(); } |

