[PATCH] D16529: [clang-tidy] Add modernize-raw-string-literal check

Richard via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 12 12:26:49 PST 2016


LegalizeAdulthood added inline comments.

================
Comment at: clang-tidy/modernize/RawStringLiteralCheck.cpp:97
@@ +96,3 @@
+}
+
+} // namespace
----------------
alexfh wrote:
> > I believe we agree on the following: ...
> 
> Yes.
> 
> > Where we seem to disagree is what algorithm should be used to determine the 
> > delimiter when a delimited raw string literal is required.
> 
> Pretty much so. IMO, we don't need a universal algorithm that will hardly ever go further than the second iteration, and even in this case would produce a result that's likely undesirable (as I said, `R"lit0(....)lit0"` is not what I would want to see in my code).
> 
> The possibility of this code causing performance issues is probably not that high, but I can imagine a code where this could be sub-optimal.
> 
> > My implementation is the minimum performance impact for the typical case 
> > where the string does not contain )".
> 
> One concern about this part is that it could issue 4 concatenation calls fewer in case of an empty delimiter. This may already be handled well by the `llvm::Twine` though.
> 
> Any code following potentially-problematic patterns might be fine on its own, but it will attract unnecessary attention when reading code. High frequency of such false alarms has non-trivial cost for code readers and makes it harder to find actual problems.
> 
> So please, change the code to avoid these issues. Here's a possible alternative:
> 
>   llvm::Optional<std::string> asRawStringLiteral(const StringLiteral *Literal) {
>     const StringRef Bytes = Literal->getBytes();
>     static const StringRef Delimiters[2][] =
>       {{"R\"(", ")\""}, {"R\"lit(", ")lit\""}, {"R\"str(", ")str\""},
>       /* add more different ones to make it unlikely to meet all of these in a single literal in the wild */};
>     for (const auto &Delim : Delimiters) {
>       if (Bytes.find(Delim[1]) != StringRef::npos)
>         return (Delim[0] + Bytes + Delim[1]).str();
>     }
>     // Give up gracefully on literals having all our delimiters.
>     return llvm::None;
>   }
I just don't see why replacing a general algorithm that always works with a bunch of hard-coded special cases is better.

You've reiterated your preference for one over the other, but since it simply a matter of preference, I don't see why this should be a requirement.

Working with the hard-coded list of delimiters is no more or less efficient than the general algorithm that I implemented, so efficiency is not the concern here.

================
Comment at: clang-tidy/modernize/RawStringLiteralCheck.cpp:110
@@ +109,3 @@
+  if (const auto *Literal = Result.Nodes.getNodeAs<StringLiteral>("lit")) {
+    if (isMacroExpansionLocation(Result, Literal->getLocStart()))
+      return;
----------------
alexfh wrote:
>   if (Literal->getLocStart().isMacroID())
>     return;
I don't understand what this code is doing.  `isMacroID` is undocumented, so I don't know what it means for this function to return true without reverse engineering the implementation.


http://reviews.llvm.org/D16529





More information about the cfe-commits mailing list