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

Steve Naroff snaroff at apple.com
Wed Jul 25 20:11:45 PDT 2007


Author: snaroff
Date: Wed Jul 25 22:11:44 2007
New Revision: 40508

URL: http://llvm.org/viewvc/llvm-project?rev=40508&view=rev
Log:

Various improvements to Sema::ParseMemberReferenceExpr().

- Added source range support to Diag's.
- Used the new type predicate API to remove dealing with the canonical
type explicitly.
- Added Type::isRecordType().
- Removed some casts.
- Removed a const qualifier from RecordType::getDecl(). 



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

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

==============================================================================
--- cfe/trunk/AST/Type.cpp (original)
+++ cfe/trunk/AST/Type.cpp Wed Jul 25 22:11:44 2007
@@ -96,6 +96,17 @@
   return 0;
 }
 
+const RecordType *Type::isRecordType() const {
+  // If this is directly a reference type, return it.
+  if (const RecordType *RTy = dyn_cast<RecordType>(this))
+    return RTy;
+  
+  // If this is a typedef for an record type, strip the typedef off without
+  // losing all typedef information.
+  if (isa<RecordType>(CanonicalType))
+    return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
+}
+
 bool Type::isStructureType() const {
   if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
     if (TT->getDecl()->getKind() == Decl::Struct)

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

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Wed Jul 25 22:11:44 2007
@@ -343,34 +343,35 @@
 ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
                          tok::TokenKind OpKind, SourceLocation MemberLoc,
                          IdentifierInfo &Member) {
-  QualType qualifiedType = ((Expr *)Base)->getType();
+  Expr *BaseExpr = static_cast<Expr *>(Base);
+  assert(BaseExpr && "no record expression");
   
-  assert(!qualifiedType.isNull() && "no type for member expression");
+  QualType BaseType = BaseExpr->getType();
+  assert(!BaseType.isNull() && "no type for member expression");
   
-  QualType canonType = qualifiedType.getCanonicalType();
-
   if (OpKind == tok::arrow) {
-    if (PointerType *PT = dyn_cast<PointerType>(canonType)) {
-      qualifiedType = PT->getPointeeType();
-      canonType = qualifiedType.getCanonicalType();
-    } else
-      return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
-  }
-  if (!isa<RecordType>(canonType))
-    return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion);
+    if (const PointerType *PT = BaseType->isPointerType())
+      BaseType = PT->getPointeeType();
+    else
+      return Diag(OpLoc, diag::err_typecheck_member_reference_arrow,
+                  SourceRange(MemberLoc));
+  }
+  // Get the member decl from the struct/union definition.
+  FieldDecl *MemberDecl;
+  if (const RecordType *RTy = BaseType->isRecordType()) {
+    RecordDecl *RDecl = RTy->getDecl();
+    if (RTy->isIncompleteType())
+      return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RDecl->getName(),
+                  BaseExpr->getSourceRange());
+    // The record definition is complete, now make sure the member is valid.
+    if (!(MemberDecl = RDecl->getMember(&Member)))
+      return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName(),
+                  SourceRange(MemberLoc));
+  } else
+    return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion,
+                SourceRange(MemberLoc));
   
-  // get the struct/union definition from the type.
-  RecordDecl *RD = cast<RecordType>(canonType)->getDecl();
-    
-  if (canonType->isIncompleteType())
-    return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RD->getName());
-    
-  FieldDecl *MemberDecl = RD->getMember(&Member);
-  if (!MemberDecl)
-    return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName());
-    
-  return new MemberExpr((Expr*)Base, OpKind == tok::arrow, 
-                        MemberDecl, MemberLoc);
+  return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl, MemberLoc);
 }
 
 /// ParseCallExpr - Handle a call to Fn with the specified array of arguments.

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=40508&r1=40507&r2=40508&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jul 25 22:11:44 2007
@@ -36,6 +36,7 @@
   class ReferenceType;
   class VectorType;
   class ArrayType;
+  class RecordType;
   
 /// QualType - For efficiency, we don't store CVR-qualified types as nodes on
 /// their own: instead each reference to a type stores the qualifiers.  This
@@ -239,6 +240,7 @@
   const PointerType *isPointerType() const;
   const ReferenceType *isReferenceType() const;
   const ArrayType *isArrayType() const;
+  const RecordType *isRecordType() const;
   bool isStructureType() const;   
   bool isUnionType() const;
   
@@ -650,10 +652,10 @@
   RecordType(); // DO NOT IMPLEMENT
 public:
     
-  const RecordDecl *getDecl() const {
+  const RecordDecl *getDecl() {
     return reinterpret_cast<RecordDecl*>(TagType::getDecl());
   }
-  RecordDecl *getDecl() {
+  RecordDecl *getDecl() const {
     return reinterpret_cast<RecordDecl*>(TagType::getDecl());
   }
   





More information about the cfe-commits mailing list