diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang-c/Index.h | 3 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 5 | ||||
-rw-r--r-- | clang/tools/CIndex/CIndex.cpp | 7 | ||||
-rw-r--r-- | clang/tools/CIndex/CIndexUSRs.cpp | 26 | ||||
-rw-r--r-- | clang/tools/CIndex/CXCursor.cpp | 5 |
5 files changed, 35 insertions, 11 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index de76076a255..6120c4863fd 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -728,7 +728,8 @@ enum CXCursorKind { CXCursor_InvalidFile = 70, CXCursor_NoDeclFound = 71, CXCursor_NotImplemented = 72, - CXCursor_LastInvalid = 72, + CXCursor_InvalidCode = 73, + CXCursor_LastInvalid = CXCursor_InvalidCode, /* Expressions */ CXCursor_FirstExpr = 100, diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 7d1033d4f15..ab6b9e1f45a 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -743,7 +743,10 @@ ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const { - return getClassInterface()->FindCategoryDeclaration(getIdentifier()); + // The class interface might be NULL if we are working with invalid code. + if (const ObjCInterfaceDecl *ID = getClassInterface()) + return ID->FindCategoryDeclaration(getIdentifier()); + return 0; } diff --git a/clang/tools/CIndex/CIndex.cpp b/clang/tools/CIndex/CIndex.cpp index f20bb753747..b3c585af37e 100644 --- a/clang/tools/CIndex/CIndex.cpp +++ b/clang/tools/CIndex/CIndex.cpp @@ -621,9 +621,10 @@ bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { } bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { - if (Visit(MakeCursorObjCClassRef(D->getCategoryDecl()->getClassInterface(), - D->getLocation(), TU))) - return true; + // 'ID' could be null when dealing with invalid code. + if (ObjCInterfaceDecl *ID = D->getClassInterface()) + if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) + return true; return VisitObjCImplDecl(D); } diff --git a/clang/tools/CIndex/CIndexUSRs.cpp b/clang/tools/CIndex/CIndexUSRs.cpp index 9dbbd3541e4..8521971a306 100644 --- a/clang/tools/CIndex/CIndexUSRs.cpp +++ b/clang/tools/CIndex/CIndexUSRs.cpp @@ -155,14 +155,30 @@ void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { break; case Decl::ObjCCategory: { ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); - GenObjCCategory(CD->getClassInterface()->getName(), - CD->getName()); + ObjCInterfaceDecl *ID = CD->getClassInterface(); + if (!ID) { + // Handle invalid code where the @interface might not + // have been specified. + // FIXME: We should be able to generate this USR even if the + // @interface isn't available. + IgnoreResults = true; + return; + } + GenObjCCategory(ID->getName(), CD->getName()); break; } case Decl::ObjCCategoryImpl: { ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); - GenObjCCategory(CD->getClassInterface()->getName(), - CD->getName()); + ObjCInterfaceDecl *ID = CD->getClassInterface(); + if (!ID) { + // Handle invalid code where the @interface might not + // have been specified. + // FIXME: We should be able to generate this USR even if the + // @interface isn't available. + IgnoreResults = true; + return; + } + GenObjCCategory(ID->getName(), CD->getName()); break; } case Decl::ObjCProtocol: @@ -251,7 +267,7 @@ CXString clang_getCursorUSR(CXCursor C) { SUG->Visit(static_cast<Decl*>(D)); if (SUG->ignoreResults() || SUG.str().empty()) - return createCXString(NULL); + return createCXString(""); // Return a copy of the string that must be disposed by the caller. return createCXString(SUG.str(), true); diff --git a/clang/tools/CIndex/CXCursor.cpp b/clang/tools/CIndex/CXCursor.cpp index 407f44c70a0..cbf9d7e6f91 100644 --- a/clang/tools/CIndex/CXCursor.cpp +++ b/clang/tools/CIndex/CXCursor.cpp @@ -266,7 +266,10 @@ cxcursor::getCursorObjCProtocolRef(CXCursor C) { CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc, ASTUnit *TU) { - assert(Class && TU && "Invalid arguments!"); + // 'Class' can be null for invalid code. + if (!Class) + return MakeCXCursorInvalid(CXCursor_InvalidCode); + assert(TU && "Invalid arguments!"); void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, TU } }; return C; |