diff options
author | Francois Pichet <pichet2000@gmail.com> | 2011-04-13 02:38:49 +0000 |
---|---|---|
committer | Francois Pichet <pichet2000@gmail.com> | 2011-04-13 02:38:49 +0000 |
commit | 6943e9befee204becfae55de1298b3d5fee87934 (patch) | |
tree | c0640128f27b36579cf4343aaf5b4e6647d32a14 /lib/Sema/SemaDecl.cpp | |
parent | ad3692bbe1874abafae1757a2b9d3bfa2249dc43 (diff) |
In Microsoft mode, within class scope, if a CXXScopeSpec's type is equal to the type of one of the base classes then downgrade the missing typename error to a warning. Up to now this is the only case I found where MSVC doesn't require "typename" at class scope. Really strange!
This fixes 1 error when parsing the MSVC 2008 header files.
Example:
template<class T> class A {
public:
typedef int TYPE;
};
template<class T> class B : public A<T> {
public:
A<T>::TYPE a; // no typename required because A<T> is a base class.
};
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129425 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a2249c787b..4338ddaa1a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -250,6 +250,33 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) { return DeclSpec::TST_unspecified; } +/// isMicrosoftMissingTypename - In Microsoft mode, within class scope, +/// if a CXXScopeSpec's type is equal to the type of one of the base classes +/// then downgrade the missing typename error to a warning. +/// This is needed for MSVC compatibility; Example: +/// @code +/// template<class T> class A { +/// public: +/// typedef int TYPE; +/// }; +/// template<class T> class B : public A<T> { +/// public: +/// A<T>::TYPE a; // no typename required because A<T> is a base class. +/// }; +/// @endcode +bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS) { + if (CurContext->isRecord()) { + const Type* Ty = SS->getScopeRep()->getAsType(); + + CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext); + for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(), + BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) + if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base->getType())) + return true; + } + return false; +} + bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, SourceLocation IILoc, Scope *S, @@ -327,7 +354,11 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, Diag(IILoc, diag::err_typename_nested_not_found) << &II << DC << SS->getRange(); else if (isDependentScopeSpecifier(*SS)) { - Diag(SS->getRange().getBegin(), diag::err_typename_missing) + unsigned DiagID = diag::err_typename_missing; + if (getLangOptions().Microsoft && isMicrosoftMissingTypename(SS)) + DiagID = diag::war_typename_missing; + + Diag(SS->getRange().getBegin(), DiagID) << (NestedNameSpecifier *)SS->getScopeRep() << II.getName() << SourceRange(SS->getRange().getBegin(), IILoc) << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename "); |