static std::error_code
openModuleFiles(StringRef DirName, StringRef ModuleFilename,
                StringRef ModuleDocFilename,
                std::unique_ptr<llvm::MemoryBuffer> &ModuleBuffer,
                std::unique_ptr<llvm::MemoryBuffer> &ModuleDocBuffer,
                llvm::SmallVectorImpl<char> &Scratch) {
  // Try to open the module file first.  If we fail, don't even look for the
  // module documentation file.
  Scratch.clear();
  llvm::sys::path::append(Scratch, DirName, ModuleFilename);
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleOrErr =
    llvm::MemoryBuffer::getFile(StringRef(Scratch.data(), Scratch.size()));
  if (!ModuleOrErr)
    return ModuleOrErr.getError();

  // Try to open the module documentation file.  If it does not exist, ignore
  // the error.  However, pass though all other errors.
  Scratch.clear();
  llvm::sys::path::append(Scratch, DirName, ModuleDocFilename);
  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> ModuleDocOrErr =
    llvm::MemoryBuffer::getFile(StringRef(Scratch.data(), Scratch.size()));
  if (!ModuleDocOrErr &&
      ModuleDocOrErr.getError() != std::errc::no_such_file_or_directory) {
    return ModuleDocOrErr.getError();
  }
  ModuleBuffer = std::move(ModuleOrErr.get());
  if (ModuleDocOrErr)
    ModuleDocBuffer = std::move(ModuleDocOrErr.get());
  return std::error_code();
}
llvm::error_code canonicalize(const llvm::Twine &path, llvm::SmallVectorImpl<char> &result) {
    std::string p = path.str();
#ifdef PATH_MAX
    int path_max = PATH_MAX;
#else
    int path_max = pathconf(p.c_str(), _PC_PATH_MAX);
    if (path_max <= 0)
        path_max = 4096;
#endif
    result.resize(path_max);
    realpath(p.c_str(), result.data());
    result.resize(strlen(result.data()));
    return llvm::error_code::success();
}
Beispiel #3
0
void UUID::toString(llvm::SmallVectorImpl<char> &out) const {
  out.resize(UUID::StringBufferSize);
  uuid_unparse_upper(Value, out.data());
  // Pop off the null terminator.
  assert(out.back() == '\0' && "did not null-terminate?!");
  out.pop_back();
}
Beispiel #4
0
StringRef DeclName::getString(llvm::SmallVectorImpl<char> &scratch,
                              bool skipEmptyArgumentNames) const {
  {
    llvm::raw_svector_ostream out(scratch);
    print(out, skipEmptyArgumentNames);
  }

  return StringRef(scratch.data(), scratch.size());
}
llvm::StringRef
ParserImpl::MergeTokensUntil(const unsigned int* toks,
                             unsigned int num_toks,
                             SourceLocation* start,
                             SourceLocation* end,
                             llvm::SmallVectorImpl<char>& buffer,
                             bool stop_at_eos,
                             bool stop_at_ws)
{
    buffer.clear();
    *start = *end = m_token.getLocation();
    for (;;)
    {
        // If we found one of the tokens, stop.
        for (unsigned i = 0; i < num_toks; ++i)
        {
            if (m_token.is(toks[i]))
                goto done;
        }

        // If we hit end of statement, stop.
        if (stop_at_eos && m_token.isEndOfStatement())
            break;

        // Turn the token back into characters.
        // The first if's are optimizations for common cases.
        llvm::StringRef data;
        if (m_token.isLiteral())
        {
            data = m_token.getLiteral();
        }
        else if (m_token.is(Token::identifier) || m_token.is(Token::label))
        {
            IdentifierInfo* ii = m_token.getIdentifierInfo();
            data = ii->getName();
        }
        else
        {
            // Get the raw data from the source manager.
            SourceManager& smgr = m_preproc.getSourceManager();
            data =
                llvm::StringRef(smgr.getCharacterData(m_token.getLocation()),
                                m_token.getLength());
        }
        buffer.append(data.begin(), data.end());
        *end = m_token.getEndLocation();
        ConsumeAnyToken();

        // If we hit a token with leading space, stop.
        // We do this down here in case the first token had preceding ws.
        if (stop_at_ws && m_token.hasLeadingSpace())
            break;
    }
done:
    return llvm::StringRef(buffer.data(), buffer.size());
}
Beispiel #6
0
/// getSpelling - This method is used to get the spelling of a token into a
/// SmallVector. Note that the returned StringRef may not point to the
/// supplied buffer if a copy can be avoided.
llvm::StringRef Preprocessor::getSpelling(const Token &Tok,
                                          llvm::SmallVectorImpl<char> &Buffer,
                                          bool *Invalid) const {
  // Try the fast path.
  if (const IdentifierInfo *II = Tok.getIdentifierInfo())
    return II->getName();

  // Resize the buffer if we need to copy into it.
  if (Tok.needsCleaning())
    Buffer.resize(Tok.getLength());

  const char *Ptr = Buffer.data();
  unsigned Len = getSpelling(Tok, Ptr, Invalid);
  return llvm::StringRef(Ptr, Len);
}
Beispiel #7
0
  void DeclExtractor::EnforceInitOrder(llvm::SmallVectorImpl<Stmt*>& Stmts){
    Scope* TUScope = m_Sema->TUScope;
    DeclContext* TUDC = static_cast<DeclContext*>(TUScope->getEntity());
    // We can't PushDeclContext, because we don't have scope.
    Sema::ContextRAII pushedDC(*m_Sema, TUDC);

    std::string FunctionName = "__fd";
    createUniqueName(FunctionName);
    IdentifierInfo& IIFD = m_Context->Idents.get(FunctionName);
    SourceLocation Loc;
    NamedDecl* ND = m_Sema->ImplicitlyDefineFunction(Loc, IIFD, TUScope);
    if (FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(ND)) {
      FD->setImplicit(false); // Better for debugging

      // Add a return statement if it doesn't exist
      if (!isa<ReturnStmt>(Stmts.back())) {
        Sema::ContextRAII pushedDC(*m_Sema, FD);
        // Generate the return statement:
        // First a literal 0, then the return taking that literal.
        // One bit is enough:
        llvm::APInt ZeroInt(m_Context->getIntWidth(m_Context->IntTy), 0,
                            /*isSigned=*/true);
        IntegerLiteral* ZeroLit
          = IntegerLiteral::Create(*m_Context, ZeroInt, m_Context->IntTy,
                                   SourceLocation());
        Stmts.push_back(m_Sema->ActOnReturnStmt(ZeroLit->getExprLoc(), 
                                                ZeroLit).take());
      }

      // Wrap Stmts into a function body.
      llvm::ArrayRef<Stmt*> StmtsRef(Stmts.data(), Stmts.size());
      CompoundStmt* CS = new (*m_Context)CompoundStmt(*m_Context, StmtsRef,
                                                      Loc, Loc);
      FD->setBody(CS);
      // We know the transaction is closed, but it is safe.
      getTransaction()->forceAppend(FD);

      // Create the VarDecl with the init      
      std::string VarName = "__vd";
      createUniqueName(VarName);
      IdentifierInfo& IIVD = m_Context->Idents.get(VarName);
      VarDecl* VD = VarDecl::Create(*m_Context, TUDC, Loc, Loc, &IIVD,
                                    FD->getReturnType(), (TypeSourceInfo*)0,
                                    SC_None);
      LookupResult R(*m_Sema, FD->getDeclName(), Loc, Sema::LookupMemberName);
      R.addDecl(FD);
      CXXScopeSpec CSS;
      Expr* UnresolvedLookup
        = m_Sema->BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).take();
      Expr* TheCall = m_Sema->ActOnCallExpr(TUScope, UnresolvedLookup, Loc, 
                                            MultiExprArg(), Loc).take();
      assert(VD && TheCall && "Missing VD or its init!");
      VD->setInit(TheCall);

      // We know the transaction is closed, but it is safe.
      getTransaction()->forceAppend(VD); // Add it to the transaction for codegenning
      TUDC->addHiddenDecl(VD);
      Stmts.clear();
      return;
    }
    llvm_unreachable("Must be able to enforce init order.");
  }
