summaryrefslogtreecommitdiffstats
path: root/clang/tools
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-15 00:54:55 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-15 00:54:55 +0000
commit3009383b9f3c4dd66a52684d33dedc654760c0a0 (patch)
tree38d244709e5f555d23f0592e75e7359c4879396c /clang/tools
parentfdc06e32cf35feb454ea2228277b2e62c040a552 (diff)
downloadbcm5719-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.cpp67
-rw-r--r--clang/tools/libclang/CXCursor.cpp22
-rw-r--r--clang/tools/libclang/CXCursor.h9
-rw-r--r--clang/tools/libclang/CXType.cpp13
-rw-r--r--clang/tools/libclang/CursorVisitor.h3
-rw-r--r--clang/tools/libclang/IndexBody.cpp11
-rw-r--r--clang/tools/libclang/IndexingContext.cpp4
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();
}
OpenPOWER on IntegriCloud