Skip to content

Commit

Permalink
[clang] Use a StringRef instead of a raw char pointer to store builti…
Browse files Browse the repository at this point in the history
…n and call information

This avoids recomputing string length that is already known at compile
time.

It has a slight impact on preprocessing / compile time, see

https://llvm-compile-time-tracker.com/compare.php?from=3f36d2d579d8b0e8824d9dd99bfa79f456858f88&to=e49640c507ddc6615b5e503144301c8e41f8f434&stat=instructions:u

This is a recommit of 719d98d with a
change to llvm/utils/TableGen/OptParserEmitter.cpp to cope with GCC bug
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108158

Differential Revision: https://reviews.llvm.org/D139881
  • Loading branch information
serge-sans-paille committed Dec 23, 2022
1 parent b7b1e5c commit 5ce4e92
Show file tree
Hide file tree
Showing 70 changed files with 601 additions and 565 deletions.
12 changes: 7 additions & 5 deletions clang-tools-extra/clangd/CompileCommands.cpp
Expand Up @@ -466,8 +466,10 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
NextAlias[T] = Self;
};
// Also grab prefixes for each option, these are not fully exposed.
const char *const *Prefixes[DriverID::LastOption] = {nullptr};
#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
std::initializer_list<llvm::StringLiteral> Prefixes[DriverID::LastOption];