// ParseArguments -
static void ParseArguments(llvm::SmallVectorImpl<const char*> &ArgVector,
                           llvm::SmallVectorImpl<const char*> &Inputs,
                           RSCCOptions &Opts,
                           clang::DiagnosticsEngine &DiagEngine) {
  if (ArgVector.size() > 1) {
    const char **ArgBegin = ArgVector.data() + 1;
    const char **ArgEnd = ArgVector.data() + ArgVector.size();
    unsigned MissingArgIndex, MissingArgCount;
    llvm::OwningPtr<OptTable> OptParser(createRSCCOptTable());
    llvm::OwningPtr<InputArgList> Args(
      OptParser->ParseArgs(ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount));

    // Check for missing argument error.
    if (MissingArgCount)
      DiagEngine.Report(clang::diag::err_drv_missing_argument)
        << Args->getArgString(MissingArgIndex) << MissingArgCount;

    clang::DiagnosticOptions DiagOpts;
    DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w);
    DiagOpts.Warnings = Args->getAllArgValues(OPT_W);
    clang::ProcessWarningOptions(DiagEngine, DiagOpts);

    // Issue errors on unknown arguments.
    for (arg_iterator it = Args->filtered_begin(OPT_UNKNOWN),
        ie = Args->filtered_end(); it != ie; ++it)
      DiagEngine.Report(clang::diag::err_drv_unknown_argument)
        << (*it)->getAsString(*Args);

    for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
        it != ie; ++it) {
      const Arg *A = *it;
      if (A->getOption().getKind() == Option::InputClass)
        Inputs.push_back(A->getValue(*Args));
    }

    Opts.mIncludePaths = Args->getAllArgValues(OPT_I);

    Opts.mOutputDir = Args->getLastArgValue(OPT_o);

    if (const Arg *A = Args->getLastArg(OPT_M_Group)) {
      switch (A->getOption().getID()) {
        case OPT_M: {
          Opts.mOutputDep = 1;
          Opts.mOutputType = slang::Slang::OT_Dependency;
          break;
        }
        case OPT_MD: {
          Opts.mOutputDep = 1;
          Opts.mOutputType = slang::Slang::OT_Bitcode;
          break;
        }
        default: {
          slangAssert(false && "Invalid option in M group!");
        }
      }
    }

    if (const Arg *A = Args->getLastArg(OPT_Output_Type_Group)) {
      switch (A->getOption().getID()) {
        case OPT_emit_asm: {
          Opts.mOutputType = slang::Slang::OT_Assembly;
          break;
        }
        case OPT_emit_llvm: {
          Opts.mOutputType = slang::Slang::OT_LLVMAssembly;
          break;
        }
        case OPT_emit_bc: {
          Opts.mOutputType = slang::Slang::OT_Bitcode;
          break;
        }
        case OPT_emit_nothing: {
          Opts.mOutputType = slang::Slang::OT_Nothing;
          break;
        }
        default: {
          slangAssert(false && "Invalid option in output type group!");
        }
      }
    }

    if (Opts.mOutputDep &&
        ((Opts.mOutputType != slang::Slang::OT_Bitcode) &&
         (Opts.mOutputType != slang::Slang::OT_Dependency)))
      DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with)
          << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
          << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);

    Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix);

    Opts.mJavaReflectionPathBase =
        Args->getLastArgValue(OPT_java_reflection_path_base);
    Opts.mJavaReflectionPackageName =
        Args->getLastArgValue(OPT_java_reflection_package_name);

    Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name);

    llvm::StringRef BitcodeStorageValue =
        Args->getLastArgValue(OPT_bitcode_storage);
    if (BitcodeStorageValue == "ar")
      Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE;
    else if (BitcodeStorageValue == "jc")
      Opts.mBitcodeStorage = slang::BCST_JAVA_CODE;
    else if (!BitcodeStorageValue.empty())
      DiagEngine.Report(clang::diag::err_drv_invalid_value)
          << OptParser->getOptionName(OPT_bitcode_storage)
          << BitcodeStorageValue;

    if (Args->hasArg(OPT_reflect_cpp)) {
      Opts.mBitcodeStorage = slang::BCST_CPP_CODE;
    }

    Opts.mOutputDepDir =
        Args->getLastArgValue(OPT_output_dep_dir, Opts.mOutputDir);
    Opts.mAdditionalDepTargets =
        Args->getAllArgValues(OPT_additional_dep_target);

    Opts.mShowHelp = Args->hasArg(OPT_help);
    Opts.mShowVersion = Args->hasArg(OPT_version);
    Opts.mDebugEmission = Args->hasArg(OPT_emit_g);

    size_t OptLevel = Args->getLastArgIntValue(OPT_optimization_level,
                                               3,
                                               DiagEngine);

    Opts.mOptimizationLevel = OptLevel == 0 ? llvm::CodeGenOpt::None
                                            : llvm::CodeGenOpt::Aggressive;

    Opts.mTargetAPI = Args->getLastArgIntValue(OPT_target_api,
                                               RS_VERSION,
                                               DiagEngine);
  }

  return;
}