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


C++ SmallString::push_back方法代码示例

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


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

示例1: while

/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified
/// memory buffer, free it, and return a new one.
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) {
  SmallString<128> NewFile;
  NewFile.reserve(MB->getBufferSize());

  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
       Ptr != End; ++Ptr) {
    // If C is not a horizontal whitespace, skip it.
    if (*Ptr != ' ' && *Ptr != '\t') {
      NewFile.push_back(*Ptr);
      continue;
    }

    // Otherwise, add one space and advance over neighboring space.
    NewFile.push_back(' ');
    while (Ptr+1 != End &&
           (Ptr[1] == ' ' || Ptr[1] == '\t'))
      ++Ptr;
  }

  // Free the old buffer and return a new one.
  MemoryBuffer *MB2 =
    MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());

  delete MB;
  return MB2;
}
开发者ID:Persper,项目名称:PTMC,代码行数:28,代码来源:FileCheck.cpp

示例2: while

/// Canonicalize whitespaces in the input file. Line endings are replaced
/// with UNIX-style '\n'.
///
/// \param PreserveHorizontal Don't squash consecutive horizontal whitespace
/// characters to a single space.
static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB,
                                           bool PreserveHorizontal) {
  SmallString<128> NewFile;
  NewFile.reserve(MB->getBufferSize());

  for (const char *Ptr = MB->getBufferStart(), *End = MB->getBufferEnd();
       Ptr != End; ++Ptr) {
    // Eliminate trailing dosish \r.
    if (Ptr <= End - 2 && Ptr[0] == '\r' && Ptr[1] == '\n') {
      continue;
    }

    // If current char is not a horizontal whitespace or if horizontal 
    // whitespace canonicalization is disabled, dump it to output as is.
    if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) {
      NewFile.push_back(*Ptr);
      continue;
    }

    // Otherwise, add one space and advance over neighboring space.
    NewFile.push_back(' ');
    while (Ptr+1 != End &&
           (Ptr[1] == ' ' || Ptr[1] == '\t'))
      ++Ptr;
  }

  // Free the old buffer and return a new one.
  MemoryBuffer *MB2 =
    MemoryBuffer::getMemBufferCopy(NewFile.str(), MB->getBufferIdentifier());

  delete MB;
  return MB2;
}
开发者ID:agheorghiu,项目名称:root,代码行数:38,代码来源:FileCheck.cpp

示例3: findEndOfWord

/// \brief Find the end of the word starting at the given offset
/// within a string.
///
/// \returns the index pointing one character past the end of the
/// word.
static unsigned findEndOfWord(unsigned Start, StringRef Str,
                              unsigned Length, unsigned Column,
                              unsigned Columns) {
  assert(Start < Str.size() && "Invalid start position!");
  unsigned End = Start + 1;

  // If we are already at the end of the string, take that as the word.
  if (End == Str.size())
    return End;

  // Determine if the start of the string is actually opening
  // punctuation, e.g., a quote or parentheses.
  char EndPunct = findMatchingPunctuation(Str[Start]);
  if (!EndPunct) {
    // This is a normal word. Just find the first space character.
    while (End < Length && !isspace(Str[End]))
      ++End;
    return End;
  }

  // We have the start of a balanced punctuation sequence (quotes,
  // parentheses, etc.). Determine the full sequence is.
  SmallString<16> PunctuationEndStack;
  PunctuationEndStack.push_back(EndPunct);
  while (End < Length && !PunctuationEndStack.empty()) {
    if (Str[End] == PunctuationEndStack.back())
      PunctuationEndStack.pop_back();
    else if (char SubEndPunct = findMatchingPunctuation(Str[End]))
      PunctuationEndStack.push_back(SubEndPunct);

    ++End;
  }

  // Find the first space character after the punctuation ended.
  while (End < Length && !isspace(Str[End]))
    ++End;

  unsigned PunctWordLength = End - Start;
  if (// If the word fits on this line
      Column + PunctWordLength <= Columns ||
      // ... or the word is "short enough" to take up the next line
      // without too much ugly white space
      PunctWordLength < Columns/3)
    return End; // Take the whole thing as a single "word".

  // The whole quoted/parenthesized string is too long to print as a
  // single "word". Instead, find the "word" that starts just after
  // the punctuation and use that end-point instead. This will recurse
  // until it finds something small enough to consider a word.
  return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns);
}
开发者ID:gwelymernans,项目名称:lfort,代码行数:56,代码来源:TextDiagnostic.cpp

