1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Victor Mozgin.

Fixes problem with offsets of elements that were created as macro expansions (PR 36463).
This commit is contained in:
John Camelon 2003-06-20 17:16:05 +00:00
parent 35a76e8822
commit 4347f9b681
15 changed files with 279 additions and 30 deletions

View file

@ -1,3 +1,7 @@
2003-06-17 Victor Mozgin
Added MacroTests.java (invocation in AllCoreTests).
Added MacroTests.c to resources.
2003-06-17 Brent Nicolle
Added Interface tests of IStructure.java.

View file

@ -0,0 +1,113 @@
/*
* Created on Jun 9, 2003
* by bnicolle
*/
package org.eclipse.cdt.core.model.tests;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.model.CElement;
import junit.framework.*;
import java.util.Stack;
/**
* @author bnicolle
*
*/
public class MacroTests extends IntegratedCModelTest {
/**
* @param name
*/
public MacroTests(String name) {
super(name);
}
/**
* @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest
*/
public String getSourcefileSubdir() {
return "resources/cmodel/";
}
/**
* @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest
*/
public String getSourcefileResource() {
return "MacroTests.c";
}
/**
* @returns a test suite named after this class
* containing all its public members named "test*"
*/
public static Test suite() {
TestSuite suite= new TestSuite(MacroTests.class);
return suite;
}
/* This is a list of elements in the test .c file. It will be used
* in a number of places in the tests
*/
String[] expectedStringList= {"Z", "X", "Y",
"SomeName", "", "A::BCD", "DEFA", "DB", "B::SomeName",
"PINT", "myPINT", "foobar"};
int[] expectedOffsets={ 8,26,39,55,75,89,114,130,152,187,212,227};
int[] expectedLengths={ 1, 1, 1, 1, 1, 8, 4, 2, 18, 4, 6, 6};
/* This is a list of that the types of the above list of elements is
* expected to be.
*/
int[] expectedTypes= { ICElement.C_MACRO, ICElement.C_MACRO,
ICElement.C_MACRO, ICElement.C_STRUCT,
ICElement.C_STRUCT, ICElement.C_VARIABLE, ICElement.C_MACRO,
ICElement.C_MACRO, ICElement.C_VARIABLE, ICElement.C_MACRO,
ICElement.C_VARIABLE, ICElement.C_FUNCTION_DECLARATION};
public void testMacro_0001() throws CModelException {
ITranslationUnit myTranslationUnit = getTU();
ICElement myElement;
Stack missing=new Stack();
int x;
for (x=0;x<expectedStringList.length;x++) {
myElement=myTranslationUnit.getElement(expectedStringList[x]);
if (myElement==null)
missing.push(expectedStringList[x]);
else {
assertTrue("Expected:" + expectedStringList[x] + " Got:" + myElement.getElementName(),
expectedStringList[x].equals(myElement.getElementName()));
assertTrue("Expected type for '" + expectedStringList[x] + "':" + expectedTypes[x] + " Got:" + myElement.getElementType(),
expectedTypes[x] == myElement.getElementType());
int offset = -1;
int length = -1;
if (myElement instanceof CElement) {
CElement elem = (CElement)myElement;
offset = elem.getIdStartPos();
length = elem.getIdLength();
}
assertTrue("Expected offset for '" + expectedStringList[x] + "':" + expectedOffsets[x] + " Got:" + offset,
expectedOffsets[x] == offset);
assertTrue("Expected length for '" + expectedStringList[x] + "':" + expectedLengths[x] + " Got:" + length,
expectedLengths[x] == length);
}
}
if (!missing.empty()) {
String output=new String("Could not get elements: ");
while (!missing.empty())
output+=missing.pop() + " ";
assertTrue(output, false);
}
}
}

View file

