mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
Classification of literals, by Richard Miskin, bug 269705.
This commit is contained in:
parent
08ce7b77df
commit
8d8462bc93
2 changed files with 257 additions and 2 deletions
|
@ -18,6 +18,7 @@ import junit.framework.TestSuite;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||
|
@ -96,12 +97,14 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
|||
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
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.gnu.cpp.IGPPBasicType;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
@ -6022,4 +6025,200 @@ public class AST2Tests extends AST2BaseTest {
|
|||
assertInstance(nodes[0], IASTPointerOperator.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// int a = -142;
|
||||
// int b = 456L;
|
||||
// int c = 100000LL;
|
||||
// int d = 0U;
|
||||
// int e = 1UL;
|
||||
// int f = 9u;
|
||||
// int g = 1234l;
|
||||
// int h = -123ll;
|
||||
// int i = 8888uL;
|
||||
public void testBug269705_int_literal() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
|
||||
for (ParserLanguage lang : ParserLanguage.values()) {
|
||||
IASTTranslationUnit tu = parseAndCheckBindings(code, lang);
|
||||
IASTDeclaration[] declarations = tu.getDeclarations();
|
||||
|
||||
// int a = -142;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 0);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int b = 456L;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 1);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertTrue(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int c = 100000LL;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 2);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isLong());
|
||||
assertTrue(isLongLong(t));
|
||||
}
|
||||
|
||||
// int d = 0U;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 3);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertTrue(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(isLongLong(t));
|
||||
assertFalse(t.isLong());
|
||||
|
||||
}
|
||||
|
||||
// int e = 1UL;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 4);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertTrue(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertTrue(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int f = 9u;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 5);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertTrue(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(isLongLong(t));
|
||||
assertFalse(t.isLong());
|
||||
|
||||
}
|
||||
|
||||
// int g = 1234l;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 6);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertTrue(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int h = -123ll;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 7);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isLong());
|
||||
assertTrue(isLongLong(t));
|
||||
}
|
||||
|
||||
// int i = 8888uL;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 8);
|
||||
assertTrue(t.getType() == IBasicType.t_int);
|
||||
assertTrue(t.isUnsigned());
|
||||
assertFalse(t.isSigned());
|
||||
assertTrue(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// int a = -142.0;
|
||||
// int b = 456.1f;
|
||||
// int c = 100000.99F;
|
||||
// int d = 0.123l;
|
||||
// int e = 1.3L;
|
||||
public void testBug269705_float_literal() throws Exception {
|
||||
final String code= getAboveComment();
|
||||
|
||||
for (ParserLanguage lang : ParserLanguage.values()) {
|
||||
IASTTranslationUnit tu = parseAndCheckBindings(code, lang);
|
||||
IASTDeclaration[] declarations = tu.getDeclarations();
|
||||
|
||||
// int a = -142.0;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 0);
|
||||
assertTrue(t.getType() == IBasicType.t_double);
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int b = 456.1f;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 1);
|
||||
assertTrue(t.getType() == IBasicType.t_float);
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int c = 100000.99F;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 2);
|
||||
assertTrue(t.getType() == IBasicType.t_float);
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
|
||||
// int d = 0.123l;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 3);
|
||||
assertTrue(t.getType() == IBasicType.t_double);
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isUnsigned());
|
||||
assertFalse(isLongLong(t));
|
||||
assertTrue(t.isLong());
|
||||
}
|
||||
|
||||
// int e = 1.3L;
|
||||
{
|
||||
IBasicType t = getTypeForDeclaration(declarations, 4);
|
||||
assertTrue(t.getType() == IBasicType.t_double);
|
||||
assertFalse(t.isSigned());
|
||||
assertFalse(t.isUnsigned());
|
||||
assertTrue(t.isLong());
|
||||
assertFalse(isLongLong(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isLongLong(IType t) throws DOMException {
|
||||
if (t instanceof ICBasicType) {
|
||||
return ((ICBasicType) t).isLongLong();
|
||||
}
|
||||
if (t instanceof IGPPBasicType) {
|
||||
return ((IGPPBasicType) t).isLongLong();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param declarations
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private IBasicType getTypeForDeclaration(IASTDeclaration[] declarations, int index) {
|
||||
IASTInitializer init = ((IASTSimpleDeclaration)declarations[index]).getDeclarators()[0].getInitializer();
|
||||
return (IBasicType)((IASTInitializerExpression)init).getExpression().getExpressionType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,9 +88,9 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
|
|||
case IASTLiteralExpression.lk_char_constant:
|
||||
return new CBasicType(IBasicType.t_char, 0, this);
|
||||
case IASTLiteralExpression.lk_float_constant:
|
||||
return new CBasicType(IBasicType.t_float, 0, this);
|
||||
return classifyTypeOfFloatLiteral();
|
||||
case IASTLiteralExpression.lk_integer_constant:
|
||||
return new CBasicType(IBasicType.t_int, 0, this);
|
||||
return classifyTypeOfIntLiteral();
|
||||
case IASTLiteralExpression.lk_string_literal:
|
||||
IType type = new CBasicType(IBasicType.t_char, 0, this);
|
||||
type = new CQualifierType(type, true, false, false);
|
||||
|
@ -99,6 +99,62 @@ public class CASTLiteralExpression extends ASTNode implements IASTLiteralExpress
|
|||
return null;
|
||||
}
|
||||
|
||||
private IType classifyTypeOfFloatLiteral() {
|
||||
final char[] lit= getValue();
|
||||
final int len= lit.length;
|
||||
int kind= IBasicType.t_double;
|
||||
int flags= 0;
|
||||
if (len > 0) {
|
||||
switch (lit[len - 1]) {
|
||||
case 'f': case 'F':
|
||||
kind= IBasicType.t_float;
|
||||
break;
|
||||
case 'l': case 'L':
|
||||
kind= IBasicType.t_double;
|
||||
flags |= CBasicType.IS_LONG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return new CBasicType(kind, flags, this);
|
||||
}
|
||||
|
||||
private IType classifyTypeOfIntLiteral() {
|
||||
int makelong= 0;
|
||||
boolean unsigned= false;
|
||||
|
||||
final char[] lit= getValue();
|
||||
for (int i= lit.length - 1; i >= 0; i--) {
|
||||
final char c= lit[i];
|
||||
if (!(c > 'f' && c <= 'z') && !(c > 'F' && c <= 'Z')) {
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case 'u':
|
||||
case 'U':
|
||||
unsigned = true;
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
makelong++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int flags= 0;
|
||||
if (unsigned) {
|
||||
flags |= CBasicType.IS_UNSIGNED;
|
||||
}
|
||||
|
||||
if (makelong > 1) {
|
||||
flags |= CBasicType.IS_LONGLONG;
|
||||
} else if (makelong == 1) {
|
||||
flags |= CBasicType.IS_LONG;
|
||||
}
|
||||
return new CBasicType(IBasicType.t_int, flags, this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated, use {@link #setValue(char[])}, instead.
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue