void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
  const auto IsGlobal =
      allOf(hasGlobalStorage(),
            hasDeclContext(anyOf(translationUnitDecl(), // Global scope.
                                 namespaceDecl(),       // Namespace scope.
                                 recordDecl())),        // Class scope.
            unless(isConstexpr()));

  const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
      varDecl(IsGlobal, unless(isDefinition())).bind("referencee")));

  Finder->addMatcher(
      varDecl(IsGlobal, isDefinition(),
              hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar))))
          .bind("var"),
      this);
}
void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
  if ((!getLangOpts().CPlusPlus) || (!getLangOpts().CXXExceptions))
    return;

  // Match any static or thread_local variable declaration that has an
  // initializer that can throw.
  Finder->addMatcher(
      varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
              unless(anyOf(isConstexpr(), hasType(cxxRecordDecl(isLambda())),
                           hasAncestor(functionDecl()))),
              anyOf(hasDescendant(cxxConstructExpr(hasDeclaration(
                        cxxConstructorDecl(unless(isNoThrow())).bind("func")))),
                    hasDescendant(cxxNewExpr(hasDeclaration(
                        functionDecl(unless(isNoThrow())).bind("func")))),
                    hasDescendant(callExpr(hasDeclaration(
                        functionDecl(unless(isNoThrow())).bind("func"))))))
          .bind("var"),
      this);
}
void StaticallyConstructedObjectsCheck::registerMatchers(MatchFinder *Finder) {
  // Constructing global, non-trivial objects with static storage is
  // disallowed, unless the object is statically initialized with a constexpr 
  // constructor or has no explicit constructor.

  // Constexpr requires C++11 or later.
  if (!getLangOpts().CPlusPlus11)
    return;

  Finder->addMatcher(varDecl(
                         // Match global, statically stored objects...
                         isGlobalStatic(),
                         // ... that have C++ constructors...
                         hasDescendant(cxxConstructExpr(unless(allOf(
                             // ... unless it is constexpr ...
                             hasDeclaration(cxxConstructorDecl(isConstexpr())),
                             // ... and is statically initialized.
                             isConstantInitializer())))))
                         .bind("decl"),
                     this);
}