[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