https://github.com/ChenMiaoi updated 
https://github.com/llvm/llvm-project/pull/229328

>From d5b5b9d45dd38a6731021bb1c8fa53de043b23be Mon Sep 17 00:00:00 2001
From: Chen Miao <[email protected]>
Date: Tue, 6 Oct 2026 15:15:31 +0800
Subject: [PATCH 1/4] [clang] Preserve ext_vector_type locations during
 template substitution

Instantiating a fixed-length `ext_vector_type` with a dependent element type
could emit an invalid-element diagnostic without a source location.

For example:

```cc
struct S {};

template <typename T> struct Vector {
  typedef T type __attribute__((ext_vector_type(4)));
};

Vector<S> v;
```

Before:

```txt
error: invalid vector element type 'S'
repro.cc:7:11: note: in instantiation of template class 'Vector<S>' requested 
here
    7 | Vector<S> v;
      |           ^
1 error generated.
```

After:

```txt
repro.cc:4:33: error: invalid vector element type 'S'
    4 |   typedef T type __attribute__((ext_vector_type(4)));
      |                                 ^
repro.cc:7:11: note: in instantiation of template class 'Vector<S>' requested 
here
    7 | Vector<S> v;
      |           ^
1 error generated.
```

Record the attribute location in `ExtVectorTypeLoc` and preserve it through
substitution, including when a dependent-sized vector becomes fixed-sized.
Use the original type source information when substituting alias templates,
while retaining the existing path for underlying types adjusted by `mode`.

Fixes #229300
---
 clang/docs/ReleaseNotes.md      |  3 +++
 clang/lib/Sema/SemaTemplate.cpp | 15 ++++++++++++---
 clang/lib/Sema/SemaType.cpp     | 30 ++++++++++++++++++++++++++----
 clang/lib/Sema/TreeTransform.h  |  7 +++----
 clang/test/SemaCXX/vector.cpp   | 31 +++++++++++++++++++++++++++++++
 5 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 7b878a0abbab3..f23217c1d286d 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -631,6 +631,9 @@ features cannot lower the translation-unit ABI level;
 
 #### Bug Fixes to Attribute Support
 
+- Fixed missing source locations for diagnostics when instantiating
+  `ext_vector_type` with a fixed length and a dependent element type. 
(#GH229300)
+
 - Fixed crash (assertion) when the `alloc_align` attribute was applied to a 
declaration whose type has a `FunctionProtoType` but which is not itself a 
`FunctionDecl`, such as a function-pointer variable. (#GH122058)
 
 - Fixed a crash on `bool` vectors declared with `ext_vector_type` and more than
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8e7433bc71281..191fba99f635c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3911,9 +3911,18 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword 
Keyword,
     if (!AliasTemplate->getDeclContext()->isFileContext())
       SavedContext.emplace(*this, AliasTemplate->getDeclContext());
 
-    CanonType =
-        SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
-                  AliasTemplate->getLocation(), AliasTemplate->getDeclName());
+    if (Pattern->isModed()) {
+      // The mode attribute changes the underlying type without updating the
+      // type source information.
+      CanonType =
+          SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
+                    AliasTemplate->getLocation(), 
AliasTemplate->getDeclName());
+    } else {
+      TypeSourceInfo *SubstTypeInfo =
+          SubstType(Pattern->getTypeSourceInfo(), TemplateArgLists,
+                    AliasTemplate->getLocation(), 
AliasTemplate->getDeclName());
+      CanonType = SubstTypeInfo ? SubstTypeInfo->getType() : QualType();
+    }
     if (CanonType.isNull()) {
       // If this was enable_if and we failed to find the nested type
       // within enable_if in a SFINAE context, dig out the specific
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index e1481b437df9e..9608c367eccf5 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -216,6 +216,9 @@ namespace {
     /// stored in a MacroQualifiedTypeLoc.
     llvm::DenseMap<const MacroQualifiedType *, SourceLocation> LocsForMacros;
 
+    /// Locations of ext_vector_type attributes for fixed-size vectors.
+    llvm::DenseMap<const ExtVectorType *, SourceLocation> LocsForExtVectors;
+
     /// Flag to indicate we parsed a noderef attribute. This is used for
     /// validating that noderef was used on a pointer or array.
     bool parsedNoDeref;
@@ -363,6 +366,15 @@ namespace {
       LocsForMacros[MQT] = Loc;
     }
 
+    SourceLocation getAttrLocForExtVectorType(const ExtVectorType *T) const {
+      return LocsForExtVectors.lookup(T);
+    }
+
+    void setAttrLocForExtVectorType(const ExtVectorType *T,
+                                    SourceLocation Loc) {
+      LocsForExtVectors[T] = Loc;
+    }
+
     void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; }
 
     bool didParseNoDeref() const { return parsedNoDeref; }
@@ -6011,6 +6023,10 @@ namespace {
     // Allow to fill pointee's type locations, e.g.,
     //   int __attr * __attr * __attr *p;
     void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); }
+    void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
+      TL.setNameLoc(State.getAttrLocForExtVectorType(TL.getTypePtr()));
+      Visit(TL.getElementLoc());
+    }
     void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
       if (DS.getTypeSpecType() == TST_typename) {
         TypeSourceInfo *TInfo = nullptr;
@@ -6354,7 +6370,9 @@ namespace {
       TL.setNameLoc(Chunk.Loc);
     }
     void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-      TL.setNameLoc(Chunk.Loc);
+      SourceLocation AttrLoc =
+          State.getAttrLocForExtVectorType(TL.getTypePtr());
+      TL.setNameLoc(AttrLoc.isValid() ? AttrLoc : Chunk.Loc);
     }
     void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
       fillAtomicQualLoc(TL, Chunk);
@@ -8552,7 +8570,8 @@ static void HandleVectorSizeAttr(QualType &CurType, const 
ParsedAttr &Attr,
 /// Process the OpenCL-like ext_vector_type attribute when it occurs on
 /// a type.
 static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
-                                    Sema &S) {
+                                    TypeProcessingState &State) {
+  Sema &S = State.getSema();
   // check the attribute arguments.
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
@@ -8562,8 +8581,11 @@ static void HandleExtVectorTypeAttr(QualType &CurType, 
const ParsedAttr &Attr,
 
   Expr *SizeExpr = Attr.getArgAsExpr(0);
   QualType T = S.BuildExtVectorType(CurType, SizeExpr, Attr.getLoc());
-  if (!T.isNull())
+  if (!T.isNull()) {
     CurType = T;
+    if (const auto *VT = dyn_cast<ExtVectorType>(T.getTypePtr()))
+      State.setAttrLocForExtVectorType(VT, Attr.getLoc());
+  }
 }
 
 static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) 
{
@@ -9211,7 +9233,7 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
       attr.setUsedAsTypeAttr();
       break;
     case ParsedAttr::AT_ExtVectorType:
-      HandleExtVectorTypeAttr(type, attr, state.getSema());
+      HandleExtVectorTypeAttr(type, attr, state);
       attr.setUsedAsTypeAttr();
       break;
     case ParsedAttr::AT_NeonVectorType:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 73367d6bea063..845c3ac32f336 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6280,7 +6280,7 @@ QualType 
TreeTransform<Derived>::TransformDependentSizedExtVectorType(
     NewTL.setNameLoc(TL.getNameLoc());
   } else {
     ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
-    NewTL.setNameLoc(TL.getNameLoc());
+    NewTL.setNameLoc(T->getAttributeLoc());
   }
 
   return Result;
@@ -6445,9 +6445,8 @@ QualType 
TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       ElementType != T->getElementType()) {
-    Result = getDerived().RebuildExtVectorType(ElementType,
-                                               T->getNumElements(),
-                                               /*FIXME*/ SourceLocation());
+    Result = getDerived().RebuildExtVectorType(ElementType, 
T->getNumElements(),
+                                               TL.getNameLoc());
     if (Result.isNull())
       return QualType();
   }
diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp
index 581d829560ea6..0bbec3e661104 100644
--- a/clang/test/SemaCXX/vector.cpp
+++ b/clang/test/SemaCXX/vector.cpp
@@ -5,6 +5,7 @@
 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 
-fsyntax-only -verify -std=c++20 %s
 // RUN: %clang_cc1 -flax-vector-conversions=integer -triple 
x86_64-apple-darwin10 -fsyntax-only -verify %s -DNO_LAX_FLOAT
 // RUN: %clang_cc1 -flax-vector-conversions=none -triple x86_64-apple-darwin10 
-fsyntax-only -verify %s -DNO_LAX_FLOAT -DNO_LAX_INT
+// RUN: not %clang_cc1 -flax-vector-conversions=all -triple 
x86_64-apple-darwin10 -fsyntax-only -ferror-limit 0 %s 2>&1 | FileCheck %s 
--check-prefix=LOCATION
 
 typedef char char16 __attribute__ ((__vector_size__ (16)));
 typedef long long longlong16 __attribute__ ((__vector_size__ (16)));
@@ -337,6 +338,36 @@ const int &reference_to_vec_element = vi4(1).x;
 typedef bool bad __attribute__((__vector_size__(16)));  // expected-error 
{{invalid vector element type 'bool'}}
 
 namespace Templates {
+struct InvalidElement {};
+
+template <typename T> struct GH229300 {
+  // LOCATION: vector.cpp:[[@LINE+1]]:33: error: invalid vector element type 
'Templates::InvalidElement'
+  typedef T type __attribute__((ext_vector_type(4))); // expected-error 
{{invalid vector element type 'Templates::InvalidElement'}}
+};
+GH229300<InvalidElement> invalid_vector; // expected-note {{in instantiation 
of template class 'Templates::GH229300<Templates::InvalidElement>' requested 
here}}
+
+template <typename T> struct GH229300Paren {
+  typedef T
+    (type)
+    // LOCATION: vector.cpp:[[@LINE+1]]:20: error: invalid vector element type 
'Templates::InvalidElement'
+    __attribute__((ext_vector_type(4))); // expected-error {{invalid vector 
element type 'Templates::InvalidElement'}}
+};
+GH229300Paren<InvalidElement> invalid_paren_vector; // expected-note {{in 
instantiation of template class 
'Templates::GH229300Paren<Templates::InvalidElement>' requested here}}
+
+#if __cplusplus >= 201103L
+template <typename T> using GH229300Alias =
+  // LOCATION: vector.cpp:[[@LINE+1]]:20: error: invalid vector element type 
'InvalidElement'
+  T __attribute__((ext_vector_type(4))); // expected-error {{invalid vector 
element type 'InvalidElement'}}
+GH229300Alias<InvalidElement> invalid_alias_vector; // expected-note {{in 
instantiation of template type alias 'GH229300Alias' requested here}}
+
+template <int N> struct GH229300DependentSize {
+  template <typename T> using type =
+    // LOCATION: vector.cpp:[[@LINE+1]]:22: error: invalid vector element type 
'InvalidElement'
+    T __attribute__((ext_vector_type(N))); // expected-error {{invalid vector 
element type 'InvalidElement'}}
+};
+GH229300DependentSize<4>::type<InvalidElement> invalid_dependent_vector; // 
expected-note {{in instantiation of template type alias 'type' requested here}}
+#endif
+
 template <typename Elt, unsigned long long Size>
 struct TemplateVectorType {
   typedef Elt __attribute__((__vector_size__(Size))) type; // #1

>From 275329259592bfa7ba82ed649da31184fc29f207 Mon Sep 17 00:00:00 2001
From: Chen Miao <[email protected]>
Date: Tue, 6 Oct 2026 15:15:31 +0800
Subject: [PATCH 2/4] [clang] Preserve ext_vector_type locations during
 template substitution

Instantiating a fixed-length `ext_vector_type` with a dependent element type
could emit an invalid-element diagnostic without a source location.

For example:

```cc
struct S {};

template <typename T> struct Vector {
  typedef T type __attribute__((ext_vector_type(4)));
};

Vector<S> v;
```

Before:

```txt
error: invalid vector element type 'S'
repro.cc:7:11: note: in instantiation of template class 'Vector<S>' requested 
here
    7 | Vector<S> v;
      |           ^
1 error generated.
```

After:

```txt
repro.cc:4:33: error: invalid vector element type 'S'
    4 |   typedef T type __attribute__((ext_vector_type(4)));
      |                                 ^
repro.cc:7:11: note: in instantiation of template class 'Vector<S>' requested 
here
    7 | Vector<S> v;
      |           ^
1 error generated.
```

Record the attribute location in `ExtVectorTypeLoc` and preserve it through
substitution, including when a dependent-sized vector becomes fixed-sized.
Use the original type source information when substituting alias templates,
while retaining the existing path for underlying types adjusted by `mode`.

Fixes #229300
---
 clang/docs/ReleaseNotes.md      |  3 +++
 clang/lib/Sema/SemaTemplate.cpp | 15 ++++++++++++---
 clang/lib/Sema/SemaType.cpp     | 30 ++++++++++++++++++++++++++----
 clang/lib/Sema/TreeTransform.h  |  7 +++----
 clang/test/SemaCXX/vector.cpp   | 31 +++++++++++++++++++++++++++++++
 5 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 0aa17906efeb7..0bb17b28e78da 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -638,6 +638,9 @@ features cannot lower the translation-unit ABI level;
 
 #### Bug Fixes to Attribute Support
 
+- Fixed missing source locations for diagnostics when instantiating
+  `ext_vector_type` with a fixed length and a dependent element type. 
(#GH229300)
+
 - Fixed crash (assertion) when the `alloc_align` attribute was applied to a 
declaration whose type has a `FunctionProtoType` but which is not itself a 
`FunctionDecl`, such as a function-pointer variable. (#GH122058)
 
 - Fixed a crash on `bool` vectors declared with `ext_vector_type` and more than
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8e7433bc71281..191fba99f635c 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3911,9 +3911,18 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword 
Keyword,
     if (!AliasTemplate->getDeclContext()->isFileContext())
       SavedContext.emplace(*this, AliasTemplate->getDeclContext());
 
-    CanonType =
-        SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
-                  AliasTemplate->getLocation(), AliasTemplate->getDeclName());
+    if (Pattern->isModed()) {
+      // The mode attribute changes the underlying type without updating the
+      // type source information.
+      CanonType =
+          SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
+                    AliasTemplate->getLocation(), 
AliasTemplate->getDeclName());
+    } else {
+      TypeSourceInfo *SubstTypeInfo =
+          SubstType(Pattern->getTypeSourceInfo(), TemplateArgLists,
+                    AliasTemplate->getLocation(), 
AliasTemplate->getDeclName());
+      CanonType = SubstTypeInfo ? SubstTypeInfo->getType() : QualType();
+    }
     if (CanonType.isNull()) {
       // If this was enable_if and we failed to find the nested type
       // within enable_if in a SFINAE context, dig out the specific
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 202bd486321f9..c09295b4562a4 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -216,6 +216,9 @@ namespace {
     /// stored in a MacroQualifiedTypeLoc.
     llvm::DenseMap<const MacroQualifiedType *, SourceLocation> LocsForMacros;
 
+    /// Locations of ext_vector_type attributes for fixed-size vectors.
+    llvm::DenseMap<const ExtVectorType *, SourceLocation> LocsForExtVectors;
+
     /// Flag to indicate we parsed a noderef attribute. This is used for
     /// validating that noderef was used on a pointer or array.
     bool parsedNoDeref;
@@ -363,6 +366,15 @@ namespace {
       LocsForMacros[MQT] = Loc;
     }
 
+    SourceLocation getAttrLocForExtVectorType(const ExtVectorType *T) const {
+      return LocsForExtVectors.lookup(T);
+    }
+
+    void setAttrLocForExtVectorType(const ExtVectorType *T,
+                                    SourceLocation Loc) {
+      LocsForExtVectors[T] = Loc;
+    }
+
     void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; }
 
     bool didParseNoDeref() const { return parsedNoDeref; }
@@ -6011,6 +6023,10 @@ namespace {
     // Allow to fill pointee's type locations, e.g.,
     //   int __attr * __attr * __attr *p;
     void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); }
+    void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
+      TL.setNameLoc(State.getAttrLocForExtVectorType(TL.getTypePtr()));
+      Visit(TL.getElementLoc());
+    }
     void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
       if (DS.getTypeSpecType() == TST_typename) {
         TypeSourceInfo *TInfo = nullptr;
@@ -6354,7 +6370,9 @@ namespace {
       TL.setNameLoc(Chunk.Loc);
     }
     void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-      TL.setNameLoc(Chunk.Loc);
+      SourceLocation AttrLoc =
+          State.getAttrLocForExtVectorType(TL.getTypePtr());
+      TL.setNameLoc(AttrLoc.isValid() ? AttrLoc : Chunk.Loc);
     }
     void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
       fillAtomicQualLoc(TL, Chunk);
