@@ -810,15 +810,18 @@ struct ParameterShape {
810810struct DeducedType {
811811 std::string typeStr; // base type, e.g. "int" or "MyClass"
812812 std::string qualification; // enclosing scopes of record and enum types, "N :: A"
813+ const Scope* typeScope = nullptr ; // the scope of a record or enum type
814+ bool globalQualification = false ; // write the type with a leading "::"
813815 unsigned int constness = 0 ; // bit 0 = data const, bit 1 = first '*' const, ..
814816 unsigned int pointer = 0 ; // number of '*'
815817 bool isUnsigned = false ;
816818 bool isLong = false ;
817819
818820 bool operator ==(const DeducedType& other) const
819821 {
820- return typeStr == other.typeStr && qualification == other.qualification && constness == other.constness &&
821- pointer == other.pointer && isUnsigned == other.isUnsigned && isLong == other.isLong ;
822+ return typeStr == other.typeStr && qualification == other.qualification && typeScope == other.typeScope &&
823+ constness == other.constness && pointer == other.pointer && isUnsigned == other.isUnsigned &&
824+ isLong == other.isLong ;
822825 }
823826};
824827
@@ -916,9 +919,40 @@ static DeducedType deducedScopeType(DeducedType deduced, const Scope* typeScope)
916919 if (deduced.qualification .empty () && enclosing && enclosing->type != ScopeType::eGlobal)
917920 return DeducedType (); // local types etc. cannot be named - bail out
918921 deduced.typeStr = typeScope->className ;
922+ deduced.typeScope = typeScope;
919923 return deduced;
920924}
921925
926+ // Does the name of the deduced type, looked up from the given scope, find another scope
927+ // than the one the type is in? The instantiation is declared in the scope of the
928+ // template, so "S" deduced from "::S" would be resolved to "X::S" when the template is
929+ // in namespace X and X has its own S. Such a type must be written with a leading "::".
930+ static bool deducedTypeIsShadowed (const Scope* from, const DeducedType& deduced)
931+ {
932+ if (!deduced.typeScope )
933+ return false ;
934+ // the outermost named scope of the type: "N" for "N :: A :: M", the type itself for "S"
935+ const Scope* outermost = deduced.typeScope ;
936+ while (outermost->nestedIn && outermost->nestedIn ->type != ScopeType::eGlobal)
937+ outermost = outermost->nestedIn ;
938+ const std::string& name = outermost->className ;
939+ for (const Scope* scope = from; scope && scope->type != ScopeType::eGlobal; scope = scope->nestedIn ) {
940+ // in a class the nested types of the base classes are visible too
941+ std::vector<const Scope*> lookupScopes;
942+ if (scope->isClassOrStructOrUnion ())
943+ lookupScopes = scope->findAssociatedScopes ();
944+ else
945+ lookupScopes.push_back (scope);
946+ for (const Scope* lookupScope : lookupScopes) {
947+ for (const Scope* nested : lookupScope->nestedList ) {
948+ if (nested->className == name)
949+ return nested != outermost;
950+ }
951+ }
952+ }
953+ return false ;
954+ }
955+
922956// Convert the type of an argument expression to the type that the parameter shape
923957// deduces for its template parameter. The returned type has an empty typeStr when the
924958// type is not supported.
@@ -1070,6 +1104,8 @@ static void insertDeducedType(Token* tok, const DeducedType& deduced)
10701104{
10711105 if (deduced.constness & 1U )
10721106 tok = tok->insertToken (" const" );
1107+ if (deduced.globalQualification )
1108+ tok = tok->insertToken (" ::" );
10731109 const std::string& qualification = deduced.qualification ;
10741110 for (std::string::size_type pos = 0 ; pos < qualification.size ();) {
10751111 std::string::size_type end = qualification.find (' ' , pos);
@@ -1335,6 +1371,8 @@ std::string TemplateSimplifier::deduceFunctionTemplateArguments(
13351371 // find the function template declarations this call could instantiate
13361372 std::vector<const TokenAndName*> candidates;
13371373 std::string baseClassQualification;
1374+ // the scope the template is declared in - the instantiation is declared there too
1375+ const Scope* declarationScope = nullptr ;
13381376 for (const LookupLevel& level : lookup.levels ) {
13391377 // a non template function with the same name might be a better overload match
13401378 if (level.scope && scopeHasNonTemplateFunction (level.scope , tok->str ()))
@@ -1347,6 +1385,7 @@ std::string TemplateSimplifier::deduceFunctionTemplateArguments(
13471385 if (!candidates.empty ()) {
13481386 if (level.isBaseClass )
13491387 baseClassQualification = level.scopeName ;
1388+ declarationScope = level.scope ;
13501389 break ;
13511390 }
13521391 }
@@ -1398,6 +1437,19 @@ std::string TemplateSimplifier::deduceFunctionTemplateArguments(
13981437 stored = std::move (deduced);
13991438 }
14001439
1440+ // a deduced type whose name is shadowed in the scope of the template must be written
1441+ // with a leading "::" so the instantiation does not use the wrong type
1442+ if (!declarationScope)
1443+ declarationScope = declaration->nameToken ()->scope (); // explicitly qualified call
1444+ for (DeducedType& deduced : deducedTypes) {
1445+ if (!deduced.typeScope )
1446+ continue ;
1447+ if (!declarationScope)
1448+ return qualification; // cannot tell which type the name would resolve to
1449+ if (deducedTypeIsShadowed (declarationScope, deduced))
1450+ deduced.globalQualification = true ;
1451+ }
1452+
14011453 // when the declaration is in a base class, qualify the call site explicitly so the
14021454 // instantiation is matched with that declaration: "btf ( x )" => "Base :: btf ( x )"
14031455 if (!baseClassQualification.empty ()) {
0 commit comments