From: Douglas Gregor Date: Fri, 10 Sep 2010 00:22:18 +0000 (+0000) Subject: Add libclang support for label statements, gotos, and taking the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=36897b05ca2886e287f01802614bc10cbadcec22;p=clang Add libclang support for label statements, gotos, and taking the address of a label (GNU extension). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113564 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index fb742078f4..b112264c69 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1000,7 +1000,6 @@ enum CXCursorKind { CXCursor_UsingDirective = 34, /** \brief A using declaration. */ CXCursor_UsingDeclaration = 35, - CXCursor_FirstDecl = CXCursor_UnexposedDecl, CXCursor_LastDecl = CXCursor_UsingDeclaration, @@ -1036,11 +1035,28 @@ enum CXCursorKind { */ CXCursor_NamespaceRef = 46, /** - * A reference to a member of a struct, union, or class that occurs in some - * non-expression context, e.g., a designated initializer. + * \brief A reference to a member of a struct, union, or class that occurs in + * some non-expression context, e.g., a designated initializer. */ CXCursor_MemberRef = 47, - CXCursor_LastRef = CXCursor_MemberRef, + /** + * \brief A reference to a labeled statement. + * + * This cursor kind is used to describe the jump to "start_over" in the + * goto statement in the following example: + * + * \code + * start_over: + * ++counter; + * + * goto start_over; + * \endcode + * + * A label reference cursor refers to a label statement. + */ + CXCursor_LabelRef = 48, + + CXCursor_LastRef = CXCursor_LabelRef, /* Error conditions */ CXCursor_FirstInvalid = 70, @@ -1100,7 +1116,21 @@ enum CXCursorKind { * reported. */ CXCursor_UnexposedStmt = 200, - CXCursor_LastStmt = 200, + + /** \brief A labelled statement in a function. + * + * This cursor kind is used to describe the "start_over:" label statement in + * the following example: + * + * \code + * start_over: + * ++counter; + * \endcode + * + */ + CXCursor_LabelStmt = 201, + + CXCursor_LastStmt = CXCursor_LabelStmt, /** * \brief Cursor that represents the translation unit itself. diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m index 5fe7cd669b..f34593f3e8 100644 --- a/test/Index/c-index-api-loadTU-test.m +++ b/test/Index/c-index-api-loadTU-test.m @@ -103,23 +103,18 @@ struct X0 {}; // CHECK: c-index-api-loadTU-test.m:46:5: FunctionDecl=main:46:5 (Definition) Extent=[46:5 - 55:2] // CHECK: c-index-api-loadTU-test.m:46:15: ParmDecl=argc:46:15 (Definition) Extent=[46:11 - 46:19] // CHECK: c-index-api-loadTU-test.m:46:34: ParmDecl=argv:46:34 (Definition) Extent=[46:27 - 46:38] -// CHECK: :0:0: UnexposedStmt= Extent=[46:42 - 55:2] -// CHECK: :0:0: UnexposedStmt= Extent=[47:2 - 47:12] // CHECK: c-index-api-loadTU-test.m:47:8: VarDecl=bee:47:8 (Definition) Extent=[47:2 - 47:11] // CHECK: c-index-api-loadTU-test.m:47:2: ObjCClassRef=Baz:33:12 Extent=[47:2 - 47:5] -// CHECK: :0:0: UnexposedStmt= Extent=[48:2 - 48:19] // CHECK: c-index-api-loadTU-test.m:48:5: VarDecl=a:48:5 (Definition) Extent=[48:2 - 48:18] // CHECK: c-index-api-loadTU-test.m:48:2: TypeRef=id:0:0 Extent=[48:2 - 48:4] // CHECK: c-index-api-loadTU-test.m:48:9: ObjCMessageExpr=foo:9:1 Extent=[48:9 - 48:18] // CHECK: c-index-api-loadTU-test.m:48:10: DeclRefExpr=bee:47:8 Extent=[48:10 - 48:13] -// CHECK: :0:0: UnexposedStmt= Extent=[49:2 - 49:27] // CHECK: c-index-api-loadTU-test.m:49:12: VarDecl=c:49:12 (Definition) Extent=[49:2 - 49:26] // CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 Extent=[49:2 - 49:4] // CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=SubP:29:1 Extent=[49:6 - 49:10] // CHECK: c-index-api-loadTU-test.m:49:16: UnexposedExpr=fooC:10:1 Extent=[49:16 - 49:26] // CHECK: c-index-api-loadTU-test.m:49:16: ObjCMessageExpr=fooC:10:1 Extent=[49:16 - 49:26] // CHECK: c-index-api-loadTU-test.m:49:17: ObjCClassRef=Foo:4:12 Extent=[49:17 - 49:20] -// CHECK: :0:0: UnexposedStmt= Extent=[50:2 - 50:15] // CHECK: c-index-api-loadTU-test.m:50:13: VarDecl=d:50:13 (Definition) Extent=[50:2 - 50:14] // CHECK: c-index-api-loadTU-test.m:50:2: TypeRef=id:0:0 Extent=[50:2 - 50:4] // CHECK: c-index-api-loadTU-test.m:50:6: ObjCProtocolRef=Proto:25:1 Extent=[50:6 - 50:11] diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp index a4f1ee8d2c..12c4a9bf53 100644 --- a/test/Index/index-templates.cpp +++ b/test/Index/index-templates.cpp @@ -110,7 +110,6 @@ void template_exprs() { // CHECK-LOAD: index-templates.cpp:50:26: FunctionTemplate=getAs:50:26 Extent=[50:3 - 50:33] // CHECK-LOAD: index-templates.cpp:50:21: TemplateTypeParameter=T:50:21 (Definition) Extent=[50:21 - 50:22] // CHECK-LOAD: index-templates.cpp:53:6: FunctionDecl=template_exprs:53:6 (Definition) -// CHECK-LOAD: :0:0: UnexposedStmt= // CHECK-LOAD: index-templates.cpp:54:3: CallExpr=f:4:6 Extent=[54:3 - 54:68] // CHECK-LOAD: index-templates.cpp:54:3: UnexposedExpr=f:4:6 Extent=[54:3 - 54:35] // CHECK-LOAD: index-templates.cpp:54:3: DeclRefExpr=f:4:6 Extent=[54:3 - 54:35] diff --git a/test/Index/load-stmts.cpp b/test/Index/load-stmts.cpp index d101092937..e07c7920e1 100644 --- a/test/Index/load-stmts.cpp +++ b/test/Index/load-stmts.cpp @@ -104,6 +104,15 @@ Derived::Derived(int x) : member(x), Base(x) { } +void considered_harmful(int x) { + start_over: + void *ptr = &&start_over; + if (x > 17) + goto *ptr; + else + goto start_over; +} + // RUN: c-index-test -test-load-source all %s | FileCheck %s // CHECK: load-stmts.cpp:1:13: TypedefDecl=T:1:13 (Definition) Extent=[1:13 - 1:14] // CHECK: load-stmts.cpp:2:8: StructDecl=X:2:8 (Definition) Extent=[2:1 - 2:23] @@ -111,9 +120,6 @@ Derived::Derived(int x) // CHECK: load-stmts.cpp:2:19: FieldDecl=b:2:19 (Definition) Extent=[2:19 - 2:20] // CHECK: load-stmts.cpp:3:6: FunctionDecl=f:3:6 (Definition) Extent=[3:6 - 11:2] // CHECK: load-stmts.cpp:3:12: ParmDecl=x:3:12 (Definition) Extent=[3:8 - 3:13] -// CHECK: :0:0: UnexposedStmt= Extent=[3:15 - 11:2] -// CHECK: :0:0: UnexposedStmt= Extent=[4:3 - 5:4] -// CHECK: :0:0: UnexposedStmt= Extent=[4:8 - 4:16] // CHECK: load-stmts.cpp:4:10: VarDecl=y:4:10 (Definition) Extent=[4:8 - 4:15] // CHECK: load-stmts.cpp:4:8: TypeRef=T:1:13 Extent=[4:8 - 4:9] // CHECK: load-stmts.cpp:4:14: DeclRefExpr=x:3:12 Extent=[4:14 - 4:15] @@ -124,32 +130,23 @@ Derived::Derived(int x) // CHECK: load-stmts.cpp:4:19: DeclRefExpr=z:4:19 Extent=[4:19 - 4:20] // CHECK: load-stmts.cpp:4:26: UnexposedExpr= Extent=[4:26 - 4:29] // CHECK: load-stmts.cpp:4:28: DeclRefExpr=x:3:12 Extent=[4:28 - 4:29] -// CHECK: :0:0: UnexposedStmt= Extent=[4:31 - 5:4] -// CHECK: :0:0: UnexposedStmt= Extent=[6:3 - 6:22] // CHECK: load-stmts.cpp:6:10: VarDecl=z2:6:10 (Definition) Extent=[6:7 - 6:17] // CHECK: load-stmts.cpp:6:7: TypeRef=T:1:13 Extent=[6:7 - 6:8] // CHECK: load-stmts.cpp:6:15: UnexposedExpr= Extent=[6:15 - 6:17] // CHECK: load-stmts.cpp:6:16: DeclRefExpr=x:3:12 Extent=[6:16 - 6:17] // CHECK: load-stmts.cpp:6:10: UnexposedExpr=z2:6:10 Extent=[6:10 - 6:12] // CHECK: load-stmts.cpp:6:10: DeclRefExpr=z2:6:10 Extent=[6:10 - 6:12] -// CHECK: :0:0: UnexposedStmt= Extent=[6:19 - 6:22] -// CHECK: :0:0: UnexposedStmt= Extent=[7:3 - 7:25] // CHECK: load-stmts.cpp:7:13: VarDecl=z3:7:13 (Definition) Extent=[7:10 - 7:20] // CHECK: load-stmts.cpp:7:10: TypeRef=T:1:13 Extent=[7:10 - 7:11] // CHECK: load-stmts.cpp:7:18: UnexposedExpr= Extent=[7:18 - 7:20] // CHECK: load-stmts.cpp:7:19: DeclRefExpr=x:3:12 Extent=[7:19 - 7:20] // CHECK: load-stmts.cpp:7:13: UnexposedExpr=z3:7:13 Extent=[7:13 - 7:15] // CHECK: load-stmts.cpp:7:13: DeclRefExpr=z3:7:13 Extent=[7:13 - 7:15] -// CHECK: :0:0: UnexposedStmt= Extent=[7:22 - 7:25] -// CHECK: :0:0: UnexposedStmt= Extent=[8:3 - 10:4] // CHECK: load-stmts.cpp:8:13: VarDecl=z4:8:13 (Definition) Extent=[8:11 - 8:19] // CHECK: load-stmts.cpp:8:11: TypeRef=T:1:13 Extent=[8:11 - 8:12] // CHECK: load-stmts.cpp:8:18: DeclRefExpr=x:3:12 Extent=[8:18 - 8:19] // CHECK: load-stmts.cpp:8:13: DeclRefExpr=z4:8:13 Extent=[8:13 - 8:15] -// CHECK: :0:0: UnexposedStmt= Extent=[8:21 - 10:4] -// CHECK: :0:0: UnexposedStmt= Extent=[9:3 - 9:17] // CHECK: load-stmts.cpp:9:8: UnexposedExpr= Extent=[9:8 - 9:10] -// CHECK: :0:0: UnexposedStmt= Extent=[9:12 - 9:17] // CHECK: load-stmts.cpp:14:7: ClassDecl=A:14:7 (Definition) Extent=[14:1 - 16:2] // CHECK: load-stmts.cpp:15:8: CXXMethod=doA:15:8 Extent=[15:8 - 15:13] // CHECK: load-stmts.cpp:18:7: ClassDecl=B:18:7 (Definition) Extent=[18:1 - 20:2] @@ -220,3 +217,7 @@ Derived::Derived(int x) // CHECK: load-stmts.cpp:104:16: TypeRef=struct Base:94:8 Extent=[104:16 - 104:2 // CHECK: load-stmts.cpp:104:16: CallExpr= Extent=[104:16 - 104:22] // CHECK: load-stmts.cpp:104:21: DeclRefExpr=x:103:22 Extent=[104:21 - 104:22] +// CHECK: load-stmts.cpp:107:6: FunctionDecl=considered_harmful:107:6 (Definition) +// CHECK: load-stmts.cpp:108:2: LabelStmt=start_over Extent=[108:2 - 109:28] +// CHECK: load-stmts.cpp:109:17: LabelRef=start_over:108:2 Extent=[109:17 - 109:27] +// CHECK: load-stmts.cpp:113:10: LabelRef=start_over:108:2 Extent=[113:10 - 113:20] diff --git a/test/Index/preamble.c b/test/Index/preamble.c index 54abf99ed1..c30a1437e3 100644 --- a/test/Index/preamble.c +++ b/test/Index/preamble.c @@ -9,14 +9,10 @@ void f(int x) { // RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 local -I %S/Inputs -include %t %s 2> %t.stderr.txt | FileCheck %s // RUN: FileCheck -check-prefix CHECK-DIAG %s < %t.stderr.txt // CHECK: preamble.h:1:12: FunctionDecl=bar:1:12 (Definition) Extent=[1:12 - 6:2] -// CHECK: :0:0: UnexposedStmt= Extent=[1:23 - 6:2] -// CHECK: :0:0: UnexposedStmt= Extent=[2:3 - 2:16] -// CHECK: :0:0: UnexposedStmt= Extent=[3:3 - 3:15] // CHECK: preamble.h:4:3: UnexposedExpr= Extent=[4:3 - 4:13] // CHECK: preamble.h:4:3: DeclRefExpr=ptr:2:8 Extent=[4:3 - 4:6] // CHECK: preamble.h:4:9: UnexposedExpr=ptr1:3:10 Extent=[4:9 - 4:13] // CHECK: preamble.h:4:9: DeclRefExpr=ptr1:3:10 Extent=[4:9 - 4:13] -// CHECK: :0:0: UnexposedStmt= Extent=[5:3 - 5:11] // CHECK: preamble.h:5:10: UnexposedExpr= Extent=[5:10 - 5:11] // CHECK: preamble.c:3:5: FunctionDecl=wibble:3:5 Extent=[3:5 - 3:16] // CHECK: preamble.c:3:15: ParmDecl=:3:15 (Definition) Extent=[3:12 - 3:16] diff --git a/test/Index/remap-load.c b/test/Index/remap-load.c index d9634a4af6..2e57fe4cd9 100644 --- a/test/Index/remap-load.c +++ b/test/Index/remap-load.c @@ -5,8 +5,6 @@ // CHECK: remap-load.c:1:5: FunctionDecl=foo:1:5 (Definition) Extent=[1:5 - 3:2] // CHECK: remap-load.c:1:13: ParmDecl=parm1:1:13 (Definition) Extent=[1:9 - 1:18] // CHECK: remap-load.c:1:26: ParmDecl=parm2:1:26 (Definition) Extent=[1:20 - 1:31] -// CHECK: :0:0: UnexposedStmt= Extent=[1:33 - 3:2] -// CHECK: :0:0: UnexposedStmt= Extent=[2:3 - 2:23] // CHECK: remap-load.c:2:10: UnexposedExpr= Extent=[2:10 - 2:23] // CHECK: remap-load.c:2:10: UnexposedExpr= Extent=[2:10 - 2:23] // CHECK: remap-load.c:2:10: UnexposedExpr=parm1:1:13 Extent=[2:10 - 2:15] diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index c899f5db6f..73e5ce06dd 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -359,7 +359,7 @@ public: // Statement visitors bool VisitStmt(Stmt *S); bool VisitDeclStmt(DeclStmt *S); - // FIXME: LabelStmt label? + bool VisitGotoStmt(GotoStmt *S); bool VisitIfStmt(IfStmt *S); bool VisitSwitchStmt(SwitchStmt *S); bool VisitCaseStmt(CaseStmt *S); @@ -377,7 +377,7 @@ public: bool VisitOffsetOfExpr(OffsetOfExpr *E); bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); bool VisitMemberExpr(MemberExpr *E); - // FIXME: AddrLabelExpr (once we have cursors for labels) + bool VisitAddrLabelExpr(AddrLabelExpr *E); bool VisitTypesCompatibleExpr(TypesCompatibleExpr *E); bool VisitVAArgExpr(VAArgExpr *E); bool VisitInitListExpr(InitListExpr *E); @@ -1438,6 +1438,10 @@ bool CursorVisitor::VisitDeclStmt(DeclStmt *S) { return false; } +bool CursorVisitor::VisitGotoStmt(GotoStmt *S) { + return Visit(MakeCursorLabelRef(S->getLabel(), S->getLabelLoc(), TU)); +} + bool CursorVisitor::VisitIfStmt(IfStmt *S) { if (VarDecl *Var = S->getConditionVariable()) { if (Visit(MakeCXCursor(Var, TU))) @@ -1640,6 +1644,10 @@ bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { return VisitExpr(E); } +bool CursorVisitor::VisitAddrLabelExpr(AddrLabelExpr *E) { + return Visit(MakeCursorLabelRef(E->getLabel(), E->getLabelLoc(), TU)); +} + bool CursorVisitor::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) { return Visit(E->getArgTInfo1()->getTypeLoc()) || Visit(E->getArgTInfo2()->getTypeLoc()); @@ -2603,6 +2611,13 @@ CXString clang_getCursorSpelling(CXCursor C) { return createCXString(Field->getNameAsString()); } + case CXCursor_LabelRef: { + LabelStmt *Label = getCursorLabelRef(C).first; + assert(Label && "Missing label"); + + return createCXString(Label->getID()->getName()); + } + default: return createCXString(""); } @@ -2615,6 +2630,14 @@ CXString clang_getCursorSpelling(CXCursor C) { return createCXString(""); } + if (clang_isStatement(C.kind)) { + Stmt *S = getCursorStmt(C); + if (LabelStmt *Label = dyn_cast_or_null(S)) + return createCXString(Label->getID()->getName()); + + return createCXString(""); + } + if (C.kind == CXCursor_MacroInstantiation) return createCXString(getCursorMacroInstantiation(C)->getName() ->getNameStart()); @@ -2687,6 +2710,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("NamespaceRef"); case CXCursor_MemberRef: return createCXString("MemberRef"); + case CXCursor_LabelRef: + return createCXString("LabelRef"); case CXCursor_UnexposedExpr: return createCXString("UnexposedExpr"); case CXCursor_BlockExpr: @@ -2701,6 +2726,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return createCXString("ObjCMessageExpr"); case CXCursor_UnexposedStmt: return createCXString("UnexposedStmt"); + case CXCursor_LabelStmt: + return createCXString("LabelStmt"); case CXCursor_InvalidFile: return createCXString("InvalidFile"); case CXCursor_InvalidCode: @@ -2899,6 +2926,11 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return clang_getNullLocation(); } + case CXCursor_LabelRef: { + std::pair P = getCursorLabelRef(C); + return cxloc::translateSourceLocation(getCursorContext(C), P.second); + } + default: // FIXME: Need a way to enumerate all non-reference cases. llvm_unreachable("Missed a reference kind"); @@ -2909,6 +2941,10 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { return cxloc::translateSourceLocation(getCursorContext(C), getLocationFromExpr(getCursorExpr(C))); + if (clang_isStatement(C.kind)) + return cxloc::translateSourceLocation(getCursorContext(C), + getCursorStmt(C)->getLocStart()); + if (C.kind == CXCursor_PreprocessingDirective) { SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); return cxloc::translateSourceLocation(getCursorContext(C), L); @@ -2965,6 +3001,9 @@ static SourceRange getRawCursorExtent(CXCursor C) { // FIXME: Figure out what source range to use for a CXBaseSpecifier. return SourceRange(); + case CXCursor_LabelRef: + return getCursorLabelRef(C).second; + default: // FIXME: Need a way to enumerate all non-reference cases. llvm_unreachable("Missed a reference kind"); @@ -3017,6 +3056,15 @@ CXCursor clang_getCursorReferenced(CXCursor C) { return clang_getNullCursor(); } + if (clang_isStatement(C.kind)) { + Stmt *S = getCursorStmt(C); + if (GotoStmt *Goto = dyn_cast_or_null(S)) + return MakeCXCursor(Goto->getLabel(), getCursorDecl(C), + getCursorASTUnit(C)); + + return clang_getNullCursor(); + } + if (C.kind == CXCursor_MacroInstantiation) { if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition()) return MakeMacroDefinitionCursor(Def, CXXUnit); @@ -3053,6 +3101,13 @@ CXCursor clang_getCursorReferenced(CXCursor C) { CXXUnit)); } + case CXCursor_LabelRef: + // FIXME: We end up faking the "parent" declaration here because we + // don't want to make CXCursor larger. + return MakeCXCursor(getCursorLabelRef(C).first, + CXXUnit->getASTContext().getTranslationUnitDecl(), + CXXUnit); + default: // We would prefer to enumerate all non-reference cursor kinds here. llvm_unreachable("Unhandled reference cursor kind"); diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index 53145a6719..6e5f61f449 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -65,7 +65,6 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { case Stmt::CompoundStmtClass: case Stmt::CaseStmtClass: case Stmt::DefaultStmtClass: - case Stmt::LabelStmtClass: case Stmt::IfStmtClass: case Stmt::SwitchStmtClass: case Stmt::WhileStmtClass: @@ -90,6 +89,10 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { K = CXCursor_UnexposedStmt; break; + case Stmt::LabelStmtClass: + K = CXCursor_LabelStmt; + break; + case Stmt::PredefinedExprClass: case Stmt::IntegerLiteralClass: case Stmt::FloatingLiteralClass: @@ -153,6 +156,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { case Stmt::BlockExprClass: K = CXCursor_UnexposedExpr; break; + case Stmt::DeclRefExprClass: case Stmt::BlockDeclRefExprClass: // FIXME: UnresolvedLookupExpr? @@ -357,6 +361,23 @@ MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) { return static_cast(C.data[0]); } +CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc, + ASTUnit *TU) { + + assert(Label && TU && "Invalid arguments!"); + void *RawLoc = reinterpret_cast(Loc.getRawEncoding()); + CXCursor C = { CXCursor_LabelRef, { Label, RawLoc, TU } }; + return C; +} + +std::pair +cxcursor::getCursorLabelRef(CXCursor C) { + assert(C.kind == CXCursor_LabelRef); + return std::make_pair(static_cast(C.data[0]), + SourceLocation::getFromRawEncoding( + reinterpret_cast(C.data[1]))); +} + Decl *cxcursor::getCursorDecl(CXCursor Cursor) { return (Decl *)Cursor.data[0]; } diff --git a/tools/libclang/CXCursor.h b/tools/libclang/CXCursor.h index eff71f398a..743b38b9c4 100644 --- a/tools/libclang/CXCursor.h +++ b/tools/libclang/CXCursor.h @@ -27,6 +27,7 @@ class CXXBaseSpecifier; class Decl; class Expr; class FieldDecl; +class LabelStmt; class MacroDefinition; class MacroInstantiation; class NamedDecl; @@ -128,6 +129,13 @@ CXCursor MakeMacroInstantiationCursor(MacroInstantiation *, ASTUnit *TU); /// source range. MacroInstantiation *getCursorMacroInstantiation(CXCursor C); +/// \brief Create a label reference at the given location. +CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc, ASTUnit *TU); + +/// \brief Unpack a label reference into the label statement it refers to and +/// the location of the reference. +std::pair getCursorLabelRef(CXCursor C); + Decl *getCursorDecl(CXCursor Cursor); Expr *getCursorExpr(CXCursor Cursor); Stmt *getCursorStmt(CXCursor Cursor);