This commit is contained in:
parent
7e1ecdbb37
commit
e57a674458
|
@ -1763,9 +1763,9 @@ namespace {
|
|||
std::list<ScopeInfo3> children;
|
||||
Type type;
|
||||
std::string fullName;
|
||||
const std::string name;
|
||||
const Token * const bodyStart;
|
||||
const Token * const bodyEnd;
|
||||
std::string name;
|
||||
const Token * bodyStart;
|
||||
const Token * bodyEnd;
|
||||
std::set<std::string> usingNamespaces;
|
||||
std::set<std::string> recordTypes;
|
||||
std::set<std::string> baseTypes;
|
||||
|
@ -1859,9 +1859,19 @@ namespace {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ScopeInfo3 * findScope(const ScopeInfo3 * scope) {
|
||||
if (scope->bodyStart == bodyStart)
|
||||
return this;
|
||||
for (auto & child : children) {
|
||||
if (child.findScope(scope))
|
||||
return &child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
void setScopeInfo(Token *tok, ScopeInfo3 **scopeInfo, bool all = false)
|
||||
void setScopeInfo(Token *tok, ScopeInfo3 **scopeInfo)
|
||||
{
|
||||
if (!tok)
|
||||
return;
|
||||
|
@ -1920,7 +1930,7 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
if (all && !added)
|
||||
if (!added)
|
||||
*scopeInfo = (*scopeInfo)->addChild(ScopeInfo3::Other, "", tok, tok->link());
|
||||
}
|
||||
return;
|
||||
|
@ -2182,9 +2192,9 @@ bool Tokenizer::simplifyUsing()
|
|||
if (end && Token::Match(end->next(), "class|struct|union %name%"))
|
||||
currentScope->recordTypes.insert(end->strAt(2));
|
||||
|
||||
Token *endToken = TemplateSimplifier::findTemplateDeclarationEnd(tok);
|
||||
if (endToken)
|
||||
tok = endToken;
|
||||
Token *declEndToken = TemplateSimplifier::findTemplateDeclarationEnd(tok);
|
||||
if (declEndToken)
|
||||
tok = declEndToken;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2195,8 +2205,6 @@ bool Tokenizer::simplifyUsing()
|
|||
Token::Match(tok->linkAt(2), "] ] = ::| %name%")))))
|
||||
continue;
|
||||
|
||||
ScopeInfo3 scopeInfo1;
|
||||
ScopeInfo3 *currentScope1 = &scopeInfo1;
|
||||
std::string name = tok->strAt(1);
|
||||
const Token *nameToken = tok->next();
|
||||
std::string scope = currentScope->fullName;
|
||||
|
@ -2278,15 +2286,31 @@ bool Tokenizer::simplifyUsing()
|
|||
// Unfortunately we have to start searching from the beginning
|
||||
// of the token stream because templates are instantiated at
|
||||
// the end of the token stream and it may be used before then.
|
||||
ScopeInfo3 scopeInfo1;
|
||||
ScopeInfo3 *currentScope1 = &scopeInfo1;
|
||||
Token *startToken = list.front();
|
||||
Token *endToken = nullptr;
|
||||
|
||||
// We can limit the search to the current function when the type alias
|
||||
// is defined in that function.
|
||||
if (currentScope->type == ScopeInfo3::Other) {
|
||||
scopeInfo1 = scopeInfo;
|
||||
currentScope1 = scopeInfo.findScope(currentScope);
|
||||
if (!currentScope1)
|
||||
return substitute; // something bad happened
|
||||
startToken = usingEnd;
|
||||
endToken = currentScope->bodyEnd->next();
|
||||
}
|
||||
|
||||
std::string scope1;
|
||||
bool inMemberFunc = false;
|
||||
const ScopeInfo3 * memberFuncScope = nullptr;
|
||||
const Token * memberFuncEnd = nullptr;
|
||||
bool skip = false; // don't erase type aliases we can't parse
|
||||
for (Token* tok1 = list.front(); tok1; tok1 = tok1->next()) {
|
||||
for (Token* tok1 = startToken; tok1 != endToken; tok1 = tok1->next()) {
|
||||
if ((Token::Match(tok1, "{|}|namespace|class|struct|union") && tok1->strAt(-1) != "using") ||
|
||||
Token::Match(tok1, "using namespace %name% ;|::")) {
|
||||
setScopeInfo(tok1, ¤tScope1, true);
|
||||
setScopeInfo(tok1, ¤tScope1);
|
||||
scope1 = currentScope1->fullName;
|
||||
if (inMemberFunc && memberFuncEnd && tok1 == memberFuncEnd) {
|
||||
inMemberFunc = false;
|
||||
|
@ -2298,9 +2322,9 @@ bool Tokenizer::simplifyUsing()
|
|||
|
||||
// skip template definitions
|
||||
if (Token::Match(tok1, "template < !!>")) {
|
||||
Token *endToken = TemplateSimplifier::findTemplateDeclarationEnd(tok1);
|
||||
if (endToken)
|
||||
tok1 = endToken;
|
||||
Token *declEndToken = TemplateSimplifier::findTemplateDeclarationEnd(tok1);
|
||||
if (declEndToken)
|
||||
tok1 = declEndToken;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ private:
|
|||
TEST_CASE(simplifyUsing10136);
|
||||
TEST_CASE(simplifyUsing10171);
|
||||
TEST_CASE(simplifyUsing10172);
|
||||
TEST_CASE(simplifyUsing10173);
|
||||
}
|
||||
|
||||
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Native, bool debugwarnings = true) {
|
||||
|
@ -1100,6 +1101,30 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void simplifyUsing10173() {
|
||||
const char code[] = "std::ostream & operator<<(std::ostream &s, const Pr<st> p) {\n"
|
||||
" return s;\n"
|
||||
"}\n"
|
||||
"void foo() {\n"
|
||||
" using Pr = d::Pr<st>;\n"
|
||||
" Pr p;\n"
|
||||
"}\n"
|
||||
"void bar() {\n"
|
||||
" Pr<st> p;\n"
|
||||
"}";
|
||||
const char exp[] = "std :: ostream & operator<< ( std :: ostream & s , const Pr < st > p ) { "
|
||||
"return s ; "
|
||||
"} "
|
||||
"void foo ( ) { "
|
||||
"d :: Pr < st > p ; "
|
||||
"} "
|
||||
"void bar ( ) { "
|
||||
"Pr < st > p ; "
|
||||
"}";
|
||||
ASSERT_EQUALS(exp, tok(code, true));
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestSimplifyUsing)
|
||||
|
|
Loading…
Reference in New Issue