[cfe-commits] r64141 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Parse/DeclSpec.h lib/Parse/DeclSpec.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaType.cpp test/SemaObjC/protocol-archane.m

Douglas Gregor dgregor at apple.com
Mon Feb 9 07:09:03 PST 2009


Author: dgregor
Date: Mon Feb  9 09:09:02 2009
New Revision: 64141

URL: http://llvm.org/viewvc/llvm-project?rev=64141&view=rev
Log:
Make Sema::getTypeName return the opaque pointer of a QualType rather
than a Decl, which gives us some more flexibility to express the
results with the type system. There are no clients using this
flexibility yet, but it's meant to be able to describe qualified names
as written in the source (e.g., "foo::type") or template-ids that name
a class template specialization (e.g., "std::vector<INT>").

DeclSpec's TST_typedef has become TST_typename, to reflect its use to
describe types found by name (that may or may not be typedefs). The
type representation of a DeclSpec with TST_typename is an opaque
QualType pointer. All users of TST_typedef, both direct and indirect,
have been updated for these changes.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Parse/DeclSpec.h
    cfe/trunk/lib/Parse/DeclSpec.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaObjC/protocol-archane.m

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Feb  9 09:09:02 2009
@@ -2001,9 +2001,11 @@
 /// \brief Represents an implicitly-generated value initialization of
 /// an object of a given type.
 ///
-/// Implicit value initializations occur within semantic initialize
-/// list expressions (\see InitListExpr) as placeholders for subobject
+/// Implicit value initializations occur within semantic initializer
+/// list expressions (InitListExpr) as placeholders for subobject
 /// initializations not explicitly specified by the user.
+///
+/// \see InitListExpr
 class ImplicitValueInitExpr : public Expr { 
 public:
   explicit ImplicitValueInitExpr(QualType ty) 

Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Mon Feb  9 09:09:02 2009
@@ -78,7 +78,7 @@
     TST_union,
     TST_struct,
     TST_class,        // C++ class type
-    TST_typedef,
+    TST_typename,     // Typedef, C++ class-name or enum name, etc.
     TST_typeofType,
     TST_typeofExpr,
     TST_error         // erroneous type

Modified: cfe/trunk/lib/Parse/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/DeclSpec.cpp?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Parse/DeclSpec.cpp Mon Feb  9 09:09:02 2009
@@ -146,7 +146,7 @@
   case DeclSpec::TST_class:       return "class";
   case DeclSpec::TST_union:       return "union";
   case DeclSpec::TST_struct:      return "struct";
-  case DeclSpec::TST_typedef:     return "typedef";
+  case DeclSpec::TST_typename:    return "type-name";
   case DeclSpec::TST_typeofType:
   case DeclSpec::TST_typeofExpr:  return "typeof";
   }

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Feb  9 09:09:02 2009
@@ -492,7 +492,7 @@
 
       ConsumeToken(); // The C++ scope.
 
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                                      TypeRep);
       if (isInvalid)
         break;
@@ -504,7 +504,7 @@
     }
         
     case tok::annot_typename: {
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                                      Tok.getAnnotationValue());
       DS.SetRangeEnd(Tok.getAnnotationEndLoc());
       ConsumeToken(); // The typename
@@ -554,7 +554,7 @@
           NextToken().getKind() == tok::l_paren)
         goto DoneWithDeclSpec;
 
-      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                                      TypeRep);
       if (isInvalid)
         break;
@@ -834,7 +834,7 @@
       
   // simple-type-specifier:
   case tok::annot_typename: {
-    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                                    Tok.getAnnotationValue());
     DS.SetRangeEnd(Tok.getAnnotationEndLoc());
     ConsumeToken(); // The typename

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Feb  9 09:09:02 2009
@@ -456,7 +456,7 @@
 
   // type-name
   case tok::annot_typename: {
-    DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                        Tok.getAnnotationValue());
     break;
   }

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

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Feb  9 09:09:02 2009
@@ -283,7 +283,7 @@
   //===--------------------------------------------------------------------===//
   // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
   //
-  virtual DeclTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, 
+  virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc, 
                               Scope *S, const CXXScopeSpec *SS);
   virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) {
     return ActOnDeclarator(S, D, LastInGroup, false);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Feb  9 09:09:02 2009
@@ -36,12 +36,13 @@
 ///
 /// This routine performs ordinary name lookup of the identifier II
 /// within the given scope, with optional C++ scope specifier SS, to
-/// determine whether the name refers to a type. If so, returns the
-/// declaration corresponding to that type. Otherwise, returns NULL.
+/// determine whether the name refers to a type. If so, returns an
+/// opaque pointer (actually a QualType) corresponding to that
+/// type. Otherwise, returns NULL.
 ///
 /// If name lookup results in an ambiguity, this routine will complain
 /// and then return NULL.
-Sema::DeclTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
                                 Scope *S, const CXXScopeSpec *SS) {
   Decl *IIDecl = 0;
   LookupResult Result = LookupParsedName(S, SS, &II, LookupOrdinaryName, false);
@@ -62,11 +63,10 @@
   }
 
   if (IIDecl) {
-    if (isa<TypedefDecl>(IIDecl) || 
-        isa<ObjCInterfaceDecl>(IIDecl) ||
-        isa<TagDecl>(IIDecl) ||
-        isa<TemplateTypeParmDecl>(IIDecl))
-      return IIDecl;
+    if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl))
+      return Context.getTypeDeclType(TD).getAsOpaquePtr();
+    else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl))
+      return Context.getObjCInterfaceType(IDecl).getAsOpaquePtr();
   }
   return 0;
 }
@@ -695,8 +695,13 @@
 /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
 /// no declarator (e.g. "struct foo;") is parsed.
 Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
-  TagDecl *Tag 
-    = dyn_cast_or_null<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
+  TagDecl *Tag = 0;
+  if (DS.getTypeSpecType() == DeclSpec::TST_class ||
+      DS.getTypeSpecType() == DeclSpec::TST_struct ||
+      DS.getTypeSpecType() == DeclSpec::TST_union ||
+      DS.getTypeSpecType() == DeclSpec::TST_enum)
+    Tag = dyn_cast<TagDecl>(static_cast<Decl *>(DS.getTypeRep()));
+
   if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
     if (!Record->getDeclName() && Record->isDefinition() &&
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef)
@@ -1111,18 +1116,19 @@
     return DeclarationName(D.getIdentifier());
 
   case Declarator::DK_Constructor: {
-    QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType());
+    QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
     Ty = Context.getCanonicalType(Ty);
     return Context.DeclarationNames.getCXXConstructorName(Ty);
   }
 
   case Declarator::DK_Destructor: {
-    QualType Ty = Context.getTypeDeclType((TypeDecl *)D.getDeclaratorIdType());
+    QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
     Ty = Context.getCanonicalType(Ty);
     return Context.DeclarationNames.getCXXDestructorName(Ty);
   }
 
   case Declarator::DK_Conversion: {
+    // FIXME: We'd like to keep the non-canonical type for diagnostics!
     QualType Ty = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
     Ty = Context.getCanonicalType(Ty);
     return Context.DeclarationNames.getCXXConversionFunctionName(Ty);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Feb  9 09:09:02 2009
@@ -318,7 +318,7 @@
                          bool Virtual, AccessSpecifier Access,
                          TypeTy *basetype, SourceLocation BaseLoc) {
   CXXRecordDecl *Decl = (CXXRecordDecl*)classdecl;
-  QualType BaseType = Context.getTypeDeclType((TypeDecl*)basetype);
+  QualType BaseType = QualType::getFromOpaquePtr(basetype);
 
   // Base specifiers must be record types.
   if (!BaseType->isRecordType())
@@ -481,15 +481,15 @@
   }
 
   if (!isFunc &&
-      D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typedef &&
+      D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename &&
       D.getNumTypeObjects() == 0) {
     // Check also for this case:
     //
     // typedef int f();
     // f a;
     //
-    Decl *TD = static_cast<Decl *>(DS.getTypeRep());
-    isFunc = Context.getTypeDeclType(cast<TypeDecl>(TD))->isFunctionType();
+    QualType TDType = QualType::getFromOpaquePtr(DS.getTypeRep());
+    isFunc = TDType->isFunctionType();
   }
 
   bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
@@ -696,7 +696,7 @@
     return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
       << MemberOrBase << SourceRange(IdLoc, RParenLoc);
   
