1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 17:35:35 +02:00

Owner of friend function templates, bug 265671.

This commit is contained in:
Markus Schorn 2009-02-20 16:35:07 +00:00
parent d3f9d03f77
commit eb5858ca7a
5 changed files with 78 additions and 10 deletions

View file

@ -48,7 +48,9 @@ public class ASTComparer extends Assert {
// avoid name resolution
"isDeclaration",
"isDefinition",
"isReference"
"isReference",
"isAssociatedWithLastName",
"getNestingLevel"
));

View file

@ -3858,4 +3858,39 @@ public class AST2TemplateTests extends AST2BaseTest {
bh.assertNonProblem("getline2(i)", 8, ICPPTemplateInstance.class);
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// class C {
// friend int f1(int);
// };
// template <typename T> class CT {
// template <typename S> friend int f2(S);
// };
// template <typename T1> class C1 {
// template <typename T2> class C2 {
// template<typename T3> class C3 {
// };
// };
// };
public void testOwnerOfFriendTemplate_265671() throws Exception {
final String code = getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IFunction f= bh.assertNonProblem("f1(", 2, IFunction.class);
IBinding owner= f.getOwner();
assertNull(owner);
ICPPFunctionTemplate ft= bh.assertNonProblem("f2(", 2, ICPPFunctionTemplate.class);
owner= f.getOwner();
assertNull(owner);
ICPPTemplateParameter tpar= ft.getTemplateParameters()[0];
assertEquals(0, tpar.getTemplateNestingLevel());
tpar= bh.assertNonProblem("T1", 2, ICPPTemplateParameter.class);
assertEquals(0, tpar.getTemplateNestingLevel());
tpar= bh.assertNonProblem("T2", 2, ICPPTemplateParameter.class);
assertEquals(1, tpar.getTemplateNestingLevel());
tpar= bh.assertNonProblem("T3", 2, ICPPTemplateParameter.class);
assertEquals(2, tpar.getTemplateNestingLevel());
parseAndCheckBindings(code, ParserLanguage.CPP);
}
}

View file

@ -57,6 +57,7 @@ public abstract class CPPTemplateParameter extends PlatformObject
if (tps == null) {
tps= tdecl.getTemplateParameters();
}
break;
} else if (node instanceof ICPPASTTemplatedTypeTemplateParameter) {
nesting++;
if (tps == null) {

View file

@ -1068,18 +1068,18 @@ public class CPPTemplates {
}
// determine nesting level of parent
int level= 0;
node= outerMostTDecl.getParent();
while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) {
level= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break;
int level= additionalLevels;
if (!CPPVisitor.isFriendFunctionDeclaration(innerMostTDecl.getDeclaration())) {
node= outerMostTDecl.getParent();
while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) {
level+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break;
}
node= node.getParent();
}
node= node.getParent();
}
level += additionalLevels;
tdecl= outerMostTDecl;
while(true) {
tdecl.setNestingLevel((short) level++);

View file

@ -2010,6 +2010,14 @@ public class CPPVisitor extends ASTQueries {
node= node.getParent();
}
boolean isFriend= false;
if (node instanceof IASTSimpleDeclaration) {
ICPPASTDeclSpecifier declSpec= (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration) node).getDeclSpecifier();
if (declSpec.isFriend()) {
isFriend= true;
}
}
// Search for enclosing binding
IASTName name= null;
node= node.getParent();
@ -2025,6 +2033,8 @@ public class CPPVisitor extends ASTQueries {
break;
}
if (node instanceof IASTCompositeTypeSpecifier) {
if (isFriend)
continue;
name= ((IASTCompositeTypeSpecifier) node).getName();
break;
}
@ -2038,4 +2048,24 @@ public class CPPVisitor extends ASTQueries {
return name.resolveBinding();
}
/**
* Check whether a given declaration is a friend function declaration.
*/
public static boolean isFriendFunctionDeclaration(IASTDeclaration declaration) {
while (declaration instanceof ICPPASTTemplateDeclaration) {
declaration= ((ICPPASTTemplateDeclaration) declaration).getDeclaration();
}
if (declaration instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) declaration;
ICPPASTDeclSpecifier declspec= (ICPPASTDeclSpecifier) sdecl.getDeclSpecifier();
if (declspec.isFriend()) {
IASTDeclarator[] dtors= sdecl.getDeclarators();
if (dtors.length == 1 && findTypeRelevantDeclarator(dtors[0]) instanceof IASTFunctionDeclarator) {
return true;
}
}
}
return false;
}
}