]> granicus.if.org Git - clang/commitdiff
Make Sema::getTypeName return the opaque pointer of a QualType rather
authorDouglas Gregor <dgregor@apple.com>
Mon, 9 Feb 2009 15:09:02 +0000 (15:09 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 9 Feb 2009 15:09:02 +0000 (15:09 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64141 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 4b17929e11acb8345d7dd940838748677fa35e50..68e486c21ba06a575436658f3741e4cd12a2da41 100644 (file)
@@ -2001,9 +2001,11 @@ public:
 /// \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) 
index dc57d57410e15ca69f72979afa104daeb2ed2c84..83c0d6179fce0e0db08719af9f343f3f29be6c42 100644 (file)
@@ -78,7 +78,7 @@ public:
     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
index d5af3842847052b7f8deca62daf5679c38001b4f..4f1ef2490a3735b564634a910f46b010bca3541b 100644 (file)
@@ -146,7 +146,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
   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";
   }
index 2ba1edc415efce0c9d7fd60086502641b76b45e4..d646ad4cc016e19f5d70d76ce9016c31d3cfbc21 100644 (file)
@@ -492,7 +492,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
 
       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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
     }
         
     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 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
           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 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
       
   // 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
index 1efa274083213c87fb802044a8b450960516b0de..3442d5977abd31cde94dddda920019ac29f6b89b 100644 (file)
@@ -456,7 +456,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
 
   // type-name
   case tok::annot_typename: {
-    DS.SetTypeSpecType(DeclSpec::TST_typedef, Loc, PrevSpec,
+    DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
                        Tok.getAnnotationValue());
     break;
   }
index 22599f3f1e5ca35cfe832233066dcac0f6e2dc42..6175e9275896da97abe27e50c16f69961db7ad98 100644 (file)
@@ -283,7 +283,7 @@ public:
   //===--------------------------------------------------------------------===//
   // 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);
index c0160b2d423789f1a5d6613735c36d199880e82d..4bba5e50f188c55f6153ed2b1122d931ab782f05 100644 (file)
@@ -36,12 +36,13 @@ using namespace clang;
 ///
 /// 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 @@ Sema::DeclTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
   }
 
   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 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
 /// 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 @@ DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
     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);
index c4c526eedb2431a83e0c70fc7f64a38a8da9a58b..02c2e9bbfab37989641861209339ce9d4ea7a0de 100644 (file)
@@ -318,7 +318,7 @@ Sema::ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
                          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 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
   }
 
   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 @@ Sema::ActOnMemInitializer(DeclTy *ConstructorD,
     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 @@ bool Sema::CheckDestructorDeclarator(Declarator &D, QualType &R,
   //   (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;
   }
 
index d31402de71214f7e43fe031fcf54352337d641ec..25fd5c39fe3a0d6ebe5b52f2f30f07f701cbc100 100644 (file)
@@ -133,36 +133,25 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
     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();      
-
-    // 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) {
+    Result = QualType::getFromOpaquePtr(DS.getTypeRep());
+
+    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 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
     //   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;
index 67e1c231f6818155aa967f7ba9f165e7ff7187ea..bfae348f082b22a81d24ff50052d145c16e841eb 100644 (file)
@@ -20,5 +20,5 @@ void foo(id x) {
 - (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