Unverified Commit 42e9478e authored by Kadir Cetinkaya's avatar Kadir Cetinkaya
Browse files

[clang][CodeComplete] Support for designated initializers

Reviewers: sammccall

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D73271
parent 993e3c92
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1952,7 +1952,8 @@ private:
  }
  bool MayBeDesignationStart();
  ExprResult ParseBraceInitializer();
  ExprResult ParseInitializerWithPotentialDesignator();
  ExprResult ParseInitializerWithPotentialDesignator(
      llvm::function_ref<void(const Designation &)> CodeCompleteCB);

  //===--------------------------------------------------------------------===//
  // clang Expressions
+6 −0
Original line number Diff line number Diff line
@@ -11555,6 +11555,12 @@ public:
                                              IdentifierInfo *II,
                                              SourceLocation OpenParLoc);
  void CodeCompleteInitializer(Scope *S, Decl *D);
  /// Trigger code completion for a record of \p BaseType. \p InitExprs are
  /// expressions in the initializer list seen so far and \p D is the current
  /// Designation being parsed.
  void CodeCompleteDesignator(const QualType BaseType,
                              llvm::ArrayRef<Expr *> InitExprs,
                              const Designation &D);
  void CodeCompleteAfterIf(Scope *S);
  void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext,
+1 −0
Original line number Diff line number Diff line
@@ -2460,6 +2460,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(

    InitializerScopeRAII InitScope(*this, D, ThisDecl);

    PreferredType.enterVariableInit(Tok.getLocation(), ThisDecl);
    ExprResult Init(ParseBraceInitializer());

    InitScope.pop();
+1 −0
Original line number Diff line number Diff line
@@ -1866,6 +1866,7 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
         && "Expected '(' or '{'!");

  if (Tok.is(tok::l_brace)) {
    PreferredType.enterTypeCast(Tok.getLocation(), TypeRep.get());
    ExprResult Init = ParseBraceInitializer();
    if (Init.isInvalid())
      return Init;
+21 −4
Original line number Diff line number Diff line
@@ -10,11 +10,14 @@
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/TokenKinds.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/Scope.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
using namespace clang;

@@ -154,7 +157,9 @@ static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc,
/// initializer (because it is an expression).  We need to consider this case
/// when parsing array designators.
///
ExprResult Parser::ParseInitializerWithPotentialDesignator() {
/// \p CodeCompleteCB is called with Designation parsed so far.
ExprResult Parser::ParseInitializerWithPotentialDesignator(
    llvm::function_ref<void(const Designation &)> CodeCompleteCB) {

  // If this is the old-style GNU extension:
  //   designation ::= identifier ':'
@@ -193,6 +198,11 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
      // designator: '.' identifier
      SourceLocation DotLoc = ConsumeToken();

      if (Tok.is(tok::code_completion)) {
        CodeCompleteCB(Desig);
        cutOffParsing();
        return ExprError();
      }
      if (Tok.isNot(tok::identifier)) {
        Diag(Tok.getLocation(), diag::err_expected_field_designator);
        return ExprError();
@@ -407,7 +417,6 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator() {
  return ExprError();
}


/// ParseBraceInitializer - Called when parsing an initializer that has a
/// leading open brace.
///
@@ -444,6 +453,10 @@ ExprResult Parser::ParseBraceInitializer() {
      Actions, EnterExpressionEvaluationContext::InitList);

  bool InitExprsOk = true;
  auto CodeCompleteDesignation = [&](const Designation &D) {
    Actions.CodeCompleteDesignator(PreferredType.get(T.getOpenLocation()),
                                   InitExprs, D);
  };

  while (1) {
    // Handle Microsoft __if_exists/if_not_exists if necessary.
@@ -463,7 +476,7 @@ ExprResult Parser::ParseBraceInitializer() {
    // initializer directly.
    ExprResult SubElt;
    if (MayBeDesignationStart())
      SubElt = ParseInitializerWithPotentialDesignator();
      SubElt = ParseInitializerWithPotentialDesignator(CodeCompleteDesignation);
    else
      SubElt = ParseInitializer();

@@ -543,13 +556,17 @@ bool Parser::ParseMicrosoftIfExistsBraceInitializer(ExprVector &InitExprs,
    return false;
  }

  auto CodeCompleteDesignation = [&](const Designation &D) {
    Actions.CodeCompleteDesignator(PreferredType.get(Braces.getOpenLocation()),
                                   InitExprs, D);
  };
  while (!isEofOrEom()) {
    trailingComma = false;
    // If we know that this cannot be a designation, just parse the nested
    // initializer directly.
    ExprResult SubElt;
    if (MayBeDesignationStart())
      SubElt = ParseInitializerWithPotentialDesignator();
      SubElt = ParseInitializerWithPotentialDesignator(CodeCompleteDesignation);
    else
      SubElt = ParseInitializer();

Loading