Coverage Report

Created: 2023-09-25 06:15

/src/cppcheck/lib/library.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Cppcheck - A tool for static C/C++ code analysis
3
 * Copyright (C) 2007-2023 Cppcheck team.
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
//---------------------------------------------------------------------------
20
#ifndef libraryH
21
#define libraryH
22
//---------------------------------------------------------------------------
23
24
#include "config.h"
25
#include "mathlib.h"
26
#include "errortypes.h"
27
#include "standards.h"
28
29
#include <cstddef>
30
#include <map>
31
#include <memory>
32
#include <set>
33
#include <string>
34
#include <unordered_map>
35
#include <unordered_set>
36
#include <utility>
37
#include <vector>
38
39
class Token;
40
class Settings;
41
42
namespace tinyxml2 {
43
    class XMLDocument;
44
    class XMLElement;
45
}
46
47
/// @addtogroup Core
48
/// @{
49
50
/**
51
 * @brief Library definitions handling
52
 */
53
class CPPCHECKLIB Library {
54
    // TODO: get rid of this
55
    friend class TestSymbolDatabase; // For testing only
56
    friend class TestSingleExecutorBase; // For testing only
57
    friend class TestThreadExecutor; // For testing only
58
    friend class TestProcessExecutor; // For testing only
59
60
public:
61
1.36k
    Library() = default;
62
63
    enum class ErrorCode { OK, FILE_NOT_FOUND, BAD_XML, UNKNOWN_ELEMENT, MISSING_ATTRIBUTE, BAD_ATTRIBUTE_VALUE, UNSUPPORTED_FORMAT, DUPLICATE_PLATFORM_TYPE, PLATFORM_TYPE_REDEFINED };
64
65
    class Error {
66
    public:
67
0
        Error() : errorcode(ErrorCode::OK) {}
68
0
        explicit Error(ErrorCode e) : errorcode(e) {}
69
        template<typename T>
70
0
        Error(ErrorCode e, T&& r) : errorcode(e), reason(r) {}
Unexecuted instantiation: Library::Error::Error<char const*>(Library::ErrorCode, char const*&&)
Unexecuted instantiation: Library::Error::Error<char const*&>(Library::ErrorCode, char const*&)
Unexecuted instantiation: Library::Error::Error<char const (&) [5]>(Library::ErrorCode, char const (&) [5])
Unexecuted instantiation: Library::Error::Error<char const (&) [6]>(Library::ErrorCode, char const (&) [6])
Unexecuted instantiation: Library::Error::Error<char const (&) [4]>(Library::ErrorCode, char const (&) [4])
Unexecuted instantiation: Library::Error::Error<char const (&) [7]>(Library::ErrorCode, char const (&) [7])
Unexecuted instantiation: Library::Error::Error<char const (&) [3]>(Library::ErrorCode, char const (&) [3])
Unexecuted instantiation: Library::Error::Error<char const* const&>(Library::ErrorCode, char const* const&)
Unexecuted instantiation: Library::Error::Error<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&>(Library::ErrorCode, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&)
Unexecuted instantiation: Library::Error::Error<char const (&) [11]>(Library::ErrorCode, char const (&) [11])
Unexecuted instantiation: Library::Error::Error<char const (&) [9]>(Library::ErrorCode, char const (&) [9])
Unexecuted instantiation: Library::Error::Error<char const (&) [42]>(Library::ErrorCode, char const (&) [42])
71
        ErrorCode errorcode;
72
        std::string reason;
73
    };
74
75
    Error load(const char exename[], const char path[]);
76
    Error load(const tinyxml2::XMLDocument &doc);
77
78
    /** this is used for unit tests */
79
    bool loadxmldata(const char xmldata[], std::size_t len);
80
81
    struct AllocFunc {
82
        int groupId;
83
        int arg;
84
        enum class BufferSize {none,malloc,calloc,strdup};
85
        BufferSize bufferSize;
86
        int bufferSizeArg1;
87
        int bufferSizeArg2;
88
        int reallocArg;
89
        bool initData;
90
    };
91
92
    /** get allocation info for function */
93
    const AllocFunc* getAllocFuncInfo(const Token *tok) const;
94
95
    /** get deallocation info for function */
96
    const AllocFunc* getDeallocFuncInfo(const Token *tok) const;
97
98
    /** get reallocation info for function */
99
    const AllocFunc* getReallocFuncInfo(const Token *tok) const;
100
101
    /** get allocation id for function */
102
    int getAllocId(const Token *tok, int arg) const;
103
104
    /** get deallocation id for function */
105
    int getDeallocId(const Token *tok, int arg) const;
106
107
    /** get reallocation id for function */
108
    int getReallocId(const Token *tok, int arg) const;
109
110
    // TODO: get rid of this
111
    /** get allocation info for function by name (deprecated, use other alloc) */
112
0
    const AllocFunc* getAllocFuncInfo(const char name[]) const {
113
0
        return getAllocDealloc(mAlloc, name);
114
0
    }
115
116
    // TODO: get rid of this
117
    /** get deallocation info for function by name (deprecated, use other alloc) */
118
0
    const AllocFunc* getDeallocFuncInfo(const char name[]) const {
119
0
        return getAllocDealloc(mDealloc, name);
120
0
    }
121
122
    // TODO: get rid of this
123
    /** get allocation id for function by name (deprecated, use other alloc) */
124
    // cppcheck-suppress unusedFunction
125
0
    int allocId(const char name[]) const {
126
0
        const AllocFunc* af = getAllocDealloc(mAlloc, name);
127
0
        return af ? af->groupId : 0;
128
0
    }
129
130
    // TODO: get rid of this
131
    /** get deallocation id for function by name (deprecated, use other alloc) */
132
0
    int deallocId(const char name[]) const {
133
0
        const AllocFunc* af = getAllocDealloc(mDealloc, name);
134
0
        return af ? af->groupId : 0;
135
0
    }
136
137
    /** set allocation id for function */
138
    // cppcheck-suppress unusedFunction - test-only
139
0
    void setalloc(const std::string &functionname, int id, int arg) {
140
0
        mAlloc[functionname].groupId = id;
141
0
        mAlloc[functionname].arg = arg;
142
0
    }
143
144
    // cppcheck-suppress unusedFunction - test-only
145
0
    void setdealloc(const std::string &functionname, int id, int arg) {
146
0
        mDealloc[functionname].groupId = id;
147
0
        mDealloc[functionname].arg = arg;
148
0
    }
149
150
    // cppcheck-suppress unusedFunction - test-only
151
0
    void setrealloc(const std::string &functionname, int id, int arg, int reallocArg = 1) {
152
0
        mRealloc[functionname].groupId = id;
153
0
        mRealloc[functionname].arg = arg;
154
0
        mRealloc[functionname].reallocArg = reallocArg;
155
0
    }
156
157
    /** add noreturn function setting */
158
    // cppcheck-suppress unusedFunction - test-only
159
0
    void setnoreturn(const std::string& funcname, bool noreturn) {
160
0
        mNoReturn[funcname] = noreturn ? FalseTrueMaybe::True : FalseTrueMaybe::False;
161
0
    }
162
163
    static bool isCompliantValidationExpression(const char* p);
164
165
    /** is allocation type memory? */
166
0
    static bool ismemory(const int id) {
167
0
        return ((id > 0) && ((id & 1) == 0));
168
0
    }
169
0
    static bool ismemory(const AllocFunc* const func) {
170
0
        return func && (func->groupId > 0) && ((func->groupId & 1) == 0);
171
0
    }
172
173
    /** is allocation type resource? */
174
0
    static bool isresource(const int id) {
175
0
        return ((id > 0) && ((id & 1) == 1));
176
0
    }
177
0
    static bool isresource(const AllocFunc* const func) {
178
0
        return func && (func->groupId > 0) && ((func->groupId & 1) == 1);
179
0
    }
180
181
    bool formatstr_function(const Token* ftok) const;
182
    int formatstr_argno(const Token* ftok) const;
183
    bool formatstr_scan(const Token* ftok) const;
184
    bool formatstr_secure(const Token* ftok) const;
185
186
    struct NonOverlappingData {
187
        int ptr1Arg;
188
        int ptr2Arg;
189
        int sizeArg;
190
        int strlenArg;
191
    };
192
    const NonOverlappingData* getNonOverlappingData(const Token *ftok) const;
193
194
    struct WarnInfo {
195
        std::string message;
196
        Standards standards;
197
        Severity::SeverityType severity;
198
    };
199
    std::map<std::string, WarnInfo> functionwarn;
200
201
    const WarnInfo* getWarnInfo(const Token* ftok) const;
202
203
    // returns true if ftok is not a library function
204
    bool isNotLibraryFunction(const Token *ftok) const;
205
    bool matchArguments(const Token *ftok, const std::string &functionName) const;
206
207
    enum class UseRetValType { NONE, DEFAULT, ERROR_CODE };
208
    UseRetValType getUseRetValType(const Token* ftok) const;
209
210
    const std::string& returnValue(const Token *ftok) const;
211
    const std::string& returnValueType(const Token *ftok) const;
212
    int returnValueContainer(const Token *ftok) const;
213
    std::vector<MathLib::bigint> unknownReturnValues(const Token *ftok) const;
214
215
    bool isnoreturn(const Token *ftok) const;
216
    bool isnotnoreturn(const Token *ftok) const;
217
218
    bool isScopeNoReturn(const Token *end, std::string *unknownFunc) const;
219
220
    class Container {
221
    public:
222
0
        Container() = default;
223
224
        enum class Action {
225
            RESIZE,
226
            CLEAR,
227
            PUSH,
228
            POP,
229
            FIND,
230
            INSERT,
231
            ERASE,
232
            CHANGE_CONTENT,
233
            CHANGE,
234
            CHANGE_INTERNAL,
235
            NO_ACTION
236
        };
237
        enum class Yield {
238
            AT_INDEX,
239
            ITEM,
240
            BUFFER,
241
            BUFFER_NT,
242
            START_ITERATOR,
243
            END_ITERATOR,
244
            ITERATOR,
245
            SIZE,
246
            EMPTY,
247
            NO_YIELD
248
        };
249
        struct Function {
250
            Action action;
251
            Yield yield;
252
            std::string returnType;
253
        };
254
        struct RangeItemRecordTypeItem {
255
            std::string name;
256
            int templateParameter; // TODO: use this
257
        };
258
        std::string startPattern, startPattern2, endPattern, itEndPattern;
259
        std::map<std::string, Function> functions;
260
        int type_templateArgNo = -1;
261
        std::vector<RangeItemRecordTypeItem> rangeItemRecordType;
262
        int size_templateArgNo = -1;
263
        bool arrayLike_indexOp{};
264
        bool stdStringLike{};
265
        bool stdAssociativeLike{};
266
        bool opLessAllowed = true;
267
        bool hasInitializerListConstructor{};
268
        bool unstableErase{};
269
        bool unstableInsert{};
270
        bool view{};
271
272
0
        Action getAction(const std::string& function) const {
273
0
            const std::map<std::string, Function>::const_iterator i = functions.find(function);
274
0
            if (i != functions.end())
275
0
                return i->second.action;
276
0
            return Action::NO_ACTION;
277
0
        }
278
279
0
        Yield getYield(const std::string& function) const {
280
0
            const std::map<std::string, Function>::const_iterator i = functions.find(function);
281
0
            if (i != functions.end())
282
0
                return i->second.yield;
283
0
            return Yield::NO_YIELD;
284
0
        }
285
286
0
        const std::string& getReturnType(const std::string& function) const {
287
0
            auto i = functions.find(function);
288
0
            return (i != functions.end()) ? i->second.returnType : emptyString;
289
0
        }
290
291
        static Yield yieldFrom(const std::string& yieldName);
292
        static Action actionFrom(const std::string& actionName);
293
    };
294
    std::unordered_map<std::string, Container> containers;
295
    const Container* detectContainer(const Token* typeStart) const;
296
    const Container* detectIterator(const Token* typeStart) const;
297
    const Container* detectContainerOrIterator(const Token* typeStart, bool* isIterator = nullptr, bool withoutStd = false) const;
298
299
    struct ArgumentChecks {
300
        bool notbool{};
301
        bool notnull{};
302
        int notuninit = -1;
303
        bool formatstr{};
304
        bool strz{};
305
        bool optional{};
306
        bool variadic{};
307
        std::string valid;
308
309
        struct IteratorInfo {
310
            int container{};
311
            bool it{};
312
            bool first{};
313
            bool last{};
314
        };
315
        IteratorInfo iteratorInfo;
316
317
        struct MinSize {
318
            enum class Type { NONE, STRLEN, ARGVALUE, SIZEOF, MUL, VALUE };
319
0
            MinSize(Type t, int a) : type(t), arg(a) {}
320
            Type type;
321
            int arg;
322
            int arg2 = 0;
323
            long long value = 0;
324
            std::string baseType;
325
        };
326
        std::vector<MinSize> minsizes;
327
328
        enum class Direction {
329
            DIR_IN,     ///< Input to called function. Data is treated as read-only.
330
            DIR_OUT,    ///< Output to caller. Data is passed by reference or address and is potentially written.
331
            DIR_INOUT,  ///< Input to called function, and output to caller. Data is passed by reference or address and is potentially modified.
332
            DIR_UNKNOWN ///< direction not known / specified
333
        };
334
        Direction direction = Direction::DIR_UNKNOWN;
335
    };
336
337
    struct Function {
338
        std::map<int, ArgumentChecks> argumentChecks; // argument nr => argument data
339
        bool use{};
340
        bool leakignore{};
341
        bool isconst{};
342
        bool ispure{};
343
        UseRetValType useretval = UseRetValType::NONE;
344
        bool ignore{};  // ignore functions/macros from a library (gtk, qt etc)
345
        bool formatstr{};
346
        bool formatstr_scan{};
347
        bool formatstr_secure{};
348
        Container::Action containerAction = Container::Action::NO_ACTION;
349
        Container::Yield containerYield = Container::Yield::NO_YIELD;
350
        std::string returnType;
351
    };
352
353
    const Function *getFunction(const Token *ftok) const;
354
    std::unordered_map<std::string, Function> functions;
355
    bool isUse(const std::string& functionName) const;
356
    bool isLeakIgnore(const std::string& functionName) const;
357
    bool isFunctionConst(const std::string& functionName, bool pure) const;
358
    bool isFunctionConst(const Token *ftok) const;
359
360
1.03k
    bool isboolargbad(const Token *ftok, int argnr) const {
361
1.03k
        const ArgumentChecks *arg = getarg(ftok, argnr);
362
1.03k
        return arg && arg->notbool;
363
1.03k
    }
364
365
    bool isnullargbad(const Token *ftok, int argnr) const;
366
    bool isuninitargbad(const Token *ftok, int argnr, int indirect = 0, bool *hasIndirect=nullptr) const;
367
368
0
    bool isargformatstr(const Token *ftok, int argnr) const {
369
0
        const ArgumentChecks *arg = getarg(ftok, argnr);
370
0
        return arg && arg->formatstr;
371
0
    }
372
373
1.38k
    bool isargstrz(const Token *ftok, int argnr) const {
374
1.38k
        const ArgumentChecks *arg = getarg(ftok, argnr);
375
1.38k
        return arg && arg->strz;
376
1.38k
    }
377
378
    bool isIntArgValid(const Token *ftok, int argnr, const MathLib::bigint argvalue) const;
379
    bool isFloatArgValid(const Token *ftok, int argnr, double argvalue) const;
380
381
0
    const std::string& validarg(const Token *ftok, int argnr) const {
382
0
        const ArgumentChecks *arg = getarg(ftok, argnr);
383
0
        return arg ? arg->valid : emptyString;
384
0
    }
385
386
1.38k
    const ArgumentChecks::IteratorInfo *getArgIteratorInfo(const Token *ftok, int argnr) const {
387
1.38k
        const ArgumentChecks *arg = getarg(ftok, argnr);
388
1.38k
        return arg && arg->iteratorInfo.it ? &arg->iteratorInfo : nullptr;
389
1.38k
    }
390
391
    bool hasminsize(const Token *ftok) const;
392
393
0
    const std::vector<ArgumentChecks::MinSize> *argminsizes(const Token *ftok, int argnr) const {
394
0
        const ArgumentChecks *arg = getarg(ftok, argnr);
395
0
        return arg ? &arg->minsizes : nullptr;
396
0
    }
397
398
    ArgumentChecks::Direction getArgDirection(const Token* ftok, int argnr) const;
399
400
    bool markupFile(const std::string &path) const;
401
402
    bool processMarkupAfterCode(const std::string &path) const;
403
404
0
    const std::set<std::string> &markupExtensions() const {
405
0
        return mMarkupExtensions;
406
0
    }
407
408
    bool reportErrors(const std::string &path) const;
409
410
    bool ignorefunction(const std::string &functionName) const;
411
412
    bool isexecutableblock(const std::string &file, const std::string &token) const;
413
414
    int blockstartoffset(const std::string &file) const;
415
416
    const std::string& blockstart(const std::string &file) const;
417
    const std::string& blockend(const std::string &file) const;
418
419
    bool iskeyword(const std::string &file, const std::string &keyword) const;
420
421
92.2k
    bool isexporter(const std::string &prefix) const {
422
92.2k
        return mExporters.find(prefix) != mExporters.end();
423
92.2k
    }
424
425
0
    bool isexportedprefix(const std::string &prefix, const std::string &token) const {
426
0
        const std::map<std::string, ExportedFunctions>::const_iterator it = mExporters.find(prefix);
427
0
        return (it != mExporters.end() && it->second.isPrefix(token));
428
0
    }
429
430
0
    bool isexportedsuffix(const std::string &prefix, const std::string &token) const {
431
0
        const std::map<std::string, ExportedFunctions>::const_iterator it = mExporters.find(prefix);
432
0
        return (it != mExporters.end() && it->second.isSuffix(token));
433
0
    }
434
435
    bool isimporter(const std::string& file, const std::string &importer) const;
436
437
    const Token* getContainerFromYield(const Token* tok, Container::Yield yield) const;
438
    const Token* getContainerFromAction(const Token* tok, Container::Action action) const;
439
440
92.2k
    bool isreflection(const std::string &token) const {
441
92.2k
        return mReflection.find(token) != mReflection.end();
442
92.2k
    }
443
444
0
    int reflectionArgument(const std::string &token) const {
445
0
        const std::map<std::string, int>::const_iterator it = mReflection.find(token);
446
0
        if (it != mReflection.end())
447
0
            return it->second;
448
0
        return -1;
449
0
    }
450
451
1.73k
    bool isentrypoint(const std::string &func) const {
452
1.73k
        return func == "main" || mEntrypoints.find(func) != mEntrypoints.end();
453
1.73k
    }
454
455
    std::vector<std::string> defines; // to provide some library defines
456
457
    struct SmartPointer {
458
        std::string name;
459
        bool unique = false;
460
    };
461
462
    std::unordered_map<std::string, SmartPointer> smartPointers;
463
    bool isSmartPointer(const Token *tok) const;
464
    const SmartPointer* detectSmartPointer(const Token* tok, bool withoutStd = false) const;
465
466
    struct PodType {
467
        unsigned int size;
468
        char sign;
469
        enum class Type { NO, BOOL, CHAR, SHORT, INT, LONG, LONGLONG } stdtype;
470
    };
471
34.1k
    const struct PodType *podtype(const std::string &name) const {
472
34.1k
        const std::unordered_map<std::string, struct PodType>::const_iterator it = mPodTypes.find(name);
473
34.1k
        return (it != mPodTypes.end()) ? &(it->second) : nullptr;
474
34.1k
    }
475
476
    struct PlatformType {
477
0
        bool operator == (const PlatformType & type) const {
478
0
            return (mSigned == type.mSigned &&
479
0
                    mUnsigned == type.mUnsigned &&
480
0
                    mLong == type.mLong &&
481
0
                    mPointer == type.mPointer &&
482
0
                    mPtrPtr == type.mPtrPtr &&
483
0
                    mConstPtr == type.mConstPtr &&
484
0
                    mType == type.mType);
485
0
        }
486
0
        bool operator != (const PlatformType & type) const {
487
0
            return !(*this == type);
488
0
        }
489
        std::string mType;
490
        bool mSigned{};
491
        bool mUnsigned{};
492
        bool mLong{};
493
        bool mPointer{};
494
        bool mPtrPtr{};
495
        bool mConstPtr{};
496
    };
497
498
    struct Platform {
499
0
        const PlatformType *platform_type(const std::string &name) const {
500
0
            const std::map<std::string, struct PlatformType>::const_iterator it = mPlatformTypes.find(name);
501
0
            return (it != mPlatformTypes.end()) ? &(it->second) : nullptr;
502
0
        }
503
        std::map<std::string, PlatformType> mPlatformTypes;
504
    };
505
506
43.3k
    const PlatformType *platform_type(const std::string &name, const std::string & platform) const {
507
43.3k
        const std::map<std::string, Platform>::const_iterator it = mPlatforms.find(platform);
508
43.3k
        if (it != mPlatforms.end()) {
509
0
            const PlatformType * const type = it->second.platform_type(name);
510
0
            if (type)
511
0
                return type;
512
0
        }
513
514
43.3k
        const std::map<std::string, PlatformType>::const_iterator it2 = mPlatformTypes.find(name);
515
43.3k
        return (it2 != mPlatformTypes.end()) ? &(it2->second) : nullptr;
516
43.3k
    }
517
518
    /**
519
     * Get function name for function call
520
     */
521
    std::string getFunctionName(const Token *ftok) const;
522
523
    static bool isContainerYield(const Token * const cond, Library::Container::Yield y, const std::string& fallback=emptyString);
524
525
    /** Suppress/check a type */
526
    enum class TypeCheck { def,
527
                           check,
528
                           suppress,
529
                           checkFiniteLifetime, // (unusedvar) object has side effects, but immediate destruction is wrong
530
    };
531
    TypeCheck getTypeCheck(std::string check, std::string typeName) const;
532
    bool hasAnyTypeCheck(const std::string& typeName) const;
533
534
private:
535
    // load a <function> xml node
536
    Error loadFunction(const tinyxml2::XMLElement * const node, const std::string &name, std::set<std::string> &unknown_elements);
537
538
    class ExportedFunctions {
539
    public:
540
0
        void addPrefix(std::string prefix) {
541
0
            mPrefixes.insert(std::move(prefix));
542
0
        }
543
0
        void addSuffix(std::string suffix) {
544
0
            mSuffixes.insert(std::move(suffix));
545
0
        }
546
0
        bool isPrefix(const std::string& prefix) const {
547
0
            return (mPrefixes.find(prefix) != mPrefixes.end());
548
0
        }
549
0
        bool isSuffix(const std::string& suffix) const {
550
0
            return (mSuffixes.find(suffix) != mSuffixes.end());
551
0
        }
552
553
    private:
554
        std::set<std::string> mPrefixes;
555
        std::set<std::string> mSuffixes;
556
    };
557
    class CodeBlock {
558
    public:
559
0
        CodeBlock() = default;
560
561
0
        void setStart(const char* s) {
562
0
            mStart = s;
563
0
        }
564
0
        void setEnd(const char* e) {
565
0
            mEnd = e;
566
0
        }
567
0
        void setOffset(const int o) {
568
0
            mOffset = o;
569
0
        }
570
0
        void addBlock(const char* blockName) {
571
0
            mBlocks.insert(blockName);
572
0
        }
573
0
        const std::string& start() const {
574
0
            return mStart;
575
0
        }
576
0
        const std::string& end() const {
577
0
            return mEnd;
578
0
        }
579
0
        int offset() const {
580
0
            return mOffset;
581
0
        }
582
0
        bool isBlock(const std::string& blockName) const {
583
0
            return mBlocks.find(blockName) != mBlocks.end();
584
0
        }
585
586
    private:
587
        std::string mStart;
588
        std::string mEnd;
589
        int mOffset{};
590
        std::set<std::string> mBlocks;
591
    };
592
    enum class FalseTrueMaybe { False, True, Maybe };
593
    int mAllocId{};
594
    std::set<std::string> mFiles;
595
    std::map<std::string, AllocFunc> mAlloc; // allocation functions
596
    std::map<std::string, AllocFunc> mDealloc; // deallocation functions
597
    std::map<std::string, AllocFunc> mRealloc; // reallocation functions
598
    std::unordered_map<std::string, FalseTrueMaybe> mNoReturn; // is function noreturn?
599
    std::map<std::string, std::string> mReturnValue;
600
    std::map<std::string, std::string> mReturnValueType;
601
    std::map<std::string, int> mReturnValueContainer;
602
    std::map<std::string, std::vector<MathLib::bigint>> mUnknownReturnValues;
603
    std::map<std::string, bool> mReportErrors;
604
    std::map<std::string, bool> mProcessAfterCode;
605
    std::set<std::string> mMarkupExtensions; // file extensions of markup files
606
    std::map<std::string, std::set<std::string>> mKeywords;  // keywords for code in the library
607
    std::unordered_map<std::string, CodeBlock> mExecutableBlocks; // keywords for blocks of executable code
608
    std::map<std::string, ExportedFunctions> mExporters; // keywords that export variables/functions to libraries (meta-code/macros)
609
    std::map<std::string, std::set<std::string>> mImporters;  // keywords that import variables/functions
610
    std::map<std::string, int> mReflection; // invocation of reflection
611
    std::unordered_map<std::string, struct PodType> mPodTypes; // pod types
612
    std::map<std::string, PlatformType> mPlatformTypes; // platform independent typedefs
613
    std::map<std::string, Platform> mPlatforms; // platform dependent typedefs
614
    std::map<std::pair<std::string,std::string>, TypeCheck> mTypeChecks;
615
    std::unordered_map<std::string, NonOverlappingData> mNonOverlappingData;
616
    std::unordered_set<std::string> mEntrypoints;
617
618
    const ArgumentChecks * getarg(const Token *ftok, int argnr) const;
619
620
    std::string getFunctionName(const Token *ftok, bool &error) const;
621
622
4.56k
    static const AllocFunc* getAllocDealloc(const std::map<std::string, AllocFunc> &data, const std::string &name) {
623
4.56k
        const std::map<std::string, AllocFunc>::const_iterator it = data.find(name);
624
4.56k
        return (it == data.end()) ? nullptr : &it->second;
625
4.56k
    }
626
627
    enum DetectContainer { ContainerOnly, IteratorOnly, Both };
628
    const Library::Container* detectContainerInternal(const Token* typeStart, DetectContainer detect, bool* isIterator = nullptr, bool withoutStd = false) const;
629
};
630
631
CPPCHECKLIB const Library::Container * getLibraryContainer(const Token * tok);
632
633
std::shared_ptr<Token> createTokenFromExpression(const std::string& returnValue,
634
                                                 const Settings* settings,
635
                                                 std::unordered_map<nonneg int, const Token*>* lookupVarId = nullptr);
636
637
/// @}
638
//---------------------------------------------------------------------------
639
#endif // libraryH