[cfe-commits] r39361 - in /cfe/cfe/trunk: AST/ASTContext.cpp AST/Expr.cpp AST/Sema.cpp AST/Sema.h AST/SemaExpr.cpp AST/Stmt.cpp AST/Type.cpp Lex/LiteralSupport.cpp Parse/ParseExpr.cpp Sema/Sema.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/Decl.h include/clang/AST/Expr.h include/clang/AST/Stmt.h include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def
snaroff at cs.uiuc.edu
snaroff at cs.uiuc.edu
Wed Jul 11 09:43:36 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:43:36 2007
New Revision: 39361
URL: http://llvm.org/viewvc/llvm-project?rev=39361&view=rev
Log:
Bug #:
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!
Modified:
cfe/cfe/trunk/AST/ASTContext.cpp
cfe/cfe/trunk/AST/Expr.cpp
cfe/cfe/trunk/AST/Sema.cpp
cfe/cfe/trunk/AST/Sema.h
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/AST/Stmt.cpp
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Lex/LiteralSupport.cpp
cfe/cfe/trunk/Parse/ParseExpr.cpp
cfe/cfe/trunk/Sema/Sema.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/Decl.h
cfe/cfe/trunk/include/clang/AST/Expr.h
cfe/cfe/trunk/include/clang/AST/Stmt.h
cfe/cfe/trunk/include/clang/AST/Type.h
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/ASTContext.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:43:36 2007
@@ -55,7 +55,7 @@
++NumFunctionP;
else if (isa<TypedefType>(T))
++NumTypeName;
- else if (TaggedType *TT = dyn_cast<TaggedType>(T)) {
+ else if (TagType *TT = dyn_cast<TagType>(T)) {
++NumTagged;
switch (TT->getDecl()->getKind()) {
default: assert(0 && "Unknown tagged type!");
@@ -280,7 +280,7 @@
// The decl stores the type cache.
if (Decl->TypeForDecl) return Decl->TypeForDecl;
- Types.push_back(Decl->TypeForDecl = new TaggedType(Decl, 0));
+ Types.push_back(Decl->TypeForDecl = new TagType(Decl, 0));
return Types.back();
}
Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:43:36 2007
@@ -22,7 +22,8 @@
//===----------------------------------------------------------------------===//
StringLiteral::StringLiteral(const char *strData, unsigned byteLength,
- bool Wide) : Expr(StringLiteralClass) {
+ bool Wide, TypeRef t) :
+ Expr(StringLiteralClass, t) {
// OPTIMIZE: could allocate this appended to the StringLiteral.
char *AStrData = new char[byteLength];
memcpy(AStrData, strData, byteLength);
@@ -73,7 +74,7 @@
//===----------------------------------------------------------------------===//
CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs)
- : Expr(CallExprClass), Fn(fn), NumArgs(numargs) {
+ : Expr(CallExprClass, fn->getTypeRef()), Fn(fn), NumArgs(numargs) {
Args = new Expr*[numargs];
for (unsigned i = 0; i != numargs; ++i)
Args[i] = args[i];
Modified: cfe/cfe/trunk/AST/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.cpp (original)
+++ cfe/cfe/trunk/AST/Sema.cpp Wed Jul 11 11:43:36 2007
@@ -26,12 +26,14 @@
// Helper functions.
//===----------------------------------------------------------------------===//
-void Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
PP.Diag(Loc, DiagID, Msg);
+ return true;
}
-void Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
+bool Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
Diag(Tok.getLocation(), DiagID, M);
+ return true;
}
const LangOptions &Sema::getLangOptions() const {
Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:36 2007
@@ -53,9 +53,10 @@
const LangOptions &getLangOptions() const;
- void Diag(SourceLocation Loc, unsigned DiagID,
+ /// always returns true, which simplifies error handling (i.e. less code).
+ bool Diag(SourceLocation Loc, unsigned DiagID,
const std::string &Msg = std::string());
- void Diag(const LexerToken &Tok, unsigned DiagID,
+ bool Diag(const LexerToken &Tok, unsigned DiagID,
const std::string &M = std::string());
//===--------------------------------------------------------------------===//
@@ -220,6 +221,8 @@
virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
tok::TokenKind Kind);
private:
+ Expr *ImplicitConversion(Expr *E); // C99 6.3
+
/// type checking binary operators (subroutines of ParseBinOp).
void CheckMultiplicativeOperands(Expr *op1, Expr *op2); // C99 6.5.5
void CheckAdditiveOperands(Expr *op1, Expr *op2); // C99 6.5.6
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:36 2007
@@ -42,11 +42,14 @@
SmallVector<SourceLocation, 4> StringTokLocs;
for (unsigned i = 0; i != NumStringToks; ++i)
StringTokLocs.push_back(StringToks[i].getLocation());
-
+
+ // FIXME: handle wchar_t
+ TypeRef t = Context.getPointerType(Context.CharTy);
+
// FIXME: use factory.
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
- Literal.AnyWide);
+ Literal.AnyWide, t);
}
@@ -63,22 +66,20 @@
// in C90, extension in C99).
if (HasTrailingLParen &&
// Not in C++.
- !getLangOptions().CPlusPlus) {
+ !getLangOptions().CPlusPlus)
D = ImplicitlyDefineFunction(Loc, II, S);
- } else {
+ else
// If this name wasn't predeclared and if this is not a function call,
// diagnose the problem.
- Diag(Loc, diag::err_undeclared_var_use, II.getName());
- return true;
- }
+ return Diag(Loc, diag::err_undeclared_var_use, II.getName());
}
- if (isa<TypedefDecl>(D)) {
- Diag(Loc, diag::err_unexpected_typedef, II.getName());
- return true;
- }
-
- return new DeclRefExpr(D);
+ if (ObjectDecl *OD = dyn_cast<ObjectDecl>(D)) {
+ return new DeclRefExpr(OD);
+ } else if (isa<TypedefDecl>(D))
+ return Diag(Loc, diag::err_unexpected_typedef, II.getName());
+
+ assert(0 && "Invalid decl");
}
Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
@@ -136,7 +137,8 @@
return new IntegerLiteral(val, t);
}
} else if (Literal.isFloatingLiteral()) {
- // TODO: add floating point processing...
+ // FIXME: fill in the value and compute the real type...
+ return new FloatingLiteral(7.7, Context.FloatTy);
}
return ExprResult(true);
}
@@ -199,7 +201,7 @@
return new IntegerLiteral(0, Context.IntTy);
}
- return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy);
+ return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, Context.IntTy);
}
@@ -219,13 +221,59 @@
Action::ExprResult Sema::
ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
ExprTy *Idx, SourceLocation RLoc) {
- return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx);
+ TypeRef t1 = ((Expr *)Base)->getTypeRef();
+ TypeRef t2 = ((Expr *)Idx)->getTypeRef();
+
+ assert(!t1.isNull() && "no type for array base expression");
+ assert(!t1.isNull() && "no type for array index expression");
+
+ // In C, the expression e1[e2] is by definition precisely equivalent to
+ // the expression *((e1)+(e2)). This means the array "Base" may actually be
+ // in the subscript position. As a result, we need to derive the array base
+ // and index from the expression types.
+
+ TypeRef baseType, indexType;
+ if (isa<ArrayType>(t1) || isa<PointerType>(t1)) {
+ baseType = t1;
+ indexType = t2;
+ } else if (isa<ArrayType>(t2) || isa<PointerType>(t2)) { // uncommon case
+ baseType = t2;
+ indexType = t1;
+ } else
+ return Diag(LLoc, diag::err_typecheck_subscript_value);
+
+ if (indexType->isIntegralType())
+ return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, baseType);
+ else
+ return Diag(LLoc, diag::err_typecheck_subscript);
}
Action::ExprResult Sema::
ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
IdentifierInfo &Member) {
+ TypeRef BT = ((Expr *)Base)->getTypeRef();
+
+ assert(!BT.isNull() && "no type for member expression");
+
+ if (OpKind == tok::arrow) {
+ if (PointerType *PT = dyn_cast<PointerType>(BT))
+ BT = PT->getPointeeType();
+ else
+ return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
+ }
+ RecordDecl *RD;
+
+ // derive the structure/union definition from the type.
+ if (BT->isStructureType() || BT->isUnionType()) {
+ TagDecl *TD = cast<TagType>(BT)->getDecl();
+ if (BT->isIncompleteType())
+ return Diag(OpLoc, diag::err_typecheck_incomplete_tag, TD->getName());
+ if (!(RD = dyn_cast<RecordDecl>(TD)))
+ return Diag(OpLoc, diag::err_typecheck_internal_error);
+ } else
+ return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion);
+
Decl *MemberDecl = 0;
// TODO: Look up MemberDecl.
return new MemberExpr((Expr*)Base, OpKind == tok::arrow, MemberDecl);
@@ -288,6 +336,10 @@
case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
case tok::comma: Opc = BinaryOperator::Comma; break;
}
+
+ // perform implicit conversions (C99 6.3)
+ Expr *e1 = ImplicitConversion((Expr*)LHS);
+ Expr *e2 = ImplicitConversion((Expr*)RHS);
if (BinaryOperator::isMultiplicativeOp(Opc))
CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
@@ -316,6 +368,15 @@
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
}
+Expr *Sema::ImplicitConversion(Expr *E) {
+#if 0
+ TypeRef t = E->getTypeRef();
+ if (t != 0) t.dump();
+ else printf("no type for expr %s\n", E->getStmtClassName());
+#endif
+ return E;
+}
+
void Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
}
Modified: cfe/cfe/trunk/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Stmt.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Stmt.cpp (original)
+++ cfe/cfe/trunk/AST/Stmt.cpp Wed Jul 11 11:43:36 2007
@@ -23,3 +23,21 @@
STMT(0, Stmt, )
#include "clang/AST/StmtNodes.def"
+
+static struct StmtClassNameTable {
+ int enumValue;
+ const char *className;
+} sNames[] = {
+#define STMT(N, CLASS, PARENT) { N, #CLASS },
+#include "clang/AST/StmtNodes.def"
+ { 0, 0 }
+};
+
+const char *Stmt::getStmtClassName() const {
+ for (int i = 0; sNames[i].className; i++) {
+ if (sClass == sNames[i].enumValue)
+ return sNames[i].className;
+ }
+ return 0; // should never happen....
+}
+
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:43:36 2007
@@ -42,7 +42,7 @@
}
bool Type::isStructureType() const {
- if (const TaggedType *TT = dyn_cast<TaggedType>(CanonicalType)) {
+ if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
if (TT->getDecl()->getKind() == Decl::Struct)
return true;
}
@@ -50,7 +50,7 @@
}
bool Type::isUnionType() const {
- if (const TaggedType *TT = dyn_cast<TaggedType>(CanonicalType)) {
+ if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
if (TT->getDecl()->getKind() == Decl::Union)
return true;
}
@@ -65,7 +65,7 @@
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::ULongLong;
case Tagged:
- const TaggedType *TT = static_cast<TaggedType*>(CanonicalType);
+ const TagType *TT = static_cast<TagType*>(CanonicalType);
if (TT->getDecl()->getKind() == Decl::Enum)
return true;
return false;
@@ -110,7 +110,7 @@
case Array:
return true;
case Tagged:
- const TaggedType *TT = static_cast<TaggedType*>(CanonicalType);
+ const TagType *TT = static_cast<TagType*>(CanonicalType);
if (TT->getDecl()->getKind() == Decl::Struct)
return true;
return true;
@@ -131,7 +131,7 @@
case Tagged:
// A tagged type (struct/union/enum/class) is incomplete if the decl is a
// forward declaration, but not a full definition (C99 6.2.5p22).
- return !cast<TaggedType>(CanonicalType)->getDecl()->isDefinition();
+ return !cast<TagType>(CanonicalType)->getDecl()->isDefinition();
case Array:
// An array of unknown size is an incomplete type (C99 6.2.5p22).
return cast<ArrayType>(CanonicalType)->getSize() == 0;
@@ -179,7 +179,7 @@
bool RecordType::classof(const Type *T) {
- if (const TaggedType *TT = dyn_cast<TaggedType>(T))
+ if (const TagType *TT = dyn_cast<TagType>(T))
return isa<RecordDecl>(TT->getDecl());
return false;
}
@@ -304,7 +304,7 @@
InnerString = getDecl()->getIdentifier()->getName() + InnerString;
}
-void TaggedType::getAsString(std::string &InnerString) const {
+void TagType::getAsString(std::string &InnerString) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
InnerString = ' ' + InnerString;
Modified: cfe/cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/LiteralSupport.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:36 2007
@@ -322,6 +322,8 @@
SizeBound = StringToks[0].getLength()-2; // -2 for "".
AnyWide = StringToks[0].getKind() == tok::wide_string_literal;
+ hadError = false;
+
// The common case is that there is only one string fragment.
for (unsigned i = 1; i != NumStringToks; ++i) {
// The string could be shorter than this if it needs cleaning, but this is a
Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:43:36 2007
@@ -608,7 +608,7 @@
if (!LHS.isInvalid && !Idx.isInvalid && Tok.getKind() == tok::r_square)
LHS = Actions.ParseArraySubscriptExpr(LHS.Val, Loc, Idx.Val, RLoc);
- else
+ else
LHS = ExprResult(true);
// Match the ']'.
Modified: cfe/cfe/trunk/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/cfe/trunk/Sema/Sema.cpp Wed Jul 11 11:43:36 2007
@@ -26,12 +26,14 @@
// Helper functions.
//===----------------------------------------------------------------------===//
-void Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
+bool Sema::Diag(SourceLocation Loc, unsigned DiagID, const std::string &Msg) {
PP.Diag(Loc, DiagID, Msg);
+ return true;
}
-void Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
+bool Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
Diag(Tok.getLocation(), DiagID, M);
+ return true;
}
const LangOptions &Sema::getLangOptions() const {
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:36 2007
@@ -53,9 +53,10 @@
const LangOptions &getLangOptions() const;
- void Diag(SourceLocation Loc, unsigned DiagID,
+ /// always returns true, which simplifies error handling (i.e. less code).
+ bool Diag(SourceLocation Loc, unsigned DiagID,
const std::string &Msg = std::string());
- void Diag(const LexerToken &Tok, unsigned DiagID,
+ bool Diag(const LexerToken &Tok, unsigned DiagID,
const std::string &M = std::string());
//===--------------------------------------------------------------------===//
@@ -220,6 +221,8 @@
virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
tok::TokenKind Kind);
private:
+ Expr *ImplicitConversion(Expr *E); // C99 6.3
+
/// type checking binary operators (subroutines of ParseBinOp).
void CheckMultiplicativeOperands(Expr *op1, Expr *op2); // C99 6.5.5
void CheckAdditiveOperands(Expr *op1, Expr *op2); // C99 6.5.6
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:36 2007
@@ -42,11 +42,14 @@
SmallVector<SourceLocation, 4> StringTokLocs;
for (unsigned i = 0; i != NumStringToks; ++i)
StringTokLocs.push_back(StringToks[i].getLocation());
-
+
+ // FIXME: handle wchar_t
+ TypeRef t = Context.getPointerType(Context.CharTy);
+
// FIXME: use factory.
// Pass &StringTokLocs[0], StringTokLocs.size() to factory!
return new StringLiteral(Literal.GetString(), Literal.GetStringLength(),
- Literal.AnyWide);
+ Literal.AnyWide, t);
}
@@ -63,22 +66,20 @@
// in C90, extension in C99).
if (HasTrailingLParen &&
// Not in C++.
- !getLangOptions().CPlusPlus) {
+ !getLangOptions().CPlusPlus)
D = ImplicitlyDefineFunction(Loc, II, S);
- } else {
+ else
// If this name wasn't predeclared and if this is not a function call,
// diagnose the problem.
- Diag(Loc, diag::err_undeclared_var_use, II.getName());
- return true;
- }
+ return Diag(Loc, diag::err_undeclared_var_use, II.getName());
}
- if (isa<TypedefDecl>(D)) {
- Diag(Loc, diag::err_unexpected_typedef, II.getName());
- return true;
- }
-
- return new DeclRefExpr(D);
+ if (ObjectDecl *OD = dyn_cast<ObjectDecl>(D)) {
+ return new DeclRefExpr(OD);
+ } else if (isa<TypedefDecl>(D))
+ return Diag(Loc, diag::err_unexpected_typedef, II.getName());
+
+ assert(0 && "Invalid decl");
}
Sema::ExprResult Sema::ParseSimplePrimaryExpr(SourceLocation Loc,
@@ -136,7 +137,8 @@
return new IntegerLiteral(val, t);
}
} else if (Literal.isFloatingLiteral()) {
- // TODO: add floating point processing...
+ // FIXME: fill in the value and compute the real type...
+ return new FloatingLiteral(7.7, Context.FloatTy);
}
return ExprResult(true);
}
@@ -199,7 +201,7 @@
return new IntegerLiteral(0, Context.IntTy);
}
- return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy);
+ return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy, Context.IntTy);
}
@@ -219,13 +221,59 @@
Action::ExprResult Sema::
ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
ExprTy *Idx, SourceLocation RLoc) {
- return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx);
+ TypeRef t1 = ((Expr *)Base)->getTypeRef();
+ TypeRef t2 = ((Expr *)Idx)->getTypeRef();
+
+ assert(!t1.isNull() && "no type for array base expression");
+ assert(!t1.isNull() && "no type for array index expression");
+
+ // In C, the expression e1[e2] is by definition precisely equivalent to
+ // the expression *((e1)+(e2)). This means the array "Base" may actually be
+ // in the subscript position. As a result, we need to derive the array base
+ // and index from the expression types.
+
+ TypeRef baseType, indexType;
+ if (isa<ArrayType>(t1) || isa<PointerType>(t1)) {
+ baseType = t1;
+ indexType = t2;
+ } else if (isa<ArrayType>(t2) || isa<PointerType>(t2)) { // uncommon case
+ baseType = t2;
+ indexType = t1;
+ } else
+ return Diag(LLoc, diag::err_typecheck_subscript_value);
+
+ if (indexType->isIntegralType())
+ return new ArraySubscriptExpr((Expr*)Base, (Expr*)Idx, baseType);
+ else
+ return Diag(LLoc, diag::err_typecheck_subscript);
}
Action::ExprResult Sema::
ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
IdentifierInfo &Member) {
+ TypeRef BT = ((Expr *)Base)->getTypeRef();
+
+ assert(!BT.isNull() && "no type for member expression");
+
+ if (OpKind == tok::arrow) {
+ if (PointerType *PT = dyn_cast<PointerType>(BT))
+ BT = PT->getPointeeType();
+ else
+ return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
+ }
+ RecordDecl *RD;
+
+ // derive the structure/union definition from the type.
+ if (BT->isStructureType() || BT->isUnionType()) {
+ TagDecl *TD = cast<TagType>(BT)->getDecl();
+ if (BT->isIncompleteType())
+ return Diag(OpLoc, diag::err_typecheck_incomplete_tag, TD->getName());
+ if (!(RD = dyn_cast<RecordDecl>(TD)))
+ return Diag(OpLoc, diag::err_typecheck_internal_error);
+ } else
+ return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion);
+
Decl *MemberDecl = 0;
// TODO: Look up MemberDecl.
return new MemberExpr((Expr*)Base, OpKind == tok::arrow, MemberDecl);
@@ -288,6 +336,10 @@
case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
case tok::comma: Opc = BinaryOperator::Comma; break;
}
+
+ // perform implicit conversions (C99 6.3)
+ Expr *e1 = ImplicitConversion((Expr*)LHS);
+ Expr *e2 = ImplicitConversion((Expr*)RHS);
if (BinaryOperator::isMultiplicativeOp(Opc))
CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
@@ -316,6 +368,15 @@
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
}
+Expr *Sema::ImplicitConversion(Expr *E) {
+#if 0
+ TypeRef t = E->getTypeRef();
+ if (t != 0) t.dump();
+ else printf("no type for expr %s\n", E->getStmtClassName());
+#endif
+ return E;
+}
+
void Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
}
Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:43:36 2007
@@ -59,11 +59,12 @@
///
Decl *Next;
-public:
+protected:
Decl(Kind DK, SourceLocation L, IdentifierInfo *Id)
: DeclKind(DK), Loc(L), Identifier(Id), Next(0) {}
virtual ~Decl();
+public:
IdentifierInfo *getIdentifier() const { return Identifier; }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -106,6 +107,8 @@
ObjectDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T,
StorageClass S = None): Decl(DK, L, Id), DeclType(T), SClass(S) {}
public:
+ // FIXME: should rename to getTypeRef/getCanonicalTypeRef to distinguish
+ // TypeRef's from Type's...
TypeRef getType() const { return DeclType; }
TypeRef getCanonicalType() const { return DeclType.getCanonicalType(); }
StorageClass getStorageClass() const { return SClass; }
@@ -185,7 +188,7 @@
/// EnumConstantDecl - An instance of this object exists for each enum constant
/// that is defined. For example, in "enum X {a,b}", each of a/b are
/// EnumConstantDecl's, X is an instance of EnumDecl, and the type of a/b is a
-/// TaggedType for the X EnumDecl.
+/// TagType for the X EnumDecl.
class EnumConstantDecl : public ObjectDecl {
public:
// FIXME: Capture value info.
Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:43:36 2007
@@ -16,6 +16,7 @@
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
+#include "clang/AST/Decl.h"
namespace llvm {
namespace clang {
@@ -27,10 +28,15 @@
/// is required.
///
class Expr : public Stmt {
- TypeRef Type;
-public:
- Expr(StmtClass SC, TypeRef T=0) : Stmt(SC), Type(T) {}
+ TypeRef TR;
+protected:
+ Expr(StmtClass SC, TypeRef T=0) : Stmt(SC), TR(T) {}
~Expr() {}
+public:
+ // FIXME: the return type of getType is inconsistent with ObjectDecl.
+ // this is confusing and needs to be reconciled (by making one conform).
+ Type *getType() const { return TR.getTypePtr(); }
+ TypeRef getTypeRef() const { return TR; }
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
@@ -47,9 +53,9 @@
/// DeclRefExpr - [C99 6.5.1p2] - A reference to a declared variable, function,
/// enum, etc.
class DeclRefExpr : public Expr {
- Decl *D;
+ ObjectDecl *D;
public:
- DeclRefExpr(Decl *d) : Expr(DeclRefExprClass), D(d) {}
+ DeclRefExpr(ObjectDecl *d) : Expr(DeclRefExprClass, d->getType()), D(d) {}
Decl *getDecl() const { return D; }
@@ -77,8 +83,10 @@
};
class FloatingLiteral : public Expr {
+ float Value; // FIXME
public:
- FloatingLiteral() : Expr(FloatingLiteralClass) {}
+ FloatingLiteral(float value, TypeRef type) :
+ Expr(FloatingLiteralClass, type), Value(value) {}
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == FloatingLiteralClass;
@@ -91,7 +99,7 @@
unsigned ByteLength;
bool IsWide;
public:
- StringLiteral(const char *strData, unsigned byteLength, bool Wide);
+ StringLiteral(const char *strData, unsigned byteLength, bool Wide, TypeRef t);
virtual ~StringLiteral();
const char *getStrData() const { return StrData; }
@@ -174,9 +182,9 @@
bool isSizeof; // true if sizeof, false if alignof.
TypeRef Ty;
public:
- SizeOfAlignOfTypeExpr(bool issizeof, TypeRef ty) :
- Expr(SizeOfAlignOfTypeExprClass),
- isSizeof(issizeof), Ty(ty) {}
+ SizeOfAlignOfTypeExpr(bool issizeof, TypeRef argType, TypeRef resultType) :
+ Expr(SizeOfAlignOfTypeExprClass, resultType),
+ isSizeof(issizeof), Ty(argType) {}
bool isSizeOf() const { return isSizeof; }
TypeRef getArgumentType() const { return Ty; }
@@ -196,8 +204,8 @@
class ArraySubscriptExpr : public Expr {
Expr *Base, *Idx;
public:
- ArraySubscriptExpr(Expr *base, Expr *idx) :
- Expr(ArraySubscriptExprClass),
+ ArraySubscriptExpr(Expr *base, Expr *idx, TypeRef t) :
+ Expr(ArraySubscriptExprClass, t),
Base(base), Idx(idx) {}
Expr *getBase() { return Base; }
Modified: cfe/cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Stmt.h?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Stmt.h Wed Jul 11 11:43:36 2007
@@ -43,6 +43,7 @@
virtual ~Stmt() {}
StmtClass getStmtClass() const { return sClass; }
+ const char *getStmtClassName() const;
void dump() const;
void print(std::ostream &OS) const;
Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:43:36 2007
@@ -424,9 +424,9 @@
};
-class TaggedType : public Type {
+class TagType : public Type {
TagDecl *Decl;
- TaggedType(TagDecl *D, Type *can) : Type(Tagged, can), Decl(D) {}
+ TagType(TagDecl *D, Type *can) : Type(Tagged, can), Decl(D) {}
friend class ASTContext; // ASTContext creates these.
public:
@@ -435,17 +435,17 @@
virtual void getAsString(std::string &InnerString) const;
static bool classof(const Type *T) { return T->getTypeClass() == Tagged; }
- static bool classof(const TaggedType *) { return true; }
+ static bool classof(const TagType *) { return true; }
};
/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
-/// to detect TaggedType objects of structs/unions/classes.
-class RecordType : public TaggedType {
+/// to detect TagType objects of structs/unions/classes.
+class RecordType : public TagType {
RecordType(); // DO NOT IMPLEMENT
public:
RecordDecl *getDecl() const {
- return reinterpret_cast<RecordDecl*>(TaggedType::getDecl());
+ return reinterpret_cast<RecordDecl*>(TagType::getDecl());
}
static bool classof(const Type *T);
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39361&r1=39360&r2=39361&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:36 2007
@@ -480,6 +480,18 @@
"exponent has no digits")
DIAG(err_hexconstant_requires_exponent, ERROR,
"hexadecimal floating constants require an exponent")
+DIAG(err_typecheck_subscript_value, ERROR,
+ "subscripted value is neither array nor pointer")
+DIAG(err_typecheck_subscript, ERROR,
+ "array subscript is not an integer")
+DIAG(err_typecheck_member_reference_structUnion, ERROR,
+ "member reference is neither a structure or union")
+DIAG(err_typecheck_member_reference_arrow, ERROR,
+ "member reference is not a pointer")
+DIAG(err_typecheck_incomplete_tag, ERROR,
+ "incomplete definition of struct/union '%s'")
+DIAG(err_typecheck_internal_error, ERROR,
+ "*internal* typechecking error")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
More information about the cfe-commits
mailing list