#define PREFIX(NAME, VALUE) \
static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELP, METAVAR, VALUES) \
Prefixes[DriverID::OPT_##ID] = PREFIX;
Expand Down Expand Up @@ -499,7 +501,7 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
llvm::SmallVector<Rule> Rules;
// Iterate over each alias, to add rules for parsing it.
for (unsigned A = ID; A != DriverID::OPT_INVALID; A = NextAlias[A]) {
if (Prefixes[A] == nullptr) // option groups.
if (!Prefixes[A].size()) // option groups.
continue;
auto Opt = DriverTable.getOption(A);
// Exclude - and -foo pseudo-options.
Expand All @@ -508,8 +510,8 @@ llvm::ArrayRef<ArgStripper::Rule> ArgStripper::rulesFor(llvm::StringRef Arg) {
auto Modes = getModes(Opt);
std::pair<unsigned, unsigned> ArgCount = getArgCount(Opt);
// Iterate over each spelling of the alias, e.g. -foo vs --foo.
for (auto *Prefix = Prefixes[A]; *Prefix != nullptr; ++Prefix) {
llvm::SmallString<64> Buf(*Prefix);
for (StringRef Prefix : Prefixes[A]) {
llvm::SmallString<64> Buf(Prefix);
Buf.append(Opt.getName());
llvm::StringRef Spelling = Result->try_emplace(Buf).first->getKey();
Rules.emplace_back();
Expand Down
7 changes: 3 additions & 4 deletions clang/include/clang/Basic/Builtins.h
Expand Up @@ -57,7 +57,8 @@ enum ID {
};

struct Info {
const char *Name, *Type, *Attributes, *HeaderName;
llvm::StringRef Name;
const char *Type, *Attributes, *HeaderName;
LanguageID Langs;
const char *Features;
};
Expand Down Expand Up @@ -86,9 +87,7 @@ class Context {

/// Return the identifier name for the specified builtin,
/// e.g. "__builtin_abs".
const char *getName(unsigned ID) const {
return getRecord(ID).Name;
}
llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }

/// Get the type descriptor string for the specified builtin.
const char *getTypeString(unsigned ID) const {
Expand Down
Expand Up @@ -63,13 +63,12 @@ class CallDescription {
/// @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(CallDescriptionFlags Flags,
ArrayRef<const char *> QualifiedName,
CallDescription(CallDescriptionFlags Flags, ArrayRef<StringRef> QualifiedName,
MaybeCount RequiredArgs = std::nullopt,
MaybeCount RequiredParams = std::nullopt);

/// Construct a CallDescription with default flags.
CallDescription(ArrayRef<const char *> QualifiedName,
CallDescription(ArrayRef<StringRef> QualifiedName,
MaybeCount RequiredArgs = std::nullopt,
MaybeCount RequiredParams = std::nullopt);

Expand Down
20 changes: 10 additions & 10 deletions clang/lib/AST/ExprConstant.cpp
Expand Up @@ -9242,8 +9242,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BIwmemchr:
if (Info.getLangOpts().CPlusPlus11)
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
<< /*isConstexpr*/0 << /*isConstructor*/0
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
else
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
[[fallthrough]];
Expand Down Expand Up @@ -9288,7 +9288,7 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
// FIXME: We can compare the bytes in the correct order.
if (IsRawByte && !isOneByteCharacterType(CharTy)) {
Info.FFDiag(E, diag::note_constexpr_memchr_unsupported)
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str()
<< CharTy;
return false;
}
Expand Down Expand Up @@ -9350,8 +9350,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
case Builtin::BIwmemmove:
if (Info.getLangOpts().CPlusPlus11)
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
<< /*isConstexpr*/0 << /*isConstructor*/0
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
else
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
[[fallthrough]];
Expand Down Expand Up @@ -12209,8 +12209,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
// A call to strlen is not a constant expression.
if (Info.getLangOpts().CPlusPlus11)
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
<< /*isConstexpr*/0 << /*isConstructor*/0
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
else
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
[[fallthrough]];
Expand All @@ -12234,8 +12234,8 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
// A call to strlen is not a constant expression.
if (Info.getLangOpts().CPlusPlus11)
Info.CCEDiag(E, diag::note_constexpr_invalid_function)
<< /*isConstexpr*/0 << /*isConstructor*/0
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'");
<< /*isConstexpr*/ 0 << /*isConstructor*/ 0
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str();
else
Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
[[fallthrough]];
Expand Down Expand Up @@ -12290,7 +12290,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
!(isOneByteCharacterType(CharTy1) && isOneByteCharacterType(CharTy2))) {
// FIXME: Consider using our bit_cast implementation to support this.
Info.FFDiag(E, diag::note_constexpr_memcmp_unsupported)
<< (std::string("'") + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'")
<< ("'" + Info.Ctx.BuiltinInfo.getName(BuiltinOp) + "'").str()
<< CharTy1 << CharTy2;
return false;
}
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Basic/Builtins.cpp
Expand Up @@ -18,8 +18,9 @@
#include "llvm/ADT/StringRef.h"
using namespace clang;

static const Builtin::Info BuiltinInfo[] = {
{ "not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,nullptr},
static constexpr Builtin::Info BuiltinInfo[] = {
{"not a builtin function", nullptr, nullptr, nullptr, ALL_LANGUAGES,
nullptr},
#define BUILTIN(ID, TYPE, ATTRS) \
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS) \
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGBuiltin.cpp
Expand Up @@ -134,7 +134,7 @@ llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
AIXLongDouble64Builtins.end())
Name = AIXLongDouble64Builtins[BuiltinID];
else
Name = Context.BuiltinInfo.getName(BuiltinID) + 10;
Name = Context.BuiltinInfo.getName(BuiltinID).substr(10);
}

llvm::FunctionType *Ty =
Expand Down Expand Up @@ -5302,7 +5302,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
LargestVectorWidth = std::max(LargestVectorWidth, VectorWidth);

// See if we have a target specific intrinsic.
const char *Name = getContext().BuiltinInfo.getName(BuiltinID);
StringRef Name = getContext().BuiltinInfo.getName(BuiltinID);
Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
StringRef Prefix =
llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Driver/DriverOptions.cpp
Expand Up @@ -16,11 +16,12 @@ using namespace clang::driver;
using namespace clang::driver::options;
using namespace llvm::opt;

#define PREFIX(NAME, VALUE) static const char *const NAME[] = VALUE;
#define PREFIX(NAME, VALUE) \
static constexpr std::initializer_list<llvm::StringLiteral> NAME = VALUE;
#include "clang/Driver/Options.inc"
#undef PREFIX

static constexpr OptTable::Info InfoTable[] = {
static constexpr std::initializer_list<OptTable::Info> InfoTable = {
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES) \
{PREFIX, NAME, HELPTEXT, METAVAR, OPT_##ID, Option::KIND##Class, \
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaChecking.cpp
Expand Up @@ -6956,7 +6956,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
// Get the decl for the concrete builtin from this, we can tell what the
// concrete integer type we should convert to is.
unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
const char *NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);
StringRef NewBuiltinName = Context.BuiltinInfo.getName(NewBuiltinID);
FunctionDecl *NewBuiltinDecl;
if (NewBuiltinID == BuiltinID)
NewBuiltinDecl = FDecl;
Expand Down Expand Up @@ -11008,7 +11008,7 @@ static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range,
unsigned AbsKind, QualType ArgType) {
bool EmitHeaderHint = true;
const char *HeaderName = nullptr;
const char *FunctionName = nullptr;
StringRef FunctionName;
if (S.getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
FunctionName = "std::abs";
if (ArgType->isIntegralOrEnumerationType()) {
Expand Down Expand Up @@ -11116,7 +11116,7 @@ void Sema::CheckAbsoluteValueFunction(const CallExpr *Call,
// Unsigned types cannot be negative. Suggest removing the absolute value
// function call.
if (ArgType->isUnsignedIntegerType()) {
const char *FunctionName =
StringRef FunctionName =
IsStdAbs ? "std::abs" : Context.BuiltinInfo.getName(AbsKind);
Diag(Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
Diag(Call->getExprLoc(), diag::note_remove_abs)
Expand Down
Expand Up @@ -532,10 +532,10 @@ namespace {
class CFRetainReleaseChecker : public Checker<check::PreCall> {
mutable APIMisuse BT{this, "null passed to CF memory management function"};
const CallDescriptionSet ModelledCalls = {
{"CFRetain", 1},
{"CFRelease", 1},
{"CFMakeCollectable", 1},
{"CFAutorelease", 1},
{{"CFRetain"}, 1},
{{"CFRelease"}, 1},
{{"CFMakeCollectable"}, 1},
{{"CFAutorelease"}, 1},
};

public:
Expand Down
Expand Up @@ -64,19 +64,15 @@ class BlockInCriticalSectionChecker : public Checker<check::PostCall> {
REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned)

BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()
: IILockGuard(nullptr), IIUniqueLock(nullptr),
LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
PthreadLockFn("pthread_mutex_lock"),
PthreadTryLockFn("pthread_mutex_trylock"),
PthreadUnlockFn("pthread_mutex_unlock"),
MtxLock("mtx_lock"),
MtxTimedLock("mtx_timedlock"),
MtxTryLock("mtx_trylock"),
MtxUnlock("mtx_unlock"),
ClassLockGuard("lock_guard"),
ClassUniqueLock("unique_lock"),
IdentifierInfoInitialized(false) {
: IILockGuard(nullptr), IIUniqueLock(nullptr), LockFn({"lock"}),
UnlockFn({"unlock"}), SleepFn({"sleep"}), GetcFn({"getc"}),
FgetsFn({"fgets"}), ReadFn({"read"}), RecvFn({"recv"}),
PthreadLockFn({"pthread_mutex_lock"}),
PthreadTryLockFn({"pthread_mutex_trylock"}),
PthreadUnlockFn({"pthread_mutex_unlock"}), MtxLock({"mtx_lock"}),
MtxTimedLock({"mtx_timedlock"}), MtxTryLock({"mtx_trylock"}),
MtxUnlock({"mtx_unlock"}), ClassLockGuard("lock_guard"),
ClassUniqueLock("unique_lock"), IdentifierInfoInitialized(false) {
// Initialize the bug type.
BlockInCritSectionBugType.reset(
new BugType(this, "Call to blocking function in critical section",
Expand Down
61 changes: 31 additions & 30 deletions clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
Expand Up @@ -134,45 +134,46 @@ class CStringChecker : public Checker< eval::Call,
const CallExpr *)>;

CallDescriptionMap<FnCheck> Callbacks = {
{{CDF_MaybeBuiltin, "memcpy", 3},
{{CDF_MaybeBuiltin, {"memcpy"}, 3},
std::bind(&CStringChecker::evalMemcpy, _1, _2, _3, CK_Regular)},
{{CDF_MaybeBuiltin, "wmemcpy", 3},
{{CDF_MaybeBuiltin, {"wmemcpy"}, 3},
std::bind(&CStringChecker::evalMemcpy, _1, _2, _3, CK_Wide)},
{{CDF_MaybeBuiltin, "mempcpy", 3},
{{CDF_MaybeBuiltin, {"mempcpy"}, 3},
std::bind(&CStringChecker::evalMempcpy, _1, _2, _3, CK_Regular)},
{{CDF_None, "wmempcpy", 3},
{{CDF_None, {"wmempcpy"}, 3},
std::bind(&CStringChecker::evalMempcpy, _1, _2, _3, CK_Wide)},
{{CDF_MaybeBuiltin, "memcmp", 3},
{{CDF_MaybeBuiltin, {"memcmp"}, 3},
std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Regular)},
{{CDF_MaybeBuiltin, "wmemcmp", 3},
{{CDF_MaybeBuiltin, {"wmemcmp"}, 3},
std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Wide)},
{{CDF_MaybeBuiltin, "memmove", 3},
{{CDF_MaybeBuiltin, {"memmove"}, 3},
std::bind(&CStringChecker::evalMemmove, _1, _2, _3, CK_Regular)},
{{CDF_MaybeBuiltin, "wmemmove", 3},
{{CDF_MaybeBuiltin, {"wmemmove"}, 3},
std::bind(&CStringChecker::evalMemmove, _1, _2, _3, CK_Wide)},
{{CDF_MaybeBuiltin, "memset", 3}, &CStringChecker::evalMemset},
{{CDF_MaybeBuiltin, "explicit_memset", 3}, &CStringChecker::evalMemset},
{{CDF_MaybeBuiltin, "strcpy", 2}, &CStringChecker::evalStrcpy},
{{CDF_MaybeBuiltin, "strncpy", 3}, &CStringChecker::evalStrncpy},
{{CDF_MaybeBuiltin, "stpcpy", 2}, &CStringChecker::evalStpcpy},
{{CDF_MaybeBuiltin, "strlcpy", 3}, &CStringChecker::evalStrlcpy},
{{CDF_MaybeBuiltin, "strcat", 2}, &CStringChecker::evalStrcat},
{{CDF_MaybeBuiltin, "strncat", 3}, &CStringChecker::evalStrncat},
{{CDF_MaybeBuiltin, "strlcat", 3}, &CStringChecker::evalStrlcat},
{{CDF_MaybeBuiltin, "strlen", 1}, &CStringChecker::evalstrLength},
{{CDF_MaybeBuiltin, "wcslen", 1}, &CStringChecker::evalstrLength},
{{CDF_MaybeBuiltin, "strnlen", 2}, &CStringChecker::evalstrnLength},
{{CDF_MaybeBuiltin, "wcsnlen", 2}, &CStringChecker::evalstrnLength},
{{CDF_MaybeBuiltin, "strcmp", 2}, &CStringChecker::evalStrcmp},
{{CDF_MaybeBuiltin, "strncmp", 3}, &CStringChecker::evalStrncmp},
{{CDF_MaybeBuiltin, "strcasecmp", 2}, &CStringChecker::evalStrcasecmp},
{{CDF_MaybeBuiltin, "strncasecmp", 3}, &CStringChecker::evalStrncasecmp},
{{CDF_MaybeBuiltin, "strsep", 2}, &CStringChecker::evalStrsep},
{{CDF_MaybeBuiltin, "bcopy", 3}, &CStringChecker::evalBcopy},
{{CDF_MaybeBuiltin, "bcmp", 3},
{{CDF_MaybeBuiltin, {"memset"}, 3}, &CStringChecker::evalMemset},
{{CDF_MaybeBuiltin, {"explicit_memset"}, 3}, &CStringChecker::evalMemset},
{{CDF_MaybeBuiltin, {"strcpy"}, 2}, &CStringChecker::evalStrcpy},
{{CDF_MaybeBuiltin, {"strncpy"}, 3}, &CStringChecker::evalStrncpy},
{{CDF_MaybeBuiltin, {"stpcpy"}, 2}, &CStringChecker::evalStpcpy},
{{CDF_MaybeBuiltin, {"strlcpy"}, 3}, &CStringChecker::evalStrlcpy},
{{CDF_MaybeBuiltin, {"strcat"}, 2}, &CStringChecker::evalStrcat},
{{CDF_MaybeBuiltin, {"strncat"}, 3}, &CStringChecker::evalStrncat},
{{CDF_MaybeBuiltin, {"strlcat"}, 3}, &CStringChecker::evalStrlcat},
{{CDF_MaybeBuiltin, {"strlen"}, 1}, &CStringChecker::evalstrLength},
{{CDF_MaybeBuiltin, {"wcslen"}, 1}, &CStringChecker::evalstrLength},
{{CDF_MaybeBuiltin, {"strnlen"}, 2}, &CStringChecker::evalstrnLength},
{{CDF_MaybeBuiltin, {"wcsnlen"}, 2}, &CStringChecker::evalstrnLength},
{{CDF_MaybeBuiltin, {"strcmp"}, 2}, &CStringChecker::evalStrcmp},
{{CDF_MaybeBuiltin, {"strncmp"}, 3}, &CStringChecker::evalStrncmp},
{{CDF_MaybeBuiltin, {"strcasecmp"}, 2}, &CStringChecker::evalStrcasecmp},
{{CDF_MaybeBuiltin, {"strncasecmp"}, 3},
&CStringChecker::evalStrncasecmp},
{{CDF_MaybeBuiltin, {"strsep"}, 2}, &CStringChecker::evalStrsep},
{{CDF_MaybeBuiltin, {"bcopy"}, 3}, &CStringChecker::evalBcopy},
{{CDF_MaybeBuiltin, {"bcmp"}, 3},
std::bind(&CStringChecker::evalMemcmp, _1, _2, _3, CK_Regular)},
{{CDF_MaybeBuiltin, "bzero", 2}, &CStringChecker::evalBzero},
{{CDF_MaybeBuiltin, "explicit_bzero", 2}, &CStringChecker::evalBzero},
{{CDF_MaybeBuiltin, {"bzero"}, 2}, &CStringChecker::evalBzero},
{{CDF_MaybeBuiltin, {"explicit_bzero"}, 2}, &CStringChecker::evalBzero},
};

// These require a bit of special handling.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
Expand Up @@ -43,7 +43,7 @@ class ChrootChecker : public Checker<eval::Call, check::PreCall> {
// This bug refers to possibly break out of a chroot() jail.
mutable std::unique_ptr<BuiltinBug> BT_BreakJail;

const CallDescription Chroot{"chroot", 1}, Chdir{"chdir", 1};
const CallDescription Chroot{{"chroot"}, 1}, Chdir{{"chdir"}, 1};

public:
ChrootChecker() {}
Expand Down
28 changes: 14 additions & 14 deletions clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
Expand Up @@ -72,26 +72,26 @@ class ContainerModeling
SVal) const;

CallDescriptionMap<NoItParamFn> NoIterParamFunctions = {
{{"clear", 0}, &ContainerModeling::handleClear},
{{"assign", 2}, &ContainerModeling::handleAssign},
{{"push_back", 1}, &ContainerModeling::handlePushBack},
{{"emplace_back", 1}, &ContainerModeling::handlePushBack},
{{"pop_back", 0}, &ContainerModeling::handlePopBack},
{{"push_front", 1}, &ContainerModeling::handlePushFront},
{{"emplace_front", 1}, &ContainerModeling::handlePushFront},
{{"pop_front", 0}, &ContainerModeling::handlePopFront},
{{{"clear"}, 0}, &ContainerModeling::handleClear},
{{{"assign"}, 2}, &ContainerModeling::handleAssign},
{{{"push_back"}, 1}, &ContainerModeling::handlePushBack},
{{{"emplace_back"}, 1}, &ContainerModeling::handlePushBack},
{{{"pop_back"}, 0}, &ContainerModeling::handlePopBack},
{{{"push_front"}, 1}, &ContainerModeling::handlePushFront},
{{{"emplace_front"}, 1}, &ContainerModeling::handlePushFront},
{{{"pop_front"}, 0}, &ContainerModeling::handlePopFront},
};

CallDescriptionMap<OneItParamFn> OneIterParamFunctions = {
{{"insert", 2}, &ContainerModeling::handleInsert},
{{"emplace", 2}, &ContainerModeling::handleInsert},
{{"erase", 1}, &ContainerModeling::handleErase},
{{"erase_after", 1}, &ContainerModeling::handleEraseAfter},
{{{"insert"}, 2}, &ContainerModeling::handleInsert},
{{{"emplace"}, 2}, &ContainerModeling::handleInsert},
{{{"erase"}, 1}, &ContainerModeling::handleErase},
{{{"erase_after"}, 1}, &ContainerModeling::handleEraseAfter},
};

CallDescriptionMap<TwoItParamFn> TwoIterParamFunctions = {
{{"erase", 2}, &ContainerModeling::handleErase},
{{"erase_after", 2}, &ContainerModeling::handleEraseAfter},
{{{"erase"}, 2}, &ContainerModeling::handleErase},
{{{"erase_after"}, 2}, &ContainerModeling::handleEraseAfter},
};
};

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/DebugContainerModeling.cpp
Expand Up @@ -41,9 +41,9 @@ class DebugContainerModeling
CheckerContext &) const;

CallDescriptionMap<FnCheck> Callbacks = {
{{"clang_analyzer_container_begin", 1},
{{{"clang_analyzer_container_begin"}, 1},
&DebugContainerModeling::analyzerContainerBegin},
{{"clang_analyzer_container_end", 1},
{{{"clang_analyzer_container_end"}, 1},
&DebugContainerModeling::analyzerContainerEnd},
};

Expand Down

0 comments on commit 5ce4e92

Please sign in to comment.