1
0
Fork 0
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:
Sergey Prigogin 2010-03-15 17:02:26 +00:00
parent 0c0bb08f51
commit 4c3dd79ee8
19 changed files with 376 additions and 86 deletions

View file

@ -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());
}
}

View file

@ -27,5 +27,4 @@ public class RewriteTests extends TestSuite {
suite.addTest(ChangeGeneratorTestSuite.suite());
return suite;
}
}

View file

@ -63,7 +63,6 @@ public class ASTWriterTest extends RewriteBaseTest {
}
}
@Override
protected void runTest() throws Throwable {
file = project.getFile("ASTWritterTest.h"); //$NON-NLS-1$

View file

@ -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"));

View file

@ -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});
}

View file

@ -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);

View file

@ -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 {

View file

@ -1,4 +1,4 @@
auto int autoCPPVariable;
int autoCPPVariable;
extern int externCPPVariable;
register int registerCPPVariable;
static int staticCPPVariable;

View file

@ -19,7 +19,7 @@ static int c;
//Test7
int foo()
{
auto int i = 1;
int i = 1;
return i;
}

View file

@ -12,7 +12,7 @@ extern int b;
static int c;
int foo()
{
auto int i = 1;
int i = 1;
return i;
}

View file

@ -184,7 +184,7 @@ public class BaseTestCase extends TestCase {
}
}
if (testThrowable!=null)
if (testThrowable != null)
throw testThrowable;
}

View file

@ -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);

View file

@ -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
*/

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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.
*/

View file

@ -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);