r240188 - Handle 'instancetype' in ParseDeclarationSpecifiers.
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 19 20:32:44 PDT 2015
On Fri, Jun 19, 2015 at 4:18 PM, Douglas Gregor <dgregor at apple.com> wrote:
> Author: dgregor
> Date: Fri Jun 19 18:18:00 2015
> New Revision: 240188
>
> URL: http://llvm.org/viewvc/llvm-project?rev=240188&view=rev
> Log:
> Handle 'instancetype' in ParseDeclarationSpecifiers.
>
> ...instead of as a special case in ParseObjCTypeName with lots of
> duplicated logic. Besides being a nice refactoring, this also allows
> "- (instancetype __nonnull)self" in addition to "- (nonnull
> instancetype)self".
>
> rdar://problem/19924646
>
> Modified:
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/lib/Parse/ParseDecl.cpp
> cfe/trunk/lib/Parse/ParseObjc.cpp
> cfe/trunk/test/SemaObjC/nullability.m
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=240188&r1=240187&r2=240188&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Fri Jun 19 18:18:00 2015
> @@ -626,6 +626,16 @@ private:
> const char *&PrevSpec, unsigned &DiagID,
> bool &isInvalid);
>
> + /// Returns true if the current token is the identifier 'instancetype'.
> + ///
> + /// Should only be used in Objective-C language modes.
> + bool isObjCInstancetype() {
> + assert(getLangOpts().ObjC1);
> + if (!Ident_instancetype)
> + Ident_instancetype = PP.getIdentifierInfo("instancetype");
> + return Tok.getIdentifierInfo() == Ident_instancetype;
>
This will assert if Tok ends up being an annotation token (see e.g.
PR24515).
(resending to the new list)
> + }
> +
> /// TryKeywordIdentFallback - For compatibility with system headers
> using
> /// keywords as identifiers, attempt to convert the current token to an
> /// identifier and optionally disable the keyword for the remainder of
> the
> @@ -1692,7 +1702,8 @@ private:
> DSC_trailing, // C++11 trailing-type-specifier in a trailing return
> type
> DSC_alias_declaration, // C++11 type-specifier-seq in an
> alias-declaration
> DSC_top_level, // top-level/namespace declaration context
> - DSC_template_type_arg // template type argument context
> + DSC_template_type_arg, // template type argument context
> + DSC_objc_method_result, // ObjC method result context, enables
> 'instancetype'
> };
>
> /// Is this a context in which we are parsing just a type-specifier (or
> @@ -1702,6 +1713,7 @@ private:
> case DSC_normal:
> case DSC_class:
> case DSC_top_level:
> + case DSC_objc_method_result:
> return false;
>
> case DSC_template_type_arg:
>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=240188&r1=240187&r2=240188&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Jun 19 18:18:00 2015
> @@ -2941,6 +2941,19 @@ void Parser::ParseDeclarationSpecifiers(
> if (DS.isTypeAltiVecVector())
> goto DoneWithDeclSpec;
>
> + if (DSContext == DSC_objc_method_result && isObjCInstancetype()) {
> + ParsedType TypeRep = Actions.ActOnObjCInstanceType(Loc);
> + assert(TypeRep);
> + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc,
> PrevSpec,
> + DiagID, TypeRep, Policy);
> + if (isInvalid)
> + break;
> +
> + DS.SetRangeEnd(Loc);
> + ConsumeToken();
> + continue;
> + }
> +
> ParsedType TypeRep =
> Actions.getTypeName(*Tok.getIdentifierInfo(),
> Tok.getLocation(), getCurScope());
>
> Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=240188&r1=240187&r2=240188&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Jun 19 18:18:00 2015
> @@ -1005,11 +1005,14 @@ ParsedType Parser::ParseObjCTypeName(Obj
> ParseObjCTypeQualifierList(DS, context);
>
> ParsedType Ty;
> - if (isTypeSpecifierQualifier()) {
> + if (isTypeSpecifierQualifier() || isObjCInstancetype()) {
> // Parse an abstract declarator.
> DeclSpec declSpec(AttrFactory);
> declSpec.setObjCQualifiers(&DS);
> - ParseSpecifierQualifierList(declSpec);
> + DeclSpecContext dsContext = DSC_normal;
> + if (context == Declarator::ObjCResultContext)
> + dsContext = DSC_objc_method_result;
> + ParseSpecifierQualifierList(declSpec, AS_none, dsContext);
> declSpec.SetRangeEnd(Tok.getLocation());
> Declarator declarator(declSpec, context);
> ParseDeclarator(declarator);
> @@ -1033,38 +1036,6 @@ ParsedType Parser::ParseObjCTypeName(Obj
> if (context == Declarator::ObjCParameterContext)
> takeDeclAttributes(*paramAttrs, declarator);
> }
> - } else if (context == Declarator::ObjCResultContext &&
> - Tok.is(tok::identifier)) {
> - if (!Ident_instancetype)
> - Ident_instancetype = PP.getIdentifierInfo("instancetype");
> -
> - if (Tok.getIdentifierInfo() == Ident_instancetype) {
> - SourceLocation loc = ConsumeToken();
> - Ty = Actions.ActOnObjCInstanceType(loc);
> -
> - // Synthesize an abstract declarator so we can use
> Sema::ActOnTypeName.
> - bool addedToDeclSpec = false;
> - const char *prevSpec;
> - unsigned diagID;
> - DeclSpec declSpec(AttrFactory);
> - declSpec.setObjCQualifiers(&DS);
> - declSpec.SetTypeSpecType(DeclSpec::TST_typename, loc, prevSpec,
> diagID,
> - Ty,
> -
> Actions.getASTContext().getPrintingPolicy());
> - declSpec.SetRangeEnd(loc);
> - Declarator declarator(declSpec, context);
> -
> - // Map a nullability specifier to a context-sensitive keyword
> attribute.
> - if (DS.getObjCDeclQualifier() & ObjCDeclSpec::DQ_CSNullability)
> - addContextSensitiveTypeNullability(*this, declarator,
> - DS.getNullability(),
> - DS.getNullabilityLoc(),
> - addedToDeclSpec);
> -
> - TypeResult type = Actions.ActOnTypeName(getCurScope(), declarator);
> - if (!type.isInvalid())
> - Ty = type.get();
> - }
> }
>
> if (Tok.is(tok::r_paren))
>
> Modified: cfe/trunk/test/SemaObjC/nullability.m
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/nullability.m?rev=240188&r1=240187&r2=240188&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/nullability.m (original)
> +++ cfe/trunk/test/SemaObjC/nullability.m Fri Jun 19 18:18:00 2015
> @@ -156,6 +156,10 @@ __attribute__((objc_root_class))
> - (nonnull instancetype)initWithBlah:(nonnull id)blah;
> - (nullable instancetype)returnMe;
> + (nullable instancetype)returnInstanceOfMe;
> +
> +- (nonnull instancetype __nullable)initWithBlah2:(nonnull id)blah; //
> expected-error {{nullability specifier '__nullable' conflicts with existing
> specifier '__nonnull'}}
> +- (instancetype __nullable)returnMe2;
> ++ (__nonnull instancetype)returnInstanceOfMe2;
> @end
>
> void test_instancetype(InitializableClass * __nonnull ic, id __nonnull
> object) {
> @@ -163,6 +167,9 @@ void test_instancetype(InitializableClas
> ip = [InitializableClass returnMe]; // expected-warning{{incompatible
> pointer types assigning to 'int *' from 'id __nullable'}}
> ip = [InitializableClass returnInstanceOfMe]; //
> expected-warning{{incompatible pointer types assigning to 'int *' from
> 'InitializableClass * __nullable'}}
> ip = [object returnMe]; // expected-warning{{incompatible pointer types
> assigning to 'int *' from 'id __nullable'}}
> +
> + ip = [ic returnMe2]; // expected-warning{{incompatible pointer types
> assigning to 'int *' from 'InitializableClass * __nullable'}}
> + ip = [InitializableClass returnInstanceOfMe2]; //
> expected-warning{{incompatible pointer types assigning to 'int *' from
> 'InitializableClass * __nonnull'}}
> }
>
> // Check null_resettable getters/setters.
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150819/ad090ad6/attachment-0001.html>
More information about the cfe-commits
mailing list