1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 01:05:38 +02:00

AST for inactive code, bug 264666.

This commit is contained in:
Markus Schorn 2009-02-24 16:01:32 +00:00
parent a401523e2f
commit 9f44be00ab
82 changed files with 1810 additions and 1270 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -129,6 +129,7 @@ public class AST2BaseTest extends BaseTestCase {
boolean expectNoProblems, boolean skipTrivialInitializers) throws ParserException { boolean expectNoProblems, boolean skipTrivialInitializers) throws ParserException {
IScanner scanner = createScanner(new CodeReader(code.toCharArray()), lang, ParserMode.COMPLETE_PARSE, IScanner scanner = createScanner(new CodeReader(code.toCharArray()), lang, ParserMode.COMPLETE_PARSE,
new ScannerInfo()); new ScannerInfo());
configureScanner(scanner);
AbstractGNUSourceCodeParser parser = null; AbstractGNUSourceCodeParser parser = null;
if (lang == ParserLanguage.CPP) { if (lang == ParserLanguage.CPP) {
ICPPParserExtensionConfiguration config = null; ICPPParserExtensionConfiguration config = null;
@ -171,6 +172,9 @@ public class AST2BaseTest extends BaseTestCase {
return tu; return tu;
} }
protected void configureScanner(IScanner scanner) {
}
public static IScanner createScanner(CodeReader codeReader, ParserLanguage lang, ParserMode mode, public static IScanner createScanner(CodeReader codeReader, ParserLanguage lang, ParserMode mode,
IScannerInfo scannerInfo) { IScannerInfo scannerInfo) {
IScannerExtensionConfiguration configuration = null; IScannerExtensionConfiguration configuration = null;
@ -492,6 +496,16 @@ public class AST2BaseTest extends BaseTestCase {
return (T) binding; return (T) binding;
} }
public void assertNoName(String section, int len) {
final int offset = contents.indexOf(section);
assertTrue(offset >= 0);
final String selection = section.substring(0, len);
IASTName name= tu.getNodeSelector(null).findName(offset, len);
if (name != null) {
fail("Found unexpected \""+selection+"\": " + name.resolveBinding());
}
}
private String renderProblemID(int i) { private String renderProblemID(int i) {
try { try {
for (Field field : IProblemBinding.class.getDeclaredFields()) { for (Field field : IProblemBinding.class.getDeclaredFields()) {
@ -523,6 +537,7 @@ public class AST2BaseTest extends BaseTestCase {
private IBinding binding(String section, int len) { private IBinding binding(String section, int len) {
final int offset = contents.indexOf(section); final int offset = contents.indexOf(section);
assertTrue(offset >= 0);
final String selection = section.substring(0, len); final String selection = section.substring(0, len);
IASTName name= tu.getNodeSelector(null).findName(offset, len); IASTName name= tu.getNodeSelector(null).findName(offset, len);
assertNotNull("did not find \""+selection+"\"", name); assertNotNull("did not find \""+selection+"\"", name);

View file

@ -0,0 +1,403 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
import java.util.BitSet;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.core.parser.ParserLanguage;
/**
* Testcases for inactive code in ast.
*/
public class ASTInactiveCodeTests extends AST2BaseTest {
public static TestSuite suite() {
return suite(ASTInactiveCodeTests.class);
}
public ASTInactiveCodeTests() {
super();
}
public ASTInactiveCodeTests(String name) {
super(name);
}
@Override
protected void configureScanner(IScanner scanner) {
super.configureScanner(scanner);
scanner.setProcessInactiveCode(true);
}
// #if %
// int a0;
// #elif %
// int a1;
// #if %
// int a2;
// #elif %
// int a3;
// #else
// int a4;
// #endif
// int a5;
// #else
// int a6;
// #endif
// int a7;
public void testIfBranches() throws Exception {
String codeTmpl= getAboveComment();
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.C, i);
}
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.CPP, i);
}
}
private void testBranches(String codeTmpl, ParserLanguage lang, int bits) throws Exception {
testBranches(codeTmpl, lang, bits, 0);
}
private void testBranches(String codeTmpl, ParserLanguage lang, int bits, int level) throws Exception {
BitSet bs= convert(bits);
char[] chars= codeTmpl.toCharArray();
int pos= codeTmpl.indexOf('%', 0);
int i= 0;
while (pos >= 0) {
chars[pos]= bs.get(i++) ? '1' : '0';
pos= codeTmpl.indexOf('%', pos+1);
}
IASTDeclarationListOwner tu= parse(new String(chars), lang);
while (level-- > 0) {
final IASTDeclaration decl = tu.getDeclarations(true)[0];
if (decl instanceof IASTSimpleDeclaration) {
tu= (IASTDeclarationListOwner) ((IASTSimpleDeclaration) decl).getDeclSpecifier();
} else {
tu= (IASTDeclarationListOwner) decl;
}
}
IASTDeclaration[] decl= tu.getDeclarations(true);
assertEquals(8, decl.length);
assertEquals(bs.get(0), decl[0].isActive());
assertEquals(!bs.get(0) && bs.get(1), decl[1].isActive());
assertEquals(!bs.get(0) && bs.get(1) && bs.get(2), decl[2].isActive());
assertEquals(!bs.get(0) && bs.get(1) && !bs.get(2) && bs.get(3), decl[3].isActive());
assertEquals(!bs.get(0) && bs.get(1) && !bs.get(2) && !bs.get(3), decl[4].isActive());
assertEquals(!bs.get(0) && bs.get(1), decl[5].isActive());
assertEquals(!bs.get(0) && !bs.get(1), decl[6].isActive());
assertEquals(true, decl[7].isActive());
}
private BitSet convert(int bits) {
BitSet result= new BitSet(32);
for (int i = 0; i < 32; i++) {
if ((bits & (1 << i)) != 0) {
result.set(i);
}
}
return result;
}
// #define A1
// #ifdef A%
// int a0;
// #elif %
// int a1;
// #if %
// int a2;
// #elif %
// int a3;
// #else
// int a4;
// #endif
// int a5;
// #else
// int a6;
// #endif
// int a7;
public void testIfdefBranches() throws Exception {
String codeTmpl= getAboveComment();
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.C, i);
}
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.CPP, i);
}
}
// #define A0
// #ifndef A%
// int a0;
// #elif %
// int a1;
// #if %
// int a2;
// #elif %
// int a3;
// #else
// int a4;
// #endif
// int a5;
// #else
// int a6;
// #endif
// int a7;
public void testIfndefBranches() throws Exception {
String codeTmpl= getAboveComment();
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.C, i);
}
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.CPP, i);
}
}
// struct S {
// #if %
// int a0;
// #elif %
// int a1;
// #if %
// int a2;
// #elif %
// int a3;
// #else
// int a4;
// #endif
// int a5;
// #else
// int a6;
// #endif
// int a7;
// };
public void testStructs() throws Exception {
String codeTmpl= getAboveComment();
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.C, i, 1);
}
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.CPP, i, 1);
}
}
// extern "C" {
// #if %
// int a0;
// #elif %
// int a1;
// #if %
// int a2;
// #elif %
// int a3;
// #else
// int a4;
// #endif
// int a5;
// #else
// int a6;
// #endif
// int a7;
// };
public void testExternC() throws Exception {
String codeTmpl= getAboveComment();
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.CPP, i, 1);
}
}
// namespace ns {
// #if %
// int a0;
// #elif %
// int a1;
// #if %
// int a2;
// #elif %
// int a3;
// #else
// int a4;
// #endif
// int a5;
// #else
// int a6;
// #endif
// int a7;
// }
public void testNamespace() throws Exception {
String codeTmpl= getAboveComment();
for (int i= 0; i < (1<<4); i++) {
testBranches(codeTmpl, ParserLanguage.CPP, i, 1);
}
}
// typedef int TInt;
// const int value= 12;
// #if 0
// int f(TInt);
// int g(value);
// #endif
public void testAmbiguity() throws Exception {
String code= getAboveComment();
IASTTranslationUnit tu= parseAndCheckBindings(code, ParserLanguage.CPP);
IASTDeclaration[] decls = tu.getDeclarations(true);
IASTSimpleDeclaration decl= (IASTSimpleDeclaration) decls[2];
assertTrue(decl.getDeclarators()[0] instanceof IASTFunctionDeclarator);
decl= (IASTSimpleDeclaration) decls[3];
assertFalse(decl.getDeclarators()[0] instanceof IASTFunctionDeclarator);
}
// int a; // 1
// #if 0
// int a; // 2
// #if 0
// int a; // 3
// #endif
// int b; // 1
// #endif
// int b; // 2
public void testDuplicateDefinition() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
bh.assertNonProblem("a; // 1", 1);
bh.assertNonProblem("a; // 2", 1);
bh.assertNonProblem("a; // 3", 1);
bh.assertNonProblem("b; // 1", 1);
bh.assertNonProblem("b; // 2", 1);
bh= new BindingAssertionHelper(code, true);
bh.assertNonProblem("a; // 1", 1);
bh.assertNonProblem("a; // 2", 1);
bh.assertNonProblem("a; // 3", 1);
bh.assertNonProblem("b; // 1", 1);
bh.assertNonProblem("b; // 2", 1);
parseAndCheckBindings(code, ParserLanguage.C);
parseAndCheckBindings(code, ParserLanguage.CPP);
}
// struct S {
// #if 0
// int a;
// };
// #else
// int b;
// };
// #endif
public void testInactiveClosingBrace() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
IField a= bh.assertNonProblem("a;", 1);
IField b= bh.assertNonProblem("b;", 1);
assertSame(a.getOwner(), b.getOwner());
bh= new BindingAssertionHelper(code, true);
a= bh.assertNonProblem("a;", 1);
b= bh.assertNonProblem("b;", 1);
assertSame(a.getOwner(), b.getOwner());
}
// struct S
// #if 1
// {
// int a;
// #else
// int b;
// #endif
// int c;
// #if 0
// int d;
// #endif
// };
public void testOpenBraceInActiveBranch() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
IField a= bh.assertNonProblem("a;", 1);
bh.assertNoName("b;", 1);
IField c= bh.assertNonProblem("c;", 1);
IField d= bh.assertNonProblem("d;", 1);
assertSame(a.getOwner(), c.getOwner());
assertSame(a.getOwner(), d.getOwner());
bh= new BindingAssertionHelper(code, true);
a= bh.assertNonProblem("a;", 1);
bh.assertNoName("b;", 1);
c= bh.assertNonProblem("c;", 1);
d= bh.assertNonProblem("d;", 1);
assertSame(a.getOwner(), c.getOwner());
assertSame(a.getOwner(), d.getOwner());
}
// #if 0
// struct S {
// #if 1
// int a;
// #else
// int b;
// #endif
// #elif 0
// int c;
// #endif
// int d;
public void testOpenBraceInInactiveBranch() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
IField a= bh.assertNonProblem("a;", 1);
IField b= bh.assertNonProblem("b;", 1);
IVariable c= bh.assertNonProblem("c;", 1); // part of a different non-nested branch
IVariable d= bh.assertNonProblem("d;", 1);
assertSame(a.getOwner(), b.getOwner());
assertNull(c.getOwner());
assertNull(d.getOwner());
bh= new BindingAssertionHelper(code, true);
a= bh.assertNonProblem("a;", 1);
b= bh.assertNonProblem("b;", 1);
c= bh.assertNonProblem("c;", 1); // part of a different non-nested branch
d= bh.assertNonProblem("d;", 1);
assertSame(a.getOwner(), b.getOwner());
assertNull(c.getOwner());
assertNull(d.getOwner());
}
// #if 0
// void f() {
// #if 1
// int a;
// #elif 0
// int b;
// #endif
// }
// #endif
public void testUnexpectedBranchesInInactiveCode() throws Exception {
String code= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, false);
IFunction f= bh.assertNonProblem("f()", 1);
bh.assertNoName("a;", 1);
bh.assertNoName("b;", 1);
bh= new BindingAssertionHelper(code, true);
f= bh.assertNonProblem("f()", 1);
bh.assertNoName("a;", 1);
bh.assertNoName("b;", 1);
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -52,6 +52,7 @@ public class DOMParserTestSuite extends TestCase {
suite.addTestSuite(CharArrayMapTest.class); suite.addTestSuite(CharArrayMapTest.class);
suite.addTest(FaultToleranceTests.suite()); suite.addTest(FaultToleranceTests.suite());
suite.addTest(LanguageExtensionsTest.suite()); suite.addTest(LanguageExtensionsTest.suite());
suite.addTest(ASTInactiveCodeTests.suite());
return suite; return suite;
} }
} }

View file