示例4: MachOUniqueMapTy

const MCSectionMachO *MCContext::
getMachOSection(StringRef Segment, StringRef Section,
                unsigned TypeAndAttributes,
                unsigned Reserved2, SectionKind Kind) {

  // We unique sections by their segment/section pair.  The returned section
  // may not have the same flags as the requested section, if so this should be
  // diagnosed by the client as an error.

  // Create the map if it doesn't already exist.
  if (MachOUniquingMap == 0)
    MachOUniquingMap = new MachOUniqueMapTy();
  MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap;

  // Form the name to look up.
  SmallString<64> Name;
  Name += Segment;
  Name.push_back(',');
  Name += Section;

  // Do the lookup, if we have a hit, return it.
  const MCSectionMachO *&Entry = Map[Name.str()];
  if (Entry) return Entry;

  // Otherwise, return a new section.
  return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
                                            Reserved2, Kind);
}
开发者ID:UIKit0,项目名称:llvm-msvc,代码行数:28,代码来源:MCContext.cpp

示例5: constructInitialFnAttributes

/// Construct initial function attributes from options.
void IRGenModule::constructInitialFnAttributes(llvm::AttrBuilder &Attrs) {
  // Add DisableFPElim. 
  if (!IRGen.Opts.DisableFPElim) {
    Attrs.addAttribute("no-frame-pointer-elim", "false");
  } else {
    Attrs.addAttribute("no-frame-pointer-elim", "true");
    Attrs.addAttribute("no-frame-pointer-elim-non-leaf");
  }

  // Add target-cpu and target-features if they are non-null.
  auto *Clang = static_cast<ClangImporter *>(Context.getClangModuleLoader());
  clang::TargetOptions &ClangOpts = Clang->getTargetInfo().getTargetOpts();

  std::string &CPU = ClangOpts.CPU;
  if (CPU != "")
    Attrs.addAttribute("target-cpu", CPU);

  std::vector<std::string> Features = ClangOpts.Features;
  if (!Features.empty()) {
    SmallString<64> allFeatures;
    // Sort so that the target features string is canonical.
    std::sort(Features.begin(), Features.end());
    interleave(Features, [&](const std::string &s) {
      allFeatures.append(s);
    }, [&]{
      allFeatures.push_back(',');
    });
    Attrs.addAttribute("target-features", allFeatures);
  }
  if (IRGen.Opts.OptimizeForSize)
    Attrs.addAttribute(llvm::Attribute::OptimizeForSize);
}
开发者ID:YanlongMa,项目名称:swift,代码行数:33,代码来源:IRGenModule.cpp

示例6: checkWasmComdat

static MCSectionWasm *selectWasmSectionForGlobal(
    MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
    const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) {
  StringRef Group = "";
  checkWasmComdat(GO);

  bool UniqueSectionNames = TM.getUniqueSectionNames();
  SmallString<128> Name = getSectionPrefixForGlobal(Kind);

  if (const auto *F = dyn_cast<Function>(GO)) {
    const auto &OptionalPrefix = F->getSectionPrefix();
    if (OptionalPrefix)
      Name += *OptionalPrefix;
  }

  if (EmitUniqueSection && UniqueSectionNames) {
    Name.push_back('.');
    TM.getNameWithPrefix(Name, GO, Mang, true);
  }
  unsigned UniqueID = MCContext::GenericSectionID;
  if (EmitUniqueSection && !UniqueSectionNames) {
    UniqueID = *NextUniqueID;
    (*NextUniqueID)++;
  }
  return Ctx.getWasmSection(Name, Kind, Group, UniqueID);
}
开发者ID:a565109863,项目名称:src,代码行数:26,代码来源:TargetLoweringObjectFileImpl.cpp

示例7: getSectionPrefixForGlobal

static MCSectionWasm *selectWasmSectionForGlobal(
    MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang,
    const TargetMachine &TM, bool EmitUniqueSection, unsigned *NextUniqueID) {
  StringRef Group = "";
  if (getWasmComdat(GO))
    llvm_unreachable("comdat not yet supported for wasm");

  bool UniqueSectionNames = TM.getUniqueSectionNames();
  SmallString<128> Name = getSectionPrefixForGlobal(Kind);

  uint32_t Type = wasm::WASM_SEC_DATA;
  if (const auto *F = dyn_cast<Function>(GO)) {
    const auto &OptionalPrefix = F->getSectionPrefix();
    if (OptionalPrefix)
      Name += *OptionalPrefix;
    Type = wasm::WASM_SEC_CODE;
  }

  if (EmitUniqueSection && UniqueSectionNames) {
    Name.push_back('.');
    TM.getNameWithPrefix(Name, GO, Mang, true);
  }
  unsigned UniqueID = MCContext::GenericSectionID;
  if (EmitUniqueSection && !UniqueSectionNames) {
    UniqueID = *NextUniqueID;
    (*NextUniqueID)++;
  }
  return Ctx.getWasmSection(Name, Type, Group, UniqueID);
}
开发者ID:filcab,项目名称:llvm,代码行数:29,代码来源:TargetLoweringObjectFileImpl.cpp

示例8: createTempSymbol

MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
                                           unsigned TypeAndAttributes,
                                           unsigned Reserved2, SectionKind Kind,
                                           const char *BeginSymName) {

  // We unique sections by their segment/section pair.  The returned section
  // may not have the same flags as the requested section, if so this should be
  // diagnosed by the client as an error.

  // Form the name to look up.
  SmallString<64> Name;
  Name += Segment;
  Name.push_back(',');
  Name += Section;

  // Do the lookup, if we have a hit, return it.
  MCSectionMachO *&Entry = MachOUniquingMap[Name];
  if (Entry)
    return Entry;

  MCSymbol *Begin = nullptr;
  if (BeginSymName)
    Begin = createTempSymbol(BeginSymName, false);

  // Otherwise, return a new section.
  return Entry = new (MachOAllocator.Allocate()) MCSectionMachO(
             Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin);
}
开发者ID:2asoft,项目名称:freebsd,代码行数:28,代码来源:MCContext.cpp

示例9: buildMSAsmString

/// Turn a sequence of our tokens back into a string that we can hand
/// to the MC asm parser.
static bool buildMSAsmString(Preprocessor &PP, SourceLocation AsmLoc,
                             ArrayRef<Token> AsmToks,
                             SmallVectorImpl<unsigned> &TokOffsets,
                             SmallString<512> &Asm) {
  assert(!AsmToks.empty() && "Didn't expect an empty AsmToks!");

  // Is this the start of a new assembly statement?
  bool isNewStatement = true;

  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
    const Token &Tok = AsmToks[i];

    // Start each new statement with a newline and a tab.
    if (!isNewStatement && (Tok.is(tok::kw_asm) || Tok.isAtStartOfLine())) {
      Asm += "\n\t";
      isNewStatement = true;
    }

    // Preserve the existence of leading whitespace except at the
    // start of a statement.
    if (!isNewStatement && Tok.hasLeadingSpace())
      Asm += ' ';

    // Remember the offset of this token.
    TokOffsets.push_back(Asm.size());

    // Don't actually write '__asm' into the assembly stream.
    if (Tok.is(tok::kw_asm)) {
      // Complain about __asm at the end of the stream.
      if (i + 1 == e) {
        PP.Diag(AsmLoc, diag::err_asm_empty);
        return true;
      }

      continue;
    }

    // Append the spelling of the token.
    SmallString<32> SpellingBuffer;
    bool SpellingInvalid = false;
    Asm += PP.getSpelling(Tok, SpellingBuffer, &SpellingInvalid);
    assert(!SpellingInvalid && "spelling was invalid after correct parse?");

    // We are no longer at the start of a statement.
    isNewStatement = false;
  }

  // Ensure that the buffer is null-terminated.
  Asm.push_back('\0');
  Asm.pop_back();

  assert(TokOffsets.size() == AsmToks.size());
  return false;
}
开发者ID:2asoft,项目名称:freebsd,代码行数:56,代码来源:ParseStmtAsm.cpp

示例10: migrateInclude

void XCTMigrator::migrateInclude(llvm::StringRef Filename,
                                 CharSourceRange FilenameRange,
                                 SourceLocation HashLoc, bool isAngled) {
  StringRef Parent = "SenTestingKit/";
  if (!Filename.startswith(Parent))
    return;
  if (isFromSenTestInclude(HashLoc))
    return;

  edit::Commit commit(Editor);
  StringRef HeaderName = Filename.substr(Parent.size());
  llvm::StringMap<llvm::StringRef>::iterator I = IncludesMap.find(HeaderName);
  if (I == IncludesMap.end() || I->second.empty()) {
    commit.remove(CharSourceRange::getCharRange(HashLoc,FilenameRange.getEnd()));
  } else {
    SmallString<128> NewInclude;
    NewInclude.push_back(isAngled ? '<' : '"');
    NewInclude += "XCTest/";
    NewInclude += I->second;
    NewInclude.push_back(isAngled ? '>' : '"');
    commit.replace(FilenameRange, NewInclude.str());
  }
  Editor.commit(commit);
}
开发者ID:PodBuilder,项目名称:LLVM,代码行数:24,代码来源:XCTMT.cpp

示例11: StructTag

/// StructTag - generate the name of the struct tag for a type.
/// These names are mandated by ARM's ABI.
static std::string StructTag(StringRef typestr) {
  bool quad = false;
  bool poly = false;
  bool usgn = false;
  
  // base type to get the type string for.
  char type = ClassifyType(typestr, quad, poly, usgn);
  
  SmallString<128> s;
  s += "__simd";
  s += quad ? "128_" : "64_";
  if (usgn)
    s.push_back('u');
  
  switch (type) {
    case 'c':
      s += poly ? "poly8" : "int8";
      break;
    case 's':
      s += poly ? "poly16" : "int16";
      break;
    case 'i':
      s += "int32";
      break;
    case 'l':
      s += "int64";
      break;
    case 'h':
      s += "float16";
      break;
    case 'f':
      s += "float32";
      break;
    default:
      throw "unhandled type!";
      break;
  }

  // Append _t, finishing the struct tag name.
  s += "_t";
  
  return s.str();
}
开发者ID:jyasskin,项目名称:llvm-mirror,代码行数:45,代码来源:NeonEmitter.cpp

示例12: if

/// @brief Find program using shell lookup rules.
/// @param Program This is either an absolute path, relative path, or simple a
///        program name. Look in PATH for any programs that match. If no
///        extension is present, try all extensions in PATHEXT.
/// @return If ec == errc::success, The absolute path to the program. Otherwise
///         the return value is undefined.
static std::string FindProgram(const std::string &Program,
                               std::error_code &ec) {
  char PathName[MAX_PATH + 1];
  typedef SmallVector<StringRef, 12> pathext_t;
  pathext_t pathext;
  // Check for the program without an extension (in case it already has one).
  pathext.push_back("");
  SplitString(std::getenv("PATHEXT"), pathext, ";");

  for (pathext_t::iterator i = pathext.begin(), e = pathext.end(); i != e; ++i){
    SmallString<5> ext;
    for (std::size_t ii = 0, e = i->size(); ii != e; ++ii)
      ext.push_back(::tolower((*i)[ii]));
    LPCSTR Extension = NULL;
    if (ext.size() && ext[0] == '.')
      Extension = ext.c_str();
    DWORD length = ::SearchPathA(NULL,
                                 Program.c_str(),
                                 Extension,
                                 array_lengthof(PathName),
                                 PathName,
                                 NULL);
    if (length == 0)
      ec = windows_error(::GetLastError());
    else if (length > array_lengthof(PathName)) {
      // This may have been the file, return with error.
      ec = windows_error(ERROR_BUFFER_OVERFLOW);
      break;
    } else {
      // We found the path! Return it.
      ec = std::error_code();
      break;
    }
  }

  // Make sure PathName is valid.
  PathName[MAX_PATH] = 0;
  return PathName;
}
开发者ID:AnachroNia,项目名称:llvm,代码行数:45,代码来源:KillTheDoctor.cpp

示例13: constructInitialAttributes

