diff options
-rw-r--r-- | include/clang/AST/Expr.h | 6 | ||||
-rw-r--r-- | include/clang/Parse/DeclSpec.h | 2 | ||||
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 30 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 36 | ||||
-rw-r--r-- | test/SemaObjC/protocol-archane.m | 2 |
10 files changed, 52 insertions, 54 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 4b17929e11..68e486c21b 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -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) diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index dc57d57410..83c0d6179f 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -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 diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index d5af384284..4f1ef2490a 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -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"; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 2ba1edc415..d646ad4cc0 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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 diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 1efa274083..3442d5977a 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -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; } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 22599f3f1e..6175e92758 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c0160b2d42..4bba5e50f1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c4c526eedb..02c2e9bbfa 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -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; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index d31402de71..25fd5c39fe 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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; diff --git a/test/SemaObjC/protocol-archane.m b/test/SemaObjC/protocol-archane.m index 67e1c231f6..bfae348f08 100644 --- a/test/SemaObjC/protocol-archane.m +++ b/test/SemaObjC/protocol-archane.m @@ -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 |