当前位置: 首页>>代码示例>>C++>>正文


C++ SourceLoc::isInvalid方法代码示例

本文整理汇总了C++中SourceLoc::isInvalid方法的典型用法代码示例。如果您正苦于以下问题:C++ SourceLoc::isInvalid方法的具体用法?C++ SourceLoc::isInvalid怎么用?C++ SourceLoc::isInvalid使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在SourceLoc的用法示例。


在下文中一共展示了SourceLoc::isInvalid方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: getDeclStartPosition

static SourceLoc getDeclStartPosition(SourceFile &File) {
  SourceManager &SM = File.getASTContext().SourceMgr;
  SourceLoc Winner;

  auto tryUpdateStart = [&](SourceLoc Loc) -> bool {
    if (Loc.isInvalid())
      return false;
    if (Winner.isInvalid()) {
      Winner = Loc;
      return true;
    }
    if (SM.isBeforeInBuffer(Loc, Winner)) {
      Winner = Loc;
      return true;
    }
    return false;
  };

  for (auto D : File.Decls) {
    if (tryUpdateStart(D->getStartLoc())) {
      tryUpdateStart(D->getAttrs().getStartLoc());
      auto RawComment = D->getRawComment();
      if (!RawComment.isEmpty())
        tryUpdateStart(RawComment.Comments.front().Range.getStart());
    }
  }

  return Winner;
}
开发者ID:peterfriese,项目名称:swift,代码行数:29,代码来源:ModuleInterfacePrinting.cpp

示例2: passCallArgNames

bool SemaAnnotator::passCallArgNames(Expr *Fn, TupleExpr *TupleE) {
  ValueDecl *D = extractDecl(Fn);
  if (!D)
    return true; // continue.

  ArrayRef<Identifier> ArgNames = TupleE->getElementNames();
  ArrayRef<SourceLoc> ArgLocs = TupleE->getElementNameLocs();
  for (auto i : indices(ArgNames)) {
    Identifier Name = ArgNames[i];
    if (Name.empty())
      continue;

    SourceLoc Loc = ArgLocs[i];
    if (Loc.isInvalid())
      continue;

    CharSourceRange Range{ Loc, Name.getLength() };
    bool Continue = SEWalker.visitCallArgName(Name, Range, D);
    if (!Continue) {
      Cancelled = true;
      return false;
    }
  }

  return true;
}
开发者ID:PiersonBro,项目名称:swift,代码行数:26,代码来源:SourceEntityWalker.cpp

示例3: getLineNumber

static unsigned getLineNumber(DCType *DC) {
  SourceLoc loc = DC->getLoc();
  if (loc.isInvalid())
    return 0;

  const ASTContext &ctx = static_cast<const DeclContext *>(DC)->getASTContext();
  return ctx.SourceMgr.getLineAndColumn(loc).first;
}
开发者ID:XLsn0wKit,项目名称:swift,代码行数:8,代码来源:DeclContext.cpp

示例4: addLocToRecord

