]> granicus.if.org Git - clang/commitdiff
In Microsoft mode, if we are within a templated function and we can't resolve Identif...
authorFrancois Pichet <pichet2000@gmail.com>
Wed, 27 Jul 2011 01:05:24 +0000 (01:05 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Wed, 27 Jul 2011 01:05:24 +0000 (01:05 +0000)
class C {
public:
    static void foo2() {  }
};

template <class T> class A {
public:
   typedef C D;
};

template <class T> class B : public A<T> {
public:
  void foo() { D::foo2(); }
};

Note that this won't work if the NestedNameSpecifier refers to a type.
This fixes 1 error when parsing the MSVC 2010 standard headers file with clang.

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

lib/Sema/SemaCXXScopeSpec.cpp
test/SemaTemplate/lookup-dependent-bases.cpp [new file with mode: 0644]

index 5f8c9c62a4092a63faa5a665c8694c4e523aaae8..d5bcb712553a355bdc85fceef8fa2650a9a661a7 100644 (file)
@@ -615,6 +615,31 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
     LookupName(Found, S);
   }
 
+  // In Microsoft mode, if we are within a templated function and we can't
+  // resolve Identifier, then extend the SS with Identifier. This will have 
+  // the effect of resolving Identifier during template instantiation. 
+  // The goal is to be able to resolve a function call whose
+  // nested-name-specifier is located inside a dependent base class.
+  // Example: 
+  //
+  // class C {
+  // public:
+  //    static void foo2() {  }
+  // };
+  // template <class T> class A { public: typedef C D; };
+  //
+  // template <class T> class B : public A<T> {
+  // public:
+  //   void foo() { D::foo2(); }
+  // };
+  if (getLangOptions().Microsoft) {
+    DeclContext *DC = LookupCtx ? LookupCtx : CurContext;
+    if (DC->isDependentContext() && DC->isFunctionOrMethod()) {
+      SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
+      return false;
+    }
+  }
+
   unsigned DiagID;
   if (!Found.empty())
     DiagID = diag::err_expected_class_or_namespace;
diff --git a/test/SemaTemplate/lookup-dependent-bases.cpp b/test/SemaTemplate/lookup-dependent-bases.cpp
new file mode 100644 (file)
index 0000000..2710caf
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+
+class C {
+public:
+   static void foo2() {  }
+};
+template <class T>
+class A {
+public:
+   typedef C D;
+};
+
+template <class T>
+class B : public A<T> {
+public:
+   void foo() {
+    D::foo2();
+   }
+};