cppcheck/lib/tokenlist.h

228 lines
6.6 KiB
C++

/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2023 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
#ifndef tokenlistH
#define tokenlistH
//---------------------------------------------------------------------------
#include "config.h"
#include <cstddef>
#include <iosfwd>
#include <string>
#include <vector>
class Settings;
class Token;
class TokenList;
namespace simplecpp {
class TokenList;
}
/// @addtogroup Core
/// @{
/**
* @brief This struct stores pointers to the front and back tokens of the list this token is in.
*/
struct TokensFrontBack {
Token *front{};
Token* back{};
const TokenList* list{};
};
class CPPCHECKLIB TokenList {
public:
explicit TokenList(const Settings* settings);
~TokenList();
TokenList(const TokenList &) = delete;
TokenList &operator=(const TokenList &) = delete;
/** @return the source file path. e.g. "file.cpp" */
const std::string& getSourceFilePath() const;
/** Is the code C. Used for bailouts */
bool isC() const {
return mIsC;
}
/** Is the code CPP. Used for bailouts */
bool isCPP() const {
return mIsCpp;
}
/**
* Delete all tokens in given token list
* @param tok token list to delete
*/
static void deleteTokens(Token *tok);
void addtoken(const std::string& str, const nonneg int lineno, const nonneg int column, const nonneg int fileno, bool split = false);
void addtoken(const std::string& str, const Token *locationTok);
void addtoken(const Token *tok, const nonneg int lineno, const nonneg int column, const nonneg int fileno);
void addtoken(const Token *tok, const Token *locationTok);
void addtoken(const Token *tok);
static void insertTokens(Token *dest, const Token *src, nonneg int n);
/**
* Copy tokens.
* @param dest destination token where copied tokens will be inserted after
* @param first first token to copy
* @param last last token to copy
* @param one_line true=>copy all tokens to the same line as dest. false=>copy all tokens to dest while keeping the 'line breaks'
* @return new location of last token copied
*/
static Token *copyTokens(Token *dest, const Token *first, const Token *last, bool one_line = true);
/**
* Create tokens from code.
* The code must be preprocessed first:
* - multiline strings are not handled.
* - UTF in the code are not handled.
* - comments are not handled.
* @param code input stream for code
* @param file0 source file name
*/
bool createTokens(std::istream &code, const std::string& file0 = emptyString);
void createTokens(simplecpp::TokenList&& tokenList);
/** Deallocate list */
void deallocateTokens();
/** append file name if seen the first time; return its index in any case */
int appendFileIfNew(std::string fileName);
/** get first token of list */
const Token *front() const {
return mTokensFrontBack.front;
}
// NOLINTNEXTLINE(readability-make-member-function-const) - do not allow usage of mutable pointer from const object
Token *front() {
return mTokensFrontBack.front;
}
/** get last token of list */
const Token *back() const {
return mTokensFrontBack.back;
}
// NOLINTNEXTLINE(readability-make-member-function-const) - do not allow usage of mutable pointer from const object
Token *back() {
return mTokensFrontBack.back;
}
/**
* Get filenames (the sourcefile + the files it include).
* The first filename is the filename for the sourcefile
* @return vector with filenames
*/
const std::vector<std::string>& getFiles() const {
return mFiles;
}
std::string getOrigFile(const Token *tok) const;
/**
* get filename for given token
* @param tok The given token
* @return filename for the given token
*/
const std::string& file(const Token *tok) const;
/**
* Get file:line for a given token
* @param tok given token
* @return location for given token
*/
std::string fileLine(const Token *tok) const;
/**
* Calculates a hash of the token list used to compare multiple
* token lists with each other as quickly as possible.
*/
std::size_t calculateHash() const;
/**
* Create abstract syntax tree.
*/
void createAst() const;
/**
* Check abstract syntax tree.
* Throws InternalError on failure
*/
void validateAst() const;
/**
* Verify that the given token is an element of the tokenlist.
* That method is implemented for debugging purposes.
* @param[in] tok token to be checked
* \return true if token was found in tokenlist, false else. In case of nullptr true is returned.
*/
bool validateToken(const Token* tok) const;
/**
* Convert platform dependent types to standard types.
* 32 bits: size_t -> unsigned long
* 64 bits: size_t -> unsigned long long
*/
void simplifyPlatformTypes();
/**
* Collapse compound standard types into a single token.
* unsigned long long int => long _isUnsigned=true,_isLong=true
*/
void simplifyStdType();
void clangSetOrigFiles();
bool isKeyword(const std::string &str) const;
private:
void determineCppC();
/** Token list */
TokensFrontBack mTokensFrontBack;
/** filenames for the tokenized source code (source + included) */
std::vector<std::string> mFiles;
/** Original filenames for the tokenized source code (source + included) */
std::vector<std::string> mOrigFiles;
/** settings */
const Settings* const mSettings{};
/** File is known to be C/C++ code */
bool mIsC{};
bool mIsCpp{};
};
/// @}
const Token* isLambdaCaptureList(const Token* tok);
const Token* findLambdaEndTokenWithoutAST(const Token* tok);
//---------------------------------------------------------------------------
#endif // tokenlistH