void SerializedDiagnosticConsumer::
emitDiagnosticMessage(SourceManager &SM,
                      SourceLoc Loc,
                      DiagnosticKind Kind,
                      StringRef Text,
                      const DiagnosticInfo &Info) {

  // Emit the diagnostic to bitcode.
  llvm::BitstreamWriter &Stream = State->Stream;
  RecordData &Record = State->Record;
  AbbreviationMap &Abbrevs = State->Abbrevs;

  StringRef filename = "";
  if (Loc.isValid())
    filename = SM.getIdentifierForBuffer(SM.findBufferContainingLoc(Loc));

  // Emit the RECORD_DIAG record.
  Record.clear();
  Record.push_back(RECORD_DIAG);
  Record.push_back(getDiagnosticLevel(Kind));
  addLocToRecord(Loc, SM, filename, Record);

  // FIXME: Swift diagnostics currently have no category.
  Record.push_back(0);
  // FIXME: Swift diagnostics currently have no flags.
  Record.push_back(0);

  // Emit the message.
  Record.push_back(Text.size());
  Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG), Record, Text);

  // If the location is invalid, do not emit source ranges or fixits.
  if (Loc.isInvalid())
    return;

  // Emit source ranges.
  auto RangeAbbrev = State->Abbrevs.get(RECORD_SOURCE_RANGE);
  for (const auto &R : Info.Ranges) {
    if (R.isInvalid())
      continue;
    State->Record.clear();
    State->Record.push_back(RECORD_SOURCE_RANGE);
    addRangeToRecord(R, SM, filename, State->Record);
    State->Stream.EmitRecordWithAbbrev(RangeAbbrev, State->Record);
  }

  // Emit FixIts.
  auto FixItAbbrev = State->Abbrevs.get(RECORD_FIXIT);
  for (const auto &F : Info.FixIts) {
    if (F.getRange().isValid()) {
      State->Record.clear();
      State->Record.push_back(RECORD_FIXIT);
      addRangeToRecord(F.getRange(), SM, filename, State->Record);
      State->Record.push_back(F.getText().size());
      Stream.EmitRecordWithBlob(FixItAbbrev, Record, F.getText());
    }
  }
}
开发者ID:A-Goretsky,项目名称:swift,代码行数:58,代码来源:SerializedDiagnosticConsumer.cpp

示例5: lookupVisibleDecls

void swift::lookupVisibleDecls(VisibleDeclConsumer &Consumer,
                               const DeclContext *DC,
                               LazyResolver *TypeResolver,
                               bool IncludeTopLevel,
                               SourceLoc Loc) {
  if (Loc.isInvalid()) {
    lookupVisibleDeclsImpl(Consumer, DC, TypeResolver, IncludeTopLevel, Loc);
    return;
  }

  // Filtering out unusable values.
  class LocalConsumer : public VisibleDeclConsumer {
    const SourceManager &SM;
    SourceLoc Loc;
    VisibleDeclConsumer &Consumer;

    bool isUsableValue(ValueDecl *VD, DeclVisibilityKind Reason) {

      // Check "use within its own initial value" case.
      if (auto *varD = dyn_cast<VarDecl>(VD))
        if (auto *PBD = varD->getParentPatternBinding())
          if (!PBD->isImplicit() &&
              SM.rangeContainsTokenLoc(PBD->getSourceRange(), Loc))
            return false;

      switch (Reason) {
      case DeclVisibilityKind::LocalVariable:
        // Use of 'TypeDecl's before declaration is allowed.
        if (isa<TypeDecl>(VD))
          return true;

        return SM.isBeforeInBuffer(VD->getLoc(), Loc);

      case DeclVisibilityKind::VisibleAtTopLevel:
        // TODO: Implement forward reference rule for script mode? Currently,
        // it's not needed because the rest of the file hasn't been parsed.
        // See: https://bugs.swift.org/browse/SR-284 for the rule.
        return true;

      default:
        // Other visibility kind are always usable.
        return true;
      }
    }

  public:
    LocalConsumer(const SourceManager &SM, SourceLoc Loc,
                  VisibleDeclConsumer &Consumer)
        : SM(SM), Loc(Loc), Consumer(Consumer) {}

    void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) {
      if (isUsableValue(VD, Reason))
        Consumer.foundDecl(VD, Reason);
    }
  } LocalConsumer(DC->getASTContext().SourceMgr, Loc, Consumer);

  lookupVisibleDeclsImpl(LocalConsumer, DC, TypeResolver, IncludeTopLevel, Loc);
}
开发者ID:erica,项目名称:swift,代码行数:58,代码来源:LookupVisibleDecls.cpp

示例6: handlePrimaryAST

    void handlePrimaryAST(ASTUnitRef AstUnit) override {
      auto &CompInst = AstUnit->getCompilerInstance();
      auto &SrcFile = AstUnit->getPrimarySourceFile();

      trace::TracedOperation TracedOp;

      SmallVector<std::pair<unsigned, unsigned>, 8> Ranges;

      auto Action = [&]() {
        if (trace::enabled()) {
          trace::SwiftInvocation SwiftArgs;
          Invok->raw(SwiftArgs.Args.Args, SwiftArgs.Args.PrimaryFile);
          trace::initTraceFiles(SwiftArgs, CompInst);
          TracedOp.start(trace::OperationKind::RelatedIdents, SwiftArgs,
                        {std::make_pair("Offset", std::to_string(Offset))});
        }

        unsigned BufferID = SrcFile.getBufferID().getValue();
        SourceLoc Loc =
          Lexer::getLocForStartOfToken(CompInst.getSourceMgr(), BufferID, Offset);
        if (Loc.isInvalid())
          return;

        SemaLocResolver Resolver(SrcFile);
        SemaToken SemaTok = Resolver.resolve(Loc);
        if (SemaTok.isInvalid())
          return;
        if (SemaTok.IsKeywordArgument)
          return;

        ValueDecl *VD = SemaTok.CtorTyRef ? SemaTok.CtorTyRef : SemaTok.ValueD;
        if (!VD)
          return; // This was a module reference.

        // Only accept pointing to an identifier.
        if (!SemaTok.IsRef &&
            (isa<ConstructorDecl>(VD) ||
             isa<DestructorDecl>(VD) ||
             isa<SubscriptDecl>(VD)))
          return;
        if (VD->getName().isOperator())
          return;

        RelatedIdScanner Scanner(SrcFile, BufferID, VD, Ranges);
        if (DeclContext *LocalDC = VD->getDeclContext()->getLocalContext()) {
          Scanner.walk(LocalDC);
        } else {
          Scanner.walk(SrcFile);
        }
      };
      Action();

      RelatedIdentsInfo Info;
      Info.Ranges = Ranges;
      Receiver(Info);
    }
开发者ID:arbales,项目名称:swift,代码行数:56,代码来源:SwiftSourceDocInfo.cpp

示例7: assert

Optional<FileSpecificDiagnosticConsumer::Subconsumer *>
FileSpecificDiagnosticConsumer::subconsumerForLocation(SourceManager &SM,
                                                       SourceLoc loc) {
  // Diagnostics with invalid locations always go to every consumer.
  if (loc.isInvalid())
    return None;

  // What if a there's a FileSpecificDiagnosticConsumer but there are no
  // subconsumers in it? (This situation occurs for the fix-its
  // FileSpecificDiagnosticConsumer.) In such a case, bail out now.
  if (Subconsumers.empty())
    return None;

  // This map is generated on first use and cached, to allow the
  // FileSpecificDiagnosticConsumer to be set up before the source files are
  // actually loaded.
  if (ConsumersOrderedByRange.empty()) {

    // It's possible to get here while a bridging header PCH is being
    // attached-to, if there's some sort of AST-reader warning or error, which
    // happens before CompilerInstance::setUpInputs(), at which point _no_
    // source buffers are loaded in yet. In that case we return None, rather
    // than trying to build a nonsensical map (and actually crashing since we
    // can't find buffers for the inputs).
    assert(!Subconsumers.empty());
    if (!SM.getIDForBufferIdentifier(Subconsumers.begin()->getInputFileName())
             .hasValue()) {
      assert(llvm::none_of(Subconsumers, [&](const Subconsumer &subconsumer) {
        return SM.getIDForBufferIdentifier(subconsumer.getInputFileName())
            .hasValue();
      }));
      return None;
    }
    auto *mutableThis = const_cast<FileSpecificDiagnosticConsumer*>(this);
    mutableThis->computeConsumersOrderedByRange(SM);
  }

  // This std::lower_bound call is doing a binary search for the first range
  // that /might/ contain 'loc'. Specifically, since the ranges are sorted
  // by end location, it's looking for the first range where the end location
  // is greater than or equal to 'loc'.
  const ConsumerAndRange *possiblyContainingRangeIter = std::lower_bound(
      ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(), loc,
      [](const ConsumerAndRange &entry, SourceLoc loc) -> bool {
        return entry.endsAfter(loc);
      });

  if (possiblyContainingRangeIter != ConsumersOrderedByRange.end() &&
      possiblyContainingRangeIter->contains(loc)) {
    auto *consumerAndRangeForLocation =
        const_cast<ConsumerAndRange *>(possiblyContainingRangeIter);
    return &(*this)[*consumerAndRangeForLocation];
  }

  return None;
}
开发者ID:JoniusLi,项目名称:swift-1,代码行数:56,代码来源:DiagnosticConsumer.cpp

