Add a new clang-tidy module for Fuchsia as an umbrella to diagnose issues with the Fuschia and Zircon coding guidelines (https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md). Adds the first of such checkers, which detects when default arguments are declared in a function declaration or when default arguments are used at call sites.

Patch by Julie Hockett

llvm-svn: 319225
diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt
index 0a3de85..a307ec0 100644
--- a/clang-tools-extra/clang-tidy/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/CMakeLists.txt
@@ -31,6 +31,7 @@
 add_subdirectory(bugprone)
 add_subdirectory(cert)
 add_subdirectory(cppcoreguidelines)
+add_subdirectory(fuchsia)
 add_subdirectory(google)
 add_subdirectory(hicpp)
 add_subdirectory(llvm)
diff --git a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
new file mode 100644
index 0000000..4a57419
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyFuchsiaModule
+  DefaultArgumentsCheck.cpp
+  FuchsiaTidyModule.cpp
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangLex
+  clangTidy
+  clangTidyUtils
+  )
diff --git a/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
new file mode 100644
index 0000000..493ce9a
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
@@ -0,0 +1,64 @@
+//===--- DefaultArgumentsCheck.cpp - clang-tidy----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DefaultArgumentsCheck.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+void DefaultArgumentsCheck::registerMatchers(MatchFinder *Finder) {
+  // Calling a function which uses default arguments is disallowed.
+  Finder->addMatcher(cxxDefaultArgExpr().bind("stmt"), this);
+  // Declaring default parameters is disallowed.
+  Finder->addMatcher(parmVarDecl(hasDefaultArgument()).bind("decl"), this);
+}
+
+void DefaultArgumentsCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const auto *S =
+          Result.Nodes.getNodeAs<CXXDefaultArgExpr>("stmt")) {
+    diag(S->getUsedLocation(),
+         "calling a function that uses a default argument is disallowed");
+    diag(S->getParam()->getLocStart(),
+        "default parameter was declared here",
+         DiagnosticIDs::Note);
+  } else if (const ParmVarDecl *D =
+          Result.Nodes.getNodeAs<ParmVarDecl>("decl")) {
+    SourceRange DefaultArgRange = D->getDefaultArgRange();
+
+    if (DefaultArgRange.getEnd() != D->getLocEnd()) {
+      return;
+    } else if (DefaultArgRange.getBegin().isMacroID()) {
+      diag(D->getLocStart(),
+           "declaring a parameter with a default argument is disallowed");
+    } else {
+      SourceLocation StartLocation = D->getName().empty() ?
+              D->getLocStart() : D->getLocation();
+
+      SourceRange RemovalRange(Lexer::getLocForEndOfToken(
+             StartLocation, 0,
+             *Result.SourceManager,
+             Result.Context->getLangOpts()
+           ),
+           DefaultArgRange.getEnd()
+         );
+
+      diag(D->getLocStart(),
+          "declaring a parameter with a default argument is disallowed")
+          << D
+          << FixItHint::CreateRemoval(RemovalRange);
+    }
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsCheck.h b/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsCheck.h
new file mode 100644
index 0000000..f54fd96
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/fuchsia/DefaultArgumentsCheck.h
@@ -0,0 +1,35 @@
+//===--- DefaultArgumentsCheck.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_FUCHSIA_DEFAULT_ARGUMENTS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_DEFAULT_ARGUMENTS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Default arguments are not allowed in declared or called functions.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-default-arguments.html
+class DefaultArgumentsCheck : public ClangTidyCheck {
+public:
+  DefaultArgumentsCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_DEFAULT_ARGUMENTS_H
diff --git a/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp b/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
new file mode 100644
index 0000000..812d551
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
@@ -0,0 +1,39 @@
+//===--- FuchsiaTidyModule.cpp - clang-tidy--------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../ClangTidy.h"
+#include "../ClangTidyModule.h"
+#include "../ClangTidyModuleRegistry.h"
+#include "DefaultArgumentsCheck.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// This module is for Fuchsia specific checks.
+class FuchsiaModule : public ClangTidyModule {
+public:
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<DefaultArgumentsCheck>(
+        "fuchsia-default-arguments");
+  }
+};
+// Register the FuchsiaTidyModule using this statically initialized variable.
+static ClangTidyModuleRegistry::Add<FuchsiaModule>
+    X("fuchsia-module", "Adds Fuchsia platform checks.");
+} // namespace fuchsia
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the FuchsiaModule.
+volatile int FuchsiaModuleAnchorSource = 0;
+
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/tool/CMakeLists.txt b/clang-tools-extra/clang-tidy/tool/CMakeLists.txt
index 092d4ec..37bb7c1 100644
--- a/clang-tools-extra/clang-tidy/tool/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/tool/CMakeLists.txt
@@ -21,6 +21,7 @@
   clangTidyBugproneModule
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
+  clangTidyFuchsiaModule
   clangTidyGoogleModule
   clangTidyHICPPModule
   clangTidyLLVMModule
diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
index 6f1718f..b5fdac4 100644
--- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
+++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp
@@ -483,6 +483,11 @@
     CppCoreGuidelinesModuleAnchorSource;
 
 // This anchor is used to force the linker to link the GoogleModule.
+extern volatile int FuchsiaModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED FuchsiaModuleAnchorDestination =
+    FuchsiaModuleAnchorSource;
+
+// This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
     GoogleModuleAnchorSource;