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

Bug 303152: trailing empty macro expansions in IASTTranslationUnit.

This commit is contained in:
Markus Schorn 2010-02-23 17:40:13 +00:00
parent 290eeeff55
commit 35de77c32b
5 changed files with 53 additions and 14 deletions

View file

@ -58,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
@ -7324,4 +7325,21 @@ public class AST2Tests extends AST2BaseTest {
parseAndCheckBindings(code, ParserLanguage.C, true); parseAndCheckBindings(code, ParserLanguage.C, true);
parseAndCheckBindings(code, ParserLanguage.CPP, true); parseAndCheckBindings(code, ParserLanguage.CPP, true);
} }
// #define MACRO
// void funca(){
// }
// MACRO
public void testEmptyTrailingMacro_303152() throws Exception {
final String code = getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
IASTTranslationUnit tu= parseAndCheckBindings(code, lang);
IASTPreprocessorMacroExpansion[] expansions = tu.getMacroExpansions();
assertEquals(1, expansions.length);
IToken t= tu.getSyntax();
while (t.getNext() != null)
t= t.getNext();
assertEquals("MACRO", t.getImage());
}
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation and others. * Copyright (c) 2002, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* John Camelon (IBM Rational Software) - Initial API and implementation * John Camelon (IBM Rational Software) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser; package org.eclipse.cdt.core.parser;
@ -18,16 +19,21 @@ public class EndOfFileException extends Exception {
private static final long serialVersionUID= 1607883323361197919L; private static final long serialVersionUID= 1607883323361197919L;
private final boolean fEndsInactiveCode; private final boolean fEndsInactiveCode;
private final int fOffset;
public EndOfFileException() { /**
fEndsInactiveCode= false; * @since 5.2
*/
public EndOfFileException(int offset) {
this(offset, false);
} }
/** /**
* @since 5.1 * @since 5.2
*/ */
public EndOfFileException(boolean endsInactiveCode) { public EndOfFileException(int offset, boolean endsInactiveCode) {
fEndsInactiveCode= true; fOffset= offset;
fEndsInactiveCode= endsInactiveCode;
} }
/** /**
@ -36,4 +42,12 @@ public class EndOfFileException extends Exception {
public boolean endsInactiveCode() { public boolean endsInactiveCode() {
return fEndsInactiveCode; return fEndsInactiveCode;
} }
/**
* Returns the offset at which the translation unit ends, or -1 if not known.
* @since 5.2
*/
public int getEndOffset() {
return fOffset;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation and others. * Copyright (c) 2002, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -41,6 +41,7 @@ public class OffsetLimitReachedException extends EndOfFileException {
private final int fOrigin; private final int fOrigin;
public OffsetLimitReachedException(int origin, IToken lastToken) { public OffsetLimitReachedException(int origin, IToken lastToken) {
super(lastToken != null ? lastToken.getEndOffset() : -1);
fOrigin= origin; fOrigin= origin;
finalToken= lastToken; finalToken= lastToken;
} }

View file

@ -194,6 +194,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
private final INodeFactory nodeFactory; private final INodeFactory nodeFactory;
private boolean fActiveCode= true; private boolean fActiveCode= true;
private int fEndOffset= -1;
protected AbstractGNUSourceCodeParser(IScanner scanner, protected AbstractGNUSourceCodeParser(IScanner scanner,
IParserLogService logService, ParserMode parserMode, IParserLogService logService, ParserMode parserMode,
@ -268,7 +269,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return t; return t;
} catch (OffsetLimitReachedException olre) { } catch (OffsetLimitReachedException olre) {
if (mode != ParserMode.COMPLETION_PARSE) if (mode != ParserMode.COMPLETION_PARSE)
throw new EndOfFileException(); throw new EndOfFileException(olre.getEndOffset());
createCompletionNode(olre.getFinalToken()); createCompletionNode(olre.getFinalToken());
throw olre; throw olre;
} }
@ -418,7 +419,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
private final void checkForEOI(IToken t) throws EndOfFileException { private final void checkForEOI(IToken t) throws EndOfFileException {
final int lt= t.getType(); final int lt= t.getType();
if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END) if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END)
throw new EndOfFileException(true); throw new EndOfFileException(t.getOffset(), true);
} }
/** /**
@ -428,6 +429,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
try { try {
return LA(i); return LA(i);
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
fEndOffset= e.getEndOffset();
return null; return null;
} }
} }
@ -448,6 +450,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
try { try {
return LT(i); return LT(i);
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
fEndOffset= e.getEndOffset();
return 0; return 0;
} }
} }
@ -679,7 +682,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
final int lt= t.getType(); final int lt= t.getType();
if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END || lt == IToken.tINACTIVE_CODE_START) { if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END || lt == IToken.tINACTIVE_CODE_START) {
if (!acceptInactiveCodeBoundary(codeBranchNesting)) if (!acceptInactiveCodeBoundary(codeBranchNesting))
throw new EndOfFileException(true); throw new EndOfFileException(t.getOffset(), true);
} }
} }
result = consume(); result = consume();
@ -691,7 +694,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
++depth; ++depth;
break; break;
case IToken.tEOC: case IToken.tEOC:
throw new EndOfFileException(); throw new EndOfFileException(result.getOffset());
} }
} }
return result; return result;
@ -1239,7 +1242,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected void parseTranslationUnit() { protected void parseTranslationUnit() {
final IASTTranslationUnit tu= getTranslationUnit(); final IASTTranslationUnit tu= getTranslationUnit();
declarationList(tu, DeclarationOptions.GLOBAL, false, 0); declarationList(tu, DeclarationOptions.GLOBAL, false, 0);
((ASTNode) tu).setLength(getEndOffset()); // Bug 3033152: getEndOffset() is computed off the last node and ignores trailing macros.
final int length= Math.max(getEndOffset(), fEndOffset);
((ASTNode) tu).setLength(length);
} }
protected final void declarationListInBraces(final IASTDeclarationListOwner tu, int offset, DeclarationOptions options) throws EndOfFileException, BacktrackException { protected final void declarationListInBraces(final IASTDeclarationListOwner tu, int offset, DeclarationOptions options) throws EndOfFileException, BacktrackException {
@ -1312,6 +1317,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTDeclaration declaration= skipProblemDeclaration(offset); IASTDeclaration declaration= skipProblemDeclaration(offset);
addDeclaration(tu, declaration, active); addDeclaration(tu, declaration, active);
if (!e.endsInactiveCode()) { if (!e.endsInactiveCode()) {
fEndOffset= e.getEndOffset();
break; break;
} }
} finally { } finally {
@ -1743,7 +1749,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
open--; open--;
break; break;
case IToken.tEOC: case IToken.tEOC:
throw new EndOfFileException(); throw new EndOfFileException(t.getOffset());
default: default:
if (content != null) { if (content != null) {

View file

@ -566,7 +566,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
case IToken.tEND_OF_INPUT: case IToken.tEND_OF_INPUT:
if (fContentAssistLimit < 0) { if (fContentAssistLimit < 0) {
throw new EndOfFileException(); throw new EndOfFileException(t1.getOffset());
} }
int useType= fHandledCompletion ? IToken.tEOC : IToken.tCOMPLETION; int useType= fHandledCompletion ? IToken.tEOC : IToken.tCOMPLETION;
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(fContentAssistLimit); int sequenceNumber= fLocationMap.getSequenceNumberForOffset(fContentAssistLimit);