the result type of the expr node.
Implement isIntegerConstantExpr for ImplicitCastExpr nodes the same
was as for CastExpr nodes.
Implement proper sign/zero extension as well as truncation and noop
conversion in the i-c-e evaluator. This allows us to correctly
handle i-c-e's like these:
char array[1024/(sizeof (long))];
int x['\xBb' == (char) 187 ? 1: -1];
this implements test/Sema/i-c-e2.c
llvm-svn: 39888
previous two checkins, which involved lot's of tedious refactoring, this checkin is nice and clean:-)
- Hacked UsualUnaryConversions, UsualArithmeticConversions, and DefaultFunctionArrayConversion
to create the AST node (using a helper function promoteExprToType).
- Added a setType method to Expr.
- Changed Expr::isIntegerConstantExpr to allow for the new node.
llvm-svn: 39866
Submitted by:
Reviewed by:
Two vector fixes:
- Sema::CheckAssignmentConstraints() needs to compare the canonical type.
- Expr::isLvalue() needs to disallow subscripting into a vector returned by a function. This
follows the rules for struct returns (in C, at least...C++ is another story:-)
Here is an example...
float4 float4_return()
{
float4 xx;
return xx;
}
void add_float4_void_return(float4 *a, float4 *b, float4 *result)
{
float f;
float4_return()[1] = f; // now illegal
}
llvm-svn: 39728
out of the llvm namespace. This makes the clang namespace be a sibling of
llvm instead of being a child.
The good thing about this is that it makes many things unambiguous. The
bad things is that many things in the llvm namespace (notably data structures
like smallvector) now require an llvm:: qualifier. IMO, libsystem and libsupport
should be split out of llvm into their own namespace in the future, which will fix
this issue.
llvm-svn: 39659
check canonical types in a few places. Tighten up VerifyConstantArrayType
to diagnose more errors, now that we can evaluate i-c-e's. Add some fixmes
about poor diagnostics.
We now correctly typecheck this example:
void s(void) {
typedef int a[(int) +1.0];
static a b; // invalid, static VLA
static int c[(int) +1.0]; // invalid, static VLA
}
void t(void) {
typedef int a[(int)1.0];
static a b; // valid, constant size
}
void u() {
static int X[-1];
static int Y[0];
}
producing:
static-vla.c:3:12: error: variable length array declared outside of any function
static a b; // invalid, static VLA
^
static-vla.c:5:14: error: variable length array declared outside of any function
static int c[(int) +1.0]; // invalid, static VLA
^ ~~~~~~~~~~
static-vla.c:15:14: error: array size is negative
static int X[-1];
^ ~~
static-vla.c:16:14: warning: zero size arrays are an extension
static int Y[0];
^ ~
llvm-svn: 39587
1. Compute and return the value of the i-c-e if the expression is one.
2. Use this computation to correctly track whether subexprs are being
evaluated, and use this to guide diagnostics appropriately.
This allows us to correctly handle all the cases in:
void bar() {
int foo();
switch (1) {
case 1 ? 0 : foo(): // bad
case 0 ? 0 : foo(): // bad
case 0 ? 1/0 : 14 : // ok
case 1 ? 1/0 : 14 : // bad
;
}
switch (1) {
case 1 ? 2: (2, 3): // ok
case 0 ? 2: (2, 3): // invalid comma.
;
}
}
This code has numerous todo items. Specifically, we need to:
1. Pass in target info, so we know the size of the integers we are producing.
2. Model type sizes and alignments correctly, so we can eval sizeof/alignof
3. Handle promotions (need to talk to steve about this).
4. Return an enum that can be used to better diagnose problems with i-c-e's.
instead of just saying "this isn't valid" we should be able to say why.
5. Various other miscellanea, like handling enums and character literals
properly.
llvm-svn: 39585
Submitted by:
Reviewed by:
- Added type checking to Sema::ParseReturnStmt (still under construction).
- Improved Expr::isLvalue() and Expr::isModifiableLvalue() to return more
info. Used the info in Sema::CheckAssignmentOperands() to produce more
descriptive diagnostics. Added FIXME to other clients of isLvalue()/etc.
- Added a SourceLocation slot to MemberExpr...changed the implementation
of getSourceRange().
- Added getResultType() helper to FunctionDecl.
- Changed many Diag calls to use the SourceRange support (now that it's
a big hit...we better milk it:-).
llvm-svn: 39501
Submitted by:
Reviewed by:
Fix two bugs...
- Sema::CheckConditionalOperands(). Needed to move the check for
null pointer constants up to the clause dealing with two pointers types.
The previous code would never get executed.
- Expr::isNullPointerConstant(). This predicate was much too naive...it
should have had a FIXME (my bad). It now deals with "void *" cast expressions.
It still has one major bug...it needs to evaluate the expression to correctly
determine if it is a null pointer constant (e.g. 7-7 should pass).
llvm-svn: 39464
Submitted by:
Reviewed by:
Extended Expr's constant expression predicates to return a source location
if the predicate returns false. This enables us to position the cursor
exactly were the error occurred (simple pleasures:-).
constant.c:9:9: error: enumerator value for 'E2' is not an integer constant
E2 = (aconst + 1), // illegal
^
constant.c:10:8: error: enumerator value for 'E3' is not an integer constant
E3 = "abc",
^
constant.c:12:12: error: enumerator value for 'E5' is not an integer constant
E5 = 0?7:printf("xx"), // illegal
^
constant.c:13:12: error: enumerator value for 'E6' is not an integer constant
E6 = 1?7:printf("xx"), // legal
^
constant.c:16:14: error: enumerator value for 'E9' is not an integer constant
E9 = E0 || a, // illegal
^
constant.c:21:6: error: array has incomplete element type 'void'
void ary[7];
^
constant.c:22:28: error: variable length array declared outside of any function
struct { int a; } ary2[1?7:printf("xx")],
^
constant.c:23:34: error: variable length array declared outside of any function
aryIllegal[0?7:printf("yy")];
^
constant.c:25:10: error: variable length array declared outside of any function
int ary3[a]; // illegal
^
constant.c:26:17: error: size of array has non-integer type 'float'
typedef int vla[2.0]; // illegal
^
constant.c:30:22: error: size of array has non-integer type 'float'
int nonIntegerArray2[1+2.0];
^
llvm-svn: 39454
Submitted by:
Reviewed by:
Refinements to the SourceRange/SourceLocation work.
- Renamed Expr::getSourceLocation() helper function to getLocStart(). Added
Expr::getLocEnd(). Converted all the getSourceRange() methods to use the new helpers.
- Removed many getSourceLocation() accessors. The Expr::getLocStart() helper
is the "right" way to get a source location. If we want to add class specific
getters (for location), then the names should be reflective of the specific class.
For examaple, UnaryOperator::getOpLocation(). For now, I see no reason to have these.
- Fixed StringLiteral.
- Start actually instantiating ParenExpr()!
llvm-svn: 39453
Submitted by:
Reviewed by:
- Added a getSourceRange() method to all subclasses of Expr.
- Changed all the constructors and instantiators.
- Only added SourceLocations's when necessary. For example, binary
expression *don't* carry the operator location...it isn't
necessary to implement getSourceRange(). On the other hand, unary
expressions *do* carry the operator location.
- Added trivial SourceRange value class to SourceLocation.
Note: need to talk to Chris about the FIXME for StringLiteral...
llvm-svn: 39452
Submitted by:
Reviewed by:
- Unified isConstantExpr/isIntegerConstantExpr by creating a private function
named isConstantExpr (that takes a bool to indicate the flavor). isConstantExpr
and isIntegerConstantExpr are now inline wrapper/helper functions.
- Fixed bug in expression based sizeof (it needed to make sure the type is constant).
- Added Sema::CheckConditionalOperands() stub. Will add contraints in my next commit.
llvm-svn: 39446
Submitted by:
Reviewed by:
- Completed Expr::isConstantExpr() and Expr::isIntegerConstantExpr().
- Completed Sema::ParseUnaryOp(), it lacked support for sizeof/alignof.
- Added Sema::CheckSizeOfAlignOfOperand(), used by ParseUnaryOp/ParseSizeOfAlignOfTypeExpr.
- Fixed a couple bugs in CheckRelationalOperands/CheckEqualityOperands (make sure extensions aren't treated as errors).
- Changed a bunch of predicates (in BinaryOperator/UnaryOperator) to member functions (the static members weren't being used).
- Added UnaryOperator::isIncrementDecrementOp/isSizeOfAlignOfOp.
llvm-svn: 39445
Submitted by:
Reviewed by:
Fixed a bug in Sema::CheckAddressOfOperand(). It was (incorrectly) using
isModifiableLvalue() instead of isLvalue(). This motivated me to (finally)
cleanup methods surrounding lsLvalue/isModifiableLvalue. Cleanup involved:
- adding Expr::isLvalue().
- modified Expr::isModifiableLvalue() to use Expr::isLvalue().
- removed Type::isLvalue(), Type::isModifiableLvalue(), and
QualType::isModifiableLvalue(). They were confusing...the respective logic
is now a part of the Expr member functions...
- also added some comments and spec references, since these methods are
so central to expressions working properly.
llvm-svn: 39443
Submitted by:
Reviewed by:
- Added Sema::isConstantArrayType() and Type::isConstantSizeType().
- Implemented type checking for "variably modified" types (i.e. VLA's).
Added checking for file scope variables, static variables, member variables,
and typedefs.
- Changed Expr::isIntegerConstantExpr() to non-virtual implementation.
Fixed bug with sizeof/alignof. Looking at the diff, I may need to
add a check to exclude alignof.
- Added Expr::isConstantExpr()...non-virtual, like above.
- Added typechecking for case statements (found a bug with actions/parsing...).
- Added several diagnostics.
- Fixed several comments.
Started implemented constant expression checking for arrays.
llvm-svn: 39437
Submitted by:
Reviewed by:
- Unified CheckSimpleAssignmentOperands/CheckCompoundAssignmentOperands
into one function, named CheckAssignmentOperands. One less function to maintain.
- Converted the unary check functions (ParseUnaryOp and friends) to have
the same API as their binary counterparts.
- Implemented CheckIndirectionOperand (was stubbed). While testing, noticed
that Expr::isModifiableLvalue was incomplete (fixed and referenced draft).
- Added constantOne instance variable to Sema.
- Removed CheckArithmeticOperand (the code was so simple that it is now
part of ParseUnaryOp). The name wasn't great anyway:-)
llvm-svn: 39435
Submitted by:
Reviewed by:
Implemented type checking for compound assignments (*=, /=, etc.).
This encouraged me to do a fairly dramatic refactoring of the Check* functions.
(since I wanted to reuse the existing work, rather than duplicate the logic).
For example, I changed all the Check* functions to return a QualType (instead
of returning an Expr). This had a very nice side benefit...there is now
only one instantiation point for BinaryOperator()! (A property I've always
wanted...separating type checking from AST building is *much* nicer). Another
change is to remove "code" from all the Check* functions (this allowed
me to remove the weird comment about enums/unsigned:-). Removing the
code forced me to add a few functions, however. For example,
< ExprResult CheckAdditiveOperands( // C99 6.5.6
< Expr *lex, Expr *rex, SourceLocation OpLoc, unsigned OpCode);
> inline QualType CheckAdditionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
> inline QualType CheckSubtractionOperands( // C99 6.5.6
> Expr *lex, Expr *rex, SourceLocation OpLoc);
While this isn't as terse, it more closely reflects the differences in
the typechecking logic. For example, I disliked having to check the code again
in CheckMultiplicativeOperands/CheckAdditiveOperands.
Created the following helper functions:
- Expr::isNullPointerConstant().
- SemaExpr.cpp: static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode().
This was purely asethetic, since ParseBinOp() is now larger. I didn't feel
like looking at 2 huge switch statements. ParseBinOp() now avoids using
any of the BinaryOperator predicates (since I switched to a switch statement:-)
Only one regret (minor). I couldn't figure out how to avoid having two assign functions,
CheckCompoundAssignmentOperands, CheckSimpleAssignmentOperands. Conceptually,
the two functions make sense. Unfortunately, their implementation contains a lot of
duplication (thought they aren't that be in the first place).
llvm-svn: 39433
Submitted by:
Reviewed by:
Work on finishing up typechecking for simple assignments (=) and function
calls. Here is an overview:
- implemented type checking for function calls (in Sema::ParseCallExpr).
- refactored UsualAssignmentConversions to return the result of the conversion.
This enum will allow all clients to emit different diagnostics based on context.
- fixed bug in Expr::isLvalue()...it wasn't handling arrays properly. Also
changed the name to isModifiableLvalue, which is consistent with the function on QualType.
- Added 6 diagnostics (3 errors, 3 extensions).
llvm-svn: 39432
Submitted by:
Reviewed by:
A bunch of "small" changes...
- Fixed a bug in ConvertFloatingRankToComplexType() that rendered it useless.
ASTContext was being copied by default (as the result of declaring the argument
incorrectly). Chris gave me the magic potion to disallow this in ASTContext.
- Removed a tab:-)
- Added some much needed comments to the float/complex promotion madness.
- Improved some aesthetics (based on code review w/Chris).
llvm-svn: 39414
Submitted by:
Reviewed by:
Continue working on type checking for unary operators. Added:
- Two 3 private functions to Sema: CheckAddressOfOperand(), CheckIndirectionOperand(),
and getDecl().
- Added Expr::isLvalue() - it was needed for CheckAddressOfOperand(). It will
also be needed for ++/-- and the assignment operators.
- Added a couple diagnostics for invalid lvalues (for & of).
llvm-svn: 39408
Submitted by:
Reviewed by:
-Changed the name of TypeRef to QualType. Many diffs.
-Changed the QualType constructor to require Quals be passed. This makes the code a bit
more verbose, however will make the code easier to work on. Given the complexity
of types, this should help spot bogosities.
-Changed the Expr constructor to require a QualType. Same motivation.
llvm-svn: 39395
Submitted by:
Reviewed by:
Fix "FIXME: does this lose qualifiers from the typedef??" in ASTContext::getTypedefType().
This change was fairly pervasive...nevertheless, here are the highlights:
- Change the type of Type::CanonicalType to TypeRef (was "Type *").
- Change the implementation of TypeRef::getCanonicalType() to work for typedefs.
- Make the implementation of Type::getCanonicalType private (only TypeRef should access). This
will force clients to use TypeRef::getCanonicalType (the correct version of the function). Since
TypeRef overloads "->", it was very easy to fall into this bug...
- Changed many references of "Type *" to "TypeRef"...when the raw type pointer is required, use t.getTypePtr().
- Changed all the *Type classes to take a TypeRef.
- Made the Type constructor protected (cleanup).
- Removed function Expr::getType().
- Convert functions in SemaExpr to use the above support. This fixed the "const" bug I was originally investigating.
I will follow this check-in up with a rename of TypeRef->QualType. I will also make sure the constructor does not default to 0 (which can lead to broken code...).
llvm-svn: 39394
Submitted by:
Reviewed by:
Type Checking...round 2. This checkin "breaks" parsing carbon.h. I imagine
that this will be true for the next week or so. Nevertheless, this round of
changes includes the following:
- Hacked various Expr classes to pass the appropriate TypeRef. Still have
a few more classes to touch.
- Implement type checking for ParseArraySubscriptExpr and ParseMemberReferenceExpr.
- Added a debug hook to derive the class name for Stmt/Expr nodes. Currently a
linear search...could easily optimize if important.
- Changed the name of TaggedType->TagType. Now we have TagType and TagDecl (which
are easier to remember).
- Fixed a bug in StringLiteral conversion I did a couple weeks ago. hadError was
not initialized (oops).
- changed Sema::Diag to return true. This streamlines the type checking code
considerably.
- Added many diagnositics.
This should be it!
llvm-svn: 39361
- adding enum constants & instance data to Stmt.
- adding classof() functions to all Stmt's.
- modifying contructors to pass the appropriate enum as an arg.
Also tightened up a couple "void *" declarations/casts for arrays.
llvm-svn: 39343
clang still compiled/linked/ran properly...simply a confusing name regression.
From now on I'll make sure I run "cvs diff" before committing any changes!
llvm-svn: 39342