From: Francois Pichet Date: Wed, 27 Jul 2011 01:05:24 +0000 (+0000) Subject: In Microsoft mode, if we are within a templated function and we can't resolve Identif... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dfb6ae1d8d114772bd91b7079c7e4bf4b517e63c;p=clang In Microsoft mode, if we are within a templated function and we can't resolve Identifier during BuildCXXNestedNameSpecifier, 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. class C { public: static void foo2() { } }; template class A { public: typedef C D; }; template class B : public A { 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 --- diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 5f8c9c62a4..d5bcb71255 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -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 A { public: typedef C D; }; + // + // template class B : public A { + // 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 index 0000000000..2710caf221 --- /dev/null +++ b/test/SemaTemplate/lookup-dependent-bases.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s + +class C { +public: + static void foo2() { } +}; +template +class A { +public: + typedef C D; +}; + +template +class B : public A { +public: + void foo() { + D::foo2(); + } +};