mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 362148: Support for __COUNTER__ macro.
This commit is contained in:
parent
09874c7c09
commit
058e14d32c
5 changed files with 88 additions and 11 deletions
|
@ -354,4 +354,13 @@ public class PreprocessorBugsTests extends PreprocessorTestsBase {
|
|||
validateIdentifier("B");
|
||||
validateProblemCount(0);
|
||||
}
|
||||
|
||||
// __COUNTER__
|
||||
// __COUNTER__
|
||||
public void testCounter_Bug362148() throws Exception {
|
||||
initializeScanner();
|
||||
validateInteger("0");
|
||||
validateInteger("1");
|
||||
validateProblemCount(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
private static final DynamicMacro __DATE__= new DateMacro("__DATE__".toCharArray()); //$NON-NLS-1$
|
||||
private static final DynamicMacro __TIME__ = new TimeMacro("__TIME__".toCharArray()); //$NON-NLS-1$
|
||||
private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
|
||||
private static final char[] __COUNTER__ = "__COUNTER__".toCharArray(); //$NON-NLS-1$
|
||||
private static final char[] ONCE = "once".toCharArray(); //$NON-NLS-1$
|
||||
|
||||
static final int NO_EXPANSION = 0x01;
|
||||
|
@ -114,18 +115,22 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
|
||||
|
||||
private final class MacroDictionary implements IMacroDictionary, ISignificantMacros.IVisitor {
|
||||
@Override
|
||||
public boolean satisfies(ISignificantMacros significantMacros) {
|
||||
return significantMacros.accept(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitDefined(char[] macro) {
|
||||
return isDefined(macro);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitUndefined(char[] macro) {
|
||||
return !isDefined(macro);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean visitValue(char[] macro, char[] value) {
|
||||
PreprocessorMacro m = fMacroDictionary.get(macro);
|
||||
return m != null && CharArrayUtils.equals(m.getExpansion(), value);
|
||||
|
@ -141,7 +146,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
|
||||
final private IIncludeFileTester<InternalFileContent> createCodeReaderTester= new IIncludeFileTester<InternalFileContent>() {
|
||||
public InternalFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||
@Override
|
||||
public InternalFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||
final InternalFileContent fc;
|
||||
IFileNomination once= fFileContentProvider.isIncludedWithPragmaOnceSemantics(path);
|
||||
if (once != null) {
|
||||
|
@ -163,7 +169,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
|
||||
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
||||
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||
@Override
|
||||
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||
if (fFileContentProvider.getInclusionExists(path)) {
|
||||
IncludeResolution res= new IncludeResolution();
|
||||
res.fHeuristic= isHeuristicMatch;
|
||||
|
@ -181,6 +188,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
fStopAtNewline= stopAtNewline;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token nextToken() throws OffsetLimitReachedException {
|
||||
final Lexer lexer= fCurrentContext.getLexer();
|
||||
Token t= lexer.nextToken();
|
||||
|
@ -194,10 +202,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLastEndOffset() {
|
||||
return fCurrentContext.getLexer().getLastEndOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token currentToken() {
|
||||
Token t= fCurrentContext.currentLexerToken();
|
||||
if (fStopAtNewline && t.getType() == Lexer.tNEWLINE)
|
||||
|
@ -323,14 +333,17 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSplitShiftROperator(boolean val) {
|
||||
fSplitShiftRightOperator= val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComputeImageLocations(boolean val) {
|
||||
fLexOptions.fCreateImageLocations= val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentAssistMode(int offset) {
|
||||
fContentAssistLimit= offset;
|
||||
fRootLexer.setContentAssistMode(offset);
|
||||
|
@ -340,13 +353,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return fRootLexer.isContentAssistMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessInactiveCode(boolean val) {
|
||||
fRootContext.setParseInactiveCode(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScanComments(boolean val) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILocationResolver getLocationResolver() {
|
||||
return fLocationMap;
|
||||
}
|
||||
|
@ -413,7 +429,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
fMacroDictionary.put(__DATE__.getNameCharArray(), __DATE__);
|
||||
fMacroDictionary.put(__TIME__.getNameCharArray(), __TIME__);
|
||||
fMacroDictionary.put(__LINE__.getNameCharArray(), __LINE__);
|
||||
|
||||
fMacroDictionary.put(__COUNTER__, new CounterMacro(__COUNTER__));
|
||||
|
||||
if (lang == ParserLanguage.CPP) {
|
||||
fMacroDictionary.put(__cplusplus.getNameCharArray(), __cplusplus);
|
||||
} else {
|
||||
|
@ -520,7 +537,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
}
|
||||
|
||||
public Map<String, IMacroBinding> getMacroDefinitions() {
|
||||
@Override
|
||||
public Map<String, IMacroBinding> getMacroDefinitions() {
|
||||
Map<String, IMacroBinding> hashMap = new HashMap<String, IMacroBinding>(fMacroDictionary.size());
|
||||
for (char[] key : fMacroDictionary.keys()) {
|
||||
hashMap.put(String.valueOf(key), fMacroDictionary.get(key));
|
||||
|
@ -528,7 +546,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return hashMap;
|
||||
}
|
||||
|
||||
public boolean isOnTopContext() {
|
||||
@Override
|
||||
public boolean isOnTopContext() {
|
||||
ScannerContext ctx= fCurrentContext;
|
||||
while (ctx != null && ctx.getLocationCtx() instanceof LocationCtxMacroExpansion) {
|
||||
ctx= ctx.getParent();
|
||||
|
@ -536,7 +555,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return ctx == fRootContext;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
isCancelled= true;
|
||||
}
|
||||
|
||||
|
@ -648,7 +668,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
* @throws EndOfFileException when the end of the translation unit has been reached.
|
||||
* @throws OffsetLimitReachedException see {@link Lexer}.
|
||||
*/
|
||||
public IToken nextToken() throws EndOfFileException {
|
||||
@Override
|
||||
public IToken nextToken() throws EndOfFileException {
|
||||
if (isCancelled) {
|
||||
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
||||
}
|
||||
|
@ -746,7 +767,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return t1;
|
||||
}
|
||||
|
||||
public void skipInactiveCode() throws OffsetLimitReachedException {
|
||||
@Override
|
||||
public void skipInactiveCode() throws OffsetLimitReachedException {
|
||||
final Lexer lexer= fCurrentContext.getLexer();
|
||||
if (lexer != null) {
|
||||
CodeState state= fCurrentContext.getCodeState();
|
||||
|
@ -758,6 +780,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getCodeBranchNesting() {
|
||||
return fCurrentContext.getCodeBranchNesting();
|
||||
}
|
||||
|
@ -1142,11 +1165,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return fLocationMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleComment(boolean isBlockComment, int offset, int endOffset) {
|
||||
fLocationMap.encounteredComment(offset, endOffset, isBlockComment);
|
||||
}
|
||||
|
||||
public void handleProblem(int id, char[] arg, int offset, int endOffset) {
|
||||
@Override
|
||||
public void handleProblem(int id, char[] arg, int offset, int endOffset) {
|
||||
fLocationMap.encounterProblem(id, arg, offset, endOffset);
|
||||
}
|
||||
|
||||
|
@ -1856,6 +1881,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public Object getAdapter(Class adapter) {
|
||||
if (adapter.isAssignableFrom(fMacroExpander.getClass())) {
|
||||
|
|
|
@ -12,8 +12,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
|
|||
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.ibm.icu.text.DateFormatSymbols;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ILinkage;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||
|
@ -24,6 +22,8 @@ import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
|||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||
|
||||
import com.ibm.icu.text.DateFormatSymbols;
|
||||
|
||||
/**
|
||||
* Models macros used by the preprocessor
|
||||
* @since 5.0
|
||||
|
@ -35,38 +35,47 @@ abstract class PreprocessorMacro implements IMacroBinding {
|
|||
fName= name;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public ILinkage getLinkage() {
|
||||
return Linkage.NO_LINKAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public char[] getNameCharArray() {
|
||||
return fName;
|
||||
}
|
||||
|
||||
@Override
|
||||
final public String getName() {
|
||||
return new String(fName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScope getScope() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding getOwner() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFunctionStyle() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getParameterList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getParameterPlaceholderList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("rawtypes")
|
||||
public Object getAdapter(Class clazz) {
|
||||
return null;
|
||||
|
@ -139,10 +148,12 @@ class ObjectStyleMacro extends PreprocessorMacro {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansion() {
|
||||
return MacroDefinitionParser.getExpansion(fExpansion, fExpansionOffset, fEndOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
final int length = fEndOffset - fExpansionOffset;
|
||||
char[] result= new char[length];
|
||||
|
@ -164,6 +175,7 @@ class ObjectStyleMacro extends PreprocessorMacro {
|
|||
return fExpansionTokens;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDynamic() {
|
||||
return false;
|
||||
}
|
||||
|
@ -283,14 +295,17 @@ final class UndefinedMacro extends PreprocessorMacro {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return false;
|
||||
}
|
||||
|
@ -301,6 +316,7 @@ abstract class DynamicMacro extends PreprocessorMacro {
|
|||
public DynamicMacro(char[] name) {
|
||||
super(name);
|
||||
}
|
||||
@Override
|
||||
public final char[] getExpansion() {
|
||||
return getExpansionImage();
|
||||
}
|
||||
|
@ -319,6 +335,7 @@ abstract class DynamicMacro extends PreprocessorMacro {
|
|||
buffer.append(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isDynamic() {
|
||||
return true;
|
||||
}
|
||||
|
@ -349,6 +366,7 @@ final class DateMacro extends DynamicMacro {
|
|||
return charArray;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
return createDate();
|
||||
}
|
||||
|
@ -367,6 +385,7 @@ final class FileMacro extends DynamicMacro {
|
|||
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
return "\"file\"".toCharArray(); //$NON-NLS-1$
|
||||
}
|
||||
|
@ -383,6 +402,7 @@ final class LineMacro extends DynamicMacro {
|
|||
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
return new char[] {'1'};
|
||||
}
|
||||
|
@ -410,7 +430,27 @@ final class TimeMacro extends DynamicMacro {
|
|||
return buffer.toString().toCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
return createDate();
|
||||
}
|
||||
}
|
||||
|
||||
final class CounterMacro extends DynamicMacro {
|
||||
private static final char[] ZERO = {'0'};
|
||||
|
||||
private long fValue= 0;
|
||||
CounterMacro(char[] name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Token execute(MacroExpander expander) {
|
||||
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, String.valueOf(fValue++).toCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getExpansionImage() {
|
||||
return ZERO;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ public class CompletionTest_MacroRef_NoPrefix extends CompletionProposalsBaseTe
|
|||
"DEBUG",
|
||||
"XMacro(x, y)",
|
||||
"__CDT_PARSER__",
|
||||
"__COUNTER__",
|
||||
"__DATE__",
|
||||
"__FILE__",
|
||||
"__LINE__",
|
||||
|
|
|
@ -358,6 +358,7 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest {
|
|||
"DEBUG",
|
||||
"XMacro(x, y)",
|
||||
"__CDT_PARSER__",
|
||||
"__COUNTER__",
|
||||
"__DATE__",
|
||||
"__FILE__",
|
||||
"__LINE__",
|
||||
|
|
Loading…
Add table
Reference in a new issue