mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 09:46:02 +02:00
Bug 303152: trailing empty macro expansions in IASTTranslationUnit.
This commit is contained in:
parent
290eeeff55
commit
35de77c32b
5 changed files with 53 additions and 14 deletions
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue