[cfe-commits] r39360 - in /cfe/cfe/trunk: AST/Sema.h AST/SemaDecl.cpp AST/SemaExpr.cpp AST/Type.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaExpr.cpp include/clang/AST/Expr.h include/clang/AST/Type.h

snaroff at cs.uiuc.edu snaroff at cs.uiuc.edu
Wed Jul 11 09:43:35 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:43:35 2007
New Revision: 39360

URL: http://llvm.org/viewvc/llvm-project?rev=39360&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Implement type checking. First round of changes are:
- Added predicates to Type.
- Added predicates to BinExpr.
- Added Check hooks that model the categories for Binary ops.
- Added TypeRef to Expr. Will lazily eval subclasses...
- Misc bug fixes/cleanups.

Modified:
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/AST/Expr.h
    cfe/cfe/trunk/include/clang/AST/Type.h

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:35 2007
@@ -24,6 +24,7 @@
   class ASTContext;
   class Preprocessor;
   class Decl;
+  class Expr;
   class VarDecl;
   class TypedefDecl;
   class FunctionDecl;
@@ -65,7 +66,7 @@
   virtual TypeResult ParseTypeName(Scope *S, Declarator &D);
   
   virtual TypeResult ParseParamDeclaratorType(Scope *S, Declarator &D);
-  
+private:
   //===--------------------------------------------------------------------===//
   // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
   //
@@ -98,6 +99,9 @@
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
   FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
+  /// AddTopLevelDecl - called after the decl has been fully processed.
+  /// Allows for bookkeeping and post-processing of each declaration.
+  void AddTopLevelDecl(Decl *current, Decl *last);
 
   /// More parsing and symbol table subroutines...
   VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
@@ -215,6 +219,15 @@
   /// ParseCXXBoolLiteral - Parse {true,false} literals.
   virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
                                          tok::TokenKind Kind);
+private:
+  /// 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
+  void CheckShiftOperands(Expr *op1, Expr *op2);          // C99 6.5.7
+  void CheckRelationalOperands(Expr *op1, Expr *op2);     // C99 6.5.8
+  void CheckEqualityOperands(Expr *op1, Expr *op2);       // C99 6.5.9
+  void CheckBitwiseOperands(Expr *op1, Expr *op2);        // C99 6.5.[10...12]
+  void CheckLogicalOperands(Expr *op1, Expr *op2);        // C99 6.5.[13,14]
 };
 
 

Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:43:35 2007
@@ -288,10 +288,8 @@
     S->AddDecl(New);
   }
   
-  // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
-  // remember this in the LastInGroupList list.
-  if (LastInGroup && S->getParent() == 0)
-    LastInGroupList.push_back((Decl*)LastInGroup);
+  if (S->getParent() == 0)
+    AddTopLevelDecl(New, (Decl *)LastInGroup);
   
   return New;
 }
@@ -714,3 +712,12 @@
   Enum->defineElements(&Values[0], Values.size());
 }
 
+void Sema::AddTopLevelDecl(Decl *current, Decl *last) {
+  if (!current) return;
+
+  // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
+  // remember this in the LastInGroupList list.
+  if (last) {
+    LastInGroupList.push_back((Decl*)last);
+  }
+}

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:35 2007
@@ -188,7 +188,7 @@
   if (isa<FunctionType>(ArgTy) && isSizeof) {
     // alignof(function) is allowed.
     Diag(OpLoc, diag::ext_sizeof_function_type);
-    return new IntegerLiteral(/*1*/);
+    return new IntegerLiteral(1, Context.IntTy);
   } else if (ArgTy->isVoidType()) {
     Diag(OpLoc, diag::ext_sizeof_void_type, isSizeof ? "sizeof" : "__alignof");
   } else if (ArgTy->isIncompleteType()) {
@@ -196,7 +196,7 @@
     ArgTy->getAsString(TypeName);
     Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type : 
          diag::err_alignof_incomplete_type, TypeName);
-    return new IntegerLiteral(/*0*/);
+    return new IntegerLiteral(0, Context.IntTy);
   }
   
   return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy);
@@ -289,6 +289,21 @@
   case tok::comma:                Opc = BinaryOperator::Comma; break;
   }
   
+  if (BinaryOperator::isMultiplicativeOp(Opc)) 
+    CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isAdditiveOp(Opc))
+    CheckAdditiveOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isShiftOp(Opc))
+    CheckShiftOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isRelationalOp(Opc))
+    CheckRelationalOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isEqualityOp(Opc))
+    CheckEqualityOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isBitwiseOp(Opc))
+    CheckBitwiseOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isLogicalOp(Opc))
+    CheckLogicalOperands((Expr*)LHS, (Expr*)RHS);
+  
   return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
 }
 
