diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 712fcac26c95..c3ed08d5a8b3 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -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().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; diff --git a/clang/test/AST/ast-dump-decl.mm b/clang/test/AST/ast-dump-decl.mm index 26756722bfdd..16ca27e3b139 100644 --- a/clang/test/AST/ast-dump-decl.mm +++ b/clang/test/AST/ast-dump-decl.mm @@ -61,5 +61,8 @@ struct Test { @protocol P @end; -using TestAlias = id

; -// CHECK: TypeAliasDecl {{.+}} <{{.+}}:[[@LINE-1]]:1, col:23> col:7 TestAlias 'id

' +using TestObjCPointerWithoutStar = id

; +// CHECK: TypeAliasDecl {{.+}} <{{.+}}:[[@LINE-1]]:1, col:40> col:7 TestObjCPointerWithoutStar 'id

' + +using TestObjCPointerWithStar = A *; +// CHECK: TypeAliasDecl {{.+}} <{{.+}}:[[@LINE-1]]:1, col:35> col:7 TestObjCPointerWithStar 'A *'