]> granicus.if.org Git - clang/commitdiff
Remove cache for macro arg stringization
authorReid Kleckner <rnk@google.com>
Tue, 30 Jul 2019 17:58:22 +0000 (17:58 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 30 Jul 2019 17:58:22 +0000 (17:58 +0000)
Summary:
The cache recorded the wrong expansion location for all but the first
stringization. It seems uncommon to stringize the same macro argument
multiple times, so this cache doesn't seem that important.

Fixes PR39942

Reviewers: vsk, rsmith

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D65428

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@367337 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/MacroArgs.h
lib/Lex/MacroArgs.cpp
lib/Lex/TokenLexer.cpp
test/CoverageMapping/macro-stringize-twice.cpp [new file with mode: 0644]
unittests/Lex/LexerTest.cpp

index 8806f2d8c6567fec787b0fc3fa390b217ad1ed2f..59676c30e0a598837b0cf660398e973261eaca8a 100644 (file)
@@ -48,10 +48,6 @@ class MacroArgs final
   /// stream.
   std::vector<std::vector<Token> > PreExpArgTokens;
 
-  /// StringifiedArgs - This contains arguments in 'stringified' form.  If the
-  /// stringified form of an argument has not yet been computed, this is empty.
-  std::vector<Token> StringifiedArgs;
-
   /// ArgCache - This is a linked list of MacroArgs objects that the
   /// Preprocessor owns which we use to avoid thrashing malloc/free.
   MacroArgs *ArgCache;
@@ -94,12 +90,6 @@ public:
   const std::vector<Token> &
     getPreExpArgument(unsigned Arg, Preprocessor &PP);
 
-  /// getStringifiedArgument - Compute, cache, and return the specified argument
-  /// that has been 'stringified' as required by the # operator.
-  const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP,
-                                      SourceLocation ExpansionLocStart,
-                                      SourceLocation ExpansionLocEnd);
-
   /// getNumMacroArguments - Return the number of arguments the invoked macro
   /// expects.
   unsigned getNumMacroArguments() const { return NumMacroArgs; }
index 5aa4679fad4626eadf5a961f1e82ef7090009dea..7ede00b4aa64249ebc9f811d95a9abe074fb1d1b 100644 (file)
@@ -76,8 +76,6 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI,
 /// destroy - Destroy and deallocate the memory for this object.
 ///
 void MacroArgs::destroy(Preprocessor &PP) {
-  StringifiedArgs.clear();
-
   // Don't clear PreExpArgTokens, just clear the entries.  Clearing the entries
   // would deallocate the element vectors.
   for (unsigned i = 0, e = PreExpArgTokens.size(); i != e; ++i)
@@ -307,21 +305,3 @@ Token MacroArgs::StringifyArgument(const Token *ArgToks,
                   ExpansionLocStart, ExpansionLocEnd);
   return Tok;
 }
-
-/// getStringifiedArgument - Compute, cache, and return the specified argument
-/// that has been 'stringified' as required by the # operator.
-const Token &MacroArgs::getStringifiedArgument(unsigned ArgNo,
-                                               Preprocessor &PP,
-                                               SourceLocation ExpansionLocStart,
-                                               SourceLocation ExpansionLocEnd) {
-  assert(ArgNo < getNumMacroArguments() && "Invalid argument number!");
-  if (StringifiedArgs.empty())
-    StringifiedArgs.resize(getNumMacroArguments(), {});
-
-  if (StringifiedArgs[ArgNo].isNot(tok::string_literal))
-    StringifiedArgs[ArgNo] = StringifyArgument(getUnexpArgument(ArgNo), PP,
-                                               /*Charify=*/false,
-                                               ExpansionLocStart,
-                                               ExpansionLocEnd);
-  return StringifiedArgs[ArgNo];
-}
index a7957e82e49552776bd62c397dfde68363142ef3..da5681aaf4784fd95d35c39178e240fae2dc040c 100644 (file)
@@ -383,18 +383,10 @@ void TokenLexer::ExpandFunctionArguments() {
       SourceLocation ExpansionLocEnd =
           getExpansionLocForMacroDefLoc(Tokens[I+1].getLocation());
 
-      Token Res;
-      if (CurTok.is(tok::hash))  // Stringify
-        Res = ActualArgs->getStringifiedArgument(ArgNo, PP,
-                                                 ExpansionLocStart,
-                                                 ExpansionLocEnd);
-      else {
-        // 'charify': don't bother caching these.
-        Res = MacroArgs::StringifyArgument(ActualArgs->getUnexpArgument(ArgNo),
-                                           PP, true,
-                                           ExpansionLocStart,
-                                           ExpansionLocEnd);
-      }
+      bool Charify = CurTok.is(tok::hashat);
+      const Token *UnexpArg = ActualArgs->getUnexpArgument(ArgNo);
+      Token Res = MacroArgs::StringifyArgument(
+          UnexpArg, PP, Charify, ExpansionLocStart, ExpansionLocEnd);
       Res.setFlag(Token::StringifiedInMacro);
 
       // The stringified/charified string leading space flag gets set to match
diff --git a/test/CoverageMapping/macro-stringize-twice.cpp b/test/CoverageMapping/macro-stringize-twice.cpp
new file mode 100644 (file)
index 0000000..7a91d91
--- /dev/null
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s | FileCheck %s
+
+// PR39942
+
+class a;
+template <class b> a &operator<<(b &, const char *);
+int c;
+#define d(l) l(__FILE__, __LINE__, c)
+#define COMPACT_GOOGLE_LOG_ERROR d(e)
+#define f(g, cond) cond ? (void)0 : h() & g
+#define i(j) COMPACT_GOOGLE_LOG_##j.g()
+#define k(j) f(i(j), 0)
+class e {
+public:
+  e(const char *, int, int);
+  a &g();
+};
+class h {
+public:
+  void operator&(a &);
+};
+void use_str(const char *);
+
+#define m(func)                                                                \
+  use_str(#func);                                                              \
+  k(ERROR) << #func;                                                           \
+  return 0; // CHECK: File 1, [[@LINE-1]]:4 -> [[@LINE-1]]:16 = (#0 - #1)
+int main() {
+  m(asdf);
+}
index 7b14f56201eb0613d5700b7ab5b841878fe8fcdf..29eea42ad95a530ffbdb15cdfe767679ec0a30e1 100644 (file)
@@ -401,18 +401,21 @@ TEST_F(LexerTest, DontOverallocateStringifyArgs) {
   auto MacroArgsDeleter = [&PP](MacroArgs *M) { M->destroy(*PP); };
   std::unique_ptr<MacroArgs, decltype(MacroArgsDeleter)> MA(
       MacroArgs::create(MI, ArgTokens, false, *PP), MacroArgsDeleter);
-  Token Result = MA->getStringifiedArgument(0, *PP, {}, {});
+  auto StringifyArg = [&](int ArgNo) {
+    return MA->StringifyArgument(MA->getUnexpArgument(ArgNo), *PP,
+                                 /*Charify=*/false, {}, {});
+  };
+  Token Result = StringifyArg(0);
   EXPECT_EQ(tok::string_literal, Result.getKind());
   EXPECT_STREQ("\"\\\"StrArg\\\"\"", Result.getLiteralData());
-  Result = MA->getStringifiedArgument(1, *PP, {}, {});
+  Result = StringifyArg(1);
   EXPECT_EQ(tok::string_literal, Result.getKind());
   EXPECT_STREQ("\"5\"", Result.getLiteralData());
-  Result = MA->getStringifiedArgument(2, *PP, {}, {});
+  Result = StringifyArg(2);
   EXPECT_EQ(tok::string_literal, Result.getKind());
   EXPECT_STREQ("\"'C'\"", Result.getLiteralData());
 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
-  EXPECT_DEATH(MA->getStringifiedArgument(3, *PP, {}, {}),
-               "Invalid argument number!");
+  EXPECT_DEATH(StringifyArg(3), "Invalid arg #");
 #endif
 }