示例8: compare

Optional<FileSpecificDiagnosticConsumer::ConsumerSpecificInformation *>
FileSpecificDiagnosticConsumer::consumerSpecificInformationForLocation(
    SourceManager &SM, SourceLoc loc) const {
  // Diagnostics with invalid locations always go to every consumer.
  if (loc.isInvalid())
    return None;

  // This map is generated on first use and cached, to allow the
  // FileSpecificDiagnosticConsumer to be set up before the source files are
  // actually loaded.
  if (ConsumersOrderedByRange.empty()) {

    // It's possible to get here while a bridging header PCH is being
    // attached-to, if there's some sort of AST-reader warning or error, which
    // happens before CompilerInstance::setUpInputs(), at which point _no_
    // source buffers are loaded in yet. In that case we return None, rather
    // than trying to build a nonsensical map (and actually crashing since we
    // can't find buffers for the inputs).
    assert(!SubConsumers.empty());
    if (!SM.getIDForBufferIdentifier(SubConsumers.begin()->first).hasValue()) {
      assert(llvm::none_of(SubConsumers, [&](const ConsumerPair &pair) {
            return SM.getIDForBufferIdentifier(pair.first).hasValue();
          }));
      return None;
    }
    auto *mutableThis = const_cast<FileSpecificDiagnosticConsumer*>(this);
    mutableThis->computeConsumersOrderedByRange(SM);
  }

  // This std::lower_bound call is doing a binary search for the first range
  // that /might/ contain 'loc'. Specifically, since the ranges are sorted
  // by end location, it's looking for the first range where the end location
  // is greater than or equal to 'loc'.
  const ConsumerSpecificInformation *possiblyContainingRangeIter =
      std::lower_bound(
          ConsumersOrderedByRange.begin(), ConsumersOrderedByRange.end(), loc,
          [](const ConsumerSpecificInformation &entry, SourceLoc loc) -> bool {
            auto compare = std::less<const char *>();
            return compare(getRawLoc(entry.range.getEnd()).getPointer(),
                           getRawLoc(loc).getPointer());
          });

  if (possiblyContainingRangeIter != ConsumersOrderedByRange.end() &&
      possiblyContainingRangeIter->range.contains(loc)) {
    return const_cast<ConsumerSpecificInformation *>(
        possiblyContainingRangeIter);
  }

  return None;
}
开发者ID:shahmishal,项目名称:swift,代码行数:50,代码来源:DiagnosticConsumer.cpp

示例9: subconsumerForLocation

Optional<FileSpecificDiagnosticConsumer::Subconsumer *>
FileSpecificDiagnosticConsumer::findSubconsumerForNonNote(
    SourceManager &SM, const SourceLoc loc,
    const SourceLoc bufferIndirectlyCausingDiagnostic) {
  const auto subconsumer = subconsumerForLocation(SM, loc);
  if (!subconsumer)
    return None; // No place to put it; might be in an imported module
  if ((*subconsumer)->getConsumer())
    return subconsumer; // A primary file with a .dia file
  // Try to put it in the responsible primary input
  if (bufferIndirectlyCausingDiagnostic.isInvalid())
    return None;
  const auto currentPrimarySubconsumer =
      subconsumerForLocation(SM, bufferIndirectlyCausingDiagnostic);
  assert(!currentPrimarySubconsumer ||
         (*currentPrimarySubconsumer)->getConsumer() &&
             "current primary must have a .dia file");
  return currentPrimarySubconsumer;
}
开发者ID:JoniusLi,项目名称:swift-1,代码行数:19,代码来源:DiagnosticConsumer.cpp

