diff options
Diffstat (limited to 'lib/Parse/ParseObjc.cpp')
| -rw-r--r-- | lib/Parse/ParseObjc.cpp | 51 | 
1 files changed, 45 insertions, 6 deletions
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index b043dd99f304..65bd79d6b4f2 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -61,6 +61,8 @@ Parser::DeclPtrTy Parser::ParseObjCAtDirectives() {  Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {    ConsumeToken(); // the identifier "class"    llvm::SmallVector<IdentifierInfo *, 8> ClassNames; +  llvm::SmallVector<SourceLocation, 8> ClassLocs; +    while (1) {      if (Tok.isNot(tok::identifier)) { @@ -69,6 +71,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {        return DeclPtrTy();      }      ClassNames.push_back(Tok.getIdentifierInfo()); +    ClassLocs.push_back(Tok.getLocation());      ConsumeToken();      if (Tok.isNot(tok::comma)) @@ -81,8 +84,9 @@ Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {    if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))      return DeclPtrTy(); -  return Actions.ActOnForwardClassDeclaration(atLoc, -                                      &ClassNames[0], ClassNames.size()); +  return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(), +                                              ClassLocs.data(), +                                              ClassNames.size());  }  /// @@ -123,6 +127,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(      Diag(Tok, diag::err_expected_ident); // missing class or category name.      return DeclPtrTy();    } +    // We have a class or category name - consume it.    IdentifierInfo *nameId = Tok.getIdentifierInfo();    SourceLocation nameLoc = ConsumeToken(); @@ -829,6 +834,12 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols,    llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents;    while (1) { +    if (Tok.is(tok::code_completion)) { +      Actions.CodeCompleteObjCProtocolReferences(ProtocolIdents.data(),  +                                                 ProtocolIdents.size()); +      ConsumeToken(); +    } +      if (Tok.isNot(tok::identifier)) {        Diag(Tok, diag::err_expected_ident);        SkipUntil(tok::greater); @@ -895,7 +906,8 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl,      // Check for extraneous top-level semicolon.      if (Tok.is(tok::semi)) { -      Diag(Tok, diag::ext_extra_struct_semi); +      Diag(Tok, diag::ext_extra_struct_semi) +        << CodeModificationHint::CreateRemoval(SourceRange(Tok.getLocation()));        ConsumeToken();        continue;      } @@ -982,6 +994,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,           "ParseObjCAtProtocolDeclaration(): Expected @protocol");    ConsumeToken(); // the "protocol" identifier +  if (Tok.is(tok::code_completion)) { +    Actions.CodeCompleteObjCProtocolDecl(CurScope); +    ConsumeToken(); +  } +    if (Tok.isNot(tok::identifier)) {      Diag(Tok, diag::err_expected_ident); // missing protocol name.      return DeclPtrTy(); @@ -1092,6 +1109,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(                                      atLoc, nameId, nameLoc, categoryId,                                      categoryLoc);      ObjCImpDecl = ImplCatType; +    PendingObjCImpDecl.push_back(ObjCImpDecl);      return DeclPtrTy();    }    // We have a class implementation @@ -1114,7 +1132,8 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(    if (Tok.is(tok::l_brace)) // we have ivars      ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);    ObjCImpDecl = ImplClsType; - +  PendingObjCImpDecl.push_back(ObjCImpDecl); +      return DeclPtrTy();  } @@ -1126,12 +1145,21 @@ Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {    if (ObjCImpDecl) {      Actions.ActOnAtEnd(atLoc, ObjCImpDecl);      ObjCImpDecl = DeclPtrTy(); +    PendingObjCImpDecl.pop_back();    }    else      Diag(atLoc, diag::warn_expected_implementation); // missing @implementation    return Result;  } +Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() { +  if (PendingObjCImpDecl.empty()) +    return Actions.ConvertDeclToDeclGroup(DeclPtrTy()); +  DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val(); +  Actions.ActOnAtEnd(SourceLocation(), ImpDecl); +  return Actions.ConvertDeclToDeclGroup(ImpDecl); +} +  ///   compatibility-alias-decl:  ///     @compatibility_alias alias-name  class-name ';'  /// @@ -1201,6 +1229,8 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {    }    if (Tok.isNot(tok::semi))      Diag(Tok, diag::err_expected_semi_after) << "@synthesize"; +  else +    ConsumeToken(); // consume ';'    return DeclPtrTy();  } @@ -1406,8 +1436,10 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() {    // parse optional ';'    if (Tok.is(tok::semi)) { -    if (ObjCImpDecl) -      Diag(Tok, diag::warn_semicolon_before_method_nody); +    if (ObjCImpDecl) { +      Diag(Tok, diag::warn_semicolon_before_method_body) +        << CodeModificationHint::CreateRemoval(SourceRange(Tok.getLocation())); +    }      ConsumeToken();    } @@ -1546,6 +1578,13 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,                                         SourceLocation NameLoc,                                         IdentifierInfo *ReceiverName,                                         ExprArg ReceiverExpr) { +  if (Tok.is(tok::code_completion)) { +    if (ReceiverName) +      Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc); +    else +      Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get()); +    ConsumeToken(); +  }    // Parse objc-selector    SourceLocation Loc;    IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);  | 
