[PATCH] D51390: [analyzer] CallDescription: Improve array management.
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 28 16:31:14 PDT 2018
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<const char *>`, instead of two different constructors for `StringRef` and `std::vector<StringRef>`.
This allows us to write an init-list of a vector of `CallDescription` objects as:
vector<CallDescription> 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<StringRef> 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<NamedDecl>(Ctx); Ctx = Ctx->getParent()) {
+ if (NumUnmatched == 0)
+ break;
+
if (const auto *ND = dyn_cast<NamespaceDecl>(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<RecordDecl>(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<StringRef> QualifiedName;
+ std::vector<const char *> QualifiedName;
unsigned RequiredArgs;
public:
const static unsigned NoArgRequirement = std::numeric_limits<unsigned>::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<StringRef> QualifiedName,
+ CallDescription(ArrayRef<const char *> 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<StringRef>({FuncName}), NoArgRequirement) {
- }
-
/// Get the name of the function that this object matches.
StringRef getFunctionName() const { return QualifiedName.back(); }
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51390.162981.patch
Type: text/x-patch
Size: 3712 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180828/0160be44/attachment.bin>
More information about the cfe-commits
mailing list