@@ -301,3 +316,24 @@
   return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
 }
 
+void Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckAdditiveOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckShiftOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckRelationalOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckEqualityOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckBitwiseOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckLogicalOperands(Expr *op1, Expr *op2) {
+}
+

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:43:35 2007
@@ -14,7 +14,9 @@
 #include "clang/Lex/IdentifierTable.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/Decl.h"
+
 #include <iostream>
+
 using namespace llvm;
 using namespace clang;
 
@@ -22,16 +24,105 @@
 
 /// isVoidType - Helper method to determine if this is the 'void' type.
 bool Type::isVoidType() const {
-  if (const BuiltinType *BT = dyn_cast<BuiltinType>(getCanonicalType()))
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
     return BT->getKind() == BuiltinType::Void;
   return false;
 }
 
+bool Type::isFunctionType() const {
+  return isa<FunctionType>(CanonicalType) ? true : false;
+}
+
+bool Type::isPointerType() const {
+  return isa<PointerType>(CanonicalType) ? true : false;
+}
+
+bool Type::isArrayType() const {
+  return isa<ArrayType>(CanonicalType) ? true : false;
+}
+
+bool Type::isStructureType() const { 
+  if (const TaggedType *TT = dyn_cast<TaggedType>(CanonicalType)) {
+    if (TT->getDecl()->getKind() == Decl::Struct)
+      return true;
+  }
+  return false;
+}
+
+bool Type::isUnionType() const { 
+  if (const TaggedType *TT = dyn_cast<TaggedType>(CanonicalType)) {
+    if (TT->getDecl()->getKind() == Decl::Union)
+      return true;
+  }
+  return false;
+}
+
+bool Type::isIntegralType() const {
+  switch (CanonicalType->getTypeClass()) {
+  default: return false;
+  case Builtin:
+    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType);
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::ULongLong;
+  case Tagged:
+    const TaggedType *TT = static_cast<TaggedType*>(CanonicalType);
+    if (TT->getDecl()->getKind() == Decl::Enum)
+      return true;
+    return false;
+  }
+}
+
+bool Type::isFloatingType() const {
+  switch (CanonicalType->getTypeClass()) {
+  default: return false;
+  case Builtin:
+    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType);
+    return BT->getKind() >= BuiltinType::Float &&
+           BT->getKind() <= BuiltinType::LongDoubleComplex;
+  }
+}
+
+bool Type::isArithmeticType() const {
+  switch (CanonicalType->getTypeClass()) {
+  default: return false;
+  case Builtin:
+    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType);
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::LongDoubleComplex;
+  }
+}
+
+bool Type::isScalarType() const {
+  switch (CanonicalType->getTypeClass()) {
+  default: return false;
+  case Builtin:
+    const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType);
+    return BT->getKind() >= BuiltinType::Bool &&
+           BT->getKind() <= BuiltinType::LongDoubleComplex;
+  case Pointer:
+    return true;
+  }
+}
+
+bool Type::isAggregateType() const {
+  switch (CanonicalType->getTypeClass()) {
+  default: return false;
+  case Array:
+    return true;
+  case Tagged:
+    const TaggedType *TT = static_cast<TaggedType*>(CanonicalType);
+    if (TT->getDecl()->getKind() == Decl::Struct)
+      return true;
+    return true;
+  }
+}
+
+
 /// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
 /// - a type that can describe objects, but which lacks information needed to
 /// determine its size.
