1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 17:26: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.IASTPointerOperator;
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.IASTPreprocessorStatement;
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.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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
*
* Contributors:
* John Camelon (IBM Rational Software) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.parser;
@ -18,16 +19,21 @@ public class EndOfFileException extends Exception {
private static final long serialVersionUID= 1607883323361197919L;
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) {
fEndsInactiveCode= true;
public EndOfFileException(int offset, boolean endsInactiveCode) {
fOffset= offset;
fEndsInactiveCode= endsInactiveCode;
}
/**
@ -36,4 +42,12 @@ public class EndOfFileException extends Exception {
public boolean endsInactiveCode() {
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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -41,6 +41,7 @@ public class OffsetLimitReachedException extends EndOfFileException {
private final int fOrigin;
public OffsetLimitReachedException(int origin, IToken lastToken) {
super(lastToken != null ? lastToken.getEndOffset() : -1);
fOrigin= origin;
finalToken= lastToken;
}

View file

@ -194,6 +194,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
private final INodeFactory nodeFactory;
private boolean fActiveCode= true;
private int fEndOffset= -1;
protected AbstractGNUSourceCodeParser(IScanner scanner,
IParserLogService logService, ParserMode parserMode,
@ -268,7 +269,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return t;
} catch (OffsetLimitReachedException olre) {
if (mode != ParserMode.COMPLETION_PARSE)
throw new EndOfFileException();
throw new EndOfFileException(olre.getEndOffset());
createCompletionNode(olre.getFinalToken());
throw olre;
}
@ -418,7 +419,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
private final void checkForEOI(IToken t) throws EndOfFileException {
final int lt= t.getType();
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 {
return LA(i);
} catch (EndOfFileException e) {
fEndOffset= e.getEndOffset();
return null;
}
}
@ -448,6 +450,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
try {
return LT(i);
} catch (EndOfFileException e) {
fEndOffset= e.getEndOffset();
return 0;
}
}
@ -679,7 +682,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
final int lt= t.getType();
if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END || lt == IToken.tINACTIVE_CODE_START) {
if (!acceptInactiveCodeBoundary(codeBranchNesting))
throw new EndOfFileException(true);
throw new EndOfFileException(t.getOffset(), true);
}
}
result = consume();
@ -691,7 +694,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
++depth;
break;
case IToken.tEOC:
throw new EndOfFileException();
throw new EndOfFileException(result.getOffset());
}
}
return result;
@ -1239,7 +1242,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected void parseTranslationUnit() {
final IASTTranslationUnit tu= getTranslationUnit();
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 {
@ -1312,6 +1317,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
IASTDeclaration declaration= skipProblemDeclaration(offset);
addDeclaration(tu, declaration, active);
if (!e.endsInactiveCode()) {
fEndOffset= e.getEndOffset();
break;
}
} finally {
@ -1743,7 +1749,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
open--;
break;
case IToken.tEOC:
throw new EndOfFileException();
throw new EndOfFileException(t.getOffset());
default:
if (content != null) {

View file

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