@@ -8552,7 +8570,8 @@ static void HandleVectorSizeAttr(QualType &CurType, const 
ParsedAttr &Attr,
 /// Process the OpenCL-like ext_vector_type attribute when it occurs on
 /// a type.
 static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
-                                    Sema &S) {
+                                    TypeProcessingState &State) {
+  Sema &S = State.getSema();
   // check the attribute arguments.
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
@@ -8562,8 +8581,11 @@ static void HandleExtVectorTypeAttr(QualType &CurType, 
const ParsedAttr &Attr,
 
   Expr *SizeExpr = Attr.getArgAsExpr(0);
   QualType T = S.BuildExtVectorType(CurType, SizeExpr, Attr.getLoc());
-  if (!T.isNull())
+  if (!T.isNull()) {
     CurType = T;
+    if (const auto *VT = dyn_cast<ExtVectorType>(T.getTypePtr()))
+      State.setAttrLocForExtVectorType(VT, Attr.getLoc());
+  }
 }
 
 static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) 
{
@@ -9211,7 +9233,7 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
       attr.setUsedAsTypeAttr();
       break;
     case ParsedAttr::AT_ExtVectorType:
-      HandleExtVectorTypeAttr(type, attr, state.getSema());
+      HandleExtVectorTypeAttr(type, attr, state);
       attr.setUsedAsTypeAttr();
       break;
     case ParsedAttr::AT_NeonVectorType:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 73367d6bea063..845c3ac32f336 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6280,7 +6280,7 @@ QualType 
TreeTransform<Derived>::TransformDependentSizedExtVectorType(
     NewTL.setNameLoc(TL.getNameLoc());
   } else {
     ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
-    NewTL.setNameLoc(TL.getNameLoc());
+    NewTL.setNameLoc(T->getAttributeLoc());
   }
 
   return Result;
@@ -6445,9 +6445,8 @@ QualType 
TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       ElementType != T->getElementType()) {
-    Result = getDerived().RebuildExtVectorType(ElementType,
-                                               T->getNumElements(),
-                                               /*FIXME*/ SourceLocation());
+    Result = getDerived().RebuildExtVectorType(ElementType, 
T->getNumElements(),
+                                               TL.getNameLoc());
     if (Result.isNull())
       return QualType();
   }
diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp
index fd6127a33f1ae..0694f6bb4f0c1 100644
--- a/clang/test/SemaCXX/vector.cpp
+++ b/clang/test/SemaCXX/vector.cpp
@@ -5,6 +5,7 @@
 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 
-fsyntax-only -verify -std=c++20 %s
 // RUN: %clang_cc1 -flax-vector-conversions=integer -triple 
x86_64-apple-darwin10 -fsyntax-only -verify %s -DNO_LAX_FLOAT
 // RUN: %clang_cc1 -flax-vector-conversions=none -triple x86_64-apple-darwin10 
-fsyntax-only -verify %s -DNO_LAX_FLOAT -DNO_LAX_INT
+// RUN: not %clang_cc1 -flax-vector-conversions=all -triple 
x86_64-apple-darwin10 -fsyntax-only -ferror-limit 0 %s 2>&1 | FileCheck %s 
--check-prefix=LOCATION
 
 typedef char char16 __attribute__ ((__vector_size__ (16)));
 typedef long long longlong16 __attribute__ ((__vector_size__ (16)));
@@ -354,6 +355,36 @@ Vector<int> int_vector;
 } // namespace GH225037
 
 namespace Templates {
+struct InvalidElement {};
+
+template <typename T> struct GH229300 {
+  // LOCATION: vector.cpp:[[@LINE+1]]:33: error: invalid vector element type 
'Templates::InvalidElement'
+  typedef T type __attribute__((ext_vector_type(4))); // expected-error 
{{invalid vector element type 'Templates::InvalidElement'}}
+};
+GH229300<InvalidElement> invalid_vector; // expected-note {{in instantiation 
of template class 'Templates::GH229300<Templates::InvalidElement>' requested 
here}}
+
+template <typename T> struct GH229300Paren {
+  typedef T
+    (type)
+    // LOCATION: vector.cpp:[[@LINE+1]]:20: error: invalid vector element type 
'Templates::InvalidElement'
+    __attribute__((ext_vector_type(4))); // expected-error {{invalid vector 
element type 'Templates::InvalidElement'}}
+};
+GH229300Paren<InvalidElement> invalid_paren_vector; // expected-note {{in 
instantiation of template class 
'Templates::GH229300Paren<Templates::InvalidElement>' requested here}}
+
+#if __cplusplus >= 201103L
+template <typename T> using GH229300Alias =
+  // LOCATION: vector.cpp:[[@LINE+1]]:20: error: invalid vector element type 
'InvalidElement'
+  T __attribute__((ext_vector_type(4))); // expected-error {{invalid vector 
element type 'InvalidElement'}}
+GH229300Alias<InvalidElement> invalid_alias_vector; // expected-note {{in 
instantiation of template type alias 'GH229300Alias' requested here}}
+
+template <int N> struct GH229300DependentSize {
+  template <typename T> using type =
+    // LOCATION: vector.cpp:[[@LINE+1]]:22: error: invalid vector element type 
'InvalidElement'
+    T __attribute__((ext_vector_type(N))); // expected-error {{invalid vector 
element type 'InvalidElement'}}
+};
+GH229300DependentSize<4>::type<InvalidElement> invalid_dependent_vector; // 
expected-note {{in instantiation of template type alias 'type' requested here}}
+#endif
+
 template <typename Elt, unsigned long long Size>
 struct TemplateVectorType {
   typedef Elt __attribute__((__vector_size__(Size))) type; // #1

>From 000617ce86050f31945c91562e8da21c5abdb71e Mon Sep 17 00:00:00 2001
From: Chen Miao <[email protected]>
Date: Sat, 10 Oct 2026 10:07:17 +0800
Subject: [PATCH 3/4] [clang] Withdraw previous ext_vector_type location fix

---
 clang/docs/ReleaseNotes.md      |  3 ---
 clang/lib/Sema/SemaTemplate.cpp | 15 +++------------
 clang/lib/Sema/SemaType.cpp     | 30 ++++--------------------------
 clang/lib/Sema/TreeTransform.h  |  7 ++++---
 clang/test/SemaCXX/vector.cpp   | 31 -------------------------------
 5 files changed, 11 insertions(+), 75 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 5ec6a5e8c3b1e..78c4f585b56b9 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -696,9 +696,6 @@ features cannot lower the translation-unit ABI level;
 
 #### Bug Fixes to Attribute Support
 
-- Fixed missing source locations for diagnostics when instantiating
-  `ext_vector_type` with a fixed length and a dependent element type. 
(#GH229300)
-
 - Fixed an assertion failure when parsing malformed GNU `__attribute__`
   syntax followed by a parenthesized expression list in C code. (#GH225045)
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 191fba99f635c..8e7433bc71281 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3911,18 +3911,9 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword 
Keyword,
     if (!AliasTemplate->getDeclContext()->isFileContext())
       SavedContext.emplace(*this, AliasTemplate->getDeclContext());
 
-    if (Pattern->isModed()) {
-      // The mode attribute changes the underlying type without updating the
-      // type source information.
-      CanonType =
-          SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
-                    AliasTemplate->getLocation(), 
AliasTemplate->getDeclName());
-    } else {
-      TypeSourceInfo *SubstTypeInfo =
-          SubstType(Pattern->getTypeSourceInfo(), TemplateArgLists,
-                    AliasTemplate->getLocation(), 
AliasTemplate->getDeclName());
-      CanonType = SubstTypeInfo ? SubstTypeInfo->getType() : QualType();
-    }
+    CanonType =
+        SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
+                  AliasTemplate->getLocation(), AliasTemplate->getDeclName());
     if (CanonType.isNull()) {
       // If this was enable_if and we failed to find the nested type
       // within enable_if in a SFINAE context, dig out the specific
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 30b09f163fe65..1cb96b556971a 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -216,9 +216,6 @@ namespace {
     /// stored in a MacroQualifiedTypeLoc.
     llvm::DenseMap<const MacroQualifiedType *, SourceLocation> LocsForMacros;
 
-    /// Locations of ext_vector_type attributes for fixed-size vectors.
-    llvm::DenseMap<const ExtVectorType *, SourceLocation> LocsForExtVectors;
-
     /// Flag to indicate we parsed a noderef attribute. This is used for
     /// validating that noderef was used on a pointer or array.
     bool parsedNoDeref;
@@ -366,15 +363,6 @@ namespace {
       LocsForMacros[MQT] = Loc;
     }
 
-    SourceLocation getAttrLocForExtVectorType(const ExtVectorType *T) const {
-      return LocsForExtVectors.lookup(T);
-    }
-
-    void setAttrLocForExtVectorType(const ExtVectorType *T,
-                                    SourceLocation Loc) {
-      LocsForExtVectors[T] = Loc;
-    }
-
     void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; }
 
     bool didParseNoDeref() const { return parsedNoDeref; }
@@ -6032,10 +6020,6 @@ namespace {
     // Allow to fill pointee's type locations, e.g.,
     //   int __attr * __attr * __attr *p;
     void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); }
-    void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-      TL.setNameLoc(State.getAttrLocForExtVectorType(TL.getTypePtr()));
-      Visit(TL.getElementLoc());
-    }
     void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
       if (DS.getTypeSpecType() == TST_typename) {
         TypeSourceInfo *TInfo = nullptr;
@@ -6379,9 +6363,7 @@ namespace {
       TL.setNameLoc(Chunk.Loc);
     }
     void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-      SourceLocation AttrLoc =
-          State.getAttrLocForExtVectorType(TL.getTypePtr());
-      TL.setNameLoc(AttrLoc.isValid() ? AttrLoc : Chunk.Loc);
+      TL.setNameLoc(Chunk.Loc);
     }
     void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
       fillAtomicQualLoc(TL, Chunk);
@@ -8579,8 +8561,7 @@ static void HandleVectorSizeAttr(QualType &CurType, const 
ParsedAttr &Attr,
 /// Process the OpenCL-like ext_vector_type attribute when it occurs on
 /// a type.
 static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
-                                    TypeProcessingState &State) {
-  Sema &S = State.getSema();
+                                    Sema &S) {
   // check the attribute arguments.
   if (Attr.getNumArgs() != 1) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
@@ -8590,11 +8571,8 @@ static void HandleExtVectorTypeAttr(QualType &CurType, 
const ParsedAttr &Attr,
 
   Expr *SizeExpr = Attr.getArgAsExpr(0);
   QualType T = S.BuildExtVectorType(CurType, SizeExpr, Attr.getLoc());
-  if (!T.isNull()) {
+  if (!T.isNull())
     CurType = T;
-    if (const auto *VT = dyn_cast<ExtVectorType>(T.getTypePtr()))
-      State.setAttrLocForExtVectorType(VT, Attr.getLoc());
-  }
 }
 
 static bool isPermittedNeonBaseType(QualType &Ty, VectorKind VecKind, Sema &S) 
{
@@ -9242,7 +9220,7 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
       attr.setUsedAsTypeAttr();
       break;
     case ParsedAttr::AT_ExtVectorType:
-      HandleExtVectorTypeAttr(type, attr, state);
+      HandleExtVectorTypeAttr(type, attr, state.getSema());
       attr.setUsedAsTypeAttr();
       break;
     case ParsedAttr::AT_NeonVectorType:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 845c3ac32f336..73367d6bea063 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6280,7 +6280,7 @@ QualType 
TreeTransform<Derived>::TransformDependentSizedExtVectorType(
     NewTL.setNameLoc(TL.getNameLoc());
   } else {
     ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
-    NewTL.setNameLoc(T->getAttributeLoc());
+    NewTL.setNameLoc(TL.getNameLoc());
   }
 
   return Result;
@@ -6445,8 +6445,9 @@ QualType 
TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       ElementType != T->getElementType()) {
-    Result = getDerived().RebuildExtVectorType(ElementType, 
T->getNumElements(),
-                                               TL.getNameLoc());
+    Result = getDerived().RebuildExtVectorType(ElementType,
+                                               T->getNumElements(),
+                                               /*FIXME*/ SourceLocation());
     if (Result.isNull())
       return QualType();
   }
diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp
index 0694f6bb4f0c1..fd6127a33f1ae 100644
--- a/clang/test/SemaCXX/vector.cpp
+++ b/clang/test/SemaCXX/vector.cpp
@@ -5,7 +5,6 @@
 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 
-fsyntax-only -verify -std=c++20 %s
 // RUN: %clang_cc1 -flax-vector-conversions=integer -triple 
x86_64-apple-darwin10 -fsyntax-only -verify %s -DNO_LAX_FLOAT
 // RUN: %clang_cc1 -flax-vector-conversions=none -triple x86_64-apple-darwin10 
-fsyntax-only -verify %s -DNO_LAX_FLOAT -DNO_LAX_INT
-// RUN: not %clang_cc1 -flax-vector-conversions=all -triple 
x86_64-apple-darwin10 -fsyntax-only -ferror-limit 0 %s 2>&1 | FileCheck %s 
--check-prefix=LOCATION
 
 typedef char char16 __attribute__ ((__vector_size__ (16)));
 typedef long long longlong16 __attribute__ ((__vector_size__ (16)));
@@ -355,36 +354,6 @@ Vector<int> int_vector;
 } // namespace GH225037
 
 namespace Templates {
-struct InvalidElement {};
-
-template <typename T> struct GH229300 {
-  // LOCATION: vector.cpp:[[@LINE+1]]:33: error: invalid vector element type 
'Templates::InvalidElement'
-  typedef T type __attribute__((ext_vector_type(4))); // expected-error 
{{invalid vector element type 'Templates::InvalidElement'}}
-};
-GH229300<InvalidElement> invalid_vector; // expected-note {{in instantiation 
of template class 'Templates::GH229300<Templates::InvalidElement>' requested 
here}}
-
-template <typename T> struct GH229300Paren {
-  typedef T
-    (type)
-    // LOCATION: vector.cpp:[[@LINE+1]]:20: error: invalid vector element type 
'Templates::InvalidElement'
-    __attribute__((ext_vector_type(4))); // expected-error {{invalid vector 
element type 'Templates::InvalidElement'}}
-};
-GH229300Paren<InvalidElement> invalid_paren_vector; // expected-note {{in 
instantiation of template class 
'Templates::GH229300Paren<Templates::InvalidElement>' requested here}}
-
-#if __cplusplus >= 201103L
-template <typename T> using GH229300Alias =
-  // LOCATION: vector.cpp:[[@LINE+1]]:20: error: invalid vector element type 
'InvalidElement'
-  T __attribute__((ext_vector_type(4))); // expected-error {{invalid vector 
element type 'InvalidElement'}}
-GH229300Alias<InvalidElement> invalid_alias_vector; // expected-note {{in 
instantiation of template type alias 'GH229300Alias' requested here}}
-
-template <int N> struct GH229300DependentSize {
-  template <typename T> using type =
-    // LOCATION: vector.cpp:[[@LINE+1]]:22: error: invalid vector element type 
'InvalidElement'
-    T __attribute__((ext_vector_type(N))); // expected-error {{invalid vector 
element type 'InvalidElement'}}
-};
-GH229300DependentSize<4>::type<InvalidElement> invalid_dependent_vector; // 
expected-note {{in instantiation of template type alias 'type' requested here}}
-#endif
-
 template <typename Elt, unsigned long long Size>
 struct TemplateVectorType {
   typedef Elt __attribute__((__vector_size__(Size))) type; // #1

>From d8c75d6276fe2ff4421418efac73a8d846ca30ea Mon Sep 17 00:00:00 2001
From: Chen Miao <[email protected]>
Date: Sun, 11 Oct 2026 01:32:34 +0800
Subject: [PATCH 4/4] [clang] Preserve vector type source information for
 diagnostics

---
 clang/docs/ReleaseNotes.md                    |  3 +
 clang/include/clang/AST/ASTNodeTraverser.h    | 11 ++-
 clang/include/clang/AST/RecursiveASTVisitor.h | 15 ++--
 clang/include/clang/AST/TypeLoc.h             | 73 +++++++++++++++++--
 clang/lib/Sema/SemaTemplate.cpp               |  2 +
 clang/lib/Sema/SemaType.cpp                   | 32 ++++++--
 clang/lib/Sema/TreeTransform.h                | 40 ++++++----
 clang/lib/Serialization/ASTReader.cpp         |  8 +-
 clang/lib/Serialization/ASTWriter.cpp         |  8 +-
 .../PCH/cxx-dependent-sized-ext-vector.cpp    | 23 +++++-
 clang/test/SemaCXX/vector.cpp                 |  6 +-
 clang/test/SemaTemplate/ext-vector-type.cpp   | 30 +++++++-
 clang/unittests/AST/SourceLocationTest.cpp    | 29 ++++++++
 13 files changed, 241 insertions(+), 39 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 78c4f585b56b9..df0c03ae8b849 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -347,6 +347,9 @@ features cannot lower the translation-unit ABI level;
 
 ### Improvements to Clang's diagnostics
 
+- Errors for invalid element types during instantiation of an `ext_vector_type`
+  now include a source location, including in alias templates. (#GH229300)
+
 - Fixed spurious `-Wimplicit-void-ptr-cast` warnings in C for parenthesized
   null pointer macros such as `(NULL)`. (#GH171874)
 
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index 8e09c49982e5d..c287c100fab88 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -525,7 +525,16 @@ class ASTNodeTraverser
     Visit(TL.getSizeExpr());
   }
   void VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
-    Visit(cast<DependentSizedExtVectorType>(TL.getType())->getSizeExpr());
+    Expr *Size = TL.getSizeExpr();
+    Visit(Size ? Size : TL.getTypePtr()->getSizeExpr());
+  }
+  void VisitVectorTypeLoc(VectorTypeLoc TL) {
+    if (Expr *Size = TL.getSizeExpr())
+      Visit(Size);
+  }
+  void VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
+    Expr *Size = TL.getSizeExpr();
+    Visit(Size ? Size : TL.getTypePtr()->getSizeExpr());
   }
   void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
     Visit(TL.getUnderlyingExpr());
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index f144c890f6ee6..02137e8101969 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1381,25 +1381,30 @@ DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
 // FIXME: order? why not size expr first?
 // FIXME: base VectorTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
-  if (TL.getTypePtr()->getSizeExpr())
-    TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+  Expr *Size = TL.getSizeExpr();
+  if (!Size)
+    Size = TL.getTypePtr()->getSizeExpr();
+  TRY_TO(TraverseStmt(Size));
   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
 })
 
 // FIXME: VectorTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(VectorType, {
+  TRY_TO(TraverseStmt(TL.getSizeExpr()));
   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
 })
 
 DEF_TRAVERSE_TYPELOC(DependentVectorType, {
-  if (TL.getTypePtr()->getSizeExpr())
-    TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+  Expr *Size = TL.getSizeExpr();
+  if (!Size)
+    Size = TL.getTypePtr()->getSizeExpr();
+  TRY_TO(TraverseStmt(Size));
   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
 })
 
-// FIXME: size and attributes
 // FIXME: base VectorTypeLoc is unfinished
 DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+  TRY_TO(TraverseStmt(TL.getSizeExpr()));
   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
 })
 
diff --git a/clang/include/clang/AST/TypeLoc.h 
b/clang/include/clang/AST/TypeLoc.h
index b3cb4d0f33629..d19b91a62e572 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -2062,25 +2062,52 @@ class DependentAddressSpaceTypeLoc
 //
 
//===----------------------------------------------------------------------===//
 
-// FIXME: size expression and attribute locations (or keyword if we
-// ever fully support altivec syntax).
+// FIXME: keyword location if we ever fully support altivec syntax.
 struct VectorTypeLocInfo {
   SourceLocation NameLoc;
+  SourceLocation AttrLoc;
+  Expr *SizeExpr;
 };
 
+// FIXME: Make VectorTypeLoc a common base for fixed-size and dependent vector
+// type locations, similar to MatrixTypeLoc.
 class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
                                              VectorType, VectorTypeLocInfo> {
 public:
+  /// The location used for the vector type's local source range, e.g.
+  ///    int __attribute__((vector_size(16)))
+  ///    ^~~
+  ///    int __attribute__((ext_vector_type(4)))
+  ///    ^~~
   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
-
   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
 
+  /// The location of the attribute name, i.e.
+  ///    int __attribute__((vector_size(16)))
+  ///                       ^~~~~~~~~~~
+  ///    int __attribute__((ext_vector_type(4)))
+  ///                       ^~~~~~~~~~~~~~~
+  SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
+  void setAttrNameLoc(SourceLocation Loc) { getLocalData()->AttrLoc = Loc; }
+
+  /// The attribute's size operand, if it has one.
+  ///    int __attribute__((vector_size(16)))
+  ///                                   ^~
+  ///    int __attribute__((ext_vector_type(4)))
+  ///                                       ^
+  ///
+  /// The size is in bytes for vector_size and in elements for ext_vector_type.
+  Expr *getSizeExpr() const { return getLocalData()->SizeExpr; }
+  void setSizeExpr(Expr *E) { getLocalData()->SizeExpr = E; }
+
   SourceRange getLocalSourceRange() const {
     return SourceRange(getNameLoc(), getNameLoc());
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
     setNameLoc(Loc);
+    setAttrNameLoc(Loc);
+    setSizeExpr(nullptr);
   }
 
   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
@@ -2088,22 +2115,37 @@ class VectorTypeLoc : public 
ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
   QualType getInnerType() const { return this->getTypePtr()->getElementType(); 
}
 };
 
-// FIXME: size expression and attribute locations (or keyword if we
-// ever fully support altivec syntax).
 class DependentVectorTypeLoc
     : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc,
                              DependentVectorType, VectorTypeLocInfo> {
 public:
-  SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
 
+  /// The location used for the vector type's local source range, e.g.
+  ///    T __attribute__((vector_size(N)))
+  ///    ^
+  SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
 
+  /// The location of the attribute name, i.e.
+  ///    T __attribute__((vector_size(N)))
+  ///                     ^~~~~~~~~~~
+  SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
+  void setAttrNameLoc(SourceLocation Loc) { getLocalData()->AttrLoc = Loc; }
+
+  /// The attribute's size operand in bytes, if it has one.
+  ///    T __attribute__((vector_size(N)))
+  ///                                 ^
+  Expr *getSizeExpr() const { return getLocalData()->SizeExpr; }
+  void setSizeExpr(Expr *E) { getLocalData()->SizeExpr = E; }
+
   SourceRange getLocalSourceRange() const {
     return SourceRange(getNameLoc(), getNameLoc());
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
     setNameLoc(Loc);
+    setAttrNameLoc(Loc);
+    setSizeExpr(nullptr);
   }
 
   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
@@ -2111,27 +2153,42 @@ class DependentVectorTypeLoc
   QualType getInnerType() const { return this->getTypePtr()->getElementType(); 
}
 };
 
-// FIXME: size expression and attribute locations.
 class ExtVectorTypeLoc
     : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc,
                                        ExtVectorType> {};
 
-// FIXME: attribute locations.
 // For some reason, this isn't a subtype of VectorType.
 class DependentSizedExtVectorTypeLoc
     : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc,
                              DependentSizedExtVectorType, VectorTypeLocInfo> {
 public:
+  /// The location used for the vector type's local source range, e.g.
+  ///    T __attribute__((ext_vector_type(N)))
+  ///    ^
   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
 
   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
 
+  /// The location of the attribute name, i.e.
+  ///    T __attribute__((ext_vector_type(N)))
+  ///                     ^~~~~~~~~~~~~~~
+  SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
+  void setAttrNameLoc(SourceLocation Loc) { getLocalData()->AttrLoc = Loc; }
+
+  /// The attribute's size operand in elements, if it has one.
+  ///    T __attribute__((ext_vector_type(N)))
+  ///                                     ^
+  Expr *getSizeExpr() const { return getLocalData()->SizeExpr; }
+  void setSizeExpr(Expr *E) { getLocalData()->SizeExpr = E; }
+
   SourceRange getLocalSourceRange() const {
     return SourceRange(getNameLoc(), getNameLoc());
   }
 
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
     setNameLoc(Loc);
+    setAttrNameLoc(Loc);
+    setSizeExpr(nullptr);
   }
 
   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8e7433bc71281..ac7c3aff80bfd 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3911,6 +3911,8 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword 
Keyword,
     if (!AliasTemplate->getDeclContext()->isFileContext())
       SavedContext.emplace(*this, AliasTemplate->getDeclContext());
 
+    // FIXME: Preserve the pattern's type source information during 
substitution
+    // while respecting underlying type changes made by mode attributes.
     CanonType =
         SubstType(Pattern->getUnderlyingType(), TemplateArgLists,
                   AliasTemplate->getLocation(), AliasTemplate->getDeclName());
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1cb96b556971a..a5f16e3d17940 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5958,6 +5958,26 @@ static void fillMatrixTypeLoc(MatrixTypeLoc MTL,
   llvm_unreachable("no matrix_type attribute found at the expected location!");
 }
 
+// FIXME: Also handle attributes on the decl-specifier, declarator and
+// declaration. Matrix type locations need the same handling.
+static void fillVectorTypeLoc(VectorTypeLoc VTL,
+                              const ParsedAttributesView &Attrs) {
+  auto Kind = isa<ExtVectorType>(VTL.getTypePtr())
+                  ? ParsedAttr::AT_ExtVectorType
+                  : ParsedAttr::AT_VectorSize;
+  for (const ParsedAttr &AL : Attrs) {
+    if (AL.getKind() == Kind && !AL.isInvalid() && AL.getNumArgs() == 1) {
+      VTL.setAttrNameLoc(AL.getLoc());
+      VTL.setSizeExpr(AL.getArgAsExpr(0));
+      return;
+    }
+  }
+
+  // The attribute may be on the declarator rather than this chunk, or the
+  // vector may use a target-specific attribute. Keep the default locations
+  // when no matching attribute is present.
+}
+
 static void fillAtomicQualLoc(AtomicTypeLoc ATL, const DeclaratorChunk &Chunk) 
{
   SourceLocation Loc;
   switch (Chunk.Kind) {
@@ -6358,19 +6378,19 @@ namespace {
     void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
       TL.setExpansionLoc(Chunk.Loc);
     }
-    void VisitVectorTypeLoc(VectorTypeLoc TL) { TL.setNameLoc(Chunk.Loc); }
-    void VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
-      TL.setNameLoc(Chunk.Loc);
+    void VisitVectorTypeLoc(VectorTypeLoc TL) {
+      TL.initializeLocal(Context, Chunk.Loc);
+      fillVectorTypeLoc(TL, Chunk.getAttrs());
     }
-    void VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-      TL.setNameLoc(Chunk.Loc);
+    void VisitDependentVectorTypeLoc(DependentVectorTypeLoc TL) {
+      TL.initializeLocal(Context, Chunk.Loc);
     }
     void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
       fillAtomicQualLoc(TL, Chunk);
     }
     void
     VisitDependentSizedExtVectorTypeLoc(DependentSizedExtVectorTypeLoc TL) {
-      TL.setNameLoc(Chunk.Loc);
+      TL.initializeLocal(Context, Chunk.Loc);
     }
     void VisitMatrixTypeLoc(MatrixTypeLoc TL) {
       fillMatrixTypeLoc(TL, Chunk.getAttrs());
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 73367d6bea063..39a7c168b28f6 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6215,14 +6215,17 @@ QualType 
TreeTransform<Derived>::TransformDependentVectorType(
   EnterExpressionEvaluationContext Unevaluated(
       SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
 
-  ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+  Expr *OrigSize = TL.getSizeExpr();
+  if (!OrigSize)
+    OrigSize = T->getSizeExpr();
+  ExprResult Size = getDerived().TransformExpr(OrigSize);
   Size = SemaRef.ActOnConstantExpression(Size);
   if (Size.isInvalid())
     return QualType();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
-      Size.get() != T->getSizeExpr()) {
+      Size.get() != OrigSize) {
     Result = getDerived().RebuildDependentVectorType(
         ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
     if (Result.isNull())
@@ -6234,9 +6237,13 @@ QualType 
TreeTransform<Derived>::TransformDependentVectorType(
     DependentVectorTypeLoc NewTL =
         TLB.push<DependentVectorTypeLoc>(Result);
     NewTL.setNameLoc(TL.getNameLoc());
+    NewTL.setAttrNameLoc(TL.getAttrNameLoc());
+    NewTL.setSizeExpr(Size.get());
   } else {
     VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
     NewTL.setNameLoc(TL.getNameLoc());
+    NewTL.setAttrNameLoc(TL.getAttrNameLoc());
+    NewTL.setSizeExpr(Size.get());
   }
 
   return Result;
@@ -6248,7 +6255,6 @@ QualType 
TreeTransform<Derived>::TransformDependentSizedExtVectorType(
                                       DependentSizedExtVectorTypeLoc TL) {
   const DependentSizedExtVectorType *T = TL.getTypePtr();
 
-  // FIXME: ext vector locs should be nested
   QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
   if (ElementType.isNull())
     return QualType();
@@ -6257,18 +6263,19 @@ QualType 
TreeTransform<Derived>::TransformDependentSizedExtVectorType(
   EnterExpressionEvaluationContext Unevaluated(
       SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
 
-  ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+  Expr *OrigSize = TL.getSizeExpr();
+  if (!OrigSize)
+    OrigSize = T->getSizeExpr();
+  ExprResult Size = getDerived().TransformExpr(OrigSize);
   Size = SemaRef.ActOnConstantExpression(Size);
   if (Size.isInvalid())
     return QualType();
 
   QualType Result = TL.getType();
-  if (getDerived().AlwaysRebuild() ||
-      ElementType != T->getElementType() ||
-      Size.get() != T->getSizeExpr()) {
-    Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
-                                                             Size.get(),
-                                                         T->getAttributeLoc());
+  if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
+      Size.get() != OrigSize) {
+    Result = getDerived().RebuildDependentSizedExtVectorType(
+        ElementType, Size.get(), T->getAttributeLoc());
     if (Result.isNull())
       return QualType();
   }
@@ -6278,9 +6285,13 @@ QualType 
TreeTransform<Derived>::TransformDependentSizedExtVectorType(
     DependentSizedExtVectorTypeLoc NewTL
       = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
     NewTL.setNameLoc(TL.getNameLoc());
+    NewTL.setAttrNameLoc(TL.getAttrNameLoc());
+    NewTL.setSizeExpr(Size.get());
   } else {
     ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
     NewTL.setNameLoc(TL.getNameLoc());
+    NewTL.setAttrNameLoc(TL.getAttrNameLoc());
+    NewTL.setSizeExpr(Size.get());
   }
 
   return Result;
@@ -6430,6 +6441,8 @@ QualType 
TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
 
   VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
+  NewTL.setAttrNameLoc(TL.getAttrNameLoc());
+  NewTL.setSizeExpr(TL.getSizeExpr());
 
   return Result;
 }
@@ -6445,15 +6458,16 @@ QualType 
TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       ElementType != T->getElementType()) {
-    Result = getDerived().RebuildExtVectorType(ElementType,
-                                               T->getNumElements(),
-                                               /*FIXME*/ SourceLocation());
+    Result = getDerived().RebuildExtVectorType(ElementType, 
T->getNumElements(),
+                                               TL.getAttrNameLoc());
     if (Result.isNull())
       return QualType();
   }
 
   ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
+  NewTL.setAttrNameLoc(TL.getAttrNameLoc());
+  NewTL.setSizeExpr(TL.getSizeExpr());
 
   return Result;
 }
diff --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index 0a897a49d1165..dd0bf801fe548 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7666,19 +7666,25 @@ void TypeLocReader::VisitDependentAddressSpaceTypeLoc(
 void TypeLocReader::VisitDependentSizedExtVectorTypeLoc(
                                         DependentSizedExtVectorTypeLoc TL) {
   TL.setNameLoc(readSourceLocation());
+  TL.setAttrNameLoc(readSourceLocation());
+  TL.setSizeExpr(Reader.readExpr());
 }
 
 void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) {
   TL.setNameLoc(readSourceLocation());
+  TL.setAttrNameLoc(readSourceLocation());
+  TL.setSizeExpr(Reader.readExpr());
 }
 
 void TypeLocReader::VisitDependentVectorTypeLoc(
     DependentVectorTypeLoc TL) {
   TL.setNameLoc(readSourceLocation());
+  TL.setAttrNameLoc(readSourceLocation());
+  TL.setSizeExpr(Reader.readExpr());
 }
 
 void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-  TL.setNameLoc(readSourceLocation());
+  VisitVectorTypeLoc(TL);
 }
 
 void TypeLocReader::VisitConstantMatrixTypeLoc(ConstantMatrixTypeLoc TL) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index 0afba1c84fd62..81b2849ec849f 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -433,19 +433,25 @@ void TypeLocWriter::VisitDependentAddressSpaceTypeLoc(
 void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc(
                                         DependentSizedExtVectorTypeLoc TL) {
   addSourceLocation(TL.getNameLoc());
+  addSourceLocation(TL.getAttrNameLoc());
+  Record.AddStmt(TL.getSizeExpr());
 }
 
 void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) {
   addSourceLocation(TL.getNameLoc());
+  addSourceLocation(TL.getAttrNameLoc());
+  Record.AddStmt(TL.getSizeExpr());
 }
 
 void TypeLocWriter::VisitDependentVectorTypeLoc(
     DependentVectorTypeLoc TL) {
   addSourceLocation(TL.getNameLoc());
+  addSourceLocation(TL.getAttrNameLoc());
+  Record.AddStmt(TL.getSizeExpr());
 }
 
 void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) {
-  addSourceLocation(TL.getNameLoc());
+  VisitVectorTypeLoc(TL);
 }
 
 void TypeLocWriter::VisitConstantMatrixTypeLoc(ConstantMatrixTypeLoc TL) {
diff --git a/clang/test/PCH/cxx-dependent-sized-ext-vector.cpp 
b/clang/test/PCH/cxx-dependent-sized-ext-vector.cpp
index 93fb56161dfc0..23345a03c0663 100644
--- a/clang/test/PCH/cxx-dependent-sized-ext-vector.cpp
+++ b/clang/test/PCH/cxx-dependent-sized-ext-vector.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -std=c++11 -emit-pch %s -o %t
 // RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+// RUN: not %clang_cc1 -std=c++11 -include-pch %t -fno-caret-diagnostics %s 
2>&1 | FileCheck %s --implicit-check-not='error:'
 
 // RUN: %clang_cc1 -std=c++11 -emit-pch -fpch-instantiate-templates %s -o %t
 // RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
@@ -9,13 +10,33 @@
 #define HEADER_INCLUDED
 
 template<typename T, int N>
+// CHECK: :[[#@LINE+1]]:30: error: zero vector size
 using vec = T __attribute__((ext_vector_type(N)));
 
+struct S {};
+
+template <class T>
+// CHECK: :[[#@LINE+1]]:1: error: invalid vector element type 'S'
+using Alias = T __attribute__((ext_vector_type(4)));
+
+template <class T, int N>
+// CHECK: :[[#@LINE+1]]:32: error: invalid vector element type 'S'
+using Sized = T __attribute__((vector_size(N)));
+
+template <class T> struct Attributed {
+  // CHECK: :[[#@LINE+1]]:29: error: invalid vector element type 'S'
+  typedef T (__attribute__((ext_vector_type(4))) Type);
+};
+
 #else
 
 void test() {
-  vec<float, 2> a;  // expected-error@-5 {{zero vector size}}
+  vec<float, 2> a;  // expected-error@-20 {{zero vector size}}
   vec<float, 0> b; // expected-note {{in instantiation of template type alias 
'vec' requested here}}
 }
 
+Alias<S> alias; // expected-error@-18 {{invalid vector element type 'S'}} 
expected-note {{in instantiation of template type alias 'Alias' requested here}}
+Sized<S, 16> invalid_sized; // expected-error@-15 {{invalid vector element 
type 'S'}} expected-note {{in instantiation of template type alias 'Sized' 
requested here}}
+Attributed<S> attributed; // expected-error@-12 {{invalid vector element type 
'S'}} expected-note {{in instantiation of template class 'Attributed<S>' 
requested here}}
+
 #endif