-bool Type::isIncompleteType() const {
-  switch (getTypeClass()) {
+bool Type::isIncompleteType() const { 
+  switch (CanonicalType->getTypeClass()) { 
   default: return false;
   case Builtin:
     // Void is the only incomplete builtin type.  Per C99 6.2.5p19, it can never
@@ -40,17 +131,10 @@
   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>(this)->getDecl()->isDefinition();
+    return !cast<TaggedType>(CanonicalType)->getDecl()->isDefinition();
   case Array:
     // An array of unknown size is an incomplete type (C99 6.2.5p22).
-    // In C99, an unknown size is permitted in 4 instances:
-    // - The array being declared is a formal parameter of a function.
-    // - The declarator is accompanied by an initializer from which the array 
-    //   can be deduced (char foo[] = "whatever").
-    // - Forward declarations (extern int matrix[][7]).
-    // - The last component of a structure (flexible array idiom).
-    // Clients of this routine will need to determine if the size is required.
-    return cast<ArrayType>(this)->getSize() == 0;
+    return cast<ArrayType>(CanonicalType)->getSize() == 0;
   }
 }
 

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:35 2007
@@ -24,6 +24,7 @@
   class ASTContext;
   class Preprocessor;
   class Decl;
+  class Expr;
   class VarDecl;
   class TypedefDecl;
   class FunctionDecl;
@@ -65,7 +66,7 @@
   virtual TypeResult ParseTypeName(Scope *S, Declarator &D);
   
   virtual TypeResult ParseParamDeclaratorType(Scope *S, Declarator &D);
-  
+private:
   //===--------------------------------------------------------------------===//
   // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
   //
@@ -98,6 +99,9 @@
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
   FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
+  /// AddTopLevelDecl - called after the decl has been fully processed.
+  /// Allows for bookkeeping and post-processing of each declaration.
+  void AddTopLevelDecl(Decl *current, Decl *last);
 
   /// More parsing and symbol table subroutines...
   VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
@@ -215,6 +219,15 @@
   /// ParseCXXBoolLiteral - Parse {true,false} literals.
   virtual ExprResult ParseCXXBoolLiteral(SourceLocation OpLoc,
                                          tok::TokenKind Kind);
+private:
+  /// 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
+  void CheckShiftOperands(Expr *op1, Expr *op2);          // C99 6.5.7
+  void CheckRelationalOperands(Expr *op1, Expr *op2);     // C99 6.5.8
+  void CheckEqualityOperands(Expr *op1, Expr *op2);       // C99 6.5.9
+  void CheckBitwiseOperands(Expr *op1, Expr *op2);        // C99 6.5.[10...12]
+  void CheckLogicalOperands(Expr *op1, Expr *op2);        // C99 6.5.[13,14]
 };
 
 

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:43:35 2007
@@ -288,10 +288,8 @@
     S->AddDecl(New);
   }
   
-  // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
-  // remember this in the LastInGroupList list.
-  if (LastInGroup && S->getParent() == 0)
-    LastInGroupList.push_back((Decl*)LastInGroup);
+  if (S->getParent() == 0)
+    AddTopLevelDecl(New, (Decl *)LastInGroup);
   
   return New;
 }
@@ -714,3 +712,12 @@
   Enum->defineElements(&Values[0], Values.size());
 }
 
+void Sema::AddTopLevelDecl(Decl *current, Decl *last) {
+  if (!current) return;
+
+  // If this is a top-level decl that is chained to some other (e.g. int A,B,C;)
+  // remember this in the LastInGroupList list.
+  if (last) {
+    LastInGroupList.push_back((Decl*)last);
+  }
+}

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:35 2007
@@ -188,7 +188,7 @@
   if (isa<FunctionType>(ArgTy) && isSizeof) {
     // alignof(function) is allowed.
     Diag(OpLoc, diag::ext_sizeof_function_type);
-    return new IntegerLiteral(/*1*/);
+    return new IntegerLiteral(1, Context.IntTy);
   } else if (ArgTy->isVoidType()) {
     Diag(OpLoc, diag::ext_sizeof_void_type, isSizeof ? "sizeof" : "__alignof");
   } else if (ArgTy->isIncompleteType()) {
@@ -196,7 +196,7 @@
     ArgTy->getAsString(TypeName);
     Diag(OpLoc, isSizeof ? diag::err_sizeof_incomplete_type : 
          diag::err_alignof_incomplete_type, TypeName);
-    return new IntegerLiteral(/*0*/);
+    return new IntegerLiteral(0, Context.IntTy);
   }
   
   return new SizeOfAlignOfTypeExpr(isSizeof, ArgTy);
@@ -289,6 +289,21 @@
   case tok::comma:                Opc = BinaryOperator::Comma; break;
   }
   
+  if (BinaryOperator::isMultiplicativeOp(Opc)) 
+    CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isAdditiveOp(Opc))
+    CheckAdditiveOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isShiftOp(Opc))
+    CheckShiftOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isRelationalOp(Opc))
+    CheckRelationalOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isEqualityOp(Opc))
+    CheckEqualityOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isBitwiseOp(Opc))
+    CheckBitwiseOperands((Expr*)LHS, (Expr*)RHS);
+  else if (BinaryOperator::isLogicalOp(Opc))
+    CheckLogicalOperands((Expr*)LHS, (Expr*)RHS);
+  
   return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
 }
 
@@ -301,3 +316,24 @@
   return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
 }
 
+void Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckAdditiveOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckShiftOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckRelationalOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckEqualityOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckBitwiseOperands(Expr *op1, Expr *op2) {
+}
+
+void Sema::CheckLogicalOperands(Expr *op1, Expr *op2) {
+}
+

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=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:43:35 2007
@@ -27,9 +27,9 @@
 /// is required.
 ///
 class Expr : public Stmt {
-  /// TODO: Type.
+  TypeRef Type;
 public:
-  Expr(StmtClass SC) : Stmt(SC) {}
+  Expr(StmtClass SC, TypeRef T=0) : Stmt(SC), Type(T) {}
   ~Expr() {}
   
   virtual void visit(StmtVisitor &Visitor);
@@ -60,25 +60,14 @@
   static bool classof(const DeclRefExpr *) { return true; }
 };
 
