From 78a0afeab0c441825ff1de6595e9b1bcbe169442 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 22 Jan 2009 16:50:58 +0000 Subject: [PATCH] Additional testcase + minor fix for resolution of structs. --- .../core/parser/tests/ast2/AST2BaseTest.java | 13 +++++++-- .../cdt/core/parser/tests/ast2/AST2Tests.java | 20 +++++++++++++- .../parser/cpp/semantics/CPPSemantics.java | 27 ++++++++++++------- .../parser/cpp/semantics/CPPTemplates.java | 20 +++++++------- .../dom/parser/cpp/semantics/CPPVisitor.java | 6 ++--- 5 files changed, 60 insertions(+), 26 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index 8aaf71d01ab..8b7e15bc054 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -89,6 +89,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor; */ public class AST2BaseTest extends BaseTestCase { protected static final IParserLogService NULL_LOG = new NullLogService(); + protected static boolean sValidateCopy; public AST2BaseTest() { super(); @@ -98,7 +99,14 @@ public class AST2BaseTest extends BaseTestCase { super(name); } - protected IASTTranslationUnit parse(String code, ParserLanguage lang) throws ParserException { + + @Override + protected void setUp() throws Exception { + sValidateCopy= true; + super.setUp(); + } + + protected IASTTranslationUnit parse(String code, ParserLanguage lang) throws ParserException { return parse(code, lang, false, true); } @@ -144,7 +152,8 @@ public class AST2BaseTest extends BaseTestCase { IASTTranslationUnit tu = parser.parse(); assertTrue(tu.isFrozen()); - validateCopy(tu); + if (sValidateCopy) + validateCopy(tu); if (parser.encounteredError() && expectNoProblems) throw new ParserException("FAILURE"); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index 94b36cc80a5..aff28501a25 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -5799,6 +5799,7 @@ public class AST2Tests extends AST2BaseTest { // }; public void testScalabilityOfLargeTrivialInitializer_Bug253690() throws Exception { + sValidateCopy= false; final int AMOUNT= 250000; final StringBuffer[] input = getContents(3); StringBuilder buf= new StringBuilder(); @@ -5821,7 +5822,7 @@ public class AST2Tests extends AST2BaseTest { } private long memoryUsed() { - System.gc();System.gc();System.gc(); + System.gc();System.gc();System.gc();System.gc();System.gc(); final Runtime runtime = Runtime.getRuntime(); return runtime.totalMemory()-runtime.freeMemory(); } @@ -5951,4 +5952,21 @@ public class AST2Tests extends AST2BaseTest { IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true); } } + + // typedef struct A A; + // struct A; // struct + // struct A* a; + public void testTypedefWithSameName() throws Exception { + final String code= getAboveComment(); + for (ParserLanguage lang : ParserLanguage.values()) { + IASTTranslationUnit tu= parseAndCheckBindings(code, lang, true); + + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang == ParserLanguage.CPP); + ITypedef t= ba.assertNonProblem("A;", 1); + ICompositeType s1= ba.assertNonProblem("A; // struct", 1); + ICompositeType s2= ba.assertNonProblem("A*", 1); + assertSame(s1, s2); + assertSame(s1, t.getType()); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index c57cfdc8295..7ab40e9c4e2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; @@ -1751,15 +1752,23 @@ public class CPPSemantics { if (type == null) { type = temp; - } else if (type != temp && !((IType)type).isSameType((IType) temp)) { - boolean i1= isFromIndex(type); - boolean i2= isFromIndex(temp); - if (i1 != i2) { - if (i1) - type= temp; - } else { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); - } + } else if (type != temp) { + boolean i1= isFromIndex(type); + boolean i2= isFromIndex(temp); + if (i1 != i2) { + // prefer non-index bindings + if (i1) + type= temp; + } else { + if (((IType)type).isSameType((IType) temp)) { + if (type instanceof ITypedef && !(temp instanceof ITypedef)) { + // prefer non-typedefs + type= temp; + } + } else { + return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); + } + } } } else { if (obj == null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 73ef749308b..cb6474cf090 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -87,6 +87,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; +import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; @@ -220,7 +221,7 @@ public class CPPTemplates { IASTName start= name; ICPPASTFunctionDefinition func= CPPVisitor.findEnclosingFunctionDefinition(name); if (func != null) { - start= CPPVisitor.findInnermostDeclarator(func.getDeclarator()).getName(); + start= ASTQueries.findInnermostDeclarator(func.getDeclarator()).getName(); start= start.getLastName(); } @@ -403,7 +404,7 @@ public class CPPTemplates { else if (param instanceof ICPPASTTemplatedTypeTemplateParameter) return ((ICPPASTTemplatedTypeTemplateParameter) param).getName(); else if (param instanceof ICPPASTParameterDeclaration) - return CPPVisitor.findInnermostDeclarator(((ICPPASTParameterDeclaration) param).getDeclarator()).getName(); + return ASTQueries.findInnermostDeclarator(((ICPPASTParameterDeclaration) param).getDeclarator()).getName(); return null; } @@ -437,12 +438,12 @@ public class CPPTemplates { } } else { IASTDeclarator dtor = dtors[0]; - dtor= CPPVisitor.findInnermostDeclarator(dtor); + dtor= ASTQueries.findInnermostDeclarator(dtor); name = dtor.getName(); } } else if (decl instanceof IASTFunctionDefinition) { IASTDeclarator dtor = ((IASTFunctionDefinition) decl).getDeclarator(); - dtor= CPPVisitor.findInnermostDeclarator(dtor); + dtor= ASTQueries.findInnermostDeclarator(dtor); name = dtor.getName(); } if (name == null) @@ -482,7 +483,7 @@ public class CPPTemplates { } assert templateParameter instanceof ICPPASTParameterDeclaration; final IASTDeclarator dtor = ((ICPPASTParameterDeclaration) templateParameter).getDeclarator(); - return new CPPTemplateNonTypeParameter(CPPVisitor.findInnermostDeclarator(dtor).getName()); + return new CPPTemplateNonTypeParameter(ASTQueries.findInnermostDeclarator(dtor).getName()); } static public ICPPScope getContainingScope(IASTNode node) { @@ -570,7 +571,6 @@ public class CPPTemplates { if (isDecl || isDef) { if (partialSpec == null) { partialSpec = new CPPClassTemplatePartialSpecialization(id); - // mstodo how to add partial specialization to class template from index? if (template instanceof ICPPInternalClassTemplate) ((ICPPInternalClassTemplate) template).addPartialSpecialization(partialSpec); return partialSpec; @@ -686,7 +686,7 @@ public class CPPTemplates { public static ICPPSpecialization createSpecialization(ICPPClassSpecialization owner, IBinding decl, ICPPTemplateParameterMap tpMap) { - // mstodo- specializations of partial specializations + // mstodo specializations of partial specializations if (decl instanceof ICPPClassTemplatePartialSpecialization) return null; @@ -1161,7 +1161,7 @@ public class CPPTemplates { IASTSimpleDeclaration sdecl= (IASTSimpleDeclaration) decl; IASTDeclarator[] dtors = sdecl.getDeclarators(); if (dtors != null && dtors.length > 0) { - name= CPPVisitor.findInnermostDeclarator(dtors[0]).getName(); + name= ASTQueries.findInnermostDeclarator(dtors[0]).getName(); } else { IASTDeclSpecifier declspec = sdecl.getDeclSpecifier(); if (declspec instanceof IASTCompositeTypeSpecifier) { @@ -1172,7 +1172,7 @@ public class CPPTemplates { } } else if (decl instanceof IASTFunctionDefinition) { IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; - name= CPPVisitor.findInnermostDeclarator(fdef.getDeclarator()).getName(); + name= ASTQueries.findInnermostDeclarator(fdef.getDeclarator()).getName(); } return name; } @@ -1242,7 +1242,7 @@ public class CPPTemplates { } } else if (nestedDecl instanceof IASTFunctionDefinition) { IASTDeclarator declarator = ((IASTFunctionDefinition) nestedDecl).getDeclarator(); - declarator= CPPVisitor.findInnermostDeclarator(declarator); + declarator= ASTQueries.findInnermostDeclarator(declarator); name = declarator.getName(); } if (name != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index ec5873df7d5..891d3311728 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -624,13 +624,11 @@ public class CPPVisitor extends ASTQueries { return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION); } // if we don't resolve the target type first, we get a problem binding in case the typedef - // redeclares the target type: - // typedef struct S S; - // mstodo this is a hack, remove it! + // redeclares the target type, otherwise it is safer to defer the resolution of the target type. IType targetType= createType(declarator); CPPTypedef td= new CPPTypedef(name); td.setType(targetType); - binding = td; + binding = td; } else if (funcDeclarator != null) { if (binding instanceof ICPPInternalBinding && binding instanceof IFunction) { IFunction function = (IFunction) binding;