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:
parent
d3f9d03f77
commit
eb5858ca7a
5 changed files with 78 additions and 10 deletions
|
@ -48,7 +48,9 @@ public class ASTComparer extends Assert {
|
|||
// avoid name resolution
|
||||
"isDeclaration",
|
||||
"isDefinition",
|
||||
"isReference"
|
||||
"isReference",
|
||||
"isAssociatedWithLastName",
|
||||
"getNestingLevel"
|
||||
));
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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++);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue