@@ -452,7 +452,8 @@ namespace {
452
452
bool inCase{}; // true from case to :
453
453
bool stopAtColon{}; // help to properly parse ternary operators
454
454
const Token* functionCallEndPar{};
455
- explicit AST_state (bool cpp) : cpp(cpp) {}
455
+ const Library &library;
456
+ explicit AST_state (bool cpp, const Library &library) : cpp(cpp), library(library) {}
456
457
};
457
458
}
458
459
@@ -490,7 +491,7 @@ static Token* skipDecl(Token* tok, std::vector<Token*>* inner = nullptr)
490
491
return tok;
491
492
}
492
493
493
- static bool iscast (const Token *tok, bool cpp )
494
+ static bool iscast (const Token *tok, const AST_state &state )
494
495
{
495
496
if (!Token::Match (tok, " ( ::| %name%" ))
496
497
return false ;
@@ -502,7 +503,7 @@ static bool iscast(const Token *tok, bool cpp)
502
503
return false ;
503
504
504
505
if (tok->previous () && tok->previous ()->isName () && tok->strAt (-1 ) != " return" &&
505
- (!cpp || !Token::Match (tok->previous (), " delete|throw" )))
506
+ (!state. cpp || !Token::Match (tok->previous (), " delete|throw" )))
506
507
return false ;
507
508
508
509
if (Token::simpleMatch (tok->previous (), " >" ) && tok->linkAt (-1 ))
@@ -527,7 +528,10 @@ static bool iscast(const Token *tok, bool cpp)
527
528
for (const Token *tok2 = tok->next (); tok2; tok2 = tok2->next ()) {
528
529
if (tok2->varId () != 0 )
529
530
return false ;
530
- if (cpp && !type && tok2->str () == " new" )
531
+ if (state.cpp && !type && tok2->str () == " new" )
532
+ return false ;
533
+
534
+ if (!state.library .isNotLibraryFunction (tok2))
531
535
return false ;
532
536
533
537
while (tok2->link () && Token::Match (tok2, " (|[|<" ))
@@ -802,7 +806,7 @@ static void compileTerm(Token *&tok, AST_state& state)
802
806
std::vector<Token*> inner;
803
807
tok = skipDecl (tok, &inner);
804
808
for (Token* tok3 : inner) {
805
- AST_state state1 (state.cpp );
809
+ AST_state state1 (state.cpp , state. library );
806
810
compileExpression (tok3, state1);
807
811
}
808
812
bool repeat = true ;
@@ -832,7 +836,7 @@ static void compileTerm(Token *&tok, AST_state& state)
832
836
}
833
837
} else if (tok->str () == " {" ) {
834
838
const Token *prev = tok->previous ();
835
- if (Token::simpleMatch (prev, " ) {" ) && iscast (prev->link (), state. cpp ))
839
+ if (Token::simpleMatch (prev, " ) {" ) && iscast (prev->link (), state))
836
840
prev = prev->link ()->previous ();
837
841
if (Token::simpleMatch (tok->link ()," } [" )) {
838
842
tok = tok->next ();
@@ -904,9 +908,9 @@ static void compileScope(Token *&tok, AST_state& state)
904
908
}
905
909
}
906
910
907
- static bool isPrefixUnary (const Token* tok, bool cpp )
911
+ static bool isPrefixUnary (const Token* tok, const AST_state &state )
908
912
{
909
- if (cpp && Token::simpleMatch (tok->previous (), " * [" ) && Token::simpleMatch (tok->link (), " ] {" )) {
913
+ if (state. cpp && Token::simpleMatch (tok->previous (), " * [" ) && Token::simpleMatch (tok->link (), " ] {" )) {
910
914
for (const Token* prev = tok->previous (); Token::Match (prev, " %name%|::|*|&|>|>>" ); prev = prev->previous ()) {
911
915
if (Token::Match (prev, " >|>>" )) {
912
916
if (!prev->link ())
@@ -918,7 +922,7 @@ static bool isPrefixUnary(const Token* tok, bool cpp)
918
922
}
919
923
}
920
924
if (!tok->previous ()
921
- || ((Token::Match (tok->previous (), " (|[|{|%op%|;|?|:|,|.|case|return|::" ) || (cpp && tok->strAt (-1 ) == " throw" ))
925
+ || ((Token::Match (tok->previous (), " (|[|{|%op%|;|?|:|,|.|case|return|::" ) || (state. cpp && tok->strAt (-1 ) == " throw" ))
922
926
&& (tok->previous ()->tokType () != Token::eIncDecOp || tok->tokType () == Token::eIncDecOp)))
923
927
return true ;
924
928
@@ -927,10 +931,10 @@ static bool isPrefixUnary(const Token* tok, bool cpp)
927
931
return !Token::Match (parent, " %type%" ) || parent->isKeyword ();
928
932
}
929
933
930
- if (tok->str () == " *" && tok->previous ()->tokType () == Token::eIncDecOp && isPrefixUnary (tok->previous (), cpp ))
934
+ if (tok->str () == " *" && tok->previous ()->tokType () == Token::eIncDecOp && isPrefixUnary (tok->previous (), state ))
931
935
return true ;
932
936
933
- return tok->strAt (-1 ) == " )" && iscast (tok->linkAt (-1 ), cpp );
937
+ return tok->strAt (-1 ) == " )" && iscast (tok->linkAt (-1 ), state );
934
938
}
935
939
936
940
static void compilePrecedence2 (Token *&tok, AST_state& state)
@@ -956,7 +960,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
956
960
isNew = false ;
957
961
}
958
962
while (tok) {
959
- if (tok->tokType () == Token::eIncDecOp && !isPrefixUnary (tok, state. cpp )) {
963
+ if (tok->tokType () == Token::eIncDecOp && !isPrefixUnary (tok, state)) {
960
964
compileUnaryOp (tok, state, compileScope);
961
965
} else if (tok->str () == " ..." ) {
962
966
if (!Token::simpleMatch (tok->previous (), " )" ))
@@ -974,7 +978,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
974
978
else
975
979
compileUnaryOp (tok, state, compileScope);
976
980
} else if (tok->str () == " [" ) {
977
- if (state.cpp && isPrefixUnary (tok, /* cpp */ true ) && Token::Match (tok->link (), " ] (|{|<" )) { // Lambda
981
+ if (state.cpp && isPrefixUnary (tok, state ) && Token::Match (tok->link (), " ] (|{|<" )) { // Lambda
978
982
// What we do here:
979
983
// - Nest the round bracket under the square bracket.
980
984
// - Nest what follows the lambda (if anything) with the lambda opening [
@@ -984,7 +988,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
984
988
// Parse arguments in the capture list
985
989
if (tok->strAt (1 ) != " ]" ) {
986
990
Token* tok2 = tok->next ();
987
- AST_state state2 (state.cpp );
991
+ AST_state state2 (state.cpp , state. library );
988
992
compileExpression (tok2, state2);
989
993
if (!state2.op .empty ()) {
990
994
squareBracket->astOperand2 (state2.op .top ());
@@ -1048,7 +1052,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
1048
1052
tok = tok->link ()->next ();
1049
1053
continue ;
1050
1054
} else if (tok->str () == " (" &&
1051
- (!iscast (tok, state. cpp ) || Token::Match (tok->previous (), " if|while|for|switch|catch" ))) {
1055
+ (!iscast (tok, state) || Token::Match (tok->previous (), " if|while|for|switch|catch" ))) {
1052
1056
Token* tok2 = tok;
1053
1057
tok = tok->next ();
1054
1058
const bool opPrevTopSquare = !state.op .empty () && state.op .top () && state.op .top ()->str () == " [" ;
@@ -1059,7 +1063,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
1059
1063
|| (tok->previous () && tok->previous ()->isName () && !Token::Match (tok->previous (), " return|case" ) && (!state.cpp || !Token::Match (tok->previous (), " throw|delete" )))
1060
1064
|| (tok->strAt (-1 ) == " ]" && (!state.cpp || !Token::Match (tok->linkAt (-1 )->previous (), " new|delete" )))
1061
1065
|| (tok->strAt (-1 ) == " >" && tok->linkAt (-1 ))
1062
- || (tok->strAt (-1 ) == " )" && !iscast (tok->linkAt (-1 ), state. cpp )) // Don't treat brackets to clarify precedence as function calls
1066
+ || (tok->strAt (-1 ) == " )" && !iscast (tok->linkAt (-1 ), state)) // Don't treat brackets to clarify precedence as function calls
1063
1067
|| (tok->strAt (-1 ) == " }" && opPrevTopSquare)) {
1064
1068
const bool operandInside = oldOpSize < state.op .size ();
1065
1069
if (operandInside)
@@ -1070,7 +1074,7 @@ static void compilePrecedence2(Token *&tok, AST_state& state)
1070
1074
tok = tok->link ()->next ();
1071
1075
if (Token::simpleMatch (tok, " ::" ))
1072
1076
compileBinOp (tok, state, compileTerm);
1073
- } else if (iscast (tok, state. cpp ) && Token::simpleMatch (tok->link (), " ) {" ) &&
1077
+ } else if (iscast (tok, state) && Token::simpleMatch (tok->link (), " ) {" ) &&
1074
1078
Token::simpleMatch (tok->link ()->linkAt (1 ), " } [" )) {
1075
1079
Token *cast = tok;
1076
1080
tok = tok->link ()->next ();
@@ -1103,7 +1107,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
1103
1107
compilePrecedence2 (tok, state);
1104
1108
while (tok) {
1105
1109
if ((Token::Match (tok, " [+-!~*&]" ) || tok->tokType () == Token::eIncDecOp) &&
1106
- isPrefixUnary (tok, state. cpp )) {
1110
+ isPrefixUnary (tok, state)) {
1107
1111
if (Token::Match (tok, " * [*,)]" )) {
1108
1112
Token* tok2 = tok->next ();
1109
1113
while (tok2->next () && tok2->str () == " *" )
@@ -1114,7 +1118,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
1114
1118
}
1115
1119
}
1116
1120
compileUnaryOp (tok, state, compilePrecedence3);
1117
- } else if (tok->str () == " (" && iscast (tok, state. cpp )) {
1121
+ } else if (tok->str () == " (" && iscast (tok, state)) {
1118
1122
Token* castTok = tok;
1119
1123
castTok->isCast (true );
1120
1124
tok = tok->link ()->next ();
@@ -1134,7 +1138,7 @@ static void compilePrecedence3(Token *&tok, AST_state& state)
1134
1138
if (Token::Match (tok->link (), " ) ::| %type%" )) {
1135
1139
if (Token::Match (tok, " ( !!)" )) {
1136
1140
Token *innerTok = tok->next ();
1137
- AST_state innerState (true );
1141
+ AST_state innerState (true , state. library );
1138
1142
compileExpression (innerTok, innerState);
1139
1143
}
1140
1144
tok = tok->link ()->next ();
@@ -1459,10 +1463,10 @@ const Token* findLambdaEndTokenWithoutAST(const Token* tok) {
1459
1463
return tok->link ()->next ();
1460
1464
}
1461
1465
1462
- static Token * createAstAtToken (Token *tok);
1466
+ static Token * createAstAtToken (Token *tok, const Library &library );
1463
1467
1464
1468
// Compile inner expressions inside inner ({..}) and lambda bodies
1465
- static void createAstAtTokenInner (Token * const tok1, const Token *endToken, bool cpp)
1469
+ static void createAstAtTokenInner (Token * const tok1, const Token *endToken, bool cpp, const Library &library )
1466
1470
{
1467
1471
for (Token* tok = tok1; precedes (tok, endToken); tok = tok ? tok->next () : nullptr ) {
1468
1472
if (tok->str () == " {" && !iscpp11init (tok)) {
@@ -1480,7 +1484,7 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo
1480
1484
}
1481
1485
if (!hasAst) {
1482
1486
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next () : nullptr )
1483
- tok = createAstAtToken (tok);
1487
+ tok = createAstAtToken (tok, library );
1484
1488
}
1485
1489
} else if (cpp && tok->str () == " [" ) {
1486
1490
if (isLambdaCaptureList (tok)) {
@@ -1490,7 +1494,7 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo
1490
1494
const Token * const endToken2 = tok->link ();
1491
1495
tok = tok->next ();
1492
1496
for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next () : nullptr )
1493
- tok = createAstAtToken (tok);
1497
+ tok = createAstAtToken (tok, library );
1494
1498
}
1495
1499
}
1496
1500
else if (Token::simpleMatch (tok, " ( * ) [" )) {
@@ -1504,9 +1508,9 @@ static void createAstAtTokenInner(Token * const tok1, const Token *endToken, boo
1504
1508
if (!hasAst) {
1505
1509
Token *const startTok = tok = tok->tokAt (4 );
1506
1510
const Token* const endtok = startTok->linkAt (-1 );
1507
- AST_state state (cpp);
1511
+ AST_state state (cpp, library );
1508
1512
compileExpression (tok, state);
1509
- createAstAtTokenInner (startTok, endtok, cpp);
1513
+ createAstAtTokenInner (startTok, endtok, cpp, library );
1510
1514
}
1511
1515
}
1512
1516
}
@@ -1532,7 +1536,7 @@ static Token * findAstTop(Token *tok1, const Token *tok2)
1532
1536
return nullptr ;
1533
1537
}
1534
1538
1535
- static Token * createAstAtToken (Token *tok)
1539
+ static Token * createAstAtToken (Token *tok, const Library &library )
1536
1540
{
1537
1541
const bool cpp = tok->isCpp ();
1538
1542
// skip function pointer declaration
@@ -1570,7 +1574,7 @@ static Token * createAstAtToken(Token *tok)
1570
1574
if (cpp && Token::Match (tok, " for ( const| auto &|&&| [" )) {
1571
1575
Token *decl = Token::findsimplematch (tok, " [" );
1572
1576
if (Token::simpleMatch (decl->link (), " ] :" )) {
1573
- AST_state state1 (cpp);
1577
+ AST_state state1 (cpp, library );
1574
1578
while (decl->str () != " ]" ) {
1575
1579
if (Token::Match (decl, " %name% ,|]" )) {
1576
1580
state1.op .push (decl);
@@ -1607,14 +1611,14 @@ static Token * createAstAtToken(Token *tok)
1607
1611
std::vector<Token*> inner;
1608
1612
Token* tok2 = skipDecl (tok->tokAt (2 ), &inner);
1609
1613
for (Token* tok3 : inner) {
1610
- AST_state state1 (cpp);
1614
+ AST_state state1 (cpp, library );
1611
1615
compileExpression (tok3, state1);
1612
1616
}
1613
1617
Token *init1 = nullptr ;
1614
1618
Token * const endPar = tok->linkAt (1 );
1615
1619
if (tok2 == tok->tokAt (2 ) && Token::Match (tok2, " %op%|(" )) {
1616
1620
init1 = tok2;
1617
- AST_state state1 (cpp);
1621
+ AST_state state1 (cpp, library );
1618
1622
compileExpression (tok2, state1);
1619
1623
if (Token::Match (init1, " ( !!{" )) {
1620
1624
for (Token *tok3 = init1; tok3 && tok3 != tok3->link (); tok3 = tok3->next ()) {
@@ -1634,7 +1638,7 @@ static Token * createAstAtToken(Token *tok)
1634
1638
tok2 = tok2->link ();
1635
1639
} else if (Token::Match (tok2, " %name% )| %op%|(|[|{|.|:|::" ) || Token::Match (tok2->previous (), " [(;{}] %cop%|(" )) {
1636
1640
init1 = tok2;
1637
- AST_state state1 (cpp);
1641
+ AST_state state1 (cpp, library );
1638
1642
compileExpression (tok2, state1);
1639
1643
if (Token::Match (tok2, " ;|)" ))
1640
1644
break ;
@@ -1647,7 +1651,7 @@ static Token * createAstAtToken(Token *tok)
1647
1651
}
1648
1652
if (!tok2 || tok2->str () != " ;" ) {
1649
1653
if (tok2 == endPar && init1) {
1650
- createAstAtTokenInner (init1->next (), endPar, cpp);
1654
+ createAstAtTokenInner (init1->next (), endPar, cpp, library );
1651
1655
tok->next ()->astOperand2 (init1);
1652
1656
tok->next ()->astOperand1 (tok);
1653
1657
}
@@ -1658,7 +1662,7 @@ static Token * createAstAtToken(Token *tok)
1658
1662
1659
1663
Token * const semicolon1 = tok2;
1660
1664
tok2 = tok2->next ();
1661
- AST_state state2 (cpp);
1665
+ AST_state state2 (cpp, library );
1662
1666
compileExpression (tok2, state2);
1663
1667
1664
1668
Token * const semicolon2 = tok2;
@@ -1667,7 +1671,7 @@ static Token * createAstAtToken(Token *tok)
1667
1671
1668
1672
if (semicolon2->str () == " ;" ) {
1669
1673
tok2 = tok2->next ();
1670
- AST_state state3 (cpp);
1674
+ AST_state state3 (cpp, library );
1671
1675
if (Token::simpleMatch (tok2, " ( {" )) {
1672
1676
state3.op .push (tok2->next ());
1673
1677
tok2 = tok2->link ()->next ();
@@ -1695,7 +1699,7 @@ static Token * createAstAtToken(Token *tok)
1695
1699
tok->next ()->astOperand1 (tok);
1696
1700
tok->next ()->astOperand2 (semicolon1);
1697
1701
1698
- createAstAtTokenInner (endPar->link (), endPar, cpp);
1702
+ createAstAtTokenInner (endPar->link (), endPar, cpp, library );
1699
1703
1700
1704
return endPar;
1701
1705
}
@@ -1718,9 +1722,9 @@ static Token * createAstAtToken(Token *tok)
1718
1722
}
1719
1723
if (Token::Match (tok2, " %name%|> %name% {" ) && tok2->next ()->varId () && iscpp11init (tok2->tokAt (2 ))) {
1720
1724
Token *const tok1 = tok = tok2->next ();
1721
- AST_state state (cpp);
1725
+ AST_state state (cpp, library );
1722
1726
compileExpression (tok, state);
1723
- createAstAtTokenInner (tok1->next (), tok1->linkAt (1 ), cpp);
1727
+ createAstAtTokenInner (tok1->next (), tok1->linkAt (1 ), cpp, library );
1724
1728
return tok;
1725
1729
}
1726
1730
}
@@ -1760,7 +1764,7 @@ static Token * createAstAtToken(Token *tok)
1760
1764
tok = tok->previous ();
1761
1765
1762
1766
Token * const tok1 = tok;
1763
- AST_state state (cpp);
1767
+ AST_state state (cpp, library );
1764
1768
if (Token::Match (tok, " %name% (" ))
1765
1769
state.functionCallEndPar = tok->linkAt (1 );
1766
1770
if (Token::simpleMatch (tok->tokAt (-1 ), " ::" ) && (!tok->tokAt (-2 ) || !tok->tokAt (-2 )->isName ()))
@@ -1770,20 +1774,20 @@ static Token * createAstAtToken(Token *tok)
1770
1774
if (endToken == tok1 || !endToken)
1771
1775
return tok1;
1772
1776
1773
- createAstAtTokenInner (tok1->next (), endToken, cpp);
1777
+ createAstAtTokenInner (tok1->next (), endToken, cpp, library );
1774
1778
1775
1779
return endToken->previous ();
1776
1780
}
1777
1781
1778
1782
if (cpp && tok->str () == " {" && iscpp11init (tok)) {
1779
1783
Token * const tok1 = tok;
1780
- AST_state state (cpp);
1784
+ AST_state state (cpp, library );
1781
1785
compileExpression (tok, state);
1782
1786
Token* const endToken = tok;
1783
1787
if (endToken == tok1 || !endToken)
1784
1788
return tok1;
1785
1789
1786
- createAstAtTokenInner (tok1->next (), endToken, cpp);
1790
+ createAstAtTokenInner (tok1->next (), endToken, cpp, library );
1787
1791
return endToken->previous ();
1788
1792
}
1789
1793
@@ -1793,7 +1797,7 @@ static Token * createAstAtToken(Token *tok)
1793
1797
void TokenList::createAst () const
1794
1798
{
1795
1799
for (Token *tok = mTokensFrontBack .front ; tok; tok = tok ? tok->next () : nullptr ) {
1796
- Token* const nextTok = createAstAtToken (tok);
1800
+ Token* const nextTok = createAstAtToken (tok, mSettings -> library );
1797
1801
if (precedes (nextTok, tok))
1798
1802
throw InternalError (tok, " Syntax Error: Infinite loop when creating AST." , InternalError::AST);
1799
1803
tok = nextTok;
0 commit comments