Index: clang-tidy/modernize/UseOverrideCheck.cpp =================================================================== --- clang-tidy/modernize/UseOverrideCheck.cpp +++ clang-tidy/modernize/UseOverrideCheck.cpp @@ -95,9 +95,9 @@ : "'override' is"; StringRef Correct = HasFinal ? "'final'" : "'override'"; - Message = - (llvm::Twine(Redundant) + - " redundant since the function is already declared " + Correct).str(); + Message = (llvm::Twine(Redundant) + + " redundant since the function is already declared " + Correct) + .str(); } DiagnosticBuilder Diag = diag(Method->getLocation(), Message); @@ -118,9 +118,11 @@ if (!HasFinal && !HasOverride) { SourceLocation InsertLoc; StringRef ReplacementText = "override "; + SourceLocation MethodLoc = Method->getLocation(); for (Token T : Tokens) { - if (T.is(tok::kw___attribute)) { + if (T.is(tok::kw___attribute) && + !Sources.isBeforeInTranslationUnit(T.getLocation(), MethodLoc)) { InsertLoc = T.getLocation(); break; } @@ -128,11 +130,12 @@ if (Method->hasAttrs()) { for (const clang::Attr *A : Method->getAttrs()) { - if (!A->isImplicit()) { + if (!A->isImplicit() && !A->isInherited()) { SourceLocation Loc = Sources.getExpansionLoc(A->getRange().getBegin()); - if (!InsertLoc.isValid() || - Sources.isBeforeInTranslationUnit(Loc, InsertLoc)) + if ((!InsertLoc.isValid() || + Sources.isBeforeInTranslationUnit(Loc, InsertLoc)) && + !Sources.isBeforeInTranslationUnit(Loc, MethodLoc)) InsertLoc = Loc; } } @@ -163,6 +166,9 @@ Tokens.back().is(tok::kw_delete)) && GetText(Tokens[Tokens.size() - 2], Sources) == "=") { InsertLoc = Tokens[Tokens.size() - 2].getLocation(); + // Check if we need to insert a space. + if ((Tokens[Tokens.size() - 2].getFlags() & Token::LeadingSpace) == 0) + ReplacementText = " override "; } else if (GetText(Tokens.back(), Sources) == "ABSTRACT") { InsertLoc = Tokens.back().getLocation(); } Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -67,6 +67,12 @@ This check selectively replaces string literals containing escaped characters with raw string literals. + +- Improved ``modernize-use-override`` check + + The fix-its placement around __declspec attributes on windows and other + attributes is improved. + Clang-tidy changes from 3.7 to 3.8 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Index: test/clang-tidy/modernize-use-override-ms.cpp =================================================================== --- /dev/null +++ test/clang-tidy/modernize-use-override-ms.cpp @@ -0,0 +1,30 @@ +// RUN: %check_clang_tidy %s modernize-use-override %t -- -- -fms-extensions + +// This test is designed to test ms-extension __declspec(dllexport) attributes. +// On non-windows platforms these are not available so we test visibility attributes instead. +#if defined(_MSC_VER) +# define EXPORT __declspec(dllexport) +#else +# define EXPORT __attribute__((visibility("default"))) +#endif + +class Base { + virtual EXPORT void a(); +}; + +class EXPORT InheritedBase { + virtual void a(); +}; + +class Derived : public Base { + virtual EXPORT void a(); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override] + // CHECK-FIXES: {{^}} EXPORT void a() override; +}; + +class EXPORT InheritedDerived : public InheritedBase { + virtual void a(); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' [modernize-use-override] + // CHECK-FIXES: {{^}} void a() override; +}; + Index: test/clang-tidy/modernize-use-override.cpp =================================================================== --- test/clang-tidy/modernize-use-override.cpp +++ test/clang-tidy/modernize-use-override.cpp @@ -21,6 +21,7 @@ virtual void d2(); virtual void e() = 0; virtual void f() = 0; + virtual void f2() const = 0; virtual void g() = 0; virtual void j() const; @@ -74,7 +75,11 @@ virtual void f()=0; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void f()override =0; + // CHECK-FIXES: {{^}} void f() override =0; + + virtual void f2() const=0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void f2() const override =0; virtual void g() ABSTRACT; // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using