mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Bug 417193 - Incorrect Symbol <X> could not be found
Fixed bug with mixing #pragma once with standard include guard. Change-Id: Ic418ab290f9d322d943bab56625ce1f0fe6b2aee Signed-off-by: Joseph Henry <joseph.henry@sas.com>
This commit is contained in:
parent
e3fbd7c4ca
commit
b741fb552a
1 changed files with 86 additions and 10 deletions
|
@ -23,6 +23,8 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
* Helper class for detecting include guards.
|
* Helper class for detecting include guards.
|
||||||
*/
|
*/
|
||||||
public class IncludeGuardDetection {
|
public class IncludeGuardDetection {
|
||||||
|
private static final String ONCE = "once"; //$NON-NLS-1$
|
||||||
|
|
||||||
public static char[] detectIncludeGuard(AbstractCharArray content, Lexer.LexerOptions lexOptions,
|
public static char[] detectIncludeGuard(AbstractCharArray content, Lexer.LexerOptions lexOptions,
|
||||||
CharArrayIntMap ppKeywords) {
|
CharArrayIntMap ppKeywords) {
|
||||||
Lexer l= new Lexer(content, lexOptions, ILexerLog.NULL, null);
|
Lexer l= new Lexer(content, lexOptions, ILexerLog.NULL, null);
|
||||||
|
@ -33,18 +35,92 @@ public class IncludeGuardDetection {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the case when there is a "#pragma once" before an include guard.
|
||||||
|
* <p>
|
||||||
|
* This can be in the form of:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* #pragma once
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* or:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* #if (anything)
|
||||||
|
* #pragma once
|
||||||
|
* #endif
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
private static Token skipPragmaOnce(Lexer l, CharArrayIntMap ppKeywords)
|
||||||
|
throws OffsetLimitReachedException {
|
||||||
|
boolean foundPragma = false;
|
||||||
|
boolean quit = false;
|
||||||
|
boolean foundIf = false;
|
||||||
|
|
||||||
|
// Skip to the first statement.
|
||||||
|
Token t = skipAll(l, Lexer.tNEWLINE);
|
||||||
|
l.saveState(); // Save the state in case we don't find a "#pragma once".
|
||||||
|
|
||||||
|
while (!quit) {
|
||||||
|
switch (t.getType()) {
|
||||||
|
case IToken.tPOUND:
|
||||||
|
t = l.nextToken(); // Just get the next token.
|
||||||
|
break;
|
||||||
|
case IToken.tIDENTIFIER:
|
||||||
|
switch (ppKeywords.get(t.getCharImage())) {
|
||||||
|
case IPreprocessorDirective.ppPragma:
|
||||||
|
t = l.nextToken(); // Get the next token (expecting "once").
|
||||||
|
if (CharArrayUtils.equals(t.getCharImage(), ONCE)) {
|
||||||
|
foundPragma = true;
|
||||||
|
t = skipAll(l, Lexer.tNEWLINE);
|
||||||
|
if (!foundIf) // Just quit if we are not in an '#if' block.
|
||||||
|
quit = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IPreprocessorDirective.ppIf:
|
||||||
|
if (foundIf) {
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
foundIf = true;
|
||||||
|
t = l.nextDirective(); // Go to the next directive.
|
||||||
|
break;
|
||||||
|
case IPreprocessorDirective.ppEndif:
|
||||||
|
if (foundIf)
|
||||||
|
t = skipAll(l, Lexer.tNEWLINE);
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
quit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundPragma) {
|
||||||
|
l.restoreState();
|
||||||
|
return l.currentToken();
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
private static char[] findIncludeGuard(Lexer l, CharArrayIntMap ppKeywords) {
|
private static char[] findIncludeGuard(Lexer l, CharArrayIntMap ppKeywords) {
|
||||||
try {
|
try {
|
||||||
if (skipAll(l, Lexer.tNEWLINE).getType() == IToken.tPOUND) {
|
if (skipPragmaOnce(l, ppKeywords).getType() == IToken.tPOUND) {
|
||||||
Token t = l.nextToken();
|
Token t = l.nextToken();
|
||||||
if (t.getType() == IToken.tIDENTIFIER) {
|
if (t.getType() == IToken.tIDENTIFIER) {
|
||||||
char[] guard= null;
|
char[] guard = null;
|
||||||
switch (ppKeywords.get(t.getCharImage())) {
|
switch (ppKeywords.get(t.getCharImage())) {
|
||||||
case IPreprocessorDirective.ppIfndef:
|
case IPreprocessorDirective.ppIfndef:
|
||||||
// #ifndef GUARD
|
// #ifndef GUARD
|
||||||
t= l.nextToken();
|
t = l.nextToken();
|
||||||
if (t.getType() == IToken.tIDENTIFIER) {
|
if (t.getType() == IToken.tIDENTIFIER) {
|
||||||
guard= t.getCharImage();
|
guard = t.getCharImage();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPreprocessorDirective.ppIf:
|
case IPreprocessorDirective.ppIf:
|
||||||
|
@ -64,11 +140,11 @@ public class IncludeGuardDetection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (OffsetLimitReachedException e) {
|
} catch (OffsetLimitReachedException e) {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static char[] findNotDefined(Lexer l) throws OffsetLimitReachedException {
|
private static char[] findNotDefined(Lexer l) throws OffsetLimitReachedException {
|
||||||
Token t;
|
Token t;
|
||||||
|
|
Loading…
Add table
Reference in a new issue