-  QualType BaseType = Context.getTypeDeclType((TypeDecl *)BaseTy);
+  QualType BaseType = QualType::getFromOpaquePtr(BaseTy);
   if (!BaseType->isRecordType())
     return Diag(IdLoc, diag::err_base_init_does_not_name_class)
       << BaseType << SourceRange(IdLoc, RParenLoc);
@@ -1149,10 +1149,10 @@
   //   (7.1.3); however, a typedef-name that names a class shall not
   //   be used as the identifier in the declarator for a destructor
   //   declaration.
-  TypeDecl *DeclaratorTypeD = (TypeDecl *)D.getDeclaratorIdType();
-  if (const TypedefDecl *TypedefD = dyn_cast<TypedefDecl>(DeclaratorTypeD)) {
+  QualType DeclaratorType = QualType::getFromOpaquePtr(D.getDeclaratorIdType());
+  if (DeclaratorType->getAsTypedefType()) {
     Diag(D.getIdentifierLoc(),  diag::err_destructor_typedef_name)
-      << TypedefD->getDeclName();
+      << DeclaratorType;
     isInvalid = true;
   }
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Mon Feb  9 09:09:02 2009
@@ -133,36 +133,25 @@
     Result = Context.getTypeDeclType(cast<TypeDecl>(D));
     break;
   }    
-  case DeclSpec::TST_typedef: {
-    Decl *D = static_cast<Decl *>(DS.getTypeRep());
-    assert(D && "Didn't get a decl for a typedef?");
+  case DeclSpec::TST_typename: {
     assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
            DS.getTypeSpecSign() == 0 &&
            "Can't handle qualifiers on typedef names yet!");
-    DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers();      
+    Result = QualType::getFromOpaquePtr(DS.getTypeRep());
 
-    // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
-    // we have this "hack" for now... 
-    if (ObjCInterfaceDecl *ObjCIntDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
-      if (PQ == 0) {
-        Result = Context.getObjCInterfaceType(ObjCIntDecl);
-        break;
-      }
-      
-      Result = Context.getObjCQualifiedInterfaceType(ObjCIntDecl,
-                                                     (ObjCProtocolDecl**)PQ,
-                                                 DS.getNumProtocolQualifiers());
-      break;
-    } else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
-      if (Context.getObjCIdType() == Context.getTypedefType(typeDecl) && PQ) {
+    if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
+      // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
+      // we have this "hack" for now... 
+      if (const ObjCInterfaceType *Interface = Result->getAsObjCInterfaceType())
+        Result = Context.getObjCQualifiedInterfaceType(Interface->getDecl(),
+                                                       (ObjCProtocolDecl**)PQ,
+                                               DS.getNumProtocolQualifiers());
+      else if (Result == Context.getObjCIdType())
         // id<protocol-list>
         Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
                                                 DS.getNumProtocolQualifiers());
-        break;
-      }
     }
     // TypeQuals handled by caller.
-    Result = Context.getTypeDeclType(dyn_cast<TypeDecl>(D));
     break;
   }
   case DeclSpec::TST_typeofType:
@@ -240,7 +229,8 @@
     //   cv-qualifiers are introduced through the use of a typedef
     //   (7.1.3) or of a template type argument (14.3), in which
     //   case the cv-qualifiers are ignored.
-    if (DS.getTypeSpecType() == DeclSpec::TST_typedef &&
+    // FIXME: Shouldn't we be checking SCS_typedef here?
+    if (DS.getTypeSpecType() == DeclSpec::TST_typename &&
         TypeQuals && Result->isReferenceType()) {
       TypeQuals &= ~QualType::Const;
       TypeQuals &= ~QualType::Volatile;

Modified: cfe/trunk/test/SemaObjC/protocol-archane.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/protocol-archane.m?rev=64141&r1=64140&r2=64141&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/protocol-archane.m (original)
+++ cfe/trunk/test/SemaObjC/protocol-archane.m Mon Feb  9 09:09:02 2009
@@ -20,5 +20,5 @@
 - (void)m1:(id <MyProtocol> const)arg1;
 
 // FIXME: provide a better diagnostic (no typedef).
-- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short typedef' is invalid}}
+- (void)m2:(id <MyProtocol> short)arg1; // expected-error {{'short type-name' is invalid}}
 @end
\ No newline at end of file





More information about the cfe-commits mailing list