[PATCH] D51390: [analyzer] CallDescription: Improve array management.

2018-09-25 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC343037: [analyzer] NFC: CallDescription: Improve array 
management. (authored by dergachev, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D51390

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  lib/StaticAnalyzer/Core/CallEvent.cpp


Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -82,37 +82,26 @@
   mutable bool IsLookupDone = false;
   // The list of the qualified names used to identify the specified CallEvent,
   // e.g. "{a, b}" represent the qualified names, like "a::b".
-  std::vector QualifiedName;
+  std::vector QualifiedName;
   unsigned RequiredArgs;
 
 public:
   const static unsigned NoArgRequirement = 
std::numeric_limits::max();
 
   /// Constructs a CallDescription object.
   ///
-  /// @param QualifiedName The list of the qualified names of the function that
-  /// will be matched. It does not require the user to provide the full list of
-  /// the qualified name. The more details provided, the more accurate the
-  /// matching.
+  /// @param QualifiedName The list of the name qualifiers of the function that
+  /// will be matched. The user is allowed to skip any of the qualifiers.
+  /// For example, {"std", "basic_string", "c_str"} would match both
+  /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
   ///
   /// @param RequiredArgs The number of arguments that is expected to match a
   /// call. Omit this parameter to match every occurrence of call with a given
   /// name regardless the number of arguments.
-  CallDescription(std::vector QualifiedName,
+  CallDescription(ArrayRef QualifiedName,
   unsigned RequiredArgs = NoArgRequirement)
   : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {}
 
-  /// Constructs a CallDescription object.
-  ///
-  /// @param FuncName The name of the function that will be matched.
-  ///
-  /// @param RequiredArgs The number of arguments that is expected to match a
-  /// call. Omit this parameter to match every occurrence of call with a given
-  /// name regardless the number of arguments.
-  CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
-  : CallDescription(std::vector({FuncName}), NoArgRequirement) {
-  }
-
   /// Get the name of the function that this object matches.
   StringRef getFunctionName() const { return QualifiedName.back(); }
 };
Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -371,23 +371,26 @@
   // accuracy.
   if (CD.QualifiedName.size() > 1 && D) {
 const DeclContext *Ctx = D->getDeclContext();
-std::vector QualifiedName = CD.QualifiedName;
-QualifiedName.pop_back();
+// See if we'll be able to match them all.
+size_t NumUnmatched = CD.QualifiedName.size() - 1;
 for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  if (NumUnmatched == 0)
+break;
+
   if (const auto *ND = dyn_cast(Ctx)) {
-if (!QualifiedName.empty() && ND->getName() == QualifiedName.back())
-  QualifiedName.pop_back();
+if (ND->getName() == CD.QualifiedName[NumUnmatched - 1])
+  --NumUnmatched;
 continue;
   }
 
   if (const auto *RD = dyn_cast(Ctx)) {
-if (!QualifiedName.empty() && RD->getName() == QualifiedName.back())
-  QualifiedName.pop_back();
+if (RD->getName() == CD.QualifiedName[NumUnmatched - 1])
+  --NumUnmatched;
 continue;
   }
 }
 
-if (!QualifiedName.empty())
+if (NumUnmatched > 0)
   return false;
   }
 


Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -82,37 +82,26 @@
   mutable bool IsLookupDone = false;
   // The list of the qualified names used to identify the specified CallEvent,
   // e.g. "{a, b}" represent the qualified names, like "a::b".
-  std::vector QualifiedName;
+  std::vector QualifiedName;
   unsigned RequiredArgs;
 
 public:
   const static unsigned NoArgRequirement = std::numeric_limits::max();
 
   /// Constructs a CallDescription object.
   ///
-  /// @param QualifiedName The list of the qualified names of the function that
-  /// will be matched. It does not require the user to provide the full list of
-  /// the qualified name. The more details provided, the more accurate the
-  /// matching.
+  /// @param QualifiedName The list of the name qualifiers of the function that
+  /// 

[PATCH] D51390: [analyzer] CallDescription: Improve array management.

2018-08-29 Thread Henry Wong via Phabricator via cfe-commits
MTC accepted this revision.
MTC added a comment.

Thank you for digging in to delete that meaningless constructor, NoQ! And sorry 
for my technology debt : ).


Repository:
  rC Clang

https://reviews.llvm.org/D51390



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51390: [analyzer] CallDescription: Improve array management.

2018-08-29 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added a comment.

Yeah, i guess i should've split those up.

Well, i had to fix the other code when i fixed the first code, because it 
contains a hardcoded duplicate of the vector type. So i decided to fix it in a 
slightly more intelligent manner.


Repository:
  rC Clang

https://reviews.llvm.org/D51390



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51390: [analyzer] CallDescription: Improve array management.

2018-08-29 Thread George Karpenkov via Phabricator via cfe-commits
george.karpenkov added a comment.

Strictly speaking those two seem like completely unrelated changes , right?


Repository:
  rC Clang

https://reviews.llvm.org/D51390



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51390: [analyzer] CallDescription: Improve array management.

2018-08-28 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet, 
rnkovacs.
Herald added subscribers: cfe-commits, Szelethus, mikhail.ramalho, 
baloghadamsoftware.

`CallDescription` constructor now accepts an `ArrayRef`, instead 
of two different constructors for `StringRef` and `std::vector`.

This allows us to write an init-list of a vector of `CallDescription` objects 
as:

  vector V = {
{ { "foo" }, 1 },
{ { "q1", "q2", "bar" }, 2 },
...
  };

achieving uniformity between unqualified and qualified descriptions, while 
still allowing the old syntax of `{ "foo", 1 }` (without braces around "foo"). 
Previously `{ { "foo" }, 1 }` wouldn't have compiled, because the compiler was 
unable to figure out which constructor to call (because `{}` are allowed to be 
omitted or added indefinitely as a redundancy).

As a cost of that, i had to switch from `StringRef`s to raw pointers, because 
you can't automatically convert an initializer-list of C strings to an 
`ArrayRef` of `StringRef`s. But that doesn't seem bad, because `StringRef`s 
aren't that much different from raw pointers, and in practice only static 
strings will be used.

Also squash a mutable copy of that array.


Repository:
  rC Clang

https://reviews.llvm.org/D51390

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  lib/StaticAnalyzer/Core/CallEvent.cpp


Index: lib/StaticAnalyzer/Core/CallEvent.cpp
===
--- lib/StaticAnalyzer/Core/CallEvent.cpp
+++ lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -371,23 +371,26 @@
   // accuracy.
   if (CD.QualifiedName.size() > 1 && D) {
 const DeclContext *Ctx = D->getDeclContext();
-std::vector QualifiedName = CD.QualifiedName;
-QualifiedName.pop_back();
+// See if we'll be able to match them all.
+size_t NumUnmatched = CD.QualifiedName.size() - 1;
 for (; Ctx && isa(Ctx); Ctx = Ctx->getParent()) {
+  if (NumUnmatched == 0)
+break;
+
   if (const auto *ND = dyn_cast(Ctx)) {
-if (!QualifiedName.empty() && ND->getName() == QualifiedName.back())
-  QualifiedName.pop_back();
+if (ND->getName() == CD.QualifiedName[NumUnmatched - 1])
+  --NumUnmatched;
 continue;
   }
 
   if (const auto *RD = dyn_cast(Ctx)) {
-if (!QualifiedName.empty() && RD->getName() == QualifiedName.back())
-  QualifiedName.pop_back();
+if (RD->getName() == CD.QualifiedName[NumUnmatched - 1])
+  --NumUnmatched;
 continue;
   }
 }
 
-if (!QualifiedName.empty())
+if (NumUnmatched > 0)
   return false;
   }
 
Index: include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -82,37 +82,26 @@
   mutable bool IsLookupDone = false;
   // The list of the qualified names used to identify the specified CallEvent,
   // e.g. "{a, b}" represent the qualified names, like "a::b".
-  std::vector QualifiedName;
+  std::vector QualifiedName;
   unsigned RequiredArgs;
 
 public:
   const static unsigned NoArgRequirement = 
std::numeric_limits::max();
 
   /// Constructs a CallDescription object.
   ///
-  /// @param QualifiedName The list of the qualified names of the function that
-  /// will be matched. It does not require the user to provide the full list of
-  /// the qualified name. The more details provided, the more accurate the
-  /// matching.
+  /// @param QualifiedName The list of the name qualifiers of the function that
+  /// will be matched. The user is allowed to skip any of the qualifiers.
+  /// For example, {"std", "basic_string", "c_str"} would match both
+  /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
   ///
   /// @param RequiredArgs The number of arguments that is expected to match a
   /// call. Omit this parameter to match every occurrence of call with a given
   /// name regardless the number of arguments.
-  CallDescription(std::vector QualifiedName,
+  CallDescription(ArrayRef QualifiedName,
   unsigned RequiredArgs = NoArgRequirement)
   : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs) {}
 
-  /// Constructs a CallDescription object.
-  ///
-  /// @param FuncName The name of the function that will be matched.
-  ///
-  /// @param RequiredArgs The number of arguments that is expected to match a
-  /// call. Omit this parameter to match every occurrence of call with a given
-  /// name regardless the number of arguments.
-  CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
-  : CallDescription(std::vector({FuncName}), NoArgRequirement) {
-  }
-
   /// Get the name of the function that this object matches.
   StringRef getFunctionName() const { return QualifiedName.back();