diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedDeclaratorsTest.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedDeclaratorsTest.java index 9a7d6e90a15..a9be78633a1 100644 --- a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedDeclaratorsTest.java +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedDeclaratorsTest.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.cdt.core.model.failedTests; +import junit.framework.Test; +import junit.framework.TestSuite; + import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IFunction; @@ -18,6 +21,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITypeDef; import org.eclipse.cdt.core.model.IVariable; import org.eclipse.cdt.core.model.tests.IntegratedCModelTest; +import org.eclipse.cdt.core.tests.FailingTest; @@ -28,8 +32,11 @@ import org.eclipse.cdt.core.model.tests.IntegratedCModelTest; public class FailedDeclaratorsTest extends IntegratedCModelTest { // the defect to track these failures is Bug 40768 - // Problems with nested declarators - static final boolean failedTest = true; + + private FailedDeclaratorsTest(String name) { + super(name); + } + /** * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest */ @@ -43,22 +50,50 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest public String getSourcefileResource() { return "DeclaratorsTests.cpp"; } - + + /** + * @returns a test suite named after this class + * containing all its public members named "test*" + */ + public static Test suite() { + TestSuite suite= new TestSuite("FailedDeclaratorsTest"); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0002"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0003"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0006"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0007"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0011"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0013"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0014"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0016"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0017"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0023"), 40768)); + suite.addTest(new FailingTest(new FailedDeclaratorsTest("testDeclarators_0024"), 40768)); + return suite; + } + + public void testDeclarators_0002() throws CModelException { + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0002"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_FUNCTION_DECLARATION); + IFunctionDeclaration decl = (IFunctionDeclaration)element; + assertEquals(decl.getSignature(), "decl_0002(char)"); + assertEquals(decl.getReturnType(), "void"); + } + public void testDeclarators_0003() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0003"); - if( failedTest ) return; // here is the where the failure is - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_FUNCTION_DECLARATION); - IFunctionDeclaration decl = (IFunctionDeclaration)element; - assertEquals(decl.getSignature(), "decl_0003(char)"); - assertEquals(decl.getReturnType(), "void"); + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0003"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_FUNCTION_DECLARATION); + IFunctionDeclaration decl = (IFunctionDeclaration)element; + assertEquals(decl.getSignature(), "decl_0003(char)"); + assertEquals(decl.getReturnType(), "void"); } public void testDeclarators_0006() throws CModelException { ITranslationUnit tu = getTU(); ICElement element = tu.getElement("decl_0006"); - if( failedTest ) return; // here is the where the failure is assertNotNull(element); assertEquals(element.getElementType(), ICElement.C_VARIABLE); IVariable decl = (IVariable)element; @@ -66,14 +101,13 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest } public void testDeclarators_0007() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0007"); - if( failedTest ) return; // here is the where the failure is - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_VARIABLE); - IVariable decl = (IVariable)element; - assertEquals(decl.getTypeName(), "void(*)(char)"); - } + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0007"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_VARIABLE); + IVariable decl = (IVariable)element; + assertEquals(decl.getTypeName(), "void(*)(char)"); + } public void testDeclarators_0011() throws CModelException { ITranslationUnit tu = getTU(); @@ -81,7 +115,6 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest assertNotNull(element); assertEquals(element.getElementType(), ICElement.C_TYPEDEF); ITypeDef decl = (ITypeDef)element; - if( failedTest ) return; // here is the where the failure is assertEquals(decl.getTypeName(), "void()(char)"); } @@ -89,7 +122,6 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest ITranslationUnit tu = getTU(); ICElement element = tu.getElement("decl_0012"); assertNotNull(element); - if( failedTest ) return; // here is the where the failure is assertEquals(element.getElementType(), ICElement.C_TYPEDEF); ITypeDef decl = (ITypeDef)element; assertEquals(decl.getTypeName(), "void()(char)"); @@ -98,7 +130,6 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest public void testDeclarators_0013() throws CModelException { ITranslationUnit tu = getTU(); ICElement element = tu.getElement("decl_0013"); - if( failedTest ) return; // here is the where the failure is assertNotNull(element); assertEquals(element.getElementType(), ICElement.C_TYPEDEF); ITypeDef decl = (ITypeDef)element; @@ -111,14 +142,12 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest assertNotNull(element); assertEquals(element.getElementType(), ICElement.C_TYPEDEF); ITypeDef decl = (ITypeDef)element; - if( failedTest ) return; // here is the where the failure is assertEquals(decl.getTypeName(), "void*()(char)"); } public void testDeclarators_0016() throws CModelException { ITranslationUnit tu = getTU(); ICElement element = tu.getElement("decl_0016"); - if( failedTest ) return; // here is the where the failure is assertNotNull(element); assertEquals(element.getElementType(), ICElement.C_TYPEDEF); ITypeDef decl = (ITypeDef)element; @@ -128,7 +157,6 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest public void testDeclarators_0017() throws CModelException { ITranslationUnit tu = getTU(); ICElement element = tu.getElement("decl_0017"); - if( failedTest ) return; // here is the where the failure is assertNotNull(element); assertEquals(element.getElementType(), ICElement.C_TYPEDEF); ITypeDef decl = (ITypeDef)element; @@ -136,33 +164,22 @@ public class FailedDeclaratorsTest extends IntegratedCModelTest } public void testDeclarators_0023() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0023"); - if( failedTest ) return; // here is the where the failure is - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_FUNCTION); - IFunction decl = (IFunction)element; - assertEquals(decl.getSignature(), "decl_0023(int)"); - assertEquals(decl.getReturnType(), "void(*(*))(char)"); - } + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0023"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_FUNCTION); + IFunction decl = (IFunction)element; + assertEquals(decl.getSignature(), "decl_0023(int)"); + assertEquals(decl.getReturnType(), "void(*(*))(char)"); + } - public void testDeclarators_0024() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0024"); - if( failedTest ) return; // here is the where the failure is - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_VARIABLE); - IVariable decl = (IVariable)element; - assertEquals(decl.getTypeName(), "void(*(*(*)(int))(float))(char)"); - } + public void testDeclarators_0024() throws CModelException { + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0024"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_VARIABLE); + IVariable decl = (IVariable)element; + assertEquals(decl.getTypeName(), "void(*(*(*)(int))(float))(char)"); + } - public void testDeclarators_0031() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0031"); - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_VARIABLE); - IVariable decl = (IVariable)element; - if( failedTest ) return; // here is the where the failure is - assertEquals(decl.getTypeName(), "int(*)(char(*)(bool))"); - } } diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedMacroTests.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedMacroTests.java index 8da37ff81d6..64b14ea2e26 100644 --- a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedMacroTests.java +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/FailedMacroTests.java @@ -53,7 +53,7 @@ public class FailedMacroTests extends IntegratedCModelTest * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest */ public String getSourcefileResource() { - return "MacroTests.c"; + return "MacroTests.cpp"; } private final static boolean failedTest = true; diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java index aad3cf4c76f..3b152487fc2 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java @@ -13,6 +13,8 @@ package org.eclipse.cdt.core.model.tests; import junit.framework.Test; import junit.framework.TestSuite; +import org.eclipse.cdt.core.model.failedTests.FailedDeclaratorsTest; + /** * @@ -41,6 +43,7 @@ public class AllCoreTests { suite.addTest(ArchiveTests.suite()); suite.addTest(TranslationUnitTests.suite()); suite.addTest(DeclaratorsTests.suite()); + suite.addTest(FailedDeclaratorsTest.suite()); suite.addTest(CPathEntryTest.suite()); return suite; diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java index 9cf65b3ad58..addb4d18cff 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java @@ -329,7 +329,7 @@ public class CModelElementsTests extends TestCase { IVariable vDecl2 = (IVariable) nsVars.get(3); assertEquals(vDecl2.getElementName(), new String("orig_malloc_hook")); checkElementOffset(vDecl2); - assertEquals(vDecl2.getTypeName(), new String ("void*(*)(const char*, int, size_t)")); + assertEquals(vDecl2.getTypeName(), new String ("void*(*)(const char*, int, int)")); checkLineNumbers(vDecl2, 81, 81); } @@ -416,7 +416,7 @@ public class CModelElementsTests extends TestCase { ITypeDef td2 = (ITypeDef) nsTypeDefs.get(1); assertEquals(td2.getElementName(), new String ("myTypedef")); checkElementOffset(td2); - assertEquals(td2.getTypeName(), new String ("")); + assertEquals(td2.getTypeName(), new String ("struct")); checkLineNumbers(td2, 101, 103); // union diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/DeclaratorsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/DeclaratorsTests.java index abc0b8e7229..89d34546bee 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/DeclaratorsTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/DeclaratorsTests.java @@ -71,18 +71,6 @@ public class DeclaratorsTests extends IntegratedCModelTest { assertEquals(decl.getReturnType(), "void"); } - public void testDeclarators_0002() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0002"); - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_FUNCTION_DECLARATION); - IFunctionDeclaration decl = (IFunctionDeclaration)element; - assertEquals(decl.getSignature(), "decl_0002(char)"); - assertEquals(decl.getReturnType(), "void"); - } - - - public void testDeclarators_0004() throws CModelException { ITranslationUnit tu = getTU(); ICElement element = tu.getElement("decl_0004"); @@ -103,11 +91,21 @@ public class DeclaratorsTests extends IntegratedCModelTest { } public void testDeclarators_0015() throws CModelException { - ITranslationUnit tu = getTU(); - ICElement element = tu.getElement("decl_0015"); - assertNotNull(element); - assertEquals(element.getElementType(), ICElement.C_TYPEDEF); - ITypeDef decl = (ITypeDef)element; - assertEquals(decl.getTypeName(), "void(*)(char)"); + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0015"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_TYPEDEF); + ITypeDef decl = (ITypeDef)element; + assertEquals(decl.getTypeName(), "void(*)(char)"); } + + public void testDeclarators_0031() throws CModelException { + ITranslationUnit tu = getTU(); + ICElement element = tu.getElement("decl_0031"); + assertNotNull(element); + assertEquals(element.getElementType(), ICElement.C_VARIABLE); + IVariable decl = (IVariable)element; + assertEquals(decl.getTypeName(), "int(*)(char(*)(bool))"); + } + } diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java index 244c8596fef..4b32db98682 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java @@ -44,7 +44,7 @@ public class IStructureTests extends IntegratedCModelTest { * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest */ public String getSourcefileResource() { - return "IStructure.c"; + return "IStructure.cpp"; } /** diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ITemplateTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ITemplateTests.java index 597b40abf58..a50829dd1fb 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ITemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ITemplateTests.java @@ -14,12 +14,19 @@ */ package org.eclipse.cdt.core.model.tests; -import org.eclipse.cdt.core.model.*; - -import junit.framework.*; import java.util.ArrayList; import java.util.List; +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITemplate; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.IVariable; + /** @@ -143,9 +150,30 @@ public class ITemplateTests extends IntegratedCModelTest { { // Check the template function List arrayElements = tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION); + // actually, none of the two are function templates, but method templates + String[] myExpectedValues = { +// "nonVector::first", + "Foo::fum", + }; + assertEquals(myExpectedValues.length, arrayElements.size()); + // This test is no correct there is no guaranty on the order + // for this particular case + for(int i=0; i::first", - "Foo::fum", +// "Foo::fum", }; assertEquals(myExpectedValues.length, arrayElements.size()); // This test is no correct there is no guaranty on the order @@ -198,21 +226,20 @@ public class ITemplateTests extends IntegratedCModelTest { // assertEquals("Failed on "+i, myExpectedValues[i], celement.getElementName()); // } } -/* - // TEMPLATE_VARIABLE moved to failed tests + { - ArrayList arrayElements = tu.getChildrenOfType(ICElement.C_TEMPLATE_VARIABLE); + List arrayElements = tu.getChildrenOfType(ICElement.C_TEMPLATE_VARIABLE); String[] myExpectedValues = { "default_alloc_template::S_start_free" }; assertEquals(myExpectedValues.length, arrayElements.size()); for(int i=0; i", @@ -305,11 +331,11 @@ public class ITemplateTests extends IntegratedCModelTest { "ArrayOverlay", "fum(int) : void", "scrum(void) : void", // TODO: deduce the rules of () versus (void), compare below. - "nonVector::first() : const T&", // TODO: where should be? + "nonVector::first() const : const T&", // TODO: where should be? "Foo::fum(int) : void", // TODO: shouldn't signature indicate const function as well? "IsGreaterThan(X, X) : bool", - /*"default_alloc_template::S_start_free : char*",*/ + "default_alloc_template::S_start_free : char*", }; assertEquals(myExpectedValues.length, arrayElements.size()); for(int i=0; i::first", "Foo::fum", "IsGreaterThan", }; @@ -153,8 +153,8 @@ public class StructuralTemplateTests extends ITemplateTests { arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_CLASS ) ); arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_UNION ) ); arrayElements.addAll( getTemplateMethods(tu) ); - arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION ) ); arrayElements.addAll(tu.getChildrenOfType(ICElement.C_TEMPLATE_METHOD)); + arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION ) ); arrayElements.addAll(tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION_DECLARATION)); // TEMPLATE_VARIABLE moved to failed tests //arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_VARIABLE ) ); @@ -203,8 +203,8 @@ public class StructuralTemplateTests extends ITemplateTests { arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_CLASS ) ); arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_UNION ) ); arrayElements.addAll( getTemplateMethods(tu) ); - arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION ) ); arrayElements.addAll(tu.getChildrenOfType(ICElement.C_TEMPLATE_METHOD)); + arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION ) ); arrayElements.addAll(tu.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION_DECLARATION)); // TEMPLATE_VARIABLE moved to failed tests //arrayElements.addAll( tu.getChildrenOfType(ICElement.C_TEMPLATE_VARIABLE ) ); @@ -215,8 +215,7 @@ public class StructuralTemplateTests extends ITemplateTests { "ArrayOverlay", "fum(int) : void", "scrum(void) : void", // TODO: deduce the rules of () versus (void), compare below. - // TODO: shouldn't signature indicate const function as well? - "nonVector::first() : const T&", // TODO: where should be? + "nonVector::first() const : const T&", // TODO: where should be? "Foo::fum(int) : void", "IsGreaterThan(X, X) : bool", /*"default_alloc_template::S_start_free : char*",*/ diff --git a/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.c b/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.cpp similarity index 94% rename from core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.c rename to core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.cpp index c46b043df41..6b7e80e597c 100644 --- a/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.c +++ b/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.cpp @@ -1,88 +1,90 @@ -// IStructure -struct testStruct1 { - char m_field1; - char* m_field2; - unsigned char m_field3; - int m_field4; - unsigned m_field5; - void* m_field6; - - void method1(); - struct testStruct1 method2( char* in_field2, int in_field4 ) {} - // this is very C++: - testStruct1( char* in_field2, int in_field4 ) {} - ~testStruct1() {} -}; - -struct testStruct2 { -}; - -struct testStruct3 { -} aTestStruct3; - -// no semicolon, parser should recover -struct testStruct4NoSemicolon { -} - -// forward declaration -struct testStruct5; - -// variable declaration using predefined struct. -struct testStruct6 aTestStruct6; - -struct { - int x; -} testAnonymousStructObject1; - -struct { - int x; -} testAnonymousStructObject2= {1}; - -// to resync the parser if necessary -struct testStruct7 { -}; - -// an inner struct -struct testStruct8 { - struct testStruct9Inner { - int x; - }; - struct testStruct10Inner { - int y; - struct testStruct11Inner { - int z; - }; - }; -}; - -union testUnion1 { - char m_field1; - char* m_field2; - unsigned char m_field3; - int m_field4; - unsigned m_field5; - void* m_field6; -}; - -class testClass1 { -}; - -class testClass2NoSemicolon { -} - -class testClass3 { -}; - -class testClass4Abstract { - void aNonVirtual(); - virtual void aVirtual(); - virtual void aPureVirtual()=0; -}; - -class testClass5 -: public testClass1, protected testClass3, private testClass4Abstract { -}; - -// to resync the parser if necessary -class testClass6 { -}; +// IStructure +struct testStruct1 { + char m_field1; + char* m_field2; + unsigned char m_field3; + int m_field4; + unsigned m_field5; + void* m_field6; + + void method1(); + struct testStruct1 method2( char* in_field2, int in_field4 ) {} + // this is very C++: + testStruct1( char* in_field2, int in_field4 ) {} + ~testStruct1() {} +}; + +struct testStruct2 { +}; + +struct testStruct3 { +} aTestStruct3; + +// no semicolon, parser should recover +struct testStruct4NoSemicolon { +} + +// forward declaration +struct testStruct5; + +// variable declaration using predefined struct. +struct testStruct6 aTestStruct6; + +struct { + int x; +} testAnonymousStructObject1; + +struct { + int x; +} testAnonymousStructObject2= {1}; + +// to resync the parser if necessary +struct testStruct7 { +}; + +// an inner struct +struct testStruct8 { + struct testStruct9Inner { + int x; + }; + struct testStruct10Inner { + int y; + struct testStruct11Inner { + int z; + }; + }; +}; + +union testUnion1 { + char m_field1; + char* m_field2; + unsigned char m_field3; + int m_field4; + unsigned m_field5; + void* m_field6; +}; + +class testClass1 { +}; + +class testClass2NoSemicolon { +} + +class catchTheSyntaxError; + +class testClass3 { +}; + +class testClass4Abstract { + void aNonVirtual(); + virtual void aVirtual(); + virtual void aPureVirtual()=0; +}; + +class testClass5 +: public testClass1, protected testClass3, private testClass4Abstract { +}; + +// to resync the parser if necessary +class testClass6 { +}; diff --git a/core/org.eclipse.cdt.core.tests/resources/cmodel/MacroTests.c b/core/org.eclipse.cdt.core.tests/resources/cmodel/MacroTests.cpp similarity index 90% rename from core/org.eclipse.cdt.core.tests/resources/cmodel/MacroTests.c rename to core/org.eclipse.cdt.core.tests/resources/cmodel/MacroTests.cpp index 07e30d6eeec..0170affd793 100644 --- a/core/org.eclipse.cdt.core.tests/resources/cmodel/MacroTests.c +++ b/core/org.eclipse.cdt.core.tests/resources/cmodel/MacroTests.cpp @@ -1,24 +1,24 @@ -#define Z struct -#define X Z -#define Y SomeName - -X Y -{ - -}; - - -X{ -}; - -int A :: BCD = 1; - -#define DEFA B -#define DB( x ) x - -int DEFA :: DB(Y) = 1; - -#define PINT const int * - -PINT myPINT; -PINT foobar( void ); +#define Z struct +#define X Z +#define Y SomeName + +X Y +{ + +}; + + +X{ +}; + +int A :: BCD = 1; + +#define DEFA B +#define DB( x ) x + +int DEFA :: DB(Y) = 1; + +#define PINT const int * + +PINT myPINT; +PINT foobar( void ); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java new file mode 100644 index 00000000000..96e6a2183d0 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ASTStringUtil.java @@ -0,0 +1,697 @@ +/******************************************************************************* + * Copyright (c) 2006 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.model; + +import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil; +import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; +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.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTInitializer; +import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.IASTInitializerList; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTPointer; +import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.c.ICASTDesignatedInitializer; +import org.eclipse.cdt.core.dom.ast.c.ICASTPointer; +import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression; +import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer; +import org.eclipse.cdt.core.parser.Keywords; + + +/** + * This is a utility class to help convert AST elements to Strings. + * + * @see org.eclipse.cdt.core.dom.ast.ASTSignatureUtil + * @see org.eclipse.cdt.core.dom.ast.ASTTypeUtil + */ + +public class ASTStringUtil { + + private static final String COMMA_SPACE= ", "; //$NON-NLS-1$ + private static final String[] EMPTY_STRING_ARRAY= new String[0]; + + /** + * Return the qualified name if the given IASTName + * is an ICPPASTQualifiedName, otherwise a simple name is returned. + * + * @param name + * @return a (possibly) qualified name + */ + public static String getQualifiedName(IASTName name) { + return appendQualifiedNameString(new StringBuffer(), name).toString(); + } + + /** + * Return the non-qualified name. + * + * @param name + * @return a non-qualified name + */ + public static String getSimpleName(IASTName name) { + return appendSimpleNameString(new StringBuffer(), name).toString(); + } + + /** + * Compute a signature string with parameters, without initializers. + * + * @param declarator + * @return the type string + * @see ASTSignatureUtil#getSignature(IASTDeclarator) + */ + public static String getSignatureString(IASTDeclarator declarator) { + return trimRight(appendSignatureString(new StringBuffer(), declarator)).toString(); + } + + /** + * Compute a signature string including parameters, but without initializers. + * + * @param declSpecifier + * @param declarator + * @return the signature string + */ + public static String getSignatureString(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) { + final StringBuffer buffer= new StringBuffer(); + appendDeclarationString(buffer, declSpecifier, declarator, true); + return trimRight(buffer).toString(); + } + + /** + * Compute a (return-)type string without parameters and initializers. + * + * @param declSpecifier + * @param declarator + * @return the type string + */ + public static String getTypeString(IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) { + final StringBuffer buffer= new StringBuffer(); + appendDeclarationString(buffer, declSpecifier, declarator, false); + return trimRight(buffer).toString(); + } + + /** + * Get the signatures of the function parameter declarations. + * + * @param functionDeclarator + * @return the parameter signature array + * + * @see ASTSignatureUtil#getParameterSignatureArray(IASTDeclarator) + */ + public static String[] getParameterSignatureArray(IASTFunctionDeclarator functionDeclarator) { + if (functionDeclarator instanceof IASTStandardFunctionDeclarator) { + final IASTStandardFunctionDeclarator standardFunctionDecl= (IASTStandardFunctionDeclarator)functionDeclarator; + final IASTParameterDeclaration[] parameters= standardFunctionDecl.getParameters(); + final boolean takesVarArgs= standardFunctionDecl.takesVarArgs(); + final String[] parameterStrings= new String[parameters.length + (takesVarArgs ? 1 : 0)]; + int i; + for (i=0; i < parameters.length; ++i) { + parameterStrings[i]= getParameterSignatureString(parameters[i]); + } + if (takesVarArgs) { + parameterStrings[i]= new String(Keywords.cpELLIPSIS); + } + return parameterStrings; + } else if (functionDeclarator instanceof ICASTKnRFunctionDeclarator) { + final ICASTKnRFunctionDeclarator knrDeclarator= (ICASTKnRFunctionDeclarator)functionDeclarator; + final IASTName[] names= knrDeclarator.getParameterNames(); + final String[] result= new String[names.length]; + for(int i=0; i 0) { + buffer.append(Keywords.THROW).append(' '); + for (int i= 0; i < exceptionTypeIds.length; i++) { + if (i > 0) { + buffer.append(COMMA_SPACE); + } + appendTypeIdString(buffer, exceptionTypeIds[i]); + } + } + if (declarator instanceof ICPPASTFunctionTryBlockDeclarator) { + assert false : "TODO: handle "+ declarator.getClass().getName(); //$NON-NLS-1$ + } + } + } else if (declarator instanceof IASTFieldDeclarator) { + final IASTFieldDeclarator fieldDeclarator= (IASTFieldDeclarator)declarator; + final IASTExpression bitFieldSize= fieldDeclarator.getBitFieldSize(); + if (bitFieldSize != null) { + buffer.append(Keywords.cpCOLON); + appendExpressionString(buffer, bitFieldSize); + } + } else { +// assert false : "TODO: handle "+ declarator.getClass().getName(); //$NON-NLS-1$ + } + return buffer; + } + + private static StringBuffer appendInitializerString(StringBuffer buffer, IASTInitializer initializer) { + if (initializer instanceof IASTInitializerExpression) { + final IASTInitializerExpression initializerExpression= (IASTInitializerExpression)initializer; + buffer.append(Keywords.cpASSIGN); + appendExpressionString(buffer, initializerExpression.getExpression()); + } else if (initializer instanceof IASTInitializerList) { + final IASTInitializerList initializerList= (IASTInitializerList)initializer; + final IASTInitializer[] initializers= initializerList.getInitializers(); + buffer.append(Keywords.cpASSIGN); + buffer.append(Keywords.cpLBRACE); + for (int i= 0; i < initializers.length; i++) { + if (i > 0) { + buffer.append(COMMA_SPACE); + } + appendInitializerString(buffer, initializers[i]); + } + trimRight(buffer); + buffer.append(Keywords.cpRBRACE); + } else if (initializer instanceof ICASTDesignatedInitializer) { + //TODO handle ICASTDesignatedInitializer? +// final ICASTDesignatedInitializer designatedInitializer= (ICASTDesignatedInitializer)initializer; +// final ICASTDesignator[] designator= designatedInitializer.getDesignators(); + } else if (initializer instanceof ICPPASTConstructorInitializer) { + final ICPPASTConstructorInitializer constructorInitializer= (ICPPASTConstructorInitializer)initializer; + final IASTExpression expression= constructorInitializer.getExpression(); + buffer.append(Keywords.cpLPAREN); + appendExpressionString(buffer, expression); + trimRight(buffer); + buffer.append(Keywords.cpRPAREN); + } else if (initializer != null) { + assert false : "TODO: handle "+ initializer.getClass().getName(); //$NON-NLS-1$ + } + return buffer; + } + + private static StringBuffer appendTypeIdString(StringBuffer buffer, IASTTypeId typeId) { + appendDeclSpecifierString(buffer, typeId.getDeclSpecifier()); + appendDeclaratorString(buffer, typeId.getAbstractDeclarator(), true); + return buffer; + } + + private static StringBuffer trimRight(StringBuffer buffer) { + int length= buffer.length(); + while (length > 0 && buffer.charAt(length - 1) == ' ') { + --length; + } + buffer.setLength(length); + return buffer; + } + + private static StringBuffer appendArrayQualifiersString(StringBuffer buffer, IASTArrayDeclarator declarator) { + final IASTArrayModifier[] modifiers= declarator.getArrayModifiers(); + for (int i= 0; i < modifiers.length; i++) { + buffer.append(Keywords.cpLBRACKET).append(Keywords.cpRBRACKET); + } + return buffer; + } + + private static StringBuffer appendPointerOperatorsString(StringBuffer buffer, IASTPointerOperator[] pointerOperators) { + for (int i= 0; i < pointerOperators.length; i++) { + final IASTPointerOperator pointerOperator= pointerOperators[i]; + if (pointerOperator instanceof IASTPointer) { + final IASTPointer pointer= (IASTPointer)pointerOperator; + if (pointer instanceof ICPPASTPointerToMember) { + final ICPPASTPointerToMember pointerToMember= (ICPPASTPointerToMember)pointer; + appendQualifiedNameString(buffer, pointerToMember.getName()); + } + buffer.append(Keywords.cpSTAR); + if (pointer.isConst()) { + buffer.append(' ').append(Keywords.CONST); + } + if (pointer.isVolatile()) { + buffer.append(' ').append(Keywords.VOLATILE); + } + if (pointerOperator instanceof ICASTPointer) { + final ICASTPointer cPointer= (ICASTPointer)pointerOperator; + if (cPointer.isRestrict()) { + buffer.append(' ').append(Keywords.RESTRICT); + } + } else if (pointerOperator instanceof IGPPASTPointer) { + final IGPPASTPointer gppPointer= (IGPPASTPointer)pointerOperator; + if (gppPointer.isRestrict()) { + buffer.append(' ').append(Keywords.RESTRICT); + } + } + } else if (pointerOperator instanceof ICPPASTReferenceOperator) { + buffer.append(Keywords.cpAMPER); + } + } + return buffer; + } + + private static StringBuffer appendParameterSignatureString(StringBuffer buffer, IASTFunctionDeclarator functionDeclarator) { + if (functionDeclarator instanceof IASTStandardFunctionDeclarator) { + final IASTStandardFunctionDeclarator standardFunctionDecl= (IASTStandardFunctionDeclarator)functionDeclarator; + final IASTParameterDeclaration[] parameters= standardFunctionDecl.getParameters(); + final boolean takesVarArgs= standardFunctionDecl.takesVarArgs(); + buffer.append(Keywords.cpLPAREN); + for (int i= 0; i < parameters.length; i++) { + if (i > 0) { + buffer.append(COMMA_SPACE); + } + appendParameterDeclarationString(buffer, parameters[i]); + } + if (takesVarArgs) { + if (parameters.length > 0) { + buffer.append(COMMA_SPACE); + } + buffer.append(Keywords.cpELLIPSIS); + } + trimRight(buffer); + buffer.append(Keywords.cpRPAREN); + } else if (functionDeclarator instanceof ICASTKnRFunctionDeclarator) { + final ICASTKnRFunctionDeclarator knrDeclarator= (ICASTKnRFunctionDeclarator)functionDeclarator; + final IASTName[] names= knrDeclarator.getParameterNames(); + for(int i=0; i 0) { + buffer.append(COMMA_SPACE); + } + if (names[i] != null) { + final IASTDeclarator declaratorForParameterName= knrDeclarator.getDeclaratorForParameterName(names[i]); + if(declaratorForParameterName != null) { + appendSignatureString(buffer, declaratorForParameterName); + } + } + } + } + return buffer; + } + + private static StringBuffer appendParameterDeclarationString(StringBuffer buffer, IASTParameterDeclaration parameter) { + final IASTDeclSpecifier declSpecifier= parameter.getDeclSpecifier(); + if (declSpecifier != null) { + appendDeclSpecifierString(buffer, declSpecifier); + trimRight(buffer); + } + final IASTDeclarator declarator= parameter.getDeclarator(); + if (declarator != null) { + appendDeclaratorString(buffer, declarator, true); + appendInitializerString(buffer, declarator.getInitializer()); + } + return buffer; + } + + private static StringBuffer appendDeclSpecifierString(StringBuffer buffer, IASTDeclSpecifier declSpecifier) { + if (declSpecifier.isConst()) { + buffer.append(Keywords.CONST).append(' '); + } + if (declSpecifier.isVolatile()) { + buffer.append(Keywords.VOLATILE).append(' '); + } +// if (declSpecifier.isInline()) { +// buffer.append(Keywords.INLINE).append(' '); +// } + if (declSpecifier instanceof ICASTDeclSpecifier) { + final ICASTDeclSpecifier cDeclSpec= (ICASTDeclSpecifier)declSpecifier; + if (cDeclSpec.isRestrict()) { + buffer.append(Keywords.RESTRICT).append(' '); + } + } else if (declSpecifier instanceof ICPPASTDeclSpecifier) { + final ICPPASTDeclSpecifier cppDeclSpec= (ICPPASTDeclSpecifier)declSpecifier; + if (cppDeclSpec.isFriend()) { + buffer.append(Keywords.FRIEND).append(' '); + } + if (cppDeclSpec.isVirtual()) { + buffer.append(Keywords.VIRTUAL).append(' '); + } + if (cppDeclSpec.isExplicit()) { + buffer.append(Keywords.EXPLICIT).append(' '); + } + if (declSpecifier instanceof IGPPASTDeclSpecifier) { + final IGPPASTDeclSpecifier gppDeclSpec= (IGPPASTDeclSpecifier)declSpecifier; + if (gppDeclSpec.isRestrict()) { + buffer.append(Keywords.RESTRICT).append(' '); + } + } + } + // storage class +// final int storageClass= declSpecifier.getStorageClass(); +// switch (storageClass) { +// case IASTDeclSpecifier.sc_typedef: +// buffer.append(Keywords.TYPEDEF).append(' '); +// break; +// case IASTDeclSpecifier.sc_extern: +// buffer.append(Keywords.EXTERN).append(' '); +// break; +// case IASTDeclSpecifier.sc_static: +// buffer.append(Keywords.STATIC).append(' '); +// break; +// case IASTDeclSpecifier.sc_auto: +// buffer.append(Keywords.AUTO).append(' '); +// break; +// case IASTDeclSpecifier.sc_register: +// buffer.append(Keywords.REGISTER).append(' '); +// break; +// case ICPPASTDeclSpecifier.sc_mutable: +// buffer.append(Keywords.MUTABLE).append(' '); +// break; +// } + if (declSpecifier instanceof IASTCompositeTypeSpecifier) { + final int key= ((IASTCompositeTypeSpecifier)declSpecifier).getKey(); + switch (key) { + case IASTCompositeTypeSpecifier.k_struct: + buffer.append(Keywords.STRUCT).append(' '); + break; + case IASTCompositeTypeSpecifier.k_union: + buffer.append(Keywords.UNION).append(' '); + break; + case ICPPASTCompositeTypeSpecifier.k_class: + buffer.append(Keywords.CLASS).append(' '); + break; + default: + } + } else if (declSpecifier instanceof IASTElaboratedTypeSpecifier) { + final IASTElaboratedTypeSpecifier elaboratedTypeSpec= (IASTElaboratedTypeSpecifier)declSpecifier; + switch (elaboratedTypeSpec.getKind()) { + case IASTElaboratedTypeSpecifier.k_enum: + buffer.append(Keywords.ENUM).append(' '); + break; + case IASTElaboratedTypeSpecifier.k_struct: + buffer.append(Keywords.STRUCT).append(' '); + break; + case IASTElaboratedTypeSpecifier.k_union: + buffer.append(Keywords.UNION).append(' '); + break; + case ICPPASTElaboratedTypeSpecifier.k_class: + buffer.append(Keywords.CLASS).append(' '); + break; + default: + assert false; + } + appendQualifiedNameString(buffer, elaboratedTypeSpec.getName()); + } else if (declSpecifier instanceof IASTEnumerationSpecifier) { + final IASTEnumerationSpecifier enumerationSpec= (IASTEnumerationSpecifier)declSpecifier; + appendQualifiedNameString(buffer, enumerationSpec.getName()); + } else if (declSpecifier instanceof IASTSimpleDeclSpecifier) { + final IASTSimpleDeclSpecifier simpleDeclSpec= (IASTSimpleDeclSpecifier)declSpecifier; + if (simpleDeclSpec.isSigned()) { + buffer.append(Keywords.SIGNED).append(' '); + } + if (simpleDeclSpec.isUnsigned()) { + buffer.append(Keywords.UNSIGNED).append(' '); + } + if (simpleDeclSpec.isShort()) { + buffer.append(Keywords.SHORT).append(' '); + } + if (simpleDeclSpec.isLong()) { + buffer.append(Keywords.LONG).append(' '); + } + if (simpleDeclSpec instanceof ICASTSimpleDeclSpecifier) { + final ICASTSimpleDeclSpecifier cSimpleDeclSpec= (ICASTSimpleDeclSpecifier)simpleDeclSpec; + if (cSimpleDeclSpec.isLongLong()) { + buffer.append(Keywords.LONG_LONG).append(' '); + } + if (cSimpleDeclSpec.isComplex()) { + buffer.append(Keywords._COMPLEX).append(' '); + } + if (cSimpleDeclSpec.isImaginary()) { + buffer.append(Keywords._IMAGINARY).append(' '); + } + switch (simpleDeclSpec.getType()) { + case ICASTSimpleDeclSpecifier.t_Bool: + buffer.append(Keywords._BOOL).append(' '); + break; + } + } + switch (simpleDeclSpec.getType()) { + case IASTSimpleDeclSpecifier.t_void: + buffer.append(Keywords.VOID).append(' '); + break; + case IASTSimpleDeclSpecifier.t_char: + buffer.append(Keywords.CHAR).append(' '); + break; + case IASTSimpleDeclSpecifier.t_int: + buffer.append(Keywords.INT).append(' '); + break; + case IASTSimpleDeclSpecifier.t_float: + buffer.append(Keywords.FLOAT).append(' '); + break; + case IASTSimpleDeclSpecifier.t_double: + buffer.append(Keywords.DOUBLE).append(' '); + break; + case ICPPASTSimpleDeclSpecifier.t_bool: + buffer.append(Keywords.BOOL).append(' '); + break; + case ICPPASTSimpleDeclSpecifier.t_wchar_t: + buffer.append(Keywords.WCHAR_T).append(' '); + break; + default: + } + } else if (declSpecifier instanceof IASTNamedTypeSpecifier) { + final IASTNamedTypeSpecifier namedTypeSpec= (IASTNamedTypeSpecifier)declSpecifier; + appendQualifiedNameString(buffer, namedTypeSpec.getName()); + } + return buffer; + } + + private static StringBuffer appendQualifiedNameString(StringBuffer buffer, IASTName name) { + return appendNameString(buffer, name, true); + } + + private static StringBuffer appendSimpleNameString(StringBuffer buffer, IASTName name) { + return appendNameString(buffer, name, false); + } + + private static StringBuffer appendNameString(StringBuffer buffer, IASTName name, boolean qualified) { + if (name instanceof ICPPASTQualifiedName) { + final ICPPASTQualifiedName qualifiedName= (ICPPASTQualifiedName)name; + if (qualified) { + final IASTName[] names= qualifiedName.getNames(); + for (int i= 0; i < names.length; i++) { + if (i > 0) { + buffer.append(Keywords.cpCOLONCOLON); + } + appendQualifiedNameString(buffer, names[i]); + } + } else { + buffer.append(qualifiedName.getLastName()); + } + } else if (name instanceof ICPPASTTemplateId) { + final ICPPASTTemplateId templateId= (ICPPASTTemplateId)name; + appendQualifiedNameString(buffer, templateId.getTemplateName()); + final IASTNode[] templateArguments= templateId.getTemplateArguments(); + buffer.append(Keywords.cpLT); + for (int i= 0; i < templateArguments.length; i++) { + if (i > 0) { + buffer.append(Keywords.cpCOMMA); + } + final IASTNode argument= templateArguments[i]; + if (argument instanceof IASTTypeId) { + appendTypeIdString(buffer, (IASTTypeId)argument); + } else if (argument instanceof IASTExpression) { + final IASTExpression expression= (IASTExpression)argument; + appendExpressionString(buffer, expression); + } + } + buffer.append(Keywords.cpGT); + } else if (name != null) { + buffer.append(name.toCharArray()); + } + return buffer; + } + + private static StringBuffer appendExpressionString(StringBuffer buffer, IASTExpression expression) { + if (expression instanceof IASTIdExpression) { + final IASTIdExpression idExpression= (IASTIdExpression)expression; + appendQualifiedNameString(buffer, idExpression.getName()); + } else if (expression instanceof IASTExpressionList) { + final IASTExpressionList expressionList= (IASTExpressionList)expression; + final IASTExpression[] expressions= expressionList.getExpressions(); + for (int i= 0; i < expressions.length; i++) { + if (i > 0) { + buffer.append(COMMA_SPACE); + } + appendExpressionString(buffer, expressions[i]); + } + } else if (expression instanceof ICPPASTTypenameExpression) { + final ICPPASTTypenameExpression typenameExpression= (ICPPASTTypenameExpression)expression; + buffer.append(Keywords.TYPENAME).append(' '); + appendQualifiedNameString(buffer, typenameExpression.getName()); + final IASTExpression initialValue= typenameExpression.getInitialValue(); + if (initialValue != null) { + buffer.append(Keywords.cpASSIGN); + appendExpressionString(buffer, initialValue); + } + } else if (expression instanceof IASTLiteralExpression) { + buffer.append(ASTSignatureUtil.getExpressionString(expression)); + } else if (expression != null) { + buffer.append(ASTSignatureUtil.getExpressionString(expression)); + } + return buffer; + } + + private static StringBuffer appendTemplateParameterString(StringBuffer buffer, ICPPASTTemplateParameter parameter){ + if (parameter instanceof ICPPASTParameterDeclaration) { + appendParameterDeclarationString(buffer, (ICPPASTParameterDeclaration)parameter); + } else if (parameter instanceof ICPPASTSimpleTypeTemplateParameter) { + final ICPPASTSimpleTypeTemplateParameter simpletypeParameter= (ICPPASTSimpleTypeTemplateParameter)parameter; + final IASTName name= simpletypeParameter.getName(); + if (name != null) { + appendSimpleNameString(buffer, name); + } else { + final int type= simpletypeParameter.getParameterType(); + switch (type) { + case ICPPASTSimpleTypeTemplateParameter.st_class: + buffer.append(Keywords.CLASS); + break; + case ICPPASTSimpleTypeTemplateParameter.st_typename: + buffer.append(Keywords.TYPENAME); + break; + } + } + } else if (parameter instanceof ICPPASTTemplatedTypeTemplateParameter) { + final ICPPASTTemplatedTypeTemplateParameter templatedTypeParameter= (ICPPASTTemplatedTypeTemplateParameter)parameter; + final ICPPASTTemplateParameter[] subParameters= templatedTypeParameter.getTemplateParameters(); + buffer.append(Keywords.TEMPLATE).append(Keywords.cpLT); + for (int i= 0; i < subParameters.length; i++) { + final ICPPASTTemplateParameter templateParameter= subParameters[i]; + if (i > 0) { + buffer.append(COMMA_SPACE); + } + appendTemplateParameterString(buffer, templateParameter); + } + trimRight(buffer); + buffer.append(Keywords.cpGT); + } + return buffer; + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementInfo.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementInfo.java index 08a0e3b714a..e7e42715118 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementInfo.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElementInfo.java @@ -69,6 +69,10 @@ class CElementInfo { } } + List internalGetChildren() { + return fChildren; + } + /** * Returns true if this child is in my children collection diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java index b84f57612f8..fb239ff4615 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder.java @@ -183,7 +183,7 @@ public class CModelBuilder { language, ParserUtil.getParserLogService() ); } catch(ParserFactoryError pfe) { - throw new ParserException( CCorePlugin.getResourceString("CModelBuilder.Parser_Construction_Failure")); //$NON-NLS-1$ + throw new ParserException( ""); //$NON-NLS-1$ } // call parse if (problemRequestor != null) { @@ -194,7 +194,7 @@ public class CModelBuilder { problemRequestor.endReporting(); } if( (!hasNoErrors) && throwExceptionOnError ) - throw new ParserException(CCorePlugin.getResourceString("CModelBuilder.Parse_Failure")); //$NON-NLS-1$ + throw new ParserException(""); //$NON-NLS-1$ return quickParseCallback.getCompilationUnit(); } @@ -207,7 +207,11 @@ public class CModelBuilder { Util.debugLog( "Parse Exception in CModelBuilder", IDebugLogConstants.MODEL ); //$NON-NLS-1$ //e.printStackTrace(); } - Util.debugLog("CModel parsing: "+ ( System.currentTimeMillis() - startTime ) + "ms", IDebugLogConstants.MODEL); //$NON-NLS-1$ //$NON-NLS-2$ + Util.debugLog("CModelBuilder: parsing " //$NON-NLS-1$ + + translationUnit.getElementName() + + " mode="+ (quickParseMode ? "quick " : "structural ") //$NON-NLS-1$ //$NON-NLS-2$ + + " time="+ ( System.currentTimeMillis() - startTime ) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ + IDebugLogConstants.MODEL, false); startTime = System.currentTimeMillis(); try { @@ -217,11 +221,14 @@ public class CModelBuilder { } catch( NullPointerException npe ) { Util.debugLog( "NullPointer exception in CModelBuilder", IDebugLogConstants.MODEL); //$NON-NLS-1$ } - + // For the debuglog to take place, you have to call // Util.setDebugging(true); // Or set debug to true in the core plugin preference - Util.debugLog("CModel building: "+ ( System.currentTimeMillis() - startTime ) + "ms", IDebugLogConstants.MODEL); //$NON-NLS-1$ //$NON-NLS-2$ + Util.debugLog("CModelBuilder: building " //$NON-NLS-1$ + +"children="+ translationUnit.getElementInfo().internalGetChildren().size() //$NON-NLS-1$ + +" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ + IDebugLogConstants.MODEL, false); return this.newElements; } @@ -303,7 +310,7 @@ public class CModelBuilder { private void generateModelElements (Parent parent, IASTAbstractTypeSpecifierDeclaration abstractDeclaration) throws CModelException, ASTNotImplementedException { // IASTAbstractTypeSpecifierDeclaration - CElement element = createAbstractElement(parent, abstractDeclaration, false, true); + createAbstractElement(parent, abstractDeclaration, false, true); } private void generateModelElements (Parent parent, IASTTemplateDeclaration templateDeclaration) throws CModelException, ASTNotImplementedException @@ -320,7 +327,7 @@ public class CModelBuilder { // set the template parameters StructureTemplate classTemplate = (StructureTemplate) element; classTemplate.setTemplateParameterTypes(parameterTypes); - } else if (element instanceof StructureTemplate) { + } else if (element instanceof StructureTemplateDeclaration) { // set the template parameters StructureTemplateDeclaration classTemplate = (StructureTemplateDeclaration) element; classTemplate.setTemplateParameterTypes(parameterTypes); @@ -335,7 +342,7 @@ public class CModelBuilder { // set the template parameters StructureTemplate classTemplate = (StructureTemplate) element; classTemplate.setTemplateParameterTypes(parameterTypes); - } else if (element instanceof StructureTemplate) { + } else if (element instanceof StructureTemplateDeclaration) { // set the template parameters StructureTemplateDeclaration classTemplate = (StructureTemplateDeclaration) element; classTemplate.setTemplateParameterTypes(parameterTypes); @@ -377,9 +384,9 @@ public class CModelBuilder { private void generateModelElements (Parent parent, IASTTypedefDeclaration declaration) throws CModelException, ASTNotImplementedException { - TypeDef typeDef = createTypeDef(parent, declaration); + createTypeDef(parent, declaration); IASTAbstractDeclaration abstractDeclaration = declaration.getAbstractDeclarator(); - CElement element = createAbstractElement(parent, abstractDeclaration, false, true); + createAbstractElement(parent, abstractDeclaration, false, true); } private CElement createClassSpecifierElement(Parent parent, IASTClassSpecifier classSpecifier, boolean isTemplate)throws ASTNotImplementedException, CModelException{ @@ -634,7 +641,7 @@ public class CModelBuilder { } IASTAbstractDeclaration abstractDeclaration = varDeclaration.getAbstractDeclaration(); - CElement abstractElement = createAbstractElement (parent, abstractDeclaration , isTemplate, false); + createAbstractElement (parent, abstractDeclaration , isTemplate, false); VariableDeclaration element = null; if(varDeclaration instanceof IASTField){ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java new file mode 100644 index 00000000000..bb6c750d0f1 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java @@ -0,0 +1,1259 @@ +/******************************************************************************* + * Copyright (c) 2006 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: + * Anton Leherbauer (Wind River Systems) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.model; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Stack; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTMacroExpansion; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; +import org.eclipse.cdt.core.dom.ast.IASTProblem; +import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisiblityLabel; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IContributedModelBuilder; +import org.eclipse.cdt.core.model.IProblemRequestor; +import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.parser.IProblem; +import org.eclipse.cdt.core.parser.Keywords; +import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclaration; +import org.eclipse.cdt.internal.core.dom.parser.IASTDeclarationAmbiguity; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; + +/** + * Build TranslationUnit structure from an IASTTranslationUnit. + * + * @since 4.0 + */ +public class CModelBuilder2 implements IContributedModelBuilder { + + private static final boolean PRINT_PROBLEMS= false; + + private static class ProblemPrinter implements IProblemRequestor { + public void acceptProblem(IProblem problem) { + System.err.println("PROBLEM: " + problem.getMessage()); //$NON-NLS-1$ + } + public void beginReporting() { + } + public void endReporting() { + } + public boolean isActive() { + return true; + } + } + + /** + * Adapts {@link IASTProblem} to {@link IProblem). + */ + private static class ProblemAdapter implements IProblem { + + private IASTProblem fASTProblem; + + /** + * @param problem + */ + public ProblemAdapter(IASTProblem problem) { + fASTProblem= problem; + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#checkCategory(int) + */ + public boolean checkCategory(int bitmask) { + return fASTProblem.checkCategory(bitmask); + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getArguments() + */ + public String getArguments() { + return fASTProblem.getArguments(); + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getID() + */ + public int getID() { + return fASTProblem.getID(); + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getMessage() + */ + public String getMessage() { + return fASTProblem.getMessage(); + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getOriginatingFileName() + */ + public char[] getOriginatingFileName() { + return fASTProblem.getContainingFilename().toCharArray(); + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getSourceEnd() + */ + public int getSourceEnd() { + IASTFileLocation location= fASTProblem.getFileLocation(); + if (location != null) { + return location.getNodeOffset() + location.getNodeLength() - 1; + } + return -1; + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getSourceLineNumber() + */ + public int getSourceLineNumber() { + IASTFileLocation location= fASTProblem.getFileLocation(); + if (location != null) { + return location.getStartingLineNumber(); + } + return -1; + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#getSourceStart() + */ + public int getSourceStart() { + IASTFileLocation location= fASTProblem.getFileLocation(); + if (location != null) { + return location.getNodeOffset(); + } + return -1; + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#isError() + */ + public boolean isError() { + return fASTProblem.isError(); + } + + /* + * @see org.eclipse.cdt.core.parser.IProblem#isWarning() + */ + public boolean isWarning() { + return fASTProblem.isWarning(); + } + + } + + private final TranslationUnit fTranslationUnit; + private String fTranslationUnitFileName; + private ASTAccessVisibility fCurrentVisibility; + private Stack fVisibilityStack; + + /** + * Create a model builder for the given translation unit. + * + * @param tu the translation unit (must be a {@link TranslationUnit} + */ + public CModelBuilder2(ITranslationUnit tu) { + fTranslationUnit= (TranslationUnit)tu; + } + + /* + * @see org.eclipse.cdt.core.model.IContributedModelBuilder#parse(boolean) + */ + public void parse(boolean quickParseMode) throws Exception { + IIndex index= CCorePlugin.getIndexManager().getIndex(fTranslationUnit.getCProject()); + try { + if (index != null) { + try { + index.acquireReadLock(); + } catch (InterruptedException ie) { + index= null; + } + } + long startTime= System.currentTimeMillis(); + final IASTTranslationUnit ast= fTranslationUnit.getAST(index, quickParseMode ? ITranslationUnit.AST_SKIP_ALL_HEADERS : 0); + Util.debugLog("CModelBuilder2: parsing " //$NON-NLS-1$ + + fTranslationUnit.getElementName() + + " mode="+ (quickParseMode ? "fast " : "full ") //$NON-NLS-1$ //$NON-NLS-2$ + + " time="+ ( System.currentTimeMillis() - startTime ) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ + IDebugLogConstants.MODEL, false); + + startTime= System.currentTimeMillis(); + buildModel(ast); + fTranslationUnit.getElementInfo().setIsStructureKnown(true); + Util.debugLog("CModelBuilder2: building " //$NON-NLS-1$ + +"children="+ fTranslationUnit.getElementInfo().internalGetChildren().size() //$NON-NLS-1$ + +" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$ + IDebugLogConstants.MODEL, false); + } finally { + if (index != null) { + index.releaseReadLock(); + } + } + } + + /** + * Build the model from the given AST. + * @param ast + * @throws CModelException + * @throws DOMException + */ + private void buildModel(IASTTranslationUnit ast) throws CModelException, DOMException { + fTranslationUnitFileName= ast.getFilePath(); + fVisibilityStack= new Stack(); + + // includes + final IASTPreprocessorIncludeStatement[] includeDirectives= ast.getIncludeDirectives(); + for (int i= 0; i < includeDirectives.length; i++) { + IASTPreprocessorIncludeStatement includeDirective= includeDirectives[i]; + if (isLocalToFile(includeDirective)) { + createInclusion(fTranslationUnit, includeDirective); + } + } + // problem includes + final IASTProblem[] ppProblems= ast.getPreprocessorProblems(); + for (int i= 0; i < ppProblems.length; i++) { + IASTProblem problem= ppProblems[i]; + if (problem.getID() == IASTProblem.PREPROCESSOR_INCLUSION_NOT_FOUND) { + if (isLocalToFile(problem)) { + createProblemInclusion(fTranslationUnit, problem); + } + } + } + // macros + final IASTPreprocessorMacroDefinition[] macroDefinitions= ast.getMacroDefinitions(); + for (int i= 0; i < macroDefinitions.length; i++) { + IASTPreprocessorMacroDefinition macroDefinition= macroDefinitions[i]; + if (isLocalToFile(macroDefinition)) { + createMacro(fTranslationUnit, macroDefinition); + } + } + // declarations + final IASTDeclaration[] declarations= ast.getDeclarations(); + for (int i= 0; i < declarations.length; i++) { + IASTDeclaration declaration= declarations[i]; + if (isLocalToFile(declaration)) { + createDeclaration(fTranslationUnit, declaration); + } + } + + // sort by offset + final List children= fTranslationUnit.getElementInfo().internalGetChildren(); + Collections.sort(children, new Comparator() { + public int compare(Object o1, Object o2) { + try { + final SourceManipulation element1= (SourceManipulation)o1; + final SourceManipulation element2= (SourceManipulation)o2; + return element1.getSourceManipulationInfo().getStartPos() - element2.getSourceManipulationInfo().getStartPos(); + } catch (CModelException exc) { + return 0; + } + }}); + + // report problems + IProblemRequestor problemRequestor= fTranslationUnit.getProblemRequestor(); + if (problemRequestor == null && PRINT_PROBLEMS) { + problemRequestor= new ProblemPrinter(); + } + if (problemRequestor != null && problemRequestor.isActive()) { + problemRequestor.beginReporting(); + IASTProblem[] problems= ppProblems; + for (int i= 0; i < problems.length; i++) { + IASTProblem problem= problems[i]; + if (isLocalToFile(problem)) { + problemRequestor.acceptProblem(new ProblemAdapter(problem)); + } else if (PRINT_PROBLEMS) { + System.err.println("PREPROCESSOR PROBLEM: " + problem.getMessage()); //$NON-NLS-1$ + } + } + problems= CPPVisitor.getProblems(ast); + for (int i= 0; i < problems.length; i++) { + IASTProblem problem= problems[i]; + if (isLocalToFile(problem)) { + problemRequestor.acceptProblem(new ProblemAdapter(problem)); + } else if (PRINT_PROBLEMS) { + System.err.println("PROBLEM: " + problem.getMessage()); //$NON-NLS-1$ + } + } + problemRequestor.endReporting(); + } + } + + private boolean isLocalToFile(IASTNode node) { + return fTranslationUnitFileName.equals(node.getContainingFilename()); + } + + private Include createInclusion(Parent parent, IASTPreprocessorIncludeStatement inclusion) throws CModelException{ + // create element + final IASTName name= inclusion.getName(); + Include element= new Include(parent, ASTStringUtil.getSimpleName(name), inclusion.isSystemInclude()); + element.setFullPathName(inclusion.getPath()); + // add to parent + parent.addChild(element); + // set positions + setIdentifierPosition(element, name); + setBodyPosition(element, inclusion); + return element; + } + + private Include createProblemInclusion(Parent parent, IASTProblem problem) throws CModelException { + // create element + String name= problem.getArguments(); + if (name == null || name.length() == 0) { + return null; + } + String signature= problem.getRawSignature(); + int nameIdx= signature.indexOf(name); + boolean isStandard= false; + if (nameIdx > 0) { + isStandard= signature.charAt(nameIdx-1) == '<'; + } + Include element= new Include(parent, name, isStandard); + // add to parent + parent.addChild(element); + // set positions + if (nameIdx > 0) { + final IASTFileLocation problemLocation= problem.getFileLocation(); + if (problemLocation != null) { + final int startOffset= problemLocation.getNodeOffset(); + element.setIdPos(startOffset + nameIdx - 1, name.length() + 2); + } + } else { + setIdentifierPosition(element, problem); + } + setBodyPosition(element, problem); + return element; + } + + private Macro createMacro(Parent parent, IASTPreprocessorMacroDefinition macro) throws CModelException{ + // create element + final IASTName name= macro.getName(); + Macro element= new Macro(parent, ASTStringUtil.getSimpleName(name)); + // add to parent + parent.addChild(element); + // set positions + setIdentifierPosition(element, name); + setBodyPosition(element, macro); + return element; + + } + + private void createDeclaration(Parent parent, IASTDeclaration declaration) throws CModelException, DOMException { + if (declaration instanceof IASTFunctionDefinition) { + createFunctionDefinition(parent, (IASTFunctionDefinition)declaration, false); + } else if (declaration instanceof IASTSimpleDeclaration) { + createSimpleDeclarations(parent, (IASTSimpleDeclaration)declaration, false); + } else if (declaration instanceof ICPPASTVisiblityLabel) { + handleVisibilityLabel((ICPPASTVisiblityLabel)declaration); + } else if(declaration instanceof ICPPASTNamespaceDefinition) { + createNamespace(parent, (ICPPASTNamespaceDefinition) declaration); + } else if (declaration instanceof ICPPASTNamespaceAlias) { + // TODO [cmodel] namespace alias? + } else if (declaration instanceof ICPPASTTemplateDeclaration) { + createTemplateDeclaration(parent, (ICPPASTTemplateDeclaration)declaration); + } else if (declaration instanceof ICPPASTTemplateSpecialization) { + // TODO [cmodel] template specialization? + } else if (declaration instanceof ICPPASTExplicitTemplateInstantiation) { + // TODO [cmodel] explicit template instantiation? + } else if (declaration instanceof ICPPASTUsingDeclaration) { + createUsingDeclaration(parent, (ICPPASTUsingDeclaration)declaration); + } else if (declaration instanceof ICPPASTUsingDirective) { + createUsingDirective(parent, (ICPPASTUsingDirective)declaration); + } else if (declaration instanceof ICPPASTLinkageSpecification) { + createLinkageSpecification(parent, (ICPPASTLinkageSpecification)declaration); + } else if (declaration instanceof IASTASMDeclaration) { + // TODO [cmodel] asm declaration? + } else if (declaration instanceof IASTProblemDeclaration) { + // TODO [cmodel] problem declaration? + } else if (declaration instanceof IASTAmbiguousDeclaration) { + // TODO [cmodel] ambiguous declaration? + } else if (declaration instanceof IASTDeclarationAmbiguity) { + // TODO [cmodel] declaration ambiguity? + } else { + assert false : "TODO: " + declaration.getClass().getName(); //$NON-NLS-1$ + } + } + + private void createTemplateDeclaration(Parent parent, ICPPASTTemplateDeclaration templateDeclaration) throws CModelException, DOMException { + IASTDeclaration declaration= templateDeclaration.getDeclaration(); + if (declaration instanceof IASTFunctionDefinition) { + CElement element= createFunctionDefinition(parent, (IASTFunctionDefinition)declaration, true); + String[] parameterTypes= ASTStringUtil.getTemplateParameterArray(templateDeclaration.getTemplateParameters()); + // set the template parameters + if (element instanceof FunctionTemplate) { + FunctionTemplate functionTemplate= (FunctionTemplate) element; + functionTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof MethodTemplate) { + MethodTemplate methodTemplate= (MethodTemplate) element; + methodTemplate.setTemplateParameterTypes(parameterTypes); + } + // set the body position + if (element instanceof SourceManipulation) { + setBodyPosition((SourceManipulation)element, templateDeclaration); + } + } else if (declaration instanceof IASTSimpleDeclaration) { + CElement[] elements= createSimpleDeclarations(parent, (IASTSimpleDeclaration)declaration, true); + String[] parameterTypes= ASTStringUtil.getTemplateParameterArray(templateDeclaration.getTemplateParameters()); + for (int i= 0; i < elements.length; i++) { + CElement element= elements[i]; + // set the template parameters + if (element instanceof StructureTemplate) { + StructureTemplate classTemplate= (StructureTemplate) element; + classTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof StructureTemplateDeclaration) { + StructureTemplateDeclaration classTemplate= (StructureTemplateDeclaration) element; + classTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof VariableTemplate) { + VariableTemplate varTemplate= (VariableTemplate) element; + varTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof FunctionTemplateDeclaration) { + FunctionTemplateDeclaration functionTemplate= (FunctionTemplateDeclaration) element; + functionTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof MethodTemplateDeclaration) { + MethodTemplateDeclaration methodTemplate= (MethodTemplateDeclaration) element; + methodTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof FunctionTemplate) { + FunctionTemplate functionTemplate= (FunctionTemplate) element; + functionTemplate.setTemplateParameterTypes(parameterTypes); + } else if (element instanceof MethodTemplate) { + MethodTemplate methodTemplate= (MethodTemplate) element; + methodTemplate.setTemplateParameterTypes(parameterTypes); + } + // set the body position + if (element instanceof SourceManipulation) { + setBodyPosition((SourceManipulation)element, templateDeclaration); + } + } + } else if (declaration instanceof IASTProblemDeclaration) { + // ignore problem declarations + } else { + assert false : "TODO: " + declaration.getClass().getName(); //$NON-NLS-1$ + } + } + + /** + * Handle extern "C" and related kinds. + * + * @param parent + * @param declaration + * @throws CModelException + * @throws DOMException + */ + private void createLinkageSpecification(Parent parent, ICPPASTLinkageSpecification linkageDeclaration) throws CModelException, DOMException { + IASTDeclaration[] declarations= linkageDeclaration.getDeclarations(); + for (int i= 0; i < declarations.length; i++) { + IASTDeclaration declaration= declarations[i]; + createDeclaration(parent, declaration); + } + } + + private CElement[] createSimpleDeclarations(Parent parent, IASTSimpleDeclaration declaration, boolean isTemplate) throws CModelException, DOMException { + final IASTDeclSpecifier declSpecifier= declaration.getDeclSpecifier(); + final IASTDeclarator[] declarators= declaration.getDeclarators(); + final CElement[] elements; + if (declarators.length > 0) { + elements= new CElement[declarators.length]; + for (int i= 0; i < declarators.length; i++) { + final IASTDeclarator declarator= declarators[i]; + final CElement element= createSimpleDeclaration(parent, declSpecifier, declarator, isTemplate); +// if (!isTemplate && element instanceof SourceManipulation) { +// setBodyPosition((SourceManipulation)element, declaration); +// } + elements[i]= element; + } + } else { + elements= new CElement[1]; + final CElement element= createSimpleDeclaration(parent, declSpecifier, null, isTemplate); + elements[0]= element; + } + return elements; + } + + private CElement createSimpleDeclaration(Parent parent, IASTDeclSpecifier declSpecifier, IASTDeclarator declarator, boolean isTemplate) throws CModelException, DOMException { + if (declSpecifier instanceof IASTCompositeTypeSpecifier) { + final CElement compositeType= createCompositeType(parent, (IASTCompositeTypeSpecifier)declSpecifier, isTemplate); + if (declarator != null) { + return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); + } + return compositeType; + } else if (declSpecifier instanceof IASTElaboratedTypeSpecifier) { + if (declarator == null) { + return createElaboratedTypeDeclaration(parent, (IASTElaboratedTypeSpecifier)declSpecifier, isTemplate); + } else { + return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); + } + } else if (declSpecifier instanceof IASTEnumerationSpecifier) { + return createEnumeration(parent, (IASTEnumerationSpecifier)declSpecifier); + } else if (declSpecifier instanceof IASTNamedTypeSpecifier) { + return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); + } else if (declSpecifier instanceof IASTSimpleDeclSpecifier) { + return createTypedefOrFunctionOrVariable(parent, declSpecifier, declarator, isTemplate); + } else { + assert false : "TODO: " + declSpecifier.getClass().getName(); //$NON-NLS-1$ + } + return null; + } + + private CElement createTypedefOrFunctionOrVariable(Parent parent, IASTDeclSpecifier declSpecifier, + IASTDeclarator declarator, boolean isTemplate) throws CModelException { + if (declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef) { + return createTypeDef(parent, declSpecifier, declarator); + } + if (declarator != null) { + IASTDeclarator nestedDeclarator= declarator.getNestedDeclarator(); + if (nestedDeclarator == null && declarator instanceof IASTFunctionDeclarator) { + return createFunctionDeclaration(parent, declSpecifier, (IASTFunctionDeclarator)declarator, isTemplate); + } + } + return createVariable(parent, declSpecifier, declarator, isTemplate); + } + + private void createNamespace(Parent parent, ICPPASTNamespaceDefinition declaration) throws CModelException, DOMException{ + // create element + final String type= Keywords.NAMESPACE; + final IASTName name= declaration.getName(); + String nsName= ASTStringUtil.getQualifiedName(name); + final Namespace element= new Namespace (parent, nsName); + // add to parent + parent.addChild(element); + // set positions + if (name != null && nsName.length() > 0) { + setIdentifierPosition(element, name); + } else { + final IASTFileLocation nsLocation= getMinFileLocation(declaration.getNodeLocations()); + if (nsLocation != null) { + element.setIdPos(nsLocation.getNodeOffset(), type.length()); + } + } + setBodyPosition(element, declaration); + + element.setTypeName(type); + + IASTDeclaration[] nsDeclarations= declaration.getDeclarations(); + for (int i= 0; i < nsDeclarations.length; i++) { + IASTDeclaration nsDeclaration= nsDeclarations[i]; + createDeclaration(element, nsDeclaration); + } + } + + private StructureDeclaration createElaboratedTypeDeclaration(Parent parent, IASTElaboratedTypeSpecifier elaboratedTypeSpecifier, boolean isTemplate) throws CModelException{ + // create element + final String type; + final int kind; + switch (elaboratedTypeSpecifier.getKind()) { + case IASTElaboratedTypeSpecifier.k_struct: + kind= (isTemplate) ? ICElement.C_TEMPLATE_STRUCT : ICElement.C_STRUCT; + type= Keywords.STRUCT; + break; + case IASTElaboratedTypeSpecifier.k_union: + kind= (isTemplate) ? ICElement.C_TEMPLATE_UNION : ICElement.C_UNION; + type= Keywords.UNION; + break; + case ICPPASTElaboratedTypeSpecifier.k_class: + kind= (isTemplate) ? ICElement.C_TEMPLATE_CLASS : ICElement.C_CLASS; + type= Keywords.CLASS; + break; + default: + kind= ICElement.C_CLASS; + type= ""; //$NON-NLS-1$ + break; + } + + final IASTName astClassName= elaboratedTypeSpecifier.getName(); + final String className= ASTStringUtil.getSimpleName(astClassName); + + StructureDeclaration element; + if (isTemplate) { + element= new StructureTemplateDeclaration(parent, kind, className); + } else { + element= new StructureDeclaration(parent, className, kind); + } + element.setTypeName(type); + + // add to parent + parent.addChild(element); + + // set positions + if (className.length() > 0) { + setIdentifierPosition(element, astClassName); + } else { + final IASTFileLocation classLocation= getMinFileLocation(elaboratedTypeSpecifier.getNodeLocations()); + if (classLocation != null) { + element.setIdPos(classLocation.getNodeOffset(), type.length()); + } + } + setBodyPosition(element, elaboratedTypeSpecifier); + return element; + } + + private Enumeration createEnumeration(Parent parent, IASTEnumerationSpecifier enumSpecifier) throws CModelException{ + // create element + final String type= Keywords.ENUM; + final IASTName astEnumName= enumSpecifier.getName(); + final String enumName= ASTStringUtil.getSimpleName(astEnumName); + final Enumeration element= new Enumeration (parent, enumName); + // add to parent + parent.addChild(element); + final IASTEnumerator[] enumerators= enumSpecifier.getEnumerators(); + for (int i= 0; i < enumerators.length; i++) { + final IASTEnumerator enumerator= enumerators[i]; + createEnumerator(element, enumerator); + } + // set enumeration position + if (astEnumName != null && enumName.length() > 0) { + setIdentifierPosition(element, astEnumName); + } else { + final IASTFileLocation enumLocation= enumSpecifier.getFileLocation(); + element.setIdPos(enumLocation.getNodeOffset(), type.length()); + } + setBodyPosition(element, enumSpecifier); + element.setTypeName(type); + return element; + } + + private Enumerator createEnumerator(Parent enumarator, IASTEnumerator enumDef) throws CModelException{ + final IASTName astEnumName= enumDef.getName(); + final Enumerator element= new Enumerator (enumarator, ASTStringUtil.getSimpleName(astEnumName)); + IASTExpression initialValue= enumDef.getValue(); + if(initialValue != null){ + element.setConstantExpression(ASTSignatureUtil.getExpressionString(initialValue)); + } + // add to parent + enumarator.addChild(element); + // set positions + setIdentifierPosition(element, astEnumName); + setBodyPosition(element, enumDef); + return element; + } + + private Structure createCompositeType(Parent parent, IASTCompositeTypeSpecifier compositeTypeSpecifier, boolean isTemplate) throws CModelException, DOMException{ + // create element + final String type; + final int kind; + final ASTAccessVisibility defaultVisibility; + switch (compositeTypeSpecifier.getKey()) { + case IASTCompositeTypeSpecifier.k_struct: + kind= (isTemplate) ? ICElement.C_TEMPLATE_STRUCT : ICElement.C_STRUCT; + type= Keywords.STRUCT; + defaultVisibility= ASTAccessVisibility.PUBLIC; + break; + case IASTCompositeTypeSpecifier.k_union: + kind= (isTemplate) ? ICElement.C_TEMPLATE_UNION : ICElement.C_UNION; + type= Keywords.UNION; + defaultVisibility= ASTAccessVisibility.PUBLIC; + break; + case ICPPASTCompositeTypeSpecifier.k_class: + kind= (isTemplate) ? ICElement.C_TEMPLATE_CLASS : ICElement.C_CLASS; + type= Keywords.CLASS; + defaultVisibility= ASTAccessVisibility.PRIVATE; + break; + default: + kind= ICElement.C_CLASS; + type= ""; //$NON-NLS-1$ + defaultVisibility= ASTAccessVisibility.PUBLIC; + break; + } + + final IASTName astClassName= compositeTypeSpecifier.getName(); + final String className= ASTStringUtil.getSimpleName(astClassName);; + + final Structure element; + if (!isTemplate) { + Structure classElement= new Structure(parent, kind, className); + element= classElement; + } else { + StructureTemplate classTemplate= new StructureTemplate(parent, kind, className); + element= classTemplate; + } + + if (compositeTypeSpecifier instanceof ICPPASTCompositeTypeSpecifier) { + // store super classes names + final ICPPASTCompositeTypeSpecifier cppCompositeTypeSpecifier= (ICPPASTCompositeTypeSpecifier)compositeTypeSpecifier; + ICPPASTBaseSpecifier[] baseSpecifiers= cppCompositeTypeSpecifier.getBaseSpecifiers(); + for (int i= 0; i < baseSpecifiers.length; i++) { + final ICPPASTBaseSpecifier baseSpecifier= baseSpecifiers[i]; + final IASTName baseName= baseSpecifier.getName(); + final ASTAccessVisibility visibility; + switch(baseSpecifier.getVisibility()) { + case ICPPASTBaseSpecifier.v_public: + visibility= ASTAccessVisibility.PUBLIC; + break; + case ICPPASTBaseSpecifier.v_protected: + visibility= ASTAccessVisibility.PROTECTED; + break; + case ICPPASTBaseSpecifier.v_private: + visibility= ASTAccessVisibility.PRIVATE; + break; + default: + visibility= ASTAccessVisibility.PUBLIC; + } + element.addSuperClass(ASTStringUtil.getSimpleName(baseName), visibility); + } + } + + element.setTypeName(type); + + // add to parent + parent.addChild(element); + // set positions + if(!isTemplate){ + setBodyPosition(element, compositeTypeSpecifier); + } + if (className.length() > 0) { + setIdentifierPosition(element, astClassName); + } else { + final IASTFileLocation classLocation= getMinFileLocation(compositeTypeSpecifier.getNodeLocations()); + if (classLocation != null) { + if (compositeTypeSpecifier.getStorageClass() == IASTDeclSpecifier.sc_typedef) { + // fix positions for typedef struct (heuristically) + final int delta= Keywords.TYPEDEF.length() + 1; + element.setIdPos(classLocation.getNodeOffset() + delta, type.length()); + if(!isTemplate){ + final SourceManipulationInfo info= element.getSourceManipulationInfo(); + info.setPos(info.getStartPos() + delta, info.getLength() - delta); + } + } else { + element.setIdPos(classLocation.getNodeOffset(), type.length()); + } + } + } + // add members + pushDefaultVisibility(defaultVisibility); + try { + final IASTDeclaration[] memberDeclarations= compositeTypeSpecifier.getMembers(); + for (int i= 0; i < memberDeclarations.length; i++) { + IASTDeclaration member= memberDeclarations[i]; + createDeclaration(element, member); + } + } finally { + popDefaultVisibility(); + } + return element; + } + + private TypeDef createTypeDef(Parent parent, IASTDeclSpecifier declSpecifier, IASTDeclarator declarator) throws CModelException{ + IASTDeclarator nestedDeclarator= declarator; + while (nestedDeclarator.getNestedDeclarator() != null) { + nestedDeclarator= nestedDeclarator.getNestedDeclarator(); + } + final IASTName astTypedefName= nestedDeclarator.getName(); + if (astTypedefName == null) { + return null; + } + // create the element + String name= ASTStringUtil.getSimpleName(astTypedefName); + + TypeDef element= new TypeDef(parent, name); + + String typeName= ASTStringUtil.getSignatureString(declSpecifier, declarator); + element.setTypeName(typeName); + + // add to parent + parent.addChild(element); + + // set positions + if (name.length() > 0) { + setIdentifierPosition(element, astTypedefName); + } else { + setIdentifierPosition(element, declSpecifier); + } + setBodyPosition(element, declSpecifier.getParent()); + + return element; + } + + private VariableDeclaration createVariable(Parent parent, IASTDeclSpecifier specifier, IASTDeclarator declarator, boolean isTemplate) throws CModelException { + if (declarator == null) { + return null; + } + IASTDeclarator nestedDeclarator= declarator; + while (nestedDeclarator.getNestedDeclarator() != null) { + nestedDeclarator= nestedDeclarator.getNestedDeclarator(); + } + final IASTName astVariableName= nestedDeclarator.getName(); + if (astVariableName == null) { + return null; + } + final String variableName= ASTStringUtil.getQualifiedName(astVariableName); + + final VariableDeclaration element; + if (declarator instanceof IASTFieldDeclarator || parent instanceof IStructure + || CModelBuilder2.getScope(astVariableName) instanceof ICPPClassScope) { + // field + Field newElement= new Field(parent, variableName); + if (specifier instanceof ICPPASTDeclSpecifier) { + final ICPPASTDeclSpecifier cppSpecifier= (ICPPASTDeclSpecifier)specifier; + newElement.setMutable(cppSpecifier.getStorageClass() == ICPPASTDeclSpecifier.sc_mutable); + newElement.setVisibility(getCurrentVisibility()); + } + element= newElement; + } else { + if (isTemplate) { + // template variable + VariableTemplate newElement= new VariableTemplate(parent, variableName); + element= newElement; + } else { + if (specifier.getStorageClass() == IASTDeclSpecifier.sc_extern) { + // variable declaration + VariableDeclaration newElement= new VariableDeclaration(parent, variableName); + element= newElement; + } else { + // variable + Variable newElement= new Variable(parent, variableName); + element= newElement; + } + } + } + element.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator)); + element.setConst(specifier.isConst()); + element.setVolatile(specifier.isVolatile()); + // TODO [cmodel] correctly resolve isStatic + element.setStatic(specifier.getStorageClass() == IASTDeclSpecifier.sc_static); + // add to parent + parent.addChild(element); + + // set positions + setIdentifierPosition(element, astVariableName); + if (!isTemplate) { + setBodyPosition(element, declarator); + } + return element; + } + + private FunctionDeclaration createFunctionDefinition(Parent parent, IASTFunctionDefinition functionDeclaration, boolean isTemplate) throws CModelException, DOMException { + final IASTFunctionDeclarator declarator= functionDeclaration.getDeclarator(); + IASTDeclarator nestedDeclarator= declarator; + while (nestedDeclarator.getNestedDeclarator() != null) { + nestedDeclarator= nestedDeclarator.getNestedDeclarator(); + } + final IASTName name= nestedDeclarator.getName(); + if (name == null) { + // Something is wrong, skip this element + return null; + } + + final IASTDeclSpecifier declSpecifier= functionDeclaration.getDeclSpecifier(); + + final String functionName= ASTStringUtil.getSimpleName(name); + final String[] parameterTypes= ASTStringUtil.getParameterSignatureArray(declarator); + final String returnType= ASTStringUtil.getTypeString(declSpecifier, declarator); + + final FunctionDeclaration element; + + if(declarator instanceof ICPPASTFunctionDeclarator) { + + final ICPPASTFunctionDeclarator cppFunctionDeclarator= (ICPPASTFunctionDeclarator)declarator; + final IASTName simpleName; + if (name instanceof ICPPASTQualifiedName) { + final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name; + simpleName= quName.getLastName(); + } else { + simpleName= name; + } + IScope scope= null; + // try to avoid expensive resolution of scope and binding + boolean isMethod= parent instanceof IStructure; + if (!isMethod && name instanceof ICPPASTQualifiedName) { + final IASTName[] names= ((ICPPASTQualifiedName)name).getNames(); + if (isTemplate) { + for (int i= 0; i < names.length; i++) { + if (names[i] instanceof ICPPASTTemplateId) { + isMethod= true; + break; + } + } + } + if (!isMethod) { + scope= CPPVisitor.getContainingScope(simpleName); + isMethod= scope instanceof ICPPClassScope; + } + } + if (isMethod) { + // method + final MethodDeclaration methodElement; + if (isTemplate) { + methodElement= new MethodTemplate(parent, ASTStringUtil.getQualifiedName(name)); + } else { + methodElement= new Method(parent, ASTStringUtil.getQualifiedName(name)); + } + element= methodElement; + final ICPPMethod methodBinding; + if (scope != null) { + methodBinding= (ICPPMethod)simpleName.getBinding(); + } else { + methodBinding= null; + } + if (methodBinding != null) { + methodElement.setVirtual(methodBinding.isVirtual()); + methodElement.setInline(methodBinding.isInline()); + methodElement.setFriend(((ICPPASTDeclSpecifier)declSpecifier).isFriend()); + methodElement.setVolatile(cppFunctionDeclarator.isVolatile()); + methodElement.setVisibility(adaptVisibilityConstant(methodBinding.getVisibility())); + methodElement.setConst(cppFunctionDeclarator.isConst()); + methodElement.setPureVirtual(false); + methodElement.setConstructor(methodBinding instanceof ICPPConstructor); + methodElement.setDestructor(methodBinding.isDestructor()); + } else { + if (declSpecifier instanceof ICPPASTDeclSpecifier) { + final ICPPASTDeclSpecifier cppDeclSpecifier= (ICPPASTDeclSpecifier)declSpecifier; + methodElement.setVirtual(cppDeclSpecifier.isVirtual()); + methodElement.setInline(cppDeclSpecifier.isInline()); + methodElement.setFriend(cppDeclSpecifier.isFriend()); + } + methodElement.setVolatile(cppFunctionDeclarator.isVolatile()); + methodElement.setVisibility(getCurrentVisibility()); + methodElement.setConst(cppFunctionDeclarator.isConst()); + methodElement.setPureVirtual(false); + final boolean isConstructor; + if (scope != null) { + isConstructor= CPPVisitor.isConstructor(scope, declarator); + } else { + isConstructor= parent.getElementName().equals(functionName); + } + methodElement.setConstructor(isConstructor); + methodElement.setDestructor(functionName.charAt(0) == '~'); + } + } else { + if (isTemplate) { + // template function + element= new FunctionTemplate(parent, ASTStringUtil.getQualifiedName(name)); + } else { + // function + element= new Function(parent, ASTStringUtil.getQualifiedName(name)); + } + } + + } else { + element= new Function(parent, functionName); + } + + element.setParameterTypes(parameterTypes); + element.setReturnType(returnType); + // TODO [cmodel] correctly resolve isStatic + element.setStatic(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static); + + // add to parent + parent.addChild(element); + + // set positions + setIdentifierPosition(element, name); + if (!isTemplate) { + setBodyPosition(element, functionDeclaration); + } + return element; + } + + private FunctionDeclaration createFunctionDeclaration(Parent parent, IASTDeclSpecifier declSpecifier, IASTFunctionDeclarator declarator, boolean isTemplate) throws CModelException { + IASTDeclarator nestedDeclarator= declarator; + while (nestedDeclarator.getNestedDeclarator() != null) { + nestedDeclarator= nestedDeclarator.getNestedDeclarator(); + } + final IASTName name= nestedDeclarator.getName(); + if (name == null) { + // Something is wrong, skip this element + return null; + } + + final String functionName= ASTStringUtil.getSimpleName(name); + final String[] parameterTypes= ASTStringUtil.getParameterSignatureArray(declarator); + final String returnType= ASTStringUtil.getTypeString(declSpecifier, declarator); + + final FunctionDeclaration element; + + if(declarator instanceof ICPPASTFunctionDeclarator) { + final ICPPASTFunctionDeclarator cppFunctionDeclarator= (ICPPASTFunctionDeclarator)declarator; + if (parent instanceof IStructure) { + // method + final MethodDeclaration methodElement; + if (isTemplate) { + methodElement= new MethodTemplateDeclaration(parent, functionName); + } else { + methodElement= new MethodDeclaration(parent, functionName); + } + element= methodElement; + if (declSpecifier instanceof ICPPASTDeclSpecifier) { + final ICPPASTDeclSpecifier cppDeclSpecifier= (ICPPASTDeclSpecifier)declSpecifier; + methodElement.setVirtual(cppDeclSpecifier.isVirtual()); + methodElement.setInline(cppDeclSpecifier.isInline()); + methodElement.setFriend(cppDeclSpecifier.isFriend()); + } + methodElement.setVolatile(cppFunctionDeclarator.isVolatile()); + methodElement.setVisibility(getCurrentVisibility()); + methodElement.setConst(cppFunctionDeclarator.isConst()); + methodElement.setPureVirtual(cppFunctionDeclarator.isPureVirtual()); + methodElement.setConstructor(functionName.equals(parent.getElementName())); + methodElement.setDestructor(functionName.charAt(0) == '~'); + } else { + if (isTemplate) { + element= new FunctionTemplateDeclaration(parent, functionName); + } else { + element= new FunctionDeclaration(parent, functionName); + } + } + } else if (declarator instanceof IASTStandardFunctionDeclarator) { + if (isTemplate) { + element= new FunctionTemplateDeclaration(parent, functionName); + } else { + element= new FunctionDeclaration(parent, functionName); + } + } else { + assert false; + return null; + } + + element.setParameterTypes(parameterTypes); + element.setReturnType(returnType); + // TODO [cmodel] correctly resolve isStatic + element.setStatic(declSpecifier.getStorageClass() == IASTDeclSpecifier.sc_static); + + // add to parent + parent.addChild(element); + + // hook up the offsets + setIdentifierPosition(element, name); + if (!isTemplate) { + setBodyPosition(element, declarator); + } + return element; + } + + private Using createUsingDirective(Parent parent, ICPPASTUsingDirective usingDirDeclaration) throws CModelException{ + // create the element + IASTName name= usingDirDeclaration.getQualifiedName(); + Using element= new Using(parent, ASTStringUtil.getQualifiedName(name), true); + + // add to parent + parent.addChild(element); + + // set positions + setIdentifierPosition(element, name); + setBodyPosition(element, usingDirDeclaration); + return element; + } + + private Using createUsingDeclaration(Parent parent, ICPPASTUsingDeclaration usingDeclaration) throws CModelException{ + // create the element + IASTName name= usingDeclaration.getName(); + Using element= new Using(parent, ASTStringUtil.getSimpleName(name), false); + + // add to parent + parent.addChild(element); + + // set positions + setIdentifierPosition(element, name); + setBodyPosition(element, usingDeclaration); + return element; + } + + /** + * Utility method to set the body position of an element from an AST node. + * + * @param element + * @param astNode + */ + private void setBodyPosition(SourceManipulation element, IASTNode astNode) { + final IASTFileLocation location= astNode.getFileLocation(); + if (location != null) { + element.setPos(location.getNodeOffset(), location.getNodeLength()); + element.setLines(location.getStartingLineNumber(), location.getEndingLineNumber()); + } else { + final IASTNodeLocation[] locations= astNode.getNodeLocations(); + final IASTFileLocation minLocation= getMinFileLocation(locations); + if (minLocation != null) { + final IASTFileLocation maxLocation= getMaxFileLocation(locations); + if (maxLocation != null) { + final int startOffset= minLocation.getNodeOffset(); + final int endOffset= maxLocation.getNodeOffset() + maxLocation.getNodeLength(); + element.setPos(startOffset, endOffset - startOffset); + final int startLine= minLocation.getStartingLineNumber(); + final int endLine= maxLocation.getEndingLineNumber(); + element.setLines(startLine, endLine); + } + } + } + } + + /** + * Utility method to set the identifier position of an element from an AST name. + * + * @param element + * @param astName + */ + private void setIdentifierPosition(SourceManipulation element, IASTNode astName) { + final IASTFileLocation location= astName.getFileLocation(); + if (location != null) { + element.setIdPos(location.getNodeOffset(), location.getNodeLength()); + } else { + final IASTNodeLocation[] locations= astName.getNodeLocations(); + final IASTFileLocation minLocation= getMinFileLocation(locations); + if (minLocation != null) { + final IASTFileLocation maxLocation= getMaxFileLocation(locations); + if (maxLocation != null) { + final int startOffset= minLocation.getNodeOffset(); + final int endOffset= maxLocation.getNodeOffset() + maxLocation.getNodeLength(); + element.setIdPos(startOffset, endOffset - startOffset); + } + } + } + } + + private static IASTFileLocation getMaxFileLocation(IASTNodeLocation[] locations) { + if (locations == null || locations.length == 0) { + return null; + } + final IASTNodeLocation nodeLocation= locations[locations.length-1]; + if (nodeLocation instanceof IASTFileLocation) { + return (IASTFileLocation)nodeLocation; + } else if (nodeLocation instanceof IASTMacroExpansion) { + IASTNodeLocation[] macroLocations= ((IASTMacroExpansion)nodeLocation).getExpansionLocations(); + return getMaxFileLocation(macroLocations); + } + return null; + } + + private static IASTFileLocation getMinFileLocation(IASTNodeLocation[] locations) { + if (locations == null || locations.length == 0) { + return null; + } + final IASTNodeLocation nodeLocation= locations[0]; + if (nodeLocation instanceof IASTFileLocation) { + return (IASTFileLocation)nodeLocation; + } else if (nodeLocation instanceof IASTMacroExpansion) { + IASTNodeLocation[] macroLocations= ((IASTMacroExpansion)nodeLocation).getExpansionLocations(); + return getMinFileLocation(macroLocations); + } + return null; + } + + /** + * Handle the special "declaration" visibility label + * @param visibilityLabel + */ + private void handleVisibilityLabel(ICPPASTVisiblityLabel visibilityLabel) { + setCurrentVisibility(adaptVisibilityConstant(visibilityLabel.getVisibility())); + } + + /** + * Convert the given ICPPASTVisiblityLabel visibility constant + * into an ASTAccessVisibility. + * + * @param visibility + * @return the corresponding ASTAccessVisibility + */ + private ASTAccessVisibility adaptVisibilityConstant(int visibility) { + switch(visibility) { + case ICPPASTVisiblityLabel.v_public: + return ASTAccessVisibility.PUBLIC; + case ICPPASTVisiblityLabel.v_protected: + return ASTAccessVisibility.PROTECTED; + case ICPPASTVisiblityLabel.v_private: + return ASTAccessVisibility.PRIVATE; + } + assert false : "Unknown visibility"; //$NON-NLS-1$ + return ASTAccessVisibility.PUBLIC; + } + + private void setCurrentVisibility(ASTAccessVisibility visibility) { + fCurrentVisibility= visibility; + } + private ASTAccessVisibility getCurrentVisibility() { + if (fCurrentVisibility == null) { + return ASTAccessVisibility.PUBLIC; + } + return fCurrentVisibility; + } + + /** + * Pop the default visibility from the outer scope. + */ + private void popDefaultVisibility() { + if (!fVisibilityStack.isEmpty()) { + setCurrentVisibility((ASTAccessVisibility)fVisibilityStack.pop()); + } + } + + /** + * Push given visibility as default class/struct/union visibility. + * + * @param visibility + */ + private void pushDefaultVisibility(ASTAccessVisibility visibility) { + fVisibilityStack.push(getCurrentVisibility()); + setCurrentVisibility(visibility); + } + + /** + * Determine the scope for given name. + * + * @param astName + * @return the scope or null + */ + private static IScope getScope(IASTName astName) { + IBinding binding= astName.getBinding(); + if (binding != null) { + try { + return binding.getScope(); + } catch (DOMException e) { + return null; + } + } + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index aaade6ecadf..eef532a379a 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -392,28 +392,18 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return (WorkingCopy) perFactoryWorkingCopies.get(this); } - /** - * To be removed with the new model builder in place - * @param newElements - * @param element + /* + * @see org.eclipse.cdt.internal.core.model.Openable#isOpen() */ - private void getNewElements(Map mapping, CElement element) { - Object info = null; - try { - info = element.getElementInfo(); - } catch (CModelException e) { - } - if (info != null) { - if (element instanceof IParent) { - ICElement[] children = ((CElementInfo) info).getChildren(); - int size = children.length; - for (int i = 0; i < size; ++i) { - CElement child = (CElement) children[i]; - getNewElements(mapping, child); - } - } - } - mapping.put(element, info); + public synchronized boolean isOpen() { + return super.isOpen(); + } + + /* + * @see org.eclipse.cdt.internal.core.model.CElement#getElementInfo(org.eclipse.core.runtime.IProgressMonitor) + */ + public synchronized CElementInfo getElementInfo(IProgressMonitor monitor) throws CModelException { + return super.getElementInfo(monitor); } /* (non-Javadoc) @@ -582,13 +572,11 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return buffer; } + /* + * @see org.eclipse.cdt.core.model.ITranslationUnit#parse() + */ public Map parse() { - Map map = new HashMap(); - try { - getNewElements(map, this); - } catch (Exception e) { - } - return map; + throw new UnsupportedOperationException("Deprecated method"); //$NON-NLS-1$ } /** @@ -609,8 +597,12 @@ public class TranslationUnit extends Openable implements ITranslationUnit { */ private void parseUsingCModelBuilder(Map newElements, boolean quickParseMode) { try { - CModelBuilder modelBuilder = new CModelBuilder(this, newElements); - modelBuilder.parse(quickParseMode); + boolean useNewModelBuilder= CCorePlugin.getDefault().useNewModelBuilder(); + if (useNewModelBuilder) { + new CModelBuilder2(this).parse(quickParseMode); + } else { + new CModelBuilder(this, newElements).parse(quickParseMode); + } } catch (Exception e) { // use the debug log for this exception. Util.debugLog( "Exception in CModelBuilder", IDebugLogConstants.MODEL); //$NON-NLS-1$ @@ -748,10 +740,16 @@ public class TranslationUnit extends Openable implements ITranslationUnit { } } + /* + * @see org.eclipse.cdt.core.model.ITranslationUnit#getAST() + */ public IASTTranslationUnit getAST() throws CoreException { return getAST(null, 0); } + /* + * @see org.eclipse.cdt.core.model.ITranslationUnit#getAST(org.eclipse.cdt.core.index.IIndex, int) + */ public IASTTranslationUnit getAST(IIndex index, int style) throws CoreException { ICodeReaderFactory codeReaderFactory; if (index != null && (style & (ITranslationUnit.AST_SKIP_INDEXED_HEADERS | ITranslationUnit.AST_SKIP_ALL_HEADERS)) != 0) { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java index e070cc9bd0d..0056e65d299 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java @@ -82,6 +82,7 @@ public class CCorePlugin extends Plugin { public final static String DEFAULT_BINARY_PARSER_SIMPLE_ID = "ELF"; //$NON-NLS-1$ public final static String DEFAULT_BINARY_PARSER_UNIQ_ID = PLUGIN_ID + "." + DEFAULT_BINARY_PARSER_SIMPLE_ID; //$NON-NLS-1$ public final static String PREF_USE_STRUCTURAL_PARSE_MODE = "useStructualParseMode"; //$NON-NLS-1$ + public final static String PREF_USE_NEW_MODEL_BUILDER = "useNewModelBuilder"; //$NON-NLS-1$ public static final String INDEXER_SIMPLE_ID = "CIndexer"; //$NON-NLS-1$ public static final String INDEXER_UNIQ_ID = PLUGIN_ID + "." + INDEXER_SIMPLE_ID; //$NON-NLS-1$ @@ -318,7 +319,7 @@ public class CCorePlugin extends Plugin { cdtLog = new CDTLogWriter(CCorePlugin.getDefault().getStateLocation().append(".log").toFile()); //$NON-NLS-1$ //Set debug tracing options - CCorePlugin.getDefault().configurePluginDebugOptions(); + configurePluginDebugOptions(); fDescriptorManager.startup(); @@ -332,6 +333,8 @@ public class CCorePlugin extends Plugin { // Set the default for using the structual parse mode to build the CModel getPluginPreferences().setDefault(PREF_USE_STRUCTURAL_PARSE_MODE, false); + // Set the default for using the new model builder to build the CModel + getPluginPreferences().setDefault(PREF_USE_NEW_MODEL_BUILDER, true); PositionTrackerManager.getInstance().install(); } @@ -986,6 +989,16 @@ public class CCorePlugin extends Plugin { return getPluginPreferences().getBoolean(PREF_USE_STRUCTURAL_PARSE_MODE); } + // Preference to turn on/off the use of the new model builder to build the CModel + public void setUseNewModelBuilder(boolean useNewModelBuilder) { + getPluginPreferences().setValue(PREF_USE_NEW_MODEL_BUILDER, useNewModelBuilder); + savePluginPreferences(); + } + + public boolean useNewModelBuilder() { + return getPluginPreferences().getBoolean(PREF_USE_NEW_MODEL_BUILDER); + } + public CDOM getDOM() { return CDOM.getInstance(); } diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 88011c52cd5..bc20f7f550e 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -647,12 +647,12 @@ class="org.eclipse.cdt.internal.ui.preferences.IndexerPreferencePage" id="org.eclipse.cdt.ui.preferences.IndexerPreferencePage" name="%indexerPrefName"/> - + diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java index ca67f720c51..759381d90fb 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/WorkInProgressPreferencePage.java @@ -28,6 +28,7 @@ import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.ui.CUIPlugin; /** @@ -83,7 +84,8 @@ public class WorkInProgressPreferencePage extends PreferencePage implements IWor result.setLayout(layout); // Add your controls here - + addCheckBox(result, "Use new model builder", CCorePlugin.PREF_USE_NEW_MODEL_BUILDER); //$NON-NLS-1$ + applyDialogFont(result); return result; } @@ -155,12 +157,15 @@ public class WorkInProgressPreferencePage extends PreferencePage implements IWor String key= (String) text.getData(); store.setValue(key, text.getText()); } - + CCorePlugin.getDefault().setUseNewModelBuilder(store.getBoolean(CCorePlugin.PREF_USE_NEW_MODEL_BUILDER)); CUIPlugin.getDefault().savePluginPreferences(); return super.performOk(); } public static void initDefaults(IPreferenceStore store) { // Initialize your defaults here + boolean coreDefault= CCorePlugin.getDefault().getPluginPreferences().getDefaultBoolean(CCorePlugin.PREF_USE_NEW_MODEL_BUILDER); + store.setDefault(CCorePlugin.PREF_USE_NEW_MODEL_BUILDER, coreDefault); + CCorePlugin.getDefault().setUseNewModelBuilder(store.getBoolean(CCorePlugin.PREF_USE_NEW_MODEL_BUILDER)); } }