/// Construct initial attributes from options.
llvm::AttributeSet IRGenModule::constructInitialAttributes() {
  llvm::AttributeSet attrsUpdated;
  // Add DisableFPElim. 
  if (!Opts.DisableFPElim) {
    attrsUpdated = attrsUpdated.addAttribute(LLVMContext,
                     llvm::AttributeSet::FunctionIndex,
                     "no-frame-pointer-elim", "false");
  } else {
    attrsUpdated = attrsUpdated.addAttribute(
        LLVMContext, llvm::AttributeSet::FunctionIndex,
        "no-frame-pointer-elim", "true");
    attrsUpdated = attrsUpdated.addAttribute(
        LLVMContext, llvm::AttributeSet::FunctionIndex,
        "no-frame-pointer-elim-non-leaf");
  }

  // Add target-cpu and target-features if they are non-null.
  auto *Clang = static_cast<ClangImporter *>(Context.getClangModuleLoader());
  clang::TargetOptions &ClangOpts = Clang->getTargetInfo().getTargetOpts();

  std::string &CPU = ClangOpts.CPU;
  if (CPU != "")
    attrsUpdated = attrsUpdated.addAttribute(LLVMContext,
                     llvm::AttributeSet::FunctionIndex, "target-cpu", CPU);

  std::vector<std::string> &Features = ClangOpts.Features;
  if (!Features.empty()) {
    SmallString<64> allFeatures;
    interleave(Features, [&](const std::string &s) {
      allFeatures.append(s);
    }, [&]{
      allFeatures.push_back(',');
    });
    attrsUpdated = attrsUpdated.addAttribute(LLVMContext,
                     llvm::AttributeSet::FunctionIndex, "target-features",
                     allFeatures);
  }
  return attrsUpdated;
}
开发者ID:dshah22,项目名称:swift,代码行数:40,代码来源:IRGenModule.cpp

示例14: clang_codeCompleteAt_Impl

void clang_codeCompleteAt_Impl(void *UserData) {
  CodeCompleteAtInfo *CCAI = static_cast<CodeCompleteAtInfo*>(UserData);
  CXTranslationUnit TU = CCAI->TU;
  const char *complete_filename = CCAI->complete_filename;
  unsigned complete_line = CCAI->complete_line;
  unsigned complete_column = CCAI->complete_column;
  struct CXUnsavedFile *unsaved_files = CCAI->unsaved_files;
  unsigned num_unsaved_files = CCAI->num_unsaved_files;
  unsigned options = CCAI->options;
  bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
  CCAI->result = 0;

#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
  const llvm::TimeRecord &StartTime =  llvm::TimeRecord::getCurrentTime();
#endif
#endif

  bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != 0;

  if (cxtu::isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return;
  }

  ASTUnit *AST = cxtu::getASTUnit(TU);
  if (!AST)
    return;

  CIndexer *CXXIdx = TU->CIdx;
  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
    setThreadBackgroundPriority();

  ASTUnit::ConcurrencyCheck Check(*AST);

  // Perform the remapping of source files.
  SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
  for (unsigned I = 0; I != num_unsaved_files; ++I) {
    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
    const llvm::MemoryBuffer *Buffer
      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
    RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename,
                                           Buffer));
  }
  
  if (EnableLogging) {
    // FIXME: Add logging.
  }

  // Parse the resulting source file to find code-completion results.
  AllocatedCXCodeCompleteResults *Results = 
        new AllocatedCXCodeCompleteResults(AST->getFileSystemOpts());
  Results->Results = 0;
  Results->NumResults = 0;
  
  // Create a code-completion consumer to capture the results.
  CodeCompleteOptions Opts;
  Opts.IncludeBriefComments = IncludeBriefComments;
  CaptureCompletionResults Capture(Opts, *Results, &TU);

  // Perform completion.
  AST->CodeComplete(complete_filename, complete_line, complete_column,
                    RemappedFiles,
                    (options & CXCodeComplete_IncludeMacros),
                    (options & CXCodeComplete_IncludeCodePatterns),
                    IncludeBriefComments,
                    Capture,
                    *Results->Diag, Results->LangOpts, *Results->SourceMgr,
                    *Results->FileMgr, Results->Diagnostics,
                    Results->TemporaryBuffers);
  
  // Keep a reference to the allocator used for cached global completions, so
  // that we can be sure that the memory used by our code completion strings
  // doesn't get freed due to subsequent reparses (while the code completion
  // results are still active).
  Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();

  

#ifdef UDP_CODE_COMPLETION_LOGGER
#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
  const llvm::TimeRecord &EndTime =  llvm::TimeRecord::getCurrentTime();
  SmallString<256> LogResult;
  llvm::raw_svector_ostream os(LogResult);

  // Figure out the language and whether or not it uses PCH.
  const char *lang = 0;
  bool usesPCH = false;

  for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
       I != E; ++I) {
    if (*I == 0)
      continue;
    if (strcmp(*I, "-x") == 0) {
      if (I + 1 != E) {
        lang = *(++I);
        continue;
      }
    }
    else if (strcmp(*I, "-include") == 0) {
//.........这里部分代码省略.........
开发者ID:adevress,项目名称:root-1,代码行数:101,代码来源:CIndexCodeCompletion.cpp

示例15: stream


//.........这里部分代码省略.........
    } else {
      enum class DependencyDirection : bool {
        Depends,
        Provides
      };
      using KindPair = std::pair<DependencyKind, DependencyDirection>;

      KindPair dirAndKind = llvm::StringSwitch<KindPair>(key->getValue(scratch))
        .Case(dependsTopLevel,
              std::make_pair(DependencyKind::TopLevelName,
                             DependencyDirection::Depends))
        .Case(dependsNominal,
              std::make_pair(DependencyKind::NominalType,
                             DependencyDirection::Depends))
        .Case(dependsMember,
              std::make_pair(DependencyKind::NominalTypeMember,
                             DependencyDirection::Depends))
        .Case(dependsDynamicLookup,
              std::make_pair(DependencyKind::DynamicLookupName,
                             DependencyDirection::Depends))
        .Case(dependsExternal,
              std::make_pair(DependencyKind::ExternalFile,
                             DependencyDirection::Depends))
        .Case(providesTopLevel,
              std::make_pair(DependencyKind::TopLevelName,
                             DependencyDirection::Provides))
        .Case(providesNominal,
              std::make_pair(DependencyKind::NominalType,
                             DependencyDirection::Provides))
        .Case(providesMember,
              std::make_pair(DependencyKind::NominalTypeMember,
                             DependencyDirection::Provides))
        .Case(providesDynamicLookup,
              std::make_pair(DependencyKind::DynamicLookupName,
                             DependencyDirection::Provides))
        .Default(std::make_pair(DependencyKind(),
                                DependencyDirection::Depends));
      if (dirAndKind.first == DependencyKind())
        return LoadResult::HadError;

      auto *entries = dyn_cast<yaml::SequenceNode>(i->getValue());
      if (!entries)
        return LoadResult::HadError;

      if (dirAndKind.first == DependencyKind::NominalTypeMember) {
        // Handle member dependencies specially. Rather than being a single
        // string, they come in the form ["{MangledBaseName}", "memberName"].
        for (yaml::Node &rawEntry : *entries) {
          bool isCascading = rawEntry.getRawTag() != "!private";

          auto *entry = dyn_cast<yaml::SequenceNode>(&rawEntry);
          if (!entry)
            return LoadResult::HadError;

          auto iter = entry->begin();
          auto *base = dyn_cast<yaml::ScalarNode>(&*iter);
          if (!base)
            return LoadResult::HadError;
          ++iter;

          auto *member = dyn_cast<yaml::ScalarNode>(&*iter);
          if (!member)
            return LoadResult::HadError;
          ++iter;

          // FIXME: LLVM's YAML support doesn't implement == correctly for end
          // iterators.
          assert(!(iter != entry->end()));

          bool isDepends = dirAndKind.second == DependencyDirection::Depends;
          auto &callback = isDepends ? dependsCallback : providesCallback;

          // Smash the type and member names together so we can continue using
          // StringMap.
          SmallString<64> appended;
          appended += base->getValue(scratch);
          appended.push_back('\0');
          appended += member->getValue(scratch);

          UPDATE_RESULT(callback(appended.str(), dirAndKind.first,
                                 isCascading));
        }
      } else {
        for (const yaml::Node &rawEntry : *entries) {
          auto *entry = dyn_cast<yaml::ScalarNode>(&rawEntry);
          if (!entry)
            return LoadResult::HadError;

          bool isDepends = dirAndKind.second == DependencyDirection::Depends;
          auto &callback = isDepends ? dependsCallback : providesCallback;

          UPDATE_RESULT(callback(entry->getValue(scratch), dirAndKind.first,
                                 entry->getRawTag() != "!private"));
        }
      }
    }
  }

  return result;
}
开发者ID:DevAndArtist,项目名称:swift,代码行数:101,代码来源:DependencyGraph.cpp


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