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

Preprocessor option to create tokens for inactive code branches, macro's from inactive code in outline view, bug 264666.

This commit is contained in:
Markus Schorn 2009-02-17 12:03:09 +00:00
parent 251c37e865
commit 5008c01caf
32 changed files with 1189 additions and 669 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.model.tests;
@ -42,6 +43,7 @@ public class AllCoreTests {
suite.addTest(CModelElementsTests.suite());
suite.addTest(CModelIdentifierTests.suite());
suite.addTest(CModelExceptionTest.suite());
suite.addTest(CModelBuilderInactiveCodeTest.suite());
suite.addTest(FlagTests.suite());
suite.addTest(ArchiveTests.suite());
suite.addTest(TranslationUnitTests.suite());

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2009 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:
* Markus Schorn (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.model.tests;
import junit.framework.Test;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.IMacro;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
/**
* Tests for C model inactive code parsing.
*/
public class CModelBuilderInactiveCodeTest extends BaseTestCase {
public static Test suite() {
return suite(CModelBuilderInactiveCodeTest.class, "_");
}
private ICProject fCProject;
private ITranslationUnit fTU;
public CModelBuilderInactiveCodeTest(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
fCProject= CProjectHelper.createCProject(getName(), null, IPDOMManager.ID_FAST_INDEXER);
assertNotNull(fCProject);
CProjectHelper.importSourcesFromPlugin(fCProject, CTestPlugin.getDefault().getBundle(), "/resources/cmodel");
fTU= (ITranslationUnit) CProjectHelper.findElement(fCProject, "CModelBuilderInactiveCodeTest.cpp");
assertNotNull(fTU);
}
@Override
protected void tearDown() throws Exception {
CProjectHelper.delete(fCProject);
super.tearDown();
}
public void testPreprocessorNodes() throws Exception {
ISourceReference e= (ISourceReference) fTU.getElement("include");
assertTrue(e instanceof IInclude);
assertFalse(e.isActive());
e= (ISourceReference) fTU.getElement("MACRO1");
assertTrue(e instanceof IMacro);
assertFalse(e.isActive());
e= (ISourceReference) fTU.getElement("MACRO2");
assertTrue(e instanceof IMacro);
assertFalse(e.isActive());
}
}

View file

@ -0,0 +1,257 @@
/*******************************************************************************
* Copyright (c) 2009 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:
* Markus Schorn - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.scanner;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.parser.IToken;
/**
* Tests for using the preprocessor on inactive code
*/
public class InactiveCodeTests extends PreprocessorTestsBase {
public static TestSuite suite() {
return suite(InactiveCodeTests.class);
}
@Override
protected void initializeScanner() throws Exception {
super.initializeScanner();
fScanner.setProcessInactiveCode(true);
}
private void validate(char[] activeInactive) throws Exception {
boolean active= true;
for (char c : activeInactive) {
switch(c) {
case 'a':
if (!active) {
validateToken(IToken.tINACTIVE_CODE_END);
active= true;
}
validateIdentifier("a");
break;
case 'i':
validateToken(active ? IToken.tINACTIVE_CODE_START : IToken.tINACTIVE_CODE_SEPARATOR);
active= false;
validateIdentifier("i");
break;
default:
fail();
}
}
}
// #define D
// #ifdef D
// a
// #elif 1
// i
// #elif 0
// i
// #else
// i
// #endif
// a
// #ifdef UD
// i
// #elif 1
// a
// #elif 0
// i
// #else
// i
// #endif
// a
// #ifdef UD
// i
// #elif 0
// i
// #elif 1
// a
// #else
// i
// #endif
// a
// #ifdef UD
// i
// #elif 0
// i
// #else
// a
// #endif
public void testIfDef() throws Exception {
initializeScanner();
validate("aiiiaiaiiaiiaiaiia".toCharArray());
validateEOF();
}
// #define D
// #ifndef UD
// a
// #elif 1
// i
// #elif 0
// i
// #else
// i
// #endif
// a
// #ifndef D
// i
// #elif 1
// a
// #elif 0
// i
// #else
// i
// #endif
// a
// #ifndef D
// i
// #elif 0
// i
// #elif 1
// a
// #else
// i
// #endif
// a
// #ifndef D
// i
// #elif 0
// i
// #else
// a
// #endif
public void testIfnDef() throws Exception {
initializeScanner();
validate("aiiiaiaiiaiiaiaiia".toCharArray());
validateEOF();
}
// #if 1
// a
// #elif 1
// i
// #elif 0
// i
// #else
// i
// #endif
// a
// #if 0
// i
// #elif 1
// a
// #elif 0
// i
// #else
// i
// #endif
// a
// #if 0
// i
// #elif 0
// i
// #elif 1
// a
// #else
// i
// #endif
// a
// #if 0
// i
// #elif 0
// i
// #else
// a
// #endif
public void testIf() throws Exception {
initializeScanner();
validate("aiiiaiaiiaiiaiaiia".toCharArray());
validateEOF();
}
// #if 0
// i
// #if 1
// i
// #elif 0
// i
// #else
// i
// #endif
// i
// #endif
// a
// #if 0
// i
// #if 0
// i
// #elif 1
// i
// #else
// i
// #endif
// i
// #endif
// a
// #if 0
// i
// #if 0
// i
// #elif 0
// i
// #else
// i
// #endif
// i
// #endif
// a
public void testNestedInInactive() throws Exception {
initializeScanner();
validate("iiiiiaiiiiiaiiiiia".toCharArray());
validateEOF();
}
// #if 0
// i
// #define M
// #endif
// a
// #ifdef M
// i
// #endif
// a
public void testInactiveMacroDefinition() throws Exception {
initializeScanner();
validate("iaia".toCharArray());
validateEOF();
assertNull(fScanner.getMacroDefinitions().get("M"));
}
// #ifdef X
// # if 0
// # endif
// #elif defined (Y)
// #endif
public void testDefinedSyntax() throws Exception {
initializeScanner();
validateToken(IToken.tINACTIVE_CODE_START);
fScanner.skipInactiveCode();
validateEOF();
validateProblemCount(0);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2007, 2009 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
@ -408,8 +408,8 @@ public class LocationMapTests extends BaseTestCase {
final String[] params = new String[]{"p1", "p2"};
IMacroBinding macro2= new TestMacro("n2", "exp2", params);
init(DIGITS);
fLocationMap.encounterPoundDefine(0, 0, 0, 0, 0, macro1);
fLocationMap.encounterPoundDefine(0, 1, 3, 10, 16, macro2);
fLocationMap.encounterPoundDefine(0, 0, 0, 0, 0, true, macro1);
fLocationMap.encounterPoundDefine(0, 1, 3, 10, 16, true, macro2);
IASTPreprocessorMacroDefinition[] prep= fLocationMap.getMacroDefinitions();
assertEquals(2, prep.length);
checkMacroDefinition(prep[0], macro1, "", "n1", "", "exp1", null, FN, 0, 0, 1, 0, 0);
@ -463,7 +463,7 @@ public class LocationMapTests extends BaseTestCase {
assertEquals(2, fLocationMap.getCurrentLineNumber('\n'+1));
fLocationMap.registerPredefinedMacro(macro1);
fLocationMap.registerMacroFromIndex(macro2, new Loc("ifile", 2, 12), 32);
fLocationMap.encounterPoundDefine(3, 13, 33, 63, 103, macro3);
fLocationMap.encounterPoundDefine(3, 13, 33, 63, 103, true, macro3);
IASTName name1= fLocationMap.encounterImplicitMacroExpansion(macro1, null);
IASTName name2= fLocationMap.encounterImplicitMacroExpansion(macro2, null);
fLocationMap.pushMacroExpansion(110, 115, 125, 30, macro3, new IASTName[]{name1, name2}, new ImageLocationInfo[0]);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2007, 2009 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
@ -24,6 +24,7 @@ public class ScannerTestSuite extends TestSuite {
suite.addTest(InclusionTests.suite());
suite.addTest(PreprocessorBugsTests.suite());
suite.addTest(ExpansionExplorerTests.suite());
suite.addTest(InactiveCodeTests.suite());
return suite;
}
}

View file

@ -0,0 +1,5 @@
#if 0
#include "include"
#define MACRO1 1
#define MACRO2(x, y) x+y
#endif

View file

@ -37,12 +37,6 @@ public interface IInclude extends ICElement, ISourceReference, ISourceManipulati
public boolean isLocal();
/**
* @return whether this include directive is in active code, ie. not hidden
* by conditional compilation
*/
public boolean isActive();
/**
* @return whether this include directive was resolved and followed.
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 QNX Software Systems and others.
* Copyright (c) 2005, 2009 QNX Software Systems 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
@ -47,7 +47,7 @@ public interface ILanguage extends IAdaptable {
/**
* Option for {@link #getASTTranslationUnit(CodeReader, IScannerInfo, ICodeReaderFactory, IIndex, int, IParserLogService)}
* Performance optimization, instructs the parser not to create image-locations.
* Performance optimization, allows the parser not to create image-locations.
* When using this option {@link IASTName#getImageLocation()} will always return <code>null</code>.
*/
public final static int OPTION_NO_IMAGE_LOCATIONS= 0x4;
@ -61,12 +61,21 @@ public interface ILanguage extends IAdaptable {
/**
* Option for {@link #getASTTranslationUnit(CodeReader, IScannerInfo, ICodeReaderFactory, IIndex, int, IParserLogService)}
* Instructs the parser not to create ast nodes for expressions within aggregate initializers
* Allows the parser not to create ast nodes for expressions within aggregate initializers
* when they do not contain names.
* @since 5.1
*/
public final static int OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS= 0x10;
/**
* Option for {@link #getASTTranslationUnit(CodeReader, IScannerInfo, ICodeReaderFactory, IIndex, int, IParserLogService)}
* Instructs the parser to create ast nodes for inactive code branches, if possible. There is no guarantee that the ast
* can actually be created for the inactive parts.
* mstodo document how the ast can be accessed.
* @since 5.1
*/
public final static int OPTION_PARSE_INACTIVE_CODE= 0x20;
/**
* Return the language id for this language.
* This is to differentiate languages from each other.

View file

@ -7,6 +7,7 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.model;
@ -56,4 +57,17 @@ public interface ISourceReference {
* if this member is not declared in a translation unit (for example, a binary type).
*/
ITranslationUnit getTranslationUnit();
/**
* Returns whether this element is in active code. Code is inactive when it is hidden
* by conditional compilation.
* @since 5.1
*/
public boolean isActive();
/**
* Allows to differentiate otherwise equal elements of the same file.
* @since 5.1
*/
int getIndex();
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2007 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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
@ -95,6 +95,14 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
*/
public final static int AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS= 0x40;
/**
* Style constant for {@link #getAST(IIndex, int)}.
* Instructs the parser to make an attempt to create ast nodes for inactive code branches.
* mstodo document how to access those.
* @since 5.1
*/
public final static int AST_PARSE_INACTIVE_CODE= 0x80;
/**
* Creates and returns an include declaration in this translation unit
* with the given name.
@ -167,9 +175,24 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
* @return the found shared working copy for this element, <code>null</code> if none
* @see IBufferFactory
* @since 2.0
* @noreference This method is not intended to be referenced by clients.
*/
IWorkingCopy findSharedWorkingCopy(IBufferFactory bufferFactory);
/**
* Returns the shared working copy for this element, using the default <code>IBuffer</code> factory, or
* <code>null</code>, if no working copy has been created for this element.
* <p>
* Users of this method must not destroy the resulting working copy.
*
* @param bufferFactory
* the given <code>IBuffer</code> factory
* @return the found shared working copy for this element, or <code>null</code> if none
* @see IBufferFactory
* @since 5.1
*/
IWorkingCopy findSharedWorkingCopy();
/**
* Returns the contents of a translation unit as a char[]
* @return char[]
@ -284,13 +307,11 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
* @see IBufferFactory
* @see IProblemRequestor
* @since 2.0
* @noreference This method is not intended to be referenced by clients.
*/
IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor, IBufferFactory factory)
throws CModelException;
IWorkingCopy getSharedWorkingCopy(
IProgressMonitor monitor,
IBufferFactory factory)
throws CModelException;
/**
* Returns a shared working copy on this element using the given factory to create
* the buffer, or this element if this element is already a working copy.
@ -333,9 +354,53 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
* @see IBufferFactory
* @see IProblemRequestor
* @since 2.0
* @noreference This method is not intended to be referenced by clients.
*/
IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor, IBufferFactory factory, IProblemRequestor requestor) throws CModelException;
/**
* Returns a shared working copy on this element using the given factory to create the buffer, or this
* element if this element is already a working copy. This API can only answer an already existing working
* copy if it is based on the same original translation unit AND was using the same buffer factory (i.e.
* as defined by <code>Object#equals</code>).
* <p>
* The life time of a shared working copy is as follows:
* <ul>
* <li>The first call to <code>getSharedWorkingCopy(...)</code> creates a new working copy for this
* element</li>
* <li>Subsequent calls increment an internal counter.</li>
* <li>A call to <code>destroy()</code> decrements the internal counter.</li>
* <li>When this counter is 0, the working copy is destroyed.
* </ul>
* So users of this method must destroy exactly once the working copy.
* <p>
* Note that the buffer factory will be used for the life time of this working copy, i.e. if the working
* copy is closed then reopened, this factory will be used. The buffer will be automatically initialized
* with the original's compilation unit content upon creation.
* <p>
* When the shared working copy instance is created, an ADDED ICElementDelta is reported on this working
* copy.
*
* @param monitor
* a progress monitor used to report progress while opening this compilation unit or
* <code>null</code> if no progress should be reported
* @param requestor
* a requestor which will get notified of problems detected during reconciling as they are
* discovered. The requestor can be set to <code>null</code> indicating that the client is not
* interested in problems.
* @exception CModelException
* if the contents of this element can not be determined. Reasons include:
* <ul>
* <li> This C element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
* </ul>
* @return a shared working copy on this element using the given factory to create the buffer, or this
* element if this element is already a working copy
* @see IBufferFactory
* @see IProblemRequestor
* @since 5.1
*/
IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor, IProblemRequestor requestor) throws CModelException;
/**
* Returns the first using in this translation unit with the name
* This is a handle-only method. The namespace declaration may or may not exist.
@ -409,7 +474,13 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
/**
* Returns a new working copy for the Translation Unit.
* @return IWorkingCopy
* @since 5.1
*/
IWorkingCopy getWorkingCopy(IProgressMonitor monitor) throws CModelException;
/**
* Returns a new working copy for the Translation Unit.
* @noreference This method is not intended to be referenced by clients.
*/
IWorkingCopy getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory) throws CModelException;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. All rights reserved.
* Copyright (c) 2007, 2009 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
@ -38,10 +38,15 @@ public class ASTCache {
private static final String DEBUG_PREFIX= "[ASTCache] "; //$NON-NLS-1$
/** Full parse mode (no PDOM) */
public static int PARSE_MODE_FULL= ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT;
public static int PARSE_MODE_FULL = ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT
| ITranslationUnit.AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS
| ITranslationUnit.AST_PARSE_INACTIVE_CODE;
/** Fast parse mode (use PDOM) */
public static int PARSE_MODE_FAST= ITranslationUnit.AST_SKIP_ALL_HEADERS | ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT
| ITranslationUnit.AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS;
public static int PARSE_MODE_FAST = ITranslationUnit.AST_SKIP_ALL_HEADERS
| ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT
| ITranslationUnit.AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS
| ITranslationUnit.AST_PARSE_INACTIVE_CODE;
/**
* Do something with an AST.

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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
@ -245,4 +245,11 @@ public class BinaryElement extends CElement implements IBinaryElement, ISourceMa
return 0;
}
public boolean isActive() {
return true;
}
public int getIndex() {
return 0;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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
@ -279,6 +279,12 @@ public abstract class CElement extends PlatformObject implements ICElement {
!lhsName.equals(rhsName)) {
return false;
}
if (lhs instanceof ISourceReference && rhs instanceof ISourceReference) {
if (((ISourceReference) lhs).getIndex() != ((ISourceReference) rhs).getIndex()) {
return false;
}
}
ICElement lhsParent= lhs.getParent();
ICElement rhsParent= rhs.getParent();

View file

@ -13,9 +13,8 @@ package org.eclipse.cdt.internal.core.model;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import org.eclipse.cdt.core.CCorePlugin;
@ -74,6 +73,7 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.IContributedModelBuilder;
import org.eclipse.cdt.core.model.INamespace;
import org.eclipse.cdt.core.model.IProblemRequestor;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.IStructure;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.Keywords;
@ -98,7 +98,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
private ASTAccessVisibility fCurrentVisibility;
private Stack<ASTAccessVisibility> fVisibilityStack;
private Set<Namespace> fAllNamespaces;
private HashMap<ISourceReference, int[]> fEqualElements;
/**
* Create a model builder for the given translation unit.
@ -132,11 +132,11 @@ public class CModelBuilder2 implements IContributedModelBuilder {
int parseFlags= quickParseMode ? ITranslationUnit.AST_SKIP_ALL_HEADERS : ITranslationUnit.AST_SKIP_INDEXED_HEADERS;
if (!(elementInfo instanceof ASTHolderTUInfo)) {
parseFlags |= ITranslationUnit.AST_SKIP_FUNCTION_BODIES;
}
else {
} else {
parseFlags |= ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT;
}
parseFlags |= ITranslationUnit.AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS;
parseFlags |= ITranslationUnit.AST_PARSE_INACTIVE_CODE;
final IASTTranslationUnit ast;
try {
ast= fTranslationUnit.getAST(index, parseFlags, fProgressMonitor);
@ -193,14 +193,13 @@ public class CModelBuilder2 implements IContributedModelBuilder {
*/
private void buildModel(IASTTranslationUnit ast) throws CModelException, DOMException {
fVisibilityStack= new Stack<ASTAccessVisibility>();
fAllNamespaces= new HashSet<Namespace>();
fEqualElements= new HashMap<ISourceReference, int[]>();
// includes
final IASTPreprocessorIncludeStatement[] includeDirectives= ast.getIncludeDirectives();
Set<Include> allIncludes= new HashSet<Include>();
for (IASTPreprocessorIncludeStatement includeDirective : includeDirectives) {
if (isLocalToFile(includeDirective)) {
createInclusion(fTranslationUnit, includeDirective, allIncludes);
createInclusion(fTranslationUnit, includeDirective);
}
}
// macros
@ -217,6 +216,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
createDeclaration(fTranslationUnit, declaration);
}
}
fEqualElements.clear();
// sort by offset
final List<ICElement> children= fTranslationUnit.getElementInfo().internalGetChildren();
@ -264,18 +264,15 @@ public class CModelBuilder2 implements IContributedModelBuilder {
return node.isPartOfTranslationUnitFile();
}
private Include createInclusion(Parent parent, IASTPreprocessorIncludeStatement inclusion, Set<Include> allIncludes) throws CModelException{
private Include createInclusion(Parent parent, IASTPreprocessorIncludeStatement inclusion) throws CModelException{
// create element
final IASTName name= inclusion.getName();
Include element= new Include(parent, ASTStringUtil.getSimpleName(name), inclusion.isSystemInclude());
element.setFullPathName(inclusion.getPath());
setIndex(element);
element.setActive(inclusion.isActive());
element.setResolved(inclusion.isResolved());
// if there is a duplicate include, also set the index
if (!allIncludes.add(element)) {
element.setIndex(allIncludes.size());
allIncludes.add(element);
}
// add to parent
parent.addChild(element);
// set positions
@ -284,10 +281,22 @@ public class CModelBuilder2 implements IContributedModelBuilder {
return element;
}
private void setIndex(SourceManipulation element) {
int[] idx= fEqualElements.get(element);
if (idx == null) {
idx= new int[] {0};
fEqualElements.put(element, idx);
} else {
element.setIndex(++idx[0]);
}
}
private Macro createMacro(Parent parent, IASTPreprocessorMacroDefinition macro) throws CModelException{
// create element
final IASTName name= macro.getName();
Macro element= new Macro(parent, ASTStringUtil.getSimpleName(name));
setIndex(element);
element.setActive(macro.isActive());
// add to parent
parent.addChild(element);
// set positions
@ -479,11 +488,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final IASTName name= declaration.getName();
final String nsName= ASTStringUtil.getQualifiedName(name);
final Namespace element= new Namespace(parent, nsName);
// if there is a duplicate namespace, also set the index
if (!fAllNamespaces.add(element)) {
element.setIndex(fAllNamespaces.size());
fAllNamespaces.add(element);
}
setIndex(element);
// add to parent
parent.addChild(element);
// set positions
@ -499,15 +505,12 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element.setTypeName(type);
final Set<Namespace> savedNamespaces= fAllNamespaces;
fAllNamespaces= new HashSet<Namespace>();
IASTDeclaration[] nsDeclarations= declaration.getDeclarations();
for (IASTDeclaration nsDeclaration : nsDeclarations) {
if (declaration.getFileLocation() != null || isLocalToFile(nsDeclaration)) {
createDeclaration(element, nsDeclaration);
}
}
fAllNamespaces= savedNamespaces;
}
private StructureDeclaration createElaboratedTypeDeclaration(Parent parent, IASTElaboratedTypeSpecifier elaboratedTypeSpecifier, boolean isTemplate) throws CModelException{
@ -547,6 +550,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
} else {
element= new StructureDeclaration(parent, className, kind);
}
setIndex(element);
element.setTypeName(type);
// add to parent
@ -571,6 +575,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final IASTName astEnumName= enumSpecifier.getName();
final String enumName= ASTStringUtil.getSimpleName(astEnumName);
final Enumeration element= new Enumeration (parent, enumName);
setIndex(element);
// add to parent
parent.addChild(element);
final IASTEnumerator[] enumerators= enumSpecifier.getEnumerators();
@ -592,6 +598,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
private Enumerator createEnumerator(Parent enumarator, IASTEnumerator enumDef) throws CModelException{
final IASTName astEnumName= enumDef.getName();
final Enumerator element= new Enumerator (enumarator, ASTStringUtil.getSimpleName(astEnumName));
setIndex(element);
IASTExpression initialValue= enumDef.getValue();
if(initialValue != null){
element.setConstantExpression(ASTSignatureUtil.getExpressionString(initialValue));
@ -643,6 +651,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
StructureTemplate classTemplate= new StructureTemplate(parent, kind, className);
element= classTemplate;
}
setIndex(element);
if (compositeTypeSpecifier instanceof ICPPASTCompositeTypeSpecifier) {
// store super classes names
@ -712,6 +721,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
String name= ASTStringUtil.getSimpleName(astTypedefName);
final TypeDef element= new TypeDef(parent, name);
setIndex(element);
String typeName= ASTStringUtil.getSignatureString(declSpecifier, declarator);
element.setTypeName(typeName);
@ -752,6 +762,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|| CModelBuilder2.getScope(astVariableName) instanceof ICPPClassScope) {
// field
Field newElement= new Field(parent, variableName);
setIndex(newElement);
if (specifier instanceof ICPPASTDeclSpecifier) {
final ICPPASTDeclSpecifier cppSpecifier= (ICPPASTDeclSpecifier)specifier;
newElement.setMutable(cppSpecifier.getStorageClass() == ICPPASTDeclSpecifier.sc_mutable);
@ -777,6 +788,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element= newElement;
}
}
setIndex(element);
element.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
info= element.getSourceManipulationInfo();
}
@ -867,6 +879,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
methodElement.setParameterTypes(parameterTypes);
methodElement.setReturnType(returnType);
methodElement.setConst(cppFunctionDeclarator.isConst());
setIndex(element);
final MethodInfo methodInfo= methodElement.getMethodInfo();
info= methodInfo;
ICPPMethod methodBinding= null;
@ -929,6 +943,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
}
element.setParameterTypes(parameterTypes);
element.setReturnType(returnType);
setIndex(element);
info= element.getFunctionInfo();
info.setConst(cppFunctionDeclarator.isConst());
}
@ -938,6 +954,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element= new Function(parent, functionName);
element.setParameterTypes(parameterTypes);
element.setReturnType(returnType);
setIndex(element);
info= element.getFunctionInfo();
}
@ -988,6 +1006,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
methodElement.setParameterTypes(parameterTypes);
methodElement.setReturnType(returnType);
methodElement.setConst(cppFunctionDeclarator.isConst());
setIndex(element);
final MethodInfo methodInfo= methodElement.getMethodInfo();
info= methodInfo;
if (declSpecifier instanceof ICPPASTDeclSpecifier) {
@ -1009,6 +1028,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
}
element.setParameterTypes(parameterTypes);
element.setReturnType(returnType);
setIndex(element);
info= (FunctionInfo)element.getElementInfo();
info.setConst(cppFunctionDeclarator.isConst());
}
@ -1020,6 +1041,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
}
element.setParameterTypes(parameterTypes);
element.setReturnType(returnType);
setIndex(element);
info= (FunctionInfo)element.getElementInfo();
} else {
assert false;
@ -1044,6 +1067,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// create the element
IASTName name= usingDirDeclaration.getQualifiedName();
Using element= new Using(parent, ASTStringUtil.getQualifiedName(name), true);
setIndex(element);
// add to parent
parent.addChild(element);
@ -1058,6 +1082,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// create the element
IASTName name= usingDeclaration.getName();
Using element= new Using(parent, ASTStringUtil.getSimpleName(name), false);
setIndex(element);
// add to parent
parent.addChild(element);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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,8 +8,8 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
import org.eclipse.cdt.core.model.ICElement;
@ -17,11 +17,9 @@ import org.eclipse.cdt.core.model.IInclude;
public class Include extends SourceManipulation implements IInclude {
private final boolean standard;
private String fullPath;
private boolean fIsActive= true;
private final boolean standard;
private boolean fIsResolved= true;
private int fIndex= 0;
public Include(ICElement parent, String name, boolean isStandard) {
super(parent, name, ICElement.C_INCLUDE);
@ -58,17 +56,6 @@ public class Include extends SourceManipulation implements IInclude {
this.fullPath = fullPath;
}
public void setActive(boolean active) {
fIsActive= active;
}
/*
* @see org.eclipse.cdt.core.model.IInclude#isActive()
*/
public boolean isActive() {
return fIsActive;
}
public void setResolved(boolean resolved) {
fIsResolved= resolved;
}
@ -80,25 +67,12 @@ public class Include extends SourceManipulation implements IInclude {
return fIsResolved;
}
/**
* Set the index of this include, in case the same include is referenced
* multiple times.
*
* @param index
*/
public void setIndex(int index) {
fIndex= index;
}
/*
* @see org.eclipse.cdt.internal.core.model.CElement#equals(java.lang.Object)
*/
@Override
public boolean equals(Object other) {
if (other instanceof IInclude && equals(this, (IInclude) other)) {
if (other instanceof Include) {
return fIndex == ((Include)other).fIndex;
}
return true;
}
return false;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2002, 2008 IBM Corporation and others.
* Copyright (c) 2002, 2009 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:
* Rational Software - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
@ -18,7 +19,6 @@ import org.eclipse.cdt.core.model.INamespace;
public class Namespace extends SourceManipulation implements INamespace{
String typeName = ""; //$NON-NLS-1$
int fIndex;
public Namespace(ICElement parent, String name) {
super(parent, name, ICElement.C_NAMESPACE);
}
@ -39,28 +39,14 @@ public class Namespace extends SourceManipulation implements INamespace{
this.typeName = typeName;
}
/**
* Set the index of this namespace, in case the same namespace is referenced
* multiple times.
*
* @param index
*/
public void setIndex(int index) {
fIndex= index;
}
/*
* @see org.eclipse.cdt.internal.core.model.CElement#equals(java.lang.Object)
*/
@Override
public boolean equals(Object other) {
if (other instanceof INamespace && equals(this, (INamespace) other)) {
if (other instanceof Namespace) {
return fIndex == ((Namespace)other).fIndex;
}
return true;
}
return false;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
@ -41,6 +42,8 @@ public class SourceManipulation extends Parent implements ISourceManipulation, I
* An empty list of Strings
*/
protected static final String[] fgEmptyStrings = {};
private boolean fIsActive= true;
private short fIndex= 0;
public SourceManipulation(ICElement parent, String name, int type) {
super(parent, name, type);
@ -350,4 +353,33 @@ public class SourceManipulation extends Parent implements ISourceManipulation, I
return CElement.CEM_SOURCEELEMENT;
}
public boolean isActive() {
return fIsActive;
}
public int getIndex() {
return fIndex;
}
public void setActive(boolean active) {
fIsActive= active;
}
public void setIndex(int i) {
fIndex= (short) i;
}
@Override
public int hashCode() {
return Util.combineHashCodes(fIndex, super.hashCode());
}
@Override
public boolean equals(Object other) {
if (other instanceof ISourceReference) {
if (fIndex != ((ISourceReference) other).getIndex())
return false;
}
return super.equals(other);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
@ -33,13 +34,9 @@ class SourceManipulationInfo extends CElementInfo {
protected int fStartLine;
protected int fEndLine;
int modifiers;
protected SourceManipulationInfo(CElement element) {
super(element);
setIsStructureKnown(true);
modifiers = 0;
}
public void setPos(int startPos, int length) {
@ -209,7 +206,7 @@ class SourceManipulationInfo extends CElementInfo {
* @return int
*/
public int getModifiers(){
return modifiers;
return 0;
}
/**

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 QNX Software Systems and others.
* Copyright (c) 2000, 2009 QNX Software Systems 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
@ -401,6 +401,10 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return super.equals(o) && !((ITranslationUnit) o).isWorkingCopy();
}
public IWorkingCopy findSharedWorkingCopy() {
return findSharedWorkingCopy(null);
}
public IWorkingCopy findSharedWorkingCopy(IBufferFactory factory) {
// if factory is null, default factory must be used
@ -456,6 +460,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
}
}
public IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor, IProblemRequestor requestor)
throws CModelException {
return getSharedWorkingCopy(monitor, null, requestor);
}
public IWorkingCopy getSharedWorkingCopy(IProgressMonitor monitor,IBufferFactory factory)
throws CModelException {
return getSharedWorkingCopy(monitor, factory, null);
@ -493,7 +502,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return this.getWorkingCopy(null, null);
}
public IWorkingCopy getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory)throws CModelException{
public IWorkingCopy getWorkingCopy(IProgressMonitor monitor) throws CModelException {
return getWorkingCopy(monitor, null);
}
public IWorkingCopy getWorkingCopy(IProgressMonitor monitor, IBufferFactory factory) throws CModelException{
WorkingCopy workingCopy;
IFile file= getFile();
if (file != null) {
@ -638,7 +651,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
*/
private void parse(Map<ICElement, CElementInfo> newElements, IProgressMonitor monitor) {
boolean quickParseMode = ! (CCorePlugin.getDefault().useStructuralParseMode());
IContributedModelBuilder mb = LanguageManager.getInstance().getContributedModelBuilderFor(this);
IContributedModelBuilder mb = LanguageManager.getInstance().getContributedModelBuilderFor((ITranslationUnit) this);
if (mb == null) {
parseUsingCModelBuilder(newElements, quickParseMode, monitor);
} else {
@ -823,6 +836,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
if ((style & AST_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS) != 0) {
options |= ILanguage.OPTION_SKIP_TRIVIAL_EXPRESSIONS_IN_AGGREGATE_INITIALIZERS;
}
if ((style & AST_PARSE_INACTIVE_CODE) != 0) {
options |= ILanguage.OPTION_PARSE_INACTIVE_CODE;
}
if (isSourceUnit()) {
options |= ILanguage.OPTION_IS_SOURCE_UNIT;
}
@ -1130,4 +1146,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return CElement.CEM_TRANSLATIONUNIT;
}
public boolean isActive() {
return true;
}
public int getIndex() {
return 0;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2009 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
@ -317,4 +317,11 @@ abstract class CElementHandle implements ICElementHandle, ISourceReference {
}
}
public boolean isActive() {
return true;
}
public int getIndex() {
return 0;
}
}

View file

@ -29,18 +29,9 @@ public interface IASTPreprocessorMacroDefinition extends
/**
* Get the macro name.
*
* @return <code>IASTName</code>
*/
public IASTName getName();
/**
* Set the macro name.
*
* @param name
*/
public void setName(IASTName name);
/**
* Returns the macro expansion, or an empty string for dynamic style macros.
*/
@ -53,11 +44,20 @@ public interface IASTPreprocessorMacroDefinition extends
*/
public IASTFileLocation getExpansionLocation();
/**
* Set the macro expansion.
*
* @param exp
* String
* Returns whether this macro definition occurs in active code.
* @since 5.1
*/
public void setExpansion(String exp);
public boolean isActive();
/**
* @noreference This method is not intended to be referenced by clients.
*/
@Deprecated public void setName(IASTName name);
/**
* @noreference This method is not intended to be referenced by clients.
*/
@Deprecated public void setExpansion(String exp);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 IBM Corporation and others.
* Copyright (c) 2007, 2009 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
@ -114,6 +114,7 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
final IScanner scanner= createScanner(reader, scanInfo, codeReaderFactory, log);
scanner.setComputeImageLocations((options & OPTION_NO_IMAGE_LOCATIONS) == 0);
scanner.setProcessInactiveCode((options & OPTION_PARSE_INACTIVE_CODE) != 0);
final ISourceCodeParser parser= createParser(scanner, log, index, false, options);

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2003, 2008 IBM Corporation and others.
* Copyright (c) 2003, 2009 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
@ -82,4 +82,20 @@ public interface IScanner {
* @since 5.0
*/
public void setComputeImageLocations(boolean val);
/**
* Toggles generation of tokens for inactive code branches. When turned on,
* each inactive code branch is preceded by a token of kind {@link IToken#tINACTIVE_CODE_START} and
* succeeded by one of kind {@link IToken#tINACTIVE_CODE_END}.
*
* @noreference This method is not intended to be referenced by clients.
*/
public void setProcessInactiveCode(boolean val);
/**
* When in inactive code, skips all tokens up to the end of the inactive code section.
* <p> Note, token after calling this method may be another token of type {@link IToken#tINACTIVE_CODE_START}.
* @noreference This method is not intended to be referenced by clients.
*/
public void skipInactiveCode() throws OffsetLimitReachedException;
}

View file

@ -39,195 +39,155 @@ public interface IToken {
int FIRST_RESERVED_SCANNER= -100;
int LAST_RESERVED_SCANNER= -1;
static public final int tIDENTIFIER = 1;
static public final int tINTEGER = 2;
static public final int tCOLONCOLON = 3;
static public final int tCOLON = 4;
static public final int tSEMI = 5;
static public final int tCOMMA = 6;
static public final int tQUESTION = 7;
static public final int tLPAREN = 8;
static public final int tRPAREN = 9;
static public final int tLBRACKET = 10;
static public final int tRBRACKET = 11;
static public final int tLBRACE = 12;
static public final int tRBRACE = 13;
static public final int tPLUSASSIGN = 14;
static public final int tINCR = 15;
static public final int tPLUS = 16;
static public final int tMINUSASSIGN = 17;
static public final int tDECR = 18;
static public final int tARROWSTAR = 19;
static public final int tARROW = 20;
static public final int tMINUS = 21;
static public final int tSTARASSIGN = 22;
static public final int tSTAR = 23;
static public final int tMODASSIGN = 24;
static public final int tMOD = 25;
static public final int tXORASSIGN = 26;
static public final int tXOR = 27;
static public final int tAMPERASSIGN = 28;
static public final int tAND = 29;
static public final int tAMPER = 30;
static public final int tBITORASSIGN = 31;
static public final int tOR = 32;
static public final int tBITOR = 33;
static public final int tBITCOMPLEMENT = 34;
static public final int tNOTEQUAL = 35;
static public final int tNOT = 36;
static public final int tEQUAL = 37;
static public final int tASSIGN = 38;
static public final int tUNKNOWN_CHAR= 39;
static public final int tSHIFTL = 40;
static public final int tLTEQUAL = 41;
static public final int tLT = 42;
static public final int tSHIFTRASSIGN = 43;
static public final int tSHIFTR = 44;
static public final int tGTEQUAL = 45;
static public final int tGT = 46;
static public final int tSHIFTLASSIGN = 47;
static public final int tELLIPSIS = 48;
static public final int tDOTSTAR = 49;
static public final int tDOT = 50;
static public final int tDIVASSIGN = 51;
static public final int tDIV = 52;
int tIDENTIFIER = 1;
int tINTEGER = 2;
int tCOLONCOLON = 3;
int tCOLON = 4;
int tSEMI = 5;
int tCOMMA = 6;
int tQUESTION = 7;
int tLPAREN = 8;
int tRPAREN = 9;
int tLBRACKET = 10;
int tRBRACKET = 11;
int tLBRACE = 12;
int tRBRACE = 13;
int tPLUSASSIGN = 14;
int tINCR = 15;
int tPLUS = 16;
int tMINUSASSIGN = 17;
int tDECR = 18;
int tARROWSTAR = 19;
int tARROW = 20;
int tMINUS = 21;
int tSTARASSIGN = 22;
int tSTAR = 23;
int tMODASSIGN = 24;
int tMOD = 25;
int tXORASSIGN = 26;
int tXOR = 27;
int tAMPERASSIGN = 28;
int tAND = 29;
int tAMPER = 30;
int tBITORASSIGN = 31;
int tOR = 32;
int tBITOR = 33;
int tBITCOMPLEMENT = 34;
int tNOTEQUAL = 35;
int tNOT = 36;
int tEQUAL = 37;
int tASSIGN = 38;
int tUNKNOWN_CHAR= 39;
int tSHIFTL = 40;
int tLTEQUAL = 41;
int tLT = 42;
int tSHIFTRASSIGN = 43;
int tSHIFTR = 44;
int tGTEQUAL = 45;
int tGT = 46;
int tSHIFTLASSIGN = 47;
int tELLIPSIS = 48;
int tDOTSTAR = 49;
int tDOT = 50;
int tDIVASSIGN = 51;
int tDIV = 52;
/** @deprecated use {@link #tAND} */
@Deprecated
static public final int t_and = 54;
/** @deprecated use {@link #tAMPERASSIGN} */
@Deprecated
static public final int t_and_eq = 55;
static public final int t_asm = 56;
static public final int t_auto = 57;
/** @deprecated use {@link #tAMPER} */
@Deprecated
static public final int t_bitand = 58;
/** @deprecated use {@link #tBITOR} */
@Deprecated
static public final int t_bitor = 59;
static public final int t_bool = 60;
static public final int t_break = 61;
static public final int t_case = 62;
static public final int t_catch = 63;
static public final int t_char = 64;
static public final int t_class = 65;
/** @deprecated use {@link #tAND} */ @Deprecated int t_and = 54;
/** @deprecated use {@link #tAMPERASSIGN} */ @Deprecated int t_and_eq = 55;
int t_asm = 56;
int t_auto = 57;
/** @deprecated use {@link #tAMPER} */ @Deprecated int t_bitand = 58;
/** @deprecated use {@link #tBITOR} */ @Deprecated int t_bitor = 59;
int t_bool = 60;
int t_break = 61;
int t_case = 62;
int t_catch = 63;
int t_char = 64;
int t_class = 65;
/** @deprecated use {@link #tBITCOMPLEMENT} */ @Deprecated int tCOMPL= tBITCOMPLEMENT;
/** @deprecated use {@link #tBITCOMPLEMENT} */ @Deprecated int t_compl = 66;
int t_const = 67;
/** @deprecated use {@link #tBITCOMPLEMENT} */
@Deprecated
static public final int tCOMPL= tBITCOMPLEMENT;
/** @deprecated use {@link #tBITCOMPLEMENT} */
@Deprecated
static public final int t_compl = 66;
static public final int t_const = 67;
static public final int t_const_cast = 69;
static public final int t_continue = 70;
static public final int t_default = 71;
static public final int t_delete = 72;
static public final int t_do = 73;
static public final int t_double = 74;
static public final int t_dynamic_cast = 75;
static public final int t_else = 76;
static public final int t_enum = 77;
static public final int t_explicit = 78;
static public final int t_export = 79;
static public final int t_extern = 80;
static public final int t_false = 81;
static public final int t_float = 82;
static public final int t_for = 83;
static public final int t_friend = 84;
static public final int t_goto = 85;
static public final int t_if = 86;
static public final int t_inline = 87;
static public final int t_int = 88;
static public final int t_long = 89;
static public final int t_mutable = 90;
static public final int t_namespace = 91;
static public final int t_new = 92;
/** @deprecated use {@link #tNOT} */
@Deprecated
static public final int t_not = 93;
/** @deprecated use {@link #tNOTEQUAL} */
@Deprecated
static public final int t_not_eq = 94;
static public final int t_operator = 95;
/** @deprecated use {@link #tOR} */
@Deprecated
static public final int t_or = 96;
/** @deprecated use {@link #tBITORASSIGN} */
@Deprecated
static public final int t_or_eq = 97;
static public final int t_private = 98;
static public final int t_protected = 99;
static public final int t_public = 100;
static public final int t_register = 101;
static public final int t_reinterpret_cast = 102;
static public final int t_return = 103;
static public final int t_short = 104;
static public final int t_sizeof = 105;
static public final int t_static = 106;
static public final int t_static_cast = 107;
static public final int t_signed = 108;
static public final int t_struct = 109;
static public final int t_switch = 110;
static public final int t_template = 111;
static public final int t_this = 112;
static public final int t_throw = 113;
static public final int t_true = 114;
static public final int t_try = 115;
static public final int t_typedef = 116;
static public final int t_typeid = 117;
static public final int t_typename = 118;
static public final int t_union = 119;
static public final int t_unsigned = 120;
static public final int t_using = 121;
static public final int t_virtual = 122;
static public final int t_void = 123;
static public final int t_volatile = 124;
static public final int t_wchar_t = 125;
static public final int t_while = 126;
/** @deprecated use {@link #tXOR} */
@Deprecated
static public final int t_xor = 127;
/** @deprecated use {@link #tXORASSIGN} */
@Deprecated
static public final int t_xor_eq = 128;
static public final int tFLOATINGPT = 129;
static public final int tSTRING = 130;
static public final int tLSTRING = 131;
static public final int tCHAR = 132;
static public final int tLCHAR = 133;
static public final int t__Bool = 134;
static public final int t__Complex = 135;
static public final int t__Imaginary = 136;
static public final int t_restrict = 137;
/** @deprecated don't use it */
@Deprecated
static public final int tMACROEXP = 138;
static public final int tPOUND= 138;
static public final int tPOUNDPOUND = 139;
static public final int tCOMPLETION = 140;
static public final int tEOC = 141; // End of Completion
/** @deprecated don't use it */
@Deprecated
static public final int tCOMMENT = 142;
/** @deprecated don't use it */
@Deprecated
static public final int tBLOCKCOMMENT = 143;
static public final int tEND_OF_INPUT= 144;
int t_const_cast = 69;
int t_continue = 70;
int t_default = 71;
int t_delete = 72;
int t_do = 73;
int t_double = 74;
int t_dynamic_cast = 75;
int t_else = 76;
int t_enum = 77;
int t_explicit = 78;
int t_export = 79;
int t_extern = 80;
int t_false = 81;
int t_float = 82;
int t_for = 83;
int t_friend = 84;
int t_goto = 85;
int t_if = 86;
int t_inline = 87;
int t_int = 88;
int t_long = 89;
int t_mutable = 90;
int t_namespace = 91;
int t_new = 92;
/** @deprecated use {@link #tNOT} */ @Deprecated int t_not = 93;
/** @deprecated use {@link #tNOTEQUAL} */ @Deprecated int t_not_eq = 94;
int t_operator = 95;
/** @deprecated use {@link #tOR} */ @Deprecated int t_or = 96;
/** @deprecated use {@link #tBITORASSIGN} */ @Deprecated int t_or_eq = 97;
int t_private = 98;
int t_protected = 99;
int t_public = 100;
int t_register = 101;
int t_reinterpret_cast = 102;
int t_return = 103;
int t_short = 104;
int t_sizeof = 105;
int t_static = 106;
int t_static_cast = 107;
int t_signed = 108;
int t_struct = 109;
int t_switch = 110;
int t_template = 111;
int t_this = 112;
int t_throw = 113;
int t_true = 114;
int t_try = 115;
int t_typedef = 116;
int t_typeid = 117;
int t_typename = 118;
int t_union = 119;
int t_unsigned = 120;
int t_using = 121;
int t_virtual = 122;
int t_void = 123;
int t_volatile = 124;
int t_wchar_t = 125;
int t_while = 126;
/** @deprecated use {@link #tXOR} */ @Deprecated int t_xor = 127;
/** @deprecated use {@link #tXORASSIGN} */ @Deprecated int t_xor_eq = 128;
int tFLOATINGPT = 129;
int tSTRING = 130;
int tLSTRING = 131;
int tCHAR = 132;
int tLCHAR = 133;
int t__Bool = 134;
int t__Complex = 135;
int t__Imaginary = 136;
int t_restrict = 137;
/** @deprecated don't use it */ @Deprecated int tMACROEXP = 138;
int tPOUND= 138;
int tPOUNDPOUND = 139;
int tCOMPLETION = 140;
int tEOC = 141; // End of Completion
/** @deprecated don't use it */ @Deprecated int tCOMMENT = 142;
/** @deprecated don't use it */ @Deprecated int tBLOCKCOMMENT = 143;
int tEND_OF_INPUT= 144;
/** @since 5.1 */ int tINACTIVE_CODE_START= 145;
/** @since 5.1 */ int tINACTIVE_CODE_SEPARATOR= 146;
/** @since 5.1 */ int tINACTIVE_CODE_END = 147;
int FIRST_RESERVED_IGCCToken = 150;
int LAST_RESERVED_IGCCToken = 199;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* Copyright (c) 2005, 2009 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
@ -206,29 +206,35 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
/**
* Look Ahead in the token list to see what is coming.
*
* @param i
* How far ahead do you wish to peek?
* Returns the next token without advancing
*/
protected IToken mark() throws EndOfFileException {
return currToken == null ? currToken = fetchToken(true) : currToken;
}
/**
* Roll back to a previous point, reseting the queue of tokens.
* @param mark a token previously obtained via {@link #mark()}.
*/
protected void backup(IToken mark) {
currToken = mark;
}
/**
* Look ahead in the token list to see what is coming.
* @param i number of tokens to look ahead, must be greater or equal to 0.
* @return the token you wish to observe
* @throws EndOfFileException
* if looking ahead encounters EOF, throw EndOfFile
*/
protected IToken LA(int i) throws EndOfFileException {
assert i >= 0;
if (isCancelled) {
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
}
if (i < 1) // can't go backwards
return null;
if (currToken == null)
currToken = fetchToken();
IToken retToken = currToken;
IToken retToken= mark();
for (; i > 1; --i) {
retToken = retToken.getNext();
if (retToken == null)
retToken = fetchToken();
retToken = fetchToken(true);
}
return retToken;
}
@ -246,12 +252,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
/**
* Look ahead in the token list and return the token type.
*
* @param i
* How far ahead do you wish to peek?
* @param i number of tokens to look ahead, must be greater or equal to 0.
* @return The type of that token
* @throws EndOfFileException
* if looking ahead encounters EOF, throw EndOfFile
*/
protected int LT(int i) throws EndOfFileException {
return LA(i).getType();
@ -295,37 +297,29 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
/**
* Consume the next token available, regardless of the type.
* Consume the next token available, regardless of the type and returns it.
*
* @return The token that was consumed and removed from our buffer.
* @throws EndOfFileException
* If there is no token to consume.
*/
protected IToken consume() throws EndOfFileException {
if (currToken == null) {
currToken = fetchToken();
}
final IToken lastToken = currToken;
currToken= lastToken.getNext();
return lastToken;
final IToken result= mark();
currToken= result.getNext();
return result;
}
/**
* Consume the next token available only if the type is as specified.
* If the type of the next token matches, it is consumed and returned. Otherwise a
* {@link BacktrackException} will be thrown.
*
* @param type
* The type of token that you are expecting.
* @return the token that was consumed and removed from our buffer.
* @throws BacktrackException
* If LT(1) != type
* @param type the expected type of the next token.
*/
protected IToken consume(int type) throws EndOfFileException, BacktrackException {
final IToken la1= LA(1);
if (la1.getType() != type)
throwBacktrack(la1);
return consume();
final IToken result= consume();
if (result.getType() != type)
throwBacktrack(result);
return result;
}
/**
@ -350,15 +344,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
/**
* Fetches a token from the scanner.
*
* @return the next token from the scanner
* @throws EndOfFileException
* thrown when the scanner.nextToken() yields no tokens
* Fetches the next token from the scanner.
*/
protected IToken fetchToken() throws EndOfFileException {
private IToken fetchToken(boolean skipInactive) throws EndOfFileException {
try {
final IToken result= scanner.nextToken();
IToken result= scanner.nextToken();
while (result.getType() == IToken.tINACTIVE_CODE_START) {
scanner.skipInactiveCode();
result= scanner.nextToken();
}
eofOffset= result.getEndOffset();
return result;
} catch (OffsetLimitReachedException olre) {
@ -375,28 +369,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
throw exception;
}
/**
* Mark our place in the buffer so that we could return to it should we have
* to.
*
* @return The current token.
* @throws EndOfFileException
* If there are no more tokens.
*/
protected IToken mark() throws EndOfFileException {
return currToken == null ? currToken = fetchToken() : currToken;
}
/**
* Rollback to a previous point, reseting the queue of tokens.
*
* @param mark
* The point that we wish to restore to.
*/
protected void backup(IToken mark) {
currToken = mark;
}
/**
* This is the single entry point for setting parsePassed to false
*/

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2007, 2009 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
@ -276,15 +276,17 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
private final ASTPreprocessorName fName;
private final int fExpansionNumber;
private final int fExpansionOffset;
private final boolean fActive;
/**
* Regular constructor.
*/
public ASTMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro,
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber, boolean active) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fExpansionNumber= expansionNumber;
fExpansionOffset= -1;
fActive= active;
fName= new ASTPreprocessorDefinition(this, IASTPreprocessorMacroDefinition.MACRO_NAME, nameNumber, nameEndNumber, macro.getNameCharArray(), macro);
}
@ -297,6 +299,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, floc, macro.getNameCharArray(), macro);
fExpansionNumber= -1;
fExpansionOffset= expansionOffset;
fActive= true;
}
@ -357,6 +360,10 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
public String toString() {
return getName().toString() + '=' + getExpansion();
}
final public boolean isActive() {
return fActive;
}
}
class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyleMacroParameter {
@ -379,8 +386,8 @@ class ASTFunctionStyleMacroDefinition extends ASTMacroDefinition implements IAST
* Regular constructor.
*/
public ASTFunctionStyleMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro,
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
super(parent, macro, startNumber, nameNumber, nameEndNumber, expansionNumber, endNumber);
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber, boolean active) {
super(parent, macro, startNumber, nameNumber, nameEndNumber, expansionNumber, endNumber, active);
}
/**

View file

@ -49,6 +49,9 @@ import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalExce
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.BranchKind;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.CodeState;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.Conditional;
import org.eclipse.core.runtime.IAdaptable;
/**
@ -68,7 +71,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private static final int ORIGIN_PREPROCESSOR_DIRECTIVE = OffsetLimitReachedException.ORIGIN_PREPROCESSOR_DIRECTIVE;
private static final int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE;
// private static final int ORIGIN_MACRO_EXPANSION = OffsetLimitReachedException.ORIGIN_MACRO_EXPANSION;
private static final char[] EMPTY_CHAR_ARRAY = new char[0];
private static final char[] ONE = "1".toCharArray(); //$NON-NLS-1$
@ -169,7 +171,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private String[] fIncludePaths;
final private String[] fQuoteIncludePaths;
private String[][] fPreIncludedFiles= null;
// private boolean fProcessInactiveCode= false;
private int fContentAssistLimit= -1;
private boolean fHandledCompletion= false;
@ -279,10 +280,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fRootLexer.setContentAssistMode(offset);
}
// mstodo
// public void setProcessInactiveCode(boolean val) {
// fProcessInactiveCode= val;
// }
public void setProcessInactiveCode(boolean val) {
fRootContext.setParseInactiveCode(val);
}
public void setScanComments(boolean val) {
}
@ -599,7 +599,19 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return t1;
}
private void appendStringContent(StringBuffer buf, Token t1) {
public void skipInactiveCode() throws OffsetLimitReachedException {
final Lexer lexer= fCurrentContext.getLexer();
if (lexer != null) {
CodeState state= fCurrentContext.getCodeState();
while (state != CodeState.eActive) {
state= skipBranch(lexer, false);
}
fCurrentContext.clearInactiveCodeMarkerToken();
}
}
private void appendStringContent(StringBuffer buf, Token t1) {
final char[] image= t1.getCharImage();
final int length= image.length;
if (length > 1) {
@ -940,8 +952,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
/**
* Assumes that the pound token has not yet been consumed
* @param ppdCtx
* @param startOffset offset in current file
* @since 5.0
*/
private void executeDirective(final Lexer lexer, final int startOffset, boolean withinExpansion) throws OffsetLimitReachedException {
@ -971,77 +981,53 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
// we have an identifier
boolean isProblem= false;
final char[] name = ident.getCharImage();
final int type = fPPKeywords.get(name);
int condEndOffset;
switch (type) {
case IPreprocessorDirective.ppImport:
case IPreprocessorDirective.ppInclude:
if (withinExpansion) {
isProblem= true;
} else {
executeInclude(lexer, startOffset, false, true);
}
executeInclude(lexer, startOffset, false, fCurrentContext.getCodeState() == CodeState.eActive, withinExpansion);
break;
case IPreprocessorDirective.ppInclude_next:
if (withinExpansion) {
isProblem= true;
} else {
executeInclude(lexer, startOffset, true, true);
}
executeInclude(lexer, startOffset, true, fCurrentContext.getCodeState() == CodeState.eActive, withinExpansion);
break;
case IPreprocessorDirective.ppDefine:
executeDefine(lexer, startOffset);
executeDefine(lexer, startOffset, fCurrentContext.getCodeState() == CodeState.eActive);
break;
case IPreprocessorDirective.ppUndef:
executeUndefine(lexer, startOffset);
break;
case IPreprocessorDirective.ppIfdef:
executeIfdef(lexer, startOffset, true, withinExpansion);
if (executeIfdef(lexer, startOffset, false, withinExpansion) == CodeState.eSkipInactive)
skipOverConditionalCode(lexer, withinExpansion);
break;
case IPreprocessorDirective.ppIfndef:
executeIfdef(lexer, startOffset, false, withinExpansion);
if (executeIfdef(lexer, startOffset, true, withinExpansion) == CodeState.eSkipInactive)
skipOverConditionalCode(lexer, withinExpansion);
break;
case IPreprocessorDirective.ppIf:
executeIf(lexer, startOffset, withinExpansion);
break;
case IPreprocessorDirective.ppElse:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELSE)) {
fLocationMap.encounterPoundElse(startOffset, ident.getEndOffset(), false);
skipOverConditionalCode(lexer, false, withinExpansion);
}
else {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, startOffset, ident.getEndOffset());
}
if (executeIf(lexer, startOffset, false, withinExpansion) == CodeState.eSkipInactive)
skipOverConditionalCode(lexer, withinExpansion);
break;
case IPreprocessorDirective.ppElif:
int condOffset= lexer.nextToken().getOffset();
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
int endOffset= lexer.currentToken().getEndOffset();
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF)) {
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, false, IASTName.EMPTY_NAME_ARRAY);
skipOverConditionalCode(lexer, false, withinExpansion);
}
else {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, startOffset, condEndOffset);
if (executeIf(lexer, startOffset, true, withinExpansion) == CodeState.eSkipInactive) {
skipOverConditionalCode(lexer, withinExpansion);
}
break;
case IPreprocessorDirective.ppElse:
if (executeElse(lexer, startOffset, withinExpansion) == CodeState.eSkipInactive) {
skipOverConditionalCode(lexer, withinExpansion);
}
break;
case IPreprocessorDirective.ppEndif:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_END)) {
fLocationMap.encounterPoundEndIf(startOffset, ident.getEndOffset());
}
else {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, startOffset, ident.getEndOffset());
}
executeEndif(lexer, startOffset, withinExpansion);
break;
case IPreprocessorDirective.ppWarning:
case IPreprocessorDirective.ppError:
condOffset= lexer.nextToken().getOffset();
int condOffset= lexer.nextToken().getOffset();
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
int endOffset= lexer.currentToken().getEndOffset();
final char[] warning= lexer.getInputChars(condOffset, condEndOffset);
final int id= type == IPreprocessorDirective.ppError
? IProblem.PREPROCESSOR_POUND_ERROR
@ -1059,17 +1045,20 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
break;
default:
isProblem= true;
break;
}
if (isProblem) {
int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, ident.getCharImage(), startOffset, endOffset);
break;
}
}
private void executeInclude(final Lexer lexer, int poundOffset, boolean include_next, boolean active) throws OffsetLimitReachedException {
private void executeInclude(final Lexer lexer, int poundOffset, boolean include_next, boolean active, boolean withinExpansion) throws OffsetLimitReachedException {
if (withinExpansion) {
final char[] name= lexer.currentToken().getCharImage();
final int endOffset = lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, name, poundOffset, endOffset);
return;
}
lexer.setInsideIncludeDirective(true);
final Token header= lexer.nextToken();
lexer.setInsideIncludeDirective(false);
@ -1228,14 +1217,15 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
private void executeDefine(final Lexer lexer, int startOffset) throws OffsetLimitReachedException {
private void executeDefine(final Lexer lexer, int startOffset, boolean isActive) throws OffsetLimitReachedException {
try {
ObjectStyleMacro macrodef = fMacroDefinitionParser.parseMacroDefinition(lexer, this);
fMacroDictionary.put(macrodef.getNameCharArray(), macrodef);
if (isActive)
fMacroDictionary.put(macrodef.getNameCharArray(), macrodef);
final Token name= fMacroDefinitionParser.getNameToken();
fLocationMap.encounterPoundDefine(startOffset, name.getOffset(), name.getEndOffset(),
macrodef.getExpansionOffset(), macrodef.getExpansionEndOffset(), macrodef);
macrodef.getExpansionOffset(), macrodef.getExpansionEndOffset(), isActive, macrodef);
} catch (InvalidMacroDefinitionException e) {
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_INVALID_MACRO_DEFN, e.fName, e.fStartOffset, e.fEndOffset);
@ -1260,63 +1250,108 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fLocationMap.encounterPoundUndef(definition, startOffset, name.getOffset(), name.getEndOffset(), endOffset, namechars);
}
private void executeIfdef(Lexer lexer, int startOffset, boolean positive, boolean withinExpansion) throws OffsetLimitReachedException {
private CodeState executeIfdef(Lexer lexer, int offset, boolean isIfndef, boolean withinExpansion) throws OffsetLimitReachedException {
final Token name= lexer.nextToken();
final int tt= name.getType();
if (tt != IToken.tIDENTIFIER) {
if (tt == IToken.tCOMPLETION) {
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, name);
}
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_DEFINITION_NOT_FOUND, name.getCharImage(), startOffset, name.getEndOffset());
return;
}
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
final int tt= name.getType();
final int nameOffset = name.getOffset();
final int nameEndOffset = name.getEndOffset();
final int endOffset= lexer.currentToken().getEndOffset();
final char[] namechars= name.getCharImage();
PreprocessorMacro macro= fMacroDictionary.get(namechars);
boolean isActive= (macro != null) == positive;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
if (positive) {
fLocationMap.encounterPoundIfdef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive, macro);
}
else {
fLocationMap.encounterPoundIfndef(startOffset, name.getOffset(), name.getEndOffset(), endOffset, isActive, macro);
}
if ((macro == null) == positive) {
skipOverConditionalCode(lexer, true, withinExpansion);
}
boolean isActive= false;
PreprocessorMacro macro= null;
final Conditional conditional= fCurrentContext.newBranch(BranchKind.eIf, withinExpansion);
if (conditional.canHaveActiveBranch(withinExpansion)) {
// we need an identifier
if (tt != IToken.tIDENTIFIER) {
if (tt == IToken.tCOMPLETION) {
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, name);
}
// report problem and treat as inactive
handleProblem(IProblem.PREPROCESSOR_DEFINITION_NOT_FOUND, name.getCharImage(), offset, nameEndOffset);
} else {
final char[] namechars= name.getCharImage();
macro= fMacroDictionary.get(namechars);
isActive= (macro == null) == isIfndef;
}
}
if (isIfndef) {
fLocationMap.encounterPoundIfndef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro);
} else {
fLocationMap.encounterPoundIfdef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro);
}
return fCurrentContext.setBranchState(conditional, isActive, withinExpansion);
}
private void executeIf(Lexer lexer, int startOffset, boolean withinExpansion) throws OffsetLimitReachedException {
boolean isActive= false;
TokenList condition= new TokenList();
final int condOffset= lexer.nextToken().getOffset();
final int condEndOffset= getTokensWithinPPDirective(true, condition, withinExpansion);
final int endOffset= lexer.currentToken().getEndOffset();
fExpressionEvaluator.clearMacrosInDefinedExpression();
if (condition.first() == null) {
handleProblem(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR, null, startOffset, endOffset);
}
else {
try {
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
} catch (EvalException e) {
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
}
}
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, fExpressionEvaluator.clearMacrosInDefinedExpression());
private CodeState executeIf(Lexer lexer, int startOffset, boolean isElif, boolean withinExpansion) throws OffsetLimitReachedException {
Conditional cond= fCurrentContext.newBranch(isElif ? BranchKind.eElif : BranchKind.eIf, withinExpansion);
if (cond == null) {
char[] name= lexer.currentToken().getCharImage();
int condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, startOffset, condEndOffset);
return fCurrentContext.getCodeState();
}
if (!isActive) {
skipOverConditionalCode(lexer, true, withinExpansion);
}
boolean isActive= false;
IASTName[] refs= IASTName.EMPTY_NAME_ARRAY;
int condOffset= lexer.nextToken().getOffset();
int condEndOffset, endOffset;
if (cond.canHaveActiveBranch(withinExpansion)) {
TokenList condition= new TokenList();
condEndOffset= getTokensWithinPPDirective(true, condition, withinExpansion);
endOffset= lexer.currentToken().getEndOffset();
if (condition.first() == null) {
handleProblem(IProblem.SCANNER_EXPRESSION_SYNTAX_ERROR, null, startOffset, endOffset);
} else {
try {
fExpressionEvaluator.clearMacrosInDefinedExpression();
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
refs = fExpressionEvaluator.clearMacrosInDefinedExpression();
} catch (EvalException e) {
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, endOffset);
}
}
} else {
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
}
if (isElif) {
fLocationMap.encounterPoundElif(startOffset, condOffset, condEndOffset, endOffset, isActive, refs);
} else {
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, refs);
}
return fCurrentContext.setBranchState(cond, isActive, withinExpansion);
}
private CodeState executeElse(final Lexer lexer, final int startOffset,boolean withinExpansion)
throws OffsetLimitReachedException {
final int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
Conditional cond= fCurrentContext.newBranch(BranchKind.eElse, withinExpansion);
if (cond == null) {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, Keywords.cELSE, startOffset, endOffset);
return fCurrentContext.getCodeState();
}
final boolean isActive= cond.canHaveActiveBranch(withinExpansion);
fLocationMap.encounterPoundElse(startOffset, endOffset, isActive);
return fCurrentContext.setBranchState(cond, isActive, withinExpansion);
}
private CodeState executeEndif(Lexer lexer, int startOffset, boolean withinExpansion) throws OffsetLimitReachedException {
final int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
final Conditional cond= fCurrentContext.newBranch(BranchKind.eEnd, withinExpansion);
if (cond == null) {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, Keywords.cENDIF, startOffset, endOffset);
} else {
fLocationMap.encounterPoundEndIf(startOffset, endOffset);
}
return fCurrentContext.getCodeState();
}
/**
* Runs the preprocessor on the rest of the line, storing the tokens in the holder supplied.
* Macro expansion is reported to the location map.
@ -1326,6 +1361,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
*/
private int getTokensWithinPPDirective(boolean isCondition, TokenList result, boolean withinExpansion) throws OffsetLimitReachedException {
final ScannerContext scannerCtx= fCurrentContext;
scannerCtx.clearInactiveCodeMarkerToken();
int options= STOP_AT_NL;
if (isCondition)
options |= PROTECT_DEFINED;
@ -1357,135 +1393,69 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return scannerCtx.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
}
private void skipOverConditionalCode(final Lexer lexer, boolean takeElseBranch, boolean withinExpansion) throws OffsetLimitReachedException {
int nesting= 0;
while(true) {
final Token pound= lexer.nextDirective();
int tt= pound.getType();
if (tt != IToken.tPOUND) {
if (tt == IToken.tCOMPLETION) {
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, pound); // completion in inactive code
}
return;
}
final Token ident= lexer.nextToken();
tt= ident.getType();
if (tt != IToken.tIDENTIFIER) {
if (tt == IToken.tCOMPLETION) {
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, ident); // completion in inactive directive
}
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
continue;
}
// we have an identifier
final char[] name = ident.getCharImage();
final int type = fPPKeywords.get(name);
switch (type) {
case IPreprocessorDirective.ppImport:
case IPreprocessorDirective.ppInclude:
if (withinExpansion) {
int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, ident.getCharImage(), pound.getOffset(), endOffset);
} else {
executeInclude(lexer, ident.getOffset(), false, false);
}
break;
case IPreprocessorDirective.ppInclude_next:
if (withinExpansion) {
int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE, ident.getCharImage(), pound.getOffset(), endOffset);
} else {
executeInclude(lexer, ident.getOffset(), true, false);
}
break;
case IPreprocessorDirective.ppIfdef:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
int endOffset= lexer.currentToken().getEndOffset();
nesting++;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIfdef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false, null);
break;
case IPreprocessorDirective.ppIfndef:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
nesting++;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIfndef(pound.getOffset(), ident.getOffset(), ident.getEndOffset(), endOffset, false, null);
break;
case IPreprocessorDirective.ppIf:
int condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
nesting++;
fCurrentContext.changeBranch(ScannerContext.BRANCH_IF);
fLocationMap.encounterPoundIf(pound.getOffset(), ident.getOffset(), condEndOffset, endOffset, false, IASTName.EMPTY_NAME_ARRAY);
break;
case IPreprocessorDirective.ppElse:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELSE)) {
boolean isActive= nesting == 0 && takeElseBranch;
fLocationMap.encounterPoundElse(pound.getOffset(), ident.getEndOffset(), isActive);
if (isActive) {
return;
}
}
else {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, pound.getOffset(), ident.getEndOffset());
}
break;
case IPreprocessorDirective.ppElif:
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF)) {
boolean isActive= false;
fExpressionEvaluator.clearMacrosInDefinedExpression();
int condOffset= lexer.nextToken().getOffset();
if (nesting == 0 && takeElseBranch) {
TokenList condition= new TokenList();
condEndOffset= getTokensWithinPPDirective(true, condition, withinExpansion);
if (condition.first() != null) {
try {
isActive= fExpressionEvaluator.evaluate(condition, fMacroDictionary, fLocationMap);
} catch (EvalException e) {
handleProblem(e.getProblemID(), e.getProblemArg(), condOffset, condEndOffset);
}
}
}
else {
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
}
endOffset= lexer.currentToken().getEndOffset();
fCurrentContext.changeBranch(ScannerContext.BRANCH_ELIF);
fLocationMap.encounterPoundElif(pound.getOffset(), condOffset, condEndOffset, endOffset, isActive, fExpressionEvaluator.clearMacrosInDefinedExpression());
if (isActive) {
return;
}
}
else {
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
endOffset= lexer.currentToken().getEndOffset();
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, pound.getOffset(), endOffset);
}
break;
case IPreprocessorDirective.ppEndif:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
if (fCurrentContext.changeBranch(ScannerContext.BRANCH_END)) {
fLocationMap.encounterPoundEndIf(pound.getOffset(), ident.getEndOffset());
if (nesting == 0) {
return;
}
--nesting;
}
else {
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, pound.getOffset(), ident.getEndOffset());
}
break;
default:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
break;
}
}
}
private void skipOverConditionalCode(final Lexer lexer, boolean withinExpansion) throws OffsetLimitReachedException {
CodeState state= CodeState.eSkipInactive;
while (state == CodeState.eSkipInactive) {
state= skipBranch(lexer, withinExpansion);
}
}
private CodeState skipBranch(final Lexer lexer, boolean withinExpansion) throws OffsetLimitReachedException {
while(true) {
final Token pound = lexer.nextDirective();
int tt = pound.getType();
if (tt != IToken.tPOUND) {
if (tt == IToken.tCOMPLETION) {
// completion in inactive code
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, pound);
}
// must be the end of the lexer
return CodeState.eActive;
}
final Token ident = lexer.nextToken();
tt = ident.getType();
if (tt != IToken.tIDENTIFIER) {
if (tt == IToken.tCOMPLETION) {
// completion in inactive directive
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, ident);
}
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
continue;
}
// we have an identifier
final char[] name = ident.getCharImage();
final int type = fPPKeywords.get(name);
switch (type) {
case IPreprocessorDirective.ppImport:
case IPreprocessorDirective.ppInclude:
executeInclude(lexer, ident.getOffset(), false, false, withinExpansion);
break;
case IPreprocessorDirective.ppInclude_next:
executeInclude(lexer, ident.getOffset(), true, false, withinExpansion);
break;
case IPreprocessorDirective.ppDefine:
executeDefine(lexer, pound.getOffset(), false);
break;
case IPreprocessorDirective.ppIfdef:
return executeIfdef(lexer, pound.getOffset(), false, withinExpansion);
case IPreprocessorDirective.ppIfndef:
return executeIfdef(lexer, pound.getOffset(), true, withinExpansion);
case IPreprocessorDirective.ppIf:
return executeIf(lexer, pound.getOffset(), false, withinExpansion);
case IPreprocessorDirective.ppElif:
return executeIf(lexer, pound.getOffset(), true, withinExpansion);
case IPreprocessorDirective.ppElse:
return executeElse(lexer, pound.getOffset(), withinExpansion);
case IPreprocessorDirective.ppEndif:
return executeEndif(lexer, pound.getOffset(), withinExpansion);
default:
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
break;
}
}
}
/**
* The method assumes that the identifier is consumed.
* <p>

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2007, 2009 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
@ -331,7 +331,7 @@ public class LocationMap implements ILocationResolver {
}
}
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, IMacroBinding macrodef) {
public void encounterPoundDefine(int startOffset, int nameOffset, int nameEndOffset, int expansionOffset, int endOffset, boolean isActive, IMacroBinding macrodef) {
startOffset= getSequenceNumberForOffset(startOffset);
nameOffset= getSequenceNumberForOffset(nameOffset);
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
@ -339,10 +339,10 @@ public class LocationMap implements ILocationResolver {
endOffset= getSequenceNumberForOffset(endOffset);
ASTPreprocessorNode astMacro;
if (!macrodef.isFunctionStyle()) {
astMacro= new ASTMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
astMacro= new ASTMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset, isActive);
}
else {
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset, isActive);
}
fDirectives.add(astMacro);
}

View file

@ -22,17 +22,28 @@ import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
final class ScannerContext {
private static final Token END_TOKEN = new Token(IToken.tEND_OF_INPUT, null, 0, 0);
public static final Integer BRANCH_IF = new Integer(0);
public static final Integer BRANCH_ELIF = new Integer(1);
public static final Integer BRANCH_ELSE = new Integer(2);
public static final Integer BRANCH_END = new Integer(3);
enum BranchKind {eIf, eElif, eElse, eEnd}
enum CodeState {eActive, eParseInactive, eSkipInactive}
final static class Conditional {
private CodeState fInitialState;
private BranchKind fLast;
private boolean fTakeElse= true;
Conditional(CodeState state) {
fInitialState= state;
fLast= BranchKind.eIf;
}
boolean canHaveActiveBranch(boolean withinExpansion) {
return fTakeElse && (fInitialState == CodeState.eActive || withinExpansion);
}
}
private CodeState fInactiveState= CodeState.eSkipInactive;
private final ILocationCtx fLocationCtx;
private final ScannerContext fParent;
private final Lexer fLexer;
private ArrayList<Integer> fBranches= null;
private Token fTokens;
private ArrayList<Conditional> fConditionals= null;
private CodeState fCurrentState= CodeState.eActive;
/**
* @param ctx
@ -49,8 +60,13 @@ final class ScannerContext {
fParent= parent;
fLexer= null;
fTokens= tokens.first();
fInactiveState= CodeState.eSkipInactive; // no branches in result of macro expansion
}
public void setParseInactiveCode(boolean val) {
fInactiveState= val ? CodeState.eParseInactive : CodeState.eSkipInactive;
}
/**
* Returns the location context associated with this scanner context.
*/
@ -75,35 +91,115 @@ final class ScannerContext {
/**
* Needs to be called whenever we change over to another branch of conditional
* compilation. Returns whether the change is legal at this point or not.
* compilation. Returns the conditional associated with the branch or <code>null</code>,
* if the change is not legal at this point.
*/
public final boolean changeBranch(Integer branchKind) {
if (fBranches == null) {
fBranches= new ArrayList<Integer>();
public final Conditional newBranch(BranchKind branchKind, boolean withinExpansion) {
if (fConditionals == null) {
fConditionals= new ArrayList<Conditional>();
}
Conditional result;
// an if starts a new conditional construct
if (branchKind == BRANCH_IF) {
fBranches.add(branchKind);
return true;
if (branchKind == BranchKind.eIf) {
fConditionals.add(result= new Conditional(fCurrentState));
return result;
}
// if we are not inside of an conditional there shouldn't be an #else, #elsif or #end
final int pos= fBranches.size()-1;
final int pos= fConditionals.size()-1;
if (pos < 0) {
return false;
return null;
}
// an #end just pops one construct.
if (branchKind == BRANCH_END) {
fBranches.remove(pos);
return true;
// an #end just pops one construct and restores state
if (branchKind == BranchKind.eEnd) {
result= fConditionals.remove(pos);
// implicit state change
changeState(result.fInitialState, withinExpansion);
return result;
}
// #elsif or #else cannot appear after another #else
if (fBranches.get(pos) == BRANCH_ELSE) {
return false;
// #elif or #else cannot appear after another #else
result= fConditionals.get(pos);
if (result.fLast == BranchKind.eElse)
return null;
// store last kind
result.fLast= branchKind;
return result;
}
private void changeState(CodeState state, boolean withinExpansion) {
if (!withinExpansion) {
switch (state) {
case eActive:
if (fCurrentState == CodeState.eParseInactive)
stopInactive();
break;
case eParseInactive:
switch (fCurrentState) {
case eActive:
startInactive();
break;
case eParseInactive:
separateInactive();
break;
case eSkipInactive:
assert false; // in macro expansions, only.
break;
}
break;
case eSkipInactive:
// no need to report this to the parser.
break;
}
}
// overwrite #if, #elsif with #elsif or #else
fBranches.set(pos, branchKind);
return true;
fCurrentState= state;
}
private void startInactive() {
if (fTokens != null && fTokens.getType() == IToken.tINACTIVE_CODE_END) {
fTokens= new Token(IToken.tINACTIVE_CODE_SEPARATOR, null, 0, 0);
} else {
fTokens= new Token(IToken.tINACTIVE_CODE_START, null, 0, 0);
}
}
private void separateInactive() {
if (fTokens == null) {
fTokens= new Token(IToken.tINACTIVE_CODE_SEPARATOR, null, 0, 0);
}
}
private void stopInactive() {
if (fTokens != null && fTokens.getType() == IToken.tINACTIVE_CODE_START) {
fTokens= null;
} else {
fTokens= new Token(IToken.tINACTIVE_CODE_END, null, 0, 0);
}
}
public CodeState getCodeState() {
return fCurrentState;
}
/**
* The preprocessor has to inform the context about the state of if- and elif- branches
*/
public CodeState setBranchState(Conditional cond, boolean isActive, boolean withinExpansion) {
CodeState newState;
if (isActive) {
cond.fTakeElse= false;
newState= cond.fInitialState;
} else if (withinExpansion) {
newState= CodeState.eParseInactive;
} else {
newState= fInactiveState;
}
changeState(newState, withinExpansion);
return newState;
}
/**
@ -112,12 +208,12 @@ final class ScannerContext {
* @since 5.0
*/
public final Token currentLexerToken() {
if (fLexer != null) {
return fLexer.currentToken();
}
if (fTokens != null) {
return fTokens;
}
if (fLexer != null) {
return fLexer.currentToken();
}
return END_TOKEN;
}
@ -125,13 +221,14 @@ final class ScannerContext {
* Returns the next token from this context.
*/
public Token nextPPToken() throws OffsetLimitReachedException {
if (fTokens != null) {
fTokens= (Token) fTokens.getNext();
return currentLexerToken();
}
if (fLexer != null) {
return fLexer.nextToken();
}
if (fTokens != null) {
fTokens= (Token) fTokens.getNext();
}
return currentLexerToken();
return END_TOKEN;
}
/**
@ -143,4 +240,8 @@ final class ScannerContext {
return fLexer.consumeLine(originPreprocessorDirective);
return -1;
}
public void clearInactiveCodeMarkerToken() {
fTokens= null;
}
}

View file

@ -126,6 +126,7 @@ public class InactiveCodeHighlightingTest extends TestCase {
createPosition(28, 33),
createPosition(39, 41),
createPosition(47, 57),
createPosition(63, 65),
createPosition(67, 69),
createPosition(73, 75),
};

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* Copyright (c) 2005, 2009 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
@ -38,6 +38,7 @@ import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.IIncludeReference;
import org.eclipse.cdt.core.model.ILibraryReference;
import org.eclipse.cdt.core.model.IMethodDeclaration;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITemplate;
import org.eclipse.cdt.core.model.ITranslationUnit;
@ -457,12 +458,18 @@ public class CElementImageProvider {
if(element instanceof ITemplate){
flags |= CElementImageDescriptor.TEMPLATE;
}
} else if (element instanceof IInclude) {
IInclude include= (IInclude) element;
if (!include.isActive()) {
}
if (element instanceof ISourceReference) {
ISourceReference sref= (ISourceReference) element;
if (!sref.isActive()) {
flags |= CElementImageDescriptor.INACTIVE;
} else if (!include.isResolved()) {
flags |= CElementImageDescriptor.WARNING;
} else {
if (element instanceof IInclude) {
IInclude include= (IInclude) element;
if (!include.isResolved()) {
flags |= CElementImageDescriptor.WARNING;
}
}
}
}
} catch (CModelException e) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* Copyright (c) 2000, 2009 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
@ -23,7 +23,7 @@ import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.util.CElementBaseLabels;
import org.eclipse.cdt.ui.CUIPlugin;
@ -235,9 +235,9 @@ public class CUILabelProvider extends LabelProvider implements IColorProvider {
* @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
*/
public Color getForeground(Object element) {
if (element instanceof IInclude) {
IInclude include= (IInclude)element;
if (!include.isActive()) {
if (element instanceof ISourceReference) {
ISourceReference sref= (ISourceReference)element;
if (!sref.isActive()) {
if (fInactiveColor == null && Display.getCurrent() != null) {
fInactiveColor= CUIPlugin.getStandardDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
fDefaultColor= CUIPlugin.getStandardDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND);