]> granicus.if.org Git - clang/commitdiff
PR26195: Set correct NestedNameSpecifierLoc for the dependent initializer
authorAlex Lorenz <arphaman@gmail.com>
Fri, 23 Jun 2017 14:10:07 +0000 (14:10 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Fri, 23 Jun 2017 14:10:07 +0000 (14:10 +0000)
This commit fixes incorrect source positions of dependent c'tor initializers
like in the following code:

template<typename MyBase>
struct Derived: MyBase::InnerIterator
{

Derived() : MyBase::InnerIterator() {} /// This line is problematic: all positions point to InnerIterator and nothing points to MyBase
};

Patch by Serge Preis!

Differential Revision: https://reviews.llvm.org/D32439

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@306103 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclCXX.cpp
test/Index/ctor-init-source-loc.cpp [new file with mode: 0644]

index 0b46e15bb0a3286a872c4b20b0fc70f9a7ff63db..27b5221fb9f739cbf617ab3620e4156050e24700 100644 (file)
@@ -3778,6 +3778,15 @@ Sema::BuildMemInitializer(Decl *ConstructorD,
           if (BaseType.isNull())
             return true;
 
+          TInfo = Context.CreateTypeSourceInfo(BaseType);
+          DependentNameTypeLoc TL =
+              TInfo->getTypeLoc().castAs<DependentNameTypeLoc>();
+          if (!TL.isNull()) {
+            TL.setNameLoc(IdLoc);
+            TL.setElaboratedKeywordLoc(SourceLocation());
+            TL.setQualifierLoc(SS.getWithLocInContext(Context));
+          }
+
           R.clear();
           R.setLookupName(MemberOrBase);
         }
diff --git a/test/Index/ctor-init-source-loc.cpp b/test/Index/ctor-init-source-loc.cpp
new file mode 100644 (file)
index 0000000..330e9c4
--- /dev/null
@@ -0,0 +1,117 @@
+// RUN: c-index-test -test-load-source all %s | FileCheck %s
+template<typename MyBase>
+struct Derived:  MyBase::InnerIterator
+{
+    Derived() : MyBase::InnerIterator() {}
+// CHECK:  TypeRef=MyBase:2:19 Extent=[5:17 - 5:23]
+};
+
+template<typename MyBase>
+struct Derived2:  MyBase::Deeper::InnerIterator
+{
+    Derived2() : MyBase::Deeper::InnerIterator() {}
+// CHECK:  TypeRef=MyBase:9:19 Extent=[12:18 - 12:24]
+};
+
+template<typename Q>
+struct Templ;
+
+template<typename MyBase>
+struct Derived3:  Templ<MyBase>::InnerIterator
+{
+    Derived3() : Templ<MyBase>::InnerIterator() {}
+// CHECK: TemplateRef=Templ:17:8 Extent=[22:18 - 22:23]
+// CHECK: TypeRef=MyBase:19:19 Extent=[22:24 - 22:30]
+};
+
+
+struct Outer {
+    template <typename Q>
+    struct Inner {
+        typedef Q Parm;
+    };
+};
+
+template<typename Q>
+struct Derived4:  Outer::Inner<Q>::Parm
+{
+    Derived4() : Outer::Inner<Q>::Parm() {}
+// CHECK: TypeRef=struct Outer:28:8 Extent=[38:18 - 38:23]
+// CHECK: TemplateRef=Inner:30:12 Extent=[38:25 - 38:30]
+// CHECK: TypeRef=Q:35:19 Extent=[38:31 - 38:32]
+};
+
+template<typename Q>
+struct Derived5:  Outer::Inner<Q>::Parm::InnerIterator
+{
+    Derived5() : Outer::Inner<Q>::Parm::InnerIterator() {}
+// CHECK: TypeRef=struct Outer:28:8 Extent=[47:18 - 47:23]
+// CHECK: TemplateRef=Inner:30:12 Extent=[47:25 - 47:30]
+// CHECK: TypeRef=Q:44:19 Extent=[47:31 - 47:32]
+};
+
+template<typename Q>
+struct Derived6:  Outer::Inner<Q>
+{
+    Derived6() : Outer::Inner<Q>() {}
+// CHECK: TypeRef=struct Outer:28:8 Extent=[56:18 - 56:23]
+// CHECK: TemplateRef=Inner:30:12 Extent=[56:25 - 56:30]
+// CHECK: TypeRef=Q:53:19 Extent=[56:31 - 56:32]
+};
+
+struct Base {};
+
+struct Derived7:  Outer::Inner<Base>::Parm
+{
+    Derived7() : Outer::Inner<Base>::Parm() {}
+// CHECK: TypeRef=struct Outer:28:8 Extent=[66:18 - 66:23]
+// CHECK: TemplateRef=Inner:30:12 Extent=[66:25 - 66:30]
+// CHECK: TypeRef=struct Base:62:8 Extent=[66:31 - 66:35]
+};
+
+struct Derived8:  Outer::Inner<Base>
+{
+    Derived8() : Outer::Inner<Base>() {}
+// CHECK: TypeRef=struct Outer:28:8 Extent=[74:18 - 74:23]
+// CHECK: TemplateRef=Inner:30:12 Extent=[74:25 - 74:30]
+// CHECK: TypeRef=struct Base:62:8 Extent=[74:31 - 74:35]
+};
+
+namespace Namespace {
+    template<typename Q> struct Templ;
+
+    struct Outer {
+        template <typename Q>
+        struct Inner {
+            typedef Q Parm;
+        };
+    };
+}
+
+template<typename MyBase>
+struct Derived9:  Namespace::Templ<MyBase>::InnerIterator
+{
+    Derived9() : Namespace::Templ<MyBase>::InnerIterator() {}
+// CHECK: NamespaceRef=Namespace:80:11 Extent=[94:18 - 94:27]
+// CHECK: TemplateRef=Templ:81:33 Extent=[94:29 - 94:34]
+// CHECK: TypeRef=MyBase:91:19 Extent=[94:35 - 94:41]
+};
+
+template<typename MyBase>
+struct Derived10:  Namespace::Templ<MyBase>
+{
+    Derived10() : Namespace::Templ<MyBase>() {}
+// CHECK: NamespaceRef=Namespace:80:11 Extent=[103:19 - 103:28]
+// CHECK: TemplateRef=Templ:81:33 Extent=[103:30 - 103:35]
+// CHECK: TypeRef=MyBase:100:19 Extent=[103:36 - 103:42]
+};
+
+template<typename MyBase>
+struct Derived11:  Namespace::Outer::Inner<MyBase>::Parm
+{
+    Derived11() : Namespace::Outer::Inner<MyBase>::Parm() {}
+// CHECK: NamespaceRef=Namespace:80:11 Extent=[112:19 - 112:28]
+// CHECK: TypeRef=struct Namespace::Outer:83:12 Extent=[112:30 - 112:35]
+// CHECK: TemplateRef=Inner:85:16 Extent=[112:37 - 112:42]
+// CHECK: TypeRef=MyBase:109:19 Extent=[112:43 - 112:49]
+};