diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index b6b79a463f7..2dbfbac4700 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -8077,7 +8077,7 @@ public class AST2CPPTests extends AST2BaseTest { String code= getAboveComment(); parseAndCheckBindings(code, ParserLanguage.CPP); } - + // namespace std { // template class initializer_list; // } @@ -8237,7 +8237,7 @@ public class AST2CPPTests extends AST2BaseTest { bh.assertProblem("h( {1.0} )", 1); bh.assertNonProblem("h( { } )", 1); } - + // namespace std { // template class initializer_list; // } @@ -8282,5 +8282,40 @@ public class AST2CPPTests extends AST2BaseTest { bh.assertProblem("fH(1)", 2); bh.assertNonProblem("fH({1})", 2); } -} + // namespace std { + // template class initializer_list; + // } + // struct A {}; + // A a; + // auto b = a; + // const auto *p = &b, q = ""; + // static auto d = 0.0; + // auto r = { 'a', 'b' }; + // auto *s = new auto(1L); + // auto t = new auto({1.0}); + // auto x; // Error - missing initializer. + // auto y = { 1.0, 5 }; // Error - inconsistent types in the array initializer. + public void testAutoType_289542() throws Exception { + String code= getAboveComment(); + BindingAssertionHelper bh= new BindingAssertionHelper(code, true); + ICPPVariable b= bh.assertNonProblem("b =", 1); + assertEquals("A", ASTTypeUtil.getType(b.getType())); + ICPPVariable p= bh.assertNonProblem("p =", 1); + assertEquals("const A *", ASTTypeUtil.getType(p.getType())); + ICPPVariable q= bh.assertNonProblem("q =", 1); + assertEquals("const char * const", ASTTypeUtil.getType(q.getType())); + ICPPVariable d= bh.assertNonProblem("d =", 1); + assertEquals("double", ASTTypeUtil.getType(d.getType())); + ICPPVariable r= bh.assertNonProblem("r =", 1); + assertEquals("std::initializer_list", ASTTypeUtil.getType(r.getType())); + ICPPVariable s= bh.assertNonProblem("s =", 1); + assertEquals("long int *", ASTTypeUtil.getType(s.getType())); + ICPPVariable t= bh.assertNonProblem("t =", 1); + assertEquals("std::initializer_list *", ASTTypeUtil.getType(t.getType())); + ICPPVariable x= bh.assertNonProblem("x;", 1); + assertNull(x.getType()); + ICPPVariable y= bh.assertNonProblem("y =", 1); + assertNull(y.getType()); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/RewriteTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/RewriteTests.java index fe6d7258b52..a8b2dfe4faa 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/RewriteTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/RewriteTests.java @@ -27,5 +27,4 @@ public class RewriteTests extends TestSuite { suite.addTest(ChangeGeneratorTestSuite.suite()); return suite; } - } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/ASTWriterTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/ASTWriterTest.java index 2b447547c43..b5630fe9a81 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/ASTWriterTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/ASTWriterTest.java @@ -63,7 +63,6 @@ public class ASTWriterTest extends RewriteBaseTest { } } - @Override protected void runTest() throws Throwable { file = project.getFile("ASTWritterTest.h"); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/AstWriterTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/AstWriterTestSuite.java index 01542deb9d4..a2930cf4715 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/AstWriterTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/rewrite/astwriter/AstWriterTestSuite.java @@ -16,7 +16,6 @@ import junit.framework.TestSuite; /** * @author Emanuel Graf - * */ public class AstWriterTestSuite{ @@ -33,8 +32,8 @@ public class AstWriterTestSuite{ "resources/rewrite/ASTWriterCommentedDeclaratorTestSource.awts")); suite.addTest(SourceRewriteTester.suite("StatementsTests", "resources/rewrite/ASTWriterStatementTestSource.awts")); - suite.addTest(SourceRewriteTester - .suite("Commented StatementsTests", "resources/rewrite/ASTWriterCommentedStatementTestSource.awts")); + suite.addTest(SourceRewriteTester.suite("Commented StatementsTests", + "resources/rewrite/ASTWriterCommentedStatementTestSource.awts")); suite.addTest(SourceRewriteTester.suite("NameTests", "resources/rewrite/ASTWriterNameTestSource.awts")); suite.addTest(SourceRewriteTester.suite("Commented NameTests", "resources/rewrite/ASTWriterCommentedNameTestSource.awts")); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java index e1c033c3d81..f92cfd9f630 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexUpdateTests.java @@ -238,21 +238,17 @@ public class IndexUpdateTests extends IndexTestBase { } // int globalVar; - + // short globalVar; - - // auto int globalVar; - + // register int globalVar; - + public void testGlobalCppVariable() throws Exception { - setupFile(4, true); + setupFile(3, true); checkCppVariable("globalVar", INT, new String[]{}); updateFile(); checkCppVariable("globalVar", SHORT, new String[]{}); updateFile(); - checkCppVariable("globalVar", INT, new String[]{AUTO}); - updateFile(); checkCppVariable("globalVar", INT, new String[]{REGISTER}); } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java index d93def16046..a6b345d7dff 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPFunctionTests.java @@ -118,7 +118,6 @@ public class CPPFunctionTests extends PDOMTestBase { IParameter[] parameters = function.getParameters(); assertEquals(2, parameters.length); assertEquals(true, parameters[0].isRegister()); - assertEquals(true, parameters[1].isAuto()); } public void testExternCPPFunction() throws Exception { @@ -126,14 +125,14 @@ public class CPPFunctionTests extends PDOMTestBase { assertEquals(1, bindings.length); assertTrue(((ICPPFunction) bindings[0]).isExtern()); } - + public void testStaticCPPFunction() throws Exception { // static elements cannot be found on global scope, see bug 161216 IBinding[] bindings = findUnqualifiedName(pdom, "staticCPPFunction"); assertEquals(1, bindings.length); assertTrue(((ICPPFunction) bindings[0]).isStatic()); } - + public void testInlineCPPFunction() throws Exception { IBinding[] bindings = findQualifiedName(pdom, "inlineCPPFunction"); assertEquals(1, bindings.length); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPVariableTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPVariableTests.java index c55d8941621..3a49b709099 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPVariableTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/CPPVariableTests.java @@ -52,7 +52,8 @@ public class CPPVariableTests extends PDOMTestBase { IBinding[] bindings = findQualifiedName(pdom, "autoCPPVariable"); assertEquals(1, bindings.length); ICPPVariable variable = (ICPPVariable) bindings[0]; - assertTrue(variable.isAuto()); + assertFalse(variable.isExtern()); + assertFalse(variable.isStatic()); } public void testCPPExternVariable() throws Exception { diff --git a/core/org.eclipse.cdt.core.tests/resources/pdomtests/variableTests/variables.cpp b/core/org.eclipse.cdt.core.tests/resources/pdomtests/variableTests/variables.cpp index 0611def6d44..13c812448ec 100644 --- a/core/org.eclipse.cdt.core.tests/resources/pdomtests/variableTests/variables.cpp +++ b/core/org.eclipse.cdt.core.tests/resources/pdomtests/variableTests/variables.cpp @@ -1,4 +1,4 @@ -auto int autoCPPVariable; +int autoCPPVariable; extern int externCPPVariable; register int registerCPPVariable; static int staticCPPVariable; diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterCommentedDeclSpecTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterCommentedDeclSpecTestSource.awts index 9acaeb840f5..7dca475d679 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterCommentedDeclSpecTestSource.awts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterCommentedDeclSpecTestSource.awts @@ -19,7 +19,7 @@ static int c; //Test7 int foo() { - auto int i = 1; + int i = 1; return i; } diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclSpecTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclSpecTestSource.awts index a2592ae218d..98c69d124d7 100644 --- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclSpecTestSource.awts +++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterDeclSpecTestSource.awts @@ -12,7 +12,7 @@ extern int b; static int c; int foo() { - auto int i = 1; + int i = 1; return i; } diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java index 2d200ed7937..938a0d5706b 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java @@ -184,7 +184,7 @@ public class BaseTestCase extends TestCase { } } - if (testThrowable!=null) + if (testThrowable != null) throw testThrowable; } 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 b1c80d49470..d858e0573a5 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 @@ -8,6 +8,7 @@ * Contributors: * Rational Software - initial implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -75,8 +76,9 @@ public class ASTSignatureUtil { buffer.append(SPACE); buffer.append(getSignature(declarators[i])); if (declarators[i].getInitializer() != null - && declarators[i].getInitializer() instanceof ICPPASTConstructorInitializer) + && declarators[i].getInitializer() instanceof ICPPASTConstructorInitializer) { buffer.append(getInitializerString(declarators[i].getInitializer())); + } } buffer.append(";"); //$NON-NLS-1$ return buffer.toString(); @@ -699,6 +701,14 @@ public class ASTSignatureUtil { result.append(Keywords.cDECLTYPE); needSpace = true; break; + case IASTSimpleDeclSpecifier.t_auto: + if (needSpace) { + result.append(SPACE); + needSpace = false; + } + result.append(Keywords.cAUTO); + needSpace = true; + break; case IASTSimpleDeclSpecifier.t_bool: if (needSpace) { result.append(SPACE); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java index 06a848d672e..bb68fcb6bb4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTSimpleDeclSpecifier.java @@ -8,6 +8,7 @@ * Contributors: * Doug Schaefer (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast; @@ -82,6 +83,12 @@ public interface IASTSimpleDeclSpecifier extends IASTDeclSpecifier { */ public static final int t_decltype = 9; + /** + * auto c = expression; + * @since 5.2 + */ + public static final int t_auto = 10; + /** * @since 5.1 */ 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 3dbf63ea0c8..7cbcdf1933f 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 @@ -2419,6 +2419,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { case IToken.t_signed: case IToken.t_unsigned: case IToken.t_decltype: + case IToken.t_auto: // class-specifier: case IToken.t_class: @@ -2428,7 +2429,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { // enum-specifier: case IToken.t_enum: - // elaborated type specifier: (together with class, struct, union, enum + // elaborated type specifier: (together with class, struct, union, enum) case IToken.t_typename: // cq-qualifiers 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 d07191cabce..daf075332e4 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 @@ -1097,15 +1097,15 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { break; case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec - if (!supportAttributeSpecifiers) - throwBacktrack(LA(1)); - __attribute_decl_seq(true, false); - break; + if (!supportAttributeSpecifiers) + throwBacktrack(LA(1)); + __attribute_decl_seq(true, false); + break; case IGCCToken.t__declspec: // __declspec precedes the identifier - if (identifier != null || !supportDeclspecSpecifiers) - throwBacktrack(LA(1)); - __attribute_decl_seq(false, true); - break; + if (identifier != null || !supportDeclspecSpecifiers) + throwBacktrack(LA(1)); + __attribute_decl_seq(false, true); + break; case IGCCToken.t_typeof: if (encounteredRawType || encounteredTypename) 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 4672ddbceec..f31ee287c42 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 @@ -150,6 +150,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private final boolean allowCPPRestrict; private final boolean supportExtendedTemplateSyntax; + private final boolean supportAutoTypeSpecifier; private final IIndex index; protected ICPPASTTranslationUnit translationUnit; @@ -182,6 +183,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { supportExtendedSizeofOperator= config.supportExtendedSizeofOperator(); supportFunctionStyleAsm= config.supportFunctionStyleAssembler(); functionCallCanBeLValue= true; + supportAutoTypeSpecifier= true; this.index= index; this.nodeFactory = CPPNodeFactory.getDefault(); scanner.setSplitShiftROperator(true); @@ -2194,8 +2196,17 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break declSpecifiers; // storage class specifiers case IToken.t_auto: - storageClass = IASTDeclSpecifier.sc_auto; - endOffset= consume().getEndOffset(); + if (supportAutoTypeSpecifier) { + if (encounteredTypename) + break declSpecifiers; + simpleType = ICPPASTSimpleDeclSpecifier.t_auto; + encounteredRawType= true; + endOffset= consume().getEndOffset(); + break; + } else { + storageClass = IASTDeclSpecifier.sc_auto; + endOffset= consume().getEndOffset(); + } break; case IToken.t_register: storageClass = IASTDeclSpecifier.sc_register; @@ -2399,15 +2410,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break; case IGCCToken.t__attribute__: // if __attribute__ is after the declSpec - if (!supportAttributeSpecifiers) - throwBacktrack(LA(1)); - __attribute_decl_seq(true, false); - break; + if (!supportAttributeSpecifiers) + throwBacktrack(LA(1)); + __attribute_decl_seq(true, false); + break; case IGCCToken.t__declspec: // __declspec precedes the identifier - if (identifier != null || !supportDeclspecSpecifiers) - throwBacktrack(LA(1)); - __attribute_decl_seq(false, true); - break; + if (identifier != null || !supportDeclspecSpecifiers) + throwBacktrack(LA(1)); + __attribute_decl_seq(false, true); + break; case IGCCToken.t_typeof: if (encounteredRawType || encounteredTypename) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java new file mode 100644 index 00000000000..7f247be8ad2 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AutoTypeResolver.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2010 Google, Inc and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Sergey Prigogin (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; +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.CPPTemplateTypeParameter; +import org.eclipse.core.runtime.CoreException; + +/** + * This class represents a template function used for deducing 'auto' types ( C++0x: 7.1.6.4). + */ +class AutoTypeResolver implements ICPPFunctionTemplate { + // Template parameter of the function. This parameter is used in place of 'auto' keyword. + public static final ICPPTemplateTypeParameter AUTO_TYPE = + new CPPTemplateTypeParameter(new CPPASTName(), false); + private static final ICPPTemplateTypeParameter[] TEMPLATE_PARAMETERS = + new ICPPTemplateTypeParameter[] { AUTO_TYPE }; + private static final String UNEXPECTED_CALL = "Unexpected call"; //$NON-NLS-1$ + private final CPPFunctionType functionType; + + public AutoTypeResolver(IType paramType) { + functionType = new CPPFunctionType(new CPPBasicType(Kind.eVoid, 0), new IType[] { paramType }); + } + + public ICPPTemplateParameter[] getTemplateParameters() { + return TEMPLATE_PARAMETERS; + } + + public ICPPFunctionType getType() { + return functionType; + } + + public boolean isMutable() throws DOMException { + return false; + } + + public boolean isInline() throws DOMException { + return false; + } + + public boolean isExternC() throws DOMException { + return false; + } + + public IType[] getExceptionSpecification() throws DOMException { + return IType.EMPTY_TYPE_ARRAY; + } + + public ICPPParameter[] getParameters() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } + + public int getRequiredArgumentCount() throws DOMException { + return 1; + } + + public boolean hasParameterPack() { + return false; + } + + public IScope getFunctionScope() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } + + public boolean isStatic() throws DOMException { + return false; + } + + public boolean isExtern() throws DOMException { + return false; + } + + public boolean isAuto() throws DOMException { + return false; + } + + public boolean isRegister() throws DOMException { + return false; + } + + public boolean takesVarArgs() throws DOMException { + return false; + } + + public String getName() { + throw new AssertionError(UNEXPECTED_CALL); + } + + public char[] getNameCharArray() { + throw new AssertionError(UNEXPECTED_CALL); + } + + public ILinkage getLinkage() throws CoreException { + throw new AssertionError(UNEXPECTED_CALL); + } + + public IBinding getOwner() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } + + public IScope getScope() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } + + @SuppressWarnings("rawtypes") + public Object getAdapter(Class adapter) { + throw new AssertionError(UNEXPECTED_CALL); + } + + public String[] getQualifiedName() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } + + public char[][] getQualifiedNameCharArray() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } + + public boolean isGloballyQualified() throws DOMException { + throw new AssertionError(UNEXPECTED_CALL); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 3c0c8ee400a..bf22ae2c13e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -275,6 +275,19 @@ public class CPPTemplates { return null; } + private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, + ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map) throws DOMException { + ICPPTemplateInstance instance= getInstance(template, arguments, false); + if (instance != null) { + return instance; + } + + IBinding owner= template.getOwner(); + instance = CPPTemplates.createInstance(owner, template, map, arguments); + addInstance(template, arguments, instance); + return instance; + } + /** * Instantiates a partial class template specialization. */ @@ -316,19 +329,6 @@ public class CPPTemplates { return instance; } - private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, - ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map) throws DOMException { - ICPPTemplateInstance instance= getInstance(template, arguments, false); - if (instance != null) { - return instance; - } - - IBinding owner= template.getOwner(); - instance = CPPTemplates.createInstance(owner, template, map, arguments); - addInstance(template, arguments, instance); - return instance; - } - /** * Obtains a cached instance from the template. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 99e8812dc6d..72b1b07e1b3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -15,6 +15,8 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; +import java.util.BitSet; + import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.EScopeKind; @@ -40,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTInitializer; +import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTInitializerList; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -79,6 +82,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; @@ -88,10 +92,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; @@ -115,12 +121,14 @@ 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.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope; @@ -160,6 +168,8 @@ 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.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerToMemberType; @@ -176,6 +186,7 @@ public class CPPVisitor extends ASTQueries { public static final char[] PTRDIFF_T = "ptrdiff_t".toCharArray(); //$NON-NLS-1$ public static final String STD = "std"; //$NON-NLS-1$ public static final String TYPE_INFO= "type_info"; //$NON-NLS-1$ + private static final String INITIALIZER_LIST = "initializer_list"; //$NON-NLS-1$ public static IBinding createBinding(IASTName name) { IASTNode parent = name.getParent(); @@ -312,7 +323,6 @@ public class CPPVisitor extends ASTQueries { return enumtor; } - private static IBinding createBinding(IASTEnumerationSpecifier specifier) { ICPPScope scope = (ICPPScope) getContainingScope(specifier); IBinding enumeration; @@ -1662,26 +1672,6 @@ public class CPPVisitor extends ASTQueries { return pt; } - /** - * @param declarator - * @return - */ - private static IType createType(IType baseType, IASTDeclarator declarator) { - if (declarator instanceof ICPPASTFunctionDeclarator) - return createType(baseType, (ICPPASTFunctionDeclarator)declarator); - - IType type = baseType; - type = getPointerTypes(type, declarator); - if (declarator instanceof IASTArrayDeclarator) - type = getArrayTypes(type, (IASTArrayDeclarator) declarator); - - IASTDeclarator nested = declarator.getNestedDeclarator(); - if (nested != null) { - return createType(type, nested); - } - return type; - } - private static IType getPointerTypes(IType type, IASTDeclarator declarator) { IASTPointerOperator[] ptrOps = declarator.getPointerOperators(); for (IASTPointerOperator ptrOp : ptrOps) { @@ -1743,7 +1733,7 @@ public class CPPVisitor extends ASTQueries { assert false; return null; } - + IType type = createType(declSpec); type = createType(type, declarator); @@ -1761,19 +1751,69 @@ public class CPPVisitor extends ASTQueries { } } } + if (declSpec instanceof ICPPASTSimpleDeclSpecifier && + ((ICPPASTSimpleDeclSpecifier) declSpec).getType() == ICPPASTSimpleDeclSpecifier.t_auto) { + parent = parent.getParent(); + if (parent instanceof ICPPASTNewExpression) { + IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); + IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); + if (arguments.length == 1) { + initClause = arguments[0]; + } + } + type = createAutoType(initClause, declSpec, declarator); + } if (type != null && isPackExpansion) { type= new CPPParameterPackType(type); } return type; } + private static IType createAutoType(IASTNode initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { + // C++0x: 7.1.6.4 + IType type = AutoTypeResolver.AUTO_TYPE; + ICPPClassTemplate initializer_list_template = null; + if (initClause instanceof ICPPASTInitializerList) { + initializer_list_template = get_initializer_list(declSpec); + if (initializer_list_template == null) { + return null; + } + type = (IType) CPPTemplates.instantiate(initializer_list_template, + new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true); + } + type = decorateType(type, declSpec, declarator); + + IType initType = null; + if (initClause instanceof IASTExpression) { + initType = ((IASTExpression) initClause).getExpressionType(); + } else if (initClause instanceof ICPPASTInitializerList) { + initType = new InitializerListType((ICPPASTInitializerList) initClause); + } + if (initType == null) { + return null; + } + ICPPFunctionTemplate template = new AutoTypeResolver(type); + CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1); + TemplateArgumentDeduction.deduceFromFunctionArgs(template, new IType[] { initType }, new BitSet(), + paramMap, false); + ICPPTemplateArgument argument = paramMap.getArgument(0, 0); + if (argument == null) { + return null; + } + type = argument.getTypeValue(); + if (initClause instanceof ICPPASTInitializerList) { + type = (IType) CPPTemplates.instantiate(initializer_list_template, + new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, true); + } + return decorateType(type, declSpec, declarator); + } + public static IType createType(IASTDeclSpecifier declSpec) { IType type = getBaseType(declSpec); - - if (type != null && (declSpec.isConst() || declSpec.isVolatile())) { - type = new CPPQualifierType(type, declSpec.isConst(), declSpec.isVolatile()); - } - return type; + if (type == null) { + return null; + } + return qualifyType(type, declSpec); } private static IType getBaseType(IASTDeclSpecifier declSpec) { @@ -1791,7 +1831,7 @@ public class CPPVisitor extends ASTQueries { ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; // Check for decltype(expr) type = getDeclType(spec); - if (type == null) { + if (type == null && spec.getType() != ICPPASTSimpleDeclSpecifier.t_auto) { type = new CPPBasicType(spec); } } @@ -1824,6 +1864,39 @@ public class CPPVisitor extends ASTQueries { return type; } + private static IType decorateType(IType type, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { + type = qualifyType(type, declSpec); + type = createType(type, declarator); + return type; + } + + private static IType qualifyType(IType type, IASTDeclSpecifier declSpec) { + if (declSpec.isConst() || declSpec.isVolatile()) { + type = new CPPQualifierType(type, declSpec.isConst(), declSpec.isVolatile()); + } + return type; + } + + /** + * @param declarator + * @return + */ + private static IType createType(IType baseType, IASTDeclarator declarator) { + if (declarator instanceof ICPPASTFunctionDeclarator) + return createType(baseType, (ICPPASTFunctionDeclarator)declarator); + + IType type = baseType; + type = getPointerTypes(type, declarator); + if (declarator instanceof IASTArrayDeclarator) + type = getArrayTypes(type, (IASTArrayDeclarator) declarator); + + IASTDeclarator nested = declarator.getNestedDeclarator(); + if (nested != null) { + return createType(type, nested); + } + return type; + } + /** * Compute the type for decltype(expr) or typeof(expr) */ @@ -1968,7 +2041,25 @@ public class CPPVisitor extends ASTQueries { } return new CPPBasicType(Kind.eInt, IBasicType.IS_LONG | IBasicType.IS_UNSIGNED); } - + + public static ICPPClassTemplate get_initializer_list(IASTNode node) { + try { + IBinding[] std= node.getTranslationUnit().getScope().find(STD); + for (IBinding binding : std) { + if (binding instanceof ICPPNamespace) { + IBinding[] initializer_list= ((ICPPNamespace) binding).getNamespaceScope().find(INITIALIZER_LIST); + for (IBinding t : initializer_list) { + if (t instanceof ICPPClassTemplate) { + return (ICPPClassTemplate) t; + } + } + } + } + } catch (DOMException e) { + } + return null; + } + public static IASTProblem[] getProblems(IASTTranslationUnit tu) { CollectProblemsAction action = new CollectProblemsAction(); tu.accept(action);