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