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 2003-06-17 Brent Nicolle
Added Interface tests of IStructure.java. 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 junit.framework.TestSuite;
import org.eclipse.cdt.core.model.tests.CModelElementsTests; import org.eclipse.cdt.core.model.tests.CModelElementsTests;
import org.eclipse.cdt.core.model.tests.MacroTests;
/** /**
* @author jcamelon * @author jcamelon
@ -31,6 +32,7 @@ public class ParserTestSuite extends TestCase {
suite.addTestSuite(DOMTests.class); suite.addTestSuite(DOMTests.class);
suite.addTestSuite(ParserSymbolTableTest.class); suite.addTestSuite(ParserSymbolTableTest.class);
suite.addTestSuite(CModelElementsTests.class); suite.addTestSuite(CModelElementsTests.class);
suite.addTestSuite(MacroTests.class);
return suite; return suite;
} }

View file

@ -723,10 +723,10 @@ public class ScannerTestCase extends BaseScannerTest
assertNotNull(parms); assertNotNull(parms);
assertTrue(expansion.size() == 3); assertTrue(expansion.size() == 3);
assertTrue(((Token) expansion.get(0)).type == IToken.tIDENTIFIER); 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(1)).type == IToken.tPLUS);
assertTrue(((Token) expansion.get(2)).type == IToken.tINTEGER); 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"); validateIdentifier("y");
validateToken(IToken.tASSIGN); 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() public int getStartOffset()
{ {
return nameStart.offset; return nameStart.getOffset();
} }
public int getEndOffset() public int getEndOffset()
{ {
return nameEnd.offset; return nameEnd.getOffset();
} }
public String toString() { public String toString() {
@ -53,7 +53,7 @@ public class Name {
public int length() public int length()
{ {
return getEndOffset() - getStartOffset() + nameEnd.getImage().length(); return getEndOffset() - getStartOffset() + nameEnd.getLength();
} }
/** /**
* @return * @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 2003-06-17 Victor Mozgin
Implemented correct handling of nested declarators in CModelBuilder. Implemented correct handling of nested declarators in CModelBuilder.
Added proper support for function pointers as parameters. 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 INCLUSION = 2;
public static int MACROEXPANSION = 3; 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 IScannerContext initialize(Reader r, String f, int k, IASTInclusion i);
public int read() throws IOException; public int read() throws IOException;
public String getFilename(); 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(); public int getOffset();
/**
* Returns relative offset (relative to the beginning of the ScannerContext).
* @return int
*/
public int getRelativeOffset();
public Reader getReader(); public Reader getReader();
public int undoStackSize(); 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 { 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(); 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 protected void push( IScannerContext context, ISourceElementRequestor requestor ) throws ScannerException

View file

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

View file

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

View file

@ -21,21 +21,37 @@ public class ScannerContext implements IScannerContext
{ {
private Reader reader; private Reader reader;
private String filename; private String filename;
private int macroOffset = -1;
private int macroLength = -1;
private int offset; private int offset;
private Stack undo = new Stack(); private Stack undo = new Stack();
private int kind; private int kind;
public ScannerContext(){} 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; reader = r;
filename = f; filename = f;
offset = 0; offset = 0;
kind = k; kind = k;
inc = i; inc = i;
macroOffset = mO;
macroLength = mL;
return this; 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 { public int read() throws IOException {
++offset; ++offset;
return reader.read(); return reader.read();
@ -50,11 +66,36 @@ public class ScannerContext implements IScannerContext
return filename; return filename;
} }
/** /* (non-Javadoc)
* Returns the offset. * @see org.eclipse.cdt.internal.core.parser.IScannerContext#getExtension()
* @return int */
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() 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; return offset;
} }

View file

@ -20,6 +20,8 @@ public class Token implements IToken {
image = i; image = i;
filename = context.getFilename(); filename = context.getFilename();
offset = context.getOffset() - image.length() - context.undoStackSize(); offset = context.getOffset() - image.length() - context.undoStackSize();
macroOffset = context.getMacroOffset();
macroLength = context.getMacroLength();
if( type == tLSTRING || type == tSTRING || type == tCHAR ){ if( type == tLSTRING || type == tSTRING || type == tCHAR ){
offset--; offset--;
@ -39,13 +41,18 @@ public class Token implements IToken {
public int type; public int type;
public int getType() { return type; } public int getType() { return type; }
public String image; protected String image;
public String getImage() { return image; } public String getImage() { return image; }
public String filename; public String filename;
public int offset;
public int getOffset() { return offset; } protected int offset;
public int getLength() { return image.length(); } 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(); } public int getEndOffset() { return getOffset() + getLength(); }

View file

@ -723,10 +723,10 @@ public class ScannerTestCase extends BaseScannerTest
assertNotNull(parms); assertNotNull(parms);
assertTrue(expansion.size() == 3); assertTrue(expansion.size() == 3);
assertTrue(((Token) expansion.get(0)).type == IToken.tIDENTIFIER); 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(1)).type == IToken.tPLUS);
assertTrue(((Token) expansion.get(2)).type == IToken.tINTEGER); 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"); validateIdentifier("y");
validateToken(IToken.tASSIGN); validateToken(IToken.tASSIGN);