template simplifier: add forward declaration map to debug output (#1629)

* template simplifier: add forward declaration map to debug output

* template simplifier: add partial specialization flag

* template simplifier: add specialization map and partial specialization map to debug output
This commit is contained in:
IOBYTE 2019-01-27 01:46:27 -05:00 committed by Daniel Marjamäki
parent 2bba9ac78a
commit 606ba4fc1a
2 changed files with 172 additions and 27 deletions

View File

@ -77,7 +77,8 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *tok, const std::string &s,
{ {
// only set flags for declaration // only set flags for declaration
if (token && nameToken && paramEnd) { if (token && nameToken && paramEnd) {
isSpecialized(Token::simpleMatch(token, "template < >")); isSpecialization(Token::simpleMatch(token, "template < >"));
isPartialSpecialization(!isSpecialization() && nameToken->strAt(1) == "<");
isAlias(paramEnd->strAt(1) == "using"); isAlias(paramEnd->strAt(1) == "using");
isClass(Token::Match(paramEnd->next(), "class|struct|union %name% <|{|:|;")); isClass(Token::Match(paramEnd->next(), "class|struct|union %name% <|{|:|;"));
const Token *tok1 = nameToken->next(); const Token *tok1 = nameToken->next();
@ -1201,7 +1202,7 @@ void TemplateSimplifier::expandTemplate(
const Token * const templateDeclarationToken = templateDeclaration.paramEnd; const Token * const templateDeclarationToken = templateDeclaration.paramEnd;
const bool isClass = templateDeclaration.isClass(); const bool isClass = templateDeclaration.isClass();
const bool isFunction = templateDeclaration.isFunction(); const bool isFunction = templateDeclaration.isFunction();
const bool isSpecialization = templateDeclaration.isSpecialized(); const bool isSpecialization = templateDeclaration.isSpecialization();
const bool isVariable = templateDeclaration.isVariable(); const bool isVariable = templateDeclaration.isVariable();
// add forward declarations // add forward declarations
@ -1225,8 +1226,8 @@ void TemplateSimplifier::expandTemplate(
start = temp1->next(); start = temp1->next();
end = temp2->linkAt(1)->next(); end = temp2->linkAt(1)->next();
} else { } else {
auto it2 = mTemplateUserSpecializationMap.find(dst); auto it2 = mTemplateSpecializationMap.find(dst);
if (it2 != mTemplateUserSpecializationMap.end()) { if (it2 != mTemplateSpecializationMap.end()) {
dst = it2->second; dst = it2->second;
dstStart = dst->previous(); dstStart = dst->previous();
isStatic = dst->next()->findClosingBracket()->strAt(1) == "static"; isStatic = dst->next()->findClosingBracket()->strAt(1) == "static";
@ -2035,7 +2036,7 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
std::vector<const Token *> typeParametersInDeclaration; std::vector<const Token *> typeParametersInDeclaration;
getTemplateParametersInDeclaration(templateDeclaration.token->tokAt(2), typeParametersInDeclaration); getTemplateParametersInDeclaration(templateDeclaration.token->tokAt(2), typeParametersInDeclaration);
const bool printDebug = mSettings->debugwarnings; const bool printDebug = mSettings->debugwarnings;
const bool specialized = templateDeclaration.isSpecialized(); const bool specialized = templateDeclaration.isSpecialization();
const bool isfunc = templateDeclaration.isFunction(); const bool isfunc = templateDeclaration.isFunction();
const bool isVar = templateDeclaration.isVariable(); const bool isVar = templateDeclaration.isVariable();
@ -2316,20 +2317,20 @@ void TemplateSimplifier::replaceTemplateUsage(
} }
} }
void TemplateSimplifier::getUserDefinedSpecializations() void TemplateSimplifier::getSpecializations()
{ {
// try to locate a matching declaration for each user defined specialization // try to locate a matching declaration for each user defined specialization
for (auto & spec : mTemplateDeclarations) { for (auto & spec : mTemplateDeclarations) {
if (spec.isSpecialized()) { if (spec.isSpecialization()) {
bool found = false; bool found = false;
for (auto & decl : mTemplateDeclarations) { for (auto & decl : mTemplateDeclarations) {
if (decl.isSpecialized()) if (decl.isSpecialization())
continue; continue;
// make sure the scopes and names match // make sure the scopes and names match
if (spec.fullName == decl.fullName) { if (spec.fullName == decl.fullName) {
// @todo make sure function parameters also match // @todo make sure function parameters also match
mTemplateUserSpecializationMap[spec.token] = decl.token; mTemplateSpecializationMap[spec.token] = decl.token;
found = true; found = true;
} }
} }
@ -2339,7 +2340,38 @@ void TemplateSimplifier::getUserDefinedSpecializations()
// make sure the scopes and names match // make sure the scopes and names match
if (spec.fullName == decl.fullName) { if (spec.fullName == decl.fullName) {
// @todo make sure function parameters also match // @todo make sure function parameters also match
mTemplateUserSpecializationMap[spec.token] = decl.token; mTemplateSpecializationMap[spec.token] = decl.token;
}
}
}
}
}
}
void TemplateSimplifier::getPartialSpecializations()
{
// try to locate a matching declaration for each user defined partial specialization
for (auto & spec : mTemplateDeclarations) {
if (spec.isPartialSpecialization()) {
bool found = false;
for (auto & decl : mTemplateDeclarations) {
if (decl.isPartialSpecialization())
continue;
// make sure the scopes and names match
if (spec.fullName == decl.fullName) {
// @todo make sure function parameters also match
mTemplatePartialSpecializationMap[spec.token] = decl.token;
found = true;
}
}
if (!found) {
for (auto & decl : mTemplateForwardDeclarations) {
// make sure the scopes and names match
if (spec.fullName == decl.fullName) {
// @todo make sure function parameters also match
mTemplatePartialSpecializationMap[spec.token] = decl.token;
} }
} }
} }
@ -2418,8 +2450,10 @@ void TemplateSimplifier::printOut(const TokenAndName &tokenAndName, const std::s
std::cout << " isVariable"; std::cout << " isVariable";
if (tokenAndName.isAlias()) if (tokenAndName.isAlias())
std::cout << " isAlias"; std::cout << " isAlias";
if (tokenAndName.isSpecialized()) if (tokenAndName.isSpecialization())
std::cout << " isSpecialized"; std::cout << " isSpecialization";
if (tokenAndName.isPartialSpecialization())
std::cout << " isPartialSpecialization";
if (tokenAndName.isForwardDeclaration()) if (tokenAndName.isForwardDeclaration())
std::cout << " isForwardDeclaration"; std::cout << " isForwardDeclaration";
std::cout << std::endl; std::cout << std::endl;
@ -2454,6 +2488,98 @@ void TemplateSimplifier::printOut(const std::string & text) const
std::cout << "mTemplateForwardDeclarations[" << count++ << "]:" << std::endl; std::cout << "mTemplateForwardDeclarations[" << count++ << "]:" << std::endl;
printOut(decl); printOut(decl);
} }
std::cout << "mTemplateForwardDeclarationsMap: " << mTemplateForwardDeclarationsMap.size() << std::endl;
unsigned int mapIndex = 0;
for (const auto & mapItem : mTemplateForwardDeclarationsMap) {
unsigned int declIndex = 0;
for (const auto & decl : mTemplateDeclarations) {
if (mapItem.first == decl.token) {
unsigned int forwardIndex = 0;
for (const auto & forwardDecl : mTemplateForwardDeclarations) {
if (mapItem.second == forwardDecl.token) {
std::cout << "mTemplateForwardDeclarationsMap[" << mapIndex << "]:" << std::endl;
std::cout << " mTemplateDeclarations[" << declIndex
<< "] => mTemplateForwardDeclarations[" << forwardIndex << "]" << std::endl;
break;
}
forwardIndex++;
}
break;
}
declIndex++;
}
mapIndex++;
}
std::cout << "mTemplateSpecializationMap: " << mTemplateSpecializationMap.size() << std::endl;
for (const auto & mapItem : mTemplateSpecializationMap) {
unsigned int decl1Index = 0;
for (const auto & decl1 : mTemplateDeclarations) {
if (decl1.isSpecialization() && mapItem.first == decl1.token) {
bool found = 0;
unsigned int decl2Index = 0;
for (const auto & decl2 : mTemplateDeclarations) {
if (mapItem.second == decl2.token) {
std::cout << "mTemplateSpecializationMap[" << mapIndex << "]:" << std::endl;
std::cout << " mTemplateDeclarations[" << decl1Index
<< "] => mTemplateDeclarations[" << decl2Index << "]" << std::endl;
found = true;
break;
}
decl2Index++;
}
if (!found) {
decl2Index = 0;
for (const auto & decl2 : mTemplateForwardDeclarations) {
if (mapItem.second == decl2.token) {
std::cout << "mTemplateSpecializationMap[" << mapIndex << "]:" << std::endl;
std::cout << " mTemplateDeclarations[" << decl1Index
<< "] => mTemplateForwardDeclarations[" << decl2Index << "]" << std::endl;
break;
}
decl2Index++;
}
}
break;
}
decl1Index++;
}
mapIndex++;
}
std::cout << "mTemplatePartialSpecializationMap: " << mTemplatePartialSpecializationMap.size() << std::endl;
for (const auto & mapItem : mTemplatePartialSpecializationMap) {
unsigned int decl1Index = 0;
for (const auto & decl1 : mTemplateDeclarations) {
if (mapItem.first == decl1.token) {
bool found = 0;
unsigned int decl2Index = 0;
for (const auto & decl2 : mTemplateDeclarations) {
if (mapItem.second == decl2.token) {
std::cout << "mTemplatePartialSpecializationMap[" << mapIndex << "]:" << std::endl;
std::cout << " mTemplateDeclarations[" << decl1Index
<< "] => mTemplateDeclarations[" << decl2Index << "]" << std::endl;
found = true;
break;
}
decl2Index++;
}
if (!found) {
decl2Index = 0;
for (const auto & decl2 : mTemplateForwardDeclarations) {
if (mapItem.second == decl2.token) {
std::cout << "mTemplatePartialSpecializationMap[" << mapIndex << "]:" << std::endl;
std::cout << " mTemplateDeclarations[" << decl1Index
<< "] => mTemplateForwardDeclarations[" << decl2Index << "]" << std::endl;
break;
}
decl2Index++;
}
}
break;
}
decl1Index++;
}
mapIndex++;
}
std::cout << "mTemplateInstantiations: " << mTemplateInstantiations.size() << std::endl; std::cout << "mTemplateInstantiations: " << mTemplateInstantiations.size() << std::endl;
count = 0; count = 0;
for (const auto & decl : mTemplateInstantiations) { for (const auto & decl : mTemplateInstantiations) {
@ -2478,7 +2604,8 @@ void TemplateSimplifier::simplifyTemplates(
mTemplateDeclarations.clear(); mTemplateDeclarations.clear();
mTemplateForwardDeclarations.clear(); mTemplateForwardDeclarations.clear();
mTemplateForwardDeclarationsMap.clear(); mTemplateForwardDeclarationsMap.clear();
mTemplateUserSpecializationMap.clear(); mTemplateSpecializationMap.clear();
mTemplatePartialSpecializationMap.clear();
mTemplateInstantiations.clear(); mTemplateInstantiations.clear();
mInstantiatedTemplates.clear(); mInstantiatedTemplates.clear();
mExplicitInstantiationsToDelete.clear(); mExplicitInstantiationsToDelete.clear();
@ -2513,7 +2640,10 @@ void TemplateSimplifier::simplifyTemplates(
fixForwardDeclaredDefaultArgumentValues(); fixForwardDeclaredDefaultArgumentValues();
// Locate user defined specializations. // Locate user defined specializations.
getUserDefinedSpecializations(); getSpecializations();
// Locate user defined partial specializations.
getPartialSpecializations();
// Locate possible instantiations of templates.. // Locate possible instantiations of templates..
getTemplateInstantiations(); getTemplateInstantiations();
@ -2552,7 +2682,7 @@ void TemplateSimplifier::simplifyTemplates(
break; break;
} }
if (decl != mTemplateDeclarations.end()) { if (decl != mTemplateDeclarations.end()) {
if (it->isSpecialized()) { if (it->isSpecialization()) {
// delete the "template < >" // delete the "template < >"
Token * tok = it->token; Token * tok = it->token;
tok->deleteNext(2); tok->deleteNext(2);

View File

@ -99,12 +99,13 @@ public:
unsigned int flags; unsigned int flags;
enum { enum {
fIsClass = (1 << 0), // class template fIsClass = (1 << 0), // class template
fIsFunction = (1 << 1), // function template fIsFunction = (1 << 1), // function template
fIsVariable = (1 << 2), // variable template fIsVariable = (1 << 2), // variable template
fIsAlias = (1 << 3), // alias template fIsAlias = (1 << 3), // alias template
fIsSpecialized = (1 << 4), // user specialized template fIsSpecialization = (1 << 4), // user specialized template
fIsForwardDeclaration = (1 << 5), // forward declaration fIsPartialSpecialization = (1 << 5), // user partial specialized template
fIsForwardDeclaration = (1 << 6), // forward declaration
}; };
bool isClass() const { bool isClass() const {
@ -135,11 +136,18 @@ public:
setFlag(fIsAlias, state); setFlag(fIsAlias, state);
} }
bool isSpecialized() const { bool isSpecialization() const {
return getFlag(fIsSpecialized); return getFlag(fIsSpecialization);
} }
void isSpecialized(bool state) { void isSpecialization(bool state) {
setFlag(fIsSpecialized, state); setFlag(fIsSpecialization, state);
}
bool isPartialSpecialization() const {
return getFlag(fIsPartialSpecialization);
}
void isPartialSpecialization(bool state) {
setFlag(fIsPartialSpecialization, state);
} }
bool isForwardDeclaration() const { bool isForwardDeclaration() const {
@ -253,7 +261,13 @@ private:
* Try to locate a matching declaration for each user defined * Try to locate a matching declaration for each user defined
* specialization. * specialization.
*/ */
void getUserDefinedSpecializations(); void getSpecializations();
/**
* Try to locate a matching declaration for each user defined
* partial specialization.
*/
void getPartialSpecializations();
/** /**
* simplify template aliases * simplify template aliases
@ -377,7 +391,8 @@ private:
std::list<TokenAndName> mTemplateDeclarations; std::list<TokenAndName> mTemplateDeclarations;
std::list<TokenAndName> mTemplateForwardDeclarations; std::list<TokenAndName> mTemplateForwardDeclarations;
std::map<Token *, Token *> mTemplateForwardDeclarationsMap; std::map<Token *, Token *> mTemplateForwardDeclarationsMap;
std::map<Token *, Token *> mTemplateUserSpecializationMap; std::map<Token *, Token *> mTemplateSpecializationMap;
std::map<Token *, Token *> mTemplatePartialSpecializationMap;
std::list<TokenAndName> mTemplateInstantiations; std::list<TokenAndName> mTemplateInstantiations;
std::list<TokenAndName> mInstantiatedTemplates; std::list<TokenAndName> mInstantiatedTemplates;
std::list<TokenAndName> mMemberFunctionsToDelete; std::list<TokenAndName> mMemberFunctionsToDelete;