Let's see if r261893 fixes this. On Thu, Feb 25, 2016 at 4:31 PM, Alexander Kornienko <ale...@google.com> wrote:
> Yes, I know. Trying to come up with a good solution. > > On Thu, Feb 25, 2016 at 4:59 AM, Sean Silva <chisophu...@gmail.com> wrote: > >> This or r261737 seem to be causing a bot failure: >> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/636 >> >> -- Sean Silva >> >> On Wed, Feb 24, 2016 at 5:35 AM, Alexander Kornienko via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: alexfh >>> Date: Wed Feb 24 07:35:32 2016 >>> New Revision: 261737 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=261737&view=rev >>> Log: >>> [clang-tidy] Added a check for forward declaration in the potentially >>> wrong namespace >>> >>> Adds a new check "misc-forward-declaration-namespace". >>> In check, A forward declaration is considerred in a potentially wrong >>> namespace >>> if there is any definition/declaration with the same name exists in a >>> different >>> namespace. >>> >>> Reviewers: akuegel, hokein, alexfh >>> >>> Patch by Eric Liu! >>> >>> Differential Revision: http://reviews.llvm.org/D17195 >>> >>> Added: >>> >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.cpp >>> >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.h >>> >>> clang-tools-extra/trunk/docs/clang-tidy/checks/misc-forward-declaration-namespace.rst >>> >>> clang-tools-extra/trunk/test/clang-tidy/misc-forward-declaration-namespace.cpp >>> Modified: >>> clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt >>> clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp >>> clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst >>> >>> Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=261737&r1=261736&r2=261737&view=diff >>> >>> ============================================================================== >>> --- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original) >>> +++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Wed Feb 24 >>> 07:35:32 2016 >>> @@ -6,6 +6,7 @@ add_clang_library(clangTidyMiscModule >>> AssignOperatorSignatureCheck.cpp >>> BoolPointerImplicitConversionCheck.cpp >>> DefinitionsInHeadersCheck.cpp >>> + ForwardDeclarationNamespaceCheck.cpp >>> InaccurateEraseCheck.cpp >>> IncorrectRoundings.cpp >>> InefficientAlgorithmCheck.cpp >>> >>> Added: >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.cpp?rev=261737&view=auto >>> >>> ============================================================================== >>> --- >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.cpp >>> (added) >>> +++ >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.cpp >>> Wed Feb 24 07:35:32 2016 >>> @@ -0,0 +1,174 @@ >>> +//===--- ForwardDeclarationNamespaceCheck.cpp - clang-tidy ------*- C++ >>> -*-===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> >>> +//===----------------------------------------------------------------------===// >>> + >>> +#include "ForwardDeclarationNamespaceCheck.h" >>> +#include <stack> >>> +#include <string> >>> +#include "clang/AST/ASTContext.h" >>> +#include "clang/AST/Decl.h" >>> +#include "clang/ASTMatchers/ASTMatchFinder.h" >>> +#include "clang/ASTMatchers/ASTMatchers.h" >>> + >>> +using namespace clang::ast_matchers; >>> + >>> +namespace clang { >>> +namespace tidy { >>> +namespace misc { >>> + >>> +void ForwardDeclarationNamespaceCheck::registerMatchers(MatchFinder >>> *Finder) { >>> + // Match all class declarations/definitions *EXCEPT* >>> + // 1. implicit classes, e.g. `class A {};` has implicit `class A` >>> inside `A`. >>> + // 2. nested classes declared/defined inside another class. >>> + // 3. template class declaration, template instantiation or >>> + // specialization (NOTE: extern specialization is filtered out by >>> + // `unless(hasAncestor(cxxRecordDecl()))`). >>> + auto IsInSpecialization = hasAncestor( >>> + decl(anyOf(cxxRecordDecl(isExplicitTemplateSpecialization()), >>> + functionDecl(isExplicitTemplateSpecialization())))); >>> + Finder->addMatcher( >>> + cxxRecordDecl( >>> + hasParent(decl(anyOf(namespaceDecl(), >>> translationUnitDecl()))), >>> + unless(isImplicit()), unless(hasAncestor(cxxRecordDecl())), >>> + unless(isInstantiated()), unless(IsInSpecialization), >>> + unless(classTemplateSpecializationDecl())) >>> + .bind("record_decl"), >>> + this); >>> + >>> + // Match all friend declarations. Classes used in friend declarations >>> are not >>> + // marked as referenced in AST. We need to record all record classes >>> used in >>> + // friend declarations. >>> + Finder->addMatcher(friendDecl().bind("friend_decl"), this); >>> +} >>> + >>> +void ForwardDeclarationNamespaceCheck::check( >>> + const MatchFinder::MatchResult &Result) { >>> + if (const auto *RecordDecl = >>> + Result.Nodes.getNodeAs<CXXRecordDecl>("record_decl")) { >>> + StringRef DeclName = RecordDecl->getName(); >>> + if (RecordDecl->isThisDeclarationADefinition()) { >>> + DeclNameToDefinitions[DeclName].push_back(RecordDecl); >>> + } else { >>> + // If a declaration has no definition, the definition could be in >>> another >>> + // namespace (a wrong namespace). >>> + // NOTE: even a declaration does have definition, we still need >>> it to >>> + // compare with other declarations. >>> + DeclNameToDeclarations[DeclName].push_back(RecordDecl); >>> + } >>> + } else { >>> + const auto *Decl = >>> Result.Nodes.getNodeAs<FriendDecl>("friend_decl"); >>> + assert(Decl && "Decl is neither record_decl nor friend decl!"); >>> + >>> + // Classes used in friend delarations are not marked referenced in >>> AST, >>> + // so we need to check classes used in friend declarations manually >>> to >>> + // reduce the rate of false positive. >>> + // For example, in >>> + // \code >>> + // struct A; >>> + // struct B { friend A; }; >>> + // \endcode >>> + // `A` will not be marked as "referenced" in the AST. >>> + if (const TypeSourceInfo *Tsi = Decl->getFriendType()) { >>> + QualType Desugared = >>> Tsi->getType().getDesugaredType(*Result.Context); >>> + FriendTypes.insert(Desugared.getTypePtr()); >>> + } >>> + } >>> +} >>> + >>> +static bool haveSameNamespaceOrTranslationUnit(const CXXRecordDecl >>> *Decl1, >>> + const CXXRecordDecl >>> *Decl2) { >>> + const DeclContext *ParentDecl1 = Decl1->getLexicalParent(); >>> + const DeclContext *ParentDecl2 = Decl2->getLexicalParent(); >>> + >>> + // Since we only matched declarations whose parent is Namespace or >>> + // TranslationUnit declaration, the parent should be either a >>> translation unit >>> + // or namespace. >>> + if (ParentDecl1->getDeclKind() == Decl::TranslationUnit || >>> + ParentDecl2->getDeclKind() == Decl::TranslationUnit) { >>> + return ParentDecl1 == ParentDecl2; >>> + } >>> + assert(ParentDecl1->getDeclKind() == Decl::Namespace && >>> + "ParentDecl1 declaration must be a namespace"); >>> + assert(ParentDecl2->getDeclKind() == Decl::Namespace && >>> + "ParentDecl2 declaration must be a namespace"); >>> + auto *Ns1 = NamespaceDecl::castFromDeclContext(ParentDecl1); >>> + auto *Ns2 = NamespaceDecl::castFromDeclContext(ParentDecl2); >>> + return Ns1->getOriginalNamespace() == Ns2->getOriginalNamespace(); >>> +} >>> + >>> +static std::string getNameOfNamespace(const CXXRecordDecl *Decl) { >>> + const auto *ParentDecl = Decl->getLexicalParent(); >>> + if (ParentDecl->getDeclKind() == Decl::TranslationUnit) { >>> + return "(global)"; >>> + } >>> + const auto *NsDecl = cast<NamespaceDecl>(ParentDecl); >>> + std::string Ns; >>> + llvm::raw_string_ostream OStream(Ns); >>> + NsDecl->printQualifiedName(OStream); >>> + OStream.flush(); >>> + return Ns.empty() ? "(global)" : Ns; >>> +} >>> + >>> +void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() { >>> + // Iterate each group of declarations by name. >>> + for (const auto &KeyValuePair : DeclNameToDeclarations) { >>> + const auto &Declarations = KeyValuePair.second; >>> + // If more than 1 declaration exists, we check if all are in the >>> same >>> + // namespace. >>> + for (const auto *CurDecl : Declarations) { >>> + if (CurDecl->hasDefinition() || CurDecl->isReferenced()) { >>> + continue; // Skip forward declarations that are used/referenced. >>> + } >>> + if (FriendTypes.count(CurDecl->getTypeForDecl()) != 0) { >>> + continue; // Skip forward declarations referenced as friend. >>> + } >>> + if (CurDecl->getLocation().isMacroID() || >>> + CurDecl->getLocation().isInvalid()) { >>> + continue; >>> + } >>> + // Compare with all other declarations with the same name. >>> + for (const auto *Decl : Declarations) { >>> + if (Decl == CurDecl) { >>> + continue; // Don't compare with self. >>> + } >>> + if (!CurDecl->hasDefinition() && >>> + !haveSameNamespaceOrTranslationUnit(CurDecl, Decl)) { >>> + diag(CurDecl->getLocation(), >>> + "declaration '%0' is never referenced, but a declaration >>> with " >>> + "the same name found in another namespace '%1'") >>> + << CurDecl->getName() << getNameOfNamespace(Decl); >>> + diag(Decl->getLocation(), "a declaration of '%0' is found >>> here", >>> + DiagnosticIDs::Note) >>> + << Decl->getName(); >>> + break; // FIXME: We only generate one warning for each >>> declaration. >>> + } >>> + } >>> + // Check if a definition in another namespace exists. >>> + const auto DeclName = CurDecl->getName(); >>> + if (DeclNameToDefinitions.find(DeclName) == >>> DeclNameToDefinitions.end()) { >>> + continue; // No definition in this translation unit, we can >>> skip it. >>> + } >>> + // Make a warning for each definition with the same name (in other >>> + // namespaces). >>> + const auto &Definitions = DeclNameToDefinitions[DeclName]; >>> + for (const auto *Def : Definitions) { >>> + diag(CurDecl->getLocation(), >>> + "no definition found for '%0', but a definition with " >>> + "the same name '%1' found in another namespace '%2'") >>> + << CurDecl->getName() << Def->getName() << >>> getNameOfNamespace(Def); >>> + diag(Def->getLocation(), "a definition of '%0' is found here", >>> + DiagnosticIDs::Note) >>> + << Def->getName(); >>> + } >>> + } >>> + } >>> +} >>> + >>> +} // namespace misc >>> +} // namespace tidy >>> +} // namespace clang >>> >>> Added: >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.h?rev=261737&view=auto >>> >>> ============================================================================== >>> --- >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.h >>> (added) >>> +++ >>> clang-tools-extra/trunk/clang-tidy/misc/ForwardDeclarationNamespaceCheck.h >>> Wed Feb 24 07:35:32 2016 >>> @@ -0,0 +1,59 @@ >>> +//===--- ForwardDeclarationNamespaceCheck.h - clang-tidy --------*- C++ >>> -*-===// >>> +// >>> +// The LLVM Compiler Infrastructure >>> +// >>> +// This file is distributed under the University of Illinois Open Source >>> +// License. See LICENSE.TXT for details. >>> +// >>> >>> +//===----------------------------------------------------------------------===// >>> + >>> +#ifndef >>> LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_FORWARDDECLARATIONNAMESPACECHECK_H >>> +#define >>> LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_FORWARDDECLARATIONNAMESPACECHECK_H >>> + >>> +#include <set> >>> +#include <vector> >>> +#include "llvm/ADT/SmallPtrSet.h" >>> +#include "../ClangTidy.h" >>> + >>> +namespace clang { >>> +namespace tidy { >>> +namespace misc { >>> + >>> +/// Checks if an unused forward declaration is in a wrong namespace. >>> +/// >>> +/// The check inspects all unused forward declarations and checks if >>> there is >>> +/// any declaration/definition with the same name, which could indicate >>> +/// that the forward declaration is potentially in a wrong namespace. >>> +/// >>> +/// \code >>> +/// namespace na { struct A; } >>> +/// namespace nb { struct A {} }; >>> +/// nb::A a; >>> +/// // warning : no definition found for 'A', but a definition with >>> the same >>> +/// name 'A' found in another namespace 'nb::' >>> +/// \endcode >>> +/// >>> +/// This check can only generate warnings, but it can't suggest fixes >>> at this >>> +/// point. >>> +/// >>> +/// For the user-facing documentation see: >>> +/// >>> http://clang.llvm.org/extra/clang-tidy/checks/misc-forward-declaration-namespace.html >>> +class ForwardDeclarationNamespaceCheck : public ClangTidyCheck { >>> +public: >>> + ForwardDeclarationNamespaceCheck(StringRef Name, ClangTidyContext >>> *Context) >>> + : ClangTidyCheck(Name, Context) {} >>> + void registerMatchers(ast_matchers::MatchFinder *Finder) override; >>> + void check(const ast_matchers::MatchFinder::MatchResult &Result) >>> override; >>> + void onEndOfTranslationUnit() override; >>> + >>> +private: >>> + llvm::StringMap<std::vector<const CXXRecordDecl *>> >>> DeclNameToDefinitions; >>> + llvm::StringMap<std::vector<const CXXRecordDecl *>> >>> DeclNameToDeclarations; >>> + llvm::SmallPtrSet<const Type *, 16> FriendTypes; >>> +}; >>> + >>> +} // namespace misc >>> +} // namespace tidy >>> +} // namespace clang >>> + >>> +#endif // >>> LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_FORWARDDECLARATIONNAMESPACECHECK_H >>> >>> Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=261737&r1=261736&r2=261737&view=diff >>> >>> ============================================================================== >>> --- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original) >>> +++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Wed Feb >>> 24 07:35:32 2016 >>> @@ -15,6 +15,7 @@ >>> #include "AssignOperatorSignatureCheck.h" >>> #include "BoolPointerImplicitConversionCheck.h" >>> #include "DefinitionsInHeadersCheck.h" >>> +#include "ForwardDeclarationNamespaceCheck.h" >>> #include "InaccurateEraseCheck.h" >>> #include "IncorrectRoundings.h" >>> #include "InefficientAlgorithmCheck.h" >>> @@ -55,6 +56,8 @@ public: >>> "misc-bool-pointer-implicit-conversion"); >>> CheckFactories.registerCheck<DefinitionsInHeadersCheck>( >>> "misc-definitions-in-headers"); >>> + CheckFactories.registerCheck<ForwardDeclarationNamespaceCheck>( >>> + "misc-forward-declaration-namespace"); >>> CheckFactories.registerCheck<InaccurateEraseCheck>( >>> "misc-inaccurate-erase"); >>> CheckFactories.registerCheck<IncorrectRoundings>( >>> >>> Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=261737&r1=261736&r2=261737&view=diff >>> >>> ============================================================================== >>> --- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original) >>> +++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Wed Feb 24 >>> 07:35:32 2016 >>> @@ -51,6 +51,7 @@ Clang-Tidy Checks >>> misc-assign-operator-signature >>> misc-bool-pointer-implicit-conversion >>> misc-definitions-in-headers >>> + misc-forward-declaration-namespace >>> misc-inaccurate-erase >>> misc-incorrect-roundings >>> misc-inefficient-algorithm >>> >>> Added: >>> clang-tools-extra/trunk/docs/clang-tidy/checks/misc-forward-declaration-namespace.rst >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/misc-forward-declaration-namespace.rst?rev=261737&view=auto >>> >>> ============================================================================== >>> --- >>> clang-tools-extra/trunk/docs/clang-tidy/checks/misc-forward-declaration-namespace.rst >>> (added) >>> +++ >>> clang-tools-extra/trunk/docs/clang-tidy/checks/misc-forward-declaration-namespace.rst >>> Wed Feb 24 07:35:32 2016 >>> @@ -0,0 +1,19 @@ >>> +.. title:: clang-tidy - misc-forward-declaration-namespace >>> + >>> +misc-forward-declaration-namespace >>> +================================== >>> + >>> +Checks if an unused forward declaration is in a wrong namespace. >>> + >>> +The check inspects all unused forward declarations and checks if there >>> is any >>> +declaration/definition with the same name existing, which could >>> indicate that >>> +the forward declaration is in a potentially wrong namespace. >>> + >>> +.. code:: c++ >>> + namespace na { struct A; } >>> + namespace nb { struct A {}; } >>> + nb::A a; >>> + // warning : no definition found for 'A', but a definition with the >>> same name >>> + // 'A' found in another namespace 'nb::' >>> + >>> +This check can only generate warnings, but it can't suggest a fix at >>> this point. >>> >>> Added: >>> clang-tools-extra/trunk/test/clang-tidy/misc-forward-declaration-namespace.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-forward-declaration-namespace.cpp?rev=261737&view=auto >>> >>> ============================================================================== >>> --- >>> clang-tools-extra/trunk/test/clang-tidy/misc-forward-declaration-namespace.cpp >>> (added) >>> +++ >>> clang-tools-extra/trunk/test/clang-tidy/misc-forward-declaration-namespace.cpp >>> Wed Feb 24 07:35:32 2016 >>> @@ -0,0 +1,163 @@ >>> +// RUN: %check_clang_tidy %s misc-forward-declaration-namespace %t >>> + >>> +namespace { >>> +// This is a declaration in a wrong namespace. >>> +class T_A; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration 'T_A' is never >>> referenced, but a declaration with the same name found in another namespace >>> 'na' [misc-forward-declaration-namespace] >>> +// CHECK-MESSAGES: note: a declaration of 'T_A' is found here >>> +// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: no definition found for >>> 'T_A', but a definition with the same name 'T_A' found in another namespace >>> '(global)' [misc-forward-declaration-namespace] >>> +// CHECK-MESSAGES: note: a definition of 'T_A' is found here >>> +} >>> + >>> +namespace na { >>> +// This is a declaration in a wrong namespace. >>> +class T_A; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration 'T_A' is never >>> referenced, but a declaration with the same name found in another namespace >>> '(anonymous)' >>> +// CHECK-MESSAGES: note: a declaration of 'T_A' is found here >>> +// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: no definition found for >>> 'T_A', but a definition with the same name 'T_A' found in another namespace >>> '(global)' >>> +// CHECK-MESSAGES: note: a definition of 'T_A' is found here >>> +} >>> + >>> +class T_A; >>> + >>> +class T_A { >>> + int x; >>> +}; >>> + >>> +class NESTED; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: no definition found for >>> 'NESTED', but a definition with the same name 'NESTED' found in another >>> namespace '(anonymous namespace)::nq::(anonymous)' >>> +// CHECK-MESSAGES: note: a definition of 'NESTED' is found here >>> + >>> +namespace { >>> +namespace nq { >>> +namespace { >>> +class NESTED {}; >>> +} >>> +} >>> +} >>> + >>> +namespace na { >>> +class T_B; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration 'T_B' is never >>> referenced, but a declaration with the same name found in another namespace >>> 'nb' >>> +// CHECK-MESSAGES: note: a declaration of 'T_B' is found here >>> +// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: no definition found for >>> 'T_B', but a definition with the same name 'T_B' found in another namespace >>> 'nb' >>> +// CHECK-MESSAGES: note: a definition of 'T_B' is found here >>> +} >>> + >>> +namespace nb { >>> +class T_B; >>> +} >>> + >>> +namespace nb { >>> +class T_B { >>> + int x; >>> +}; >>> +} >>> + >>> +namespace na { >>> +class T_B; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration 'T_B' is never >>> referenced, but a declaration with the same name found in another namespace >>> 'nb' >>> +// CHECK-MESSAGES: note: a declaration of 'T_B' is found here >>> +// CHECK-MESSAGES: :[[@LINE-3]]:7: warning: no definition found for >>> 'T_B', but a definition with the same name 'T_B' found in another namespace >>> 'nb' >>> +// CHECK-MESSAGES: note: a definition of 'T_B' is found here >>> +} >>> + >>> +// A simple forward declaration. Although it is never used, but no >>> declaration >>> +// with the same name is found in other namespace. >>> +class OUTSIDER; >>> + >>> +namespace na { >>> +// This class is referenced declaration, we don't generate warning. >>> +class OUTSIDER_1; >>> +} >>> + >>> +void f(na::OUTSIDER_1); >>> + >>> +namespace nc { >>> +// This class is referenced as friend in OOP. >>> +class OUTSIDER_1; >>> + >>> +class OOP { >>> + friend struct OUTSIDER_1; >>> +}; >>> +} >>> + >>> +namespace nd { >>> +class OUTSIDER_1; >>> +void f(OUTSIDER_1 *); >>> +} >>> + >>> +namespace nb { >>> +class OUTSIDER_1; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration 'OUTSIDER_1' is >>> never referenced, but a declaration with the same name found in another >>> namespace 'na' >>> +// CHECK-MESSAGES: note: a declaration of 'OUTSIDER_1' is found here >>> +} >>> + >>> + >>> +namespace na { >>> +template<typename T> >>> +class T_C; >>> +} >>> + >>> +namespace nb { >>> +// FIXME: this is an error, but we don't consider template class >>> declaration >>> +// now. >>> +template<typename T> >>> +class T_C; >>> +} >>> + >>> +namespace na { >>> +template<typename T> >>> +class T_C { >>> + int x; >>> +}; >>> +} >>> + >>> +namespace na { >>> + >>> +template <typename T> >>> +class T_TEMP { >>> + template <typename _Tp1> >>> + struct rebind { typedef T_TEMP<_Tp1> other; }; >>> +}; >>> + >>> +// We ignore class template specialization. >>> +template class T_TEMP<char>; >>> +} >>> + >>> +namespace nb { >>> + >>> +template <typename T> >>> +class T_TEMP_1 { >>> + template <typename _Tp1> >>> + struct rebind { typedef T_TEMP_1<_Tp1> other; }; >>> +}; >>> + >>> +// We ignore class template specialization. >>> +extern template class T_TEMP_1<char>; >>> +} >>> + >>> +namespace nd { >>> +class D; >>> +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: declaration 'D' is never >>> referenced, but a declaration with the same name found in another namespace >>> 'nd::ne' >>> +// CHECK-MESSAGES: note: a declaration of 'D' is found here >>> +} >>> + >>> +namespace nd { >>> +namespace ne { >>> +class D; >>> +} >>> +} >>> + >>> +int f(nd::ne::D &d); >>> + >>> + >>> +// This should be ignored by the check. >>> +template <typename... Args> >>> +class Observer { >>> + class Impl; >>> +}; >>> + >>> +template <typename... Args> >>> +class Observer<Args...>::Impl { >>> +}; >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits