mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Fix for 168924, ambiguity parsing cast-expressions.
This commit is contained in:
parent
219cfb58d9
commit
1ce81432d7
8 changed files with 82 additions and 105 deletions
|
@ -3494,7 +3494,7 @@ public class AST2Tests extends AST2BaseTest {
|
|||
// z= (a)/z;
|
||||
// z= (a)%z;
|
||||
// }
|
||||
public void _testBracketAroundIdentifier_168924() throws IOException, ParserException {
|
||||
public void testBracketAroundIdentifier_168924() throws IOException, ParserException {
|
||||
StringBuffer buf= getContents(1)[0];
|
||||
IASTTranslationUnit tu= parse(buf.toString(), ParserLanguage.C, true, true);
|
||||
IASTFunctionDefinition func= (IASTFunctionDefinition) tu.getDeclarations()[0];
|
||||
|
|
|
@ -2268,4 +2268,24 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In case a cast expression is followed by +/- or & we should avoid it:
|
||||
* (a)+1 vs. (int)+1;
|
||||
* @since 4.0
|
||||
*/
|
||||
protected boolean avoidCastExpressionByHeuristics() throws EndOfFileException {
|
||||
if (LT(1) == IToken.tIDENTIFIER) {
|
||||
if (LT(2) == IToken.tRPAREN) {
|
||||
switch (LT(3)) {
|
||||
case IToken.tPLUS:
|
||||
case IToken.tMINUS:
|
||||
case IToken.tAMPER:
|
||||
case IToken.tSTAR:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -835,7 +835,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
boolean needBack = false;
|
||||
try {
|
||||
try {
|
||||
if (!avoidCastExpressionByHeuristics()) {
|
||||
typeId = typeId(false);
|
||||
}
|
||||
if (typeId != null) {
|
||||
switch (LT(1)) {
|
||||
case IToken.tRPAREN:
|
||||
|
@ -887,7 +889,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
*/
|
||||
protected IASTExpression unaryExpression() throws EndOfFileException,
|
||||
BacktrackException {
|
||||
int startingOffset = LA(1).getOffset();
|
||||
switch (LT(1)) {
|
||||
case IToken.tSTAR:
|
||||
return unaryOperatorCastExpression(IASTUnaryExpression.op_star);
|
||||
|
@ -906,41 +907,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
case IToken.tDECR:
|
||||
return unaryOperatorCastExpression(IASTUnaryExpression.op_prefixDecr);
|
||||
case IToken.t_sizeof:
|
||||
startingOffset = consume().getOffset();
|
||||
IToken mark = LA(1);
|
||||
IASTExpression unaryExpression = null;
|
||||
IASTTypeId typeId = null;
|
||||
int lastOffset = 0;
|
||||
if (LT(1) == IToken.tLPAREN) {
|
||||
boolean needBack = false;
|
||||
consume();
|
||||
typeId = typeId(false);
|
||||
if (typeId != null) {
|
||||
switch (LT(1)) {
|
||||
case IToken.tRPAREN:
|
||||
case IToken.tEOC:
|
||||
lastOffset = consume().getEndOffset();
|
||||
break;
|
||||
default:
|
||||
needBack = true;
|
||||
}
|
||||
} else {needBack = true; }
|
||||
if (needBack) {
|
||||
backup(mark);
|
||||
typeId = null;
|
||||
unaryExpression = unaryExpression();
|
||||
lastOffset = calculateEndOffset(unaryExpression);
|
||||
}
|
||||
} else {
|
||||
unaryExpression = unaryExpression();
|
||||
lastOffset = calculateEndOffset(unaryExpression);
|
||||
}
|
||||
mark = null;
|
||||
if (typeId == null && unaryExpression != null)
|
||||
return buildUnaryExpression(IASTUnaryExpression.op_sizeof,
|
||||
unaryExpression, startingOffset, lastOffset);
|
||||
return buildTypeIdExpression(IASTTypeIdExpression.op_sizeof,
|
||||
typeId, startingOffset, lastOffset);
|
||||
return parseSizeofExpression();
|
||||
|
||||
default:
|
||||
if (LT(1) == IGCCToken.t_typeof && supportTypeOfUnaries) {
|
||||
|
@ -1001,17 +968,22 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
IASTTypeId t = typeId(false);
|
||||
if (t != null) {
|
||||
consume(IToken.tRPAREN).getEndOffset();
|
||||
if (LT(1) == IToken.tLBRACE) {
|
||||
IASTInitializer i = cInitializerClause(Collections.EMPTY_LIST);
|
||||
firstExpression = buildTypeIdInitializerExpression(t, i,
|
||||
offset, calculateEndOffset(i));
|
||||
break;
|
||||
} else {backup(m); }
|
||||
} catch (BacktrackException bt) {
|
||||
backup(m);
|
||||
}
|
||||
}
|
||||
} catch (BacktrackException bt) {
|
||||
}
|
||||
backup(m);
|
||||
firstExpression= primaryExpression();
|
||||
break;
|
||||
|
||||
default:
|
||||
firstExpression = primaryExpression();
|
||||
break;
|
||||
}
|
||||
|
||||
IASTExpression secondExpression = null;
|
||||
|
|
|
@ -914,8 +914,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
boolean popped = false;
|
||||
IASTTypeId typeId = null;
|
||||
IToken startCastExpression=null;
|
||||
|
||||
// If this isn't a type name, then we shouldn't be here
|
||||
if (!avoidCastExpressionByHeuristics()) {
|
||||
typeId = typeId(false);
|
||||
}
|
||||
if (typeId != null && LT(1) == IToken.tRPAREN) {
|
||||
consume();
|
||||
startCastExpression=mark();
|
||||
|
|
|
@ -81,14 +81,14 @@ public class CallHierarchyBaseTest extends BaseUITestCase {
|
|||
protected void openCallHierarchy(CEditor editor, boolean showReferencedBy) {
|
||||
CallHierarchyUI.setIsJUnitTest(true);
|
||||
CallHierarchyUI.open(editor, (ITextSelection) editor.getSelectionProvider().getSelection());
|
||||
runEventQueue(200);
|
||||
runEventQueue(0);
|
||||
CHViewPart ch= null;
|
||||
IWorkbenchPage page = editor.getSite().getPage();
|
||||
for (int i = 0; i < 20; i++) {
|
||||
for (int i = 0; i < 400; i++) {
|
||||
ch= (CHViewPart)page.findView(CUIPlugin.ID_CALL_HIERARCHY);
|
||||
if (ch != null)
|
||||
break;
|
||||
runEventQueue(200);
|
||||
runEventQueue(10);
|
||||
}
|
||||
assertNotNull(ch);
|
||||
ch.onSetShowReferencedBy(showReferencedBy);
|
||||
|
@ -97,7 +97,13 @@ public class CallHierarchyBaseTest extends BaseUITestCase {
|
|||
protected TreeViewer getCHTreeViewer() {
|
||||
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
|
||||
runEventQueue(0);
|
||||
CHViewPart ch= (CHViewPart)page.findView(CUIPlugin.ID_CALL_HIERARCHY);
|
||||
CHViewPart ch= null;
|
||||
for (int i=0; i<50; i++) {
|
||||
ch= (CHViewPart)page.findView(CUIPlugin.ID_CALL_HIERARCHY);
|
||||
if (ch != null)
|
||||
break;
|
||||
runEventQueue(10);
|
||||
}
|
||||
assertNotNull(ch);
|
||||
return ch.getTreeViewer();
|
||||
}
|
||||
|
@ -105,7 +111,7 @@ public class CallHierarchyBaseTest extends BaseUITestCase {
|
|||
protected TreeItem checkTreeNode(Tree tree, int i0, String label) {
|
||||
TreeItem root= null;
|
||||
try {
|
||||
for (int i=0; i<20; i++) {
|
||||
for (int i=0; i<100; i++) {
|
||||
root= tree.getItem(i0);
|
||||
try {
|
||||
if (!"...".equals(root.getText())) {
|
||||
|
@ -114,7 +120,7 @@ public class CallHierarchyBaseTest extends BaseUITestCase {
|
|||
} catch (SWTException e) {
|
||||
// in case widget was disposed, item may be replaced
|
||||
}
|
||||
runEventQueue(50);
|
||||
runEventQueue(10);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.testplugin.FileManager;
|
||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
||||
|
@ -61,7 +62,7 @@ import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction;
|
|||
* @author dsteffle
|
||||
*/
|
||||
public class BaseSelectionTestsIndexer extends BaseUITestCase {
|
||||
protected IProject project;
|
||||
protected ICProject fCProject;
|
||||
static FileManager fileManager = new FileManager();
|
||||
IProgressMonitor monitor = new NullProgressMonitor();
|
||||
|
||||
|
@ -88,7 +89,7 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
|
|||
|
||||
protected IFile importFile(String fileName, String contents ) throws Exception{
|
||||
//Obtain file handle
|
||||
IFile file = project.getProject().getFile(fileName);
|
||||
IFile file = fCProject.getProject().getFile(fileName);
|
||||
|
||||
InputStream stream = new ByteArrayInputStream( contents.getBytes() );
|
||||
//Create file input stream
|
||||
|
@ -106,9 +107,9 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
|
|||
|
||||
protected IFile importFileWithLink(String fileName, String contents) throws Exception{
|
||||
//Obtain file handle
|
||||
IFile file = project.getProject().getFile(fileName);
|
||||
IFile file = fCProject.getProject().getFile(fileName);
|
||||
|
||||
IPath location = new Path(project.getLocation().removeLastSegments(1).toOSString() + File.separator + fileName); //$NON-NLS-1$
|
||||
IPath location = new Path(fCProject.getProject().getLocation().removeLastSegments(1).toOSString() + File.separator + fileName); //$NON-NLS-1$
|
||||
|
||||
File linkFile = new File(location.toOSString());
|
||||
if (!linkFile.exists()) {
|
||||
|
@ -130,6 +131,7 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
|
|||
}
|
||||
|
||||
protected IFile importFileInsideLinkedFolder(String fileName, String contents, String folderName ) throws Exception{
|
||||
IProject project= fCProject.getProject();
|
||||
IFolder linkedFolder = project.getFolder(folderName);
|
||||
IPath folderLocation = new Path(project.getLocation().toOSString() + File.separator + folderName + "_this_is_linked"); //$NON-NLS-1$
|
||||
IFolder actualFolder = project.getFolder(folderName + "_this_is_linked"); //$NON-NLS-1$
|
||||
|
@ -155,7 +157,7 @@ public class BaseSelectionTestsIndexer extends BaseUITestCase {
|
|||
}
|
||||
|
||||
protected IFolder importFolder(String folderName) throws Exception {
|
||||
IFolder folder = project.getProject().getFolder(folderName);
|
||||
IFolder folder = fCProject.getProject().getFolder(folderName);
|
||||
|
||||
//Create file input stream
|
||||
if( !folder.exists() )
|
||||
|
|
|
@ -50,32 +50,19 @@ public abstract class CPPSelectionTestsAnyIndexer extends BaseSelectionTestsInde
|
|||
super.setUp();
|
||||
|
||||
//Create temp project
|
||||
ICProject cproject = createProject("CPPSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
|
||||
assertNotNull("Unable to create project", cproject);
|
||||
fCProject= createProject("CPPSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
|
||||
assertNotNull("Unable to create project", fCProject);
|
||||
// MakeProjectNature.addNature(project, new NullProgressMonitor());
|
||||
// ScannerConfigNature.addScannerConfigNature(project);
|
||||
// PerProjectSICollector.calculateCompilerBuiltins(project);
|
||||
|
||||
CCorePlugin.getPDOMManager().setIndexerId(cproject, sourceIndexerID);
|
||||
project= cproject.getProject();
|
||||
index= CCorePlugin.getIndexManager().getIndex(cproject);
|
||||
CCorePlugin.getPDOMManager().setIndexerId(fCProject, sourceIndexerID);
|
||||
index= CCorePlugin.getIndexManager().getIndex(fCProject);
|
||||
}
|
||||
|
||||
protected void tearDown() {
|
||||
try {
|
||||
protected void tearDown() throws Exception {
|
||||
CProjectHelper.delete(fCProject);
|
||||
super.tearDown();
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
//Delete project
|
||||
if (project.exists()) {
|
||||
try {
|
||||
System.gc();
|
||||
System.runFinalization();
|
||||
project.delete(true, monitor);
|
||||
} catch (CoreException e) {
|
||||
fail(getMessage(e.getStatus()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ICProject createProject(String projectName) throws CoreException {
|
||||
|
|
|
@ -49,29 +49,16 @@ public abstract class CSelectionTestsAnyIndexer extends BaseSelectionTestsIndexe
|
|||
super.setUp();
|
||||
|
||||
//Create temp project
|
||||
ICProject cproject = createProject("CSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
|
||||
assertNotNull("Unable to create project", cproject);
|
||||
fCProject = createProject("CSelectionTestsDOMIndexerProject"); //$NON-NLS-1$
|
||||
assertNotNull("Unable to create project", fCProject);
|
||||
|
||||
CCorePlugin.getPDOMManager().setIndexerId(cproject, sourceIndexerID);
|
||||
project= cproject.getProject();
|
||||
index= CCorePlugin.getIndexManager().getIndex(cproject);
|
||||
CCorePlugin.getPDOMManager().setIndexerId(fCProject, sourceIndexerID);
|
||||
index= CCorePlugin.getIndexManager().getIndex(fCProject);
|
||||
}
|
||||
|
||||
protected void tearDown() {
|
||||
try {
|
||||
protected void tearDown() throws Exception {
|
||||
CProjectHelper.delete(fCProject);
|
||||
super.tearDown();
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
//Delete project
|
||||
if (project.exists()) {
|
||||
try {
|
||||
System.gc();
|
||||
System.runFinalization();
|
||||
project.delete(true, monitor);
|
||||
} catch (CoreException e) {
|
||||
fail(getMessage(e.getStatus()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ICProject createProject(String projectName) throws CoreException {
|
||||
|
|
Loading…
Add table
Reference in a new issue