示例10: startEntityRef

bool IndexSwiftASTWalker::startEntityRef(ValueDecl *D, SourceLoc Loc) {
  if (!shouldIndex(D))
    return false;

  if (Loc.isInvalid())
    return false;

  if (isa<AbstractFunctionDecl>(D)) {
    CallRefEntityInfo Info;
    if (initCallRefEntityInfo(ExprStack.back(), getParentExpr(), D, Loc, Info))
      return false;

    return startEntity(D, Info);

  } else {
    EntityInfo Info;
    if (initEntityInfo(D, Loc, /*isRef=*/true, Info))
      return false;

    return startEntity(D, Info);
  }
}
开发者ID:AaronTKD,项目名称:swift,代码行数:22,代码来源:SwiftIndexing.cpp

示例11: startEntityDecl

bool IndexSwiftASTWalker::startEntityDecl(ValueDecl *D) {
  if (!shouldIndex(D))
    return false;

  SourceLoc Loc = D->getLoc();
  if (Loc.isInvalid() && !IsModuleFile)
    return false;

  if (isa<FuncDecl>(D)) {
    FuncDeclEntityInfo Info;
    if (initFuncDeclEntityInfo(D, Info))
      return false;

    return startEntity(D, Info);

  } else {
    EntityInfo Info;
    if (initEntityInfo(D, Loc, /*isRef=*/false, Info))
      return false;

    return startEntity(D, Info);
  }
}
开发者ID:AaronTKD,项目名称:swift,代码行数:23,代码来源:SwiftIndexing.cpp

示例12: emitDiagnostic