@ -15,6 +15,7 @@ import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.model.tests.CModelElementsTests;
import org.eclipse.cdt.core.model.tests.MacroTests;
/**
* @author jcamelon
@ -31,6 +32,7 @@ public class ParserTestSuite extends TestCase {
suite.addTestSuite(DOMTests.class);
suite.addTestSuite(ParserSymbolTableTest.class);
suite.addTestSuite(CModelElementsTests.class);
suite.addTestSuite(MacroTests.class);
return suite;
}

View file

@ -723,10 +723,10 @@ public class ScannerTestCase extends BaseScannerTest
assertNotNull(parms);
assertTrue(expansion.size() == 3);
assertTrue(((Token) expansion.get(0)).type == IToken.tIDENTIFIER);
assertTrue(((Token) expansion.get(0)).image.equals("x"));
assertTrue(((Token) expansion.get(0)).getImage().equals("x"));
assertTrue(((Token) expansion.get(1)).type == IToken.tPLUS);
assertTrue(((Token) expansion.get(2)).type == IToken.tINTEGER);
assertTrue(((Token) expansion.get(2)).image.equals("1"));
assertTrue(((Token) expansion.get(2)).getImage().equals("1"));
validateIdentifier("y");
validateToken(IToken.tASSIGN);

View file

@ -0,0 +1,24 @@
#define Z struct
#define X Z
#define Y SomeName
X Y
{
};
X{
};
int A :: BCD = 1;
#define DEFA B
#define DB( x ) x
int DEFA :: DB(Y) = 1;
#define PINT const int *
PINT myPINT;
PINT foobar( void );

View file

@ -26,12 +26,12 @@ public class Name {
public int getStartOffset()
{
return nameStart.offset;
return nameStart.getOffset();
}
public int getEndOffset()
{
return nameEnd.offset;
return nameEnd.getOffset();
}
public String toString() {
@ -53,7 +53,7 @@ public class Name {
public int length()
{
return getEndOffset() - getStartOffset() + nameEnd.getImage().length();
return getEndOffset() - getStartOffset() + nameEnd.getLength();
}
/**
* @return

View file

@ -1,3 +1,6 @@
2003-06-20 Victor Mozgin
Fixed PR 36463 : Offsets of macros are incorrect.
2003-06-17 Victor Mozgin
Implemented correct handling of nested declarators in CModelBuilder.
Added proper support for function pointers as parameters.

View file

@ -19,10 +19,43 @@ public interface IScannerContext {
public static int INCLUSION = 2;
public static int MACROEXPANSION = 3;
/**
* This initializer is used for scanner contexts which are macro expansions.
*
* @param macroOffset Offset of the expanding macro
* @param macroLength Length of the macro identifier
* @return
*/
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i, int macroOffset, int macroLength);
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i);
public int read() throws IOException;
public String getFilename();
/**
* Returns macro offset (the offset of the top expanded macro).
* @return int
*/
public int getMacroOffset();
/**
* Returns macro length (the length of the top expanded macro identifier).
* @return int
*/
public int getMacroLength();
/**
* Returns the offset.
* @return int
*/
public int getOffset();
/**
* Returns relative offset (relative to the beginning of the ScannerContext).
* @return int
*/
public int getRelativeOffset();
public Reader getReader();
public int undoStackSize();

View file

@ -37,8 +37,22 @@ public class ContextStack {
}
public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor) throws ScannerException {
updateContext(reader, filename, type, inclusion, requestor, -1, -1);
}
public void updateContext(Reader reader, String filename, int type, IASTInclusion inclusion, ISourceElementRequestor requestor, int macroOffset, int macroLength) throws ScannerException
{
// If we expand a macro within a macro, then keep offsets of the top-level one,
// as only the top level macro identifier is properly positioned
if (type == IScannerContext.MACROEXPANSION) {
if (currentContext.getKind() == IScannerContext.MACROEXPANSION) {
macroOffset = currentContext.getMacroOffset();
macroLength = currentContext.getMacroLength();
}
}
undoStack.clear();
push( new ScannerContext().initialize(reader, filename, type, null ), requestor );
push( new ScannerContext().initialize(reader, filename, type, null, macroOffset, macroLength ), requestor );
}
protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ScannerException

View file

