juliehockett created this revision.
juliehockett added a project: clang-tools-extra.
Herald added subscribers: xazax.hun, mgorny.

This adds a Fuchsia module to clang-tidy to warn for features that are 
disallowed. The following checks were added to the new module:

fuchsia-default-arguments: Check to prevent use of default arguments in 
declared or called functions.
fuchsia-overloaded-operator: Check to prevent operator overloading.
fuchsia-statically-constructed-objects: Check to prevent creation of  
statically-stored objects.
fuchsia-thread-local: Check to prevent thread-local storage.
fuchsia-trailing-return: Check to prevent functions with trailing returns.
fuchsia-virtual-inheritance: Check to prevent the definition of classes with 
virtual inheritance.
fuchsia-multiple-inheritance: Check to prevent multiple inheritance in Fuchsia.

Tests and documentation are also updated.


https://reviews.llvm.org/D40108

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/fuchsia/CMakeLists.txt
  clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
  clang-tidy/fuchsia/DefaultArgumentsCheck.h
  clang-tidy/fuchsia/FuchsiaTidyModule.cpp
  clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
  clang-tidy/fuchsia/MultipleInheritanceCheck.h
  clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
  clang-tidy/fuchsia/OverloadedOperatorCheck.h
  clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
  clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
  clang-tidy/fuchsia/ThreadLocalCheck.cpp
  clang-tidy/fuchsia/ThreadLocalCheck.h
  clang-tidy/fuchsia/TrailingReturnCheck.cpp
  clang-tidy/fuchsia/TrailingReturnCheck.h
  clang-tidy/fuchsia/VirtualInheritanceCheck.cpp
  clang-tidy/fuchsia/VirtualInheritanceCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/fuchsia-default-arguments.rst
  docs/clang-tidy/checks/fuchsia-multiple-inheritance.rst
  docs/clang-tidy/checks/fuchsia-overloaded-operator.rst
  docs/clang-tidy/checks/fuchsia-statically-constructed-objects.rst
  docs/clang-tidy/checks/fuchsia-thread-local.rst
  docs/clang-tidy/checks/fuchsia-trailing-return.rst
  docs/clang-tidy/checks/fuchsia-virtual-inheritance.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/fuchsia-default-arguments.cpp
  test/clang-tidy/fuchsia-multiple-inheritance.cpp
  test/clang-tidy/fuchsia-overloaded-operator.cpp
  test/clang-tidy/fuchsia-statically-constructed-objects.cpp
  test/clang-tidy/fuchsia-thread-local.cpp
  test/clang-tidy/fuchsia-trailing-return.cpp
  test/clang-tidy/fuchsia-virtual-inheritance.cpp

