1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 08:55:25 +02:00

Fix for Bug 120607 - C/C++ Indexer rejects valid pre-processor directive

This commit is contained in:
Anton Leherbauer 2007-02-28 15:53:12 +00:00
parent 2786bd52fb
commit 3f7444610f
21 changed files with 397 additions and 106 deletions

View file

@ -61,6 +61,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
@ -195,6 +196,7 @@ public class DOMLocationTests extends AST2BaseTest {
* @param length
*/
private void assertSoleLocation(IASTNode n, int offset, int length) {
assertEquals(length, ((ASTNode)n).getLength());
IASTNodeLocation[] locations = n.getNodeLocations();
assertEquals(1, locations.length);
IASTNodeLocation nodeLocation = locations[0];
@ -695,4 +697,29 @@ public class DOMLocationTests extends AST2BaseTest {
assertTrue(expr instanceof IASTTypeIdExpression);
assertSoleLocation(expr, buffer.indexOf("sizeof"), "sizeof(int)".length());
}
public void testBug120607() throws Exception {
// C/C++ Indexer rejects valid pre-processor directive
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=120607
StringBuffer buffer = new StringBuffer();
buffer.append("#import \"include_once.h\"\n");
buffer.append("#warning \"deprecated include\"\n");
buffer.append("#line 5\n");
buffer.append("# 5 \"foo.h\"\n");
buffer.append("#ident \"version 1.0\"\n");
buffer.append("#assert thisIsTrue(value)\n");
buffer.append("#unassert thisIsTrue(value)\n");
buffer.append("#invalid");
String code= buffer.toString();
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP, true, false);
IASTProblem[] problems= tu.getPreprocessorProblems();
assertEquals(3, problems.length);
assertEquals(IASTProblem.PREPROCESSOR_INCLUSION_NOT_FOUND, problems[0].getID());
assertEquals(IASTProblem.PREPROCESSOR_POUND_WARNING, problems[1].getID());
assertEquals(IASTProblem.PREPROCESSOR_INVALID_DIRECTIVE, problems[2].getID());
assertSoleLocation(problems[0], code, "#import \"include_once.h\"");
assertSoleLocation(problems[1], code, "\"deprecated include\"");
assertSoleLocation(problems[2], code, "invalid");
}
}

View file

@ -147,6 +147,12 @@ public interface IASTProblem extends IASTNode {
public final static String A_PREPROC_POUND_ERROR = ParserMessages
.getString("IProblem.preproc.poundError"); //$NON-NLS-1$
/**
* The text that follows a #warning preprocessor directive
*/
public final static String A_PREPROC_POUND_WARNING = ParserMessages
.getString("IProblem.preproc.poundWarning"); //$NON-NLS-1$
/**
* The filename that failed somehow in an preprocessor include directive
*/
@ -400,6 +406,14 @@ public interface IASTProblem extends IASTNode {
*/
public final static int PREPROCESSOR_INVALID_VA_ARGS = PREPROCESSOR_RELATED | 0x00D;
/**
* #warning encountered by Preprocessor. Required attributes:
* A_PREPROC_POUND_WARNING
*
* @see #A_PREPROC_POUND_WARNING
*/
public final static int PREPROCESSOR_POUND_WARNING = PREPROCESSOR_RELATED | 0x00E;
/*
* Parser Syntactic Problems
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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
@ -16,4 +16,5 @@ package org.eclipse.cdt.core.parser;
*/
public class EndOfFileException extends Exception
{
private static final long serialVersionUID= 1607883323361197919L;
}

View file

@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser;
/**
* Constants for supported preprocessor directive types.
*
* @since 4.0
*/
public interface IPreprocessorDirective {
/**
* Special constant indicating to ignore the preprocessor directive.
*/
public static final int ppIgnore= -2;
/**
* Special constant indicating to mark the preprocessor directive as invalid.
*/
public static final int ppInvalid= -1;
/**
* Standard preprocessor directive <code>#if</code>.
*/
public static final int ppIf= 0;
/**
* Standard preprocessor directive <code>#ifdef</code>.
*/
public static final int ppIfdef= 1;
/**
* Standard preprocessor directive <code>#ifndef</code>.
*/
public static final int ppIfndef= 2;
/**
* Standard preprocessor directive <code>#elif</code>.
*/
public static final int ppElif= 3;
/**
* Standard preprocessor directive <code>#else</code>.
*/
public static final int ppElse= 4;
/**
* Standard preprocessor directive <code>#endif</code>.
*/
public static final int ppEndif= 5;
/**
* Standard preprocessor directive <code>#include</code>.
*/
public static final int ppInclude= 6;
/**
* Standard preprocessor directive <code>#define</code>.
*/
public static final int ppDefine= 7;
/**
* Standard preprocessor directive <code>#undef</code>.
*/
public static final int ppUndef= 8;
/**
* Standard preprocessor directive <code>#error</code>.
*/
public static final int ppError= 9;
/**
* Standard preprocessor directive <code>#pragma</code>.
*/
public static final int ppPragma= 10;
/**
* GNU preprocessor extension <code>#include_next</code>.
* Search include file after the directory of the current file.
*/
public static final int ppInclude_next= 11;
/**
* GNU preprocessor extension <code>#import</code>.
* Include only once.
*/
public static final int ppImport= 12;
/**
* GNU preprocessor extension <code>#warning</code>.
* Similar to <code>#error</code>.
*/
public static final int ppWarning= 13;
}

View file

@ -166,6 +166,10 @@ public interface IProblem
* The text that follows a #error preprocessor directive
*/
public final static String A_PREPROC_POUND_ERROR = ParserMessages.getString("IProblem.preproc.poundError"); //$NON-NLS-1$
/**
* The text that follows a #warning preprocessor directive
*/
public final static String A_PREPROC_POUND_WARNING = ParserMessages.getString("IProblem.preproc.poundWarning"); //$NON-NLS-1$
/**
* The filename that failed somehow in an preprocessor include directive
@ -411,6 +415,13 @@ public interface IProblem
*/
public final static int PREPROCESSOR_INVALID_VA_ARGS = PREPROCESSOR_RELATED | 0x00D;
/**
* #warning encountered by Preprocessor.
* Required attributes: A_PREPROC_POUND_WARNING
* @see #A_PREPROC_POUND_WARNING
*/
public final static int PREPROCESSOR_POUND_WARNING = PREPROCESSOR_RELATED | 0x00E;
/*
* Parser Syntactic Problems
*/

View file

@ -20,12 +20,12 @@ import org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver;
* @author jcamelon
*
*/
public interface IScanner {
public interface IScanner {
public static final int tPOUNDPOUND = -6;
public static final int tPOUND = -7;
public void setOffsetBoundary( int offset );
public void setOffsetBoundary( int offset );
public void setContentAssistMode( int offset );
public void setASTFactory( IASTFactory f );

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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:
* IBM Rational Software - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.parser;
@ -242,6 +243,15 @@ public class Keywords {
public static final char[] cDEFINE = "define".toCharArray(); //$NON-NLS-1$
public static final char[] cUNDEF = "undef".toCharArray(); //$NON-NLS-1$
public static final char[] cERROR = "error".toCharArray(); //$NON-NLS-1$
public static final char[] cINCLUDE_NEXT = "include_next".toCharArray(); //$NON-NLS-1$
public static final char[] cPRAGMA = "pragma".toCharArray(); //$NON-NLS-1$
public static final char[] cLINE = "line".toCharArray(); //$NON-NLS-1$
// preprocessor extensions (supported by GCC)
public static final char[] cINCLUDE_NEXT = "include_next".toCharArray(); //$NON-NLS-1$
public static final char[] cIMPORT = "import".toCharArray(); //$NON-NLS-1$
public static final char[] cIDENT = "ident".toCharArray(); //$NON-NLS-1$
public static final char[] cSCCS = "sccs".toCharArray(); //$NON-NLS-1$
public static final char[] cWARNING = "warning".toCharArray(); //$NON-NLS-1$
public static final char[] cASSERT = "assert".toCharArray(); //$NON-NLS-1$
public static final char[] cUNASSERT = "unassert".toCharArray(); //$NON-NLS-1$
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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
@ -17,6 +17,8 @@ import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
*/
public class OffsetLimitReachedException extends EndOfFileException {
private static final long serialVersionUID= -4315255081891716385L;
private final IASTCompletionNode node;
private final IToken finalToken;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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
@ -15,6 +15,8 @@ package org.eclipse.cdt.core.parser;
*/
public class ParseError extends Error {
private static final long serialVersionUID= -3626877473345356953L;
private final ParseErrorKind errorKind;
public static class ParseErrorKind extends Enum

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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
@ -16,6 +16,8 @@ package org.eclipse.cdt.core.parser;
*/
public class ParserFactoryError extends Error {
private static final long serialVersionUID= -2692315766161768983L;
public static class Kind extends Enum {
public static final Kind NULL_READER = new Kind( 1 );

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* Copyright (c) 2004, 2007 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
@ -8,6 +8,7 @@
* Contributors:
* IBM - Initial API and implementation
* Yuan Zhang / Beth Tibbitts (IBM Research)
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@ -120,6 +121,8 @@ public class CASTProblem extends CASTNode implements IASTProblem {
new Integer(IASTProblem.PREPROCESSOR_POUND_ERROR),
ParserMessages
.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
errorMessages.put(new Integer(IASTProblem.PREPROCESSOR_POUND_WARNING), ParserMessages
.getString("ScannerProblemFactory.error.preproc.warning")); //$NON-NLS-1$
errorMessages
.put(
new Integer(IASTProblem.PREPROCESSOR_INCLUSION_NOT_FOUND),

View file

@ -7,6 +7,7 @@
*
* Contributors:
* IBM - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -118,6 +119,8 @@ public class CPPASTProblem extends CPPASTNode implements IASTProblem {
new Integer(IASTProblem.PREPROCESSOR_POUND_ERROR),
ParserMessages
.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
errorMessages.put(new Integer(IASTProblem.PREPROCESSOR_POUND_WARNING), ParserMessages
.getString("ScannerProblemFactory.error.preproc.warning")); //$NON-NLS-1$
errorMessages
.put(
new Integer(IASTProblem.PREPROCESSOR_INCLUSION_NOT_FOUND),

View file

@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2005, 2006 IBM Corporation and others.
# Copyright (c) 2005, 2007 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,10 +7,12 @@
#
# Contributors:
# IBM Rational Software - Initial API and implementation
# Anton Leherbauer (Wind River Systems)
###############################################################################
IProblem.unknownFileName=<unknown>
IProblem.preproc.poundError=#error text
IProblem.preproc.poundWarning=#warning text
IProblem.preproc.include=include file
IProblem.preproc.macro=macro name
IProblem.preproc.condition=preprocessor condition
@ -23,6 +25,7 @@ IProblem.typeName=type name
QuickParseCallback.exception.constIterator=OffsetableIterator is a const iterator
ScannerProblemFactory.error.preproc.error=#error encountered with text: {0}
ScannerProblemFactory.error.preproc.warning=#warning encountered with text: {0}
ScannerProblemFactory.error.preproc.inclusionNotFound=Preprocessor Inclusion not found: {0}
ScannerProblemFactory.error.preproc.definitionNotFound=Macro definition not found: {0}
ScannerProblemFactory.error.preproc.invalidMacroDefn=Macro definition malformed for macro: {0}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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:
* IBM Rational Software - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.problem;
@ -154,6 +155,8 @@ public class Problem implements IProblem {
errorMessages.put(
new Integer(IProblem.PREPROCESSOR_POUND_ERROR),
ParserMessages.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
errorMessages.put(new Integer(IProblem.PREPROCESSOR_POUND_WARNING), ParserMessages
.getString("ScannerProblemFactory.error.preproc.warning")); //$NON-NLS-1$
errorMessages.put(
new Integer(IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND),
ParserMessages.getString("ScannerProblemFactory.error.preproc.inclusionNotFound")); //$NON-NLS-1$

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IGCCToken;
import org.eclipse.cdt.core.parser.IMacro;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IPreprocessorDirective;
import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.IScannerInfo;
@ -41,6 +42,7 @@ import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.CharTable;
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
@ -70,16 +72,18 @@ abstract class BaseScanner implements IScanner {
protected static class InclusionData {
public final Object inclusion;
public final CodeReader reader;
public final boolean includeOnce;
/**
/**
* @param reader
* @param inclusion
* @param includeOnce
*/
public InclusionData(CodeReader reader, Object inclusion) {
public InclusionData(CodeReader reader, Object inclusion, boolean includeOnce) {
this.reader = reader;
this.inclusion = inclusion;
this.includeOnce= includeOnce;
}
public String toString() {
@ -120,6 +124,9 @@ abstract class BaseScanner implements IScanner {
protected String[] stdIncludePaths;
protected String[] locIncludePaths = null;
/** Set of already included files */
protected CharArraySet includedFiles= new CharArraySet(32);
int count;
protected ExpressionEvaluator expressionEvaluator;
@ -177,6 +184,8 @@ abstract class BaseScanner implements IScanner {
protected final CharArrayIntMap additionalKeywords;
protected final CharArrayIntMap additionalPPKeywords;
protected static class ExpressionEvaluator {
private static char[] emptyCharArray = new char[0];
@ -1257,6 +1266,16 @@ abstract class BaseScanner implements IScanner {
keywords = cppkeywords;
additionalKeywords = configuration.getAdditionalKeywords();
// additionalPPKeywords= configuration.getAdditionalPreprocessorKeywords();
// add default GNU extensions (will be paramameterized)
additionalPPKeywords= new CharArrayIntMap(8, IPreprocessorDirective.ppInvalid);
additionalPPKeywords.put(Keywords.cINCLUDE_NEXT, IPreprocessorDirective.ppInclude_next);
additionalPPKeywords.put(Keywords.cIMPORT, IPreprocessorDirective.ppImport);
additionalPPKeywords.put(Keywords.cWARNING, IPreprocessorDirective.ppWarning);
additionalPPKeywords.put(Keywords.cIDENT, IPreprocessorDirective.ppIgnore);
additionalPPKeywords.put(Keywords.cSCCS, IPreprocessorDirective.ppIgnore);
additionalPPKeywords.put(Keywords.cASSERT, IPreprocessorDirective.ppIgnore);
additionalPPKeywords.put(Keywords.cUNASSERT, IPreprocessorDirective.ppIgnore);
setupBuiltInMacros(configuration);
@ -1379,8 +1398,12 @@ abstract class BaseScanner implements IScanner {
protected void pushContext(char[] buffer, Object data) {
if (data instanceof InclusionData) {
if (isCircularInclusion( (InclusionData)data ))
InclusionData inclusionData= (InclusionData)data;
if (isCircularInclusion( inclusionData ))
return;
if (inclusionData.includeOnce && isRepeatedInclusion(inclusionData))
return;
includedFiles.put(inclusionData.reader.filename);
}
pushContext(buffer);
bufferData[bufferStackPos] = data;
@ -1405,6 +1428,17 @@ abstract class BaseScanner implements IScanner {
return false;
}
/**
* Check if the given inclusion was already included before.
*
* @param inclusionData
* @return
*/
private boolean isRepeatedInclusion(InclusionData inclusionData) {
return includedFiles.containsKey(inclusionData.reader.filename);
}
protected Object popContext() {
//NOTE - do not set counters to 0 or -1 or something
//Subclasses may require those values in their popContext()
@ -1434,7 +1468,7 @@ abstract class BaseScanner implements IScanner {
int l = getLineNumber(o);
Object i = createInclusionConstruct(r.filename, r.filename, false, o,
l, o, o, l, o, l, true);
InclusionData d = new InclusionData(r, i);
InclusionData d = new InclusionData(r, i, false);
pushContext(r.buffer, d);
}
@ -2633,27 +2667,33 @@ abstract class BaseScanner implements IScanner {
int end;
int type = ppKeywords.get(buffer, start, len);
if (type != ppKeywords.undefined) {
if (type == ppKeywords.undefined) {
type= additionalPPKeywords.get(buffer, start, len);
}
if (type != IPreprocessorDirective.ppInvalid) {
switch (type) {
case ppInclude:
case IPreprocessorDirective.ppInclude:
handlePPInclude(pos, false, startingLineNumber, true);
return;
case ppInclude_next:
case IPreprocessorDirective.ppInclude_next:
handlePPInclude(pos, true, startingLineNumber, true);
return;
case ppDefine:
case IPreprocessorDirective.ppImport:
handlePPInclude(pos, false, startingLineNumber, true);
return;
case IPreprocessorDirective.ppDefine:
handlePPDefine(pos, startingLineNumber);
return;
case ppUndef:
case IPreprocessorDirective.ppUndef:
handlePPUndef(pos);
return;
case ppIfdef:
case IPreprocessorDirective.ppIfdef:
handlePPIfdef(pos, true);
return;
case ppIfndef:
case IPreprocessorDirective.ppIfndef:
handlePPIfdef(pos, false);
return;
case ppIf:
case IPreprocessorDirective.ppIf:
start = bufferPos[bufferStackPos]+1;
skipToNewLine();
end= bufferPos[bufferStackPos]+1;
@ -2675,13 +2715,13 @@ abstract class BaseScanner implements IScanner {
processIf(pos, end, true);
}
return;
case ppElse:
case ppElif:
case IPreprocessorDirective.ppElse:
case IPreprocessorDirective.ppElif:
// Condition must have been true, skip over the rest
if (branchState(type == ppElse ? BRANCH_ELSE : BRANCH_ELIF)) {
if (branchState(type == IPreprocessorDirective.ppElse ? BRANCH_ELSE : BRANCH_ELIF)) {
skipToNewLine();
if (type == ppElse)
if (type == IPreprocessorDirective.ppElse)
processElse(pos, bufferPos[bufferStackPos] + 1,
false);
else
@ -2697,16 +2737,19 @@ abstract class BaseScanner implements IScanner {
if (isLimitReached())
handleInvalidCompletion();
return;
case ppError:
case IPreprocessorDirective.ppError:
case IPreprocessorDirective.ppWarning:
skipOverWhiteSpace();
start = bufferPos[bufferStackPos] + 1;
skipToNewLine();
end= bufferPos[bufferStackPos] + 1;
handleProblem(IProblem.PREPROCESSOR_POUND_ERROR, start,
boolean isWarning= type == IPreprocessorDirective.ppWarning;
handleProblem(isWarning ? IProblem.PREPROCESSOR_POUND_WARNING : IProblem.PREPROCESSOR_POUND_ERROR, start,
CharArrayUtils.extract(buffer, start, end-start));
processError(pos, end);
processWarning(pos, end);
return;
case ppEndif:
case IPreprocessorDirective.ppEndif:
skipToNewLine();
if (branchState(BRANCH_END)) {
processEndif(pos, bufferPos[bufferStackPos] + 1);
@ -2717,16 +2760,40 @@ abstract class BaseScanner implements IScanner {
start, ppKeywords.findKey(buffer, start, len));
}
return;
case ppPragma:
case IPreprocessorDirective.ppPragma:
skipToNewLine();
processPragma(pos, bufferPos[bufferStackPos]+1);
return;
case IPreprocessorDirective.ppIgnore:
skipToNewLine();
return;
}
}
}
// directive was not handled, create a problem
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, start, null);
} else {
// ignore preprocessor output lines of the form
// # <linenum> "<filename>" flags
if (c >= '0' && c <= '9' && start > pos+1) {
while (++bufferPos[bufferStackPos] < limit) {
c = buffer[bufferPos[bufferStackPos]];
if ((c >= '0' && c <= '9'))
continue;
break;
}
if (bufferPos[bufferStackPos] < limit) {
c = buffer[bufferPos[bufferStackPos]];
if (c == ' ' || c == '\t') {
// now we have # <linenum>
// skip the rest
skipToNewLine();
return;
}
}
--bufferPos[bufferStackPos];
}
}
// directive was not handled, create a problem
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, start,
new String(buffer, start, getCurrentOffset() - start + 1).toCharArray());
skipToNewLine();
}
@ -2748,6 +2815,16 @@ abstract class BaseScanner implements IScanner {
*/
protected abstract void processError(int startPos, int endPos);
/**
* Process #warning directive.
*
* @param startPos
* @param endPos
*/
protected void processWarning(int startPos, int endPos) {
// default: do nothing
}
protected abstract void processElsif(int startPos, int endPos, boolean taken);
protected abstract void processElse(int startPos, int endPos, boolean taken);
@ -2877,7 +2954,7 @@ abstract class BaseScanner implements IScanner {
if (filename == null || filename == EMPTY_STRING) {
if (active) {
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, startOffset,
null);
new String(buffer, startOffset, nameEndOffset - startOffset).toCharArray());
return;
}
filename= new String(buffer, nameOffset, nameEndOffset - nameOffset);
@ -2889,7 +2966,7 @@ abstract class BaseScanner implements IScanner {
skipToNewLine();
if (active) {
findAndPushInclusion(filename, fileNameArray, local, include_next, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
findAndPushInclusion(filename, fileNameArray, local, include_next, false, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
} else {
processInclude(fileNameArray, local, active, startOffset, nameOffset, nameEndOffset, endOffset, startingLineNumber, nameLine, endLine);
}
@ -2916,18 +2993,19 @@ abstract class BaseScanner implements IScanner {
/**
* @param filename
* @param fileNameArray
* @param local
* @param include_next
* @param startOffset
* @param nameOffset
* @param nameEndOffset
* @param endOffset
* @param startingLine
* @param nameLine
* @param endLine
* @param fileNameArray
* @param local
* @param include_next
* @param includeOnce
* @param startOffset
* @param nameOffset
* @param nameEndOffset
* @param endOffset
* @param startingLine
* @param nameLine
* @param endLine
*/
protected void findAndPushInclusion(String filename, char[] fileNameArray, boolean local, boolean include_next, int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLine, int nameLine, int endLine) {
protected void findAndPushInclusion(String filename, char[] fileNameArray, boolean local, boolean include_next, boolean includeOnce, int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLine, int nameLine, int endLine) {
if (parserMode == ParserMode.QUICK_PARSE) {
Object inclusion = createInclusionConstruct(fileNameArray,
EMPTY_CHAR_ARRAY, local, startOffset, startingLine,
@ -2947,7 +3025,7 @@ abstract class BaseScanner implements IScanner {
reader.filename, local, startOffset,
startingLine, nameOffset,
nameEndOffset, nameLine, endOffset,
endLine, false)));
endLine, false), includeOnce));
return;
}
processInclude(fileNameArray, local, true, startOffset, nameOffset, nameEndOffset, endOffset, startingLine, nameLine, endLine);
@ -2975,7 +3053,7 @@ abstract class BaseScanner implements IScanner {
reader.filename, local, startOffset,
startingLine, nameOffset,
nameEndOffset, nameLine, endOffset,
endLine, false)));
endLine, false), includeOnce));
return;
}
}
@ -3005,7 +3083,7 @@ abstract class BaseScanner implements IScanner {
reader.filename, local, startOffset,
startingLine, nameOffset,
nameEndOffset, nameLine, endOffset,
endLine, false)));
endLine, false), includeOnce));
return;
}
}
@ -3015,7 +3093,7 @@ abstract class BaseScanner implements IScanner {
fileNameArray);
}
protected abstract CodeReader createReader(String path, String fileName);
protected abstract CodeReader createReader(String path, String fileName);
private int findIncludePos(String[] paths, File currentDirectory) {
@ -3494,23 +3572,23 @@ abstract class BaseScanner implements IScanner {
int type = ppKeywords.get(buffer, start, len);
if (type != ppKeywords.undefined) {
switch (type) {
case ppIfdef:
case ppIfndef:
case ppIf:
case IPreprocessorDirective.ppIfdef:
case IPreprocessorDirective.ppIfndef:
case IPreprocessorDirective.ppIf:
++nesting;
branchState(BRANCH_IF);
skipToNewLine();
if (type == ppIfdef)
if (type == IPreprocessorDirective.ppIfdef)
processIfdef(startPos,
bufferPos[bufferStackPos]+1, true, false);
else if (type == ppIfndef)
else if (type == IPreprocessorDirective.ppIfndef)
processIfdef(startPos,
bufferPos[bufferStackPos]+1, false, false);
else
processIf(startPos, bufferPos[bufferStackPos]+1,
false);
break;
case ppElse:
case IPreprocessorDirective.ppElse:
if (branchState(BRANCH_ELSE)) {
skipToNewLine();
if (checkelse && nesting == 0) {
@ -3529,7 +3607,7 @@ abstract class BaseScanner implements IScanner {
skipToNewLine();
}
break;
case ppElif:
case IPreprocessorDirective.ppElif:
if (branchState(BRANCH_ELIF)) {
if (checkelse && nesting == 0) {
// check the condition
@ -3563,7 +3641,7 @@ abstract class BaseScanner implements IScanner {
skipToNewLine();
}
break;
case ppEndif:
case IPreprocessorDirective.ppEndif:
if (branchState(BRANCH_END)) {
processEndif(startPos,
bufferPos[bufferStackPos] + 1);
@ -3582,10 +3660,13 @@ abstract class BaseScanner implements IScanner {
skipToNewLine();
}
break;
case ppInclude:
case IPreprocessorDirective.ppInclude:
handlePPInclude(startPos, false, getLineNumber(startPos), false);
break;
case ppInclude_next:
case IPreprocessorDirective.ppInclude_next:
handlePPInclude(startPos, true, getLineNumber(startPos), false);
break;
case IPreprocessorDirective.ppImport:
handlePPInclude(startPos, true, getLineNumber(startPos), false);
break;
}
@ -4818,30 +4899,6 @@ abstract class BaseScanner implements IScanner {
protected static CharArrayIntMap ppKeywords;
protected static final int ppIf = 0;
protected static final int ppIfdef = 1;
protected static final int ppIfndef = 2;
protected static final int ppElif = 3;
protected static final int ppElse = 4;
protected static final int ppEndif = 5;
protected static final int ppInclude = 6;
protected static final int ppDefine = 7;
protected static final int ppUndef = 8;
protected static final int ppError = 9;
protected static final int ppInclude_next = 10;
protected static final int ppPragma = 11;
protected static final char[] TAB = { '\t' };
protected static final char[] SPACE = { ' ' };
@ -4940,19 +4997,19 @@ abstract class BaseScanner implements IScanner {
cppkeywords.put(Keywords.cXOR_EQ, IToken.t_xor_eq);
// Preprocessor keywords
ppKeywords = new CharArrayIntMap(16, -1);
ppKeywords.put(Keywords.cIF, ppIf);
ppKeywords.put(Keywords.cIFDEF, ppIfdef);
ppKeywords.put(Keywords.cIFNDEF, ppIfndef);
ppKeywords.put(Keywords.cELIF, ppElif);
ppKeywords.put(Keywords.cELSE, ppElse);
ppKeywords.put(Keywords.cENDIF, ppEndif);
ppKeywords.put(Keywords.cINCLUDE, ppInclude);
ppKeywords.put(Keywords.cDEFINE, ppDefine);
ppKeywords.put(Keywords.cUNDEF, ppUndef);
ppKeywords.put(Keywords.cERROR, ppError);
ppKeywords.put(Keywords.cINCLUDE_NEXT, ppInclude_next);
ppKeywords.put(Keywords.cPRAGMA, ppPragma);
ppKeywords = new CharArrayIntMap(16, IPreprocessorDirective.ppInvalid);
ppKeywords.put(Keywords.cIF, IPreprocessorDirective.ppIf);
ppKeywords.put(Keywords.cIFDEF, IPreprocessorDirective.ppIfdef);
ppKeywords.put(Keywords.cIFNDEF, IPreprocessorDirective.ppIfndef);
ppKeywords.put(Keywords.cELIF, IPreprocessorDirective.ppElif);
ppKeywords.put(Keywords.cELSE, IPreprocessorDirective.ppElse);
ppKeywords.put(Keywords.cENDIF, IPreprocessorDirective.ppEndif);
ppKeywords.put(Keywords.cINCLUDE, IPreprocessorDirective.ppInclude);
ppKeywords.put(Keywords.cDEFINE, IPreprocessorDirective.ppDefine);
ppKeywords.put(Keywords.cUNDEF, IPreprocessorDirective.ppUndef);
ppKeywords.put(Keywords.cERROR, IPreprocessorDirective.ppError);
ppKeywords.put(Keywords.cPRAGMA, IPreprocessorDirective.ppPragma);
ppKeywords.put(Keywords.cLINE, IPreprocessorDirective.ppIgnore);
}
/**

View file

@ -461,6 +461,14 @@ public class DOMScanner extends BaseScanner {
getGlobalOffset(endPos));
}
/*
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#processWarning(int, int)
*/
protected void processWarning(int startPos, int endPos) {
locationMap.encounterPoundWarning(getGlobalOffset(startPos),
getGlobalOffset(endPos));
}
/*
* (non-Javadoc)
*

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2006 IBM Corporation and others.
* Copyright (c) 2004, 2007 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
@ -8,6 +8,7 @@
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
@ -71,6 +72,8 @@ public interface IScannerPreprocessorLog {
public void encounterPoundError(int startOffset, int endOffset);
public void encounterPoundWarning(int startOffset, int endOffset);
public void encounterPoundUndef(int startOffset, int endOffset,
char[] symbol, int nameOffset, IMacroDefinition macroDefinition);

View file

@ -256,6 +256,10 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
}
public static class ASTWarning extends ASTNode implements
IASTPreprocessorErrorStatement {
}
/**
* @author jcamelon
*/
@ -384,6 +388,12 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
}
protected static class _Warning extends _Context implements _IPreprocessorDirective {
public _Warning(_CompositeContext parent, int startOffset, int endOffset) {
super(parent, startOffset, endOffset);
}
}
/**
* @author jcamelon
*/
@ -1658,6 +1668,8 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
result = createASTPragma((_Pragma) context);
else if (context instanceof _Error)
result = createASTError((_Error) context);
else if (context instanceof _Warning)
result = createASTWarning((_Warning) context);
else if (context instanceof _If)
result = createASTIf((_If) context);
else if (context instanceof _Ifdef)
@ -1758,6 +1770,18 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
return result;
}
/**
* @param warning
* @return
*/
private IASTPreprocessorStatement createASTWarning(_Warning warning) {
IASTPreprocessorErrorStatement result = new ASTWarning();
((ASTNode) result).setOffsetAndLength(warning.context_directive_start, warning.getDirectiveLength());
result.setParent(rootNode);
result.setPropertyInParent(IASTTranslationUnit.PREPROCESSOR_STATEMENT);
return result;
}
/**
* @param pragma
* @return
@ -2177,6 +2201,14 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
endOffset));
}
/*
* @see org.eclipse.cdt.internal.core.parser.scanner2.IScannerPreprocessorLog#encounterPoundWarning(int, int)
*/
public void encounterPoundWarning(int startOffset, int endOffset) {
currentContext.addSubContext(new _Warning(currentContext, startOffset,
endOffset));
}
/*
* (non-Javadoc)
*

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* Copyright (c) 2004, 2007 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:
* IBM - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
@ -148,7 +149,7 @@ public class Scanner2 extends BaseScanner {
* @see org.eclipse.cdt.internal.core.parser.scanner2.BaseScanner#quickParsePushPopInclusion(java.lang.Object)
*/
protected void quickParsePushPopInclusion(Object inclusion) {
callbackManager.pushCallback(new InclusionData(null, inclusion));
callbackManager.pushCallback(new InclusionData(null, inclusion, false));
callbackManager.pushCallback(inclusion);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* Copyright (c) 2004, 2007 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:
* IBM - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
@ -61,6 +62,8 @@ public class ScannerASTProblem extends ASTNode implements IASTProblem {
new Integer(IASTProblem.PREPROCESSOR_POUND_ERROR),
ParserMessages
.getString("ScannerProblemFactory.error.preproc.error")); //$NON-NLS-1$
errorMessages.put(new Integer(IASTProblem.PREPROCESSOR_POUND_WARNING), ParserMessages
.getString("ScannerProblemFactory.error.preproc.warning")); //$NON-NLS-1$
errorMessages
.put(
new Integer(IASTProblem.PREPROCESSOR_INCLUSION_NOT_FOUND),

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation and others.
* Copyright (c) 2002, 2007 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:
* IBM Rational Software - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2;
@ -60,6 +61,8 @@ public class ScannerProblemFactory extends BaseProblemFactory implements IProble
{
case IProblem.PREPROCESSOR_POUND_ERROR :
return IProblem.A_PREPROC_POUND_ERROR;
case IProblem.PREPROCESSOR_POUND_WARNING :
return IProblem.A_PREPROC_POUND_WARNING;
case IProblem.PREPROCESSOR_INCLUSION_NOT_FOUND :
return IProblem.A_PREPROC_INCLUDE_FILENAME;
case IProblem.PREPROCESSOR_DEFINITION_NOT_FOUND :