From 0751a71a3a74f163605efc633a9049eeb87be243 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Tue, 17 May 2005 18:40:38 +0000 Subject: [PATCH] GCC builtin functions via implicit bindings stored on translation unit scope. by Devin Steffler with small changes --- .../core/parser/tests/ast2/AST2BaseTest.java | 49 + .../parser/tests/ast2/AST2CPPSpecTest.java | 8 +- .../tests/ast2/AST2SelectionParseTest.java | 24 +- .../parser/tests/ast2/AST2SpecBaseTest.java | 6 + .../core/parser/tests/ast2/AST2UtilTests.java | 2 +- .../parser/tests/ast2/DOMLocationTests.java | 2 +- .../parser/tests/ast2/DOMParserTestSuite.java | 1 + .../ast2/GCCCompleteParseExtensionsTest.java | 295 ++++++ .../cdt/core/dom/ast/ASTSignatureUtil.java | 6 + .../dom/ast/IASTBuiltinSymbolProvider.java | 29 + .../org/eclipse/cdt/core/dom/ast/IScope.java | 9 + .../parser/AbstractGNUSourceCodeParser.java | 9 +- .../dom/parser/GCCBuiltinSymbolProvider.java | 998 ++++++++++++++++++ .../core/dom/parser/ProblemBinding.java | 4 + .../c/ANSICParserExtensionConfiguration.java | 16 +- .../core/dom/parser/c/CImplicitFunction.java | 91 ++ .../core/dom/parser/c/CImplicitTypedef.java | 107 ++ .../internal/core/dom/parser/c/CScope.java | 12 + .../parser/c/{CTypeDef.java => CTypedef.java} | 4 +- .../internal/core/dom/parser/c/CVisitor.java | 7 +- .../c/GCCParserExtensionConfiguration.java | 7 + .../core/dom/parser/c/GNUCSourceParser.java | 21 +- .../c/ICParserExtensionConfiguration.java | 11 +- .../ANSICPPParserExtensionConfiguration.java | 15 +- .../dom/parser/cpp/CPPClassInstanceScope.java | 19 + .../core/dom/parser/cpp/CPPClassScope.java | 18 +- .../dom/parser/cpp/CPPImplicitFunction.java | 153 +++ .../dom/parser/cpp/CPPImplicitMethod.java | 149 +-- .../dom/parser/cpp/CPPImplicitTypedef.java | 169 +++ .../core/dom/parser/cpp/CPPScope.java | 19 + .../core/dom/parser/cpp/CPPSemantics.java | 13 +- .../core/dom/parser/cpp/CPPTypedef.java | 3 +- .../core/dom/parser/cpp/CPPUnknownScope.java | 4 + .../dom/parser/cpp/GNUCPPSourceParser.java | 17 +- .../cpp/GPPParserExtensionConfiguration.java | 16 +- .../cpp/ICPPParserExtensionConfiguration.java | 4 +- 36 files changed, 2148 insertions(+), 169 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBuiltinSymbolProvider.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitFunction.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/{CTypeDef.java => CTypedef.java} (96%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitTypedef.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index d8b206e7d17..58a3e3722ae 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -38,6 +38,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; @@ -326,4 +327,52 @@ public class AST2BaseTest extends TestCase { protected void isParameterTypeEqual(IFunctionType fType, String str) { assertEquals(str, ASTTypeUtil.getParameterTypeString(fType)); } + + static protected class CNameResolver extends CASTVisitor { + { + shouldVisitNames = true; + } + public int numProblemBindings=0; + public int numNullBindings=0; + public List nameList = new ArrayList(); + public int visit( IASTName name ){ + nameList.add( name ); + IBinding binding = name.resolveBinding(); + if (binding instanceof IProblemBinding) + numProblemBindings++; + if (binding == null) + numNullBindings++; + return PROCESS_CONTINUE; + } + public IASTName getName( int idx ){ + if( idx < 0 || idx >= nameList.size() ) + return null; + return (IASTName) nameList.get( idx ); + } + public int size() { return nameList.size(); } + } + + static protected class CPPNameResolver extends CPPASTVisitor { + { + shouldVisitNames = true; + } + public int numProblemBindings=0; + public int numNullBindings=0; + public List nameList = new ArrayList(); + public int visit( IASTName name ){ + nameList.add( name ); + IBinding binding = name.resolveBinding(); + if (binding instanceof IProblemBinding) + numProblemBindings++; + if (binding == null) + numNullBindings++; + return PROCESS_CONTINUE; + } + public IASTName getName( int idx ){ + if( idx < 0 || idx >= nameList.size() ) + return null; + return (IASTName) nameList.get( idx ); + } + public int size() { return nameList.size(); } + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index da81bf6eaf6..bc8374a6583 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -173,10 +173,10 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { */ public void test3_2s4() throws Exception { StringBuffer buffer = new StringBuffer(); - buffer.append("struct X; // declare X as a struct type\n"); //$NON-NLS-1$ - buffer.append("struct X* x1; // use X in pointer formation\n"); //$NON-NLS-1$ - buffer.append("X* x2; // use X in pointer formation\n"); //$NON-NLS-1$ - parseCandCPP(buffer.toString(), true, 0); + buffer.append("struct X; // declare X as a struct type\n"); //$NON-NLS-1$ + buffer.append("struct X* x1; // use X in pointer formation\n"); //$NON-NLS-1$ + buffer.append("X* x2; // use X in pointer formation\n"); //$NON-NLS-1$ + parse(buffer.toString(), ParserLanguage.CPP, true, 0); } /** diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java index 732f83aac6b..063fad473b0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SelectionParseTest.java @@ -1102,7 +1102,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("x;"); //$NON-NLS-1$ int length = "x".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTDeclarator); assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$ @@ -1121,7 +1121,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("x;"); //$NON-NLS-1$ int length = "x".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTDeclarator); assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$ @@ -1140,7 +1140,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("char x;"); //$NON-NLS-1$ int length = "char x;".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTSimpleDeclaration); assertEquals( ((IASTSimpleDeclaration)node).getDeclarators()[0].getName().toString(), "x" ); //$NON-NLS-1$ @@ -1160,7 +1160,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("y;"); //$NON-NLS-1$ int length = "y".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTDeclarator); assertEquals(((IASTDeclarator)node).getName().toString(), "y"); //$NON-NLS-1$ @@ -1181,7 +1181,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("c x;"); //$NON-NLS-1$ int length = "c".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTNamedTypeSpecifier); assertEquals(((IASTNamedTypeSpecifier)node).getName().toString(), "c"); //$NON-NLS-1$ @@ -1192,7 +1192,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { index = code.indexOf("x;"); //$NON-NLS-1$ length = "x".length(); //$NON-NLS-1$ - node = parse( code, ParserLanguage.C, index, length ); + node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTDeclarator); assertEquals(((IASTDeclarator)node).getName().toString(), "x"); //$NON-NLS-1$ @@ -1242,7 +1242,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { index = code.indexOf("c[2]"); //$NON-NLS-1$ length = "c".length(); //$NON-NLS-1$ - node = parse( code, ParserLanguage.C, index, length ); + node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTName); name = (IASTName)node; @@ -1261,7 +1261,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("list[]"); //$NON-NLS-1$ int length = "list".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTName); IASTName name = (IASTName)node; @@ -1272,13 +1272,13 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { index = code.indexOf("[]"); //$NON-NLS-1$ length = "[]".length(); //$NON-NLS-1$ - node = parse( code, ParserLanguage.C, index, length ); + node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTArrayModifier); index = code.indexOf("*const list[]"); //$NON-NLS-1$ length = "*const".length(); //$NON-NLS-1$ - node = parse( code, ParserLanguage.C, index, length ); + node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTPointer); } @@ -1291,7 +1291,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { String code = buffer.toString(); int index = code.indexOf("b,a"); //$NON-NLS-1$ int length = "b".length(); //$NON-NLS-1$ - IASTNode node = parse( code, ParserLanguage.C, index, length ); + IASTNode node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTDeclarator); IASTName name = ((IASTDeclarator)node).getName(); @@ -1338,7 +1338,7 @@ public class AST2SelectionParseTest extends AST2SelectionParseBaseTest { index = code.indexOf("lemp->symbols") + 6; //$NON-NLS-1$ length = "symbols".length(); //$NON-NLS-1$ - node = parse( code, ParserLanguage.C, index, length ); + node = parse( code, ParserLanguage.C, true, true, index, length ); assertNotNull(node); assertTrue(node instanceof IASTName); name = (IASTName)node; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java index 951405814f9..4ab8d3cd3a8 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java @@ -171,12 +171,15 @@ public class AST2SpecBaseTest extends TestCase { shouldVisitNames = true; } public int numProblemBindings=0; + public int numNullBindings=0; public List nameList = new ArrayList(); public int visit( IASTName name ){ nameList.add( name ); IBinding binding = name.resolveBinding(); if (binding instanceof IProblemBinding) numProblemBindings++; + if (binding == null) + numNullBindings++; return PROCESS_CONTINUE; } public IASTName getName( int idx ){ @@ -192,12 +195,15 @@ public class AST2SpecBaseTest extends TestCase { shouldVisitNames = true; } public int numProblemBindings=0; + public int numNullBindings=0; public List nameList = new ArrayList(); public int visit( IASTName name ){ nameList.add( name ); IBinding binding = name.resolveBinding(); if (binding instanceof IProblemBinding) numProblemBindings++; + if (binding == null) + numNullBindings++; return PROCESS_CONTINUE; } public IASTName getName( int idx ){ diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2UtilTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2UtilTests.java index 6066501301f..db5438c038d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2UtilTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2UtilTests.java @@ -141,7 +141,7 @@ public class AST2UtilTests extends AST2BaseTest { buff.append("int foo(x, y) char x; int y; {}\n"); //$NON-NLS-1$ buff.append("int foo2(char x, int y) {}\n"); //$NON-NLS-1$ - IASTTranslationUnit tu = parse(buff.toString(), ParserLanguage.C); + IASTTranslationUnit tu = parse(buff.toString(), ParserLanguage.C, true); IASTDeclaration[] d = tu.getDeclarations(); String fooSignature = ASTSignatureUtil.getSignature(((IASTFunctionDefinition)d[0]).getDeclarator()); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java index 9123804aef7..7dfa9397dba 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java @@ -185,7 +185,7 @@ public class DOMLocationTests extends AST2BaseTest { public void testBug83664() throws Exception { String code = "int foo(x) int x; {\n return x;\n }\n"; //$NON-NLS-1$ - IASTTranslationUnit tu = parse(code, ParserLanguage.C); + IASTTranslationUnit tu = parse(code, ParserLanguage.C, true); IASTDeclaration[] declarations = tu.getDeclarations(); assertEquals(declarations.length, 1); IASTFunctionDefinition definition = (IASTFunctionDefinition) declarations[0]; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index 9b613fb6f85..2da6e8e2572 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -43,6 +43,7 @@ public class DOMParserTestSuite extends TestCase { suite.addTestSuite( AST2CSpecTest.class ); suite.addTestSuite( AST2CSpecFailingTest.class ); suite.addTestSuite( DOMSelectionParseTest.class ); + suite.addTestSuite( GCCCompleteParseExtensionsTest.class ); suite.addTest( CompletionTestSuite.suite() ); return suite; } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java new file mode 100644 index 00000000000..396b1d97887 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/GCCCompleteParseExtensionsTest.java @@ -0,0 +1,295 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Canada Ltd. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.tests.ast2; + +import java.io.StringWriter; +import java.io.Writer; + +import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil; +import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +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.gnu.cpp.IGPPASTPointer; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.internal.core.dom.parser.c.CASTFunctionDefinition; +import org.eclipse.cdt.internal.core.dom.parser.c.CFunction; +import org.eclipse.cdt.internal.core.parser.ParserException; + +/** + * @author jcamelon + * + */ +public class GCCCompleteParseExtensionsTest extends AST2BaseTest { + + private IASTTranslationUnit parseGCC(String code) throws ParserException { + IASTTranslationUnit tu = parse(code, ParserLanguage.C, true, true); + + CNameResolver resolver = new CNameResolver(); + tu.accept(resolver); + if (resolver.numProblemBindings > 0) + throw new ParserException(" there are " + resolver.numProblemBindings + " ProblemBindings on the tu"); //$NON-NLS-1$ //$NON-NLS-2$ + if (resolver.numNullBindings > 0) + throw new ParserException("Expected no null bindings, encountered " + resolver.numNullBindings); //$NON-NLS-1$ + + return tu; + } + + private IASTTranslationUnit parseGPP(String code) throws ParserException { + IASTTranslationUnit tu = parse(code, ParserLanguage.CPP, true, true); + + CPPNameResolver resolver = new CPPNameResolver(); + tu.accept(resolver); + if (resolver.numProblemBindings > 0) + throw new ParserException(" there are " + resolver.numProblemBindings + " ProblemBindings on the tu"); //$NON-NLS-1$ //$NON-NLS-2$ + if (resolver.numNullBindings > 0) + throw new ParserException("Expected no null bindings, encountered " + resolver.numNullBindings); //$NON-NLS-1$ + + return tu; + } + + public void testBug39695() throws Exception + { + parseGCC("int a = __alignof__ (int);").getDeclarations(); //$NON-NLS-1$ + } + + public void testBug39684() throws Exception + { + IASTDeclaration bar = parseGCC("typeof(foo(1)) bar () { return foo(1); }").getDeclarations()[0]; //$NON-NLS-1$ + assertTrue(bar instanceof CASTFunctionDefinition); + CFunction barFunc = (CFunction)((CASTFunctionDefinition)bar).getDeclarator().getName().resolveBinding(); + IFunctionType type = barFunc.getType(); + + // TODO Devin typeof declSpec has 0 length, also doesn't seem to have a type for typeof... raise a bug +// IASTSimpleTypeSpecifier simpleTypeSpec = ((IASTSimpleTypeSpecifier)bar.getReturnType().getTypeSpecifier()); +// assertEquals( simpleTypeSpec.getType(), IASTGCCSimpleTypeSpecifier.Type.TYPEOF ); + } + + public void testBug39698A() throws Exception + { + IASTDeclaration[] decls = parseGPP("int a=0; \n int b=1; \n int c = a ? b;").getDeclarations(); //$NON-NLS-1$ + assertEquals( ASTSignatureUtil.getExpressionString( ((IASTInitializerExpression)((IASTSimpleDeclaration)decls[2]).getDeclarators()[0].getInitializer()).getExpression() ), "a >? b" ); //$NON-NLS-1$ + } + + public void testPredefinedSymbol_bug69791() throws Exception { + parseGPP("typedef __builtin_va_list __gnuc_va_list; \n").getDeclarations();//$NON-NLS-1$ + parseGCC("typedef __builtin_va_list __gnuc_va_list; \n").getDeclarations();//$NON-NLS-1$ + } + + public void testBug39697() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "__asm__( \"CODE\" );\n" ); //$NON-NLS-1$ + writer.write( "__inline__ int foo() { return 4; }\n"); //$NON-NLS-1$ + writer.write( "__const__ int constInt;\n"); //$NON-NLS-1$ + writer.write( "__volatile__ int volInt;\n"); //$NON-NLS-1$ + writer.write( "__signed__ int signedInt;\n"); //$NON-NLS-1$ + IASTDeclaration[] decls = parseGCC( writer.toString() ).getDeclarations(); + + assertEquals(((IASTASMDeclaration)decls[0]).getAssembly(), "CODE"); //$NON-NLS-1$ + assertTrue( ((IASTFunctionDefinition)decls[1]).getDeclSpecifier().isInline() ); + assertTrue( ((IASTSimpleDeclaration)decls[2]).getDeclSpecifier().isConst() ); + assertTrue( ((IASTSimpleDeclaration)decls[3]).getDeclSpecifier().isVolatile() ); + assertTrue( ((ICASTSimpleDeclSpecifier)((IASTSimpleDeclaration)decls[4]).getDeclSpecifier()).isSigned() ); + + writer = new StringWriter(); + writer.write( "int * __restrict__ resPointer1;\n"); //$NON-NLS-1$ + writer.write( "int * __restrict resPointer2;\n"); //$NON-NLS-1$ + decls = parseGCC( writer.toString() ).getDeclarations(); + assertTrue( ((ICASTPointer)((IASTSimpleDeclaration)decls[0]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); + assertTrue( ((ICASTPointer)((IASTSimpleDeclaration)decls[1]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); + + writer = new StringWriter(); + writer.write( "int * __restrict__ resPointer1;\n"); //$NON-NLS-1$ + writer.write( "int * __restrict resPointer2;\n"); //$NON-NLS-1$ + decls = parseGPP( writer.toString() ).getDeclarations(); + assertTrue( ((IGPPASTPointer)((IASTSimpleDeclaration)decls[0]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); + assertTrue( ((IGPPASTPointer)((IASTSimpleDeclaration)decls[1]).getDeclarators()[0].getPointerOperators()[0]).isRestrict() ); + + } + + public void testBug73954A() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write("void f(){ \n");//$NON-NLS-1$ + writer.write(" __builtin_expect( 23, 2); \n");//$NON-NLS-1$ + writer.write(" __builtin_prefetch( (const void *)0, 1, 2); \n");//$NON-NLS-1$ + writer.write(" __builtin_huge_val(); \n");//$NON-NLS-1$ + writer.write(" __builtin_huge_valf(); \n");//$NON-NLS-1$ + writer.write(" __builtin_huge_vall(); \n");//$NON-NLS-1$ + writer.write(" __builtin_inf(); \n");//$NON-NLS-1$ + writer.write(" __builtin_inff(); \n");//$NON-NLS-1$ + writer.write(" __builtin_infl(); \n");//$NON-NLS-1$ + writer.write(" __builtin_nan(\"\"); \n");//$NON-NLS-1$ + writer.write(" __builtin_nanf(\"\"); \n");//$NON-NLS-1$ + writer.write(" __builtin_nanl(\"\"); \n");//$NON-NLS-1$ + writer.write(" __builtin_nans(\"\"); \n");//$NON-NLS-1$ + writer.write(" __builtin_nansf(\"\"); \n");//$NON-NLS-1$ + writer.write(" __builtin_nansl(\"\"); \n");//$NON-NLS-1$ + writer.write(" __builtin_ffs (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_clz (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_ctz (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_popcount (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_parity (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_ffsl (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_clzl (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_ctzl (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_popcountl (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_parityl (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_ffsll (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_clzll (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_ctzll (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_popcountll (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_parityll (0); \n");//$NON-NLS-1$ + writer.write(" __builtin_powi (0, 0); \n");//$NON-NLS-1$ + writer.write(" __builtin_powif (0, 0); \n");//$NON-NLS-1$ + writer.write(" __builtin_powil (0, 0); \n");//$NON-NLS-1$ + writer.write("} \n"); //$NON-NLS-1$ + + parseGCC( writer.toString() ); + } + + public void testBug39686() throws Exception + { + Writer code = new StringWriter(); + code.write("__complex__ double x; // complex double\n"); //$NON-NLS-1$ + code.write("__complex__ short int a; // complex short int\n"); //$NON-NLS-1$ + code.write("__complex__ float y = 2.5fi; // 2.5 imaginary float literal\n"); //$NON-NLS-1$ + code.write("__complex__ int z = 3i; // imaginary intege r literal\n"); //$NON-NLS-1$ + code.write("double v = __real__ x; // real part of expression\n"); //$NON-NLS-1$ + code.write("double w = __imag__ x; // imaginary part of expression\n"); //$NON-NLS-1$ + parseGCC(code.toString()); + } + + public void testBug39551B() throws Exception + { + //this used to be 99.99 * __I__, but I don't know where the __I__ came from, its not in C99, nor in GCC + IASTDeclaration decl = parseGCC("_Imaginary double id = 99.99 * 1i;").getDeclarations()[0]; //$NON-NLS-1$ + // TODO Devin does ICPPASTSimpleDeclSpecifier need something for isImaginary ? + // assertEquals( variable.getName(), "id"); //$NON-NLS-1$ +// assertTrue( ((IASTSimpleTypeSpecifier)variable.getAbstractDeclaration().getTypeSpecifier()).isImaginary() ); + } + + public void testBug39681() throws Exception + { + Writer code = new StringWriter(); + code.write("double\n"); //$NON-NLS-1$ + code.write("foo (double a, double b)\n"); //$NON-NLS-1$ + code.write("{\n"); //$NON-NLS-1$ + code.write(" double square (double z) { return z * z; }\n"); //$NON-NLS-1$ + code.write(" return square (a) + square (b);\n"); //$NON-NLS-1$ + code.write("}\n"); //$NON-NLS-1$ + parseGCC(code.toString()); + } + + public void testBug39677() throws Exception + { + parseGPP("class B { public: B(); int a;}; B::B() : a(({ 1; })) {}"); //$NON-NLS-1$ + Writer writer = new StringWriter(); + writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; }))\n" );//$NON-NLS-1$ + parseGPP( writer.toString() ); + + writer = new StringWriter(); + writer.write( "int x = ({ int foo() { return 1; } int y = foo (); int z;\n" ); //$NON-NLS-1$ + writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ + writer.write( "else z = - y;\n" );//$NON-NLS-1$ + writer.write( "z; });\n" );//$NON-NLS-1$ + parseGPP( writer.toString() ); + + writer = new StringWriter(); + writer.write( "int foo(); \n" ); //$NON-NLS-1$ + writer.write( "typeof({ int y = foo (); \n" ); //$NON-NLS-1$ + writer.write( " int z; \n" ); //$NON-NLS-1$ + writer.write( " if (y > 0) z = y; \n" ); //$NON-NLS-1$ + writer.write( " else z = - y; \n" ); //$NON-NLS-1$ + writer.write( " z; \n" ); //$NON-NLS-1$ + writer.write( " }) zoot; \n" ); //$NON-NLS-1$ + + try { + parseGPP( writer.toString() ); // TODO Devin raised bug 93980 + assertFalse(true); + } catch (Exception e) {} + } + + public void testBug75401() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "#define va_arg __builtin_va_arg \n"); //$NON-NLS-1$ + writer.write( "#define va_list __builtin_va_list \n"); //$NON-NLS-1$ + writer.write( "void main( int argc, char** argv ) { \n"); //$NON-NLS-1$ + writer.write( " va_list v; \n"); //$NON-NLS-1$ + writer.write( " long l = va_arg( v, long ); \n"); //$NON-NLS-1$ + writer.write( "} \n"); //$NON-NLS-1$ + + parseGCC( writer.toString() ); + } + + public void testBug73954B() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "#define foo(x) \\\n"); //$NON-NLS-1$ + writer.write( " __builtin_choose_expr( 1, foo_d(x), (void)0 ) \n"); //$NON-NLS-1$ + writer.write( "int foo_d( int x ); \n"); //$NON-NLS-1$ + writer.write( "int main() { \n"); //$NON-NLS-1$ + writer.write( " if( __builtin_constant_p(1) && \n"); //$NON-NLS-1$ + writer.write( " __builtin_types_compatible_p( 1, 'c') ) \n"); //$NON-NLS-1$ + writer.write( " foo(1); \n"); //$NON-NLS-1$ + writer.write( "} \n"); //$NON-NLS-1$ + + parseGCC( writer.toString()); + } + + public void testGNUExternalTemplate_bug71603() throws Exception { + parseGPP("template \n class A {}; \n extern template class A; \n").getDeclarations(); //$NON-NLS-1$ + } + + public void testBug74190_g_assert_1() throws Exception { + Writer writer = new StringWriter(); + writer.write( "void log( int ); \n"); //$NON-NLS-1$ + writer.write( "void f() { \n"); //$NON-NLS-1$ + writer.write( " int a = 1; \n"); //$NON-NLS-1$ + writer.write( " (void)({ if( a ){ } \n"); //$NON-NLS-1$ + writer.write( " else{ log( a ); } \n"); //$NON-NLS-1$ + writer.write( " }); \n"); //$NON-NLS-1$ + writer.write( "} \n"); //$NON-NLS-1$ + + try { + parseGCC( writer.toString() ); // TODO Devin raised bug 93980 + assertFalse(true); + } catch (Exception e) {} + } + + public void testBug74190_g_return_if_fail() throws Exception { + Writer writer = new StringWriter(); + writer.write( "void f() { \n"); //$NON-NLS-1$ + writer.write( " (void)({ if( ( ({ 0; }) ) ) \n"); //$NON-NLS-1$ + writer.write( " { } \n"); //$NON-NLS-1$ + writer.write( " }); \n"); //$NON-NLS-1$ + writer.write( "} \n"); //$NON-NLS-1$ + + try { + parseGCC( writer.toString() ); // TODO Devin raised bug 93982 + assertFalse(true); + } catch (Exception e) {} + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java index 0a84b0506bc..7aa143fe3cc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTSignatureUtil.java @@ -1014,6 +1014,12 @@ public class ASTSignatureUtil { case IASTBinaryExpression.op_notequals: opString = String.valueOf(Keywords.cpNOTEQUAL); break; + case IGPPASTBinaryExpression.op_max: + opString = String.valueOf(Keywords.cpMAX); + break; + case IGPPASTBinaryExpression.op_min: + opString = String.valueOf(Keywords.cpMIN); + break; } return opString; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBuiltinSymbolProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBuiltinSymbolProvider.java new file mode 100644 index 00000000000..bad3c45894e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBuiltinSymbolProvider.java @@ -0,0 +1,29 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.core.dom.ast; + +/** + * This is used to IASTName implementations to determine if they are bound to a Built-in Symbol + * provided by a Built-in Symbol Provider that implements this interface. + * + * @author dsteffle + */ +public interface IASTBuiltinSymbolProvider { + + /** + * Returns all of the IBindings corresponding to the IASTBuiltinSymbolProvider. + * + * @param symbol + * @return + */ + public IBinding[] getBuiltinBindings(); + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java index da8426a358d..29f6b7e9ba9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java @@ -86,6 +86,15 @@ public interface IScope { */ public IBinding getBinding(IASTName name, boolean resolve) throws DOMException; + + /** + * This adds an IBinding to the scope. It is primarily used by the parser to add + * implicit IBindings to the scope (such as GCC built-in functions). + * + * @param binding + * @throws DOMException + */ + public void addBinding(IBinding binding) throws DOMException; /** * Set whether or not all the names in this scope have been cached diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index bd81454d812..6a02ea231b0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -84,17 +84,24 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected final boolean supportTypeOfUnaries; protected final boolean supportAlignOfUnaries; + + protected final boolean supportKnRC; + + protected final boolean supportGCCOtherBuiltinSymbols; protected AbstractGNUSourceCodeParser(IScanner scanner, IParserLogService logService, ParserMode parserMode, boolean supportStatementsInExpressions, - boolean supportTypeOfUnaries, boolean supportAlignOfUnaries) { + boolean supportTypeOfUnaries, boolean supportAlignOfUnaries, + boolean supportKnRC, boolean supportGCCOtherBuiltinSymbols) { this.scanner = scanner; this.log = logService; this.mode = parserMode; this.supportStatementsInExpressions = supportStatementsInExpressions; this.supportTypeOfUnaries = supportTypeOfUnaries; this.supportAlignOfUnaries = supportAlignOfUnaries; + this.supportKnRC = supportKnRC; + this.supportGCCOtherBuiltinSymbols = supportGCCOtherBuiltinSymbols; } protected boolean parsePassed = true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java new file mode 100644 index 00000000000..3293dc533ad --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/GCCBuiltinSymbolProvider.java @@ -0,0 +1,998 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser; + +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTBuiltinSymbolProvider; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.c.CASTPointer; +import org.eclipse.cdt.internal.core.dom.parser.c.CASTSimpleDeclSpecifier; +import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType; +import org.eclipse.cdt.internal.core.dom.parser.c.CFunctionType; +import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitFunction; +import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitTypedef; +import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType; +import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitTypedef; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPBasicType; + +/** + * This is the IASTBuiltinSymbolProvider used to implement the "Other" built-in GCC symbols defined: + * http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins + * + * @author dsteffle + */ +public class GCCBuiltinSymbolProvider implements IASTBuiltinSymbolProvider { + /** + * BUILTIN_GCC_SYMBOL is a built-in GCC symbol. + */ + public static final ASTNodeProperty BUILTIN_GCC_SYMBOL = new ASTNodeProperty( + "GCCBuiltinSymbolProvider.BUILTIN_GCC_SYMBOL - built-in GCC symbol"); //$NON-NLS-1$ + + private static final char[] __BUILTIN_VA_LIST = "__builtin_va_list".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_EXPECT = "__builtin_expect".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_PREFETCH = "__builtin_prefetch".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_HUGE_VAL = "__builtin_huge_val".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_HUGE_VALF = "__builtin_huge_valf".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_HUGE_VALL = "__builtin_huge_vall".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_INF = "__builtin_inf".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_INFF = "__builtin_inff".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_INFL = "__builtin_infl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_NAN = "__builtin_nan".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_NANF = "__builtin_nanf".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_NANL = "__builtin_nanl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_NANS = "__builtin_nans".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_NANSF = "__builtin_nansf".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_NANSL = "__builtin_nansl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_FFS = "__builtin_ffs".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_CLZ = "__builtin_clz".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_CTZ = "__builtin_ctz".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_POPCOUNT = "__builtin_popcount".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_PARITY = "__builtin_parity".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_FFSL = "__builtin_ffsl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_CLZL = "__builtin_clzl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_CTZL = "__builtin_ctzl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_POPCOUNTL = "__builtin_popcountl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_PARITYL = "__builtin_parityl".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_FFSLL = "__builtin_ffsll".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_CLZLL = "__builtin_clzll".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_CTZLL = "__builtin_ctzll".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_POPCOUNTLL = "__builtin_popcountll".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_PARITYLL = "__builtin_parityll".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_TYPES_COMPATIBLE_P = "__builtin_types_compatible_p".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_POWI = "__builtin_powi".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_POWIF = "__builtin_powif".toCharArray(); //$NON-NLS-1$ + private static final char[] __BUILTIN_POWIL = "__builtin_powil".toCharArray(); //$NON-NLS-1$ + private static final int NUM_OTHER_GCC_BUILTINS = 34; // the total number of builtin functions listed above + + private IBinding[] bindings=new IBinding[NUM_OTHER_GCC_BUILTINS]; + private IScope scope=null; + private ParserLanguage lang=null; + public GCCBuiltinSymbolProvider(IScope scope, ParserLanguage lang) { + this.scope = scope; + this.lang = lang; + } + + public void initialize() { + __builtin_va_list(); + __builtin_expect(); + __builtin_prefetch(); + __builtin_huge_val(); + __builtin_inf(); + __builtin_nan(); + __builtin_unsigned_int(); + __builtin_unsigned_long(); + __builtin_unsigned_long_long(); + __builtin_types_compatible_p(); + __builtin_powi(); + } + + private void __builtin_va_list() { + // char * __builtin_va_list(); + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_char); + IType type = new CBasicType(sds); + CPointerType returnType = new CPointerType(type); + returnType.setPointer(new CASTPointer()); + IFunctionType functionType = null; + functionType = new CFunctionType(returnType, new IType[0]); + temp = new CImplicitTypedef(functionType, __BUILTIN_VA_LIST, scope); + } else { + IType type = new CPPBasicType( IBasicType.t_char, 0 ); + IType returnType = new CPPPointerType(type); + IFunctionType functionType = null; + functionType = new CPPFunctionType(returnType, new IType[0]); + temp = new CPPImplicitTypedef(functionType, __BUILTIN_VA_LIST, scope); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_expect() { + //long __builtin_expect( long exp, long c ) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setLong(true); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = new CBasicType(sds); + parms[1] = parms[0]; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = theParms[0]; + temp = new CImplicitFunction(__BUILTIN_EXPECT, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_unspecified, CPPBasicType.IS_LONG ); + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = returnType; + parms[1] = parms[0]; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = theParms[0]; + temp = new CPPImplicitFunction(__BUILTIN_EXPECT, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_prefetch() { + // void __builtin_prefetch (const void *addr, ...) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_void); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + parmSds.setConst(true); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + ((CPointerType)parms[0]).setPointer(new CASTPointer()); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_PREFETCH, scope, functionType, theParms, true); + } else { + IType returnType = new CPPBasicType( IBasicType.t_void, 0 ); + IType parmType = new CPPPointerType( new CPPQualifierType(new CPPBasicType(IBasicType.t_void, 0), true, false) ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_PREFETCH, scope, functionType, theParms, true); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_huge_val() { + //double __builtin_huge_val (void) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_HUGE_VAL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, 0 ); + IType parmType = new CPPBasicType(IBasicType.t_void, 0); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_HUGE_VAL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //float __builtin_huge_valf (void) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_float); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_HUGE_VALF, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_float, 0 ); + IType parmType = new CPPBasicType(IBasicType.t_void, 0); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_HUGE_VALF, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //long double __builtin_huge_vall (void) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + sds.setLong(true); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_HUGE_VALL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, CPPBasicType.IS_LONG ); + IType parmType = new CPPBasicType(IBasicType.t_void, 0); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_HUGE_VALL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + } + + private void __builtin_inf() { + //double __builtin_inf (void) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_INF, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, 0 ); + IType parmType = new CPPBasicType(IBasicType.t_void, 0); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_INF, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //float __builtin_inff (void) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_float); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_INFF, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_float, 0 ); + IType parmType = new CPPBasicType(IBasicType.t_void, 0); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_INFF, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //long double __builtin_infl (void) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + sds.setLong(true); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_void); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_INFL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, CPPBasicType.IS_LONG ); + IType parmType = new CPPBasicType(IBasicType.t_void, 0); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = parmType; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_INFL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_nan() { + // const char * + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_char); + parmSds.setConst(true); + CPointerType c_const_char_p = new CPointerType(new CQualifierType(parmSds)); + c_const_char_p.setPointer(new CASTPointer()); + IType cpp_const_char_p = new CPPPointerType(new CPPQualifierType(new CPPBasicType(IBasicType.t_char, 0), true, false)); + + //double __builtin_nan (const char * str) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = c_const_char_p; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_NAN, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, 0 ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = cpp_const_char_p; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_NAN, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //float __builtin_nanf (const char * str) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_float); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = c_const_char_p; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_NANF, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_float, 0 ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = cpp_const_char_p; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_NANF, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //long double __builtin_nanl (const char * str) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + sds.setLong(true); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = c_const_char_p; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_NANL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, CPPBasicType.IS_LONG ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = cpp_const_char_p; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_NANL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //double __builtin_nans (const char * str) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = c_const_char_p; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_NANS, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, 0 ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = cpp_const_char_p; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_NANS, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //float __builtin_nansf (const char * str) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_float); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = c_const_char_p; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_NANSF, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_float, 0 ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = cpp_const_char_p; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_NANSF, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //long double __builtin_nansl (const char * str) + temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_double); + sds.setLong(true); + IType returnType = new CBasicType(sds); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = c_const_char_p; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_NANSL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_double, CPPBasicType.IS_LONG ); + IFunctionType functionType = null; + IType[] parms = new IType[1]; + parms[0] = cpp_const_char_p; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[1]; + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_NANSL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_unsigned_int() { + //unsigned int + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_int); + parmSds.setUnsigned(true); + IType c_unsigned_int = new CQualifierType(parmSds); + IType cpp_unsigned_int = new CPPBasicType(IBasicType.t_int, CPPBasicType.IS_UNSIGNED); + + //int __builtin_ffs(unsigned int x) + IBinding temp = null; + + IFunctionType functionType = null; + IParameter[] theParms = new IParameter[1]; + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_int); + IType returnType = new CBasicType(sds); + IType[] parms = new IType[1]; + parms[0] = c_unsigned_int; + functionType = new CFunctionType(returnType, parms); + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_FFS, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_int, 0 ); + IType[] parms = new IType[1]; + parms[0] = cpp_unsigned_int; + functionType = new CPPFunctionType(returnType, parms); + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_FFS, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_clz(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_CLZ, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_CLZ, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_ctz(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_CTZ, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_CTZ, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_popcount(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_POPCOUNT, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_POPCOUNT, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_parity(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_PARITY, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_PARITY, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_unsigned_long() { + //unsigned long + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_unspecified); + parmSds.setUnsigned(true); + parmSds.setLong(true); + IType c_unsigned_long = new CQualifierType(parmSds); + IType cpp_unsigned_long = new CPPBasicType(IBasicType.t_unspecified, CPPBasicType.IS_UNSIGNED & CPPBasicType.IS_LONG); + + //int __builtin_ffsl(unsigned int x) + IBinding temp = null; + + IFunctionType functionType = null; + IParameter[] theParms = new IParameter[1]; + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_int); + IType returnType = new CBasicType(sds); + IType[] parms = new IType[1]; + parms[0] = c_unsigned_long; + functionType = new CFunctionType(returnType, parms); + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_FFSL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_int, 0 ); + IType[] parms = new IType[1]; + parms[0] = cpp_unsigned_long; + functionType = new CPPFunctionType(returnType, parms); + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_FFSL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_clzl(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_CLZL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_CLZL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_ctzl(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_CTZL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_CTZL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_popcountl(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_POPCOUNTL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_POPCOUNTL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_parityl(unsigned int x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_PARITYL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_PARITYL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_unsigned_long_long() { + //unsigned long long + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_unspecified); + parmSds.setUnsigned(true); + parmSds.setLongLong(true); + IType c_unsigned_long_long = new CQualifierType(parmSds); + IType cpp_unsigned_long_long = new GPPBasicType(IBasicType.t_unspecified, CPPBasicType.IS_UNSIGNED & GPPBasicType.IS_LONGLONG, null); + + //int __builtin_ffsll(unsigned long long x) + IBinding temp = null; + + IFunctionType functionType = null; + IParameter[] theParms = new IParameter[1]; + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_int); + IType returnType = new CBasicType(sds); + IType[] parms = new IType[1]; + parms[0] = c_unsigned_long_long; + functionType = new CFunctionType(returnType, parms); + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CImplicitFunction(__BUILTIN_FFSLL, scope, functionType, theParms, false); + } else { + IType returnType = new CPPBasicType( IBasicType.t_int, 0 ); + IType[] parms = new IType[1]; + parms[0] = cpp_unsigned_long_long; + functionType = new CPPFunctionType(returnType, parms); + theParms[0] = new BuiltinParameter(parms[0]); + temp = new CPPImplicitFunction(__BUILTIN_FFSLL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_clzll(unsigned long long x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_CLZLL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_CLZLL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_ctzll(unsigned long long x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_CTZLL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_CTZLL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_popcountll(unsigned long long x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_POPCOUNTLL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_POPCOUNTLL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + //int __builtin_parityll(unsigned long long x) + temp = null; + + if (lang == ParserLanguage.C) { + temp = new CImplicitFunction(__BUILTIN_PARITYLL, scope, functionType, theParms, false); + } else { + temp = new CPPImplicitFunction(__BUILTIN_PARITYLL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + } + + private void __builtin_types_compatible_p() { + // int __builtin_types_compatible_p( type1, type2 ) implemented via ( ... ) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + ICASTSimpleDeclSpecifier sds = new CASTSimpleDeclSpecifier(); + sds.setType(IASTSimpleDeclSpecifier.t_int); + IType returnType = new CBasicType(sds); + ICASTSimpleDeclSpecifier parmSds = new CASTSimpleDeclSpecifier(); + parmSds.setType(IASTSimpleDeclSpecifier.t_unspecified); + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = new CPointerType(new CQualifierType(parmSds)); + parms[1] = parms[0]; + functionType = new CFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = theParms[0]; + temp = new CImplicitFunction(__BUILTIN_TYPES_COMPATIBLE_P, scope, functionType, theParms, true); + } else { + IType returnType = new CPPBasicType( IBasicType.t_int, 0 ); + IType parmType = new CPPBasicType(IBasicType.t_unspecified, 0); + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = parmType; + parms[1] = parms[0]; + functionType = new CPPFunctionType(returnType, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = theParms[0]; + temp = new CPPImplicitFunction(__BUILTIN_TYPES_COMPATIBLE_P, scope, functionType, theParms, true); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + private void __builtin_powi() { + // double and int + ICASTSimpleDeclSpecifier doubleSds = new CASTSimpleDeclSpecifier(); + doubleSds.setType(IASTSimpleDeclSpecifier.t_double); + ICASTSimpleDeclSpecifier intSds = new CASTSimpleDeclSpecifier(); + intSds.setType(IASTSimpleDeclSpecifier.t_int); + ICASTSimpleDeclSpecifier floatSds = new CASTSimpleDeclSpecifier(); + floatSds.setType(IASTSimpleDeclSpecifier.t_float); + ICASTSimpleDeclSpecifier longDoubleSds = new CASTSimpleDeclSpecifier(); + longDoubleSds.setType(IASTSimpleDeclSpecifier.t_double); + longDoubleSds.setLong(true); + IType c_double = new CBasicType(doubleSds); + IType cpp_double = new CPPBasicType(IBasicType.t_double, 0); + IType c_int = new CBasicType(intSds); + IType cpp_int = new CPPBasicType(IBasicType.t_int, 0); + IType c_float = new CBasicType(floatSds); + IType cpp_float = new CPPBasicType(IBasicType.t_float, 0); + IType c_long_double = new CBasicType(longDoubleSds); + IType cpp_long_double = new CPPBasicType(IBasicType.t_double, CPPBasicType.IS_LONG); + + // double __builtin_powi (double, int) + IBinding temp = null; + + if (lang == ParserLanguage.C) { + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = c_double; + parms[1] = c_int; + functionType = new CFunctionType(c_double, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = new BuiltinParameter(parms[1]); + temp = new CImplicitFunction(__BUILTIN_POWI, scope, functionType, theParms, false); + } else { + IType[] parms = new IType[2]; + parms[0] = cpp_double; + parms[1] = cpp_int; + IFunctionType functionType = new CPPFunctionType(cpp_double, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = new BuiltinParameter(parms[1]); + temp = new CPPImplicitFunction(__BUILTIN_POWI, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + // float __builtin_powif (float, int) + temp = null; + + if (lang == ParserLanguage.C) { + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = c_float; + parms[1] = c_int; + functionType = new CFunctionType(c_float, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = new BuiltinParameter(parms[1]); + temp = new CImplicitFunction(__BUILTIN_POWIF, scope, functionType, theParms, false); + } else { + IType[] parms = new IType[2]; + parms[0] = cpp_float; + parms[1] = cpp_int; + IFunctionType functionType = new CPPFunctionType(cpp_float, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = new BuiltinParameter(parms[1]); + temp = new CPPImplicitFunction(__BUILTIN_POWIF, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + + // long double __builtin_powil (long double, int) + temp = null; + + if (lang == ParserLanguage.C) { + IFunctionType functionType = null; + IType[] parms = new IType[2]; + parms[0] = c_long_double; + parms[1] = c_int; + functionType = new CFunctionType(c_long_double, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = new BuiltinParameter(parms[1]); + temp = new CImplicitFunction(__BUILTIN_POWIL, scope, functionType, theParms, false); + } else { + IType[] parms = new IType[2]; + parms[0] = cpp_long_double; + parms[1] = cpp_int; + IFunctionType functionType = new CPPFunctionType(cpp_long_double, parms); + IParameter[] theParms = new IParameter[2]; + theParms[0] = new BuiltinParameter(parms[0]); + theParms[1] = new BuiltinParameter(parms[1]); + temp = new CPPImplicitFunction(__BUILTIN_POWIL, scope, functionType, theParms, false); + } + + bindings = (IBinding[])ArrayUtil.append(IBinding.class, bindings, temp); + } + + public IBinding[] getBuiltinBindings() { + initialize(); + return (IBinding[])ArrayUtil.trim(IBinding.class, bindings); + } + + private class BuiltinParameter implements IParameter { + + private static final String BLANK_STRING = ""; //$NON-NLS-1$ + private IType type=null; + + public BuiltinParameter(IType type) { + this.type = type; + } + + public IType getType() { + return type; + } + + /** + * returns false + */ + public boolean isStatic() { + return false; + } + + /** + * returns false + */ + public boolean isExtern() { + return false; + } + + /** + * returns false + */ + public boolean isAuto() { + return false; + } + + /** + * returns false + */ + public boolean isRegister() { + return false; + } + + public String getName() { + return BLANK_STRING; + } + + public char[] getNameCharArray() { + return BLANK_STRING.toCharArray(); + } + + /** + * returns false + */ + public IScope getScope() { + return null; + } + + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index 9850dec316b..1b4a5694204 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -203,4 +203,8 @@ public class ProblemBinding implements IProblemBinding, IType, IScope { } return -1; } + + public void addBinding(IBinding binding) throws DOMException { + throw new DOMException( this ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ANSICParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ANSICParserExtensionConfiguration.java index 135a5ae65f9..8851a4cf6dd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ANSICParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ANSICParserExtensionConfiguration.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2002-2004 IBM Canada and others. + * Copyright (c) 2002, 2005 IBM Canada and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v0.5 * which accompanies this distribution, and is available at @@ -43,4 +43,18 @@ public class ANSICParserExtensionConfiguration implements return false; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser2.c.ICParserExtensionConfiguration#supportKnRC() + */ + public boolean supportKnRC() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser2.c.ICParserExtensionConfiguration#supportGCCBuiltinSymbols() + */ + public boolean supportGCCOtherBuiltinSymbols() { + return false; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitFunction.java new file mode 100644 index 00000000000..ddc48617083 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitFunction.java @@ -0,0 +1,91 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.c; + +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * The CImplicitFunction is used to represent implicit functions that exist on the translation + * unit but are not actually part of the physical AST created by CDT. + * + * An example is GCC built-in functions. + * + * @author dsteffle + */ +public class CImplicitFunction extends CExternalFunction implements IFunction, ICInternalBinding { + + private IParameter[] parms=null; + private IScope scope=null; + private IFunctionType type=null; + private boolean takesVarArgs=false; + private char[] name=null; + + public CImplicitFunction(char[] name, IScope scope, IFunctionType type, IParameter[] parms, boolean takesVarArgs) { + super(null, null); + this.name=name; + this.scope=scope; + this.type=type; + this.parms=parms; + this.takesVarArgs=takesVarArgs; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() + */ + public IParameter[] getParameters() { + return parms; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() + */ + public IFunctionType getType() { + return type; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#takesVarArgs() + */ + public boolean takesVarArgs() { + return takesVarArgs; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return String.valueOf(name); + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + return name; + } + + /* + * (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return scope; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java new file mode 100644 index 00000000000..2aeafccb8c3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CImplicitTypedef.java @@ -0,0 +1,107 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.c; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; + +/** + * The CImplicitTypedef is used to represent implicit typedefs that exist on the translation + * unit but are not actually part of the physical AST created by CDT. + * + * An example is the GCC built-in typedef: typedef char * __builtin_va_list; + * + * @author dsteffle + */ +public class CImplicitTypedef extends CTypedef implements ITypedef, ICInternalBinding { + private IType type=null; + private char[] name=null; + private IScope scope=null; + + public CImplicitTypedef(IType type, char[] name, IScope scope) { + super(null); + this.type = type; + this.name = name; + this.scope = scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ITypedef#getType() + */ + public IType getType() { + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return String.valueOf(name); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) + */ +// public boolean isSameType(IType t) { +// if( t == this ) +// return true; +// if( t instanceof ITypedef ) +// try { +// IType temp = getType(); +// if( temp != null ) +// return temp.isSameType( ((ITypedef)t).getType()); +// return false; +// } catch ( DOMException e ) { +// return false; +// } +// +// IType temp; +// temp = getType(); +// if( temp != null ) +// return temp.isSameType( t ); +// return false; +// } + + /* + * (non-Javadoc) + * @see java.lang.Object#clone() + */ +// public Object clone(){ +// IType t = null; +// t = (IType) super.clone(); +// return t; +// } + + /** + * returns null + * @return + */ + public IASTNode getPhysicalNode() { + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java index 8ceb7764f35..5172cefd087 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java @@ -204,4 +204,16 @@ public class CScope implements ICScope { bindings[1].clear(); isFullyCached = false; } + + public void addBinding(IBinding binding) { + int type = NAMESPACE_TYPE_OTHER; + if (binding instanceof ICompositeType || binding instanceof IEnumeration) { + type = NAMESPACE_TYPE_TAG; + } + + if( bindings[type] == CharArrayObjectMap.EMPTY_MAP ) + bindings[type] = new CharArrayObjectMap(2); + + bindings[type].put(binding.getNameCharArray(), binding); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypedef.java similarity index 96% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypedef.java index 87ee588f2a3..7c6f1632df2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypedef.java @@ -24,11 +24,11 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; * Created on Nov 8, 2004 * @author aniefer */ -public class CTypeDef implements ITypedef, ITypeContainer { +public class CTypedef implements ITypedef, ITypeContainer { private final IASTName name; private IType type = null; - public CTypeDef( IASTName name ){ + public CTypedef( IASTName name ){ this.name = name; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index f421612e81a..e49c42bc17b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -728,13 +728,13 @@ public class CVisitor { } binding = new ProblemBinding( name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD, name.toCharArray() ); } else if( parent instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) parent).getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) - binding = new CTypeDef( name ); + binding = new CTypedef( name ); else binding = new CFunction( (IASTFunctionDeclarator) declarator ); } else if( parent instanceof IASTSimpleDeclaration ){ IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent; if( simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ){ - binding = new CTypeDef( name ); + binding = new CTypedef( name ); } else { IType t1 = null, t2 = null; if( binding != null ) { @@ -1069,6 +1069,9 @@ public class CVisitor { } if( binding != null ) return binding; + } else if (!prefix && scope != null && scope.getParent() == null && scope.getBinding( name, false ) != null) { + binding = scope.getBinding( name, false ); + return binding; } else { Object result = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCParserExtensionConfiguration.java index e9dd6abd672..6d5a30325ef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GCCParserExtensionConfiguration.java @@ -50,4 +50,11 @@ public class GCCParserExtensionConfiguration implements return true; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser2.c.ICParserExtensionConfiguration#supportGCCOtherBuiltinSymbols() + */ + public boolean supportGCCOtherBuiltinSymbols() { + return true; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index af670fa957d..abf6b8b90ad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -73,6 +73,8 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; +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.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator; @@ -95,12 +97,14 @@ import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ParseError; +import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser; import org.eclipse.cdt.internal.core.dom.parser.BacktrackException; +import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; @@ -129,7 +133,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { super(scanner, logService, parserMode, config .supportStatementsInExpressions(), config .supportTypeofUnaryExpressions(), config - .supportAlignOfUnaryExpression()); + .supportAlignOfUnaryExpression(), config + .supportKnRC(), config.supportGCCOtherBuiltinSymbols()); supportGCCStyleDesignators = config.supportGCCStyleDesignators(); } @@ -565,6 +570,16 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { protected void translationUnit() { try { translationUnit = createTranslationUnit(); + + // add built-in names to the scope + if (supportGCCOtherBuiltinSymbols) { + IScope tuScope = translationUnit.getScope(); + + IBinding[] bindings = new GCCBuiltinSymbolProvider(translationUnit.getScope(), ParserLanguage.C).getBuiltinBindings(); + for(int i=0; i 0) { // KnR C parameters were found so + + if (supportKnRC && numKnRCParms > 0) { // KnR C parameters were found so // handle the declarator accordingly parmNames = new IASTName[numKnRCParms]; parmDeclarations = new IASTDeclaration[numKnRCParms]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICParserExtensionConfiguration.java index bb794d23c74..a4a56d26835 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/ICParserExtensionConfiguration.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2002-2004 IBM Canada and others. + * Copyright (c) 2002, 2005 IBM Canada and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v0.5 * which accompanies this distribution, and is available at @@ -18,6 +18,13 @@ public interface ICParserExtensionConfiguration { public boolean supportGCCStyleDesignators(); public boolean supportTypeofUnaryExpressions(); public boolean supportAlignOfUnaryExpression(); + public boolean supportKnRC(); + + /** + * See http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins + * for more information on GCC's Other Built-in Symbols. + * @return + */ + public boolean supportGCCOtherBuiltinSymbols(); - } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ANSICPPParserExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ANSICPPParserExtensionConfiguration.java index 2481387089a..e0fc97fcf44 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ANSICPPParserExtensionConfiguration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ANSICPPParserExtensionConfiguration.java @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (c) 2002-2004 IBM Canada and others. + * Copyright (c) 2002, 2005 IBM Canada and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v0.5 * which accompanies this distribution, and is available at @@ -78,5 +78,18 @@ public class ANSICPPParserExtensionConfiguration implements return false; } + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser2.cpp.ICPPParserExtensionConfiguration#supportGCCOtherBuiltinSymbols() + */ + public boolean supportGCCOtherBuiltinSymbols() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.parser2.cpp.ICPPParserExtensionConfiguration#supportKnRC() + */ + public boolean supportKnRC() { + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java index 70a16b3285a..b8322ab12ed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstanceScope.java @@ -242,4 +242,23 @@ public class CPPClassInstanceScope implements ICPPClassScope { bindings.clear(); isFullyCached = false; } + + public void addBinding(IBinding binding) { + if( bindings == null ) + bindings = new CharArrayObjectMap(1); + char [] c = binding.getNameCharArray(); + Object o = bindings.get( c ); + if( o != null ){ + if( o instanceof ObjectSet ){ + ((ObjectSet)o).put( binding ); + } else { + ObjectSet set = new ObjectSet(2); + set.put( o ); + set.put( binding ); + bindings.put( c, set ); + } + } else { + bindings.put( c, binding ); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 38977e30df5..081f739d386 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -36,7 +36,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.parser.util.ArrayUtil; -import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectSet; @@ -127,22 +126,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { addConstructor( binding ); return; } - if( bindings == null ) - bindings = new CharArrayObjectMap(1); - char [] c = binding.getNameCharArray(); - Object o = bindings.get( c ); - if( o != null ){ - if( o instanceof ObjectSet ){ - ((ObjectSet)o).put( binding ); - } else { - ObjectSet set = new ObjectSet(2); - set.put( o ); - set.put( binding ); - bindings.put( c, set ); - } - } else { - bindings.put( c, binding ); - } + super.addBinding(binding); } public void addName(IASTName name) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java new file mode 100644 index 00000000000..a8c287976c1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitFunction.java @@ -0,0 +1,153 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; + +/** + * The CPPImplicitFunction is used to represent implicit functions that exist on the translation + * unit but are not actually part of the physical AST created by CDT. + * + * An example is GCC built-in functions. + * + * @author dsteffle + */ +public class CPPImplicitFunction extends CPPFunction implements ICPPFunction, ICPPInternalBinding { + + private IParameter[] parms=null; + private IScope scope=null; + private IType returnType=null; + private IFunctionType functionType=null; + private boolean takesVarArgs=false; + private char[] name=null; + + public CPPImplicitFunction(char[] name, IScope scope, IType type, IParameter[] parms, boolean takesVarArgs) { + super( null ); + this.name=name; + this.scope=scope; + this.returnType=type; + this.parms=parms; + this.takesVarArgs=takesVarArgs; + } + + public IParameter [] getParameters() { + return parms; + } + + public IFunctionType getType() { + if( functionType == null ){ + ICPPASTFunctionDeclarator primary = getPrimaryDeclaration(); + + if( primary != null ){ + functionType = super.getType(); + } else { + functionType = CPPVisitor.createImplicitFunctionType( returnType, parms ); + } + } + + return functionType; + } + + private ICPPASTFunctionDeclarator getPrimaryDeclaration() { + if (definition != null) + return definition; + else if (declarations != null && declarations.length > 0) + return declarations[0]; + + return null; + } + + public String getName() { + return String.valueOf( name ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + return name; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope() + */ + public IScope getFunctionScope() { + return null; + } + + public IBinding resolveParameter( IASTParameterDeclaration param ){ + IASTName aName = param.getDeclarator().getName(); + IParameter binding = (IParameter) aName.getBinding(); + if( binding != null ) + return binding; + + //get the index in the parameter list + ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent(); + IASTParameterDeclaration [] ps = fdtor.getParameters(); + int i = 0; + for( ; i < ps.length; i++ ){ + if( param == ps[i] ) + break; + } + + //set the binding for the corresponding parameter in all known defns and decls + binding = parms[i]; + IASTParameterDeclaration temp = null; + if( definition != null ){ + temp = definition.getParameters()[i]; + IASTName n = temp.getDeclarator().getName(); + n.setBinding( binding ); + ((CPPParameter)binding).addDeclaration( n ); + } + if( declarations != null ){ + for( int j = 0; j < declarations.length; j++ ){ + temp = declarations[j].getParameters()[i]; + IASTName n = temp.getDeclarator().getName(); + n.setBinding( binding ); + ((CPPParameter)binding).addDeclaration( n ); + } + } + return binding; + } + + protected void updateParameterBindings( ICPPASTFunctionDeclarator fdtor ){ + if( parms != null ){ + IASTParameterDeclaration [] nps = fdtor.getParameters(); + if( nps.length != parms.length ) + return; + + for( int i = 0; i < nps.length; i++ ){ + IASTName aName = nps[i].getDeclarator().getName(); + aName.setBinding( parms[i] ); + if( parms[i] instanceof ICPPInternalBinding ) + ((ICPPInternalBinding)parms[i]).addDeclaration( aName ); + } + } + } + + public boolean takesVarArgs() { + return takesVarArgs; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java index cb6a1a0c089..a66ca6907b4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java @@ -15,149 +15,55 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IParameter; -import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; 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.ICPPMethod; import org.eclipse.cdt.core.parser.util.CharArrayUtils; /** * @author aniefer */ -public class CPPImplicitMethod extends CPPMethod { - - private char [] implicitName = null; - private IParameter [] parameters = null; - private IType returnType = null; - private ICPPClassScope scope = null; +public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod { public CPPImplicitMethod( ICPPClassScope scope, char[] name, IType returnType, IParameter[] params ) { - super( null ); - this.implicitName = name; - this.parameters = params; - this.returnType = returnType; - this.scope = scope; + super( name, scope, returnType, params, false ); } - /** - * @param cs - * @param ps - */ - - public IParameter [] getParameters() { - return parameters; - } - - public IFunctionType getType() { - if( type == null ){ - IASTDeclaration primary = null; - try { - primary = getPrimaryDeclaration(); - } catch (DOMException e) { - } - if( primary != null ){ - type = super.getType(); - } else { - type = CPPVisitor.createImplicitFunctionType( returnType, parameters ); - } - } - - return type; - } - - public String getName() { - return String.valueOf( implicitName ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() - */ - public char[] getNameCharArray() { - return implicitName; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() - */ - public IScope getScope() { - return scope; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope() - */ - public IScope getFunctionScope() { - return null; - } - public int getVisibility() throws DOMException { IASTDeclaration decl = getPrimaryDeclaration(); if( decl == null ) { //12.1-5, 12.8-10 Implicitl constructors and assignment operators are public return ICPPASTVisiblityLabel.v_public; } - return super.getVisibility(); - } - - public IBinding resolveParameter( IASTParameterDeclaration param ){ - IASTName name = param.getDeclarator().getName(); - IParameter binding = (IParameter) name.getBinding(); - if( binding != null ) - return binding; - //get the index in the parameter list - ICPPASTFunctionDeclarator fdtor = (ICPPASTFunctionDeclarator) param.getParent(); - IASTParameterDeclaration [] ps = fdtor.getParameters(); - int i = 0; - for( ; i < ps.length; i++ ){ - if( param == ps[i] ) - break; - } - - //set the binding for the corresponding parameter in all known defns and decls - binding = parameters[i]; - IASTParameterDeclaration temp = null; - if( definition != null ){ - temp = definition.getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); - n.setBinding( binding ); - ((CPPParameter)binding).addDeclaration( n ); - } - if( declarations != null ){ - for( int j = 0; j < declarations.length; j++ ){ - temp = declarations[j].getParameters()[i]; - IASTName n = temp.getDeclarator().getName(); - n.setBinding( binding ); - ((CPPParameter)binding).addDeclaration( n ); - } - } - return binding; + IASTCompositeTypeSpecifier cls = (IASTCompositeTypeSpecifier) decl.getParent(); + IASTDeclaration [] members = cls.getMembers(); + ICPPASTVisiblityLabel vis = null; + for( int i = 0; i < members.length; i++ ){ + if( members[i] instanceof ICPPASTVisiblityLabel ) + vis = (ICPPASTVisiblityLabel) members[i]; + else if( members[i] == decl ) + break; + } + if( vis != null ){ + return vis.getVisibility(); + } else if( cls.getKey() == ICPPASTCompositeTypeSpecifier.k_class ){ + return ICPPASTVisiblityLabel.v_private; + } + return ICPPASTVisiblityLabel.v_public; } - - protected void updateParameterBindings( ICPPASTFunctionDeclarator fdtor ){ - if( parameters != null ){ - IASTParameterDeclaration [] nps = fdtor.getParameters(); - if( nps.length != parameters.length ) - return; - - for( int i = 0; i < nps.length; i++ ){ - IASTName name = nps[i].getDeclarator().getName(); - name.setBinding( parameters[i] ); - ((CPPParameter)parameters[i]).addDeclaration( name ); - } - } - } public IASTDeclaration getPrimaryDeclaration() throws DOMException{ //first check if we already know it @@ -169,10 +75,10 @@ public class CPPImplicitMethod extends CPPMethod { } } - IFunctionType ftype = CPPVisitor.createImplicitFunctionType( returnType, parameters ); + IFunctionType ftype = getType(); IType [] params = ftype.getParameterTypes(); - ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) scope.getPhysicalNode(); + ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) getScope().getPhysicalNode(); IASTDeclaration [] members = compSpec.getMembers(); for( int i = 0; i < members.length; i++ ){ IASTDeclarator dtor = null; @@ -195,7 +101,7 @@ public class CPPImplicitMethod extends CPPMethod { while( dtor != null ){ IASTName name = dtor.getName(); if( dtor instanceof ICPPASTFunctionDeclarator && - CharArrayUtils.equals( name.toCharArray(), implicitName ) ) + CharArrayUtils.equals( name.toCharArray(), getNameCharArray() ) ) { IFunctionType t = (IFunctionType) CPPVisitor.createType( dtor ); IType [] ps = t.getParameterTypes(); @@ -221,4 +127,15 @@ public class CPPImplicitMethod extends CPPMethod { } return null; } + + public boolean isVirtual() { + return false; + } + + public boolean isDestructor() { + char [] n = getNameCharArray(); + if( n != null && n.length > 0 ) + return n[0] == '~'; + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitTypedef.java new file mode 100644 index 00000000000..46c177bf2b7 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitTypedef.java @@ -0,0 +1,169 @@ +/********************************************************************** + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate; + +/** + * The CPPImplicitTypedef is used to represent implicit typedefs that exist on the translation + * unit but are not actually part of the physical AST created by CDT. + * + * An example is the GCC built-in typedef: typedef char * __builtin_va_list; + * + * @author dsteffle + */ +public class CPPImplicitTypedef extends CPPTypedef implements ITypedef, ICPPInternalBinding { + private IType type=null; + private char[] name=null; + private IScope scope=null; + + public CPPImplicitTypedef(IType type, char[] name, IScope scope) { + super(null); + this.type = type; + this.name = name; + this.scope = scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ITypedef#getType() + */ + public IType getType() { + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + return String.valueOf(name); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + return name; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return scope; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType) + */ + public boolean isSameType(IType t) { + if( t == this ) + return true; + if( t instanceof ITypedef ) { + IType temp = getType(); + if( temp != null ) + try { + return temp.isSameType( ((ITypedef)t).getType()); + } catch (DOMException e) {} + return false; + } + + IType temp; + temp = getType(); + if( temp != null ) + return temp.isSameType( t ); + return false; + } + + /* (non-Javadoc) + * @see java.lang.Object#clone() + */ + public Object clone(){ + IType t = null; + t = (IType) super.clone(); + return t; + } + + /** + * returns null + */ + public IASTNode[] getDeclarations() { + return null; + } + + /** + * returns null + */ + public IASTNode getDefinition() { + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#createDelegate(org.eclipse.cdt.core.dom.ast.IASTName) + */ + public ICPPDelegate createDelegate(IASTName aName) { + return new CPPTypedefDelegate( aName, this ); + } + + /** + * does nothing + */ + public void addDefinition(IASTNode node) { + // do nothing + } + + /** + * does nothing + */ + public void addDeclaration(IASTNode node) { + // do nothing + } + + /** + * does nothing + */ + public void removeDeclaration(IASTNode node) { + // do nothing + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getFullyQualifiedName() + */ + public String[] getQualifiedName() { + String[] temp = new String[1]; + temp[0] = String.valueOf(name); + + return temp; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getFullyQualifiedNameCharArray() + */ + public char[][] getQualifiedNameCharArray() { + char[][] temp = new char[1][]; + temp[0] = name; + + return temp; + } + + /** + * returns true + */ + public boolean isGloballyQualified() { + return true; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 2127f86aa6e..dd80603da13 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -179,4 +179,23 @@ abstract public class CPPScope implements ICPPScope{ if( bindings != null ) bindings.clear(); } + + public void addBinding(IBinding binding) { + if( bindings == null ) + bindings = new CharArrayObjectMap(1); + char [] c = binding.getNameCharArray(); + Object o = bindings.get( c ); + if( o != null ){ + if( o instanceof ObjectSet ){ + ((ObjectSet)o).put( binding ); + } else { + ObjectSet set = new ObjectSet(2); + set.put( o ); + set.put( binding ); + bindings.put( c, set ); + } + } else { + bindings.put( c, binding ); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 7cc76d2924a..62a44664bdb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -773,8 +773,12 @@ public class CPPSemantics { Object [] objs = null; if( source instanceof CharArrayObjectMap ) map = (CharArrayObjectMap) source; - else - objs = ArrayUtil.trim( Object.class, (Object[]) source ); + else{ + if (source instanceof Object[]) + objs = ArrayUtil.trim( Object.class, (Object[]) source ); + else + objs = new Object[]{ source }; + } int size = map != null ? map.size() : objs.length; int resultInitialSize = resultMap.size(); @@ -831,6 +835,11 @@ public class CPPSemantics { mergeResults( data, binding, true ); } } else { + if (!data.prefixLookup && data.astName != null ) { + IBinding b = scope.getBinding( data.astName, false ); + if (b instanceof CPPImplicitFunction || b instanceof CPPImplicitTypedef) + mergeResults( data, b, true ); + } mergeResults( data, lookupInScope( data, scope, blockItem ), true ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java index 1ce0da4e372..853cefdb660 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java @@ -56,7 +56,8 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding */ public CPPTypedef(IASTName name) { this.declarations = new IASTName[] { name }; - name.setBinding( this ); + if (name != null) + name.setBinding( this ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java index 2f1718a5511..6155bdf9bb8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java @@ -119,4 +119,8 @@ public class CPPUnknownScope implements ICPPScope { public void flushCache() { } + public void addBinding(IBinding aBinding) { + // do nothing, this is part of template magic and not a normal scope + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 5aeadbb0503..69b3e484a37 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -76,6 +76,8 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; +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.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; @@ -134,11 +136,13 @@ import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ParseError; +import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser; import org.eclipse.cdt.internal.core.dom.parser.BacktrackException; +import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousStatement; import org.eclipse.cdt.internal.core.parser.SimpleDeclarationStrategy; @@ -1922,7 +1926,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IParserLogService log, ICPPParserExtensionConfiguration config) { super(scanner, log, mode, config.supportStatementsInExpressions(), config.supportTypeofUnaryExpressions(), config - .supportAlignOfUnaryExpression()); + .supportAlignOfUnaryExpression(), config. + supportKnRC(), config.supportGCCOtherBuiltinSymbols()); allowCPPRestrict = config.allowRestrictPointerOperators(); supportExtendedTemplateSyntax = config.supportExtendedTemplateSyntax(); supportMinAndMaxOperators = config.supportMinAndMaxOperators(); @@ -4495,6 +4500,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { protected void translationUnit() { try { translationUnit = createTranslationUnit(); + + // add built-in names to the scope + if (supportGCCOtherBuiltinSymbols) { + IScope tuScope = translationUnit.getScope(); + + IBinding[] bindings = new GCCBuiltinSymbolProvider(translationUnit.getScope(), ParserLanguage.CPP).getBuiltinBindings(); + for(int i=0; i