Index: test/clang-tidy/fuchsia-virtual-inheritance.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-virtual-inheritance.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s fuchsia-virtual-inheritance %t
+
+class A {
+public:
+  A(int value) : val(value) {}
+
+  int do_A() { return val; }
+
+private:
+  int val;
+};
+
+class B : public virtual A {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: [kernel-c++] virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT: class B : public virtual A {
+public:
+  B() : A(0) {}
+  int do_B() { return 1 + do_A(); }
+};
+
+class C : public virtual A {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: [kernel-c++] virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT: class C : public virtual A {
+public:
+  C() : A(0) {}
+  int do_C() { return 2 + do_A(); }
+};
+
+class D : public B, public C {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: [kernel-c++] virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT: class C : public B, public C {
+public:
+  D(int value) : A(value), B(), C() {}
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: [kernel-c++] constructing a class which inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT:  D(int value) : A(value), B(), C() {}
+  // CHECK-MESSAGES: [[@LINE-3]]:33: warning: [kernel-c++] constructing a class which inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT:  D(int value) : A(value), B(), C() {}
+
+  int do_D() { return do_A() + do_B() + do_C(); }
+};
+
+int main(void) {
+  A *a = new A(0);
+  B *b = new B();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: [kernel-c++] constructing a class which inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT:  B *b = new B();
+  C *c = new C();
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: [kernel-c++] constructing a class which inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT:  C *c = new C();
+  D *d = new D(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: [kernel-c++] constructing a class which inherits a virtual base class is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT:  D *d = new D(0);
+  return 0;
+}
Index: test/clang-tidy/fuchsia-trailing-return.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-trailing-return.cpp
@@ -0,0 +1,14 @@
+// RUN: %check_clang_tidy %s fuchsia-trailing-return %t
+
+int add_one(const int arg) { return arg; }
+
+auto get_add_one() -> int (*)(const int) {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: trailing returns are disallowed
+  // CHECK-NEXT: auto get_add_one() -> int (*)(const int) {
+  return add_one;
+}
+
+int main(void) {
+  get_add_one()(5);
+  return 0;
+}
Index: test/clang-tidy/fuchsia-thread-local.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-thread-local.cpp
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s fuchsia-thread-local %t
+
+int main(void) {
+  thread_local int foo;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: thread local storage is disallowed
+  // CHECK-NEXT:  thread_local int foo;
+
+  extern thread_local int bar;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: thread local storage is disallowed
+  // CHECK-NEXT:  extern thread_local int bar;
+  int baz;
+  return 0;
+}
Index: test/clang-tidy/fuchsia-statically-constructed-objects.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-statically-constructed-objects.cpp
@@ -0,0 +1,46 @@
+// RUN: %check_clang_tidy %s fuchsia-statically-constructed-objects %t
+
+class AdderClass {
+public:
+  AdderClass(int value1, int value2) : val(value1 + value2) {}
+  constexpr AdderClass(int value) : val(value) {}
+
+private:
+  int val;
+};
+
+struct mystruct {
+  int a;
+};
+
+struct mystruct_with_method {
+  int a;
+  void b() { a++; }
+};
+
+struct static_mystruct_container {
+  int a;
+  static int b;
+  static struct mystruct c;
+};
+
+int main(void) {
+
+  static AdderClass a(1, 2);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: statically constructed objects are disallowed
+  // CHECK-NEXT:  static AdderClass a(1, 2);
+
+  // Allowed (constexpr ctor)
+  static AdderClass b(0);
+
+  static struct mystruct c;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: statically constructed objects are disallowed
+  // CHECK-NEXT:  static struct mystruct c;
+
+  static struct mystruct_with_method d;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: statically constructed objects are disallowed
+  // CHECK-NEXT:  static struct mystruct_with_method d;
+
+  static int e;
+  struct static_mystruct_container f;
+}
Index: test/clang-tidy/fuchsia-overloaded-operator.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-overloaded-operator.cpp
@@ -0,0 +1,15 @@
+// RUN: %check_clang_tidy %s fuchsia-overloaded-operator %t
+
+class A {
+public:
+  int operator+(int);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: operator overloading is disallowed [fuchsia-overloaded-operator]
+};
+
+class B {
+public:
+  B &operator=(B other);
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:3: warning: operator overloading is disallowed [fuchsia-overloaded-operator]
+  B &operator=(B &&other);
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:3: warning: operator overloading is disallowed [fuchsia-overloaded-operator]
+};
Index: test/clang-tidy/fuchsia-multiple-inheritance.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-multiple-inheritance.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s fuchsia-multiple-inheritance %t
+
+class Base_A {
+public:
+  virtual int foo() { return 0; }
+};
+
+class Base_B {
+public:
+  virtual int bar() { return 0; }
+};
+
+class Base_A_child : public Base_A {
+public:
+  virtual int baz() { return 0; }
+};
+
+class Interface_A {
+public:
+  virtual int foo() = 0;
+};
+
+class Interface_B {
+public:
+  virtual int bar() = 0;
+};
+
+class Interface_C {
+public:
+  virtual int blat() = 0;
+};
+
+class Interface_A_with_member {
+public:
+  virtual int foo() = 0;
+  int val = 0;
+};
+
+class Interface_with_A_Parent : public Base_A {
+public:
+  virtual int baz() = 0;
+};
+
+// Inherits from multiple concrete classes.
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes which aren't pure virtual is disallowed [fuchsia-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {};
+class Bad_Child1 : public Base_A, Base_B {};
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting mulitple classes which aren't pure virtual is disallowed [fuchsia-multiple-inheritance]
+class Bad_Child2 : public Base_A, Interface_A_with_member {
+  virtual int foo() override { return 0; }
+};
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes which aren't pure virtual is disallowed [fuchsia-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+  virtual int baz() override { return 0; }
+};
+
+// Easy cases of single inheritance
+class Simple_Child1 : public Base_A {};
+class Simple_Child2 : public Interface_A {
+  virtual int foo() override { return 0; }
+};
+
+// Valid uses of multiple inheritance
+class Good_Child1 : public Interface_A, Interface_B {
+  virtual int foo() override { return 0; }
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child2 : public Base_A, Interface_B {
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child3 : public Base_A_child, Interface_C, Interface_B {
+  virtual int bar() override { return 0; }
+  virtual int blat() override { return 0; }
+};
+
+int main(void) {
+  Bad_Child1 a;
+  Bad_Child2 b;
+  Bad_Child3 c;
+  Simple_Child1 d;
+  Simple_Child2 e;
+  Good_Child1 f;
+  Good_Child2 g;
+  Good_Child3 h;
+  return 0;
+}
Index: test/clang-tidy/fuchsia-default-arguments.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fuchsia-default-arguments.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s fuchsia-default-arguments %t
+
+int foo(int value = 5) { return value; }
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: declaring functions which use default arguments is disallowed [fuchsia-default-arguments]
+
+int f(void) {
+  foo();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling functions which use default arguments is disallowed [fuchsia-default-arguments]
+  // CHECK-NEXT: note: the default parameter was declared here:
+  // CHECK-NEXT: int foo(int value = 5) { return value; }
+}
+
+// Negatives.
+int bar(int value) { return value; }
+
+int n(void) {
+  foo(0);
+  bar(0);
+}
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -54,6 +54,13 @@
    cppcoreguidelines-pro-type-vararg
    cppcoreguidelines-slicing
    cppcoreguidelines-special-member-functions
+   fuchsia-default-arguments
+   fuchsia-multiple-inheritance
+   fuchsia-overloaded-operator
+   fuchsia-statically-constructed-objects
+   fuchsia-thread-local
+   fuchsia-trailing-return
+   fuchsia-virtual-inheritance
    google-build-explicit-make-pair
    google-build-namespaces
    google-build-using-namespace
Index: docs/clang-tidy/checks/fuchsia-virtual-inheritance.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-virtual-inheritance.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - fuchsia-virtual-inheritance
+
+fuchsia-virtual-inheritance
+===========================
+
+Warns if classes are defined or created with virtual inheritance.
+
+Ex. Classes should not be defined with virtual inheritance:
+
+.. code-block:: c++
+
+  class B : public virtual A {}   // warning
+
+Classes with virtual inheritance should not be created:
+
+.. code-block:: c++
+
+  B *b = new B();   // warning
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/clang-tidy/checks/fuchsia-trailing-return.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-trailing-return.rst
@@ -0,0 +1,20 @@
+.. title:: clang-tidy - fuchsia-trailing-return
+
+fuchsia-trailing-return
+=======================
+
+Warns if a function has a trailing return.
+
+Ex.
+
+.. code-block:: c++
+
+  // No warning
+  int add_one(const int arg) { return arg; }
+
+  // Warning
+  auto get_add_one() -> int (*)(const int) {
+    return add_one;
+  }
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/clang-tidy/checks/fuchsia-thread-local.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-thread-local.rst
@@ -0,0 +1,15 @@
+.. title:: clang-tidy - fuchsia-thread-local
+
+fuchsia-thread-local
+====================
+
+Warns if thread-local storage is used.
+
+Ex. Using thread_local or extern thread_local is not allowed:
+
+.. code-block:: c++
+
+  thread_local int foo;           // Warning
+  extern thread_local int bar;    // Warning
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/clang-tidy/checks/fuchsia-statically-constructed-objects.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-statically-constructed-objects.rst
@@ -0,0 +1,32 @@
+.. title:: clang-tidy - fuchsia-statically-constructed-objects
+
+fuchsia-statically-constructed-objects
+======================================
+
+Warns if statically-stored objects are created, unless constructed
+with constexpr.
+
+Ex. Creating static classes or structs is not allowed:
+
+.. code-block:: c++
+
+  class AdderClass {
+  public:
+    AdderClass(int value1, int value2) : val(value1 + value2) {}
+    constexpr AdderClass(int value) : val(value) {}
+
+  private:
+    int val;
+  };
+
+  // Will cause warning
+  static AdderClass a(1, 2);
+
+But creation of static objects using constexpr constructors is allowed:
+
+.. code-block:: c++
+
+  // No warning
+  static AdderClass b(0);
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/clang-tidy/checks/fuchsia-overloaded-operator.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-overloaded-operator.rst
@@ -0,0 +1,17 @@
+.. title:: clang-tidy - fuchsia-overloaded-operator
+
+fuchsia-overloaded-operator
+===========================
+
+Warns if an operator is overloaded, except for the copy and move operators.
+
+Ex.
+
+.. code-block:: c++
+
+  int operator+(int);     // Warning
+
+  B &operator=(B other);  // No warning
+  B &operator=(B &&other) // No warning
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/clang-tidy/checks/fuchsia-multiple-inheritance.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-multiple-inheritance.rst
@@ -0,0 +1,46 @@
+.. title:: clang-tidy - fuchsia-multiple-inheritance
+
+fuchsia-multiple-inheritance
+============================
+
+Warns if a function inherits from multiple classes that are not pure virtual.
+
+Ex: Declaring a class that inherits from multiple concrete classes is
+disallowed:
+
+.. code-block:: c++
+
+  class Base_A {
+  public:
+    virtual int foo() { return 0; }
+  };
+
+  class Base_B {
+  public:
+    virtual int bar() { return 0; }
+  };
+
+  // Warning
+  class Bad_Child1 : public Base_A, Base_B {};
+
+A class that inherits from a pure virtual is allowed:
+
+.. code-block:: c++
+
+  class Interface_A {
+  public:
+    virtual int foo() = 0;
+  };
+
+  class Interface_B {
+  public:
+    virtual int bar() = 0;
+  };
+
+  // No warning
+  class Good_Child1 : public Interface_A, Interface_B {
+    virtual int foo() override { return 0; }
+    virtual int bar() override { return 0; }
+  };
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/clang-tidy/checks/fuchsia-default-arguments.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fuchsia-default-arguments.rst
@@ -0,0 +1,24 @@
+.. title:: clang-tidy - fuchsia-default-arguments
+
+fuchsia-default-arguments
+=========================
+
+Warns if a function is declared or called with default arguments.
+
+Ex. The declaration:
+
+.. code-block:: c++
+
+  int foo(int value = 5) { return value; }
+
+will cause a warning.
+
+If a function with default arguments is already defined, calling it with no
+arguments will also cause a warning. Calling it without defaults will not cause
+a warning:
+.. code-block:: c++
+
+  foo();  // warning
+  foo(0); // no warning
+
+See the features disallowed in Fuchsia at https://fuchsia.googlesource.com/zircon/+/master/docs/cxx.md
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,41 @@
 Improvements to clang-tidy
 --------------------------
 
+- New `fuchsia-multiple-inheritance
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-multiple-inheritance.html>`_ check
+
+  Check to prevent multiple inheritance in Fuchsia.
+
+- New `fuchsia-virtual-inheritance
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-virtual-inheritance.html>`_ check
+
+  Check to prevent the definition of classes with virtual inheritance.
+
+- New `fuchsia-trailing-return
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-trailing-return.html>`_ check
+
+  Check to prevent functions with trailing returns in Fuchsia.
+
+- New `fuchsia-thread-local
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-thread-local.html>`_ check
+
+  Check to prevent thread-local storage in Fuchsia.
+
+- New `fuchsia-statically-constructed-objects
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-statically-constructed-objects.html>`_ check
+
+  Check to prevent creation of  statically-stored objects in Fuchsia.
+
+- New `fuchsia-overloaded-operator
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-overloaded-operator.html>`_ check
+
+  Check to prevent operator overloading in Fuchsia.
+
+- New `fuchsia-default-arguments
+  <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-default-arguments.html>`_ check
+
+  Check to prevent use of default arguments in declared or called functions in Fuchsia.
+
 - New `objc-property-declaration
   <http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html>`_ check
 
@@ -67,8 +102,8 @@
 - New `google-objc-global-variable-declaration
   <http://clang.llvm.org/extra/clang-tidy/checks/google-global-variable-declaration.html>`_ check
 
-  Add new check for Objective-C code to ensure global 
-  variables follow the naming convention of 'k[A-Z].*' (for constants) 
+  Add new check for Objective-C code to ensure global
+  variables follow the naming convention of 'k[A-Z].*' (for constants)
   or 'g[A-Z].*' (for variables).
 
 - New module `objc` for Objective-C style checks.
@@ -137,21 +172,21 @@
   Finds cases where integer division in a floating point context is likely to
   cause unintended loss of precision.
 
-- New `cppcoreguidelines-owning-memory <http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-owning-memory.html>`_ check 
+- New `cppcoreguidelines-owning-memory <http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-owning-memory.html>`_ check
 
   This check implements the type-based semantic of ``gsl::owner<T*>``, but without
   flow analysis.
 
 - New `hicpp-exception-baseclass
   <http://clang.llvm.org/extra/clang-tidy/checks/hicpp-exception-baseclass.html>`_ check
 
-  Ensures that all exception will be instances of ``std::exception`` and classes 
+  Ensures that all exception will be instances of ``std::exception`` and classes
   that are derived from it.
 
 - New `hicpp-signed-bitwise
   <http://clang.llvm.org/extra/clang-tidy/checks/hicpp-signed-bitwise.html>`_ check
 
-  Finds uses of bitwise operations on signed integer types, which may lead to 
+  Finds uses of bitwise operations on signed integer types, which may lead to
   undefined or implementation defined behaviour.
 
 - New `android-cloexec-inotify-init1
@@ -170,7 +205,7 @@
   <http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-emplace.html#cmdoption-arg-IgnoreImplicitConstructors>`_
   option.
 
-- Added aliases for the `High Integrity C++ Coding Standard <http://www.codingstandard.com/section/index/>`_ 
+- Added aliases for the `High Integrity C++ Coding Standard <http://www.codingstandard.com/section/index/>`_
   to already implemented checks in other modules.
 
   - `hicpp-deprecated-headers <http://clang.llvm.org/extra/clang-tidy/checks/hicpp-deprecated-headers.html>`_
Index: clang-tidy/tool/ClangTidyMain.cpp
===================================================================
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -482,6 +482,11 @@
 static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
     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 =
Index: clang-tidy/tool/CMakeLists.txt
===================================================================
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -21,6 +21,7 @@
   clangTidyBugproneModule
   clangTidyCERTModule
   clangTidyCppCoreGuidelinesModule
+  clangTidyFuchsiaModule
   clangTidyGoogleModule
   clangTidyHICPPModule
   clangTidyLLVMModule
Index: clang-tidy/fuchsia/VirtualInheritanceCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/VirtualInheritanceCheck.h
@@ -0,0 +1,35 @@
+//===--- VirtualInheritanceCheck.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_VIRTUAL_INHERITANCE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_VIRTUAL_INHERITANCE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Defining classes with virtual inheritance is disallowed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-virtual-inheritance.html
+class VirtualInheritanceCheck : public ClangTidyCheck {
+public:
+  VirtualInheritanceCheck(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_VIRTUAL_INHERITANCE_H
Index: clang-tidy/fuchsia/VirtualInheritanceCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/VirtualInheritanceCheck.cpp
@@ -0,0 +1,54 @@
+//===--- VirtualInheritanceCheck.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 "VirtualInheritanceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+AST_MATCHER(CXXRecordDecl, hasVirtualBaseClass) {
+  return Node.hasDefinition() && (Node.getNumVBases() != 0);
+}
+
+void VirtualInheritanceCheck::registerMatchers(MatchFinder *Finder) {
+  // Defining classes using virtual inheritance is disallowed.
+  Finder->addMatcher(cxxRecordDecl(hasVirtualBaseClass()).bind("decl"), this);
+  // Calling constructors of classes using virtual inheritance is disallowed.
+  // To clarify, this matcher finds, in order:
+  //  1) Calls to Constructors,
+  //  2) The declarations of those constructors,
+  //  3) The classes those constructors belong to,
+  //  4) And matches the classes which have virtual base classes.
+  Finder->addMatcher(
+      cxxConstructExpr(hasDeclaration(cxxConstructorDecl(
+                           ofClass(cxxRecordDecl(hasVirtualBaseClass())))))
+          .bind("stmt"),
+      this);
+}
+
+void VirtualInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const CXXRecordDecl *D =
+            Result.Nodes.getNodeAs<CXXRecordDecl>("decl")) {
+    diag(D->getLocStart(), "[kernel-c++] virtual inheritance is disallowed");
+  } else if (const CXXConstructExpr *S =
+            Result.Nodes.getNodeAs<CXXConstructExpr>("stmt")) {
+    diag(S->getLocStart(),
+        "[kernel-c++] constructing a class which inherits "
+        "a virtual base class is disallowed");
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/TrailingReturnCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/TrailingReturnCheck.h
@@ -0,0 +1,35 @@
+//===--- TrailingReturnCheck.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_TRAILING_RETURN_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_TRAILING_RETURN_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Functions with trailing returns are disallowed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-trailing-return.html
+class TrailingReturnCheck : public ClangTidyCheck {
+public:
+  TrailingReturnCheck(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_TRAILING_RETURN_H
Index: clang-tidy/fuchsia/TrailingReturnCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/TrailingReturnCheck.cpp
@@ -0,0 +1,39 @@
+//===--- TrailingReturnCheck.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 "TrailingReturnCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+AST_MATCHER(FunctionDecl, hasTrailingReturn) {
+  const Type *T = Node.getType().getTypePtr();
+  const FunctionProtoType *F = cast<FunctionProtoType>(T);
+  return F->hasTrailingReturn();
+}
+
+void TrailingReturnCheck::registerMatchers(MatchFinder *Finder) {
+  // Functions which have trailing returns are disallowed.
+  Finder->addMatcher(functionDecl(hasTrailingReturn()).bind("decl"), this);
+}
+
+void TrailingReturnCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const Decl *D = Result.Nodes.getNodeAs<Decl>("decl")) {
+    diag(D->getLocStart(), "trailing returns are disallowed");
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/ThreadLocalCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/ThreadLocalCheck.h
@@ -0,0 +1,35 @@
+//===--- ThreadLocalCheck.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_THREAD_LOCAL_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_THREAD_LOCAL_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Thread-local storage is disallowed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-thread-local.html
+class ThreadLocalCheck : public ClangTidyCheck {
+public:
+  ThreadLocalCheck(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_THREAD_LOCAL_H
Index: clang-tidy/fuchsia/ThreadLocalCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/ThreadLocalCheck.cpp
@@ -0,0 +1,33 @@
+//===--- ThreadLocalCheck.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 "ThreadLocalCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+void ThreadLocalCheck::registerMatchers(MatchFinder *Finder) {
+  // Using thread-local storage is disallowed.
+    Finder->addMatcher(varDecl(hasThreadStorageDuration()).bind("decl"), this);
+}
+
+void ThreadLocalCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>("decl")) {
+    diag(D->getLocStart(), "thread local storage is disallowed");
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h
@@ -0,0 +1,35 @@
+//===--- StaticallyConstructedObjectsCheck.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_STATICALLY_CONSTRUCTED_OBJECTS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_STATICALLY_CONSTRUCTED_OBJECTS_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Constructing objects which are statically stored is disallowed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-statically-constructed-objects.html
+class StaticallyConstructedObjectsCheck : public ClangTidyCheck {
+public:
+  StaticallyConstructedObjectsCheck(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_STATICALLY_CONSTRUCTED_OBJECTS_H
Index: clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp
@@ -0,0 +1,42 @@
+//===--- StaticallyConstructedObjectsCheck.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 "StaticallyConstructedObjectsCheck.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+void StaticallyConstructedObjectsCheck::registerMatchers(MatchFinder *Finder) {
+  // Constructing objects which are stored statically is disallowed.
+  Finder->addMatcher(
+      varDecl(allOf(
+                  // Match statically stored objects...
+                  hasStaticStorageDuration(),
+                  // ... which have C++ constructors...
+                  hasDescendant(cxxConstructExpr(unless(
+                      // ... that are not constexpr.
+                      hasDeclaration(cxxConstructorDecl(isConstexpr())))))))
+          .bind("decl"),
+      this);
+}
+
+void StaticallyConstructedObjectsCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const VarDecl *D = Result.Nodes.getNodeAs<VarDecl>("decl")) {
+      diag(D->getLocStart(), "statically constructed objects are disallowed");
+      diag(D->getLocStart(), "if possible, use a constexpr constructor instead",
+          DiagnosticIDs::Note);
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/OverloadedOperatorCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/OverloadedOperatorCheck.h
@@ -0,0 +1,35 @@
+//===--- OverloadedOperatorCheck.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_OVERLOADED_OPERATOR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_OVERLOADED_OPERATOR_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Operator overloading is disallowed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-overloaded-operator.html
+class OverloadedOperatorCheck : public ClangTidyCheck {
+public:
+  OverloadedOperatorCheck(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_OVERLOADED_OPERATOR_H
Index: clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/OverloadedOperatorCheck.cpp
@@ -0,0 +1,38 @@
+//===--- OverloadedOperatorCheck.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 "OverloadedOperatorCheck.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+AST_MATCHER(CXXMethodDecl, hasOverloadedOperator) {
+  if (Node.isCopyAssignmentOperator() || Node.isMoveAssignmentOperator()) {
+    return false;
+  }
+  return Node.isOverloadedOperator();
+}
+
+void OverloadedOperatorCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(cxxMethodDecl(hasOverloadedOperator()).bind("decl"), this);
+}
+
+void OverloadedOperatorCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const CXXMethodDecl *D =
+            Result.Nodes.getNodeAs<CXXMethodDecl>("decl")) {
+      diag(D->getLocStart(),"operator overloading is disallowed");
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/MultipleInheritanceCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/MultipleInheritanceCheck.h
@@ -0,0 +1,51 @@
+//===--- MultipleInheritanceCheck.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_MULTIPLE_INHERITANCE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLE_INHERITANCE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+/// Mulitple inheritance is disallowed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-multiple-inheritance.html
+class MultipleInheritanceCheck : public ClangTidyCheck {
+public:
+  MultipleInheritanceCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+  void onStartOfTranslationUnit() override {
+   InterfaceMap = new llvm::StringMap<bool>;
+  }
+  void onEndOfTranslationUnit() override { delete InterfaceMap; }
+
+  void addNodeToInterfaceMap(const CXXRecordDecl *Node, bool isInterface);
+  bool getInterfaceStatus(const CXXRecordDecl *Node, bool *isInterface);
+  bool isCurrentClassInterface(const CXXRecordDecl *Node);
+  bool isInterface(const CXXRecordDecl *Node);
+
+private:
+  // Contains the identity of each named CXXRecord as an interface.  This is used
+  // to memoize lookup speeds and improve performance from O(N^2) to O(N), where N
+  // is the number of classes.
+  llvm::StringMap<bool> *InterfaceMap;
+};
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLE_INHERITANCE_H
Index: clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -0,0 +1,121 @@
+//===--- MultipleInheritanceCheck.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 "MultipleInheritanceCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang;
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace fuchsia {
+
+  AST_MATCHER(CXXRecordDecl, hasDefinition) {
+    if (!Node.hasDefinition())
+      return false;
+    return true;
+  }
+
+// Adds a node (by name) to the interface map, if it was not present in the map
+// previously.
+void MultipleInheritanceCheck::addNodeToInterfaceMap(const CXXRecordDecl *Node,
+                            bool isInterface) {
+  StringRef Name = Node->getIdentifier()->getName();
+  MultipleInheritanceCheck::InterfaceMap->insert(
+                            std::make_pair(Name, isInterface));
+}
+
+// Returns "true" if the boolean "isInterface" has been set to the
+// interface status of the current Node. Return "false" if the
+// interface status for the current node is not yet known.
+bool MultipleInheritanceCheck::getInterfaceStatus(const CXXRecordDecl *Node,
+                            bool *isInterface) {
+  StringRef Name = Node->getIdentifier()->getName();
+  if (MultipleInheritanceCheck::InterfaceMap->count(Name)) {
+    *isInterface = MultipleInheritanceCheck::InterfaceMap->lookup(Name);
+    return true;
+  }
+  return false;
+}
+
+// TODO(smklein): Make an exception for 'Dispatcher' -- consider it an
+// interface, even though it isn't.
+bool MultipleInheritanceCheck::isCurrentClassInterface(
+                            const CXXRecordDecl *Node) {
+  // Interfaces should have no fields.
+  if (!Node->field_empty()) {
+    return false;
+  }
+  // Interfaces should have exclusively pure methods.
+  for (auto method : Node->methods()) {
+    if (method->isUserProvided() && !method->isPure()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
+  // Short circuit the lookup if we have analyzed this record before.
+  bool PreviousIsInterfaceResult;
+  if (MultipleInheritanceCheck::getInterfaceStatus(Node,
+                              &PreviousIsInterfaceResult)) {
+    return PreviousIsInterfaceResult;
+  }
+
+  // To be an interface, all base classes must be interfaces as well.
+  for (const auto &I : Node->bases()) {
+    const RecordType *Ty = I.getType()->getAs<RecordType>();
+    assert(Ty && "RecordType of base class is unknown");
+    CXXRecordDecl *Base = cast<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+    if (!MultipleInheritanceCheck::isInterface(Base)) {
+      MultipleInheritanceCheck::addNodeToInterfaceMap(Node, false);
+      return false;
+    }
+  }
+
+  bool CurrentClassIsInterface =
+          MultipleInheritanceCheck::isCurrentClassInterface(Node);
+  MultipleInheritanceCheck::addNodeToInterfaceMap(Node,
+          CurrentClassIsInterface);
+  return CurrentClassIsInterface;
+}
+
+void MultipleInheritanceCheck::registerMatchers(MatchFinder *Finder) {
+  // Match declarations which have definitions.
+  Finder->addMatcher(cxxRecordDecl(hasDefinition()).bind("decl"), this);
+}
+
+void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
+  if (const CXXRecordDecl *D =
+            Result.Nodes.getNodeAs<CXXRecordDecl>("decl")) {
+
+    // Check against map to see if if the class inherits from multiple 
+    // concrete classes
+    int NumConcrete = 0;
+    for (const auto &I : D->bases()) {
+      const RecordType *Ty = I.getType()->getAs<RecordType>();
+      assert(Ty && "RecordType of base class is unknown");
+      CXXRecordDecl *Base = cast<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+      if (!MultipleInheritanceCheck::isInterface(Base))
+        NumConcrete++;
+    }
+
+    if (NumConcrete > 1) {
+      diag(D->getLocStart(), "inheriting mulitple classes which aren't "
+                             "pure virtual is disallowed");
+    }
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/FuchsiaTidyModule.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/FuchsiaTidyModule.cpp
@@ -0,0 +1,59 @@
+//===--- 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"
+#include "MultipleInheritanceCheck.h"
+#include "OverloadedOperatorCheck.h"
+#include "StaticallyConstructedObjectsCheck.h"
+#include "ThreadLocalCheck.h"
+#include "TrailingReturnCheck.h"
+#include "VirtualInheritanceCheck.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");
+    CheckFactories.registerCheck<MultipleInheritanceCheck>(
+        "fuchsia-multiple-inheritance");
+    CheckFactories.registerCheck<OverloadedOperatorCheck>(
+        "fuchsia-overloaded-operator");
+    CheckFactories.registerCheck<StaticallyConstructedObjectsCheck>(
+        "fuchsia-statically-constructed-objects");
+    CheckFactories.registerCheck<ThreadLocalCheck>(
+        "fuchsia-thread-local");
+    CheckFactories.registerCheck<TrailingReturnCheck>(
+        "fuchsia-trailing-return");
+    CheckFactories.registerCheck<VirtualInheritanceCheck>(
+        "fuchsia-virtual-inheritance");
+  }
+};
+// 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
Index: clang-tidy/fuchsia/DefaultArgumentsCheck.h
===================================================================
--- /dev/null
+++ 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
Index: clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/DefaultArgumentsCheck.cpp
@@ -0,0 +1,42 @@
+//===--- 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 {
+
+AST_MATCHER(ParmVarDecl, hasDefaultArgument) { return Node.hasDefaultArg(); }
+
+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 CXXDefaultArgExpr *S =
+          Result.Nodes.getNodeAs<CXXDefaultArgExpr>("stmt")) {
+    diag(S->getUsedLocation(),
+         "calling functions which use default arguments is disallowed");
+    diag(S->getParam()->getLocStart(), "the default parameter was declared here",
+         DiagnosticIDs::Note);
+  } else if (const ParmVarDecl *D = Result.Nodes.getNodeAs<ParmVarDecl>("decl")) {
+    diag(D->getLocStart(),
+         "declaring functions which use default arguments is disallowed");
+  }
+}
+
+} // namespace fuchsia
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fuchsia/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-tidy/fuchsia/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyFuchsiaModule
+  DefaultArgumentsCheck.cpp
+  FuchsiaTidyModule.cpp
+  MultipleInheritanceCheck.cpp
+  OverloadedOperatorCheck.cpp
+  StaticallyConstructedObjectsCheck.cpp
+  ThreadLocalCheck.cpp
+  TrailingReturnCheck.cpp
+  VirtualInheritanceCheck.cpp
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangLex
+  clangTidy
+  clangTidyUtils
+  )
Index: clang-tidy/CMakeLists.txt
===================================================================
--- clang-tidy/CMakeLists.txt
+++ 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)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to