@ -14,7 +14,9 @@ package org.eclipse.cdt.core.model;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
@ -69,9 +71,13 @@ public interface ILanguage extends IAdaptable {
/** /**
* Option for {@link #getASTTranslationUnit(CodeReader, IScannerInfo, ICodeReaderFactory, IIndex, int, IParserLogService)} * Option for {@link #getASTTranslationUnit(CodeReader, IScannerInfo, ICodeReaderFactory, IIndex, int, IParserLogService)}
* Instructs the parser to create ast nodes for inactive code branches, if possible. There is no guarantee that the ast * Instructs the parser to create ast nodes for inactive code branches, if possible. The parser
* can actually be created for the inactive parts. * makes its best effort to create ast for the inactive code branches but may decide to skip parts
* mstodo document how the ast can be accessed. * of the inactive code (e.g. function bodies, entire code branches, etc.).
* <p>
* The inactive nodes can be accessed via {@link IASTDeclarationListOwner#getDeclarations(boolean)} or
* by using a visitor with {@link ASTVisitor#includeInactiveNodes} set to <code>true</code>.
*
* @since 5.1 * @since 5.1
*/ */
public final static int OPTION_PARSE_INACTIVE_CODE= 0x20; public final static int OPTION_PARSE_INACTIVE_CODE= 0x20;

View file

@ -13,7 +13,9 @@ package org.eclipse.cdt.core.model;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
@ -97,8 +99,13 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
/** /**
* Style constant for {@link #getAST(IIndex, int)}. * Style constant for {@link #getAST(IIndex, int)}.
* Instructs the parser to make an attempt to create ast nodes for inactive code branches. * Instructs the parser to make an attempt to create ast nodes for inactive code branches. The parser
* mstodo document how to access those. * makes its best effort to create ast for the inactive code branches but may decide to skip parts
* of the inactive code (e.g. function bodies, entire code branches, etc.).
* <p>
* The inactive nodes can be accessed via {@link IASTDeclarationListOwner#getDeclarations(boolean)} or
* by using a visitor with {@link ASTVisitor#includeInactiveNodes} set to <code>true</code>.
*
* @since 5.1 * @since 5.1
*/ */
public final static int AST_PARSE_INACTIVE_CODE= 0x80; public final static int AST_PARSE_INACTIVE_CODE= 0x80;

View file

@ -210,7 +210,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
} }
} }
// declarations // declarations
final IASTDeclaration[] declarations= ast.getDeclarations(); final IASTDeclaration[] declarations= ast.getDeclarations(true);
for (IASTDeclaration declaration : declarations) { for (IASTDeclaration declaration : declarations) {
if (isLocalToFile(declaration)) { if (isLocalToFile(declaration)) {
createDeclaration(fTranslationUnit, declaration); createDeclaration(fTranslationUnit, declaration);
@ -405,7 +405,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
* @throws DOMException * @throws DOMException
*/ */
private void createLinkageSpecification(Parent parent, ICPPASTLinkageSpecification linkageDeclaration) throws CModelException, DOMException { private void createLinkageSpecification(Parent parent, ICPPASTLinkageSpecification linkageDeclaration) throws CModelException, DOMException {
IASTDeclaration[] declarations= linkageDeclaration.getDeclarations(); IASTDeclaration[] declarations= linkageDeclaration.getDeclarations(true);
for (IASTDeclaration declaration : declarations) { for (IASTDeclaration declaration : declarations) {
if (linkageDeclaration.getFileLocation() != null || isLocalToFile(declaration)) { if (linkageDeclaration.getFileLocation() != null || isLocalToFile(declaration)) {
createDeclaration(parent, declaration); createDeclaration(parent, declaration);
@ -489,6 +489,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final String nsName= ASTStringUtil.getQualifiedName(name); final String nsName= ASTStringUtil.getQualifiedName(name);
final Namespace element= new Namespace(parent, nsName); final Namespace element= new Namespace(parent, nsName);
setIndex(element); setIndex(element);
element.setActive(declaration.isActive());
// add to parent // add to parent
parent.addChild(element); parent.addChild(element);
@ -505,7 +506,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element.setTypeName(type); element.setTypeName(type);
IASTDeclaration[] nsDeclarations= declaration.getDeclarations(); IASTDeclaration[] nsDeclarations= declaration.getDeclarations(true);
for (IASTDeclaration nsDeclaration : nsDeclarations) { for (IASTDeclaration nsDeclaration : nsDeclarations) {
if (declaration.getFileLocation() != null || isLocalToFile(nsDeclaration)) { if (declaration.getFileLocation() != null || isLocalToFile(nsDeclaration)) {
createDeclaration(element, nsDeclaration); createDeclaration(element, nsDeclaration);
@ -551,6 +552,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element= new StructureDeclaration(parent, className, kind); element= new StructureDeclaration(parent, className, kind);
} }
setIndex(element); setIndex(element);
element.setActive(elaboratedTypeSpecifier.isActive());
element.setTypeName(type); element.setTypeName(type);
// add to parent // add to parent
@ -576,6 +578,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final String enumName= ASTStringUtil.getSimpleName(astEnumName); final String enumName= ASTStringUtil.getSimpleName(astEnumName);
final Enumeration element= new Enumeration (parent, enumName); final Enumeration element= new Enumeration (parent, enumName);
setIndex(element); setIndex(element);
element.setActive(enumSpecifier.isActive());
// add to parent // add to parent
parent.addChild(element); parent.addChild(element);
@ -599,6 +602,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final IASTName astEnumName= enumDef.getName(); final IASTName astEnumName= enumDef.getName();
final Enumerator element= new Enumerator (enumarator, ASTStringUtil.getSimpleName(astEnumName)); final Enumerator element= new Enumerator (enumarator, ASTStringUtil.getSimpleName(astEnumName));
setIndex(element); setIndex(element);
element.setActive(enumDef.isActive());
IASTExpression initialValue= enumDef.getValue(); IASTExpression initialValue= enumDef.getValue();
if(initialValue != null){ if(initialValue != null){
@ -652,6 +656,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element= classTemplate; element= classTemplate;
} }
setIndex(element); setIndex(element);
element.setActive(compositeTypeSpecifier.isActive());
if (compositeTypeSpecifier instanceof ICPPASTCompositeTypeSpecifier) { if (compositeTypeSpecifier instanceof ICPPASTCompositeTypeSpecifier) {
// store super classes names // store super classes names
@ -696,7 +701,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// add members // add members
pushDefaultVisibility(defaultVisibility); pushDefaultVisibility(defaultVisibility);
try { try {
final IASTDeclaration[] memberDeclarations= compositeTypeSpecifier.getMembers(); final IASTDeclaration[] memberDeclarations= compositeTypeSpecifier.getDeclarations(true);
for (IASTDeclaration member : memberDeclarations) { for (IASTDeclaration member : memberDeclarations) {
if (compositeTypeSpecifier.getFileLocation() != null || isLocalToFile(member)) { if (compositeTypeSpecifier.getFileLocation() != null || isLocalToFile(member)) {
createDeclaration(element, member); createDeclaration(element, member);
@ -722,6 +727,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final TypeDef element= new TypeDef(parent, name); final TypeDef element= new TypeDef(parent, name);
setIndex(element); setIndex(element);
element.setActive(declarator.isActive());
String typeName= ASTStringUtil.getSignatureString(declSpecifier, declarator); String typeName= ASTStringUtil.getSignatureString(declSpecifier, declarator);
element.setTypeName(typeName); element.setTypeName(typeName);
@ -792,6 +798,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
element.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator)); element.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
info= element.getSourceManipulationInfo(); info= element.getSourceManipulationInfo();
} }
element.setActive(declarator.isActive());
element.setConst(specifier.isConst()); element.setConst(specifier.isConst());
element.setVolatile(specifier.isVolatile()); element.setVolatile(specifier.isVolatile());
// TODO [cmodel] correctly resolve isStatic // TODO [cmodel] correctly resolve isStatic
@ -958,6 +965,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
info= element.getFunctionInfo(); info= element.getFunctionInfo();
} }
element.setActive(functionDeclaration.isActive());
// TODO [cmodel] correctly resolve isStatic // TODO [cmodel] correctly resolve isStatic
info.setStatic(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static); info.setStatic(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static);
@ -1048,6 +1056,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
assert false; assert false;
return null; return null;
} }
element.setActive(declarator.isActive());
// TODO [cmodel] correctly resolve isStatic // TODO [cmodel] correctly resolve isStatic
info.setStatic(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static); info.setStatic(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static);
@ -1068,6 +1077,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
IASTName name= usingDirDeclaration.getQualifiedName(); IASTName name= usingDirDeclaration.getQualifiedName();
Using element= new Using(parent, ASTStringUtil.getQualifiedName(name), true); Using element= new Using(parent, ASTStringUtil.getQualifiedName(name), true);
setIndex(element); setIndex(element);
element.setActive(usingDirDeclaration.isActive());
// add to parent // add to parent
parent.addChild(element); parent.addChild(element);
@ -1083,7 +1093,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
IASTName name= usingDeclaration.getName(); IASTName name= usingDeclaration.getName();
Using element= new Using(parent, ASTStringUtil.getSimpleName(name), false); Using element= new Using(parent, ASTStringUtil.getSimpleName(name), false);
setIndex(element); setIndex(element);
element.setActive(usingDeclaration.isActive());
// add to parent // add to parent
parent.addChild(element); parent.addChild(element);

View file

@ -119,6 +119,13 @@ public abstract class ASTVisitor {
*/ */
public boolean shouldVisitTemplateParameters = false; public boolean shouldVisitTemplateParameters = false;
/**
* Per default inactive nodes are not visited. You can change that by setting
* this flag to <code>true</code>.
* @since 5.1
*/
public boolean includeInactiveNodes= false;
/** /**
* For internal use, only. * For internal use, only.
* @noreference This field is not intended to be referenced by clients. * @noreference This field is not intended to be referenced by clients.
@ -134,7 +141,8 @@ public abstract class ASTVisitor {
/** /**
* Creates a visitor. * Creates a visitor.
* @param visitNodes whether visitor is setup to visit all nodes per default. * @param visitNodes whether visitor is setup to visit all nodes per default, except
* ambiguous nodes ({@link #shouldVisitAmbiguousNodes}) and inactive nodes ({@link #includeInactiveNodes}).
* @since 5.1 * @since 5.1
*/ */
public ASTVisitor(boolean visitNodes) { public ASTVisitor(boolean visitNodes) {

View file

@ -17,7 +17,7 @@ package org.eclipse.cdt.core.dom.ast;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface IASTCompositeTypeSpecifier extends IASTDeclSpecifier , IASTNameOwner { public interface IASTCompositeTypeSpecifier extends IASTDeclSpecifier , IASTNameOwner, IASTDeclarationListOwner {
/** /**
* <code>TYPE_NAME</code> represents the relationship between an * <code>TYPE_NAME</code> represents the relationship between an

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.core.model.ITranslationUnit;
/**
* Common interface for parents of declaration lists.
* @since 5.1
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IASTDeclarationListOwner extends IASTNode {
/**
* Adds a declaration to the owner. May only be called as long as the ast is not frozen.
*/
void addDeclaration(IASTDeclaration declaration);
/**
* Returns the array of declarations.
* @param includeInactive whether to include declarations from inactive code branches.
* @see ITranslationUnit#AST_PARSE_INACTIVE_CODE
* @since 5.1
*/
IASTDeclaration[] getDeclarations(boolean includeInactive);
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -208,6 +208,11 @@ public interface IASTNode {
*/ */
public boolean isFrozen(); public boolean isFrozen();
/**
* Returns false if this node was parsed in an inactive code branch.
* @since 5.1
*/
public boolean isActive();
/** /**
* Returns a copy of the tree rooted at this node. * Returns a copy of the tree rooted at this node.

View file

@ -23,7 +23,7 @@ import org.eclipse.core.runtime.IAdaptable;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface IASTTranslationUnit extends IASTNode, IAdaptable { public interface IASTTranslationUnit extends IASTNode, IASTDeclarationListOwner, IAdaptable {
/** /**
* <code>OWNED_DECLARATION</code> represents the relationship between an <code>IASTTranslationUnit</code> and * <code>OWNED_DECLARATION</code> represents the relationship between an <code>IASTTranslationUnit</code> and

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.core.dom.ast.c; package org.eclipse.cdt.core.dom.ast.c;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
/** /**
* Structs and Unions in C can be qualified w/restrict keyword. * Structs and Unions in C can be qualified w/restrict keyword.
@ -18,8 +19,8 @@ import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICASTCompositeTypeSpecifier extends public interface ICASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifier, ICASTDeclSpecifier,
IASTCompositeTypeSpecifier, ICASTDeclSpecifier { IASTDeclarationListOwner {
/** /**
* @since 5.1 * @since 5.1

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -21,6 +21,20 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
*/ */
public abstract class CPPASTVisitor extends ASTVisitor implements ICPPASTVisitor { public abstract class CPPASTVisitor extends ASTVisitor implements ICPPASTVisitor {
/**
* @see ASTVisitor#ASTVisitor()
*/
public CPPASTVisitor() {
}
/**
* @see ASTVisitor#ASTVisitor(boolean)
* @since 5.1
*/
public CPPASTVisitor(boolean visitNodes) {
super(visitNodes);
}
public int visit(ICPPASTBaseSpecifier baseSpecifier) { public int visit(ICPPASTBaseSpecifier baseSpecifier) {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
@ -21,8 +22,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPASTCompositeTypeSpecifier extends public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifier, ICPPASTDeclSpecifier,
IASTCompositeTypeSpecifier, ICPPASTDeclSpecifier { IASTDeclarationListOwner {
/** /**
* <code>k_class</code> C++ introduces the class concept for composite * <code>k_class</code> C++ introduces the class concept for composite

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
/** /**
* This interface represents a linkage specification. e.g. extern "C" { ... } * This interface represents a linkage specification. e.g. extern "C" { ... }
@ -19,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPASTLinkageSpecification extends IASTDeclaration { public interface ICPPASTLinkageSpecification extends IASTDeclaration, IASTDeclarationListOwner {
/** /**
* Get the "literal" that represents the linkage. * Get the "literal" that represents the linkage.

View file

@ -12,17 +12,18 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
/** /**
* This interface repesents a namespace definition in C++. * This interface represents a namespace definition in C++.
* *
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPASTNamespaceDefinition extends IASTDeclaration, IASTNameOwner { public interface ICPPASTNamespaceDefinition extends IASTDeclaration, IASTNameOwner, IASTDeclarationListOwner {
/** /**
* <code>OWNED_DECLARATION</code> is the role served by all the nested * <code>OWNED_DECLARATION</code> is the role served by all the nested

View file

@ -14,7 +14,26 @@ package org.eclipse.cdt.core.parser;
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noinstantiate This class is not intended to be instantiated by clients. * @noinstantiate This class is not intended to be instantiated by clients.
*/ */
public class EndOfFileException extends Exception public class EndOfFileException extends Exception {
{
private static final long serialVersionUID= 1607883323361197919L; private static final long serialVersionUID= 1607883323361197919L;
private final boolean fEndsInactiveCode;
public EndOfFileException() {
fEndsInactiveCode= false;
}
/**
* @since 5.1
*/
public EndOfFileException(boolean endsInactiveCode) {
fEndsInactiveCode= true;
}
/**
* @since 5.1
*/
public boolean endsInactiveCode() {
return fEndsInactiveCode;
}
} }

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser;
/**
* Interface for tokens of kind {@link IToken#tINACTIVE_CODE_START}, {@link IToken#tINACTIVE_CODE_SEPARATOR} and
* {@link IToken#tINACTIVE_CODE_END}.
* @since 5.1
*/
public interface IInactiveCodeToken extends IToken {
/**
* @return {@code 0} for the start-token of the outermost branch (indicates that code in the
* translation-unit outside of any branches precedes this token). <br>
* A value greater than 0 indicating how deep the code preceding this token is nested
* within code branches, otherwise.
*/
int getOldNesting();
/**
* @return {@code 0} for the end-token of the outermost branch (indicates that code in the
* translation-unit outside of any branches will follow). <br>
* A value greater than 0 indicating how deep the code following this token is nested
* within code branches, otherwise.
*/
int getNewNesting();
}

View file

@ -98,4 +98,12 @@ public interface IScanner {
* @noreference This method is not intended to be referenced by clients. * @noreference This method is not intended to be referenced by clients.
*/ */
public void skipInactiveCode() throws OffsetLimitReachedException; public void skipInactiveCode() throws OffsetLimitReachedException;
/**
* Returns the current nesting in code branches.
* @see IInactiveCodeToken#getOldNesting()
* @see IInactiveCodeToken#getNewNesting()
* @noreference This method is not intended to be referenced by clients.
*/
public int getCodeBranchNesting();
} }

View file

@ -27,10 +27,13 @@ public interface IToken {
public int getEndOffset(); public int getEndOffset();
public IToken getNext(); public IToken getNext();
public void setNext(IToken t); public void setNext(IToken t);
public void setType(int i); public void setType(int i);
/**
* @noreference This method is not intended to be referenced by clients.
*/
@Deprecated
public boolean isOperator(); public boolean isOperator();
// Token types // Token types

View file

@ -28,7 +28,6 @@ import org.eclipse.core.runtime.CoreException;
* Access to methods on scopes and bindings internal to the parser. * Access to methods on scopes and bindings internal to the parser.
*/ */
public class ASTInternal { public class ASTInternal {
public static IASTNode[] getDeclarationsOfBinding(IBinding binding) { public static IASTNode[] getDeclarationsOfBinding(IBinding binding) {
if( binding instanceof ICPPInternalBinding ) { if( binding instanceof ICPPInternalBinding ) {
return ((ICPPInternalBinding)binding).getDeclarations(); return ((ICPPInternalBinding)binding).getDeclarations();
@ -171,4 +170,16 @@ public class ASTInternal {
} }
return filePath; return filePath;
} }
public static void addDeclaration(IBinding b, IASTNode declaration) {
if (b instanceof ICPPInternalBinding && declaration.isActive()) {
((ICPPInternalBinding) b).addDeclaration(declaration);
}
}
public static void addDefinition(IBinding b, IASTNode declaration) {
if (b instanceof ICPPInternalBinding && declaration.isActive()) {
((ICPPInternalBinding) b).addDefinition(declaration);
}
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -42,6 +42,7 @@ public abstract class ASTNode implements IASTNode {
private int offset; private int offset;
private boolean frozen = false; private boolean frozen = false;
private boolean active = true;
public IASTNode getParent() { public IASTNode getParent() {
return parent; return parent;
@ -56,6 +57,10 @@ public abstract class ASTNode implements IASTNode {
return frozen; return frozen;
} }
public boolean isActive() {
return active;
}
public void freeze() { public void freeze() {
frozen = true; frozen = true;
for(IASTNode child : getChildren()) { for(IASTNode child : getChildren()) {
@ -65,6 +70,12 @@ public abstract class ASTNode implements IASTNode {
} }
} }
public void setInactive() {
if(frozen)
throw new IllegalStateException("attempt to modify frozen AST node"); //$NON-NLS-1$
active= false;
}
protected void assertNotFrozen() throws IllegalStateException { protected void assertNotFrozen() throws IllegalStateException {
if(frozen) if(frozen)
throw new IllegalStateException("attempt to modify frozen AST node"); //$NON-NLS-1$ throw new IllegalStateException("attempt to modify frozen AST node"); //$NON-NLS-1$

View file

@ -10,19 +10,16 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -30,43 +27,38 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
* Base class for {@link CVisitor} and {@link CPPVisitor} * Base class for {@link CVisitor} and {@link CPPVisitor}
*/ */
public class ASTQueries { public class ASTQueries {
private static class NameSearch extends ASTVisitor {
private boolean fFound;
NameSearch() {
super(false);
shouldVisitAmbiguousNodes= true;
shouldVisitNames= true;
}
public void reset() {
fFound= false;
}
public boolean foundName() {
return fFound;
}
@Override
public int visit(IASTName name) {
fFound= true;
return PROCESS_ABORT;
}
}
private static NameSearch NAME_SEARCH= new NameSearch();
/** /**
* Tests whether the given expression can contain ast-names, suitable to be used before ambiguity * Tests whether the given expression can contain ast-names, suitable to be used before ambiguity
* resolution. * resolution.
*/ */
public static boolean canContainName(IASTExpression expr) { public static boolean canContainName(IASTExpression expr) {
if (expr == null || expr instanceof IASTLiteralExpression) if (expr == null)
return false; return false;
if (expr instanceof IASTAmbiguousExpression) NAME_SEARCH.reset();
return true; expr.accept(NAME_SEARCH);
if (expr instanceof IASTIdExpression) return NAME_SEARCH.foundName();
return true;
if (expr instanceof IASTCastExpression)
return true;
if (expr instanceof IASTUnaryExpression) {
IASTUnaryExpression uexpr= (IASTUnaryExpression) expr;
return canContainName(uexpr.getOperand());
}
if (expr instanceof IASTBinaryExpression) {
IASTBinaryExpression bexpr= (IASTBinaryExpression) expr;
return canContainName(bexpr.getOperand1()) || canContainName(bexpr.getOperand2());
}
if (expr instanceof IASTConditionalExpression) {
IASTConditionalExpression cexpr= (IASTConditionalExpression) expr;
return canContainName(cexpr.getLogicalConditionExpression()) ||
canContainName(cexpr.getPositiveResultExpression()) || canContainName(cexpr.getNegativeResultExpression());
}
if (expr instanceof IASTExpressionList) {
IASTExpressionList lexpr= (IASTExpressionList) expr;
IASTExpression[] subexprs= lexpr.getExpressions();
for (IASTExpression subexpr : subexprs) {
if (canContainName(subexpr))
return true;
}
}
return true;
} }
/** /**
@ -114,4 +106,25 @@ public class ASTQueries {
} }
return result; return result;
} }
/**
* Extracts the active declarations from an array of declarations.
*/
public static IASTDeclaration[] extractActiveDeclarations(final IASTDeclaration[] allDeclarations, final int size) {
IASTDeclaration[] active;
if (size == 0) {
active= IASTDeclaration.EMPTY_DECLARATION_ARRAY;
} else {
active= new IASTDeclaration[size];
int j= 0;
for (int i = 0; i < size; i++) {
IASTDeclaration d= allDeclarations[i];
if (d.isActive()) {
active[j++]= d;
}
}
active= (IASTDeclaration[]) ArrayUtil.removeNullsAfter(IASTDeclaration.class, active, j-1);
}
return active;
}
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -16,7 +16,6 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTComment; import org.eclipse.cdt.core.dom.ast.IASTComment;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
@ -36,7 +35,6 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver; import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener; import org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent; import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent;
@ -54,8 +52,9 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
private static final IASTProblem[] EMPTY_PROBLEM_ARRAY = new IASTProblem[0]; private static final IASTProblem[] EMPTY_PROBLEM_ARRAY = new IASTProblem[0];
private static final String EMPTY_STRING = ""; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$
protected IASTDeclaration[] fDeclarations = null; private IASTDeclaration[] fAllDeclarations = null;
protected int fLastDeclaration=-1; private IASTDeclaration[] fActiveDeclarations= null;
private int fLastDeclaration=-1;
protected ILocationResolver fLocationResolver; protected ILocationResolver fLocationResolver;
private IIndex fIndex; private IIndex fIndex;
@ -73,19 +72,39 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
if (d != null) { if (d != null) {
d.setParent(this); d.setParent(this);
d.setPropertyInParent(OWNED_DECLARATION); d.setPropertyInParent(OWNED_DECLARATION);
fDeclarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, fDeclarations, ++fLastDeclaration, d); fAllDeclarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, fAllDeclarations, ++fLastDeclaration, d);
fActiveDeclarations= null;
} }
} }
/*
* (non-Javadoc)
*
* @see org.eclipse.cdt.core.dom.ast.IASTTranslationUnit#getDeclarations()
*/
public final IASTDeclaration[] getDeclarations() { public final IASTDeclaration[] getDeclarations() {
if (fDeclarations == null) return IASTDeclaration.EMPTY_DECLARATION_ARRAY; IASTDeclaration[] active= fActiveDeclarations;
fDeclarations= (IASTDeclaration[]) ArrayUtil.removeNullsAfter( IASTDeclaration.class, fDeclarations, fLastDeclaration); if (active == null) {
return fDeclarations; active = ASTQueries.extractActiveDeclarations(fAllDeclarations, fLastDeclaration+1);
fActiveDeclarations= active;
}
return active;
}
public final IASTDeclaration[] getDeclarations(boolean includeInactive) {
if (includeInactive) {
fAllDeclarations= (IASTDeclaration[]) ArrayUtil.removeNullsAfter(IASTDeclaration.class, fAllDeclarations, fLastDeclaration);
return fAllDeclarations;
}
return getDeclarations();
}
public final void replace(IASTNode child, IASTNode other) {
assert child.isActive() == other.isActive();
for (int i = 0; i <= fLastDeclaration; ++i) {
if (fAllDeclarations[i] == child) {
other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent());
fAllDeclarations[i] = (IASTDeclaration) other;
fActiveDeclarations= null;
return;
}
}
} }
/* /*
@ -242,17 +261,14 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
default : break; default : break;
} }
} }
IASTDeclaration [] ds = getDeclarations(); IASTDeclaration[] decls = getDeclarations(action.includeInactiveNodes);
for( int i = 0; i < ds.length; i++ ){ for (IASTDeclaration decl : decls) {
if( !ds[i].accept( action ) ) return false; if (!decl.accept(action)) return false;
}
if( action.shouldVisitTranslationUnit){
switch( action.leave( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
} }
if (action.shouldVisitTranslationUnit && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
return true; return true;
} }
@ -354,35 +370,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
/** /**
* Must be called by the parser, before the ast is passed to the clients. * Must be called by the parser, before the ast is passed to the clients.
*/ */
public void resolveAmbiguities() { public abstract void resolveAmbiguities();
accept(createAmbiguityNodeVisitor());
cleanupAfterAmbiguityResolution();
}
protected abstract ASTVisitor createAmbiguityNodeVisitor();
protected void cleanupAfterAmbiguityResolution() {
// clear bindings (see bug 232811)
accept(new ASTVisitor(){
{
shouldVisitNames= true;
shouldVisitDeclSpecifiers= true;
}
@Override
public int visit(IASTName name) {
name.setBinding(null);
return PROCESS_CONTINUE;
}
@Override
public int visit(IASTDeclSpecifier declSpec) {
if (declSpec instanceof CPPASTCompositeTypeSpecifier)
((CPPASTCompositeTypeSpecifier) declSpec).setScope(null);
return PROCESS_CONTINUE;
}
});
}
protected void copyAbstractTU(ASTTranslationUnit copy) { protected void copyAbstractTU(ASTTranslationUnit copy) {
copy.setIndex(fIndex); copy.setIndex(fIndex);

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration; import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
@ -22,11 +23,13 @@ import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTContinueStatement; import org.eclipse.cdt.core.dom.ast.IASTContinueStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationListOwner;
import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
@ -70,6 +73,7 @@ import org.eclipse.cdt.core.dom.parser.ISourceCodeParser;
import org.eclipse.cdt.core.parser.AbstractParserLogService; import org.eclipse.cdt.core.parser.AbstractParserLogService;
import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.EndOfFileException;
import org.eclipse.cdt.core.parser.IGCCToken; import org.eclipse.cdt.core.parser.IGCCToken;
import org.eclipse.cdt.core.parser.IInactiveCodeToken;
import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
@ -108,6 +112,17 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
} }
private static final ASTVisitor MARK_INACTIVE = new ASTGenericVisitor(true) {
{
shouldVisitAmbiguousNodes= true;
}
@Override
protected int genericVisit(IASTNode node) {
((ASTNode) node).setInactive();
return PROCESS_CONTINUE;
}
};
protected static final int DEFAULT_DESIGNATOR_LIST_SIZE = 4; protected static final int DEFAULT_DESIGNATOR_LIST_SIZE = 4;
protected static int parseCount = 0; protected static int parseCount = 0;
@ -135,8 +150,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* enter a nested declaration, in order to avoid holding on to all the tokens. * enter a nested declaration, in order to avoid holding on to all the tokens.
*/ */
protected IToken declarationMark; protected IToken declarationMark;
protected IToken currToken; protected IToken nextToken;
protected int eofOffset; protected IToken lastTokenFromScanner;
protected boolean onTopInTemplateArgs= false; protected boolean onTopInTemplateArgs= false;
protected boolean inBinaryExpression= true; protected boolean inBinaryExpression= true;
@ -149,6 +164,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTTypeId fTypeIdForCastAmbiguity; protected IASTTypeId fTypeIdForCastAmbiguity;
private final INodeFactory nodeFactory; private final INodeFactory nodeFactory;
private boolean fActiveCode= true;
protected AbstractGNUSourceCodeParser(IScanner scanner, protected AbstractGNUSourceCodeParser(IScanner scanner,
IParserLogService logService, ParserMode parserMode, IParserLogService logService, ParserMode parserMode,
@ -206,43 +222,179 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
/** /**
* Returns the next token without advancing * Fetches the next token from the scanner.
*/ */
protected IToken mark() throws EndOfFileException { private final IToken fetchToken(boolean skipInactive) throws EndOfFileException {
return currToken == null ? currToken = fetchToken(true) : currToken; try {
IToken t= scanner.nextToken();
if (skipInactive) {
while (t.getType() == IToken.tINACTIVE_CODE_START) {
scanner.skipInactiveCode();
t= scanner.nextToken();
}
}
if (lastTokenFromScanner != null)
lastTokenFromScanner.setNext(t);
lastTokenFromScanner= t;
return t;
} catch (OffsetLimitReachedException olre) {
if (mode != ParserMode.COMPLETION_PARSE)
throw new EndOfFileException();
createCompletionNode(olre.getFinalToken());
throw olre;
}
}
private final IToken nextToken(boolean skipInactive) throws EndOfFileException {
IToken t= nextToken;
if (t == null) {
t= fetchToken(skipInactive);
}
nextToken= t;
return t;
}
private final IToken lookaheadToken(int i, boolean skipInactive) throws EndOfFileException {
assert i >= 0;
if (isCancelled) {
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
}
IToken t= nextToken(skipInactive);
for (; i > 1; --i) {
t = t.getNext();
if (t == null)
t = fetchToken(skipInactive);
}
return t;
}
/**
* Returns the next token without advancing. Same as {@code LA(1)}.
*/
protected final IToken LA() throws EndOfFileException {
IToken t= nextToken(true);
checkForEOI(t);
return t;
}
/**
* Returns one of the next tokens. With {@code i == 1}, the next token is returned.
* @param i number of tokens to look ahead, must be greater than 0.
*/
protected final IToken LA(int i) throws EndOfFileException {
IToken t= lookaheadToken(i, true);
checkForEOI(t);
return t;
}
/**
* Consumes and returns the next token available.
*/
protected final IToken consume() throws EndOfFileException {
IToken t= nextToken(true);
checkForEOI(t);
nextToken= t.getNext();
return t;
}
/**
* Tests whether we are looking at a change from active to inactive code at this point. If so, the change
* is accepted.
*
* @param nesting
* the nesting level of the code branch we have to stay within
* @return <code>false</code> if an inactive code branch was rejected because of its nesting level,
* <code>true</code>, otherwise.
*/
protected final boolean acceptInactiveCodeBoundary(int nesting) {
try {
while (true) {
IToken t= nextToken(false);
switch (t.getType()) {
case IToken.tINACTIVE_CODE_START:
case IToken.tINACTIVE_CODE_SEPARATOR:
IInactiveCodeToken it = (IInactiveCodeToken) t;
if (it.getNewNesting() < nesting || (it.getNewNesting() == nesting && it.getOldNesting() == nesting)) {
return false;
}
fActiveCode= false;
nextToken= t.getNext(); // consume the token
continue;
case IToken.tINACTIVE_CODE_END:
it = (IInactiveCodeToken) t;
if (it.getNewNesting() < nesting || (it.getNewNesting() == nesting && it.getOldNesting() == nesting)) {
return false;
}
fActiveCode= true;
nextToken= t.getNext(); // consume the token
continue;
default:
return true;
}
}
} catch (EndOfFileException e) {
}
return true;
}
protected final void skipInactiveCode() throws OffsetLimitReachedException {
IToken t= nextToken;
if (fActiveCode && (t == null || t.getType() != IToken.tINACTIVE_CODE_START))
return;
try {
fActiveCode= true;
while (t != null && t.getType() != IToken.tINACTIVE_CODE_END)
t= t.getNext();
if (t != null) {
nextToken= t.getNext();
} else {
nextToken= null;
scanner.skipInactiveCode();
}
} catch (OffsetLimitReachedException olre) {
if (mode == ParserMode.COMPLETION_PARSE) {
createCompletionNode(olre.getFinalToken());
throw olre;
}
}
}
protected final boolean isActiveCode() {
return fActiveCode;
}
protected final int getCodeBranchNesting() {
return scanner.getCodeBranchNesting();
}
/**
* Returns the next token, which can be used to reset the input back to
* this point in the stream.
*/
protected final IToken mark() throws EndOfFileException {
return LA();
} }
/** /**
* Roll back to a previous point, reseting the queue of tokens. * Roll back to a previous point, reseting the queue of tokens.
* @param mark a token previously obtained via {@link #mark()}. * @param mark a token previously obtained via {@link #mark()}.
*/ */
protected void backup(IToken mark) { protected final void backup(IToken mark) {
currToken = mark; nextToken = mark;
} }
/** private final void checkForEOI(IToken t) throws EndOfFileException {
* Look ahead in the token list to see what is coming. final int lt= t.getType();
* @param i number of tokens to look ahead, must be greater or equal to 0. if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END)
* @return the token you wish to observe throw new EndOfFileException(true);
*/
protected IToken LA(int i) throws EndOfFileException {
assert i >= 0;
if (isCancelled) {
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
}
IToken retToken= mark();
for (; i > 1; --i) {
retToken = retToken.getNext();
if (retToken == null)
retToken = fetchToken(true);
}
return retToken;
} }
/** /**
* Same as {@link #LA(int)}, but returns <code>null</code> when eof is reached. * Same as {@link #LA(int)}, but returns <code>null</code> when eof is reached.
*/ */
protected IToken LAcatchEOF(int i) { protected final IToken LAcatchEOF(int i) {
try { try {
return LA(i); return LA(i);
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
@ -255,14 +407,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
* @param i number of tokens to look ahead, must be greater or equal to 0. * @param i number of tokens to look ahead, must be greater or equal to 0.
* @return The type of that token * @return The type of that token
*/ */
protected int LT(int i) throws EndOfFileException { protected final int LT(int i) throws EndOfFileException {
return LA(i).getType(); return LA(i).getType();
} }
/** /**
* Same as {@link #LT(int)}, but returns <code>0</code> when eof is reached. * Same as {@link #LT(int)}, but returns <code>0</code> when eof is reached.
*/ */
protected int LTcatchEOF(int i) { protected final int LTcatchEOF(int i) {
try { try {
return LT(i); return LT(i);
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
@ -270,52 +422,12 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
} }
protected boolean isOnSameLine(int offset1, int offset2) {
ILocationResolver lr= (ILocationResolver) getTranslationUnit().getAdapter(ILocationResolver.class);
IASTFileLocation floc= lr.getMappedFileLocation(offset1, offset2-offset1+1);
return floc.getFileName().equals(lr.getContainingFilePath(offset1)) &&
floc.getStartingLineNumber() == floc.getEndingLineNumber();
}
protected int calculateEndOffset(IASTNode n) {
ASTNode node = (ASTNode) n;
return node.getOffset() + node.getLength();
}
protected void setRange(IASTNode n, IASTNode from) {
((ASTNode) n).setOffsetAndLength((ASTNode) from);
}
protected void setRange(IASTNode n, int offset, int endOffset) {
((ASTNode) n).setOffsetAndLength(offset, endOffset-offset);
}
protected void adjustLength(IASTNode n, IASTNode endNode) {
final int endOffset= calculateEndOffset(endNode);
final ASTNode node = (ASTNode) n;
node.setLength(endOffset-node.getOffset());
}
/**
* Consume the next token available, regardless of the type and returns it.
*
* @return The token that was consumed and removed from our buffer.
* @throws EndOfFileException
* If there is no token to consume.
*/
protected IToken consume() throws EndOfFileException {
final IToken result= mark();
currToken= result.getNext();
return result;
}
/** /**
* If the type of the next token matches, it is consumed and returned. Otherwise a * If the type of the next token matches, it is consumed and returned. Otherwise a
* {@link BacktrackException} will be thrown. * {@link BacktrackException} will be thrown.
*
* @param type the expected type of the next token. * @param type the expected type of the next token.
*/ */
protected IToken consume(int type) throws EndOfFileException, BacktrackException { protected final IToken consume(int type) throws EndOfFileException, BacktrackException {
final IToken result= consume(); final IToken result= consume();
if (result.getType() != type) if (result.getType() != type)
throwBacktrack(result); throwBacktrack(result);
@ -323,14 +435,14 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
/** /**
* Consume the next token available only if the type is as specified. In case we * Consume the next token available only if the type is as specified. In case we reached the end of
* reached the end of completion, no token is consumed and the eoc-token returned. * completion, no token is consumed and the eoc-token returned.
* *
* @param type * @param type
* The type of token that you are expecting. * The type of token that you are expecting.
* @return the token that was consumed and removed from our buffer. * @return the token that was consumed and removed from our buffer.
* @throws BacktrackException * @throws BacktrackException
* If LT(1) != type * if LT(1) != type
*/ */
protected IToken consumeOrEOC(int type) throws EndOfFileException, BacktrackException { protected IToken consumeOrEOC(int type) throws EndOfFileException, BacktrackException {
final IToken la1= LA(1); final IToken la1= LA(1);
@ -343,30 +455,36 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return consume(); return consume();
} }
/** protected final boolean isOnSameLine(int offset1, int offset2) {
* Fetches the next token from the scanner. ILocationResolver lr= (ILocationResolver) getTranslationUnit().getAdapter(ILocationResolver.class);
*/ IASTFileLocation floc= lr.getMappedFileLocation(offset1, offset2-offset1+1);
private IToken fetchToken(boolean skipInactive) throws EndOfFileException { return floc.getFileName().equals(lr.getContainingFilePath(offset1)) &&
try { floc.getStartingLineNumber() == floc.getEndingLineNumber();
IToken result= scanner.nextToken();
while (result.getType() == IToken.tINACTIVE_CODE_START) {
scanner.skipInactiveCode();
result= scanner.nextToken();
}
eofOffset= result.getEndOffset();
return result;
} catch (OffsetLimitReachedException olre) {
handleOffsetLimitException(olre);
// never returns, to make the java-compiler happy:
return null;
}
} }
protected void handleOffsetLimitException(OffsetLimitReachedException exception) throws EndOfFileException { protected final int calculateEndOffset(IASTNode n) {
if (mode != ParserMode.COMPLETION_PARSE) ASTNode node = (ASTNode) n;
throw new EndOfFileException(); return node.getOffset() + node.getLength();
createCompletionNode(exception.getFinalToken()); }
throw exception;
protected final void setRange(IASTNode n, IASTNode from) {
((ASTNode) n).setOffsetAndLength((ASTNode) from);
}
protected final void setRange(IASTNode n, int offset, int endOffset) {
((ASTNode) n).setOffsetAndLength(offset, endOffset-offset);
}
protected final void adjustLength(IASTNode n, IASTNode endNode) {
final int endOffset= calculateEndOffset(endNode);
final ASTNode node = (ASTNode) n;
node.setLength(endOffset-node.getOffset());
}
protected final int getEndOffset() {
if (lastTokenFromScanner == null)
return 0;
return lastTokenFromScanner.getEndOffset();
} }
/** /**
@ -487,13 +605,23 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected abstract void nullifyTranslationUnit(); protected abstract void nullifyTranslationUnit();
protected IToken skipOverCompoundStatement() throws BacktrackException, protected IToken skipOverCompoundStatement() throws BacktrackException, EndOfFileException {
EndOfFileException {
// speed up the parser by skipping the body, simply look for matching brace and return // speed up the parser by skipping the body, simply look for matching brace and return
final boolean isActive = isActiveCode();
final int codeBranchNesting= getCodeBranchNesting();
consume(IToken.tLBRACE); consume(IToken.tLBRACE);
IToken result = null; IToken result = null;
int depth = 1; int depth = 1;
while (depth > 0) { while (depth > 0) {
if (!isActive) {
IToken t= lookaheadToken(1, false);
final int lt= t.getType();
if (lt == IToken.tINACTIVE_CODE_SEPARATOR || lt == IToken.tINACTIVE_CODE_END || lt == IToken.tINACTIVE_CODE_START) {
if (!acceptInactiveCodeBoundary(codeBranchNesting))
throw new EndOfFileException(true);
}
}
result = consume(); result = consume();
switch (result.getType()) { switch (result.getType()) {
case IToken.tRBRACE: case IToken.tRBRACE:
@ -541,7 +669,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
while(true) { while(true) {
switch (LT(1)) { switch (LT(1)) {
case IToken.tEOC: case IToken.tEOC:
endOffset= eofOffset; endOffset= getEndOffset();
break loop; break loop;
case IToken.tSEMI: case IToken.tSEMI:
if (depth == 0) { if (depth == 0) {
@ -567,7 +695,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
endOffset= consume().getEndOffset(); endOffset= consume().getEndOffset();
} }
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
endOffset= eofOffset; endOffset= getEndOffset();
} }
return endOffset; return endOffset;
} }
@ -581,7 +709,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
while(true) { while(true) {
switch (LT(1)) { switch (LT(1)) {
case IToken.tEOC: case IToken.tEOC:
endOffset= eofOffset; endOffset= getEndOffset();
break loop; break loop;
case IToken.tSEMI: case IToken.tSEMI:
case IToken.tLBRACE: case IToken.tLBRACE:
@ -610,7 +738,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
endOffset= consume().getEndOffset(); endOffset= consume().getEndOffset();
} }
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
endOffset= eofOffset; endOffset= getEndOffset();
} }
IASTProblem problem= createProblem(IProblem.SYNTAX_ERROR, offset, endOffset-offset); IASTProblem problem= createProblem(IProblem.SYNTAX_ERROR, offset, endOffset-offset);
return buildProblemExpression(problem); return buildProblemExpression(problem);
@ -698,7 +826,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTExpression compoundStatementExpression() throws EndOfFileException, BacktrackException { protected IASTExpression compoundStatementExpression() throws EndOfFileException, BacktrackException {
int startingOffset = consume().getOffset(); // tLPAREN always int startingOffset = consume().getOffset(); // tLPAREN always
IASTCompoundStatement compoundStatement = null; IASTCompoundStatement compoundStatement = null;
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode())
skipOverCompoundStatement(); skipOverCompoundStatement();
else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) { else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) {
if (scanner.isOnTopContext()) if (scanner.isOnTopContext())
@ -863,44 +991,94 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected void parseTranslationUnit() { protected void parseTranslationUnit() {
final IASTTranslationUnit tu= getTranslationUnit(); final IASTTranslationUnit tu= getTranslationUnit();
int offset= -1; declarationList(tu, DeclarationOptions.GLOBAL, false, 0);
((ASTNode) tu).setLength(getEndOffset());
}
protected final void declarationListInBraces(final IASTDeclarationListOwner tu, int offset, DeclarationOptions options) throws EndOfFileException, BacktrackException {
// consume brace, if requested
int codeBranchNesting= getCodeBranchNesting();
consume(IToken.tLBRACE);
declarationList(tu, options, true, codeBranchNesting);
final int lt1 = LTcatchEOF(1);
if (lt1 == IToken.tRBRACE) {
int endOffset= consume().getEndOffset();
setRange(tu, offset, endOffset);
return;
}
final int endOffset = getEndOffset();
setRange(tu, offset, endOffset);
if (lt1 == IToken.tEOC || (lt1 == 0 && tu instanceof IASTCompositeTypeSpecifier)) {
return;
}
throwBacktrack(createProblem(IProblem.SYNTAX_ERROR, endOffset, 0), tu);
}
private final void declarationList(final IASTDeclarationListOwner tu, DeclarationOptions options, boolean upToBrace, int codeBranchNesting) {
final boolean wasActive= isActiveCode();
while (true) { while (true) {
final boolean ok= acceptInactiveCodeBoundary(codeBranchNesting);
if (!ok) {
// we left to an enclosing code branch. If we started in inactive code, it's time to leave.
if (!wasActive)
return;
// if we started in active code, we need to skip the outer and therefore unrelated
// inactive branches until we hit active code again.
try { try {
skipInactiveCode();
} catch (OffsetLimitReachedException e) {
return;
}
codeBranchNesting= Math.min(getCodeBranchNesting()+1, codeBranchNesting);
// we could be at the start of inactive code so restart the loop
continue;
}
final boolean active= isActiveCode();
IToken next= LAcatchEOF(1); IToken next= LAcatchEOF(1);
if (next == null || next.getType() == IToken.tEOC) if (next == null || next.getType() == IToken.tEOC)
break; return;
final int nextOffset = next.getOffset(); if (upToBrace && next.getType() == IToken.tRBRACE && active == wasActive) {
return;
}
final int offset = next.getOffset();
declarationMark= next; declarationMark= next;
next= null; // don't hold on to the token while parsing namespaces, class bodies, etc. next= null; // don't hold on to the token while parsing namespaces, class bodies, etc.
try {
if (offset == nextOffset) { IASTDeclaration declaration= declaration(options);
// no progress if (((ASTNode) declaration).getLength() == 0 && LTcatchEOF(1) != IToken.tEOC) {
tu.addDeclaration(skipProblemDeclaration(offset)); declaration= skipProblemDeclaration(offset);
} else {
offset= nextOffset;
final IASTDeclaration declaration= declaration(DeclarationOptions.GLOBAL);
tu.addDeclaration(declaration);
} }
addDeclaration(tu, declaration, active);
} catch (BacktrackException bt) { } catch (BacktrackException bt) {
IASTDeclaration[] decls= problemDeclaration(offset, bt, DeclarationOptions.GLOBAL); IASTDeclaration[] decls= problemDeclaration(offset, bt, options);
for (IASTDeclaration declaration : decls) { for (IASTDeclaration declaration : decls) {
tu.addDeclaration(declaration); addDeclaration(tu, declaration, active);
} }
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
tu.addDeclaration(skipProblemDeclaration(offset)); IASTDeclaration declaration= skipProblemDeclaration(offset);
addDeclaration(tu, declaration, active);
if (!e.endsInactiveCode()) {
break; break;
} catch (OutOfMemoryError oome) { }
logThrowable("translationUnit", oome); //$NON-NLS-1$
throw oome;
} catch (Exception e) {
logException("translationUnit", e); //$NON-NLS-1$
tu.addDeclaration(skipProblemDeclaration(offset));
} finally { } finally {
declarationMark= null; declarationMark= null;
} }
} }
((ASTNode) tu).setLength(eofOffset); }
private void addDeclaration(final IASTDeclarationListOwner parent, IASTDeclaration declaration,
final boolean active) {
if (!active) {
declaration.accept(MARK_INACTIVE);
}
parent.addDeclaration(declaration);
} }
protected IASTExpression assignmentOperatorExpression(int kind, protected IASTExpression assignmentOperatorExpression(int kind,
@ -1162,19 +1340,19 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTStatement handleFunctionBody() throws BacktrackException, EndOfFileException { protected IASTStatement handleFunctionBody() throws BacktrackException, EndOfFileException {
declarationMark= null; declarationMark= null;
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) { if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode()) {
IToken curr = LA(1); int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement(); IToken last = skipOverCompoundStatement();
IASTCompoundStatement cs = nodeFactory.newCompoundStatement(); IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last.getEndOffset() - curr.getOffset()); setRange(cs, offset, last.getEndOffset());
return cs; return cs;
} else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) { } else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) {
if (scanner.isOnTopContext()) if (scanner.isOnTopContext())
return functionBody(); return functionBody();
IToken curr = LA(1); int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement(); IToken last = skipOverCompoundStatement();
IASTCompoundStatement cs = nodeFactory.newCompoundStatement(); IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last.getEndOffset() - curr.getOffset()); setRange(cs, offset, last.getEndOffset());
return cs; return cs;
} }
@ -1261,7 +1439,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
loop: while (true) { loop: while (true) {
switch (LTcatchEOF(1)) { switch (LTcatchEOF(1)) {
case 0: // eof case 0: // eof
endOffset= eofOffset; endOffset= getEndOffset();
break loop; break loop;
case IToken.tRBRACE: case IToken.tRBRACE:
endOffset= consume().getEndOffset(); endOffset= consume().getEndOffset();
@ -1302,7 +1480,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
} }
} }
} catch (EndOfFileException eof) { } catch (EndOfFileException eof) {
throwBacktrack(createProblem(IProblem.SYNTAX_ERROR, problemOffset, eofOffset-problemOffset), result); throwBacktrack(createProblem(IProblem.SYNTAX_ERROR, problemOffset, getEndOffset()-problemOffset), result);
} catch (BacktrackException bt) { } catch (BacktrackException bt) {
IASTProblem problem= skipProblemEnumerator(problemOffset); IASTProblem problem= skipProblemEnumerator(problemOffset);
throwBacktrack(problem, result); throwBacktrack(problem, result);
@ -1352,7 +1530,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return new IASTDeclaration[] {(IASTDeclaration) n, buildProblemDeclaration(origProblem)}; return new IASTDeclaration[] {(IASTDeclaration) n, buildProblemDeclaration(origProblem)};
} }
if (declarationMark != null) { if (declarationMark != null && isActiveCode()) {
IASTDeclaration trailingProblem= null; IASTDeclaration trailingProblem= null;
offset= declarationMark.getOffset(); offset= declarationMark.getOffset();
@ -1382,7 +1560,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
break; break;
} }
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
endOffset= eofOffset; endOffset= getEndOffset();
break; break;
} }
} }
@ -1995,10 +2173,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
*/ */
protected void __attribute_decl_seq(boolean allowAttrib, boolean allowDeclspec) throws BacktrackException, EndOfFileException { protected void __attribute_decl_seq(boolean allowAttrib, boolean allowDeclspec) throws BacktrackException, EndOfFileException {
while (true) { while (true) {
IToken token = LA(1); final int lt = LTcatchEOF(1);
if ( allowAttrib && (token.getType() == IGCCToken.t__attribute__)) { if ( allowAttrib && (lt == IGCCToken.t__attribute__)) {
__attribute__(); __attribute__();
} else if (allowDeclspec && (token.getType() == IGCCToken.t__declspec)) { } else if (allowDeclspec && (lt == IGCCToken.t__declspec)) {
__declspec(); __declspec();
} else { } else {
break; break;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,59 +10,31 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
/** /**
* Visitor to search for nodes by file offsets. * Visitor to search for nodes by file offsets.
* @since 5.0 * @since 5.0
*/ */
public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisitor { public class FindNodeForOffsetAction extends ASTGenericVisitor {
private final ASTNodeSpecification<?> fNodeSpec; private final ASTNodeSpecification<?> fNodeSpec;
public FindNodeForOffsetAction(ASTNodeSpecification<?> nodeSpec) { public FindNodeForOffsetAction(ASTNodeSpecification<?> nodeSpec) {
super(!nodeSpec.requiresClass(IASTName.class));
fNodeSpec= nodeSpec; fNodeSpec= nodeSpec;
shouldVisitNames = true; shouldVisitNames = true;
shouldVisitDeclarations= true; shouldVisitDeclarations= true;
includeInactiveNodes= true;
shouldVisitArrayModifiers=
shouldVisitInitializers=
shouldVisitParameterDeclarations=
shouldVisitDeclarators=
shouldVisitDeclSpecifiers=
shouldVisitDesignators=
shouldVisitEnumerators=
shouldVisitExpressions=
shouldVisitStatements=
shouldVisitTypeIds=
shouldVisitEnumerators=
shouldVisitBaseSpecifiers=
shouldVisitNamespaces=
shouldVisitTemplateParameters=
shouldVisitTranslationUnit= !nodeSpec.requiresClass(IASTName.class);
} }
public int processNode(IASTNode node) { @Override
public int genericVisit(IASTNode node) {
if (node instanceof ASTNode) { if (node instanceof ASTNode) {
final ASTNode astNode = (ASTNode) node; final ASTNode astNode = (ASTNode) node;
if (!fNodeSpec.canContainMatches(astNode)) { if (!fNodeSpec.canContainMatches(astNode)) {
@ -80,96 +52,17 @@ public class FindNodeForOffsetAction extends CPPASTVisitor implements ICASTVisit
if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fNodeSpec.getSequenceEnd()) if (declaration instanceof ASTNode && ((ASTNode) declaration).getOffset() > fNodeSpec.getSequenceEnd())
return PROCESS_ABORT; return PROCESS_ABORT;
return processNode(declaration); return genericVisit(declaration);
} }
@Override @Override
public int visit(IASTDeclarator declarator) { public int visit(IASTDeclarator declarator) {
int ret = processNode(declarator); int ret = genericVisit(declarator);
IASTPointerOperator[] ops = declarator.getPointerOperators(); IASTPointerOperator[] ops = declarator.getPointerOperators();
for (int i = 0; i < ops.length; i++) for (int i = 0; i < ops.length; i++)
processNode(ops[i]); genericVisit(ops[i]);
return ret; return ret;
} }
@Override
public int visit(IASTArrayModifier arrayModifier) {
return processNode(arrayModifier);
}
@Override
public int visit(IASTDeclSpecifier declSpec) {
return processNode(declSpec);
}
@Override
public int visit(IASTEnumerator enumerator) {
return processNode(enumerator);
}
@Override
public int visit(IASTExpression expression) {
return processNode(expression);
}
@Override
public int visit(IASTInitializer initializer) {
return processNode(initializer);
}
@Override
public int visit(IASTName name) {
return processNode(name);
}
@Override
public int visit(IASTParameterDeclaration parameterDeclaration) {
return processNode(parameterDeclaration);
}
@Override
public int visit(IASTStatement statement) {
return processNode(statement);
}
@Override
public int visit(IASTTypeId typeId) {
return processNode(typeId);
}
@Override
public int visit(ICPPASTBaseSpecifier baseSpecifier) {
return processNode(baseSpecifier);
}
@Override
public int visit(ICPPASTNamespaceDefinition namespaceDefinition) {
return processNode(namespaceDefinition);
}
@Override
public int visit(ICPPASTTemplateParameter templateParameter) {
return processNode(templateParameter);
}
@Override
public int visit(IASTProblem problem) {
return processNode(problem);
}
public int visit(ICASTDesignator designator) {
return processNode(designator);
}
public int leave(ICASTDesignator designator) {
return PROCESS_CONTINUE;
}
@Override
public int visit(IASTTranslationUnit tu) {
return processNode(tu);
}
} }

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
public final class CASTAmbiguityResolver extends ASTVisitor { public final class CASTAmbiguityResolver extends ASTVisitor {
public CASTAmbiguityResolver() { public CASTAmbiguityResolver() {
super(false); super(false);
includeInactiveNodes= true;
shouldVisitAmbiguousNodes= true; shouldVisitAmbiguousNodes= true;
} }

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/** /**
@ -27,15 +28,18 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
public class CASTCompositeTypeSpecifier extends CASTBaseDeclSpecifier implements public class CASTCompositeTypeSpecifier extends CASTBaseDeclSpecifier implements
ICASTCompositeTypeSpecifier, IASTAmbiguityParent { ICASTCompositeTypeSpecifier, IASTAmbiguityParent {
private int key; private int fKey;
private IASTName name; private IASTName fName;
private IASTDeclaration[] fActiveDeclarations= null;
private IASTDeclaration [] fAllDeclarations = null;
private int fDeclarationsPos=-1;
private IScope fScope = null;
public CASTCompositeTypeSpecifier() { public CASTCompositeTypeSpecifier() {
} }
public CASTCompositeTypeSpecifier(int key, IASTName name) { public CASTCompositeTypeSpecifier(int key, IASTName name) {
this.key = key; this.fKey = key;
setName(name); setName(name);
} }
@ -47,61 +51,70 @@ public class CASTCompositeTypeSpecifier extends CASTBaseDeclSpecifier implements
protected void copyCompositeTypeSpecifier(CASTCompositeTypeSpecifier copy) { protected void copyCompositeTypeSpecifier(CASTCompositeTypeSpecifier copy) {
copyBaseDeclSpec(copy); copyBaseDeclSpec(copy);
copy.setKey(key); copy.setKey(fKey);
copy.setName(name == null ? null : name.copy()); copy.setName(fName == null ? null : fName.copy());
for(IASTDeclaration member : getMembers()) for(IASTDeclaration member : getMembers())
copy.addMemberDeclaration(member == null ? null : member.copy()); copy.addMemberDeclaration(member == null ? null : member.copy());
} }
public int getKey() { public int getKey() {
return key; return fKey;
} }
public void setKey(int key) { public void setKey(int key) {
assertNotFrozen(); assertNotFrozen();
this.key = key; this.fKey = key;
} }
public IASTName getName() { public IASTName getName() {
return name; return fName;
} }
public void setName(IASTName name) { public void setName(IASTName name) {
assertNotFrozen(); assertNotFrozen();
this.name = name; this.fName = name;
if (name != null) { if (name != null) {
name.setParent(this); name.setParent(this);
name.setPropertyInParent(TYPE_NAME); name.setPropertyInParent(TYPE_NAME);
} }
} }
private IASTDeclaration [] declarations = null;
private int declarationsPos=-1;
private IScope scope = null;
public IASTDeclaration[] getMembers() { public IASTDeclaration[] getMembers() {
if( declarations == null ) return IASTDeclaration.EMPTY_DECLARATION_ARRAY; IASTDeclaration[] active= fActiveDeclarations;
declarations = (IASTDeclaration[]) ArrayUtil.removeNullsAfter( IASTDeclaration.class, declarations, declarationsPos ); if (active == null) {
return declarations; active = ASTQueries.extractActiveDeclarations(fAllDeclarations, fDeclarationsPos+1);
fActiveDeclarations= active;
}
return active;
} }
public final IASTDeclaration[] getDeclarations(boolean includeInactive) {
if (includeInactive) {
fAllDeclarations= (IASTDeclaration[]) ArrayUtil.removeNullsAfter(IASTDeclaration.class, fAllDeclarations, fDeclarationsPos);
return fAllDeclarations;
}
return getMembers();
}
public void addMemberDeclaration(IASTDeclaration declaration) { public void addMemberDeclaration(IASTDeclaration declaration) {
assertNotFrozen(); assertNotFrozen();
if (declaration != null) { if (declaration != null) {
declaration.setParent(this); declaration.setParent(this);
declaration.setPropertyInParent(MEMBER_DECLARATION); declaration.setPropertyInParent(MEMBER_DECLARATION);
declarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, declarations, ++declarationsPos, declaration ); fAllDeclarations = (IASTDeclaration[]) ArrayUtil.append(IASTDeclaration.class, fAllDeclarations,
++fDeclarationsPos, declaration);
fActiveDeclarations= null;
} }
} }
public void addDeclaration(IASTDeclaration declaration) {
addMemberDeclaration(declaration);
}
public IScope getScope() { public IScope getScope() {
if( scope == null ) if( fScope == null )
scope = new CCompositeTypeScope( this ); fScope = new CCompositeTypeScope( this );
return scope; return fScope;
} }
@Override @Override
@ -113,11 +126,13 @@ public class CASTCompositeTypeSpecifier extends CASTBaseDeclSpecifier implements
default : break; default : break;
} }
} }
if( name != null ) if( !name.accept( action ) ) return false; if (fName != null && !fName.accept(action))
return false;
IASTDeclaration [] decls = getMembers(); IASTDeclaration[] decls= getDeclarations(action.includeInactiveNodes);
for( int i = 0; i < decls.length; i++ ) for (int i = 0; i < decls.length; i++) {
if (!decls[i].accept(action)) return false; if (!decls[i].accept(action)) return false;
}
if (action.shouldVisitDeclSpecifiers) { if (action.shouldVisitDeclSpecifiers) {
switch (action.leave(this)) { switch (action.leave(this)) {
@ -129,24 +144,22 @@ public class CASTCompositeTypeSpecifier extends CASTBaseDeclSpecifier implements
return true; return true;
} }
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
if( n == this.name ) if( n == this.fName )
return r_definition; return r_definition;
return r_unclear; return r_unclear;
} }
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if (declarations == null) return; assert child.isActive() == other.isActive();
for(int i=0; i < declarations.length; ++i) { for (int i = 0; i <= fDeclarationsPos; ++i) {
if (declarations[i] == null) break; if (fAllDeclarations[i] == child) {
if (declarations[i] == child) {
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
declarations[i] = (IASTDeclaration) other; fAllDeclarations[i] = (IASTDeclaration) other;
break; fActiveDeclarations= null;
return;
} }
} }
} }
} }

View file

@ -14,11 +14,8 @@ package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.ast.IMacroBinding;
@ -99,21 +96,8 @@ public class CASTTranslationUnit extends ASTTranslationUnit implements IASTAmbig
} }
@Override @Override
protected ASTVisitor createAmbiguityNodeVisitor() { public void resolveAmbiguities() {
return new CASTAmbiguityResolver(); accept(new CASTAmbiguityResolver());
}
public void replace(IASTNode child, IASTNode other) {
if (fDeclarations == null) return;
for(int i=0; i < fDeclarations.length; ++i) {
if (fDeclarations[i] == null) break;
if (fDeclarations[i] == child) {
other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent());
fDeclarations[i] = (IASTDeclaration) other;
return;
}
}
} }
/** /**

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -49,6 +49,9 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte
} }
public void addDeclaration(IASTName decl) { public void addDeclaration(IASTName decl) {
if (!decl.isActive())
return;
if( decl.getPropertyInParent() != IASTElaboratedTypeSpecifier.TYPE_NAME ) if( decl.getPropertyInParent() != IASTElaboratedTypeSpecifier.TYPE_NAME )
return; return;
@ -141,10 +144,8 @@ public class CEnumeration extends PlatformObject implements IEnumeration, ICInte
return bindings; return bindings;
} }
/**
* @param name
*/
public void addDefinition(IASTName name) { public void addDefinition(IASTName name) {
if (name.isActive())
definition = name; definition = name;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -35,6 +35,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
/** /**
@ -68,6 +69,9 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
return null; return null;
} }
public void addDeclarator( IASTFunctionDeclarator fnDeclarator ){ public void addDeclarator( IASTFunctionDeclarator fnDeclarator ){
if (!fnDeclarator.isActive())
return;
if( fnDeclarator.getParent() instanceof IASTFunctionDefinition || fnDeclarator instanceof ICASTKnRFunctionDeclarator ) { if( fnDeclarator.getParent() instanceof IASTFunctionDefinition || fnDeclarator instanceof ICASTKnRFunctionDeclarator ) {
if (definition == fnDeclarator) { if (definition == fnDeclarator) {
// recursion? // recursion?
@ -134,7 +138,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
if( size > 0 ){ if( size > 0 ){
for( int i = 0; i < size; i++ ){ for( int i = 0; i < size; i++ ){
IASTParameterDeclaration p = params[i]; IASTParameterDeclaration p = params[i];
result[i] = (IParameter) CVisitor.findInnermostDeclarator(p.getDeclarator()).getName().resolveBinding(); result[i] = (IParameter) ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName().resolveBinding();
} }
} }
} else if (dtor instanceof ICASTKnRFunctionDeclarator) { } else if (dtor instanceof ICASTKnRFunctionDeclarator) {
@ -270,7 +274,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
IASTParameterDeclaration [] parameters = ((IASTStandardFunctionDeclarator)definition).getParameters(); IASTParameterDeclaration [] parameters = ((IASTStandardFunctionDeclarator)definition).getParameters();
if( parameters.length > idx ) { if( parameters.length > idx ) {
temp = parameters[idx]; temp = parameters[idx];
CVisitor.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding ); ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding );
} }
} else if( definition instanceof ICASTKnRFunctionDeclarator ){ } else if( definition instanceof ICASTKnRFunctionDeclarator ){
fKnRDtor = (ICASTKnRFunctionDeclarator) definition; fKnRDtor = (ICASTKnRFunctionDeclarator) definition;
@ -289,7 +293,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
for( int j = 0; j < declarators.length && declarators[j] != null; j++ ){ for( int j = 0; j < declarators.length && declarators[j] != null; j++ ){
if( declarators[j].getParameters().length > idx ){ if( declarators[j].getParameters().length > idx ){
temp = declarators[j].getParameters()[idx]; temp = declarators[j].getParameters()[idx];
CVisitor.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding ); ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName().setBinding( binding );
} }
} }
} }
@ -305,7 +309,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
if(params.length < nps.length ) if(params.length < nps.length )
return; return;
for( int i = 0; i < nps.length; i++ ){ for( int i = 0; i < nps.length; i++ ){
IASTName name = CVisitor.findInnermostDeclarator(nps[i].getDeclarator()).getName(); IASTName name = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
name.setBinding( params[i] ); name.setBinding( params[i] );
if( params[i] instanceof CParameter ) if( params[i] instanceof CParameter )
((CParameter)params[i]).addDeclaration( name ); ((CParameter)params[i]).addDeclaration( name );

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -143,7 +143,7 @@ public class CParameter extends PlatformObject implements IParameter {
* @param name * @param name
*/ */
public void addDeclaration(IASTName name) { public void addDeclaration(IASTName name) {
if( name != null ) if (name != null && name.isActive())
declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name); declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name);
} }

View file

@ -222,16 +222,15 @@ public class CStructure extends PlatformObject implements ICompositeType, ICInte
return t; return t;
} }
/**
* @param compositeTypeSpec
*/
public void addDefinition(ICASTCompositeTypeSpecifier compositeTypeSpec) { public void addDefinition(ICASTCompositeTypeSpecifier compositeTypeSpec) {
if (compositeTypeSpec.isActive()) {
definition = compositeTypeSpec.getName(); definition = compositeTypeSpec.getName();
compositeTypeSpec.getName().setBinding(this); compositeTypeSpec.getName().setBinding(this);
} }
}
public void addDeclaration(IASTName decl) { public void addDeclaration(IASTName decl) {
if (decl.getPropertyInParent() != IASTElaboratedTypeSpecifier.TYPE_NAME) if (!decl.isActive() || decl.getPropertyInParent() != IASTElaboratedTypeSpecifier.TYPE_NAME)
return; return;
decl.setBinding(this); decl.setBinding(this);

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable; import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
@ -73,8 +74,11 @@ public class CVariable extends PlatformObject implements IInternalVariable, ICIn
} }
public void addDeclaration(IASTName name) { public void addDeclaration(IASTName name) {
if (name != null && name.isActive()) {
declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name); declarations = (IASTName[]) ArrayUtil.append(IASTName.class, declarations, name);
} }
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IVariable#getType() * @see org.eclipse.cdt.core.dom.ast.IVariable#getType()
*/ */
@ -198,6 +202,6 @@ public class CVariable extends PlatformObject implements IInternalVariable, ICIn
if (!(node instanceof IASTDeclarator)) if (!(node instanceof IASTDeclarator))
return null; return null;
return CVisitor.findOutermostDeclarator((IASTDeclarator) node); return ASTQueries.findOutermostDeclarator((IASTDeclarator) node);
} }
} }

View file

@ -480,7 +480,7 @@ public class CVisitor extends ASTQueries {
} catch (DOMException e) { } catch (DOMException e) {
} }
} }
if (binding != null && !(binding instanceof IIndexBinding)) { if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) {
if (binding instanceof IEnumeration) { if (binding instanceof IEnumeration) {
if (binding instanceof CEnumeration) { if (binding instanceof CEnumeration) {
((CEnumeration)binding).addDefinition(name); ((CEnumeration)binding).addDefinition(name);
@ -546,7 +546,7 @@ public class CVisitor extends ASTQueries {
binding= scope.getBinding(name, false); binding= scope.getBinding(name, false);
} catch (DOMException e) { } catch (DOMException e) {
} }
if (binding != null) { if (binding != null && name.isActive()) {
if (binding instanceof CEnumeration) { if (binding instanceof CEnumeration) {
((CEnumeration)binding).addDeclaration(name); ((CEnumeration)binding).addDeclaration(name);
} else if (binding instanceof CStructure) { } else if (binding instanceof CStructure) {
@ -559,7 +559,7 @@ public class CVisitor extends ASTQueries {
insertIntoScope= elabTypeSpec.getTranslationUnit().getScope(); insertIntoScope= elabTypeSpec.getTranslationUnit().getScope();
try { try {
binding= insertIntoScope.getBinding(name, false); binding= insertIntoScope.getBinding(name, false);
if (binding != null) { if (binding != null && name.isActive()) {
if (binding instanceof CEnumeration) { if (binding instanceof CEnumeration) {
((CEnumeration)binding).addDeclaration(name); ((CEnumeration)binding).addDeclaration(name);
} else if (binding instanceof CStructure) { } else if (binding instanceof CStructure) {
@ -691,7 +691,7 @@ public class CVisitor extends ASTQueries {
binding = scope.getBinding(name, false); binding = scope.getBinding(name, false);
} catch (DOMException e) { } catch (DOMException e) {
} }
if (binding != null && binding instanceof IIndexBinding == false) { if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) {
if (binding instanceof ICInternalFunction) if (binding instanceof ICInternalFunction)
((ICInternalFunction)binding).addDeclarator((ICASTKnRFunctionDeclarator) declarator); ((ICInternalFunction)binding).addDeclarator((ICASTKnRFunctionDeclarator) declarator);
else else
@ -755,7 +755,7 @@ public class CVisitor extends ASTQueries {
return binding; return binding;
} }
} else if (funcDeclarator != null) { } else if (funcDeclarator != null) {
if (binding != null && !(binding instanceof IIndexBinding)) { if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) {
if (binding instanceof IFunction) { if (binding instanceof IFunction) {
IFunction function = (IFunction) binding; IFunction function = (IFunction) binding;
if (function instanceof CFunction) { if (function instanceof CFunction) {
@ -774,7 +774,7 @@ public class CVisitor extends ASTQueries {
binding = new CTypedef(name); binding = new CTypedef(name);
} else { } else {
IType t1 = null, t2 = null; IType t1 = null, t2 = null;
if (binding != null && !(binding instanceof IIndexBinding)) { if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) {
if (binding instanceof IParameter) { if (binding instanceof IParameter) {
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray()); return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray());
} else if (binding instanceof IVariable) { } else if (binding instanceof IVariable) {
@ -812,7 +812,7 @@ public class CVisitor extends ASTQueries {
if (scope != null) { if (scope != null) {
binding = scope.getBinding(name, false); binding = scope.getBinding(name, false);
if (binding != null && !(binding instanceof IIndexBinding)) { if (binding != null && !(binding instanceof IIndexBinding) && name.isActive()) {
if (binding instanceof CStructure) if (binding instanceof CStructure)
((CStructure)binding).addDefinition(compositeTypeSpec); ((CStructure)binding).addDefinition(compositeTypeSpec);
return binding; return binding;

View file

@ -137,7 +137,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
} }
protected IASTInitializer optionalCInitializer() throws EndOfFileException, BacktrackException { protected IASTInitializer optionalCInitializer() throws EndOfFileException, BacktrackException {
if (LT(1) == IToken.tASSIGN) { if (LTcatchEOF(1) == IToken.tASSIGN) {
consume(); consume();
return cInitializerClause(false); return cInitializerClause(false);
} }
@ -414,9 +414,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
for (IASTDeclarator declarator : declarators) for (IASTDeclarator declarator : declarators)
simpleDeclaration.addDeclarator(declarator); simpleDeclaration.addDeclarator(declarator);
((ASTNode) simpleDeclaration).setOffsetAndLength(firstOffset, endOffset-firstOffset); setRange(simpleDeclaration, firstOffset, endOffset);
if ( altDeclSpec != null && altDeclarator != null) { if ( altDeclSpec != null && altDeclarator != null) {
simpleDeclaration= new CASTAmbiguousSimpleDeclaration(simpleDeclaration, altDeclSpec, altDeclarator); simpleDeclaration= new CASTAmbiguousSimpleDeclaration(simpleDeclaration, altDeclSpec, altDeclarator);
setRange(simpleDeclaration, firstOffset, endOffset);
} }
if (insertSemi) { if (insertSemi) {
@ -1221,48 +1222,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
name= nodeFactory.newName(); name= nodeFactory.newName();
} }
ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name); ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name);
declarationListInBraces(result, offset, DeclarationOptions.C_MEMBER);
int endOffset= consume().getEndOffset();
int declOffset= -1;
loop: while (true) {
try {
IToken next= LAcatchEOF(1);
if (next == null || next.getType() == IToken.tEOC)
break loop; // the missing semicolon will cause a problem, just break the loop.
if (next.getType() == IToken.tRBRACE) {
endOffset= consume().getEndOffset();
break loop;
}
final int nextOffset = next.getOffset();
declarationMark= next;
next= null; // don't hold on to the token while parsing namespaces, class bodies, etc.
IASTDeclaration d;
if (declOffset == nextOffset) {
// no progress
d= skipProblemDeclaration(declOffset);
} else {
d = declaration(DeclarationOptions.C_MEMBER);
}
result.addMemberDeclaration(d);
endOffset= calculateEndOffset(d);
} catch (BacktrackException bt) {
IASTDeclaration[] decls= problemDeclaration(declOffset, bt, DeclarationOptions.C_MEMBER);
for (IASTDeclaration declaration : decls) {
result.addMemberDeclaration(declaration);
endOffset= calculateEndOffset(declaration);
}
} catch (EndOfFileException e) {
result.addMemberDeclaration(skipProblemDeclaration(declOffset));
endOffset= eofOffset;
break loop;
} finally {
declarationMark= null;
}
}
((ASTNode) result).setOffsetAndLength(offset, endOffset - offset);
return result; return result;
} }
@ -1302,7 +1262,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
throws EndOfFileException, BacktrackException, FoundAggregateInitializer { throws EndOfFileException, BacktrackException, FoundAggregateInitializer {
IASTDeclarator d = declarator(option); IASTDeclarator d = declarator(option);
if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tLBRACE) if (LTcatchEOF(1) == IToken.tASSIGN && LT(2) == IToken.tLBRACE)
throw new FoundAggregateInitializer(d); throw new FoundAggregateInitializer(d);
IASTInitializer i = optionalCInitializer(); IASTInitializer i = optionalCInitializer();
@ -1409,8 +1369,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
final int startingOffset, int endOffset, final int startingOffset, int endOffset,
final DeclarationOptions option) throws EndOfFileException, BacktrackException { final DeclarationOptions option) throws EndOfFileException, BacktrackException {
IASTDeclarator result= null; IASTDeclarator result= null;
int lt1;
loop: while(true) { loop: while(true) {
final int lt1= LT(1); lt1= LTcatchEOF(1);
switch (lt1) { switch (lt1) {
case IToken.tLPAREN: case IToken.tLPAREN:
result= functionDeclarator(isAbstract(declaratorName, nestedDeclarator) result= functionDeclarator(isAbstract(declaratorName, nestedDeclarator)
@ -1445,6 +1406,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
break loop; break loop;
} }
} }
if (lt1 != 0)
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers); __attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
if (result == null) { if (result == null) {
@ -1454,7 +1416,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
endOffset= calculateEndOffset(result); endOffset= calculateEndOffset(result);
} }
if (LT(1) == IToken.t_asm) { // asm labels bug 226121 if (lt1 != 0 && LT(1) == IToken.t_asm) { // asm labels bug 226121
consume(); consume();
endOffset= asmExpression(null).getEndOffset(); endOffset= asmExpression(null).getEndOffset();

View file

@ -54,6 +54,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
public CPPASTAmbiguityResolver() { public CPPASTAmbiguityResolver() {
super(false); super(false);
includeInactiveNodes= true;
shouldVisitAmbiguousNodes= true; shouldVisitAmbiguousNodes= true;
shouldVisitDeclarations= true; shouldVisitDeclarations= true;
shouldVisitDeclSpecifiers= true; shouldVisitDeclSpecifiers= true;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/** /**
@ -27,21 +28,26 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
public class CPPASTCompositeTypeSpecifier extends CPPASTBaseDeclSpecifier public class CPPASTCompositeTypeSpecifier extends CPPASTBaseDeclSpecifier
implements ICPPASTCompositeTypeSpecifier, IASTAmbiguityParent { implements ICPPASTCompositeTypeSpecifier, IASTAmbiguityParent {
private int k; private int fKey;
private IASTName n; private IASTName fName;
private ICPPClassScope scope; private ICPPClassScope fScope;
private IASTDeclaration[] fAllDeclarations;
private IASTDeclaration[] fActiveDeclarations;
private int fDeclarationsPos=-1;
private ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier[] baseSpecs = null;
private int baseSpecsPos = -1;
public CPPASTCompositeTypeSpecifier() { public CPPASTCompositeTypeSpecifier() {
} }
public CPPASTCompositeTypeSpecifier(int k, IASTName n) { public CPPASTCompositeTypeSpecifier(int k, IASTName n) {
this.k = k; this.fKey = k;
setName(n); setName(n);
} }
public CPPASTCompositeTypeSpecifier copy() { public CPPASTCompositeTypeSpecifier copy() {
CPPASTCompositeTypeSpecifier copy = new CPPASTCompositeTypeSpecifier(k, n == null ? null : n.copy()); CPPASTCompositeTypeSpecifier copy = new CPPASTCompositeTypeSpecifier(fKey, fName == null ? null : fName.copy());
copyBaseDeclSpec(copy); copyBaseDeclSpec(copy);
for(IASTDeclaration member : getMembers()) for(IASTDeclaration member : getMembers())
copy.addMemberDeclaration(member == null ? null : member.copy()); copy.addMemberDeclaration(member == null ? null : member.copy());
@ -66,21 +72,21 @@ public class CPPASTCompositeTypeSpecifier extends CPPASTBaseDeclSpecifier
} }
public int getKey() { public int getKey() {
return k; return fKey;
} }
public void setKey(int key) { public void setKey(int key) {
assertNotFrozen(); assertNotFrozen();
k = key; fKey = key;
} }
public IASTName getName() { public IASTName getName() {
return n; return fName;
} }
public void setName(IASTName name) { public void setName(IASTName name) {
assertNotFrozen(); assertNotFrozen();
this.n = name; this.fName = name;
if (name != null) { if (name != null) {
name.setParent(this); name.setParent(this);
name.setPropertyInParent(TYPE_NAME); name.setPropertyInParent(TYPE_NAME);
@ -88,34 +94,50 @@ public class CPPASTCompositeTypeSpecifier extends CPPASTBaseDeclSpecifier
} }
public IASTDeclaration[] getMembers() { public IASTDeclaration[] getMembers() {
if( declarations == null ) return IASTDeclaration.EMPTY_DECLARATION_ARRAY; IASTDeclaration[] active= fActiveDeclarations;
return (IASTDeclaration[]) ArrayUtil.trim( IASTDeclaration.class, declarations ); if (active == null) {
active = ASTQueries.extractActiveDeclarations(fAllDeclarations, fDeclarationsPos+1);
fActiveDeclarations= active;
}
return active;
}
public final IASTDeclaration[] getDeclarations(boolean includeInactive) {
if (includeInactive) {
fAllDeclarations= (IASTDeclaration[]) ArrayUtil.removeNullsAfter(IASTDeclaration.class, fAllDeclarations, fDeclarationsPos);
return fAllDeclarations;
}
return getMembers();
} }
public void addMemberDeclaration(IASTDeclaration decl) { public void addMemberDeclaration(IASTDeclaration decl) {
if (decl == null)
return;
// ignore inactive visibility labels
if (decl instanceof ICPPASTVisibilityLabel && !decl.isActive())
return;
assertNotFrozen(); assertNotFrozen();
declarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, declarations, decl );
if(decl != null) {
decl.setParent(this); decl.setParent(this);
decl.setPropertyInParent(decl instanceof ICPPASTVisibilityLabel ? VISIBILITY_LABEL : MEMBER_DECLARATION); decl.setPropertyInParent(decl instanceof ICPPASTVisibilityLabel ? VISIBILITY_LABEL : MEMBER_DECLARATION);
} fAllDeclarations = (IASTDeclaration[]) ArrayUtil.append(IASTDeclaration.class, fAllDeclarations,
++fDeclarationsPos, decl);
fActiveDeclarations= null;
} }
public final void addDeclaration(IASTDeclaration decl) {
private IASTDeclaration [] declarations = new IASTDeclaration[4]; addMemberDeclaration(decl);
private ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier [] baseSpecs = null; }
private int baseSpecsPos=-1;
public ICPPClassScope getScope() { public ICPPClassScope getScope() {
if( scope == null ) if (fScope == null)
scope = new CPPClassScope( this ); fScope = new CPPClassScope(this);
return fScope;
return scope;
} }
public void setScope(ICPPClassScope scope) { public void setScope(ICPPClassScope scope) {
this.scope = scope; this.fScope = scope;
} }
@Override @Override
@ -127,43 +149,40 @@ public class CPPASTCompositeTypeSpecifier extends CPPASTBaseDeclSpecifier
default: break; default: break;
} }
} }
if( n != null ) if( !n.accept( action ) ) return false;
if (fName != null && !fName.accept(action))
return false;
ICPPASTBaseSpecifier[] bases = getBaseSpecifiers(); ICPPASTBaseSpecifier[] bases = getBaseSpecifiers();
for( int i = 0; i < bases.length; i++ ) for (int i = 0; i < bases.length; i++) {
if (!bases[i].accept(action)) return false; if (!bases[i].accept(action)) return false;
}
IASTDeclaration [] decls = getMembers(); IASTDeclaration[] decls = getDeclarations(action.includeInactiveNodes);
for( int i = 0; i < decls.length; i++ ) for (int i = 0; i < decls.length; i++) {
if (!decls[i].accept(action)) return false; if (!decls[i].accept(action)) return false;
}
if (action.shouldVisitDeclSpecifiers && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
if( action.shouldVisitDeclSpecifiers ){
switch( action.leave( this ) ){
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
}
return true; return true;
} }
public int getRoleForName(IASTName name) { public int getRoleForName(IASTName name) {
if( name == this.n ) if( name == this.fName )
return r_definition; return r_definition;
return r_unclear; return r_unclear;
} }
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if( declarations == null ) return; assert child.isActive() == other.isActive();
for( int i = 0; i < declarations.length; ++i ) for (int i = 0; i <= fDeclarationsPos; ++i) {
{ if (fAllDeclarations[i] == child) {
if( declarations[i] == null ) {
break;
}
if( declarations[i] == child )
{
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
declarations[i] = (IASTDeclaration) other; fAllDeclarations[i] = (IASTDeclaration) other;
fActiveDeclarations= null;
} }
} }
} }

View file

@ -1,12 +1,12 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * John Camelon (IBM) - Initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -16,25 +16,29 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/** /**
* @author jcamelon * Extern "C" construct.
*/ */
public class CPPASTLinkageSpecification extends ASTNode implements public class CPPASTLinkageSpecification extends ASTNode implements
ICPPASTLinkageSpecification, IASTAmbiguityParent { ICPPASTLinkageSpecification, IASTAmbiguityParent {
private String literal; private String fLiteral;
private IASTDeclaration[] fAllDeclarations;
private IASTDeclaration[] fActiveDeclarations;
private int fLastDeclaration=-1;
public CPPASTLinkageSpecification() { public CPPASTLinkageSpecification() {
} }
public CPPASTLinkageSpecification(String literal) { public CPPASTLinkageSpecification(String literal) {
this.literal = literal; this.fLiteral = literal;
} }
public CPPASTLinkageSpecification copy() { public CPPASTLinkageSpecification copy() {
CPPASTLinkageSpecification copy = new CPPASTLinkageSpecification(literal); CPPASTLinkageSpecification copy = new CPPASTLinkageSpecification(fLiteral);
for(IASTDeclaration declaration : getDeclarations()) for(IASTDeclaration declaration : getDeclarations())
copy.addDeclaration(declaration == null ? null : declaration.copy()); copy.addDeclaration(declaration == null ? null : declaration.copy());
copy.setOffsetAndLength(this); copy.setOffsetAndLength(this);
@ -43,29 +47,40 @@ public class CPPASTLinkageSpecification extends ASTNode implements
public String getLiteral() { public String getLiteral() {
return literal; return fLiteral;
} }
public void setLiteral(String value) { public void setLiteral(String value) {
assertNotFrozen(); assertNotFrozen();
this.literal = value; this.fLiteral = value;
} }
public IASTDeclaration [] getDeclarations() { public final void addDeclaration(IASTDeclaration decl) {
if( declarations == null ) return IASTDeclaration.EMPTY_DECLARATION_ARRAY; if (decl != null) {
return (IASTDeclaration[]) ArrayUtil.trim( IASTDeclaration.class, declarations ); decl.setParent(this);
} decl.setPropertyInParent(OWNED_DECLARATION);
fAllDeclarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, fAllDeclarations, ++fLastDeclaration, decl);
public void addDeclaration(IASTDeclaration declaration) { fActiveDeclarations= null;
assertNotFrozen();
declarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, declarations, declaration );
if(declaration != null) {
declaration.setParent(this);
declaration.setPropertyInParent(OWNED_DECLARATION);
} }
} }
private IASTDeclaration [] declarations = new IASTDeclaration[4]; public final IASTDeclaration[] getDeclarations() {
IASTDeclaration[] active= fActiveDeclarations;
if (active == null) {
active = ASTQueries.extractActiveDeclarations(fAllDeclarations, fLastDeclaration+1);
fActiveDeclarations= active;
}
return active;
}
public final IASTDeclaration[] getDeclarations(boolean includeInactive) {
if (includeInactive) {
fAllDeclarations= (IASTDeclaration[]) ArrayUtil.removeNullsAfter(IASTDeclaration.class, fAllDeclarations, fLastDeclaration);
return fAllDeclarations;
}
return getDeclarations();
}
@Override @Override
public boolean accept(ASTVisitor action) { public boolean accept(ASTVisitor action) {
@ -77,31 +92,26 @@ public class CPPASTLinkageSpecification extends ASTNode implements
} }
} }
IASTDeclaration [] decls = getDeclarations(); IASTDeclaration[] decls = getDeclarations(action.includeInactiveNodes);
for( int i = 0; i < decls.length; i++ ) for (IASTDeclaration decl : decls) {
if( !decls[i].accept( action ) ) return false; if (!decl.accept(action)) return false;
}
if( action.shouldVisitDeclarations ){ if (action.shouldVisitDeclarations && action.leave(this) == ASTVisitor.PROCESS_ABORT)
switch( action.leave( this ) ){ return false;
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
}
return true; return true;
} }
public void replace(IASTNode child, IASTNode other) { public final void replace(IASTNode child, IASTNode other) {
if( declarations == null ) return; assert child.isActive() == other.isActive();
for( int i = 0; i < declarations.length; ++i ) for (int i = 0; i <= fLastDeclaration; ++i) {
{ if (fAllDeclarations[i] == child) {
if( declarations[i] == null ) continue;
if( declarations[i] == child )
{
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
declarations[i] = (IASTDeclaration) other; fAllDeclarations[i] = (IASTDeclaration) other;
fActiveDeclarations= null;
return;
} }
} }
} }

View file

@ -1,12 +1,12 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * John Camelon (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -22,15 +22,19 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
/** /**
* @author jcamelon * Definition of a namespace.
*/ */
public class CPPASTNamespaceDefinition extends ASTNode implements public class CPPASTNamespaceDefinition extends ASTNode implements
ICPPASTNamespaceDefinition, IASTAmbiguityParent { ICPPASTNamespaceDefinition, IASTAmbiguityParent {
private IASTName name; private IASTName fName;
private IASTDeclaration[] fAllDeclarations;
private IASTDeclaration[] fActiveDeclarations;
private int fLastDeclaration=-1;
public CPPASTNamespaceDefinition() { public CPPASTNamespaceDefinition() {
} }
@ -40,7 +44,7 @@ public class CPPASTNamespaceDefinition extends ASTNode implements
} }
public CPPASTNamespaceDefinition copy() { public CPPASTNamespaceDefinition copy() {
CPPASTNamespaceDefinition copy = new CPPASTNamespaceDefinition(name == null ? null : name.copy()); CPPASTNamespaceDefinition copy = new CPPASTNamespaceDefinition(fName == null ? null : fName.copy());
for(IASTDeclaration declaration : getDeclarations()) for(IASTDeclaration declaration : getDeclarations())
copy.addDeclaration(declaration == null ? null : declaration.copy()); copy.addDeclaration(declaration == null ? null : declaration.copy());
copy.setOffsetAndLength(this); copy.setOffsetAndLength(this);
@ -48,37 +52,47 @@ public class CPPASTNamespaceDefinition extends ASTNode implements
} }
public IASTName getName() { public IASTName getName() {
return name; return fName;
} }
public void setName(IASTName name) { public void setName(IASTName name) {
assertNotFrozen(); assertNotFrozen();
this.name = name; this.fName = name;
if (name != null) { if (name != null) {
name.setParent(this); name.setParent(this);
name.setPropertyInParent(NAMESPACE_NAME); name.setPropertyInParent(NAMESPACE_NAME);
} }
} }
public IASTDeclaration [] getDeclarations() { public final void addDeclaration(IASTDeclaration decl) {
if( declarations == null ) return IASTDeclaration.EMPTY_DECLARATION_ARRAY; if (decl != null) {
return (IASTDeclaration[]) ArrayUtil.trim( IASTDeclaration.class, declarations ); decl.setParent(this);
} decl.setPropertyInParent(OWNED_DECLARATION);
fAllDeclarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, fAllDeclarations, ++fLastDeclaration, decl);
public void addDeclaration(IASTDeclaration declaration) { fActiveDeclarations= null;
assertNotFrozen();
declarations = (IASTDeclaration[]) ArrayUtil.append( IASTDeclaration.class, declarations, declaration );
if(declaration != null) {
declaration.setParent(this);
declaration.setPropertyInParent(OWNED_DECLARATION);
} }
} }
private IASTDeclaration [] declarations = new IASTDeclaration[32]; public final IASTDeclaration[] getDeclarations() {
IASTDeclaration[] active= fActiveDeclarations;
if (active == null) {
active = ASTQueries.extractActiveDeclarations(fAllDeclarations, fLastDeclaration+1);
fActiveDeclarations= active;
}
return active;
}
public final IASTDeclaration[] getDeclarations(boolean includeInactive) {
if (includeInactive) {
fAllDeclarations= (IASTDeclaration[]) ArrayUtil.removeNullsAfter(IASTDeclaration.class, fAllDeclarations, fLastDeclaration);
return fAllDeclarations;
}
return getDeclarations();
}
public IScope getScope() { public IScope getScope() {
try { try {
return ((ICPPNamespace) name.resolveBinding()).getNamespaceScope(); return ((ICPPNamespace) fName.resolveBinding()).getNamespaceScope();
} catch ( DOMException e ) { } catch ( DOMException e ) {
return e.getProblem(); return e.getProblem();
} }
@ -94,37 +108,35 @@ public class CPPASTNamespaceDefinition extends ASTNode implements
} }
} }
if( name != null ) if( !name.accept( action ) ) return false; if (fName != null && !fName.accept(action))
IASTDeclaration [] decls = getDeclarations(); return false;
for ( int i = 0; i < decls.length; i++ )
if( !decls[i].accept( action ) ) return false;
if (action.shouldVisitNamespaces && action instanceof ICPPASTVisitor) { IASTDeclaration [] decls = getDeclarations(action.includeInactiveNodes);
switch( ((ICPPASTVisitor)action).leave( this ) ){ for (IASTDeclaration decl : decls) {
case ASTVisitor.PROCESS_ABORT : return false; if (!decl.accept(action)) return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
} }
if (action.shouldVisitNamespaces && action instanceof ICPPASTVisitor &&
((ICPPASTVisitor) action).leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
return true; return true;
} }
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
if( name == n ) return r_definition; if( fName == n ) return r_definition;
return r_unclear; return r_unclear;
} }
public void replace(IASTNode child, IASTNode other) { public void replace(IASTNode child, IASTNode other) {
if( declarations == null ) return; assert child.isActive() == other.isActive();
for( int i = 0; i < declarations.length; ++i ) for (int i = 0; i <= fLastDeclaration; ++i) {
{ if (fAllDeclarations[i] == child) {
if( declarations[i] == null ) break;
if( declarations[i] == child )
{
other.setParent(child.getParent()); other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent()); other.setPropertyInParent(child.getPropertyInParent());
declarations[i] = (IASTDeclaration) other; fAllDeclarations[i] = (IASTDeclaration) other;
fActiveDeclarations= null;
return;
} }
} }
} }

View file

@ -12,11 +12,7 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IMacroBinding; import org.eclipse.cdt.core.dom.ast.IMacroBinding;
@ -32,7 +28,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CPPBuiltinParameter; import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CPPBuiltinParameter;
@ -57,10 +52,6 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
return copy; return copy;
} }
@Override
public void cleanupAfterAmbiguityResolution() {
}
public CPPNamespaceScope getScope() { public CPPNamespaceScope getScope() {
if (fScope == null) { if (fScope == null) {
fScope = new CPPNamespaceScope(this); fScope = new CPPNamespaceScope(this);
@ -69,7 +60,7 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
return fScope; return fScope;
} }
private void addBuiltinOperators(IScope theScope) { private void addBuiltinOperators(CPPScope theScope) {
// void // void
IType cpp_void = new CPPBasicType(IBasicType.t_void, 0); IType cpp_void = new CPPBasicType(IBasicType.t_void, 0);
// void * // void *
@ -85,16 +76,12 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
IParameter[] newTheParms = new IParameter[1]; IParameter[] newTheParms = new IParameter[1];
newTheParms[0] = new CPPBuiltinParameter(newParms[0]); newTheParms[0] = new CPPBuiltinParameter(newParms[0]);
temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms, false); temp = new CPPImplicitFunction(OverloadableOperator.NEW.toCharArray(), theScope, newFunctionType, newTheParms, false);
try { theScope.addBinding(temp);
ASTInternal.addBinding(theScope, temp);
} catch (DOMException de) {}
// void * operator new[] (std::size_t); // void * operator new[] (std::size_t);
temp = null; temp = null;
temp = new CPPImplicitFunction(OverloadableOperator.NEW_ARRAY.toCharArray(), theScope, newFunctionType, newTheParms, false); temp = new CPPImplicitFunction(OverloadableOperator.NEW_ARRAY.toCharArray(), theScope, newFunctionType, newTheParms, false);
try { theScope.addBinding(temp);
ASTInternal.addBinding(theScope, temp);
} catch (DOMException de) {}
// void operator delete(void*); // void operator delete(void*);
temp = null; temp = null;
@ -104,16 +91,12 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
IParameter[] deleteTheParms = new IParameter[1]; IParameter[] deleteTheParms = new IParameter[1];
deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]); deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]);
temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false); temp = new CPPImplicitFunction(OverloadableOperator.DELETE.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false);
try { theScope.addBinding(temp);
ASTInternal.addBinding(theScope, temp);
} catch (DOMException de) {}
// void operator delete[](void*); // void operator delete[](void*);
temp = null; temp = null;
temp = new CPPImplicitFunction(OverloadableOperator.DELETE_ARRAY.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false); temp = new CPPImplicitFunction(OverloadableOperator.DELETE_ARRAY.toCharArray(), theScope, deleteFunctionType, deleteTheParms, false);
try { theScope.addBinding(temp);
ASTInternal.addBinding(theScope, temp);
} catch (DOMException de) {}
} }
public IASTName[] getDeclarationsInAST(IBinding binding) { public IASTName[] getDeclarationsInAST(IBinding binding) {
@ -149,18 +132,6 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
return fBinding; return fBinding;
} }
public void replace(IASTNode child, IASTNode other) {
if (fDeclarations == null) return;
for(int i=0; i < fDeclarations.length; ++i) {
if (fDeclarations[i] == null) break;
if (fDeclarations[i] == child) {
other.setParent(child.getParent());
other.setPropertyInParent(child.getPropertyInParent());
fDeclarations[i] = (IASTDeclaration) other;
}
}
}
public ParserLanguage getParserLanguage() { public ParserLanguage getParserLanguage() {
return ParserLanguage.CPP; return ParserLanguage.CPP;
} }
@ -198,7 +169,7 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
} }
@Override @Override
protected ASTVisitor createAmbiguityNodeVisitor() { public void resolveAmbiguities() {
return new CPPASTAmbiguityResolver(); accept(new CPPASTAmbiguityResolver());
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008 Wind River Systems Inc. and others. * Copyright (c) 2008, 2009 Wind River Systems Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -87,15 +87,6 @@ public class CPPBuiltinVariable extends CPPVariable {
// do nothing // do nothing
} }
/**
* does nothing
*/
@Override
public void removeDeclaration(IASTNode node) {
// do nothing
}
@Override @Override
public String[] getQualifiedName() { public String[] getQualifiedName() {
String[] temp = new String[1]; String[] temp = new String[1];

View file

@ -163,6 +163,10 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
@Override @Override
public void addName(IASTName name) throws DOMException { public void addName(IASTName name) throws DOMException {
// don't add names from inactive code branches
if (!name.isActive())
return;
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
// check whether the qualification matches // check whether the qualification matches
IBinding b= getClassType(); IBinding b= getClassType();

View file

@ -333,14 +333,6 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
} }
} }
public void removeDeclaration(IASTNode node) {
if (definition == node) {
definition = null;
return;
}
ArrayUtil.remove(declarations, node);
}
public String[] getQualifiedName() { public String[] getQualifiedName() {
return CPPVisitor.getQualifiedName(this); return CPPVisitor.getQualifiedName(this);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -109,9 +109,6 @@ public class CPPEnumeration extends PlatformObject implements IEnumeration, ICPP
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
} }
public void removeDeclaration(IASTNode node) {
}
public boolean isSameType( IType type ) { public boolean isSameType( IType type ) {
if( type == this ) if( type == this )
return true; return true;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -58,9 +58,6 @@ public class CPPEnumerator extends PlatformObject implements IEnumerator, ICPPIn
return enumName; return enumName;
} }
public void removeDeclaration(IASTNode node) {
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName() * @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/ */

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -42,6 +42,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
@ -115,7 +116,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
public CPPFunction(ICPPASTFunctionDeclarator declarator) { public CPPFunction(ICPPASTFunctionDeclarator declarator) {
if (declarator != null) { if (declarator != null) {
IASTNode parent = CPPVisitor.findOutermostDeclarator(declarator).getParent(); IASTNode parent = ASTQueries.findOutermostDeclarator(declarator).getParent();
if (parent instanceof IASTFunctionDefinition) if (parent instanceof IASTFunctionDefinition)
definition = declarator; definition = declarator;
else else
@ -199,25 +200,13 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
node = node.getParent(); node = node.getParent();
if (node instanceof IASTDeclarator == false) if (node instanceof IASTDeclarator == false)
return null; return null;
node= CPPVisitor.findTypeRelevantDeclarator((IASTDeclarator) node); node= ASTQueries.findTypeRelevantDeclarator((IASTDeclarator) node);
if (node instanceof ICPPASTFunctionDeclarator == false) if (node instanceof ICPPASTFunctionDeclarator == false)
return null; return null;
return (ICPPASTFunctionDeclarator) node; return (ICPPASTFunctionDeclarator) node;
} }
public void removeDeclaration(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node);
if (definition == dtor) {
definition = null;
return;
}
if (declarations != null) {
ArrayUtil.remove(declarations, dtor);
}
}
public IParameter[] getParameters() { public IParameter[] getParameters() {
IASTStandardFunctionDeclarator dtor = getPreferredDtor(); IASTStandardFunctionDeclarator dtor = getPreferredDtor();
IASTParameterDeclaration[] params = dtor.getParameters(); IASTParameterDeclaration[] params = dtor.getParameters();
@ -226,7 +215,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (size > 0) { if (size > 0) {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
IASTParameterDeclaration p = params[i]; IASTParameterDeclaration p = params[i];
final IASTName name = CPPVisitor.findInnermostDeclarator(p.getDeclarator()).getName(); final IASTName name = ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName();
final IBinding binding= name.resolveBinding(); final IBinding binding= name.resolveBinding();
if (binding instanceof IParameter) { if (binding instanceof IParameter) {
result[i]= (IParameter) binding; result[i]= (IParameter) binding;
@ -262,7 +251,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
protected IASTName getASTName() { protected IASTName getASTName() {
IASTDeclarator dtor = (definition != null) ? definition : declarations[0]; IASTDeclarator dtor = (definition != null) ? definition : declarations[0];
dtor= CPPVisitor.findInnermostDeclarator(dtor); dtor= ASTQueries.findInnermostDeclarator(dtor);
IASTName name= dtor.getName(); IASTName name= dtor.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
@ -277,11 +266,11 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (scope instanceof ICPPClassScope) { if (scope instanceof ICPPClassScope) {
ICPPASTDeclSpecifier declSpec = null; ICPPASTDeclSpecifier declSpec = null;
if (definition != null) { if (definition != null) {
IASTNode node = CPPVisitor.findOutermostDeclarator(definition).getParent(); IASTNode node = ASTQueries.findOutermostDeclarator(definition).getParent();
IASTFunctionDefinition def = (IASTFunctionDefinition) node; IASTFunctionDefinition def = (IASTFunctionDefinition) node;
declSpec = (ICPPASTDeclSpecifier) def.getDeclSpecifier(); declSpec = (ICPPASTDeclSpecifier) def.getDeclSpecifier();
} else { } else {
IASTNode node = CPPVisitor.findOutermostDeclarator(declarations[0]).getParent(); IASTNode node = ASTQueries.findOutermostDeclarator(declarations[0]).getParent();
IASTSimpleDeclaration decl = (IASTSimpleDeclaration)node; IASTSimpleDeclaration decl = (IASTSimpleDeclaration)node;
declSpec = (ICPPASTDeclSpecifier) decl.getDeclSpecifier(); declSpec = (ICPPASTDeclSpecifier) decl.getDeclSpecifier();
} }
@ -328,10 +317,10 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
IASTParameterDeclaration[] paramDecls = definition.getParameters(); IASTParameterDeclaration[] paramDecls = definition.getParameters();
if (paramDecls.length > i) { // This will be less than i if we have a void parameter if (paramDecls.length > i) { // This will be less than i if we have a void parameter
temp = paramDecls[i]; temp = paramDecls[i];
IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) { if (n != name) {
n.setBinding(binding); n.setBinding(binding);
((CPPParameter)binding).addDeclaration(n); ASTInternal.addDeclaration(binding, n);
} }
} }
} }
@ -340,10 +329,10 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
IASTParameterDeclaration[] paramDecls = declarations[j].getParameters(); IASTParameterDeclaration[] paramDecls = declarations[j].getParameters();
if (paramDecls.length > i) { if (paramDecls.length > i) {
temp = paramDecls[i]; temp = paramDecls[i];
IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) { if (n != name) {
n.setBinding(binding); n.setBinding(binding);
((CPPParameter)binding).addDeclaration(n); ASTInternal.addDeclaration(binding, n);
} }
} }
} }
@ -357,14 +346,14 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
IASTParameterDeclaration[] nps = fdtor.getParameters(); IASTParameterDeclaration[] nps = fdtor.getParameters();
CPPParameter temp = null; CPPParameter temp = null;
for (int i = 0; i < ops.length; i++) { for (int i = 0; i < ops.length; i++) {
temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding(); temp = (CPPParameter) ASTQueries.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
if (temp != null && nps.length > i) { //length could be different, ie 0 or 1 with void if (temp != null && nps.length > i) { //length could be different, ie 0 or 1 with void
IASTDeclarator dtor = nps[i].getDeclarator(); IASTDeclarator dtor = nps[i].getDeclarator();
while (dtor.getNestedDeclarator() != null) while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator(); dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName(); IASTName name = dtor.getName();
name.setBinding(temp); name.setBinding(temp);
temp.addDeclaration(name); ASTInternal.addDeclaration(temp, name);
} }
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/** /**
@ -179,10 +180,10 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
try { try {
IParameter[] params = getParameters(); IParameter[] params = getParameters();
if (i < params.length) { if (i < params.length) {
name.setBinding(params[i]); final IParameter myParam = params[i];
if (params[i] instanceof ICPPInternalBinding) name.setBinding(myParam);
((ICPPInternalBinding)params[i]).addDeclaration(name); ASTInternal.addDeclaration(myParam, name);
return params[i]; return myParam;
} }
} catch (DOMException e) { } catch (DOMException e) {
@ -222,15 +223,14 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
} }
IASTParameterDeclaration[] nps = fdtor.getParameters(); IASTParameterDeclaration[] nps = fdtor.getParameters();
for (int i = 0; i < nps.length; i++) { for (int i = 0; i < nps.length; i++) {
//temp = (CPPParameter) ops[i].getDeclarator().getName().getBinding(); final IParameter param = params[i];
if (params[i] != null) { if (param != null) {
IASTDeclarator dtor = nps[i].getDeclarator(); IASTDeclarator dtor = nps[i].getDeclarator();
while (dtor.getNestedDeclarator() != null) while (dtor.getNestedDeclarator() != null)
dtor = dtor.getNestedDeclarator(); dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName(); IASTName name = dtor.getName();
name.setBinding(params[i]); name.setBinding(param);
if (params[i] instanceof ICPPInternalBinding) ASTInternal.addDeclaration(param, name);
((ICPPInternalBinding) params[i]).addDeclaration(name);
} }
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -35,6 +35,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@ -130,11 +132,11 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters(); IASTParameterDeclaration[] nps = getDeclaratorByName(declName).getParameters();
CPPParameter temp = null; CPPParameter temp = null;
for(int i = 0; i < nps.length; i++) { for(int i = 0; i < nps.length; i++) {
temp = (CPPParameter) CPPVisitor.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding(); temp = (CPPParameter) ASTQueries.findInnermostDeclarator(ops[i].getDeclarator()).getName().getBinding();
if (temp != null) { if (temp != null) {
IASTName name = CPPVisitor.findInnermostDeclarator(nps[i].getDeclarator()).getName(); IASTName name = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
name.setBinding(temp); name.setBinding(temp);
temp.addDeclaration(name); ASTInternal.addDeclaration(temp, name);
} }
} }
} }
@ -149,7 +151,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
if (size > 0) { if (size > 0) {
for(int i = 0; i < size; i++) { for(int i = 0; i < size; i++) {
IASTParameterDeclaration p = params[i]; IASTParameterDeclaration p = params[i];
final IASTName pname = CPPVisitor.findInnermostDeclarator(p.getDeclarator()).getName(); final IASTName pname = ASTQueries.findInnermostDeclarator(p.getDeclarator()).getName();
final IBinding binding= pname.resolveBinding(); final IBinding binding= pname.resolveBinding();
if (binding instanceof IParameter) { if (binding instanceof IParameter) {
result[i]= (IParameter) binding; result[i]= (IParameter) binding;
@ -211,7 +213,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
} }
public IBinding resolveParameter(IASTParameterDeclaration param) { public IBinding resolveParameter(IASTParameterDeclaration param) {
IASTName name = CPPVisitor.findInnermostDeclarator(param.getDeclarator()).getName(); IASTName name = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
IBinding binding = name.getBinding(); IBinding binding = name.getBinding();
if (binding != null) if (binding != null)
return binding; return binding;
@ -231,10 +233,10 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition); ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(definition);
if (fdecl != null) { if (fdecl != null) {
temp = fdecl.getParameters()[i]; temp = fdecl.getParameters()[i];
IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) { if (n != name) {
n.setBinding(binding); n.setBinding(binding);
((CPPParameter)binding).addDeclaration(n); ASTInternal.addDeclaration(binding, n);
} }
} }
} }
@ -243,10 +245,10 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]); ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(declarations[j]);
if (fdecl != null) { if (fdecl != null) {
temp = fdecl.getParameters()[i]; temp = fdecl.getParameters()[i];
IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
if (n != name) { if (n != name) {
n.setBinding(binding); n.setBinding(binding);
((CPPParameter)binding).addDeclaration(n); ASTInternal.addDeclaration(binding, n);
} }
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -18,7 +18,8 @@ import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
/** /**
* The CPPImplicitFunction is used to represent implicit functions that exist on the translation * The CPPImplicitFunction is used to represent implicit functions that exist on the translation
@ -83,7 +84,7 @@ public class CPPImplicitFunction extends CPPFunction {
@Override @Override
public IBinding resolveParameter(IASTParameterDeclaration param) { public IBinding resolveParameter(IASTParameterDeclaration param) {
IASTName aName = CPPVisitor.findInnermostDeclarator(param.getDeclarator()).getName(); IASTName aName = ASTQueries.findInnermostDeclarator(param.getDeclarator()).getName();
IParameter binding = (IParameter) aName.getBinding(); IParameter binding = (IParameter) aName.getBinding();
if (binding != null) if (binding != null)
return binding; return binding;
@ -102,16 +103,16 @@ public class CPPImplicitFunction extends CPPFunction {
IASTParameterDeclaration temp = null; IASTParameterDeclaration temp = null;
if (definition != null) { if (definition != null) {
temp = definition.getParameters()[i]; temp = definition.getParameters()[i];
IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
n.setBinding(binding); n.setBinding(binding);
((CPPParameter)binding).addDeclaration( n ); ASTInternal.addDeclaration(binding, n);
} }
if (declarations != null) { if (declarations != null) {
for (int j = 0; j < declarations.length && declarations[j] != null; j++) { for (int j = 0; j < declarations.length && declarations[j] != null; j++) {
temp = declarations[j].getParameters()[i]; temp = declarations[j].getParameters()[i];
IASTName n = CPPVisitor.findInnermostDeclarator(temp.getDeclarator()).getName(); IASTName n = ASTQueries.findInnermostDeclarator(temp.getDeclarator()).getName();
n.setBinding(binding); n.setBinding(binding);
((CPPParameter)binding).addDeclaration( n ); ASTInternal.addDeclaration(binding, n);
} }
} }
return binding; return binding;
@ -125,10 +126,10 @@ public class CPPImplicitFunction extends CPPFunction {
return; return;
for (int i = 0; i < nps.length; i++) { for (int i = 0; i < nps.length; i++) {
IASTName aName = CPPVisitor.findInnermostDeclarator(nps[i].getDeclarator()).getName(); IASTName aName = ASTQueries.findInnermostDeclarator(nps[i].getDeclarator()).getName();
aName.setBinding( parms[i] ); final IParameter param = parms[i];
if( parms[i] instanceof ICPPInternalBinding ) aName.setBinding(param);
((ICPPInternalBinding)parms[i]).addDeclaration( aName ); ASTInternal.addDeclaration(param, aName);
} }
} }
} }

View file

@ -149,9 +149,9 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod
if (ok) { if (ok) {
name.setBinding(this); name.setBinding(this);
if (member instanceof IASTSimpleDeclaration) if (member instanceof IASTSimpleDeclaration)
addDeclaration(dtor); ASTInternal.addDeclaration(this, dtor);
else if (member instanceof IASTFunctionDefinition) else if (member instanceof IASTFunctionDefinition)
addDefinition(dtor); ASTInternal.addDefinition(this, dtor);
return member; return member;
} }
} }

View file

@ -1,12 +1,13 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * Devin Steffler (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -21,8 +22,6 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
* unit but are not actually part of the physical AST created by CDT. * unit but are not actually part of the physical AST created by CDT.
* *
* An example is the GCC built-in typedef: typedef char * __builtin_va_list; * An example is the GCC built-in typedef: typedef char * __builtin_va_list;
*
* @author dsteffle
*/ */
public class CPPImplicitTypedef extends CPPTypedef { public class CPPImplicitTypedef extends CPPTypedef {
private IType type=null; private IType type=null;
@ -115,15 +114,6 @@ public class CPPImplicitTypedef extends CPPTypedef {
// do nothing // do nothing
} }
/**
* does nothing
*/
@Override
public void removeDeclaration(IASTNode node) {
// do nothing
}
@Override @Override
public String[] getQualifiedName() { public String[] getQualifiedName() {
String[] temp = new String[1]; String[] temp = new String[1];

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -88,8 +88,6 @@ public class CPPLabel extends PlatformObject implements ILabel, ICPPInternalBind
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
} }
public void removeDeclaration(IASTNode node) {
}
public ILinkage getLinkage() { public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE; return Linkage.CPP_LINKAGE;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -303,8 +303,8 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
public void addDefinition(IASTNode node) { public void addDefinition(IASTNode node) {
if (!(node instanceof IASTName)) if (!(node instanceof IASTName))
return; return;
IASTName name = (IASTName) node;
IASTName name = (IASTName) node;
if (namespaceDefinitions == null) { if (namespaceDefinitions == null) {
namespaceDefinitions = new IASTName[] { name }; namespaceDefinitions = new IASTName[] { name };
return; return;
@ -323,9 +323,6 @@ public class CPPNamespace extends PlatformObject implements ICPPNamespace, ICPPI
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
addDefinition(node); addDefinition(node);
} }
public void removeDeclaration(IASTNode node) {
ArrayUtil.remove(namespaceDefinitions, node);
}
public IBinding[] getMemberBindings() { public IBinding[] getMemberBindings() {
if (namespaceDefinitions != null) { if (namespaceDefinitions != null) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -91,9 +91,6 @@ public class CPPNamespaceAlias extends PlatformObject implements ICPPNamespaceAl
} }
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
}
public void removeDeclaration(IASTNode node) {
} }
public IBinding[] getMemberBindings() throws DOMException { public IBinding[] getMemberBindings() throws DOMException {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -123,10 +123,6 @@ public class CPPParameter extends PlatformObject implements ICPPParameter, ICPPI
} }
} }
public void removeDeclaration(IASTNode node) {
ArrayUtil.remove(declarations, node);
}
private IASTName getPrimaryDeclaration() { private IASTName getPrimaryDeclaration() {
if (declarations != null) { if (declarations != null) {
for (int i = 0; i < declarations.length && declarations[i] != null; i++) { for (int i = 0; i < declarations.length && declarations[i] != null; i++) {

View file

@ -78,6 +78,10 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void addName(IASTName name) throws DOMException { public void addName(IASTName name) throws DOMException {
// don't add inactive names to the scope
if (!name.isActive())
return;
if (bindings == null) if (bindings == null)
bindings = new CharArrayObjectMap(1); bindings = new CharArrayObjectMap(1);
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -97,14 +97,6 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
} }
} }
public void removeDeclaration(IASTNode node) {
if (node == definition) {
definition = null;
return;
}
ArrayUtil.remove(declarations, node);
}
public String getName() { public String getName() {
return specialized.getName(); return specialized.getName();
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -238,14 +239,6 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
} }
} }
public void removeDeclaration(IASTNode node) {
if (definition == node) {
definition = null;
return;
}
ArrayUtil.remove(declarations, node);
}
public IBinding resolveTemplateParameter(ICPPTemplateParameter templateParameter) { public IBinding resolveTemplateParameter(ICPPTemplateParameter templateParameter) {
int pos= templateParameter.getParameterPosition(); int pos= templateParameter.getParameterPosition();
@ -298,9 +291,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
IBinding b= oName.resolvePreBinding(); IBinding b= oName.resolvePreBinding();
IASTName n = CPPTemplates.getTemplateParameterName(updateParams[k]); IASTName n = CPPTemplates.getTemplateParameterName(updateParams[k]);
n.setBinding(b); n.setBinding(b);
if (b instanceof ICPPInternalBinding) { ASTInternal.addDeclaration(b, n);
((ICPPInternalBinding) b).addDeclaration(n);
}
} }
} }
} }

View file

@ -198,9 +198,6 @@ public abstract class CPPTemplateParameter extends PlatformObject
} }
} }
} }
public void removeDeclaration(IASTNode node) {
ArrayUtil.remove(declarations, node);
}
public ILinkage getLinkage() { public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE; return Linkage.CPP_LINKAGE;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -190,10 +190,6 @@ public class CPPTypedef extends PlatformObject implements ITypedef, ITypeContain
} }
} }
public void removeDeclaration(IASTNode node) {
ArrayUtil.remove(declarations, node);
}
public ILinkage getLinkage() { public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE; return Linkage.CPP_LINKAGE;
} }

View file

@ -57,9 +57,6 @@ public class CPPUnknownBinding extends PlatformObject
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
} }
public void removeDeclaration(IASTNode node) {
}
public String[] getQualifiedName() { public String[] getQualifiedName() {
return CPPVisitor.getQualifiedName(this); return CPPVisitor.getQualifiedName(this);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -91,9 +91,6 @@ public class CPPUsingDeclaration extends PlatformObject implements ICPPUsingDecl
} }
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
}
public void removeDeclaration(IASTNode node) {
} }
public ILinkage getLinkage() { public ILinkage getLinkage() {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -168,14 +168,6 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
} }
} }
public void removeDeclaration(IASTNode node) {
if (node == definition) {
definition = null;
return;
}
ArrayUtil.remove(declarations, node);
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations() * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
*/ */

View file

@ -269,7 +269,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
qname.addName(name); qname.addName(name);
} }
if (LT(1) != IToken.tCOLONCOLON) if (LTcatchEOF(1) != IToken.tCOLONCOLON)
break loop; break loop;
if (mustBeLast) if (mustBeLast)
@ -367,7 +367,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
* Makes a fast check whether there could be template arguments. * Makes a fast check whether there could be template arguments.
*/ */
private boolean canBeTemplateArguments() throws EndOfFileException, BacktrackException { private boolean canBeTemplateArguments() throws EndOfFileException, BacktrackException {
if (LT(1) != IToken.tLT) if (LTcatchEOF(1) != IToken.tLT)
return false; return false;
final IToken mark= mark(); final IToken mark= mark();
@ -1344,62 +1344,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
ICPPASTLinkageSpecification linkage = nodeFactory.newLinkageSpecification(spec); ICPPASTLinkageSpecification linkage = nodeFactory.newLinkageSpecification(spec);
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
int endOffset= consume().getEndOffset(); declarationListInBraces(linkage, offset, DeclarationOptions.GLOBAL);
int declOffset= -1;
while(true) {
IToken next= LAcatchEOF(1);
if (next == null) {
((ASTNode) linkage).setOffsetAndLength(offset, endOffset-offset);
throwBacktrack(createProblem(IProblem.SYNTAX_ERROR, endOffset, 0), linkage);
return null; // hint for java-compiler
}
try {
if (next.getType() == IToken.tEOC)
break;
if (next.getType() == IToken.tRBRACE) {
endOffset= consume().getEndOffset();
break;
}
final int nextOffset = next.getOffset();
declarationMark= next;
next= null; // don't hold on to the token while parsing namespaces, class bodies, etc.
IASTDeclaration d;
if (declOffset == nextOffset) {
// no progress
d= skipProblemDeclaration(declOffset);
} else {
declOffset= nextOffset;
d= declaration(DeclarationOptions.GLOBAL);
}
linkage.addDeclaration(d);
endOffset= calculateEndOffset(d);
} catch (BacktrackException bt) {
IASTDeclaration[] decls= problemDeclaration(declOffset, bt, DeclarationOptions.GLOBAL);
for (IASTDeclaration declaration : decls) {
linkage.addDeclaration(declaration);
endOffset= calculateEndOffset(declaration);
}
} catch (EndOfFileException e) {
IASTDeclaration d= skipProblemDeclaration(declOffset);
linkage.addDeclaration(d);
endOffset= calculateEndOffset(d);
break;
} finally {
declarationMark= null;
}
}
((ASTNode) linkage).setOffsetAndLength(offset, endOffset - offset);
return linkage; return linkage;
} }
// single declaration // single declaration
IASTDeclaration d = declaration(DeclarationOptions.GLOBAL); IASTDeclaration d = declaration(DeclarationOptions.GLOBAL);
linkage.addDeclaration(d); linkage.addDeclaration(d);
int endOffset= calculateEndOffset(d); setRange(linkage, offset, calculateEndOffset(d));
((ASTNode) linkage).setOffsetAndLength(offset, endOffset-offset);
return linkage; return linkage;
} }
@ -1636,9 +1588,32 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
((ASTNode) declspec).setOffsetAndLength(t.getOffset(), 0); ((ASTNode) declspec).setOffsetAndLength(t.getOffset(), 0);
((ASTNode) decl).setOffsetAndLength(t.getOffset(), t.getLength()); ((ASTNode) decl).setOffsetAndLength(t.getOffset(), t.getLength());
return decl; return decl;
case IToken.t_public:
case IToken.t_protected:
case IToken.t_private:
if (option == DeclarationOptions.CPP_MEMBER) {
t= consume();
int key= t.getType();
int endOffset= consume(IToken.tCOLON).getEndOffset();
ICPPASTVisibilityLabel label = nodeFactory.newVisibilityLabel(token2Visibility(key));
setRange(label, t.getOffset(), endOffset);
return label;
}
break;
} }
try {
return simpleDeclaration(option); return simpleDeclaration(option);
} catch (BacktrackException e) {
if (option != DeclarationOptions.CPP_MEMBER || declarationMark == null)
throw e;
backup(declarationMark);
try {
return usingDeclaration(declarationMark.getOffset());
} catch (BacktrackException e2) {
throw e; // throw original exception;
}
}
} }
/** /**
@ -1667,54 +1642,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (LT(1) == IToken.tLBRACE) { if (LT(1) == IToken.tLBRACE) {
ICPPASTNamespaceDefinition ns = nodeFactory.newNamespaceDefinition(name); ICPPASTNamespaceDefinition ns = nodeFactory.newNamespaceDefinition(name);
endOffset= consume().getEndOffset(); declarationListInBraces(ns, offset, DeclarationOptions.GLOBAL);
int declOffset= -1;
while(true) {
IToken next= LAcatchEOF(1);
if (next == null) {
((ASTNode) ns).setOffsetAndLength(offset, endOffset-offset);
throwBacktrack(createProblem(IProblem.SYNTAX_ERROR, endOffset, 0), ns);
return null; // hint for java-compiler
}
try {
if (next.getType() == IToken.tEOC)
break;
if (next.getType() == IToken.tRBRACE) {
endOffset= consume().getEndOffset();
break;
}
final int nextOffset = next.getOffset();
declarationMark= next;
next= null; // don't hold on to the token while parsing namespaces, class bodies, etc.
IASTDeclaration d;
if (declOffset == nextOffset) {
// no progress
d= skipProblemDeclaration(declOffset);
} else {
declOffset= nextOffset;
d= declaration(DeclarationOptions.GLOBAL);
}
ns.addDeclaration(d);
endOffset= calculateEndOffset(d);
} catch (BacktrackException bt) {
IASTDeclaration[] decls= problemDeclaration(declOffset, bt, DeclarationOptions.GLOBAL);
for (IASTDeclaration declaration : decls) {
ns.addDeclaration(declaration);
endOffset= calculateEndOffset(declaration);
}
} catch (EndOfFileException e) {
IASTDeclaration d= skipProblemDeclaration(declOffset);
ns.addDeclaration(d);
endOffset= calculateEndOffset(d);
break;
} finally {
declarationMark= null;
}
}
((ASTNode) ns).setOffsetAndLength(offset, endOffset - offset);
return ns; return ns;
} }
@ -2629,7 +2557,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
throws EndOfFileException, BacktrackException, FoundAggregateInitializer { throws EndOfFileException, BacktrackException, FoundAggregateInitializer {
final IASTDeclarator dtor= declarator(strategy, option); final IASTDeclarator dtor= declarator(strategy, option);
if (option.fAllowInitializer) { if (option.fAllowInitializer) {
if (LT(1) == IToken.tASSIGN && LT(2) == IToken.tLBRACE) if (LTcatchEOF(1) == IToken.tASSIGN && LTcatchEOF(2) == IToken.tLBRACE)
throw new FoundAggregateInitializer(dtor); throw new FoundAggregateInitializer(dtor);
IASTInitializer initializer= optionalCPPInitializer(dtor); IASTInitializer initializer= optionalCPPInitializer(dtor);
@ -2658,7 +2586,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected IASTInitializer optionalCPPInitializer(IASTDeclarator d) throws EndOfFileException, BacktrackException { protected IASTInitializer optionalCPPInitializer(IASTDeclarator d) throws EndOfFileException, BacktrackException {
// handle initializer // handle initializer
if (LT(1) == IToken.tASSIGN) { final int lt1= LTcatchEOF(1);
if (lt1 == IToken.tASSIGN) {
consume(); consume();
try { try {
return initializerClause(false); return initializerClause(false);
@ -2666,7 +2595,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
failParse(); failParse();
throw eof; throw eof;
} }
} else if (LT(1) == IToken.tLPAREN) { } else if (lt1 == IToken.tLPAREN) {
if (d instanceof IASTFunctionDeclarator && d.getNestedDeclarator() == null) { if (d instanceof IASTFunctionDeclarator && d.getNestedDeclarator() == null) {
// constructor initializer doesn't make sense for a function // constructor initializer doesn't make sense for a function
// declarator, // declarator,
@ -2911,8 +2840,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
boolean isConst = false, isVolatile = false, isRestrict = false; boolean isConst = false, isVolatile = false, isRestrict = false;
IASTName name= null; IASTName name= null;
int coloncolon= LT(1) == IToken.tCOLONCOLON ? 1 : 0; int coloncolon= LT(1) == IToken.tCOLONCOLON ? 1 : 0;
loop: while (LT(coloncolon+1) == IToken.tIDENTIFIER) { loop: while (LTcatchEOF(coloncolon+1) == IToken.tIDENTIFIER) {
switch(LT(coloncolon+2)) { switch(LTcatchEOF(coloncolon+2)) {
case IToken.tCOLONCOLON: case IToken.tCOLONCOLON:
coloncolon+= 2; coloncolon+= 2;
break; break;
@ -2936,14 +2865,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return; return;
} }
} }
if (LT(1) != IToken.tSTAR) { if (LTcatchEOF(1) != IToken.tSTAR) {
backup(mark); backup(mark);
return; return;
} }
int endOffset= consume().getEndOffset(); int endOffset= consume().getEndOffset();
loop: for (;;) { loop: for (;;) {
switch (LT(1)) { switch (LTcatchEOF(1)) {
case IToken.t_const: case IToken.t_const:
endOffset= consume().getEndOffset(); endOffset= consume().getEndOffset();
isConst = true; isConst = true;
@ -2995,7 +2924,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
throws EndOfFileException, BacktrackException { throws EndOfFileException, BacktrackException {
IASTDeclarator result= null; IASTDeclarator result= null;
loop: while(true) { loop: while(true) {
final int lt1= LT(1); final int lt1= LTcatchEOF(1);
switch (lt1) { switch (lt1) {
case IToken.tLPAREN: case IToken.tLPAREN:
if (option.fAllowFunctions && strategy == DtorStrategy.PREFER_FUNCTION) { if (option.fAllowFunctions && strategy == DtorStrategy.PREFER_FUNCTION) {
@ -3040,7 +2969,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
endOffset= calculateEndOffset(result); endOffset= calculateEndOffset(result);
} }
if (LT(1) == IToken.t_asm) { // asm labels bug 226121 if (LTcatchEOF(1) == IToken.t_asm) { // asm labels bug 226121
consume(); consume();
endOffset= asmExpression(null).getEndOffset(); endOffset= asmExpression(null).getEndOffset();
@ -3267,80 +3196,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
throwBacktrack(errorPoint); throwBacktrack(errorPoint);
} }
mark= null; // don't hold on to tokens while parsing the members. mark= null; // don't hold on to tokens while parsing the members.
int endOffset= consume().getEndOffset();
final char[] outerName= currentClassName; final char[] outerName= currentClassName;
currentClassName= name.getLookupKey(); currentClassName= name.getLookupKey();
try { try {
int declOffset= -1; declarationListInBraces(astClassSpecifier, offset, DeclarationOptions.CPP_MEMBER);
loop: while (true) {
BacktrackException origBackTrack= null;
try {
IToken next= LAcatchEOF(1);
if (next == null || next.getType() == IToken.tEOC)
break loop; // the missing semicolon will cause a problem, just break the loop.
if (next.getType() == IToken.tRBRACE) {
endOffset= consume().getEndOffset();
break loop;
}
final int nextOffset = next.getOffset();
declarationMark= next;
next= null; // don't hold on to the token while parsing namespaces, class bodies, etc.
IASTDeclaration d;
if (declOffset == nextOffset) {
// no progress
d= skipProblemDeclaration(declOffset);
} else {
declOffset= nextOffset;
switch (LT(1)) {
case IToken.t_public:
case IToken.t_protected:
case IToken.t_private:
int key= consume().getType();
endOffset= consume(IToken.tCOLON).getEndOffset();
ICPPASTVisibilityLabel label = nodeFactory.newVisibilityLabel(token2Visibility(key));
((ASTNode) label).setOffsetAndLength(declOffset, endOffset - declOffset);
astClassSpecifier.addMemberDeclaration(label);
continue loop;
}
try {
d= declaration(DeclarationOptions.CPP_MEMBER);
} catch (BacktrackException e) {
if (declarationMark == null)
throw e;
origBackTrack= new BacktrackException(e);
backup(declarationMark);
d= usingDeclaration(declarationMark.getOffset());
}
}
astClassSpecifier.addMemberDeclaration(d);
endOffset= calculateEndOffset(d);
} catch (BacktrackException bt) {
if (origBackTrack != null) {
bt= origBackTrack;
}
IASTDeclaration[] decls= problemDeclaration(declOffset, bt, DeclarationOptions.CPP_MEMBER);
for (IASTDeclaration declaration : decls) {
astClassSpecifier.addMemberDeclaration(declaration);
endOffset= calculateEndOffset(declaration);
}
} catch (EndOfFileException e) {
astClassSpecifier.addMemberDeclaration(skipProblemDeclaration(declOffset));
endOffset= eofOffset;
break loop;
} finally {
declarationMark= null;
}
}
} finally { } finally {
currentClassName= outerName; currentClassName= outerName;
} }
((ASTNode) astClassSpecifier).setOffsetAndLength(offset, endOffset - offset);
return astClassSpecifier; return astClassSpecifier;
} }
@ -3501,19 +3364,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
protected IASTStatement catchBlockCompoundStatement() throws BacktrackException, EndOfFileException { protected IASTStatement catchBlockCompoundStatement() throws BacktrackException, EndOfFileException {
if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE) { if (mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE || !isActiveCode()) {
IToken curr = LA(1); int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement(); IToken last = skipOverCompoundStatement();
IASTCompoundStatement cs = nodeFactory.newCompoundStatement(); IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last.getEndOffset() - curr.getOffset()); setRange(cs, offset, last.getEndOffset());
return cs; return cs;
} else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) { } else if (mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE) {
if (scanner.isOnTopContext()) if (scanner.isOnTopContext())
return compoundStatement(); return compoundStatement();
IToken curr = LA(1); int offset = LA(1).getOffset();
IToken last = skipOverCompoundStatement(); IToken last = skipOverCompoundStatement();
IASTCompoundStatement cs = nodeFactory.newCompoundStatement(); IASTCompoundStatement cs = nodeFactory.newCompoundStatement();
((ASTNode) cs).setOffsetAndLength(curr.getOffset(), last.getEndOffset() - curr.getOffset()); setRange(cs, offset, last.getEndOffset());
return cs; return cs;
} }
return compoundStatement(); return compoundStatement();

View file

@ -1,12 +1,12 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -14,19 +14,15 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
/** /**
* @author aniefer * Non api methods for cpp bindings.
*/ */
public interface ICPPInternalBinding extends ICPPBinding { public interface ICPPInternalBinding extends ICPPBinding {
//methods required by the CPPVisitor but not meant for the public interface
IASTNode getDefinition();
//implementors should keep the node with the lowest offset in declarations[0] //implementors should keep the node with the lowest offset in declarations[0]
IASTNode[] getDeclarations(); IASTNode[] getDeclarations();
IASTNode getDefinition();
/**
* @param declarator
*/
void addDefinition(IASTNode node); void addDefinition(IASTNode node);
void addDeclaration(IASTNode node); void addDeclaration(IASTNode node);
void removeDeclaration(IASTNode node);
} }

View file

@ -422,9 +422,15 @@ public class CPPSemantics {
} }
} }
if (binding != null && !(binding instanceof IProblemBinding)) { if (binding instanceof IFunction && !(binding instanceof IProblemBinding)) {
if (data.forFunctionDeclaration()) { if (data.forFunctionDeclaration()) {
addDefinition(binding, data.astName); IASTNode node = data.astName.getParent();
if (node instanceof ICPPASTQualifiedName)
node = node.getParent();
if (node instanceof ICPPASTFunctionDeclarator
&& node.getParent() instanceof IASTFunctionDefinition) {
ASTInternal.addDefinition(binding, node);
}
} }
} }
// If we're still null... // If we're still null...
@ -1483,18 +1489,6 @@ public class CPPSemantics {
} }
} }
private static void addDefinition(IBinding binding, IASTName name) {
if (binding instanceof IFunction) {
IASTNode node = name.getParent();
if (node instanceof ICPPASTQualifiedName)
node = node.getParent();
if (node instanceof ICPPASTFunctionDeclarator && node.getParent() instanceof IASTFunctionDefinition) {
if (binding instanceof ICPPInternalBinding)
((ICPPInternalBinding)binding).addDefinition(node);
}
}
}
public static IBinding resolveAmbiguities(IASTName name, Object[] bindings) { public static IBinding resolveAmbiguities(IASTName name, Object[] bindings) {
bindings = ArrayUtil.trim(Object.class, bindings); bindings = ArrayUtil.trim(Object.class, bindings);
if (bindings == null || bindings.length == 0) { if (bindings == null || bindings.length == 0) {

View file

@ -88,6 +88,7 @@ import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
@ -591,9 +592,9 @@ public class CPPTemplates {
result= instantiate(classTemplate, args); result= instantiate(classTemplate, args);
if (result instanceof ICPPInternalBinding) { if (result instanceof ICPPInternalBinding) {
if (isDecl) { if (isDecl) {
((ICPPInternalBinding) result).addDeclaration(id); ASTInternal.addDeclaration(result, id);
} else if (isDef) { } else if (isDef) {
((ICPPInternalBinding) result).addDefinition(id); ASTInternal.addDefinition(result, id);
} }
} }
} }

View file

@ -354,9 +354,7 @@ public class CPPVisitor extends ASTQueries {
} }
if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) {
binding= ((CPPASTTranslationUnit) elabType.getTranslationUnit()).mapToAST((ICPPClassType) binding); binding= ((CPPASTTranslationUnit) elabType.getTranslationUnit()).mapToAST((ICPPClassType) binding);
if (binding instanceof ICPPInternalBinding) { ASTInternal.addDeclaration(binding, elabType);
((ICPPInternalBinding) binding).addDeclaration(elabType);
}
} }
if (binding != null && if (binding != null &&
@ -392,7 +390,7 @@ public class CPPVisitor extends ASTQueries {
if (scope != null) { if (scope != null) {
binding = scope.getBinding(elabType.getName(), false); binding = scope.getBinding(elabType.getName(), false);
} }
if (!(binding instanceof ICPPInternalBinding) || !(binding instanceof ICPPClassType)) { if (!(binding instanceof ICPPInternalBinding) || !(binding instanceof ICPPClassType) && name.isActive()) {
if (elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum) { if (elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum) {
if (template) if (template)
binding = new CPPClassTemplate(name); binding = new CPPClassTemplate(name);
@ -403,7 +401,7 @@ public class CPPVisitor extends ASTQueries {
} }
} else { } else {
if ((binding instanceof ICPPClassTemplate) == template) { if ((binding instanceof ICPPClassTemplate) == template) {
((ICPPInternalBinding) binding).addDeclaration(elabType); ASTInternal.addDeclaration(binding, elabType);
} else { } else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION); binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
} }
@ -435,20 +433,19 @@ public class CPPVisitor extends ASTQueries {
} }
if (name.getLookupKey().length > 0 && scope != null) // can't lookup anonymous things if (name.getLookupKey().length > 0 && scope != null) // can't lookup anonymous things
binding = scope.getBinding(name, false); binding = scope.getBinding(name, false);
if (!(binding instanceof ICPPInternalBinding) || !(binding instanceof ICPPClassType)) { if (binding instanceof ICPPInternalBinding && binding instanceof ICPPClassType && name.isActive()) {
ICPPInternalBinding internal = (ICPPInternalBinding) binding;
if (internal.getDefinition() == null && (binding instanceof ICPPClassTemplate) == template) {
ASTInternal.addDefinition(internal, compType);
} else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION);
}
} else {
if (template) { if (template) {
binding = new CPPClassTemplate(name); binding = new CPPClassTemplate(name);
} else { } else {
binding = new CPPClassType(name, binding); binding = new CPPClassType(name, binding);
} }
} else {
ICPPInternalBinding internal = (ICPPInternalBinding) binding;
if (internal.getDefinition() == null &&
(binding instanceof ICPPClassTemplate) == template) {
internal.addDefinition(compType);
} else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDEFINITION);
}
} }
} catch (DOMException e) { } catch (DOMException e) {
binding = e.getProblem(); binding = e.getProblem();
@ -539,11 +536,10 @@ public class CPPVisitor extends ASTQueries {
ICPPASTTemplateDeclaration tmplDecl= CPPTemplates.getTemplateDeclaration(name); ICPPASTTemplateDeclaration tmplDecl= CPPTemplates.getTemplateDeclaration(name);
if (tmplDecl instanceof ICPPASTTemplateSpecialization) { if (tmplDecl instanceof ICPPASTTemplateSpecialization) {
IBinding b= CPPSemantics.resolveBinding(name); IBinding b= CPPSemantics.resolveBinding(name);
if (b instanceof ICPPInternalBinding) { if (parent instanceof ICPPASTFunctionDefinition) {
if (parent instanceof ICPPASTFunctionDefinition) ASTInternal.addDefinition(b, name);
((ICPPInternalBinding) b).addDefinition(name); } else {
else ASTInternal.addDeclaration(b, name);
((ICPPInternalBinding) b).addDeclaration(name);
} }
return b; return b;
} }
@ -625,13 +621,12 @@ public class CPPVisitor extends ASTQueries {
} }
} else if (simpleDecl != null && } else if (simpleDecl != null &&
simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) { simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
if (binding instanceof ICPPInternalBinding && binding instanceof ITypedef) { if (binding instanceof ICPPInternalBinding && binding instanceof ITypedef && name.isActive()) {
try { try {
IType t1 = ((ITypedef) binding).getType(); IType t1 = ((ITypedef) binding).getType();
IType t2 = createType(declarator); IType t2 = createType(declarator);
if (t1 != null && t2 != null && t1.isSameType(t2)) { if (t1 != null && t2 != null && t1.isSameType(t2)) {
ICPPInternalBinding internal = (ICPPInternalBinding) binding; ASTInternal.addDeclaration(binding, name);
internal.addDeclaration(name);
return binding; return binding;
} }
} catch (DOMException e1) { } catch (DOMException e1) {
@ -646,14 +641,14 @@ public class CPPVisitor extends ASTQueries {
td.setType(targetType); td.setType(targetType);
binding = td; binding = td;
} else if (funcDeclarator != null) { } else if (funcDeclarator != null) {
if (binding instanceof ICPPInternalBinding && binding instanceof IFunction) { if (binding instanceof ICPPInternalBinding && binding instanceof IFunction && name.isActive()) {
IFunction function = (IFunction) binding; IFunction function = (IFunction) binding;
if (CPPSemantics.isSameFunction(function, funcDeclarator)) { if (CPPSemantics.isSameFunction(function, funcDeclarator)) {
ICPPInternalBinding internal = (ICPPInternalBinding) function; ICPPInternalBinding internal = (ICPPInternalBinding) function;
if (parent instanceof IASTSimpleDeclaration) { if (parent instanceof IASTSimpleDeclaration) {
internal.addDeclaration(name); ASTInternal.addDeclaration(internal, name);
} else if (internal.getDefinition() == null) { } else if (internal.getDefinition() == null) {
internal.addDefinition(name); ASTInternal.addDefinition(internal, name);
} else { } else {
IASTNode def = internal.getDefinition(); IASTNode def = internal.getDefinition();
if (def instanceof IASTDeclarator) if (def instanceof IASTDeclarator)
@ -690,8 +685,7 @@ public class CPPVisitor extends ASTQueries {
} }
if (t1 != null && t2 != null) { if (t1 != null && t2 != null) {
if (t1.isSameType(t2)) { if (t1.isSameType(t2)) {
if (binding instanceof ICPPInternalBinding) ASTInternal.addDeclaration(binding, name);
((ICPPInternalBinding) binding).addDeclaration(name);
} else { } else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION); binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -103,4 +103,8 @@ public class ASTLiteralNode implements IASTNode {
public IASTNode copy() { public IASTNode copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean isActive() {
return true;
}
} }

View file

@ -224,7 +224,6 @@ class ASTPragma extends ASTDirectiveWithCondition implements IASTPreprocessorPra
class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreprocessorIncludeStatement { class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreprocessorIncludeStatement {
private final ASTPreprocessorName fName; private final ASTPreprocessorName fName;
private final String fPath; private final String fPath;
private final boolean fIsActive;
private final boolean fIsResolved; private final boolean fIsResolved;
private final boolean fIsSystemInclude; private final boolean fIsSystemInclude;
private final boolean fFoundByHeuristics; private final boolean fFoundByHeuristics;
@ -235,10 +234,12 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME, nameStartNumber, nameEndNumber, headerName, null); fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME, nameStartNumber, nameEndNumber, headerName, null);
fPath= filePath == null ? "" : filePath; //$NON-NLS-1$ fPath= filePath == null ? "" : filePath; //$NON-NLS-1$
fIsActive= active;
fIsResolved= filePath != null; fIsResolved= filePath != null;
fIsSystemInclude= !userInclude; fIsSystemInclude= !userInclude;
fFoundByHeuristics= heuristic; fFoundByHeuristics= heuristic;
if (!active) {
setInactive();
}
} }
public IASTName getName() { public IASTName getName() {
@ -249,10 +250,6 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
return fPath; return fPath;
} }
public boolean isActive() {
return fIsActive;
}
public boolean isResolved() { public boolean isResolved() {
return fIsResolved; return fIsResolved;
} }
@ -361,6 +358,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
return getName().toString() + '=' + getExpansion(); return getName().toString() + '=' + getExpansion();
} }
@Override
final public boolean isActive() { final public boolean isActive() {
return fActive; return fActive;
} }
@ -433,20 +431,16 @@ class ASTFunctionStyleMacroDefinition extends ASTMacroDefinition implements IAST
class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefStatement { class ASTUndef extends ASTPreprocessorNode implements IASTPreprocessorUndefStatement {
private final ASTPreprocessorName fName; private final ASTPreprocessorName fName;
private final boolean fActive;
public ASTUndef(IASTTranslationUnit parent, char[] name, int startNumber, int nameNumber, int nameEndNumber, IBinding binding, boolean isActive) { public ASTUndef(IASTTranslationUnit parent, char[] name, int startNumber, int nameNumber, int nameEndNumber, IBinding binding, boolean isActive) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, nameEndNumber); super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, nameEndNumber);
fName= new ASTPreprocessorName(this, IASTPreprocessorStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding); fName= new ASTPreprocessorName(this, IASTPreprocessorStatement.MACRO_NAME, nameNumber, nameEndNumber, name, binding);
fActive= isActive; if (!isActive)
setInactive();
} }
public ASTPreprocessorName getMacroName() { public ASTPreprocessorName getMacroName() {
return fName; return fName;
} }
public boolean isActive() {
return fActive;
}
} }
class ASTInclusionNode implements IASTInclusionNode { class ASTInclusionNode implements IASTInclusionNode {

View file

@ -611,6 +611,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} }
} }
public int getCodeBranchNesting() {
return fCurrentContext.getCodeBranchNesting();
}
private void appendStringContent(StringBuffer buf, Token t1) { private void appendStringContent(StringBuffer buf, Token t1) {
final char[] image= t1.getCharImage(); final char[] image= t1.getCharImage();
final int length= image.length; final int length= image.length;
@ -1296,7 +1301,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} else { } else {
fLocationMap.encounterPoundIfdef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro); fLocationMap.encounterPoundIfdef(offset, nameOffset, nameEndOffset, endOffset, isActive, macro);
} }
return fCurrentContext.setBranchState(conditional, isActive, withinExpansion); return fCurrentContext.setBranchState(conditional, isActive, withinExpansion, offset);
} }
private CodeState executeIf(Lexer lexer, int startOffset, boolean isElif, boolean withinExpansion) throws OffsetLimitReachedException { private CodeState executeIf(Lexer lexer, int startOffset, boolean isElif, boolean withinExpansion) throws OffsetLimitReachedException {
@ -1339,7 +1344,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} else { } else {
fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, refs); fLocationMap.encounterPoundIf(startOffset, condOffset, condEndOffset, endOffset, isActive, refs);
} }
return fCurrentContext.setBranchState(cond, isActive, withinExpansion); 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)
@ -1353,7 +1358,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final boolean isActive= cond.canHaveActiveBranch(withinExpansion); final boolean isActive= cond.canHaveActiveBranch(withinExpansion);
fLocationMap.encounterPoundElse(startOffset, endOffset, isActive); fLocationMap.encounterPoundElse(startOffset, endOffset, isActive);
return fCurrentContext.setBranchState(cond, isActive, withinExpansion); return fCurrentContext.setBranchState(cond, isActive, withinExpansion, startOffset);
} }
private CodeState executeEndif(Lexer lexer, int startOffset, boolean withinExpansion) throws OffsetLimitReachedException { private CodeState executeEndif(Lexer lexer, int startOffset, boolean withinExpansion) throws OffsetLimitReachedException {
@ -1364,7 +1369,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} else { } else {
fLocationMap.encounterPoundEndIf(startOffset, endOffset); fLocationMap.encounterPoundEndIf(startOffset, endOffset);
} }
return fCurrentContext.getCodeState(); return fCurrentContext.setBranchEndState(cond, withinExpansion, startOffset);
} }
/** /**

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.parser.IInactiveCodeToken;
/**
* Special token to separate active from inactive code
*/
public class InactiveCodeToken extends Token implements IInactiveCodeToken {
private int fOldNesting;
private int fNewNesting;
InactiveCodeToken(int kind, int oldNesting, int newNesting, int offset) {
super(kind, null, offset, offset);
fOldNesting= oldNesting;
fNewNesting= newNesting;
}
public int getOldNesting() {
return fOldNesting;
}
public int getNewNesting() {
return fNewNesting;
}
}

View file

@ -116,8 +116,6 @@ final class ScannerContext {
// an #end just pops one construct and restores state // an #end just pops one construct and restores state
if (branchKind == BranchKind.eEnd) { if (branchKind == BranchKind.eEnd) {
result= fConditionals.remove(pos); result= fConditionals.remove(pos);
// implicit state change
changeState(result.fInitialState, withinExpansion);
return result; return result;
} }
@ -131,20 +129,20 @@ final class ScannerContext {
return result; return result;
} }
private void changeState(CodeState state, boolean withinExpansion) { private void changeState(CodeState state, BranchKind kind, boolean withinExpansion, int offset) {
if (!withinExpansion) { if (!withinExpansion) {
switch (state) { switch (state) {
case eActive: case eActive:
if (fCurrentState == CodeState.eParseInactive) if (fCurrentState == CodeState.eParseInactive)
stopInactive(); stopInactive(offset, kind);
break; break;
case eParseInactive: case eParseInactive:
switch (fCurrentState) { switch (fCurrentState) {
case eActive: case eActive:
startInactive(); startInactive(offset, kind);
break; break;
case eParseInactive: case eParseInactive:
separateInactive(); separateInactive(offset, kind);
break; break;
case eSkipInactive: case eSkipInactive:
assert false; // in macro expansions, only. assert false; // in macro expansions, only.
@ -159,26 +157,35 @@ final class ScannerContext {
fCurrentState= state; fCurrentState= state;
} }
private void startInactive() { private void startInactive(int offset, BranchKind kind) {
if (fTokens != null && fTokens.getType() == IToken.tINACTIVE_CODE_END) { final int nesting = getCodeBranchNesting();
fTokens= new Token(IToken.tINACTIVE_CODE_SEPARATOR, null, 0, 0); final int oldNesting = getOldNestingLevel(kind, nesting);
} else { fTokens= new InactiveCodeToken(IToken.tINACTIVE_CODE_START, oldNesting, nesting, offset);
fTokens= new Token(IToken.tINACTIVE_CODE_START, null, 0, 0);
}
} }
private void separateInactive() { private void separateInactive(int offset, BranchKind kind) {
if (fTokens == null) { final int nesting = getCodeBranchNesting();
fTokens= new Token(IToken.tINACTIVE_CODE_SEPARATOR, null, 0, 0); final int oldNesting = getOldNestingLevel(kind, nesting);
} fTokens= new InactiveCodeToken(IToken.tINACTIVE_CODE_SEPARATOR, oldNesting, nesting, offset);
} }
private void stopInactive() { private int getOldNestingLevel(BranchKind kind, int nesting) {
if (fTokens != null && fTokens.getType() == IToken.tINACTIVE_CODE_START) { switch(kind) {
fTokens= null; case eIf:
} else { return nesting-1;
fTokens= new Token(IToken.tINACTIVE_CODE_END, null, 0, 0); case eElif:
case eElse:
return nesting;
case eEnd:
return nesting+1;
} }
return nesting;
}
private void stopInactive(int offset, BranchKind kind) {
final int nesting = getCodeBranchNesting();
final int oldNesting = getOldNestingLevel(kind, nesting);
fTokens= new InactiveCodeToken(IToken.tINACTIVE_CODE_END, oldNesting, nesting, offset);
} }
public CodeState getCodeState() { public CodeState getCodeState() {
@ -188,7 +195,7 @@ final class ScannerContext {
/** /**
* The preprocessor has to inform the context about the state of if- and elif- branches * The preprocessor has to inform the context about the state of if- and elif- branches
*/ */
public CodeState setBranchState(Conditional cond, boolean isActive, boolean withinExpansion) { public CodeState setBranchState(Conditional cond, boolean isActive, boolean withinExpansion, int offset) {
CodeState newState; CodeState newState;
if (isActive) { if (isActive) {
cond.fTakeElse= false; cond.fTakeElse= false;
@ -198,7 +205,17 @@ final class ScannerContext {
} else { } else {
newState= fInactiveState; newState= fInactiveState;
} }
changeState(newState, withinExpansion); changeState(newState, cond.fLast, withinExpansion, offset);
return newState;
}
/**
* The preprocessor has to inform the context about the state of if- and elif- branches
*/
public CodeState setBranchEndState(Conditional cond, boolean withinExpansion, int offset) {
// implicit state change
CodeState newState = cond.fInitialState;
changeState(newState, BranchKind.eEnd, withinExpansion, offset);
return newState; return newState;
} }
@ -244,4 +261,13 @@ final class ScannerContext {
public void clearInactiveCodeMarkerToken() { public void clearInactiveCodeMarkerToken() {
fTokens= null; fTokens= null;
} }
/**
* Returns the current nesting within code branches
*/
public int getCodeBranchNesting() {
if (fConditionals == null)
return 0;
return fConditionals.size();
}
} }

View file

@ -316,8 +316,7 @@ abstract public class PDOMWriter {
} }
} }
} }
} else if ((stmt instanceof IASTPreprocessorUndefStatement && ((IASTPreprocessorUndefStatement) stmt).isActive()) } else if (stmt.isActive() && (stmt instanceof IASTPreprocessorUndefStatement || stmt instanceof IASTPreprocessorMacroDefinition)) {
|| (stmt instanceof IASTPreprocessorMacroDefinition && ((IASTPreprocessorMacroDefinition) stmt).isActive())) {
IASTFileLocation sourceLoc = stmt.getFileLocation(); IASTFileLocation sourceLoc = stmt.getFileLocation();
if (sourceLoc != null) { // skip built-ins and command line macros if (sourceLoc != null) { // skip built-ins and command line macros
IIndexFileLocation path2 = fResolver.resolveASTPath(sourceLoc.getFileName()); IIndexFileLocation path2 = fResolver.resolveASTPath(sourceLoc.getFileName());

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -214,6 +214,10 @@ public class PDOMASTAdapter {
return fDelegate.isFrozen(); return fDelegate.isFrozen();
} }
public boolean isActive() {
return fDelegate.isFrozen();
}
public IASTName copy() { public IASTName copy() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View file

@ -38,12 +38,14 @@ public class CompletionTest_MacroRef_NoPrefix extends CompletionProposalsBaseTe
"__TIME__", "__TIME__",
"__builtin_constant_p(exp)", "__builtin_constant_p(exp)",
"__builtin_va_arg(ap, type)", "__builtin_va_arg(ap, type)",
"__builtin_offsetof(T, m)",
"__builtin_types_compatible_p(x, y)", "__builtin_types_compatible_p(x, y)",
"__complex__", "__complex__",
"__cplusplus", "__cplusplus",
"__extension__", "__extension__",
"__imag__", "__imag__",
"__null", "__null",
"__offsetof__(x)",
"__real__", "__real__",
"__stdcall", "__stdcall",
"__thread", "__thread",

View file

@ -369,11 +369,13 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest {
"__TIME__", "__TIME__",
"__builtin_constant_p(exp)", "__builtin_constant_p(exp)",
"__builtin_va_arg(ap, type)", "__builtin_va_arg(ap, type)",
"__builtin_offsetof(T, m)",
"__builtin_types_compatible_p(x, y)", "__builtin_types_compatible_p(x, y)",
"__complex__", "__complex__",
"__extension__", "__extension__",
"__imag__", "__imag__",
"__null", "__null",
"__offsetof__(x)",
"__real__", "__real__",
"__stdcall", "__stdcall",
"__thread", "__thread",

View file

@ -1,5 +1,5 @@
############################################################################### ###############################################################################
# Copyright (c) 2000, 2008 IBM Corporation and others. # Copyright (c) 2000, 2009 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials # All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0 # are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at # which accompanies this distribution, and is available at
@ -38,6 +38,10 @@ MemberFilterActionGroup.hide_nonpublic.label=Hide Non-&Public Members
MemberFilterActionGroup.hide_nonpublic.tooltip=Hide Non-Public Members MemberFilterActionGroup.hide_nonpublic.tooltip=Hide Non-Public Members
MemberFilterActionGroup.hide_nonpublic.description=Toggles the visibility of non-public members MemberFilterActionGroup.hide_nonpublic.description=Toggles the visibility of non-public members
MemberFilterActionGroup.hide_inactive.label=Hide &Inactive Elements
MemberFilterActionGroup.hide_inactive.tooltip=Hide Inactive Elements
MemberFilterActionGroup.hide_inactive.description=Toggles the visibility of inactive elements
ActionUtil.notOnBuildPath.title=Operation Cannot be Performed ActionUtil.notOnBuildPath.title=Operation Cannot be Performed
ActionUtil.notOnBuildPath.message=The resource is not on the build path of a Java project. ActionUtil.notOnBuildPath.message=The resource is not on the build path of a Java project.

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2001, 2008 IBM Corporation and others. * Copyright (c) 2001, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,13 +11,15 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.viewsupport; package org.eclipse.cdt.internal.ui.viewsupport;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.IDeclaration; import org.eclipse.cdt.core.model.IDeclaration;
import org.eclipse.cdt.core.model.IField; import org.eclipse.cdt.core.model.IField;
import org.eclipse.cdt.core.model.IMember; import org.eclipse.cdt.core.model.IMember;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
/** /**
@ -30,6 +32,8 @@ public class MemberFilter extends ViewerFilter{
public static final int FILTER_NONPUBLIC= 1; public static final int FILTER_NONPUBLIC= 1;
public static final int FILTER_STATIC= 2; public static final int FILTER_STATIC= 2;
public static final int FILTER_FIELDS= 4; public static final int FILTER_FIELDS= 4;
public static final int FILTER_INACTIVE= 0x10;
/** @deprecated Unsupported filter constant */ /** @deprecated Unsupported filter constant */
@Deprecated @Deprecated
public static final int FILTER_LOCALTYPES= 8; public static final int FILTER_LOCALTYPES= 8;
@ -86,6 +90,11 @@ public class MemberFilter extends ViewerFilter{
// ignore // ignore
} }
} }
if (hasFilter(FILTER_INACTIVE)) {
if (element instanceof ISourceReference && !((ISourceReference) element).isActive()) {
return false;
}
}
return true; return true;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2001, 2008 IBM Corporation and others. * Copyright (c) 2001, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -12,6 +12,7 @@ package org.eclipse.cdt.internal.ui.viewsupport;
import org.eclipse.jface.action.Action; import org.eclipse.jface.action.Action;
import org.eclipse.ui.PlatformUI; import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.ui.actions.MemberFilterActionGroup; import org.eclipse.cdt.ui.actions.MemberFilterActionGroup;
/** /**
@ -28,8 +29,9 @@ public class MemberFilterAction extends Action {
fFilterActionGroup= actionGroup; fFilterActionGroup= actionGroup;
fFilterProperty= property; fFilterProperty= property;
if (contextHelpId != null) {
PlatformUI.getWorkbench().getHelpSystem().setHelp(this, contextHelpId); PlatformUI.getWorkbench().getHelpSystem().setHelp(this, contextHelpId);
}
setChecked(initValue); setChecked(initValue);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2001, 2008 IBM Corporation and others. * Copyright (c) 2001, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -29,37 +29,48 @@ package org.eclipse.cdt.ui.actions;
*/ */
import java.util.ArrayList; import java.util.ArrayList;
import org.eclipse.cdt.internal.ui.viewsupport.MemberFilter; import org.eclipse.core.runtime.Assert;
import org.eclipse.cdt.internal.ui.viewsupport.MemberFilterAction;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.ui.actions.ActionMessages;
import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.StructuredViewer; import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.ui.IActionBars; import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento; import org.eclipse.ui.IMemento;
import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.actions.ActionGroup;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.PreferenceConstants;
import org.eclipse.cdt.internal.ui.CPluginImages; import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
import org.eclipse.cdt.internal.ui.actions.ActionMessages;
import org.eclipse.cdt.internal.ui.viewsupport.MemberFilter;
import org.eclipse.cdt.internal.ui.viewsupport.MemberFilterAction;
public class MemberFilterActionGroup extends ActionGroup { public class MemberFilterActionGroup extends ActionGroup {
public static final int FILTER_NONPUBLIC= MemberFilter.FILTER_NONPUBLIC; public static final int FILTER_NONPUBLIC= MemberFilter.FILTER_NONPUBLIC;
public static final int FILTER_STATIC= MemberFilter.FILTER_STATIC; public static final int FILTER_STATIC= MemberFilter.FILTER_STATIC;
public static final int FILTER_FIELDS= MemberFilter.FILTER_FIELDS; public static final int FILTER_FIELDS= MemberFilter.FILTER_FIELDS;
/**
* @since 5.1
*/
public static final int FILTER_INACTIVE= MemberFilter.FILTER_INACTIVE;
/** @deprecated Unsupported filter constant */ /** @deprecated Unsupported filter constant */
@Deprecated @Deprecated
public static final int FILTER_LOCALTYPES= MemberFilter.FILTER_LOCALTYPES; public static final int FILTER_LOCALTYPES= MemberFilter.FILTER_LOCALTYPES;
/**
* @deprecated we may choose to add more filters in future versions.
*/
@Deprecated
public static final int ALL_FILTERS= FILTER_NONPUBLIC | FILTER_FIELDS | FILTER_STATIC; public static final int ALL_FILTERS= FILTER_NONPUBLIC | FILTER_FIELDS | FILTER_STATIC;
private static final String TAG_HIDEFIELDS= "hidefields"; //$NON-NLS-1$ private static final String TAG_HIDEFIELDS= "hidefields"; //$NON-NLS-1$
private static final String TAG_HIDESTATIC= "hidestatic"; //$NON-NLS-1$ private static final String TAG_HIDESTATIC= "hidestatic"; //$NON-NLS-1$
private static final String TAG_HIDENONPUBLIC= "hidenonpublic"; //$NON-NLS-1$ private static final String TAG_HIDENONPUBLIC= "hidenonpublic"; //$NON-NLS-1$
private static final String TAG_HIDEINACTIVE= "hideinactive"; //$NON-NLS-1$
private MemberFilterAction[] fFilterActions; private MemberFilterAction[] fFilterActions;
private MemberFilter fFilter; private MemberFilter fFilter;
@ -101,6 +112,7 @@ public class MemberFilterActionGroup extends ActionGroup {
boolean doHideFields= store.getBoolean(getPreferenceKey(FILTER_FIELDS)); boolean doHideFields= store.getBoolean(getPreferenceKey(FILTER_FIELDS));
boolean doHideStatic= store.getBoolean(getPreferenceKey(FILTER_STATIC)); boolean doHideStatic= store.getBoolean(getPreferenceKey(FILTER_STATIC));
boolean doHidePublic= store.getBoolean(getPreferenceKey(FILTER_NONPUBLIC)); boolean doHidePublic= store.getBoolean(getPreferenceKey(FILTER_NONPUBLIC));
boolean doHideInactive= store.getBoolean(getPreferenceKey(FILTER_INACTIVE));
fFilter= new MemberFilter(); fFilter= new MemberFilter();
if (doHideFields) if (doHideFields)
@ -109,6 +121,8 @@ public class MemberFilterActionGroup extends ActionGroup {
fFilter.addFilter(FILTER_STATIC); fFilter.addFilter(FILTER_STATIC);
if (doHidePublic) if (doHidePublic)
fFilter.addFilter(FILTER_NONPUBLIC); fFilter.addFilter(FILTER_NONPUBLIC);
if (doHideInactive)
fFilter.addFilter(FILTER_INACTIVE);
// fields // fields
String title= ActionMessages.getString("MemberFilterActionGroup.hide_fields.label"); //$NON-NLS-1$ String title= ActionMessages.getString("MemberFilterActionGroup.hide_fields.label"); //$NON-NLS-1$
@ -134,8 +148,15 @@ public class MemberFilterActionGroup extends ActionGroup {
hideNonPublic.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_nonpublic.tooltip")); //$NON-NLS-1$ hideNonPublic.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_nonpublic.tooltip")); //$NON-NLS-1$
CPluginImages.setImageDescriptors(hideNonPublic, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_SHOW_PUBLIC); CPluginImages.setImageDescriptors(hideNonPublic, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_SHOW_PUBLIC);
// inactive
title= ActionMessages.getString("MemberFilterActionGroup.hide_inactive.label"); //$NON-NLS-1$
MemberFilterAction hideInactive= new MemberFilterAction(this, title, FILTER_INACTIVE, null, doHideInactive);
hideInactive.setDescription(ActionMessages.getString("MemberFilterActionGroup.hide_inactive.description")); //$NON-NLS-1$
hideInactive.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_inactive.tooltip")); //$NON-NLS-1$
CPluginImages.setImageDescriptors(hideInactive, CPluginImages.T_LCL, CPluginImages.IMG_ACTION_HIDE_INACTIVE);
// order corresponds to order in toolbar // order corresponds to order in toolbar
fFilterActions= new MemberFilterAction[] { hideFields, hideStatic, hideNonPublic }; fFilterActions= new MemberFilterAction[] { hideFields, hideStatic, hideNonPublic, hideInactive };
fViewer.addFilter(fFilter); fViewer.addFilter(fFilter);
} }
@ -148,9 +169,9 @@ public class MemberFilterActionGroup extends ActionGroup {
* the last used filter settings in the preference store * the last used filter settings in the preference store
* @param inViewMenu if <code>true</code> the actions are added to the view * @param inViewMenu if <code>true</code> the actions are added to the view
* menu. If <code>false</code> they are added to the toobar. * menu. If <code>false</code> they are added to the toobar.
* @param availableFilters Specifies which filter action should be contained. <code>FILTER_NONPUBLIC</code>, * @param availableFilters Specifies which filter action should be contained. {@link #FILTER_NONPUBLIC},
* <code>FILTER_STATIC</code> and <code>FILTER_FIELDS</code> * {@link #FILTER_STATIC}, {@link #FILTER_FIELDS}, {@link #FILTER_INACTIVE}
* or a combination of these constants are possible values. Use <code>ALL_FILTERS</code> to select all available filters. * or a combination of these constants are possible values.
*/ */
public MemberFilterActionGroup(StructuredViewer viewer, String viewerId, boolean inViewMenu, int availableFilters) { public MemberFilterActionGroup(StructuredViewer viewer, String viewerId, boolean inViewMenu, int availableFilters) {
@ -212,6 +233,21 @@ public class MemberFilterActionGroup extends ActionGroup {
actions.add(hideNonPublic); actions.add(hideNonPublic);
} }
// non-public
filterProperty= FILTER_INACTIVE;
if (isSet(filterProperty, availableFilters)) {
boolean filterEnabled= store.getBoolean(getPreferenceKey(filterProperty));
if (filterEnabled) {
fFilter.addFilter(filterProperty);
}
title= ActionMessages.getString("MemberFilterActionGroup.hide_inactive.label"); //$NON-NLS-1$
MemberFilterAction hideInactive= new MemberFilterAction(this, title, filterProperty, null, filterEnabled);
hideInactive.setDescription(ActionMessages.getString("MemberFilterActionGroup.hide_inactive.description")); //$NON-NLS-1$
hideInactive.setToolTipText(ActionMessages.getString("MemberFilterActionGroup.hide_inactive.tooltip")); //$NON-NLS-1$
CPluginImages.setImageDescriptors(hideInactive, CPluginImages.T_LCL, "filterInactive.gif"); //$NON-NLS-1$
actions.add(hideInactive);
}
// order corresponds to order in toolbar // order corresponds to order in toolbar
fFilterActions= actions.toArray(new MemberFilterAction[actions.size()]); fFilterActions= actions.toArray(new MemberFilterAction[actions.size()]);
@ -230,7 +266,7 @@ public class MemberFilterActionGroup extends ActionGroup {
* Sets the member filters. * Sets the member filters.
* *
* @param filterProperty the filter to be manipulated. Valid values are <code>FILTER_FIELDS</code>, * @param filterProperty the filter to be manipulated. Valid values are <code>FILTER_FIELDS</code>,
* <code>FILTER_PUBLIC</code>, and <code>FILTER_PRIVATE</code> as defined by this action * <code>FILTER_PUBLIC</code>, <code>FILTER_PRIVATE</code> and <code>FILTER_INACTIVE</code> as defined by this action
* group * group
* @param set if <code>true</code> the given filter is installed. If <code>false</code> the * @param set if <code>true</code> the given filter is installed. If <code>false</code> the
* given filter is removed * given filter is removed
@ -278,8 +314,8 @@ public class MemberFilterActionGroup extends ActionGroup {
* Returns <code>true</code> if the given filter is installed. * Returns <code>true</code> if the given filter is installed.
* *
* @param filterProperty the filter to be tested. Valid values are <code>FILTER_FIELDS</code>, * @param filterProperty the filter to be tested. Valid values are <code>FILTER_FIELDS</code>,
* <code>FILTER_PUBLIC</code>, and <code>FILTER_PRIVATE</code> as defined by this action * <code>FILTER_PUBLIC</code>, <code>FILTER_PRIVATE</code> and <code>FILTER_INACTIVE</code>
* group * as defined by this action group
*/ */
public boolean hasMemberFilter(int filterProperty) { public boolean hasMemberFilter(int filterProperty) {
return fFilter.hasFilter(filterProperty); return fFilter.hasFilter(filterProperty);
@ -294,6 +330,7 @@ public class MemberFilterActionGroup extends ActionGroup {
memento.putString(TAG_HIDEFIELDS, String.valueOf(hasMemberFilter(FILTER_FIELDS))); memento.putString(TAG_HIDEFIELDS, String.valueOf(hasMemberFilter(FILTER_FIELDS)));
memento.putString(TAG_HIDESTATIC, String.valueOf(hasMemberFilter(FILTER_STATIC))); memento.putString(TAG_HIDESTATIC, String.valueOf(hasMemberFilter(FILTER_STATIC)));
memento.putString(TAG_HIDENONPUBLIC, String.valueOf(hasMemberFilter(FILTER_NONPUBLIC))); memento.putString(TAG_HIDENONPUBLIC, String.valueOf(hasMemberFilter(FILTER_NONPUBLIC)));
memento.putString(TAG_HIDEINACTIVE, String.valueOf(hasMemberFilter(FILTER_INACTIVE)));
} }
/** /**
@ -305,11 +342,12 @@ public class MemberFilterActionGroup extends ActionGroup {
*/ */
public void restoreState(IMemento memento) { public void restoreState(IMemento memento) {
setMemberFilters( setMemberFilters(
new int[] {FILTER_FIELDS, FILTER_STATIC, FILTER_NONPUBLIC}, new int[] {FILTER_FIELDS, FILTER_STATIC, FILTER_NONPUBLIC, FILTER_INACTIVE},
new boolean[] { new boolean[] {
Boolean.valueOf(memento.getString(TAG_HIDEFIELDS)).booleanValue(), Boolean.valueOf(memento.getString(TAG_HIDEFIELDS)).booleanValue(),
Boolean.valueOf(memento.getString(TAG_HIDESTATIC)).booleanValue(), Boolean.valueOf(memento.getString(TAG_HIDESTATIC)).booleanValue(),
Boolean.valueOf(memento.getString(TAG_HIDENONPUBLIC)).booleanValue() Boolean.valueOf(memento.getString(TAG_HIDENONPUBLIC)).booleanValue(),
Boolean.valueOf(memento.getString(TAG_HIDEINACTIVE)).booleanValue()
}, false); }, false);
} }
@ -332,6 +370,7 @@ public class MemberFilterActionGroup extends ActionGroup {
tbm.add(fFilterActions[0]); // fields tbm.add(fFilterActions[0]); // fields
tbm.add(fFilterActions[1]); // static tbm.add(fFilterActions[1]); // static
tbm.add(fFilterActions[2]); // public tbm.add(fFilterActions[2]); // public
tbm.add(fFilterActions[3]); // inactive
} }
/** /**
@ -348,10 +387,12 @@ public class MemberFilterActionGroup extends ActionGroup {
menu.prependToGroup(filters, fFilterActions[0]); // fields menu.prependToGroup(filters, fFilterActions[0]); // fields
menu.prependToGroup(filters, fFilterActions[1]); // static menu.prependToGroup(filters, fFilterActions[1]); // static
menu.prependToGroup(filters, fFilterActions[2]); // public menu.prependToGroup(filters, fFilterActions[2]); // public
menu.prependToGroup(filters, fFilterActions[3]); // inactive
} else { } else {
menu.add(fFilterActions[0]); // fields menu.add(fFilterActions[0]); // fields
menu.add(fFilterActions[1]); // static menu.add(fFilterActions[1]); // static
menu.add(fFilterActions[2]); // public menu.add(fFilterActions[2]); // public
menu.add(fFilterActions[3]); // inactive
} }
} }