Properly determine the end location of an ObjCObjectPointerType.
authorRichard Smith <richard@metafoo.co.uk>
Fri, 29 Oct 2021 20:12:51 +0000 (13:12 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Fri, 29 Oct 2021 20:15:53 +0000 (13:15 -0700)
After rGa9db0a804a53, we correctly determined the end for pointer types
like `id` that are spelled without a `*`, but incorrectly determined the
end for pointer types spelled with a `*`.

clang/lib/AST/TypeLoc.cpp
clang/test/AST/ast-dump-decl.mm

index 712fcac..c3ed08d 100644 (file)
@@ -240,6 +240,8 @@ SourceLocation TypeLoc::getEndLoc() const {
     case IncompleteArray:
     case VariableArray:
     case FunctionNoProto:
+      // The innermost type with suffix syntax always determines the end of the
+      // type.
       Last = Cur;
       break;
     case FunctionProto:
@@ -248,16 +250,22 @@ SourceLocation TypeLoc::getEndLoc() const {
       else
         Last = Cur;
       break;
+    case ObjCObjectPointer:
+      // `id` and `id<...>` have no star location.
+      if (Cur.castAs<ObjCObjectPointerTypeLoc>().getStarLoc().isInvalid())
+        break;
+      LLVM_FALLTHROUGH;
     case Pointer:
     case BlockPointer:
     case MemberPointer:
     case LValueReference:
     case RValueReference:
     case PackExpansion:
+      // Types with prefix syntax only determine the end of the type if there
+      // is no suffix type.
       if (!Last)
         Last = Cur;
       break;
-    case ObjCObjectPointer:
     case Qualified:
     case Elaborated:
       break;
index 2675672..16ca27e 100644 (file)
@@ -61,5 +61,8 @@ struct Test {
 @protocol P
 @end;
 
-using TestAlias = id<P>;
-// CHECK:      TypeAliasDecl {{.+}} <{{.+}}:[[@LINE-1]]:1, col:23> col:7 TestAlias 'id<P>'
+using TestObjCPointerWithoutStar = id<P>;
+// CHECK:      TypeAliasDecl {{.+}} <{{.+}}:[[@LINE-1]]:1, col:40> col:7 TestObjCPointerWithoutStar 'id<P>'
+
+using TestObjCPointerWithStar = A *;
+// CHECK:      TypeAliasDecl {{.+}} <{{.+}}:[[@LINE-1]]:1, col:35> col:7 TestObjCPointerWithStar 'A *'