diff options
author | Alexander Kornienko <alexfh@google.com> | 2017-02-07 11:39:56 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2017-02-07 11:39:56 +0000 |
commit | 258d9a528eb292970f25bf7036c11b7bd6380d87 (patch) | |
tree | dd12cd7e7c8951f2f2ae69a6c1910af830478d38 /clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp | |
parent | 59542bb08ac237d2e315f73077387e925ba73a51 (diff) | |
download | bcm5719-llvm-258d9a528eb292970f25bf7036c11b7bd6380d87.tar.gz bcm5719-llvm-258d9a528eb292970f25bf7036c11b7bd6380d87.zip |
[clang-tidy] misc-argument-comment - extended gmock support
It looks like direct calls to mocked methods happen in the wild. This patch
add support for these as well.
llvm-svn: 294293
Diffstat (limited to 'clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp')
-rw-r--r-- | clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp b/clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp index cad112bfb67..d7ac9f3a9b3 100644 --- a/clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ArgumentCommentCheck.cpp @@ -147,33 +147,43 @@ static bool sameName(StringRef InComment, StringRef InDecl, bool StrictMode) { return InComment.compare_lower(InDecl) == 0; } +static bool looksLikeExpectMethod(const CXXMethodDecl *Expect) { + return Expect != nullptr && Expect->getLocation().isMacroID() && + Expect->getNameInfo().getName().isIdentifier() && + Expect->getName().startswith("gmock_"); +} +static bool areMockAndExpectMethods(const CXXMethodDecl *Mock, + const CXXMethodDecl *Expect) { + assert(looksLikeExpectMethod(Expect)); + return Mock != nullptr && Mock->getNextDeclInContext() == Expect && + Mock->getNumParams() == Expect->getNumParams() && + Mock->getLocation().isMacroID() && + Mock->getNameInfo().getName().isIdentifier() && + Mock->getName() == Expect->getName().substr(strlen("gmock_")); +} + // This uses implementation details of MOCK_METHODx_ macros: for each mocked // method M it defines M() with appropriate signature and a method used to set // up expectations - gmock_M() - with each argument's type changed the -// corresponding matcher. This function finds M by gmock_M. -static const CXXMethodDecl * -findMockedMethod(const CXXMethodDecl *ExpectMethod) { - if (!ExpectMethod->getNameInfo().getName().isIdentifier()) - return nullptr; - StringRef Name = ExpectMethod->getName(); - if (!Name.startswith("gmock_")) - return nullptr; - Name = Name.substr(strlen("gmock_")); - - const DeclContext *Ctx = ExpectMethod->getDeclContext(); - if (Ctx == nullptr || !Ctx->isRecord()) - return nullptr; - for (const auto *D : Ctx->decls()) { - if (const auto *Method = dyn_cast<CXXMethodDecl>(D)) { - if (Method->getName() != Name) - continue; - // Sanity check the mocked method. - if (Method->getNextDeclInContext() == ExpectMethod && - Method->getLocation().isMacroID() && - Method->getNumParams() == ExpectMethod->getNumParams()) { - return Method; +// corresponding matcher. This function returns M when given either M or +// gmock_M. +static const CXXMethodDecl *findMockedMethod(const CXXMethodDecl *Method) { + if (looksLikeExpectMethod(Method)) { + const DeclContext *Ctx = Method->getDeclContext(); + if (Ctx == nullptr || !Ctx->isRecord()) + return nullptr; + for (const auto *D : Ctx->decls()) { + if (D->getNextDeclInContext() == Method) { + const auto *Previous = dyn_cast<CXXMethodDecl>(D); + return areMockAndExpectMethods(Previous, Method) ? Previous : nullptr; } } + return nullptr; + } + if (const auto *Next = dyn_cast_or_null<CXXMethodDecl>( + Method->getNextDeclInContext())) { + if (looksLikeExpectMethod(Next) && areMockAndExpectMethods(Method, Next)) + return Method; } return nullptr; } |