From 30a1ab0388becd4a162bbb4130969ec3d48322ff Mon Sep 17 00:00:00 2001 From: Mike Kucera Date: Tue, 1 Apr 2008 16:58:22 +0000 Subject: fixed problem with friend classes not resolving, fixed offset calculations for qualified name nodes --- .../cdt/core/lrparser/tests/cpp/ISOCPPTests.java | 53 ++++++++ .../grammar/cpp/CPPGrammar.g | 2 +- .../dom/lrparser/action/BuildASTParserAction.java | 13 +- .../action/cpp/CPPBuildASTParserAction.java | 134 ++++++++++++--------- .../lrparser/cpp/CPPExpressionStatementParser.java | 2 +- .../lrparser/cpp/CPPNoCastExpressionParser.java | 2 +- .../cpp/CPPNoFunctionDeclaratorParser.java | 2 +- .../internal/core/dom/lrparser/cpp/CPPParser.java | 2 +- .../lrparser/cpp/CPPSizeofExpressionParser.java | 2 +- 9 files changed, 151 insertions(+), 61 deletions(-) create mode 100644 lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/cpp/ISOCPPTests.java (limited to 'lrparser') diff --git a/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/cpp/ISOCPPTests.java b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/cpp/ISOCPPTests.java new file mode 100644 index 00000000000..4307ebdd683 --- /dev/null +++ b/lrparser/org.eclipse.cdt.core.lrparser.tests/src/org/eclipse/cdt/core/lrparser/tests/cpp/ISOCPPTests.java @@ -0,0 +1,53 @@ +package org.eclipse.cdt.core.lrparser.tests.cpp; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage; +import org.eclipse.cdt.core.dom.lrparser.c99.C99Language; +import org.eclipse.cdt.core.dom.lrparser.cpp.ISOCPPLanguage; +import org.eclipse.cdt.core.lrparser.tests.c99.C99Tests; +import org.eclipse.cdt.core.lrparser.tests.c99.ParseHelper; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTests; +import org.eclipse.cdt.internal.core.parser.ParserException; + +public class ISOCPPTests extends AST2CPPTests { + + + public static TestSuite suite() { + return suite(ISOCPPTests.class); + } + + public ISOCPPTests() { + + } + + public ISOCPPTests(String name) { + super(name); + } + + + @SuppressWarnings("restriction") + @Override + protected IASTTranslationUnit parse( String code, ParserLanguage lang, @SuppressWarnings("unused") boolean useGNUExtensions, boolean expectNoProblems, @SuppressWarnings("unused") boolean parseComments) throws ParserException { + ILanguage language = lang.isCPP() ? getCPPLanguage() : getC99Language(); + return ParseHelper.parse(code, language, expectNoProblems); + } + + + protected ILanguage getC99Language() { + return C99Language.getDefault(); + } + + protected ILanguage getCPPLanguage() { + return ISOCPPLanguage.getDefault(); + } + + public void testBug98704() throws Exception { + // this one gets stuck in infinite loop + + } + +} diff --git a/lrparser/org.eclipse.cdt.core.lrparser/grammar/cpp/CPPGrammar.g b/lrparser/org.eclipse.cdt.core.lrparser/grammar/cpp/CPPGrammar.g index 14283f0bb11..516d2a134d7 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/grammar/cpp/CPPGrammar.g +++ b/lrparser/org.eclipse.cdt.core.lrparser/grammar/cpp/CPPGrammar.g @@ -442,7 +442,7 @@ template_opt -- the ::=? is necessary for example 8.2.1 in the C++ spec to parse correctly dcolon_opt ::=? '::' - /. $Build consumePlaceHolder(); $EndBuild ./ + /. $Build consumeToken(); $EndBuild ./ -- need the actual token to compute offsets | $empty /. $Build consumeEmpty(); $EndBuild ./ diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java index 8bcb5050c1e..36621d5a1fa 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java @@ -350,7 +350,7 @@ public abstract class BuildASTParserAction { } i++; } - return tokens.subList(first, last+1); + return tokens.subList(first, last + 1); } @@ -407,6 +407,17 @@ public abstract class BuildASTParserAction { } + /** + * Gets the current token and places it on the stack for later consumption. + */ + public void consumeToken() { + if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); + + astStack.push(parser.getRightIToken()); + + if(TRACE_AST_STACK) System.out.println(astStack); + } + public void consumeTranslationUnit() { diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java index 5121fac7ec2..15c81cc6695 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/cpp/CPPBuildASTParserAction.java @@ -157,7 +157,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { List arrayExpressions = astStack.closeScope(); IASTTypeId typeId = (IASTTypeId) astStack.pop(); IASTExpression placement = (IASTExpression) astStack.pop(); // may be null - boolean hasDoubleColon = astStack.pop() == PLACE_HOLDER; + boolean hasDoubleColon = astStack.pop() != null; ICPPASTNewExpression newExpression = nodeFactory.newCPPNewExpression(placement, initializer, typeId); newExpression.setIsGlobal(hasDoubleColon); @@ -220,7 +220,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); IASTExpression operand = (IASTExpression) astStack.pop(); - boolean hasDoubleColon = astStack.pop() == PLACE_HOLDER; + boolean hasDoubleColon = astStack.pop() != null; ICPPASTDeleteExpression deleteExpr = nodeFactory.newDeleteExpression(operand); deleteExpr.setIsGlobal(hasDoubleColon); @@ -305,10 +305,13 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { IASTName name = (IASTName) astStack.pop(); boolean isTemplate = astStack.pop() == PLACE_HOLDER; LinkedList nestedNames = (LinkedList) astStack.pop(); - boolean hasDColon = astStack.pop() == PLACE_HOLDER; - + IToken dColon = (IToken) astStack.pop(); + nestedNames.addFirst(name); - IASTName qualifiedName = createQualifiedName(nestedNames, hasDColon); + + int startOffset = dColon == null ? offset(nestedNames.getLast()) : offset(dColon); + int endOffset = endOffset(name); + IASTName qualifiedName = createQualifiedName(nestedNames, startOffset, endOffset, dColon != null); ICPPASTTypenameExpression typenameExpr = nodeFactory.newCPPTypenameExpression(qualifiedName, expr, isTemplate); @@ -698,41 +701,46 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { } - + private IASTName createQualifiedName(LinkedList nestedNames, int startOffset, int endOffset, boolean startsWithColonColon) { + return createQualifiedName(nestedNames, startOffset, endOffset, startsWithColonColon, false); + } /** * Creates a qualified name from a list of names (that must be in reverse order). + * + * @param names List of name nodes in reverse order */ @SuppressWarnings("restriction") - private IASTName createQualifiedName(LinkedList nestedNames, boolean startsWithColonColon) { - if(!startsWithColonColon && nestedNames.size() == 1) // its actually an unqualified name - return nestedNames.get(0); - - int startOffset = offset(nestedNames.getLast()); - int endOffset = endOffset(nestedNames.getFirst()); - int length = endOffset - startOffset; + private IASTName createQualifiedName(LinkedList names, int startOffset, int endOffset, boolean startsWithColonColon, boolean endsWithColonColon) { + if(!endsWithColonColon && !startsWithColonColon && names.size() == 1) + return names.getFirst(); // its actually an unqualified name - // find the tokens that make up the name - List nameTokens = tokenOffsetSubList(parser.getRuleTokens(), startOffset, endOffset); + ICPPASTQualifiedName qualifiedName = nodeFactory.newCPPQualifiedName(); + qualifiedName.setFullyQualified(startsWithColonColon); + setOffsetAndLength(qualifiedName, startOffset, endOffset - startOffset); + for(IASTName name : reverseIterable(names)) + qualifiedName.addName(name); - StringBuilder signature = new StringBuilder(startsWithColonColon ? "::" : ""); //$NON-NLS-1$ //$NON-NLS-2$ + // compute the signature, find the tokens that make up the name + List nameTokens = tokenOffsetSubList(parser.getRuleTokens(), startOffset, endOffset); + StringBuilder sb = new StringBuilder(); IToken prev = null; for(IToken t : nameTokens) { if(needSpaceBetween(prev, t)) - signature.append(' '); - signature.append(t.toString()); + sb.append(' '); + sb.append(t.toString()); prev = t; } + ((CPPASTQualifiedName)qualifiedName).setSignature(sb.toString()); + + // there must be a dummy name in the AST after the last double colon, this happens with pointer to member + if(endsWithColonColon) { + IASTName dummyName = nodeFactory.newName(); + setOffsetAndLength(dummyName, endOffset, 0); + qualifiedName.addName(dummyName); + } - ICPPASTQualifiedName qualifiedName = nodeFactory.newCPPQualifiedName(); - qualifiedName.setFullyQualified(startsWithColonColon); - setOffsetAndLength(qualifiedName, startOffset, length); - ((CPPASTQualifiedName)qualifiedName).setSignature(signature.toString()); - - for(IASTName name : reverseIterable(nestedNames)) - qualifiedName.addName(name); - return qualifiedName; } @@ -770,15 +778,18 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { astStack.pop(); LinkedList nestedNames = (LinkedList) astStack.pop(); - boolean startsWithColonColon = astStack.pop() == PLACE_HOLDER; + IToken dColon = (IToken) astStack.pop(); - if(nestedNames.isEmpty() && !startsWithColonColon) { // then its not a qualified name + if(nestedNames.isEmpty() && dColon == null) { // then its not a qualified name return lastName; } nestedNames.addFirst(lastName); // the list of names is in reverse order - return createQualifiedName(nestedNames, startsWithColonColon); + int startOffset = dColon == null ? offset(nestedNames.getLast()) : offset(dColon); + int endOffset = endOffset(lastName); + + return createQualifiedName(nestedNames, startOffset, endOffset, dColon != null); } @@ -796,14 +807,16 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { IASTName destructorTypeName = (IASTName) astStack.pop(); IASTName extraName = hasExtraTypeName ? (IASTName) astStack.pop() : null; LinkedList nestedNames = (LinkedList) astStack.pop(); - boolean hasDColon = astStack.pop() == PLACE_HOLDER; + IToken dColon = (IToken) astStack.pop(); if(hasExtraTypeName) nestedNames.addFirst(extraName); nestedNames.addFirst(destructorTypeName); - IASTName qualifiedName = createQualifiedName(nestedNames, hasDColon); + int startOffset = dColon == null ? offset(nestedNames.getLast()) : offset(dColon); + int endOffset = endOffset(destructorTypeName); + IASTName qualifiedName = createQualifiedName(nestedNames, startOffset, endOffset, dColon != null); setOffsetAndLength(qualifiedName); astStack.push(qualifiedName); @@ -999,7 +1012,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { * @param token Allows subclasses to override this method and use any * object to determine how to set a specifier. */ - protected void setSpecifier(IASTDeclSpecifier node, IToken token) { + protected void setSpecifier(ICPPASTDeclSpecifier node, IToken token) { //TODO int kind = asC99Kind(token) int kind = token.getKind(); switch(kind){ @@ -1012,37 +1025,38 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { case TK_inline: node.setInline(true); return; case TK_const: node.setConst(true); return; + case TK_friend: node.setFriend(true); return; + case TK_virtual: node.setVirtual(true); return; case TK_volatile: node.setVolatile(true); return; + case TK_explicit: node.setExplicit(true); return; } if(node instanceof ICPPASTSimpleDeclSpecifier) { ICPPASTSimpleDeclSpecifier n = (ICPPASTSimpleDeclSpecifier) node; switch(kind) { - case TK_void: n.setType(IASTSimpleDeclSpecifier.t_void); break; - case TK_char: n.setType(IASTSimpleDeclSpecifier.t_char); break; - case TK_int: n.setType(IASTSimpleDeclSpecifier.t_int); break; - case TK_float: n.setType(IASTSimpleDeclSpecifier.t_float); break; - case TK_double: n.setType(IASTSimpleDeclSpecifier.t_double); break; - case TK_bool: n.setType(ICPPASTSimpleDeclSpecifier.t_bool); break; - case TK_wchar_t: n.setType(ICPPASTSimpleDeclSpecifier.t_wchar_t); break; + case TK_void: n.setType(IASTSimpleDeclSpecifier.t_void); return; + case TK_char: n.setType(IASTSimpleDeclSpecifier.t_char); return; + case TK_int: n.setType(IASTSimpleDeclSpecifier.t_int); return; + case TK_float: n.setType(IASTSimpleDeclSpecifier.t_float); return; + case TK_double: n.setType(IASTSimpleDeclSpecifier.t_double); return; + case TK_bool: n.setType(ICPPASTSimpleDeclSpecifier.t_bool); return; + case TK_wchar_t: n.setType(ICPPASTSimpleDeclSpecifier.t_wchar_t); return; - case TK_signed: n.setSigned(true); break; - case TK_unsigned: n.setUnsigned(true); break; - case TK_long: n.setLong(true); break; - case TK_short: n.setShort(true); break; - case TK_friend: n.setFriend(true); break; - case TK_virtual: n.setVirtual(true); break; - case TK_volatile: n.setVolatile(true); break; - case TK_explicit: n.setExplicit(true); break; + case TK_signed: n.setSigned(true); return; + case TK_unsigned: n.setUnsigned(true); return; + case TK_long: n.setLong(true); return; + case TK_short: n.setShort(true); return; } } + + } public void consumeDeclarationSpecifiersSimple() { if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); - IASTSimpleDeclSpecifier declSpec = nodeFactory.newCPPSimpleDeclSpecifier(); + ICPPASTDeclSpecifier declSpec = nodeFactory.newCPPSimpleDeclSpecifier(); for(Object token : astStack.closeScope()) setSpecifier(declSpec, (IToken)token); @@ -1063,7 +1077,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { List topScope = astStack.closeScope(); // There's already a composite or elaborated or enum type specifier somewhere on the stack, find it. - IASTDeclSpecifier declSpec = findFirstAndRemove(topScope, IASTDeclSpecifier.class); + ICPPASTDeclSpecifier declSpec = findFirstAndRemove(topScope, ICPPASTDeclSpecifier.class); // now apply the rest of the specifiers for(Object token : topScope) @@ -1344,14 +1358,15 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { int key = getCompositeTypeSpecifier(parser.getLeftIToken()); List baseSpecifiers = astStack.closeScope(); - // may be null, but if it is then hasNestedNameSpecifier == false IASTName className = (IASTName) astStack.pop(); if(hasNestedNameSpecifier) { LinkedList nestedNames = (LinkedList) astStack.pop(); nestedNames.addFirst(className); - className = createQualifiedName(nestedNames, false); + int startOffset = offset(nestedNames.getLast()); + int endOffset = endOffset(className); + className = createQualifiedName(nestedNames, startOffset, endOffset, false); } if(className == null) @@ -1433,10 +1448,21 @@ public class CPPBuildASTParserAction extends BuildASTParserAction { if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); List qualifiers = astStack.closeScope(); - LinkedList nestedNames = (LinkedList) astStack.pop(); - boolean hasDColon = astStack.pop() == PLACE_HOLDER; - IASTName name = createQualifiedName(nestedNames, hasDColon); + IToken dColon = (IToken) astStack.pop(); + + int startOffset = dColon == null ? offset(nestedNames.getLast()) : offset(dColon); + int endOffset = endOffset(nestedNames.getFirst()); // temporary + + // find the last double colon by searching for it + for(IToken t : reverseIterable(parser.getRuleTokens())) { + if(t.getKind() == TK_ColonColon) { + endOffset = endOffset(t); + break; + } + } + + IASTName name = createQualifiedName(nestedNames, startOffset, endOffset, dColon != null, true); ICPPASTPointerToMember pointer = nodeFactory.newPointerToMember(name); addCVQualifiersToPointer(pointer, qualifiers); diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPExpressionStatementParser.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPExpressionStatementParser.java index 57e3158b710..6898e64f9c7 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPExpressionStatementParser.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPExpressionStatementParser.java @@ -416,7 +416,7 @@ public CPPExpressionStatementParser(String[] mapFrom) { // constructor // Rule 42: dcolon_opt ::= :: // case 42: { action.builder. - consumePlaceHolder(); break; + consumeToken(); break; } // diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoCastExpressionParser.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoCastExpressionParser.java index 5ad315f4388..37c9b995c22 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoCastExpressionParser.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoCastExpressionParser.java @@ -416,7 +416,7 @@ public CPPNoCastExpressionParser(String[] mapFrom) { // constructor // Rule 42: dcolon_opt ::= :: // case 42: { action.builder. - consumePlaceHolder(); break; + consumeToken(); break; } // diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoFunctionDeclaratorParser.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoFunctionDeclaratorParser.java index 1fb40d2b27f..569504758bc 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoFunctionDeclaratorParser.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPNoFunctionDeclaratorParser.java @@ -416,7 +416,7 @@ public CPPNoFunctionDeclaratorParser(String[] mapFrom) { // constructor // Rule 42: dcolon_opt ::= :: // case 42: { action.builder. - consumePlaceHolder(); break; + consumeToken(); break; } // diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPParser.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPParser.java index 25c8535b283..52738c46920 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPParser.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPParser.java @@ -416,7 +416,7 @@ public CPPParser(String[] mapFrom) { // constructor // Rule 42: dcolon_opt ::= :: // case 42: { action.builder. - consumePlaceHolder(); break; + consumeToken(); break; } // diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPSizeofExpressionParser.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPSizeofExpressionParser.java index 04e4e6cfbd1..32dbd64645d 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPSizeofExpressionParser.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/internal/core/dom/lrparser/cpp/CPPSizeofExpressionParser.java @@ -416,7 +416,7 @@ public CPPSizeofExpressionParser(String[] mapFrom) { // constructor // Rule 42: dcolon_opt ::= :: // case 42: { action.builder. - consumePlaceHolder(); break; + consumeToken(); break; } // -- cgit v1.2.3