mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 17:55:39 +02:00
Bug 286081.
This commit is contained in:
parent
4b2dc9b25f
commit
44d46d0b79
1 changed files with 120 additions and 111 deletions
|
@ -55,7 +55,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.ScannerContext.Conditional;
|
||||||
import org.eclipse.core.runtime.IAdaptable;
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C-Preprocessor providing tokens for the parsers. The class should not be used directly, rather than that
|
* C-Preprocessor providing tokens for the parsers. The class should not be used directly, rather than that
|
||||||
* you should be using the {@link IScanner} interface.
|
* you should be using the {@link IScanner} interface.
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
|
@ -98,7 +98,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
T checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath);
|
T checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
|
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
|
||||||
public IncludeFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
public IncludeFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||||
final IncludeFileContent fc= fCodeReaderFactory.getContentForInclusion(path);
|
final IncludeFileContent fc= fCodeReaderFactory.getContentForInclusion(path);
|
||||||
if (fc != null) {
|
if (fc != null) {
|
||||||
|
@ -108,9 +108,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return fc;
|
return fc;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static class IncludeResolution {String fLocation; boolean fHeuristic;}
|
private static class IncludeResolution {String fLocation; boolean fHeuristic;}
|
||||||
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
||||||
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||||
if (fCodeReaderFactory.getInclusionExists(path)) {
|
if (fCodeReaderFactory.getInclusionExists(path)) {
|
||||||
IncludeResolution res= new IncludeResolution();
|
IncludeResolution res= new IncludeResolution();
|
||||||
|
@ -215,7 +215,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
final String filePath= new String(reader.filename);
|
final String filePath= new String(reader.filename);
|
||||||
configureIncludeSearchPath(new File(filePath).getParentFile(), info);
|
configureIncludeSearchPath(new File(filePath).getParentFile(), info);
|
||||||
setupMacroDictionary(configuration, info, language);
|
setupMacroDictionary(configuration, info, language);
|
||||||
|
|
||||||
fAllIncludedFiles.add(filePath);
|
fAllIncludedFiles.add(filePath);
|
||||||
ILocationCtx ctx= fLocationMap.pushTranslationUnit(filePath, reader.buffer);
|
ILocationCtx ctx= fLocationMap.pushTranslationUnit(filePath, reader.buffer);
|
||||||
fCodeReaderFactory.reportTranslationUnitFile(filePath);
|
fCodeReaderFactory.reportTranslationUnitFile(filePath);
|
||||||
|
@ -227,7 +227,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fPreIncludedFiles= new String[][] {einfo.getMacroFiles(), einfo.getIncludeFiles()};
|
fPreIncludedFiles= new String[][] {einfo.getMacroFiles(), einfo.getIncludeFiles()};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IIndexBasedCodeReaderFactory wrapReaderFactory(final ICodeReaderFactory readerFactory) {
|
private IIndexBasedCodeReaderFactory wrapReaderFactory(final ICodeReaderFactory readerFactory) {
|
||||||
if (readerFactory instanceof IIndexBasedCodeReaderFactory) {
|
if (readerFactory instanceof IIndexBasedCodeReaderFactory) {
|
||||||
return (IIndexBasedCodeReaderFactory) readerFactory;
|
return (IIndexBasedCodeReaderFactory) readerFactory;
|
||||||
|
@ -270,7 +270,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
public void setComputeImageLocations(boolean val) {
|
public void setComputeImageLocations(boolean val) {
|
||||||
fLexOptions.fCreateImageLocations= val;
|
fLexOptions.fCreateImageLocations= val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContentAssistMode(int offset) {
|
public void setContentAssistMode(int offset) {
|
||||||
fContentAssistLimit= offset;
|
fContentAssistLimit= offset;
|
||||||
fRootLexer.setContentAssistMode(offset);
|
fRootLexer.setContentAssistMode(offset);
|
||||||
|
@ -291,8 +291,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
Keywords.addKeywordsPreprocessor(fPPKeywords);
|
Keywords.addKeywordsPreprocessor(fPPKeywords);
|
||||||
if (language == ParserLanguage.C) {
|
if (language == ParserLanguage.C) {
|
||||||
Keywords.addKeywordsC(fKeywords);
|
Keywords.addKeywordsC(fKeywords);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Keywords.addKeywordsCpp(fKeywords);
|
Keywords.addKeywordsCpp(fKeywords);
|
||||||
}
|
}
|
||||||
CharArrayIntMap additionalKeywords= configuration.getAdditionalKeywords();
|
CharArrayIntMap additionalKeywords= configuration.getAdditionalKeywords();
|
||||||
|
@ -324,7 +323,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
for (String qip : quoteIncludeSearchPath) {
|
for (String qip : quoteIncludeSearchPath) {
|
||||||
fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, qip), true);
|
fIncludeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, qip), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fIncludeSearchPath == null) {
|
if (fIncludeSearchPath == null) {
|
||||||
fIncludeSearchPath= new IncludeSearchPathElement[searchPath.length];
|
fIncludeSearchPath= new IncludeSearchPathElement[searchPath.length];
|
||||||
|
@ -350,20 +349,20 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fMacroDictionary.put(__TIME__.getNameCharArray(), __TIME__);
|
fMacroDictionary.put(__TIME__.getNameCharArray(), __TIME__);
|
||||||
fMacroDictionary.put(__LINE__.getNameCharArray(), __LINE__);
|
fMacroDictionary.put(__LINE__.getNameCharArray(), __LINE__);
|
||||||
|
|
||||||
if (lang == ParserLanguage.CPP)
|
if (lang == ParserLanguage.CPP) {
|
||||||
fMacroDictionary.put(__cplusplus.getNameCharArray(), __cplusplus);
|
fMacroDictionary.put(__cplusplus.getNameCharArray(), __cplusplus);
|
||||||
else {
|
} else {
|
||||||
fMacroDictionary.put(__STDC_HOSTED__.getNameCharArray(), __STDC_HOSTED__);
|
fMacroDictionary.put(__STDC_HOSTED__.getNameCharArray(), __STDC_HOSTED__);
|
||||||
fMacroDictionary.put(__STDC_VERSION__.getNameCharArray(), __STDC_VERSION__);
|
fMacroDictionary.put(__STDC_VERSION__.getNameCharArray(), __STDC_VERSION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMacro[] toAdd = config.getAdditionalMacros();
|
IMacro[] toAdd = config.getAdditionalMacros();
|
||||||
if(toAdd != null) {
|
if (toAdd != null) {
|
||||||
for (final IMacro macro : toAdd) {
|
for (final IMacro macro : toAdd) {
|
||||||
addMacroDefinition(macro.getSignature(), macro.getExpansion());
|
addMacroDefinition(macro.getSignature(), macro.getExpansion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<String, String> macroDict= info.getDefinedSymbols();
|
final Map<String, String> macroDict= info.getDefinedSymbols();
|
||||||
if (macroDict != null) {
|
if (macroDict != null) {
|
||||||
for (Map.Entry<String, String> entry : macroDict.entrySet()) {
|
for (Map.Entry<String, String> entry : macroDict.entrySet()) {
|
||||||
|
@ -372,7 +371,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
addMacroDefinition(key.toCharArray(), value.toCharArray());
|
addMacroDefinition(key.toCharArray(), value.toCharArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<PreprocessorMacro> predefined= fMacroDictionary.values();
|
Collection<PreprocessorMacro> predefined= fMacroDictionary.values();
|
||||||
for (PreprocessorMacro macro : predefined) {
|
for (PreprocessorMacro macro : predefined) {
|
||||||
fLocationMap.registerPredefinedMacro(macro);
|
fLocationMap.registerPredefinedMacro(macro);
|
||||||
|
@ -398,8 +397,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fCurrentContext= new ScannerContext(ctx, fCurrentContext, new Lexer(buffer, fLexOptions, this, this));
|
fCurrentContext= new ScannerContext(ctx, fCurrentContext, new Lexer(buffer, fLexOptions, this, this));
|
||||||
ScannerContext preCtx= fCurrentContext;
|
ScannerContext preCtx= fCurrentContext;
|
||||||
try {
|
try {
|
||||||
while(internalFetchToken(preCtx, CHECK_NUMBERS, false).getType() != IToken.tEND_OF_INPUT) {
|
while (internalFetchToken(preCtx, CHECK_NUMBERS, false).getType() != IToken.tEND_OF_INPUT) {
|
||||||
// just eat the tokens
|
// just eat the tokens
|
||||||
}
|
}
|
||||||
final ILocationCtx locationCtx = fCurrentContext.getLocationCtx();
|
final ILocationCtx locationCtx = fCurrentContext.getLocationCtx();
|
||||||
fLocationMap.popContext(locationCtx);
|
fLocationMap.popContext(locationCtx);
|
||||||
|
@ -415,8 +414,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fCurrentContext= new ScannerContext(ctx, fCurrentContext, new Lexer(buffer, fLexOptions, this, this));
|
fCurrentContext= new ScannerContext(ctx, fCurrentContext, new Lexer(buffer, fLexOptions, this, this));
|
||||||
}
|
}
|
||||||
fPreIncludedFiles= null;
|
fPreIncludedFiles= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private char[] createSyntheticFile(String[] files) {
|
private char[] createSyntheticFile(String[] files) {
|
||||||
int totalLength= 0;
|
int totalLength= 0;
|
||||||
final char[] instruction= "#include <".toCharArray(); //$NON-NLS-1$
|
final char[] instruction= "#include <".toCharArray(); //$NON-NLS-1$
|
||||||
|
@ -436,7 +435,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PreprocessorMacro addMacroDefinition(char[] key, char[] value) {
|
public PreprocessorMacro addMacroDefinition(char[] key, char[] value) {
|
||||||
final Lexer lex= new Lexer(key, fLexOptions, ILexerLog.NULL, null);
|
final Lexer lex= new Lexer(key, fLexOptions, ILexerLog.NULL, null);
|
||||||
try {
|
try {
|
||||||
|
@ -444,13 +443,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fLocationMap.registerPredefinedMacro(result);
|
fLocationMap.registerPredefinedMacro(result);
|
||||||
fMacroDictionary.put(result.getNameCharArray(), result);
|
fMacroDictionary.put(result.getNameCharArray(), result);
|
||||||
return result;
|
return result;
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
fLog.traceLog("Invalid macro definition: '" + String.valueOf(key) + "'"); //$NON-NLS-1$//$NON-NLS-2$
|
fLog.traceLog("Invalid macro definition: '" + String.valueOf(key) + "'"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, IMacroBinding> getMacroDefinitions() {
|
public Map<String, IMacroBinding> getMacroDefinitions() {
|
||||||
Map<String, IMacroBinding> hashMap = new HashMap<String, IMacroBinding>(fMacroDictionary.size());
|
Map<String, IMacroBinding> hashMap = new HashMap<String, IMacroBinding>(fMacroDictionary.size());
|
||||||
for (char[] key : fMacroDictionary.keys()) {
|
for (char[] key : fMacroDictionary.keys()) {
|
||||||
|
@ -498,14 +496,14 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
t.setNext(null);
|
t.setNext(null);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pushbackToken(Token t) {
|
private void pushbackToken(Token t) {
|
||||||
t.setNext(fPrefetchedTokens);
|
t.setNext(fPrefetchedTokens);
|
||||||
fPrefetchedTokens= t;
|
fPrefetchedTokens= t;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns next token for the parser. String literals are not concatenated. When
|
* Returns next token for the parser. String literals are not concatenated. When
|
||||||
* the end is reached tokens with type {@link IToken#tEND_OF_INPUT}.
|
* the end is reached tokens with type {@link IToken#tEND_OF_INPUT}.
|
||||||
* @throws OffsetLimitReachedException see {@link Lexer}.
|
* @throws OffsetLimitReachedException see {@link Lexer}.
|
||||||
*/
|
*/
|
||||||
|
@ -513,7 +511,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (isCancelled) {
|
if (isCancelled) {
|
||||||
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token t1= fetchToken();
|
Token t1= fetchToken();
|
||||||
switch (t1.getType()) {
|
switch (t1.getType()) {
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
|
@ -521,7 +519,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
break;
|
break;
|
||||||
case IToken.tEND_OF_INPUT:
|
case IToken.tEND_OF_INPUT:
|
||||||
if (fContentAssistLimit >= 0) {
|
if (fContentAssistLimit >= 0) {
|
||||||
int useType= fHandledCompletion ? IToken.tEOC : IToken.tCOMPLETION;
|
int useType= fHandledCompletion ? IToken.tEOC : IToken.tCOMPLETION;
|
||||||
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(fContentAssistLimit);
|
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(fContentAssistLimit);
|
||||||
t1= new Token(useType, null, sequenceNumber, sequenceNumber);
|
t1= new Token(useType, null, sequenceNumber, sequenceNumber);
|
||||||
fHandledCompletion= true;
|
fHandledCompletion= true;
|
||||||
|
@ -544,11 +542,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (isCancelled) {
|
if (isCancelled) {
|
||||||
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token t1= fetchToken();
|
Token t1= fetchToken();
|
||||||
|
|
||||||
final int tt1= t1.getType();
|
final int tt1= t1.getType();
|
||||||
switch(tt1) {
|
switch (tt1) {
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
fHandledCompletion= true;
|
fHandledCompletion= true;
|
||||||
break;
|
break;
|
||||||
|
@ -557,7 +555,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (fContentAssistLimit < 0) {
|
if (fContentAssistLimit < 0) {
|
||||||
throw new EndOfFileException();
|
throw new EndOfFileException();
|
||||||
}
|
}
|
||||||
int useType= fHandledCompletion ? IToken.tEOC : IToken.tCOMPLETION;
|
int useType= fHandledCompletion ? IToken.tEOC : IToken.tCOMPLETION;
|
||||||
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(fContentAssistLimit);
|
int sequenceNumber= fLocationMap.getSequenceNumberForOffset(fContentAssistLimit);
|
||||||
t1= new Token(useType, null, sequenceNumber, sequenceNumber);
|
t1= new Token(useType, null, sequenceNumber, sequenceNumber);
|
||||||
fHandledCompletion= true;
|
fHandledCompletion= true;
|
||||||
|
@ -572,10 +570,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
Token t2;
|
Token t2;
|
||||||
StringBuffer buf= null;
|
StringBuffer buf= null;
|
||||||
int endOffset= 0;
|
int endOffset= 0;
|
||||||
loop: while(true) {
|
loop: while (true) {
|
||||||
t2= fetchToken();
|
t2= fetchToken();
|
||||||
final int tt2= t2.getType();
|
final int tt2= t2.getType();
|
||||||
switch(tt2) {
|
switch (tt2) {
|
||||||
case IToken.tLSTRING:
|
case IToken.tLSTRING:
|
||||||
case IToken.tSTRING:
|
case IToken.tSTRING:
|
||||||
case IToken.tUTF16STRING:
|
case IToken.tUTF16STRING:
|
||||||
|
@ -602,12 +600,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
char[] image= new char[buf.length() + prefix.length + 2];
|
char[] image= new char[buf.length() + prefix.length + 2];
|
||||||
int off= -1;
|
int off= -1;
|
||||||
|
|
||||||
for(char c : prefix)
|
for (char c : prefix)
|
||||||
image[++off] = c;
|
image[++off] = c;
|
||||||
|
|
||||||
image[++off]= '"';
|
image[++off]= '"';
|
||||||
buf.getChars(0, buf.length(), image, ++off);
|
buf.getChars(0, buf.length(), image, ++off);
|
||||||
image[image.length-1]= '"';
|
image[image.length - 1]= '"';
|
||||||
t1= new TokenWithImage(st.getTokenValue(), null, t1.getOffset(), endOffset, image);
|
t1= new TokenWithImage(st.getTokenValue(), null, t1.getOffset(), endOffset, image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -618,8 +616,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fLastToken= t1;
|
fLastToken= t1;
|
||||||
return t1;
|
return t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void skipInactiveCode() throws OffsetLimitReachedException {
|
public void skipInactiveCode() throws OffsetLimitReachedException {
|
||||||
final Lexer lexer= fCurrentContext.getLexer();
|
final Lexer lexer= fCurrentContext.getLexer();
|
||||||
if (lexer != null) {
|
if (lexer != null) {
|
||||||
|
@ -631,7 +628,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getCodeBranchNesting() {
|
public int getCodeBranchNesting() {
|
||||||
return fCurrentContext.getCodeBranchNesting();
|
return fCurrentContext.getCodeBranchNesting();
|
||||||
}
|
}
|
||||||
|
@ -640,14 +637,14 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
final char[] image= t1.getCharImage();
|
final char[] image= t1.getCharImage();
|
||||||
final int length= image.length;
|
final int length= image.length;
|
||||||
int start = 1;
|
int start = 1;
|
||||||
for(char c : image) {
|
for (char c : image) {
|
||||||
if(c == '"')
|
if (c == '"')
|
||||||
break;
|
break;
|
||||||
start++;
|
start++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (length > 1) {
|
if (length > 1) {
|
||||||
final int diff= image[length-1] == '"' ? length-start-1 : length-start;
|
final int diff= image[length - 1] == '"' ? length - start - 1 : length - start;
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
buf.append(image, start, diff);
|
buf.append(image, start, diff);
|
||||||
}
|
}
|
||||||
|
@ -656,8 +653,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
Token internalFetchToken(final ScannerContext uptoEndOfCtx, int options, boolean withinExpansion) throws OffsetLimitReachedException {
|
Token internalFetchToken(final ScannerContext uptoEndOfCtx, int options, boolean withinExpansion) throws OffsetLimitReachedException {
|
||||||
Token ppToken= fCurrentContext.currentLexerToken();
|
Token ppToken= fCurrentContext.currentLexerToken();
|
||||||
while(true) {
|
while (true) {
|
||||||
switch(ppToken.getType()) {
|
switch (ppToken.getType()) {
|
||||||
case Lexer.tBEFORE_INPUT:
|
case Lexer.tBEFORE_INPUT:
|
||||||
ppToken= fCurrentContext.nextPPToken();
|
ppToken= fCurrentContext.nextPPToken();
|
||||||
continue;
|
continue;
|
||||||
|
@ -670,7 +667,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case Lexer.tOTHER_CHARACTER:
|
case Lexer.tOTHER_CHARACTER:
|
||||||
handleProblem(IProblem.SCANNER_BAD_CHARACTER, ppToken.getCharImage(),
|
handleProblem(IProblem.SCANNER_BAD_CHARACTER, ppToken.getCharImage(),
|
||||||
ppToken.getOffset(), ppToken.getEndOffset());
|
ppToken.getOffset(), ppToken.getEndOffset());
|
||||||
ppToken= fCurrentContext.nextPPToken();
|
ppToken= fCurrentContext.nextPPToken();
|
||||||
continue;
|
continue;
|
||||||
|
@ -687,7 +684,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
ppToken= fCurrentContext.currentLexerToken();
|
ppToken= fCurrentContext.currentLexerToken();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case IToken.tPOUND:
|
case IToken.tPOUND:
|
||||||
{
|
{
|
||||||
final Lexer lexer= fCurrentContext.getLexer();
|
final Lexer lexer= fCurrentContext.getLexer();
|
||||||
if (lexer != null && lexer.currentTokenIsFirstOnLine()) {
|
if (lexer != null && lexer.currentTokenIsFirstOnLine()) {
|
||||||
|
@ -736,12 +733,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
final char[] image= number.getCharImage();
|
final char[] image= number.getCharImage();
|
||||||
boolean hasExponent = false;
|
boolean hasExponent = false;
|
||||||
|
|
||||||
// Integer constants written in binary are a non-standard extension
|
// Integer constants written in binary are a non-standard extension
|
||||||
// supported by GCC since 4.3 and by some other C compilers
|
// supported by GCC since 4.3 and by some other C compilers
|
||||||
// They consist of a prefix 0b or 0B, followed by a sequence of 0 and 1 digits
|
// They consist of a prefix 0b or 0B, followed by a sequence of 0 and 1 digits
|
||||||
// see http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
|
// see http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html
|
||||||
boolean isBin = false;
|
boolean isBin = false;
|
||||||
|
|
||||||
boolean isHex = false;
|
boolean isHex = false;
|
||||||
boolean isOctal = false;
|
boolean isOctal = false;
|
||||||
boolean hasDot= false;
|
boolean hasDot= false;
|
||||||
|
@ -784,17 +781,17 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
switch (image[pos]) {
|
switch (image[pos]) {
|
||||||
// octal digits
|
// octal digits
|
||||||
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
|
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// decimal digits
|
// decimal digits
|
||||||
case '8': case '9':
|
case '8': case '9':
|
||||||
if (isOctal) {
|
if (isOctal) {
|
||||||
handleProblem(IProblem.SCANNER_BAD_OCTAL_FORMAT, image, number.getOffset(), number.getEndOffset());
|
handleProblem(IProblem.SCANNER_BAD_OCTAL_FORMAT, image, number.getOffset(), number.getEndOffset());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// hex digits
|
// hex digits
|
||||||
case 'a': case 'A': case 'b': case 'B': case 'c': case 'C': case 'd': case 'D': case 'f': case 'F':
|
case 'a': case 'A': case 'b': case 'B': case 'c': case 'C': case 'd': case 'D': case 'f': case 'F':
|
||||||
if (isHex && !hasExponent) {
|
if (isHex && !hasExponent) {
|
||||||
|
@ -843,7 +840,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the suffix
|
// check the suffix
|
||||||
loop: for (; pos < image.length; pos++) {
|
loop: for (; pos < image.length; pos++) {
|
||||||
final char c= image[pos];
|
final char c= image[pos];
|
||||||
|
@ -864,31 +861,27 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
// The check for bin has to come before float, otherwise binary integers
|
// The check for bin has to come before float, otherwise binary integers
|
||||||
// with float components get flagged as BAD_FLOATING_POINT
|
// with float components get flagged as BAD_FLOATING_POINT
|
||||||
handleProblem(IProblem.SCANNER_BAD_BINARY_FORMAT, image, number.getOffset(), number.getEndOffset());
|
handleProblem(IProblem.SCANNER_BAD_BINARY_FORMAT, image, number.getOffset(), number.getEndOffset());
|
||||||
}
|
} else if (isFloat) {
|
||||||
else if (isFloat) {
|
|
||||||
handleProblem(IProblem.SCANNER_BAD_FLOATING_POINT, image, number.getOffset(), number.getEndOffset());
|
handleProblem(IProblem.SCANNER_BAD_FLOATING_POINT, image, number.getOffset(), number.getEndOffset());
|
||||||
}
|
} else if (isHex) {
|
||||||
else if (isHex) {
|
|
||||||
handleProblem(IProblem.SCANNER_BAD_HEX_FORMAT, image, number.getOffset(), number.getEndOffset());
|
handleProblem(IProblem.SCANNER_BAD_HEX_FORMAT, image, number.getOffset(), number.getEndOffset());
|
||||||
}
|
} else if (isOctal) {
|
||||||
else if (isOctal) {
|
|
||||||
handleProblem(IProblem.SCANNER_BAD_OCTAL_FORMAT, image, number.getOffset(), number.getEndOffset());
|
handleProblem(IProblem.SCANNER_BAD_OCTAL_FORMAT, image, number.getOffset(), number.getEndOffset());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
handleProblem(IProblem.SCANNER_BAD_DECIMAL_FORMAT, image, number.getOffset(), number.getEndOffset());
|
handleProblem(IProblem.SCANNER_BAD_DECIMAL_FORMAT, image, number.getOffset(), number.getEndOffset());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T findInclusion(final String includeDirective, final boolean quoteInclude,
|
private <T> T findInclusion(final String includeDirective, final boolean quoteInclude,
|
||||||
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
|
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
|
||||||
T reader = null;
|
T reader = null;
|
||||||
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
||||||
if (new File(includeDirective).isAbsolute() || includeDirective.startsWith("/")) { //$NON-NLS-1$
|
if (new File(includeDirective).isAbsolute() || includeDirective.startsWith("/")) { //$NON-NLS-1$
|
||||||
return tester.checkFile(includeDirective, false, null);
|
return tester.checkFile(includeDirective, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentFile != null && quoteInclude && !includeNext) {
|
if (currentFile != null && quoteInclude && !includeNext) {
|
||||||
// Check to see if we find a match in the current directory
|
// Check to see if we find a match in the current directory
|
||||||
final File currentDir= new File(currentFile).getParentFile();
|
final File currentDir= new File(currentFile).getParentFile();
|
||||||
|
@ -900,10 +893,17 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're not include_next, then we are looking for the first occurrence of
|
// If we're not include_next, then we are looking for the first occurrence of
|
||||||
// the file, otherwise, we ignore all the paths before the current directory
|
// the file, otherwise, we ignore all the paths before the current directory.
|
||||||
IncludeSearchPathElement searchAfter= includeNext ? fCurrentContext.getFoundOnPath() : null;
|
IncludeSearchPathElement searchAfter= null;
|
||||||
|
if (includeNext) {
|
||||||
|
searchAfter = fCurrentContext.getFoundOnPath();
|
||||||
|
if (searchAfter == null) {
|
||||||
|
searchAfter = findFileInIncludePath(currentFile, includeDirective);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (IncludeSearchPathElement path : fIncludeSearchPath) {
|
for (IncludeSearchPathElement path : fIncludeSearchPath) {
|
||||||
if (searchAfter != null) {
|
if (searchAfter != null) {
|
||||||
if (searchAfter.equals(path)) {
|
if (searchAfter.equals(path)) {
|
||||||
|
@ -928,6 +928,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) {
|
||||||
|
for (IncludeSearchPathElement path : fIncludeSearchPath) {
|
||||||
|
String fileLocation = path.getLocation(includeDirective);
|
||||||
|
if (file.equals(fileLocation)) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer buffer = new StringBuffer("Scanner @ file:"); //$NON-NLS-1$
|
StringBuffer buffer = new StringBuffer("Scanner @ file:"); //$NON-NLS-1$
|
||||||
|
@ -936,27 +946,24 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
buffer.append(fLocationMap.getCurrentLineNumber(fCurrentContext.currentLexerToken().getOffset()));
|
buffer.append(fLocationMap.getCurrentLineNumber(fCurrentContext.currentLexerToken().getOffset()));
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void addMacroDefinition(IIndexMacro macro) {
|
private void addMacroDefinition(IIndexMacro macro) {
|
||||||
try {
|
try {
|
||||||
final char[] expansionImage = macro.getExpansionImage();
|
final char[] expansionImage = macro.getExpansionImage();
|
||||||
if (expansionImage == null) {
|
if (expansionImage == null) {
|
||||||
// this is an undef
|
// this is an undef
|
||||||
fMacroDictionary.remove(macro.getNameCharArray());
|
fMacroDictionary.remove(macro.getNameCharArray());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
PreprocessorMacro result= MacroDefinitionParser.parseMacroDefinition(macro.getNameCharArray(), macro.getParameterList(), expansionImage);
|
PreprocessorMacro result= MacroDefinitionParser.parseMacroDefinition(macro.getNameCharArray(), macro.getParameterList(), expansionImage);
|
||||||
final IASTFileLocation loc= macro.getFileLocation();
|
final IASTFileLocation loc= macro.getFileLocation();
|
||||||
fLocationMap.registerMacroFromIndex(result, loc, -1);
|
fLocationMap.registerMacroFromIndex(result, loc, -1);
|
||||||
fMacroDictionary.put(result.getNameCharArray(), result);
|
fMacroDictionary.put(result.getNameCharArray(), result);
|
||||||
}
|
}
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
fLog.traceLog("Invalid macro definition: '" + macro.getName() + "'"); //$NON-NLS-1$//$NON-NLS-2$
|
fLog.traceLog("Invalid macro definition: '" + macro.getName() + "'"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILocationResolver getLocationMap() {
|
public ILocationResolver getLocationMap() {
|
||||||
return fLocationMap;
|
return fLocationMap;
|
||||||
}
|
}
|
||||||
|
@ -978,7 +985,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
switch (ident.getType()) {
|
switch (ident.getType()) {
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
Token completionToken= new TokenWithImage(ident.getType(), null,
|
Token completionToken= new TokenWithImage(ident.getType(), null,
|
||||||
startOffset, ident.getEndOffset(), ("#" + ident.getImage()).toCharArray()); //$NON-NLS-1$
|
startOffset, ident.getEndOffset(), ("#" + ident.getImage()).toCharArray()); //$NON-NLS-1$
|
||||||
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, completionToken);
|
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, completionToken);
|
||||||
|
|
||||||
|
@ -1035,16 +1042,16 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (executeIfdef(lexer, startOffset, true, withinExpansion) == CodeState.eSkipInactive)
|
if (executeIfdef(lexer, startOffset, true, withinExpansion) == CodeState.eSkipInactive)
|
||||||
skipOverConditionalCode(lexer, withinExpansion);
|
skipOverConditionalCode(lexer, withinExpansion);
|
||||||
break;
|
break;
|
||||||
case IPreprocessorDirective.ppIf:
|
case IPreprocessorDirective.ppIf:
|
||||||
if (executeIf(lexer, startOffset, false, withinExpansion) == CodeState.eSkipInactive)
|
if (executeIf(lexer, startOffset, false, withinExpansion) == CodeState.eSkipInactive)
|
||||||
skipOverConditionalCode(lexer, withinExpansion);
|
skipOverConditionalCode(lexer, withinExpansion);
|
||||||
break;
|
break;
|
||||||
case IPreprocessorDirective.ppElif:
|
case IPreprocessorDirective.ppElif:
|
||||||
if (executeIf(lexer, startOffset, true, withinExpansion) == CodeState.eSkipInactive) {
|
if (executeIf(lexer, startOffset, true, withinExpansion) == CodeState.eSkipInactive) {
|
||||||
skipOverConditionalCode(lexer, withinExpansion);
|
skipOverConditionalCode(lexer, withinExpansion);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPreprocessorDirective.ppElse:
|
case IPreprocessorDirective.ppElse:
|
||||||
if (executeElse(lexer, startOffset, withinExpansion) == CodeState.eSkipInactive) {
|
if (executeElse(lexer, startOffset, withinExpansion) == CodeState.eSkipInactive) {
|
||||||
skipOverConditionalCode(lexer, withinExpansion);
|
skipOverConditionalCode(lexer, withinExpansion);
|
||||||
}
|
}
|
||||||
|
@ -1052,21 +1059,21 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
case IPreprocessorDirective.ppEndif:
|
case IPreprocessorDirective.ppEndif:
|
||||||
executeEndif(lexer, startOffset, withinExpansion);
|
executeEndif(lexer, startOffset, withinExpansion);
|
||||||
break;
|
break;
|
||||||
case IPreprocessorDirective.ppWarning:
|
case IPreprocessorDirective.ppWarning:
|
||||||
case IPreprocessorDirective.ppError:
|
case IPreprocessorDirective.ppError:
|
||||||
int condOffset= lexer.nextToken().getOffset();
|
int condOffset= lexer.nextToken().getOffset();
|
||||||
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
if (fCurrentContext.getCodeState() == CodeState.eActive) {
|
if (fCurrentContext.getCodeState() == CodeState.eActive) {
|
||||||
int endOffset= lexer.currentToken().getEndOffset();
|
int endOffset= lexer.currentToken().getEndOffset();
|
||||||
final char[] warning= lexer.getInputChars(condOffset, condEndOffset);
|
final char[] warning= lexer.getInputChars(condOffset, condEndOffset);
|
||||||
final int id= type == IPreprocessorDirective.ppError
|
final int id= type == IPreprocessorDirective.ppError
|
||||||
? IProblem.PREPROCESSOR_POUND_ERROR
|
? IProblem.PREPROCESSOR_POUND_ERROR
|
||||||
: IProblem.PREPROCESSOR_POUND_WARNING;
|
: IProblem.PREPROCESSOR_POUND_WARNING;
|
||||||
handleProblem(id, warning, condOffset, condEndOffset);
|
handleProblem(id, warning, condOffset, condEndOffset);
|
||||||
fLocationMap.encounterPoundError(startOffset, condOffset, condEndOffset, endOffset);
|
fLocationMap.encounterPoundError(startOffset, condOffset, condEndOffset, endOffset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPreprocessorDirective.ppPragma:
|
case IPreprocessorDirective.ppPragma:
|
||||||
condOffset= lexer.nextToken().getOffset();
|
condOffset= lexer.nextToken().getOffset();
|
||||||
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
if (fCurrentContext.getCodeState() == CodeState.eActive) {
|
if (fCurrentContext.getCodeState() == CodeState.eActive) {
|
||||||
|
@ -1103,7 +1110,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
char[] headerName= null;
|
char[] headerName= null;
|
||||||
boolean userInclude= true;
|
boolean userInclude= true;
|
||||||
|
|
||||||
switch(header.getType()) {
|
switch (header.getType()) {
|
||||||
case Lexer.tSYSTEM_HEADER_NAME:
|
case Lexer.tSYSTEM_HEADER_NAME:
|
||||||
userInclude= false;
|
userInclude= false;
|
||||||
headerName = extractHeaderName(header.getCharImage(), '<', '>', nameOffsets);
|
headerName = extractHeaderName(header.getCharImage(), '<', '>', nameOffsets);
|
||||||
|
@ -1118,12 +1125,12 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, header);
|
throw new OffsetLimitReachedException(ORIGIN_PREPROCESSOR_DIRECTIVE, header);
|
||||||
|
|
||||||
case IToken.tIDENTIFIER:
|
case IToken.tIDENTIFIER:
|
||||||
TokenList tl= new TokenList();
|
TokenList tl= new TokenList();
|
||||||
condEndOffset= nameOffsets[1]= getTokensWithinPPDirective(false, tl, false);
|
condEndOffset= nameOffsets[1]= getTokensWithinPPDirective(false, tl, false);
|
||||||
Token t= tl.first();
|
Token t= tl.first();
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
switch(t.getType()) {
|
switch (t.getType()) {
|
||||||
case IToken.tSTRING:
|
case IToken.tSTRING:
|
||||||
headerName = extractHeaderName(t.getCharImage(), '"', '"', new int[]{0,0});
|
headerName = extractHeaderName(t.getCharImage(), '"', '"', new int[]{0,0});
|
||||||
break;
|
break;
|
||||||
|
@ -1152,7 +1159,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (headerName == null || headerName.length==0) {
|
if (headerName == null || headerName.length == 0) {
|
||||||
if (active) {
|
if (active) {
|
||||||
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE,
|
handleProblem(IProblem.PREPROCESSOR_INVALID_DIRECTIVE,
|
||||||
lexer.getInputChars(poundOffset, condEndOffset), poundOffset, condEndOffset);
|
lexer.getInputChars(poundOffset, condEndOffset), poundOffset, condEndOffset);
|
||||||
|
@ -1166,18 +1173,19 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
if (!active) {
|
if (!active) {
|
||||||
// test if the include is inactive just because it was included before (bug 167100)
|
// test if the include is inactive just because it was included before (bug 167100)
|
||||||
final IncludeResolution resolved= findInclusion(new String(headerName), userInclude, include_next, getCurrentFilename(), createPathTester);
|
final IncludeResolution resolved= findInclusion(new String(headerName), userInclude, include_next,
|
||||||
|
getCurrentFilename(), createPathTester);
|
||||||
if (resolved != null && fCodeReaderFactory.hasFileBeenIncludedInCurrentTranslationUnit(resolved.fLocation)) {
|
if (resolved != null && fCodeReaderFactory.hasFileBeenIncludedInCurrentTranslationUnit(resolved.fLocation)) {
|
||||||
path= resolved.fLocation;
|
path= resolved.fLocation;
|
||||||
isHeuristic= resolved.fHeuristic;
|
isHeuristic= resolved.fHeuristic;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
final IncludeFileContent fi= findInclusion(new String(headerName), userInclude, include_next,
|
||||||
final IncludeFileContent fi= findInclusion(new String(headerName), userInclude, include_next, getCurrentFilename(), createCodeReaderTester);
|
getCurrentFilename(), createCodeReaderTester);
|
||||||
if (fi != null) {
|
if (fi != null) {
|
||||||
path= fi.getFileLocation();
|
path= fi.getFileLocation();
|
||||||
isHeuristic= fi.isFoundByHeuristics();
|
isHeuristic= fi.isFoundByHeuristics();
|
||||||
switch(fi.getKind()) {
|
switch (fi.getKind()) {
|
||||||
case FOUND_IN_INDEX:
|
case FOUND_IN_INDEX:
|
||||||
processInclusionFromIndex(poundOffset, path, fi);
|
processInclusionFromIndex(poundOffset, path, fi);
|
||||||
break;
|
break;
|
||||||
|
@ -1186,8 +1194,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (reader != null && !isCircularInclusion(path)) {
|
if (reader != null && !isCircularInclusion(path)) {
|
||||||
reported= true;
|
reported= true;
|
||||||
fAllIncludedFiles.add(path);
|
fAllIncludedFiles.add(path);
|
||||||
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic, fi.isSource());
|
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1],
|
||||||
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer, fLexOptions, this, this));
|
condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic, fi.isSource());
|
||||||
|
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer,
|
||||||
|
fLexOptions, this, this));
|
||||||
fctx.setFoundOnPath(fi.getFoundOnPath());
|
fctx.setFoundOnPath(fi.getFoundOnPath());
|
||||||
fCurrentContext= fctx;
|
fCurrentContext= fctx;
|
||||||
}
|
}
|
||||||
|
@ -1196,9 +1206,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
case SKIP_FILE:
|
case SKIP_FILE:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
final int len = headerName.length + 2;
|
||||||
final int len = headerName.length+2;
|
|
||||||
StringBuilder name= new StringBuilder(len);
|
StringBuilder name= new StringBuilder(len);
|
||||||
name.append(userInclude ? '"' : '<');
|
name.append(userInclude ? '"' : '<');
|
||||||
name.append(headerName);
|
name.append(headerName);
|
||||||
|
@ -1211,7 +1220,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reported) {
|
if (!reported) {
|
||||||
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, headerName, path, userInclude, active, isHeuristic);
|
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, headerName, path, userInclude, active, isHeuristic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1227,7 +1236,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
char[] headerName;
|
char[] headerName;
|
||||||
int start= 0;
|
int start= 0;
|
||||||
int length= image.length;
|
int length= image.length;
|
||||||
if (length > 0 && image[length-1] == endDelim) {
|
if (length > 0 && image[length - 1] == endDelim) {
|
||||||
length--;
|
length--;
|
||||||
offsets[1]--;
|
offsets[1]--;
|
||||||
if (length > 0 && image[0] == startDelim) {
|
if (length > 0 && image[0] == startDelim) {
|
||||||
|
@ -1260,7 +1269,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fMacroDictionary.put(macrodef.getNameCharArray(), macrodef);
|
fMacroDictionary.put(macrodef.getNameCharArray(), macrodef);
|
||||||
|
|
||||||
final Token name= fMacroDefinitionParser.getNameToken();
|
final Token name= fMacroDefinitionParser.getNameToken();
|
||||||
fLocationMap.encounterPoundDefine(startOffset, name.getOffset(), name.getEndOffset(),
|
fLocationMap.encounterPoundDefine(startOffset, name.getOffset(), name.getEndOffset(),
|
||||||
macrodef.getExpansionOffset(), macrodef.getExpansionEndOffset(), isActive, macrodef);
|
macrodef.getExpansionOffset(), macrodef.getExpansionEndOffset(), isActive, macrodef);
|
||||||
} catch (InvalidMacroDefinitionException e) {
|
} catch (InvalidMacroDefinitionException e) {
|
||||||
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
|
@ -1335,7 +1344,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
int condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
int condEndOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, startOffset, condEndOffset);
|
handleProblem(IProblem.PREPROCESSOR_UNBALANCE_CONDITION, name, startOffset, condEndOffset);
|
||||||
return fCurrentContext.getCodeState();
|
return fCurrentContext.getCodeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isActive= false;
|
boolean isActive= false;
|
||||||
IASTName[] refs= IASTName.EMPTY_NAME_ARRAY;
|
IASTName[] refs= IASTName.EMPTY_NAME_ARRAY;
|
||||||
|
@ -1370,7 +1379,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
return fCurrentContext.setBranchState(cond, isActive, withinExpansion, startOffset);
|
return fCurrentContext.setBranchState(cond, isActive, withinExpansion, startOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeState executeElse(final Lexer lexer, final int startOffset,boolean withinExpansion)
|
private CodeState executeElse(final Lexer lexer, final int startOffset,boolean withinExpansion)
|
||||||
throws OffsetLimitReachedException {
|
throws OffsetLimitReachedException {
|
||||||
final int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
final int endOffset= lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
|
@ -1398,8 +1407,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the preprocessor on the rest of the line, storing the tokens in the holder supplied.
|
* Runs the preprocessor on the rest of the line, storing the tokens in the holder supplied.
|
||||||
* Macro expansion is reported to the location map.
|
* Macro expansion is reported to the location map.
|
||||||
* In case isCondition is set to <code>true</code>, identifiers with image 'defined' are
|
* In case isCondition is set to <code>true</code>, identifiers with image 'defined' are
|
||||||
* converted to the defined-token and its argument is not macro expanded.
|
* converted to the defined-token and its argument is not macro expanded.
|
||||||
* Returns the end-offset of the last token that was consumed.
|
* Returns the end-offset of the last token that was consumed.
|
||||||
*/
|
*/
|
||||||
|
@ -1410,9 +1419,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (isCondition)
|
if (isCondition)
|
||||||
options |= PROTECT_DEFINED;
|
options |= PROTECT_DEFINED;
|
||||||
|
|
||||||
loop: while(true) {
|
loop: while (true) {
|
||||||
Token t= internalFetchToken(scannerCtx, options, withinExpansion);
|
Token t= internalFetchToken(scannerCtx, options, withinExpansion);
|
||||||
switch(t.getType()) {
|
switch (t.getType()) {
|
||||||
case IToken.tEND_OF_INPUT:
|
case IToken.tEND_OF_INPUT:
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
scannerCtx.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE); // make sure the exception is thrown.
|
scannerCtx.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE); // make sure the exception is thrown.
|
||||||
|
@ -1436,7 +1445,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
// make sure an exception is thrown if we are running content assist at the end of the line
|
// make sure an exception is thrown if we are running content assist at the end of the line
|
||||||
return scannerCtx.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
return scannerCtx.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skipOverConditionalCode(final Lexer lexer, boolean withinExpansion) throws OffsetLimitReachedException {
|
private void skipOverConditionalCode(final Lexer lexer, boolean withinExpansion) throws OffsetLimitReachedException {
|
||||||
CodeState state= CodeState.eSkipInactive;
|
CodeState state= CodeState.eSkipInactive;
|
||||||
while (state == CodeState.eSkipInactive) {
|
while (state == CodeState.eSkipInactive) {
|
||||||
|
@ -1445,13 +1454,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodeState skipBranch(final Lexer lexer, boolean withinExpansion) throws OffsetLimitReachedException {
|
private CodeState skipBranch(final Lexer lexer, boolean withinExpansion) throws OffsetLimitReachedException {
|
||||||
while(true) {
|
while (true) {
|
||||||
final Token pound = lexer.nextDirective();
|
final Token pound = lexer.nextDirective();
|
||||||
int tt = pound.getType();
|
int tt = pound.getType();
|
||||||
if (tt != IToken.tPOUND) {
|
if (tt != IToken.tPOUND) {
|
||||||
if (tt == IToken.tCOMPLETION) {
|
if (tt == IToken.tCOMPLETION) {
|
||||||
// completion in inactive code
|
// completion in inactive code
|
||||||
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, pound);
|
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, pound);
|
||||||
}
|
}
|
||||||
// must be the end of the lexer
|
// must be the end of the lexer
|
||||||
return CodeState.eActive;
|
return CodeState.eActive;
|
||||||
|
@ -1461,7 +1470,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (tt != IToken.tIDENTIFIER) {
|
if (tt != IToken.tIDENTIFIER) {
|
||||||
if (tt == IToken.tCOMPLETION) {
|
if (tt == IToken.tCOMPLETION) {
|
||||||
// completion in inactive directive
|
// completion in inactive directive
|
||||||
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, ident);
|
throw new OffsetLimitReachedException(ORIGIN_INACTIVE_CODE, ident);
|
||||||
}
|
}
|
||||||
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
lexer.consumeLine(ORIGIN_PREPROCESSOR_DIRECTIVE);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1506,7 +1515,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
* If applicable the macro is expanded and the resulting tokens are put onto a new context.
|
* If applicable the macro is expanded and the resulting tokens are put onto a new context.
|
||||||
* @param identifier the token where macro expansion may occur.
|
* @param identifier the token where macro expansion may occur.
|
||||||
* @param lexer the input for the expansion.
|
* @param lexer the input for the expansion.
|
||||||
* @param stopAtNewline whether or not tokens to be read are limited to the current line.
|
* @param stopAtNewline whether or not tokens to be read are limited to the current line.
|
||||||
* @param isPPCondition whether the expansion is inside of a preprocessor condition. This
|
* @param isPPCondition whether the expansion is inside of a preprocessor condition. This
|
||||||
* implies a specific handling for the defined token.
|
* implies a specific handling for the defined token.
|
||||||
*/
|
*/
|
||||||
|
@ -1520,7 +1529,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (macro instanceof FunctionStyleMacro) {
|
if (macro instanceof FunctionStyleMacro) {
|
||||||
Token t= lexer.currentToken();
|
Token t= lexer.currentToken();
|
||||||
if (!stopAtNewline) {
|
if (!stopAtNewline) {
|
||||||
while(t.getType() == Lexer.tNEWLINE) {
|
while (t.getType() == Lexer.tNEWLINE) {
|
||||||
t= lexer.nextToken();
|
t= lexer.nextToken();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1536,7 +1545,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
final IASTName[] expansions= expander.clearImplicitExpansions();
|
final IASTName[] expansions= expander.clearImplicitExpansions();
|
||||||
final ImageLocationInfo[] ili= expander.clearImageLocationInfos();
|
final ImageLocationInfo[] ili= expander.clearImageLocationInfos();
|
||||||
final Token last= replacement.last();
|
final Token last= replacement.last();
|
||||||
final int length= last == null ? 0 : last.getEndOffset();
|
final int length= last == null ? 0 : last.getEndOffset();
|
||||||
ILocationCtx ctx= fLocationMap.pushMacroExpansion(
|
ILocationCtx ctx= fLocationMap.pushMacroExpansion(
|
||||||
identifier.getOffset(), identifier.getEndOffset(), lexer.getLastEndOffset(), length, macro, expansions, ili);
|
identifier.getOffset(), identifier.getEndOffset(), lexer.getLastEndOffset(), length, macro, expansions, ili);
|
||||||
fCurrentContext= new ScannerContext(ctx, fCurrentContext, replacement);
|
fCurrentContext= new ScannerContext(ctx, fCurrentContext, replacement);
|
||||||
|
|
Loading…
Add table
Reference in a new issue