mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Support for C++0x 'auto' keyword and a test case. Bug 289542.
This commit is contained in:
parent
0c0bb08f51
commit
4c3dd79ee8
19 changed files with 376 additions and 86 deletions
|
@ -8077,7 +8077,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
String code= getAboveComment();
|
||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||
}
|
||||
|
||||
|
||||
// namespace std {
|
||||
// template<typename T> 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<typename T> 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<typename T> 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<char>", 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<double> *", ASTTypeUtil.getType(t.getType()));
|
||||
ICPPVariable x= bh.assertNonProblem("x;", 1);
|
||||
assertNull(x.getType());
|
||||
ICPPVariable y= bh.assertNonProblem("y =", 1);
|
||||
assertNull(y.getType());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,5 +27,4 @@ public class RewriteTests extends TestSuite {
|
|||
suite.addTest(ChangeGeneratorTestSuite.suite());
|
||||
return suite;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ public class ASTWriterTest extends RewriteBaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
file = project.getFile("ASTWritterTest.h"); //$NON-NLS-1$
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
auto int autoCPPVariable;
|
||||
int autoCPPVariable;
|
||||
extern int externCPPVariable;
|
||||
register int registerCPPVariable;
|
||||
static int staticCPPVariable;
|
||||
|
|
|
@ -19,7 +19,7 @@ static int c;
|
|||
//Test7
|
||||
int foo()
|
||||
{
|
||||
auto int i = 1;
|
||||
int i = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ extern int b;
|
|||
static int c;
|
||||
int foo()
|
||||
{
|
||||
auto int i = 1;
|
||||
int i = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ public class BaseTestCase extends TestCase {
|
|||
}
|
||||
}
|
||||
|
||||
if (testThrowable!=null)
|
||||
if (testThrowable != null)
|
||||
throw testThrowable;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* <code>auto c = expression;</code>
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final int t_auto = 10;
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue