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:
parent
251c37e865
commit
5008c01caf
32 changed files with 1189 additions and 669 deletions
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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]);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#if 0
|
||||
#include "include"
|
||||
#define MACRO1 1
|
||||
#define MACRO2(x, y) x+y
|
||||
#endif
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue