Skip to content

Commit 3a34536

Browse files
committed
make sure the language for a TokenList is always determined
1 parent 48f8f82 commit 3a34536

14 files changed

Lines changed: 102 additions & 49 deletions

lib/clangimport.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,8 +330,12 @@ namespace clangimport {
330330
void dumpAst(int num = 0, int indent = 0) const;
331331
void createTokens1(TokenList &tokenList) {
332332
//dumpAst();
333-
if (!tokenList.back())
333+
if (!tokenList.back()) {
334334
setLocations(tokenList, 0, 1, 1);
335+
// FIXME: treat as C++ if no filename (i.e. no lang) is specified for now
336+
if (tokenList.getSourceFilePath().empty())
337+
tokenList.setLang(Standards::Language::CPP);
338+
}
335339
else
336340
setLocations(tokenList, tokenList.back()->fileIndex(), tokenList.back()->linenr(), 1);
337341
createTokens(tokenList);
@@ -626,6 +630,7 @@ void clangimport::AstNode::setValueType(Token *tok)
626630
continue;
627631

628632
TokenList decl(nullptr);
633+
decl.setLang(tok->isCpp() ? Standards::Language::CPP : Standards::Language::C);
629634
addTypeTokens(decl, type, tok->scope());
630635
if (!decl.front())
631636
break;

lib/cppcheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ unsigned int CppCheck::checkFile(const std::string& filename, const std::string
797797
}
798798
Tokenizer tokenizer2(&mSettings, this);
799799
std::istringstream istr2(code);
800-
tokenizer2.list.createTokens(istr2);
800+
tokenizer2.list.createTokens(istr2, Path::identify(*files.begin()));
801801
executeRules("define", tokenizer2);
802802
}
803803
#endif

lib/library.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ static std::vector<std::string> getnames(const char *names)
5353
return ret;
5454
}
5555