@ -59,7 +59,7 @@ public class Name {
public int length()
{
return getEndOffset() - getStartOffset() + nameEnd.getImage().length();
return getEndOffset() - getStartOffset() + nameEnd.getLength();
}
/**
* @return

View file

@ -604,6 +604,8 @@ public class Scanner implements IScanner {
((c >= 'a') && (c <= 'z'))
|| ((c >= 'A') && (c <= 'Z')) | (c == '_')) {
int baseOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
if( madeMistake ) madeMistake = false;
// String buffer is slow, we need a better way such as memory mapped files
StringBuffer buff = new StringBuffer();
@ -630,7 +632,7 @@ public class Scanner implements IScanner {
if (mapping != null) {
if( contextStack.shouldExpandDefinition( POUND_DEFINE + ident ) ) {
expandDefinition(ident, mapping);
expandDefinition(ident, mapping, baseOffset);
c = getChar();
continue;
}
@ -2023,11 +2025,14 @@ public class Scanner implements IScanner {
return parameterValues;
}
protected void expandDefinition(String symbol, Object expansion)
throws ScannerException {
protected void expandDefinition(String symbol, Object expansion, int symbolOffset)
throws ScannerException
{
// All the tokens generated by the macro expansion
// will have dimensions (offset and length) equal to the expanding symbol.
if (expansion instanceof String ) {
String replacementValue = (String) expansion;
contextStack.updateContext( new StringReader(replacementValue), (POUND_DEFINE + symbol ), ScannerContext.MACROEXPANSION, null, requestor );
contextStack.updateContext( new StringReader(replacementValue), (POUND_DEFINE + symbol ), ScannerContext.MACROEXPANSION, null, requestor, symbolOffset, symbol.length());
} else if (expansion instanceof IMacroDescriptor ) {
IMacroDescriptor macro = (IMacroDescriptor) expansion;
skipOverWhitespace();
@ -2050,6 +2055,9 @@ public class Scanner implements IScanner {
c = getChar( true );
}
// Position of the closing ')'
int endMacroOffset = lastContext.getOffset() - lastContext.undoStackSize() - 1;
String betweenTheBrackets = buffer.toString().trim();
Vector parameterValues = getMacroParameters(betweenTheBrackets, false);
@ -2144,7 +2152,7 @@ public class Scanner implements IScanner {
String finalString = buffer.toString();
contextStack.updateContext(
new StringReader(finalString),
POUND_DEFINE + macro.getSignature(), ScannerContext.MACROEXPANSION, null, requestor );
POUND_DEFINE + macro.getSignature(), ScannerContext.MACROEXPANSION, null, requestor, symbolOffset, endMacroOffset - symbolOffset + 1 );
} else
if (throwExceptionOnBadMacroExpansion)
throw new ScannerException(

View file

@ -21,21 +21,37 @@ public class ScannerContext implements IScannerContext
{
private Reader reader;
private String filename;
private int macroOffset = -1;
private int macroLength = -1;
private int offset;
private Stack undo = new Stack();
private int kind;
public ScannerContext(){}
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i)
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion, int, int)
*/
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i, int mO, int mL)
{
reader = r;
filename = f;
offset = 0;
kind = k;
inc = i;
macroOffset = mO;
macroLength = mL;
return this;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#initialize(Reader, String, int, IASTInclusion)
*/
public IScannerContext initialize(Reader r, String f, int k, IASTInclusion i)
{
return initialize(r, f, k, i, -1, -1);
}
public int read() throws IOException {
++offset;
return reader.read();
@ -50,11 +66,36 @@ public class ScannerContext implements IScannerContext
return filename;
}
/**
* Returns the offset.
* @return int
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getExtension()
*/
public final int getMacroOffset()
{
return macroOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getMacroLength()
*/
public final int getMacroLength()
{
return macroLength;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getOffset()
*/
public final int getOffset()
{
// All the tokens generated by the macro expansion
// will have dimensions (offset and length) equal to the expanding symbol.
return (macroOffset < 0) ? offset : macroOffset;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.IScannerContext#getRelativeOffset()
*/
public final int getRelativeOffset()
{
return offset;
}

View file

@ -20,6 +20,8 @@ public class Token implements IToken {
image = i;
filename = context.getFilename();
offset = context.getOffset() - image.length() - context.undoStackSize();
macroOffset = context.getMacroOffset();
macroLength = context.getMacroLength();
if( type == tLSTRING || type == tSTRING || type == tCHAR ){
offset--;
@ -39,13 +41,18 @@ public class Token implements IToken {
public int type;
public int getType() { return type; }
public String image;
protected String image;
public String getImage() { return image; }
public String filename;
public int offset;
public int getOffset() { return offset; }
public int getLength() { return image.length(); }
protected int offset;
protected int macroOffset = -1;
protected int macroLength = -1;
// All the tokens generated by the macro expansion
// will have dimensions (offset and length) equal to the expanding symbol.
public int getOffset() { return (macroOffset < 0) ? offset : macroOffset; }
public int getLength() { return (macroLength < 0) ? image.length() : macroLength; }
public int getEndOffset() { return getOffset() + getLength(); }

View file

@ -723,10 +723,10 @@ public class ScannerTestCase extends BaseScannerTest
assertNotNull(parms);
assertTrue(expansion.size() == 3);
assertTrue(((Token) expansion.get(0)).type == IToken.tIDENTIFIER);
assertTrue(((Token) expansion.get(0)).image.equals("x"));
assertTrue(((Token) expansion.get(0)).getImage().equals("x"));
assertTrue(((Token) expansion.get(1)).type == IToken.tPLUS);
assertTrue(((Token) expansion.get(2)).type == IToken.tINTEGER);
assertTrue(((Token) expansion.get(2)).image.equals("1"));
assertTrue(((Token) expansion.get(2)).getImage().equals("1"));
validateIdentifier("y");
validateToken(IToken.tASSIGN);