1 //===- CallDescription.cpp - function/method call matching     --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file This file defines a generic mechanism for matching for function and
10 /// method calls of C, C++, and Objective-C languages. Instances of these
11 /// classes are frequently used together with the CallEvent classes.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
16 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/Optional.h"
19 
20 using namespace llvm;
21 using namespace clang;
22 
23 // A constructor helper.
24 static Optional<size_t> readRequiredParams(Optional<unsigned> RequiredArgs,
25                                            Optional<size_t> RequiredParams) {
26   if (RequiredParams)
27     return RequiredParams;
28   if (RequiredArgs)
29     return static_cast<size_t>(*RequiredArgs);
30   return None;
31 }
32 
33 ento::CallDescription::CallDescription(
34     int Flags, ArrayRef<const char *> QualifiedName,
35     Optional<unsigned> RequiredArgs /*= None*/,
36     Optional<size_t> RequiredParams /*= None*/)
37     : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs),
38       RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)),
39       Flags(Flags) {
40   assert(!QualifiedName.empty());
41 }
42 
43 /// Construct a CallDescription with default flags.
44 ento::CallDescription::CallDescription(
45     ArrayRef<const char *> QualifiedName,
46     Optional<unsigned> RequiredArgs /*= None*/,
47     Optional<size_t> RequiredParams /*= None*/)
48     : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {}
49 
50 ento::CallDescriptionSet::CallDescriptionSet(
51     std::initializer_list<CallDescription> &&List) {
52   Impl.LinearMap.reserve(List.size());
53   for (const CallDescription &CD : List)
54     Impl.LinearMap.push_back({CD, /*unused*/ true});
55 }
56 
57 bool ento::CallDescriptionSet::contains(const CallEvent &Call) const {
58   return static_cast<bool>(Impl.lookup(Call));
59 }
60