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/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index c899f5d..73e5ce0 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -359,7 +359,7 @@
// 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 @@
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 @@
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 @@
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 @@
return createCXString(Field->getNameAsString());
}
+ case CXCursor_LabelRef: {
+ LabelStmt *Label = getCursorLabelRef(C).first;
+ assert(Label && "Missing label");
+
+ return createCXString(Label->getID()->getName());
+ }
+
default:
return createCXString("<not implemented>");
}
@@ -2615,6 +2630,14 @@
return createCXString("");
}
+ if (clang_isStatement(C.kind)) {
+ Stmt *S = getCursorStmt(C);
+ if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
+ return createCXString(Label->getID()->getName());
+
+ return createCXString("");
+ }
+
if (C.kind == CXCursor_MacroInstantiation)
return createCXString(getCursorMacroInstantiation(C)->getName()
->getNameStart());
@@ -2687,6 +2710,8 @@
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 @@
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 @@
return clang_getNullLocation();
}
+ case CXCursor_LabelRef: {
+ std::pair<LabelStmt *, SourceLocation> 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 @@
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 @@
// 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 @@
return clang_getNullCursor();
}
+ if (clang_isStatement(C.kind)) {
+ Stmt *S = getCursorStmt(C);
+ if (GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(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 @@
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");