summaryrefslogtreecommitdiffstats
path: root/clang/tools/libclang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2015-07-07 03:57:35 +0000
committerDouglas Gregor <dgregor@apple.com>2015-07-07 03:57:35 +0000
commite9d95f1ecc98ced831cace8b4b78cb7cc380f4aa (patch)
tree73962adb18c3f8c191701021f69a14b4121676e6 /clang/tools/libclang
parent85f3f9513dbc88b9898d022a1a55a03d55612721 (diff)
downloadbcm5719-llvm-e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa.tar.gz
bcm5719-llvm-e9d95f1ecc98ced831cace8b4b78cb7cc380f4aa.zip
Handle Objective-C type arguments.
Objective-C type arguments can be provided in angle brackets following an Objective-C interface type. Syntactically, this is the same position as one would provide protocol qualifiers (e.g., id<NSCopying>), so parse both together and let Sema sort out the ambiguous cases. This applies both when parsing types and when parsing the superclass of an Objective-C class, which can now be a specialized type (e.g., NSMutableArray<T> inherits from NSArray<T>). Check Objective-C type arguments against the type parameters of the corresponding class. Verify the length of the type argument list and that each type argument satisfies the corresponding bound. Specializations of parameterized Objective-C classes are represented in the type system as distinct types. Both specialized types (e.g., NSArray<NSString *> *) and unspecialized types (NSArray *) are represented, separately. llvm-svn: 241542
Diffstat (limited to 'clang/tools/libclang')
-rw-r--r--clang/tools/libclang/CIndex.cpp44
-rw-r--r--clang/tools/libclang/CursorVisitor.h1
2 files changed, 44 insertions, 1 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 6c887e18896..a2467ebad4a 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1021,6 +1021,9 @@ bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
TU)))
return true;
+ if (VisitObjCTypeParamList(ND->getTypeParamList()))
+ return true;
+
ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
E = ND->protocol_end(); I != E; ++I, ++PL)
@@ -1080,12 +1083,37 @@ bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
return false;
}
+bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
+ if (!typeParamList)
+ return false;
+
+ for (auto *typeParam : *typeParamList) {
+ // Visit the type parameter.
+ if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
+ return true;
+
+ // Visit the bound, if it's explicit.
+ if (typeParam->hasExplicitBound()) {
+ if (auto TInfo = typeParam->getTypeSourceInfo()) {
+ if (Visit(TInfo->getTypeLoc()))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
if (!D->isThisDeclarationADefinition()) {
// Forward declaration is treated like a reference.
return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
}
+ // Objective-C type parameters.
+ if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
+ return true;
+
// Issue callbacks for super class.
if (D->getSuperClass() &&
Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
@@ -1093,6 +1121,10 @@ bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
TU)))
return true;
+ if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
+ if (Visit(SuperClassTInfo->getTypeLoc()))
+ return true;
+
ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
E = D->protocol_end(); I != E; ++I, ++PL)
@@ -1486,6 +1518,11 @@ bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
return true;
+ for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
+ if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
+ return true;
+ }
+
for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
TU)))
@@ -4411,7 +4448,12 @@ static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
*BestCursor = getTypeRefedCallExprCursor(*BestCursor);
return CXChildVisit_Recurse;
}
-
+
+ // If we already have an Objective-C superclass reference, don't
+ // update it further.
+ if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
+ return CXChildVisit_Break;
+
*BestCursor = cursor;
return CXChildVisit_Recurse;
}
diff --git a/clang/tools/libclang/CursorVisitor.h b/clang/tools/libclang/CursorVisitor.h
index 1b2a922204f..2a0f5205984 100644
--- a/clang/tools/libclang/CursorVisitor.h
+++ b/clang/tools/libclang/CursorVisitor.h
@@ -222,6 +222,7 @@ public:
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
+ bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList);
bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
bool VisitObjCImplDecl(ObjCImplDecl *D);
bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
OpenPOWER on IntegriCloud