56-
static void gettokenlistfromvalid(const std::string& valid, TokenList& tokenList)
56+
static void gettokenlistfromvalid(const std::string& valid, bool cpp, TokenList& tokenList)
5757
{
5858
std::istringstream istr(valid + ',');
59-
tokenList.createTokens(istr);
59+
tokenList.createTokens(istr, cpp ? Standards::Language::CPP : Standards::Language::C);
6060
for (Token *tok = tokenList.front(); tok; tok = tok->next()) {
6161
if (Token::Match(tok,"- %num%")) {
6262
tok->str("-" + tok->strAt(1));
@@ -920,7 +920,7 @@ bool Library::isIntArgValid(const Token *ftok, int argnr, const MathLib::bigint
920920
if (ac->valid.find('.') != std::string::npos)
921921
return isFloatArgValid(ftok, argnr, argvalue);
922922
TokenList tokenList(nullptr);
923-
gettokenlistfromvalid(ac->valid, tokenList);
923+
gettokenlistfromvalid(ac->valid, ftok->isCpp(), tokenList);
924924
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
925925
if (tok->isNumber() && argvalue == MathLib::toBigNumber(tok->str()))
926926
return true;
@@ -940,7 +940,7 @@ bool Library::isFloatArgValid(const Token *ftok, int argnr, double argvalue) con
940940
if (!ac || ac->valid.empty())
941941
return true;
942942
TokenList tokenList(nullptr);
943-
gettokenlistfromvalid(ac->valid, tokenList);
943+
gettokenlistfromvalid(ac->valid, ftok->isCpp(), tokenList);
944944
for (const Token *tok = tokenList.front(); tok; tok = tok->next()) {
945945
if (Token::Match(tok, "%num% : %num%") && argvalue >= MathLib::toDoubleNumber(tok->str()) && argvalue <= MathLib::toDoubleNumber(tok->strAt(2)))
946946
return true;
@@ -1729,13 +1729,14 @@ bool Library::hasAnyTypeCheck(const std::string& typeName) const
17291729

17301730
std::shared_ptr<Token> createTokenFromExpression(const std::string& returnValue,
17311731
const Settings* settings,
1732+
bool cpp,
17321733
std::unordered_map<nonneg int, const Token*>* lookupVarId)
17331734
{
17341735
std::shared_ptr<TokenList> tokenList = std::make_shared<TokenList>(settings);
17351736
{
17361737
const std::string code = "return " + returnValue + ";";
17371738
std::istringstream istr(code);
1738-
if (!tokenList->createTokens(istr))
1739+
if (!tokenList->createTokens(istr, cpp ? Standards::Language::CPP : Standards::Language::C))
17391740
return nullptr;
17401741
}
17411742

lib/library.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ CPPCHECKLIB const Library::Container * getLibraryContainer(const Token * tok);
603603

604604
std::shared_ptr<Token> createTokenFromExpression(const std::string& returnValue,
605605
const Settings* settings,
606+
bool cpp,
606607
std::unordered_map<nonneg int, const Token*>* lookupVarId = nullptr);
607608

608609
/// @}

lib/programmemory.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,7 +1595,7 @@ namespace {
15951595
arg_map[argn] = v;
15961596
argn++;
15971597
}
1598-
return evaluateLibraryFunction(arg_map, returnValue, settings);
1598+
return evaluateLibraryFunction(arg_map, returnValue, settings, ftok->isCpp());
15991599
}
16001600
}
16011601
}
@@ -1751,15 +1751,16 @@ std::vector<ValueFlow::Value> execute(const Scope* scope, ProgramMemory& pm, con
17511751

17521752
ValueFlow::Value evaluateLibraryFunction(const std::unordered_map<nonneg int, ValueFlow::Value>& args,
17531753
const std::string& returnValue,
1754-
const Settings* settings)
1754+
const Settings* settings,
1755+
bool cpp)
17551756
{
17561757
thread_local static std::unordered_map<std::string,
17571758
std::function<ValueFlow::Value(const std::unordered_map<nonneg int, ValueFlow::Value>& arg)>>
17581759
functions = {};
17591760
if (functions.count(returnValue) == 0) {
17601761

17611762
std::unordered_map<nonneg int, const Token*> lookupVarId;
1762-
std::shared_ptr<Token> expr = createTokenFromExpression(returnValue, settings, &lookupVarId);
1763+
std::shared_ptr<Token> expr = createTokenFromExpression(returnValue, settings, cpp, &lookupVarId);
17631764

17641765
functions[returnValue] =
17651766
[lookupVarId, expr, settings](const std::unordered_map<nonneg int, ValueFlow::Value>& xargs) {

lib/programmemory.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ ProgramMemory getProgramMemory(const Token* tok, const Token* expr, const ValueF
211211

212212
ValueFlow::Value evaluateLibraryFunction(const std::unordered_map<nonneg int, ValueFlow::Value>& args,
213213
const std::string& returnValue,
214-
const Settings* settings);
214+
const Settings* settings,
215+
bool cpp);
215216

216217
#endif
217218

lib/symboldatabase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7479,7 +7479,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
74797479
ValueType valuetype;
74807480
TokenList tokenList(&mSettings);
74817481
std::istringstream istr(typestr+";");
7482-
tokenList.createTokens(istr);
7482+
tokenList.createTokens(istr, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C);
74837483
tokenList.simplifyStdType();
74847484
if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) {
74857485
valuetype.originalTypeName = typestr;
@@ -7569,7 +7569,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
75697569
}
75707570
TokenList tokenList(&mSettings);
75717571
std::istringstream istr(typestr+";");
7572-
if (tokenList.createTokens(istr)) {
7572+
if (tokenList.createTokens(istr, tok->isCpp() ? Standards::Language::CPP : Standards::Language::C)) {
75737573
ValueType vt;
75747574
tokenList.simplifyPlatformTypes();
75757575
tokenList.simplifyStdType();

lib/token.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,5 +2741,6 @@ bool Token::isCpp() const
27412741
if (mTokensFrontBack && mTokensFrontBack->list) {
27422742
return mTokensFrontBack->list->isCPP();
27432743
}
2744+
assert(false);
27442745
return true; // assume C++ by default
27452746
}

lib/token.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class CPPCHECKLIB Token {
151151
friend class TestToken;
152152

153153
private:
154-
TokensFrontBack* mTokensFrontBack{};
154+
TokensFrontBack* const mTokensFrontBack{};
155155

156156
public:
157157
Token(const Token &) = delete;

lib/tokenlist.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "standards.h"
3131
#include "token.h"
3232

33+
#include <cassert>
3334
#include <cctype>
3435
#include <exception>
3536
#include <functional>
@@ -83,7 +84,7 @@ void TokenList::deallocateTokens()
8384

8485
void TokenList::determineCppC()
8586
{
86-
// only try to determine it if it wasn't enforced
87+
// only try to determine if it wasn't enforced
8788
if (mLang == Standards::Language::None) {
8889
mLang = Path::identify(getSourceFilePath());
8990
}
@@ -317,8 +318,27 @@ void TokenList::insertTokens(Token *dest, const Token *src, nonneg int n)
317318

318319
bool TokenList::createTokens(std::istream &code, const std::string& file0)
319320
{
321+
assert(!file0.empty());
322+
320323
appendFileIfNew(file0);
321324

325+
return createTokensInternal(code, file0);
326+
}
327+
328+
//---------------------------------------------------------------------------
329+
330+
bool TokenList::createTokens(std::istream &code, Standards::Language lang)
331+
{
332+
if (mLang == Standards::Language::None)
333+
mLang = lang;
334+
335+
return createTokensInternal(code, "");
336+
}
337+
338+
//---------------------------------------------------------------------------
339+
340+
bool TokenList::createTokensInternal(std::istream &code, const std::string& file0)
341+
{
322342
simplecpp::OutputList outputList;
323343
simplecpp::TokenList tokens(code, mFiles, file0, &outputList);
324344

@@ -2096,3 +2116,25 @@ bool TokenList::isKeyword(const std::string &str) const
20962116
static const auto& latest_c_keywords = Keywords::getAll(Standards::cstd_t::CLatest);
20972117
return latest_c_keywords.find(str) != latest_c_keywords.end();
20982118
}
2119+
2120+
bool TokenList::isC() const
2121+
{
2122+
assert(mLang != Standards::Language::None);
2123+
2124+
return mLang == Standards::Language::C;
2125+
}
2126+
2127+
bool TokenList::isCPP() const
2128+
{
2129+
assert(mLang != Standards::Language::None);
2130+
2131+
return mLang == Standards::Language::CPP;
2132+
}
2133+
2134+
void TokenList::setLang(Standards::Language lang)
2135+
{
2136+
assert(lang != Standards::Language::None);
2137+
assert(mLang == Standards::Language::None);
2138+
2139+
mLang = lang;
2140+
}

0 commit comments

Comments
 (0)