[clang-tidy] Fix redundant-string-init check with msvc 14 headers.

Summary:
The string constructors are not defined using optional parameters and are not recognized by the redundant-string-init checker.

The following patch fixes the redundant-string-init checker for the Visual Studio 14 headers file.
The matcher now accept both variant (with 1 and 2 parameters).

Also added new unittests.

Similar issue than: [[ http://reviews.llvm.org/D18285 | review ]]

In the xstring.h header, the constructors are defined this way:
```
basic_string(const _Myt& _Right) [...]
basic_string(const _Myt& _Right, const _Alloc& _Al) [...]
```

Reviewers: alexfh, hokein

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D18293

llvm-svn: 264069
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
index ad6c2cd..d49c55e 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -20,31 +20,48 @@
 
 AST_MATCHER(StringLiteral, lengthIsZero) { return Node.getLength() == 0; }
 
+AST_MATCHER_P(Expr, ignoringImplicit,
+              ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder);
+}
+
 } // namespace
 
 void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
     return;
 
-  const auto StringCtorExpr = cxxConstructExpr(
-      hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
-      argumentCountIs(2),
-      hasArgument(0, ignoringParenImpCasts(stringLiteral(lengthIsZero()))),
-      hasArgument(1, cxxDefaultArgExpr()));
+  // Match string constructor.
+  const auto StringConstructorExpr = expr(anyOf(
+      cxxConstructExpr(argumentCountIs(1),
+                       hasDeclaration(cxxMethodDecl(hasName("basic_string")))),
+      // If present, the second argument is the alloc object which must not
+      // be present explicitly.
+      cxxConstructExpr(argumentCountIs(2),
+                       hasDeclaration(cxxMethodDecl(hasName("basic_string"))),
+                       hasArgument(1, cxxDefaultArgExpr()))));
 
-  // string foo = "";
-  // OR
-  // string bar("");
+  // Match a string constructor expression with an empty string literal.
+  const auto EmptyStringCtorExpr =
+      cxxConstructExpr(StringConstructorExpr,
+          hasArgument(0, ignoringParenImpCasts(
+                             stringLiteral(lengthIsZero()))));
+
+  const auto EmptyStringCtorExprWithTemporaries =
+      expr(ignoringImplicit(
+          cxxConstructExpr(StringConstructorExpr,
+              hasArgument(0, ignoringImplicit(EmptyStringCtorExpr)))));
+
+  // Match a variable declaration with an empty string literal as initializer.
+  // Examples:
+  //     string foo = "";
+  //     string bar("");
   Finder->addMatcher(
       namedDecl(varDecl(hasType(cxxRecordDecl(hasName("basic_string"))),
                         hasInitializer(
-                            expr(anyOf(StringCtorExpr,
-                                       exprWithCleanups(has(expr(anyOf(
-                                           StringCtorExpr,
-                                           cxxConstructExpr(hasArgument(
-                                               0, cxxBindTemporaryExpr(has(
-                                                      StringCtorExpr))))))))))
-                                .bind("expr"))))
+                            expr(anyOf(EmptyStringCtorExpr,
+                                       EmptyStringCtorExprWithTemporaries))
+                            .bind("expr"))))
           .bind("decl"),
       this);
 }