diff --git a/clang/test/SemaCXX/vector.cpp b/clang/test/SemaCXX/vector.cpp
index fd6127a33f1ae..6ae7d3103d3f5 100644
--- a/clang/test/SemaCXX/vector.cpp
+++ b/clang/test/SemaCXX/vector.cpp
@@ -5,6 +5,7 @@
 // RUN: %clang_cc1 -flax-vector-conversions=all -triple x86_64-apple-darwin10 
-fsyntax-only -verify -std=c++20 %s
 // RUN: %clang_cc1 -flax-vector-conversions=integer -triple 
x86_64-apple-darwin10 -fsyntax-only -verify %s -DNO_LAX_FLOAT
 // RUN: %clang_cc1 -flax-vector-conversions=none -triple x86_64-apple-darwin10 
-fsyntax-only -verify %s -DNO_LAX_FLOAT -DNO_LAX_INT
+// RUN: not %clang_cc1 -flax-vector-conversions=all -triple 
x86_64-apple-darwin10 -fsyntax-only -fno-caret-diagnostics %s 2>&1 | FileCheck 
%s
 
 typedef char char16 __attribute__ ((__vector_size__ (16)));
 typedef long long longlong16 __attribute__ ((__vector_size__ (16)));
@@ -346,8 +347,8 @@ typedef ScopedE ScopedEnumSizeVector 
__attribute__((vector_size(16))); // expect
 #endif
 
 template <typename T> struct Vector {
-  // Rebuilding a fixed-size extended vector currently loses the attribute 
location.
-  typedef T type __attribute__((ext_vector_type(4))); // expected-error@*:* 
{{invalid vector element type 'GH225037::E'}}
+  // CHECK: :[[#@LINE+1]]:11: error: invalid vector element type 'GH225037::E'
+  typedef T type __attribute__((ext_vector_type(4))); // expected-error 
{{invalid vector element type 'GH225037::E'}}
 };
 Vector<E> enum_vector; // expected-note {{in instantiation of template class 
'GH225037::Vector<GH225037::E>' requested here}}
 Vector<int> int_vector;
@@ -546,6 +547,7 @@ namespace PR48540 {
 // The below used to cause an OOM error, or an assert, make sure it is still
 //  valid.
 int (__attribute__((vector_size(16))) a);
+int (parenthesized_vector) __attribute__((vector_size(16)));
 
 template <typename T, int I>
 struct S {
diff --git a/clang/test/SemaTemplate/ext-vector-type.cpp 
b/clang/test/SemaTemplate/ext-vector-type.cpp
index f968c13f10238..6d4a250361aa7 100644
--- a/clang/test/SemaTemplate/ext-vector-type.cpp
+++ b/clang/test/SemaTemplate/ext-vector-type.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: not %clang_cc1 -std=c++11 -fsyntax-only -fno-caret-diagnostics %s 2>&1 
| FileCheck %s
 template<typename T, unsigned Length> 
 struct make1 { 
   typedef T __attribute__((ext_vector_type(Length))) type; 
@@ -92,3 +93,30 @@ namespace Deduction {
   int array2[X0<float2>::value == 2? 1 : -1];
   int array3[X0<float4>::value == 3? 1 : -1];
 }
+
+// The primary error should retain a source location, independently of the
+// template instantiation notes.
+struct S {};
+
+template <class T> struct Parenthesized {
+  typedef T (Type)
+      // CHECK: :[[#@LINE-1]]:13: error: invalid vector element type 'S'
+      __attribute__((ext_vector_type(4))); // expected-error@-2 {{invalid 
vector element type 'S'}}
+};
+Parenthesized<S> parenthesized; // expected-note {{in instantiation of 
template class 'Parenthesized<S>' requested here}}
+
+template <class T>
+// CHECK: :[[#@LINE+1]]:1: error: invalid vector element type 'S'
+using Alias = T __attribute__((ext_vector_type(4))); // expected-error 
{{invalid vector element type 'S'}}
+Alias<S> alias; // expected-note {{in instantiation of template type alias 
'Alias' requested here}}
+Alias<int> valid_alias;
+
+// The source location must also survive conversion from a dependent-sized
+// vector to a fixed-size vector whose element type is still dependent.
+template <int N> struct TwoStage {
+  template <class T>
+  // CHECK: :[[#@LINE+1]]:3: error: invalid vector element type 'S'
+  using Type = T __attribute__((ext_vector_type(N))); // expected-error 
{{invalid vector element type 'S'}}
+};
+TwoStage<4>::Type<S> two_stage; // expected-note {{in instantiation of 
template type alias 'Type' requested here}}
+TwoStage<4>::Type<int> valid_two_stage;
diff --git a/clang/unittests/AST/SourceLocationTest.cpp 
b/clang/unittests/AST/SourceLocationTest.cpp
index 021b2dfac4060..671cb8b809154 100644
--- a/clang/unittests/AST/SourceLocationTest.cpp
+++ b/clang/unittests/AST/SourceLocationTest.cpp
@@ -230,6 +230,35 @@ TEST(TypeLoc, LongRange) {
   EXPECT_TRUE(Verifier.match("long a;", typeLoc()));
 }
 
+TEST(TypeLoc, VectorSourceInfo) {
+  llvm::Annotations Code(R"cpp(
+    typedef int (__attribute__(($Vector^vector_size($VectorSize[[8 * 2]]))) 
Vector);
+    typedef int 
(__attribute__(($Extended^ext_vector_type($ExtendedSize[[4]]))) Extended);
+  )cpp");
+  auto AST = tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{});
+  ASSERT_TRUE(AST);
+
+  ASTContext &Ctx = AST->getASTContext();
+  const SourceManager &SM = Ctx.getSourceManager();
+  auto Matches = match(
+      typedefNameDecl(hasAnyName("Vector", "Extended")).bind("decl"), Ctx);
+  ASSERT_EQ(Matches.size(), 2u);
+  for (const auto &Match : Matches) {
+    const auto *Decl = Match.getNodeAs<TypedefNameDecl>("decl");
+    std::string Name = Decl->getNameAsString();
+    auto TL = Decl->getTypeSourceInfo()->getTypeLoc().getAs<VectorTypeLoc>();
+    ASSERT_TRUE(TL) << Name;
+    ASSERT_TRUE(TL.getAttrNameLoc().isValid()) << Name;
+    EXPECT_EQ(SM.getFileOffset(TL.getAttrNameLoc()), Code.point(Name)) << Name;
+    ASSERT_TRUE(TL.getSizeExpr()) << Name;
+    auto Range = Lexer::getAsCharRange(TL.getSizeExpr()->getSourceRange(), SM,
+                                       Ctx.getLangOpts());
+    auto Expected = Code.range(Name + "Size");
+    EXPECT_EQ(SM.getFileOffset(Range.getBegin()), Expected.Begin) << Name;
+    EXPECT_EQ(SM.getFileOffset(Range.getEnd()), Expected.End) << Name;
+  }
+}
+
 TEST(TypeLoc, DecltypeTypeLocRange) {
   llvm::Annotations Code(R"(
     $full1[[decltype(1)]] a;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to