-
-// FIXME: The "type" will eventually be moved to Stmt.
 class IntegerLiteral : public Expr {
-  TypeRef Type; // IntTy, LongTy, LongLongTy
-                // UnsignedIntTy, UnsignedLongTy, UnsignedLongLongTy
   intmax_t Value;
 public:
-  // FIXME: To satisfy some of the current adhoc usage...
-  IntegerLiteral() : Expr(IntegerLiteralClass),
-     Type(0), Value(0) {
-  }
+  // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, 
+  // or UnsignedLongLongTy
   IntegerLiteral(intmax_t value, TypeRef type)
-    : Expr(IntegerLiteralClass), Type(type), Value(value) {
-#if 0
-      std::cout << "Value=" << Value;
-      std::cout << " Type= ";
-      std::cout << static_cast<BuiltinType *>(type.getTypePtr())->getName();
-      std::cout << "\n";
-#endif
+    : Expr(IntegerLiteralClass, type), Value(value) {
+    assert(type->isIntegralType() && "Illegal type in IntegerLiteral");
   }
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
@@ -89,7 +78,7 @@
 
 class FloatingLiteral : public Expr {
 public:
-  FloatingLiteral() : Expr(FloatingLiteralClass) {}
+  FloatingLiteral() : Expr(FloatingLiteralClass) {} 
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == FloatingLiteralClass; 
@@ -328,6 +317,15 @@
   /// getOpcodeStr - Turn an Opcode enum value into the punctuation char it
   /// corresponds to, e.g. "<<=".
   static const char *getOpcodeStr(Opcode Op);
+
+  /// predicates to categorize the respective opcodes.
+  static bool isMultiplicativeOp(Opcode Op) { return Op >= Mul && Op <= Rem; }
+  static bool isAdditiveOp(Opcode Op) { return Op == Add || Op == Sub; }
+  static bool isShiftOp(Opcode Op) { return Op == Shl || Op == Shr; }
+  static bool isRelationalOp(Opcode Op) { return Op >= LT && Op <= GE; }
+  static bool isEqualityOp(Opcode Op) { return Op == EQ || Op == NE; }
+  static bool isBitwiseOp(Opcode Op) { return Op >= And && Op <= Or; }
+  static bool isLogicalOp(Opcode Op) { return Op == LAnd || Op == LOr; }
   
   Opcode getOpcode() const { return Opc; }
   Expr *getLHS() { return LHS; }
@@ -338,7 +336,6 @@
     return T->getStmtClass() == BinaryOperatorClass; 
   }
   static bool classof(const BinaryOperator *) { return true; }
-  
 private:
   Expr *LHS, *RHS;
   Opcode Opc;

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=39360&r1=39359&r2=39360&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:43:35 2007
@@ -182,13 +182,26 @@
   
   bool isCanonical() const { return CanonicalType == this; }
   Type *getCanonicalType() const { return CanonicalType; }
-  
-  /// isVoidType - Helper method to determine if this is the 'void' type.
-  bool isVoidType() const;
+
+  /// Helper methods to distinguish type categories. All type predicates
+  /// operate on the canonical type, ignoring typedefs.
+  bool isIntegralType() const;   // short/int/long, char, bool, enum { ... }
+  bool isFloatingType() const;   // float, double, long double, complex
+  bool isArithmeticType() const; // integral + floating
+  bool isScalarType() const;     // arithmetic + pointers
+  bool isAggregateType() const;  // arrays, structures
+  
+  bool isVoidType() const;       
+  bool isFunctionType() const;   
+  bool isPointerType() const;
+  bool isArrayType() const;
+  bool isStructureType() const;
+  bool isUnionType() const;
   
   /// isIncompleteType - Return true if this is an incomplete type (C99 6.2.5p1)
   /// - a type that can describe objects, but which lacks information needed to
-  /// determine its size (e.g. void, or a fwd declared struct).
+  /// determine its size (e.g. void, or a fwd declared struct). Clients of this
+  /// routine will need to determine if the size is actually required.  
   bool isIncompleteType() const;
   
   virtual void getAsString(std::string &InnerString) const = 0;
@@ -397,7 +410,7 @@
 class TypedefType : public Type {
   TypedefDecl *Decl;
   TypedefType(TypedefDecl *D, Type *can) : Type(TypeName, can), Decl(D) {
-    assert(!isa<TypedefType>(can) && "Invalid canonoical type");
+    assert(!isa<TypedefType>(can) && "Invalid canonical type");
   }
   friend class ASTContext;  // ASTContext creates these.
 public:





More information about the cfe-commits mailing list