void DiagnosticEngine::emitDiagnostic(const Diagnostic &diagnostic) {
  auto behavior = state.determineBehavior(diagnostic.getID());
  if (behavior == DiagnosticState::Behavior::Ignore)
    return;

  // Figure out the source location.
  SourceLoc loc = diagnostic.getLoc();
  if (loc.isInvalid() && diagnostic.getDecl()) {
    const Decl *decl = diagnostic.getDecl();
    // If a declaration was provided instead of a location, and that declaration
    // has a location we can point to, use that location.
    loc = decl->getLoc();

    if (loc.isInvalid()) {
      // There is no location we can point to. Pretty-print the declaration
      // so we can point to it.
      SourceLoc ppLoc = PrettyPrintedDeclarations[decl];
      if (ppLoc.isInvalid()) {
        class TrackingPrinter : public StreamPrinter {
          SmallVectorImpl<std::pair<const Decl *, uint64_t>> &Entries;

        public:
          TrackingPrinter(
              SmallVectorImpl<std::pair<const Decl *, uint64_t>> &Entries,
              raw_ostream &OS) :
            StreamPrinter(OS), Entries(Entries) {}

          void printDeclLoc(const Decl *D) override {
            Entries.push_back({ D, OS.tell() });
          }
        };
        SmallVector<std::pair<const Decl *, uint64_t>, 8> entries;
        llvm::SmallString<128> buffer;
        llvm::SmallString<128> bufferName;
        {
          // Figure out which declaration to print. It's the top-most
          // declaration (not a module).
          const Decl *ppDecl = decl;
          auto dc = decl->getDeclContext();

          // FIXME: Horrible, horrible hackaround. We're not getting a
          // DeclContext everywhere we should.
          if (!dc) {
            return;
          }

          while (!dc->isModuleContext()) {
            switch (dc->getContextKind()) {
            case DeclContextKind::Module:
              llvm_unreachable("Not in a module context!");
              break;

            case DeclContextKind::FileUnit:
            case DeclContextKind::TopLevelCodeDecl:
              break;

            case DeclContextKind::ExtensionDecl:
              ppDecl = cast<ExtensionDecl>(dc);
              break;

            case DeclContextKind::GenericTypeDecl:
              ppDecl = cast<GenericTypeDecl>(dc);
              break;

            case DeclContextKind::SerializedLocal:
            case DeclContextKind::Initializer:
            case DeclContextKind::AbstractClosureExpr:
            case DeclContextKind::AbstractFunctionDecl:
            case DeclContextKind::SubscriptDecl:
              break;
            }

            dc = dc->getParent();
          }

          // Build the module name path (in reverse), which we use to
          // build the name of the buffer.
          SmallVector<StringRef, 4> nameComponents;
          while (dc) {
            nameComponents.push_back(cast<Module>(dc)->getName().str());
            dc = dc->getParent();
          }

          for (unsigned i = nameComponents.size(); i; --i) {
            bufferName += nameComponents[i-1];
            bufferName += '.';
          }

          if (auto value = dyn_cast<ValueDecl>(ppDecl)) {
            bufferName += value->getNameStr();
          } else if (auto ext = dyn_cast<ExtensionDecl>(ppDecl)) {
            bufferName += ext->getExtendedType().getString();
          }

          // Pretty-print the declaration we've picked.
          llvm::raw_svector_ostream out(buffer);
          TrackingPrinter printer(entries, out);
          ppDecl->print(printer, PrintOptions::printForDiagnostics());
        }

//.........这里部分代码省略.........
开发者ID:IngmarStein,项目名称:swift,代码行数:101,代码来源:DiagnosticEngine.cpp

示例13: fixItChangeInoutArgType

void AssignmentFailure::fixItChangeInoutArgType(const Expr *arg,
                                                Type actualType,
                                                Type neededType) const {
  auto *DC = getDC();
  auto *DRE = dyn_cast<DeclRefExpr>(arg);
  if (!DRE)
    return;

  auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl());
  if (!VD)
    return;

  // Don't emit for non-local variables.
  // (But in script-mode files, we consider module-scoped
  // variables in the same file to be local variables.)
  auto VDC = VD->getDeclContext();
  bool isLocalVar = VDC->isLocalContext();
  if (!isLocalVar && VDC->isModuleScopeContext()) {
    auto argFile = DC->getParentSourceFile();
    auto varFile = VDC->getParentSourceFile();
    isLocalVar = (argFile == varFile && argFile->isScriptMode());
  }
  if (!isLocalVar)
    return;

  SmallString<32> scratch;
  SourceLoc endLoc;   // Filled in if we decide to diagnose this
  SourceLoc startLoc; // Left invalid if we're inserting

  auto isSimpleTypelessPattern = [](Pattern *P) -> bool {
    if (auto VP = dyn_cast_or_null<VarPattern>(P))
      P = VP->getSubPattern();
    return P && isa<NamedPattern>(P);
  };

  auto typeRange = VD->getTypeSourceRangeForDiagnostics();
  if (typeRange.isValid()) {
    startLoc = typeRange.Start;
    endLoc = typeRange.End;
  } else if (isSimpleTypelessPattern(VD->getParentPattern())) {
    endLoc = VD->getNameLoc();
    scratch += ": ";
  }

  if (endLoc.isInvalid())
    return;

  scratch += neededType.getString();

  // Adjust into the location where we actually want to insert
  endLoc = Lexer::getLocForEndOfToken(getASTContext().SourceMgr, endLoc);

  // Since we already adjusted endLoc, this will turn an insertion
  // into a zero-character replacement.
  if (!startLoc.isValid())
    startLoc = endLoc;

  emitDiagnostic(VD->getLoc(), diag::inout_change_var_type_if_possible,
                 actualType, neededType)
      .fixItReplaceChars(startLoc, endLoc, scratch);
}
开发者ID:erica,项目名称:swift,代码行数:61,代码来源:CSDiagnostics.cpp

示例14: ParserStatus

ParserStatus
Parser::parseParameterClause(SourceLoc &leftParenLoc,
                             SmallVectorImpl<ParsedParameter> &params,
                             SourceLoc &rightParenLoc,
                             DefaultArgumentInfo *defaultArgs,
                             ParameterContextKind paramContext) {
  assert(params.empty() && leftParenLoc.isInvalid() &&
         rightParenLoc.isInvalid() && "Must start with empty state");

  // Consume the starting '(';
  leftParenLoc = consumeToken(tok::l_paren);

  // Trivial case: empty parameter list.
  if (Tok.is(tok::r_paren)) {
    rightParenLoc = consumeToken(tok::r_paren);
    return ParserStatus();
  }

  // Parse the parameter list.
  bool isClosure = paramContext == ParameterContextKind::Closure;
  return parseList(tok::r_paren, leftParenLoc, rightParenLoc, tok::comma,
                      /*OptionalSep=*/false, /*AllowSepAfterLast=*/false,
                      diag::expected_rparen_parameter,
                      [&]() -> ParserStatus {
    ParsedParameter param;
    ParserStatus status;
    SourceLoc StartLoc = Tok.getLoc();

    unsigned defaultArgIndex = defaultArgs ? defaultArgs->NextIndex++ : 0;

    // Attributes.
    bool FoundCCToken;
    parseDeclAttributeList(param.Attrs, FoundCCToken,
                          /*stop at type attributes*/true, true);
    if (FoundCCToken) {
      if (CodeCompletion) {
        CodeCompletion->completeDeclAttrKeyword(nullptr, isInSILMode(), true);
      } else {
        status |= makeParserCodeCompletionStatus();
      }
    }

    // ('inout' | 'let' | 'var')?
    if (Tok.is(tok::kw_inout)) {
      param.LetVarInOutLoc = consumeToken();
      param.SpecifierKind = ParsedParameter::InOut;
    } else if (Tok.is(tok::kw_let)) {
      param.LetVarInOutLoc = consumeToken();
      param.SpecifierKind = ParsedParameter::Let;
    } else if (Tok.is(tok::kw_var)) {
      diagnose(Tok.getLoc(), diag::var_parameter_not_allowed)
        .fixItRemove(Tok.getLoc());
      param.LetVarInOutLoc = consumeToken();
      param.SpecifierKind = ParsedParameter::Var;
    }

    // Redundant specifiers are fairly common, recognize, reject, and recover
    // from this gracefully.
    if (Tok.isAny(tok::kw_inout, tok::kw_let, tok::kw_var)) {
      diagnose(Tok, diag::parameter_inout_var_let)
        .fixItRemove(Tok.getLoc());
      consumeToken();
      param.isInvalid = true;
    }

    if (startsParameterName(*this, isClosure)) {
      // identifier-or-none for the first name
      if (Tok.is(tok::kw__)) {
        param.FirstNameLoc = consumeToken();
      } else {
        assert(Tok.canBeArgumentLabel() && "startsParameterName() lied");
        param.FirstName = Context.getIdentifier(Tok.getText());
        param.FirstNameLoc = consumeToken();
      }

      // identifier-or-none? for the second name
      if (Tok.canBeArgumentLabel()) {
        if (!Tok.is(tok::kw__))
          param.SecondName = Context.getIdentifier(Tok.getText());

        param.SecondNameLoc = consumeToken();
      }

      // Operators and closures cannot have API names.
      if ((paramContext == ParameterContextKind::Operator ||
           paramContext == ParameterContextKind::Closure) &&
          !param.FirstName.empty() &&
          param.SecondNameLoc.isValid()) {
        diagnose(param.FirstNameLoc, diag::parameter_operator_keyword_argument,
                 isClosure)
          .fixItRemoveChars(param.FirstNameLoc, param.SecondNameLoc);
        param.FirstName = param.SecondName;
        param.FirstNameLoc = param.SecondNameLoc;
        param.SecondName = Identifier();
        param.SecondNameLoc = SourceLoc();
      }

      // (':' type)?
      if (consumeIf(tok::colon)) {
        auto type = parseType(diag::expected_parameter_type);
//.........这里部分代码省略.........
开发者ID:ditedondaw,项目名称:swift,代码行数:101,代码来源:ParsePattern.cpp

示例15: ParsingTypeTuple

/// parseTypeTupleBody
///   type-tuple:
///     '(' type-tuple-body? ')'
///   type-tuple-body:
///     type-tuple-element (',' type-tuple-element)* '...'?
///   type-tuple-element:
///     identifier ':' type
///     type
ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
  Parser::StructureMarkerRAII ParsingTypeTuple(*this, Tok);
  SourceLoc RPLoc, LPLoc = consumeToken(tok::l_paren);
  SourceLoc EllipsisLoc;
  unsigned EllipsisIdx;
  SmallVector<TypeRepr *, 8> ElementsR;

  ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
                                  tok::comma, /*OptionalSep=*/false,
                                  /*AllowSepAfterLast=*/false,
                                  diag::expected_rparen_tuple_type_list,
                                  [&] () -> ParserStatus {
    // If this is an inout marker in an argument list, consume the inout.
    SourceLoc InOutLoc;
    consumeIf(tok::kw_inout, InOutLoc);

    // If the tuple element starts with "ident :", then
    // the identifier is an element tag, and it is followed by a type
    // annotation.
    if (Tok.canBeArgumentLabel() && peekToken().is(tok::colon)) {
      // Consume the name
      Identifier name;
      if (!Tok.is(tok::kw__))
        name = Context.getIdentifier(Tok.getText());
      SourceLoc nameLoc = consumeToken();

      // Consume the ':'.
      consumeToken(tok::colon);

      // Parse the type annotation.
      ParserResult<TypeRepr> type = parseType(diag::expected_type);
      if (type.hasCodeCompletion())
        return makeParserCodeCompletionStatus();
      if (type.isNull())
        return makeParserError();

      // If an 'inout' marker was specified, build the type.  Note that we bury
      // the inout locator within the named locator.  This is weird but required
      // by sema apparently.
      if (InOutLoc.isValid())
        type = makeParserResult(new (Context) InOutTypeRepr(type.get(),
                                                            InOutLoc));

      
      ElementsR.push_back(
          new (Context) NamedTypeRepr(name, type.get(), nameLoc));
    } else {
      // Otherwise, this has to be a type.
      ParserResult<TypeRepr> type = parseType();
      if (type.hasCodeCompletion())
        return makeParserCodeCompletionStatus();
      if (type.isNull())
        return makeParserError();
      if (InOutLoc.isValid())
        type = makeParserResult(new (Context) InOutTypeRepr(type.get(),
                                                            InOutLoc));

      ElementsR.push_back(type.get());
    }

    // Parse '= expr' here so we can complain about it directly, rather
    // than dying when we see it.
    if (Tok.is(tok::equal)) {
      SourceLoc equalLoc = consumeToken(tok::equal);
      auto init = parseExpr(diag::expected_init_value);
      auto inFlight = diagnose(equalLoc, diag::tuple_type_init);
      if (init.isNonNull())
        inFlight.fixItRemove(SourceRange(equalLoc, init.get()->getEndLoc()));
    }

    if (Tok.isEllipsis()) {
      if (EllipsisLoc.isValid()) {
        diagnose(Tok, diag::multiple_ellipsis_in_tuple)
          .highlight(EllipsisLoc)
          .fixItRemove(Tok.getLoc());
        (void)consumeToken();
      } else {
        EllipsisLoc = consumeToken();
        EllipsisIdx = ElementsR.size() - 1;
      }
    }
    return makeParserSuccess();
  });

  if (EllipsisLoc.isValid() && ElementsR.empty()) {
    EllipsisLoc = SourceLoc();
  }

  if (EllipsisLoc.isInvalid())
    EllipsisIdx = ElementsR.size();

  return makeParserResult(Status,
//.........这里部分代码省略.........
开发者ID:A-Goretsky,项目名称:swift,代码行数:101,代码来源:ParseType.cpp


注:本文中的SourceLoc::isInvalid方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。