Beispiel #1
0
void EnterPreprocessorTokenStream(clang::Preprocessor& _pp, const clang::Token *start, size_t len, bool DisableMacroExpansion) {
#if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR == 8)
    _pp.EnterTokenStream(start, len, false, DisableMacroExpansion);
#else
    _pp.EnterTokenStream(clang::ArrayRef<clang::Token>{start, len}, DisableMacroExpansion);
#endif
}
clang::FileID CreateFileIDForMemBuffer(clang::Preprocessor &PP, llvm::MemoryBuffer *Buf, clang::SourceLocation Loc)
{
#if CLANG_VERSION_MAJOR != 3 || CLANG_VERSION_MINOR > 4
    return PP.getSourceManager().createFileID(Buf, clang::SrcMgr::C_User, 0, 0, Loc);
#else
    return PP.getSourceManager().createFileIDForMemBuffer(Buf, clang::SrcMgr::C_User, 0, 0, Loc);
#endif
}
Beispiel #3
0
		virtual bool HandleComment(clang::Preprocessor& pp, clang::SourceRange range) override
		{
			auto FID = pp.getSourceManager().getMainFileID();
			int start = range.getBegin().getRawEncoding();
			int end = range.getEnd().getRawEncoding();
			int length = end - start;
			auto bufferStart = pp.getSourceManager().getBuffer(FID)->getBufferStart();
			int fileOffset = pp.getSourceManager().getLocForStartOfFile(FID).getRawEncoding();

			const char* data = bufferStart + start - fileOffset;
			string str(data, length);
			cout << str << endl;

			return false;
		}
Beispiel #4
0
bool MetricPPCustomer::HandleComment(clang::Preprocessor &PP, clang::SourceRange Loc) {

    clang::SourceLocation Start = Loc.getBegin();
    clang::SourceManager &SM = PP.getSourceManager();
	std::string fileName = SM.getFilename( Start ).str();

	/* Excude comments that are not:
	     - Not in the main file and
		 - Not in the file we're currently processing and
		 - Are in a file we've already processed comments for
    */
	if(( SM.getFileID( Start )  == SM.getMainFileID() ) ||
		( fileName == m_commentFile ) ||
		( m_commentFileList->find( fileName ) == m_commentFileList->end() ))
	{
		std::string C(SM.getCharacterData(Start),
					  SM.getCharacterData(Loc.getEnd()));

		if( m_options.ShouldIncludeFile( fileName ))
		{
			MetricUnit* unit = m_topUnit->getSubUnit(fileName, METRIC_UNIT_FILE);
			unit->increment(METRIC_TYPE_COMMENT_BYTE_COUNT, getFileAndLine( SM, &Start ), C.length());
			unit->increment(METRIC_TYPE_COMMENT_COUNT, getFileAndLine( SM, &Start ));
		}

		m_commentFile = fileName;
		m_commentFileList->insert( fileName );
	}
	else
	{
		m_commentFile = "";
	}

	return false;
}
// Get a "file:line:column" source location string.
static std::string getSourceLocationString(clang::Preprocessor &PP,
                                           clang::SourceLocation Loc) {
  if (Loc.isInvalid())
    return std::string("(none)");

  if (Loc.isFileID()) {
    clang::PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);

    if (PLoc.isInvalid()) {
      return std::string("(invalid)");
    }

    std::string Str;
    llvm::raw_string_ostream SS(Str);

    // The macro expansion and spelling pos is identical for file locs.
    SS << "\"" << PLoc.getFilename() << ':' << PLoc.getLine() << ':'
       << PLoc.getColumn() << "\"";

    std::string Result = SS.str();

    // YAML treats backslash as escape, so use forward slashes.
    std::replace(Result.begin(), Result.end(), '\\', '/');

    return Result;
  }

  return std::string("(nonfile)");
}
Beispiel #6
0
static best_guess tok_type(clang::Preprocessor &pp, const char *macro_name,
                           const clang::Token &t, StringSet *seen) {
    using namespace clang;
    tok::TokenKind k = t.getKind();

    if(k == tok::identifier) {
        IdentifierInfo *ii = t.getIdentifierInfo();
        if(ii && !seen->count(ii->getNameStart()))
            return macro_type(pp, ii->getNameStart(),
                              pp.getMacroInfo(ii), seen);

        return tok_ok;
    }

    if (k == tok::l_paren || k == tok::r_paren || k == tok::amp || k == tok::plus ||
        k == tok::star || k == tok::minus || k == tok::tilde || k == tok::slash ||
        k == tok::percent || k == tok::lessless || k == tok::greatergreater ||
        k == tok::caret || k == tok::pipe || k == tok::exclaim ||
        k == tok::kw_int || k == tok::kw_float || k == tok::kw_double ||
        k == tok::kw_long || k == tok::kw_signed || k == tok::kw_unsigned)

        return tok_ok;

    return tok_invalid;
}
Beispiel #7
0
static std::string macro_to_string(const clang::Preprocessor &pp,
                                   const clang::MacroInfo *mi) {
    std::stringstream ss;

    for(clang::MacroInfo::tokens_iterator j = mi->tokens_begin();
        j != mi->tokens_end(); j++) {
        const clang::Token &t = (*j);
        ss << pp.getSpelling(t);
    }

    return ss.str();
}
RSContext::RSContext(clang::Preprocessor &PP,
                     clang::ASTContext &Ctx,
                     const clang::TargetInfo &Target,
                     PragmaList *Pragmas,
                     unsigned int TargetAPI,
                     std::vector<std::string> *GeneratedFileNames)
    : mPP(PP),
      mCtx(Ctx),
      mTarget(Target),
      mPragmas(Pragmas),
      mTargetAPI(TargetAPI),
      mGeneratedFileNames(GeneratedFileNames),
      mTargetData(NULL),
      mLLVMContext(llvm::getGlobalContext()),
      mLicenseNote(NULL),
      mRSPackageName("android.renderscript"),
      version(0),
      mMangleCtx(Ctx.createMangleContext()) {
  slangAssert(mGeneratedFileNames && "Must supply GeneratedFileNames");

  // For #pragma rs export_type
  PP.AddPragmaHandler(
      "rs", RSPragmaHandler::CreatePragmaExportTypeHandler(this));

  // For #pragma rs java_package_name
  PP.AddPragmaHandler(
      "rs", RSPragmaHandler::CreatePragmaJavaPackageNameHandler(this));

  // For #pragma rs set_reflect_license
  PP.AddPragmaHandler(
      "rs", RSPragmaHandler::CreatePragmaReflectLicenseHandler(this));

  // For #pragma version
  PP.AddPragmaHandler(RSPragmaHandler::CreatePragmaVersionHandler(this));

  // Prepare target data
  mTargetData = new llvm::TargetData(Target.getTargetDescription());

  return;
}
    virtual bool HandleComment( clang::Preprocessor &pp, clang::SourceRange rng)
    {
      clang::SourceManager &sm = pp.getSourceManager();
      if( sm.getFilename(rng.getBegin()) == m_inFile)
      {
        std::pair<FileID, unsigned int> startLoc = sm.getDecomposedLoc(rng.getBegin());
        std::pair<FileID, unsigned int> endLoc = sm.getDecomposedLoc(rng.getEnd());

        llvm::StringRef fileData = sm.getBufferData(startLoc.first);

        std::cout << fileData.substr(startLoc.second, endLoc.second - startLoc.second).str();
        std::cout << std::endl;
      }
      return false;
    }
Beispiel #10
0
/// Classify the given Clang enumeration to describe how to import it.
void EnumInfo::classifyEnum(const clang::EnumDecl *decl,
                            clang::Preprocessor &pp) {
  // Anonymous enumerations simply get mapped to constants of the
  // underlying type of the enum, because there is no way to conjure up a
  // name for the Swift type.
  if (!decl->hasNameForLinkage()) {
    kind = EnumKind::Constants;
    return;
  }

  // First, check for attributes that denote the classification
  if (auto domainAttr = decl->getAttr<clang::NSErrorDomainAttr>()) {
    kind = EnumKind::Enum;
    attribute = domainAttr;
    return;
  }

  // Was the enum declared using *_ENUM or *_OPTIONS?
  // FIXME: Use Clang attributes instead of grovelling the macro expansion loc.
  auto loc = decl->getLocStart();
  if (loc.isMacroID()) {
    StringRef MacroName = pp.getImmediateMacroName(loc);
    if (MacroName == "CF_ENUM" || MacroName == "__CF_NAMED_ENUM" ||
        MacroName == "OBJC_ENUM" || MacroName == "SWIFT_ENUM" ||
        MacroName == "SWIFT_ENUM_NAMED") {
      kind = EnumKind::Enum;
      return;
    }
    if (MacroName == "CF_OPTIONS" || MacroName == "OBJC_OPTIONS" ||
        MacroName == "SWIFT_OPTIONS") {
      kind = EnumKind::Options;
      return;
    }
  }

  // Hardcode a particular annoying case in the OS X headers.
  if (decl->getName() == "DYLD_BOOL") {
    kind = EnumKind::Enum;
    return;
  }

  // Fall back to the 'Unknown' path.
  kind = EnumKind::Unknown;
}
Beispiel #11
0
 void ClangInternalState::printMacroDefinitions(llvm::raw_ostream& Out,
                                               const clang::Preprocessor& PP) {
   stdstrstream contentsOS;
   PP.printMacros(contentsOS);
   Out << "Ordered Alphabetically:\n";
   std::vector<std::string> elems;
   {
     // Split the string into lines.
     char delim = '\n';
     std::stringstream ss(contentsOS.str());
     std::string item;
     while (std::getline(ss, item, delim)) {
       elems.push_back(item);
     }
     // Sort them alphabetically
     std::sort(elems.begin(), elems.end());
   }
   for(std::vector<std::string>::iterator I = elems.begin(),
         E = elems.end(); I != E; ++I)
     Out << *I << '\n';
   Out.flush();
 }
void PragmaRecorder::HandlePragma(clang::Preprocessor &PP,
                                  clang::PragmaIntroducerKind Introducer,
                                  clang::Token &FirstToken) {
    clang::Token &CurrentToken = FirstToken;
    std::string PragmaName, PragmaValue = "";
    // Pragma in ACC should be a name/value pair

    if (GetPragmaNameFromToken(FirstToken, PragmaName)) {
        // start parsing the value '(' PragmaValue ')'
        const clang::Token* NextToken = &PP.LookAhead(0);

        if (NextToken->is(clang::tok::l_paren))
            PP.LexUnexpandedToken(CurrentToken);
        else
            goto end_parsing_pragma_value;

        NextToken = &PP.LookAhead(0);
        if (GetPragmaValueFromToken(*NextToken, PragmaValue))
            PP.Lex(CurrentToken);
        else
            goto end_parsing_pragma_value;

        if (!NextToken->is(clang::tok::r_paren)) {
            NextToken = &PP.LookAhead(0);
            if (NextToken->is(clang::tok::r_paren))
                PP.LexUnexpandedToken(CurrentToken);
            else
                goto end_parsing_pragma_value;
        }

        // Until now, we ensure that we have a pragma name/value pair
        mPragmas->push_back(make_pair(PragmaName, PragmaValue));
    }

end_parsing_pragma_value:
    // Inform lex to eat the token
    PP.LexUnexpandedToken(CurrentToken);

    return;
}
    void InsertIntoAutoloadingState (Decl* decl, std::string annotation) {

      assert(annotation != "" && "Empty annotation!");
      assert(m_PP);

      const FileEntry* FE = 0;
      SourceLocation fileNameLoc;
      bool isAngled = false;
      const DirectoryLookup* LookupFrom = 0;
      const DirectoryLookup* CurDir = 0;

      FE = m_PP->LookupFile(fileNameLoc, annotation, isAngled, LookupFrom,
                            CurDir, /*SearchPath*/0, /*RelativePath*/ 0,
                            /*suggestedModule*/0, /*SkipCache*/false,
                            /*OpenFile*/ false, /*CacheFail*/ false);

      assert(FE && "Must have a valid FileEntry");

      if (m_Map->find(FE) == m_Map->end())
        (*m_Map)[FE] = std::vector<Decl*>();

      (*m_Map)[FE].push_back(decl);
    }
Beispiel #14
0
static std::pair<clang::StringLiteral*, clang::StringLiteral *> ExtractLiterals(clang::ParenExpr *PE,
                                                                                const clang::Preprocessor &PP,
                                                                                const char *Keyword,
                                                                                const char (&Error)[N]) {
    clang::BinaryOperator* BO = llvm::dyn_cast<clang::BinaryOperator>(PE->getSubExpr());
    clang::StringLiteral *Val1 = nullptr, *Val2 = nullptr;
    if (!BO) {
        PP.getDiagnostics().Report(PE->getExprLoc(),
                                   PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                    "Invalid %0 annotation")) << Keyword;
    } else {
        if (!(Val1 = llvm::dyn_cast<clang::StringLiteral>(BO->getLHS())))
            PP.getDiagnostics().Report(BO->getLHS()->getExprLoc(),
                    PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, Error));
            if (!(Val2 = llvm::dyn_cast<clang::StringLiteral>(BO->getRHS())))
                PP.getDiagnostics().Report(BO->getRHS()->getExprLoc(),
                    PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, Error));
    }
    return {Val1, Val2};
}
Beispiel #15
0
static clang::SourceLocation GetFromLiteral(clang::Token Tok, clang::StringLiteral *Lit, clang::Preprocessor &PP) {
    return Lit->getLocationOfByte(PP.getSourceManager().getFileOffset(Tok.getLocation()),
                           PP.getSourceManager(), PP.getLangOpts(), PP.getTargetInfo());
}
void PragmaRecorder::HandlePragma(clang::Preprocessor &PP,
                                  clang::PragmaIntroducerKind Introducer,
                                  clang::Token &FirstToken) {
  clang::Token &CurrentToken = FirstToken;
  std::string PragmaName, PragmaValue = "";
  // Pragma in ACC should be a name/value pair

  if (GetPragmaNameFromToken(FirstToken, PragmaName)) {
    // start parsing the value '(' PragmaValue ')', if we have one.
    const clang::Token* NextToken = &PP.LookAhead(0);

    if (NextToken->is(clang::tok::l_paren))
      PP.LexUnexpandedToken(CurrentToken);
    else
      goto end_parsing_pragma_value;

    NextToken = &PP.LookAhead(0);
    if (GetPragmaValueFromToken(*NextToken, PragmaValue)) {
      PP.Lex(CurrentToken);
    } else {
      PP.LexUnexpandedToken(CurrentToken);
      PP.Diag(NextToken->getLocation(),
              PP.getDiagnostics().getCustomDiagID(
                  clang::DiagnosticsEngine::Error,
                  "expected value after '#pragma %0('")) << PragmaName;
      return;
    }

    if (!NextToken->is(clang::tok::r_paren)) {
      NextToken = &PP.LookAhead(0);
      if (NextToken->is(clang::tok::r_paren)) {
        PP.LexUnexpandedToken(CurrentToken);
      } else {
        PP.LexUnexpandedToken(CurrentToken);
        PP.Diag(NextToken->getLocation(),
                PP.getDiagnostics().getCustomDiagID(
                    clang::DiagnosticsEngine::Error,
                    "missing ')' after '#pragma %0(%1'"))
            << PragmaName << PragmaValue;
        return;
      }
    }
  } else {
    PP.Diag(FirstToken.getLocation(),
            PP.getDiagnostics().getCustomDiagID(
                clang::DiagnosticsEngine::Error,
                "no pragma name or value"));
    return;
  }

 end_parsing_pragma_value:

  // PragmaValue may be an empty string.
  mPragmas->push_back(make_pair(PragmaName, PragmaValue));

  // Inform lex to eat the token
  PP.LexUnexpandedToken(CurrentToken);

  return;
}
Beispiel #17
0
    void InsertIntoAutoloadingState(Decl* decl, Annotations_t FileNames) {

      assert(m_PP);

      auto addFile = [this,decl](llvm::StringRef FileName, bool warn) {
        if (FileName.empty()) return (const FileEntry*)nullptr;

        const FileEntry* FE = 0;
        SourceLocation fileNameLoc;
        // Remember this file wth full path, not "./File.h" (ROOT-8863).
        bool isAngled = true;
        const DirectoryLookup* FromDir = 0;
        const FileEntry* FromFile = 0;
        const DirectoryLookup* CurDir = 0;
        bool needCacheUpdate = false;

        if (FileName.equals(m_PrevFileName.first))
          FE = m_PrevFE.first;
        else if (FileName.equals(m_PrevFileName.second))
          FE = m_PrevFE.second;
        else {
          FE = m_PP->LookupFile(fileNameLoc, FileName, isAngled,
                                FromDir, FromFile, CurDir, /*SearchPath*/0,
                                /*RelativePath*/ 0, /*suggestedModule*/0,
                                /*IsMapped*/0, /*SkipCache*/ false,
                                /*OpenFile*/ false, /*CacheFail*/ true);
          needCacheUpdate = true;
        }

        if (FE) {
          auto& Vec = (*m_Map)[FE];
          Vec.push_back(decl);
          if (needCacheUpdate) return FE;
          else return (const FileEntry*)nullptr;
        } else if (warn) {
          // If the top level header is expected to be findable at run-time,
          // the direct header might not because the include path might be
          // different enough and only the top-header is guaranteed to be seen
          // by the user as an interface header to be available on the
          // run-time include path.
          cling::errs()
          << "Error in cling::AutoloadingVisitor::InsertIntoAutoloadingState:\n"
          "   Missing FileEntry for " << FileName << "\n";
          if (NamedDecl* ND = dyn_cast<NamedDecl>(decl)) {
            cling::errs() << "   requested to autoload type ";
            ND->getNameForDiagnostic(cling::errs(),
                                     ND->getASTContext().getPrintingPolicy(),
                                     true /*qualified*/);
            cling::errs() << "\n";
          }
          return (const FileEntry*)nullptr;
        } else {
          // Case of the direct header that is not a top level header, no
          // warning in this case (to likely to be a false positive).
          return (const FileEntry*)nullptr;
        }
      };

      const FileEntry* cacheUpdate;

      if ( (cacheUpdate = addFile(FileNames.first,true)) ) {
        m_PrevFE.first = cacheUpdate;
        m_PrevFileName.first = FileNames.first;
      }
      if ( (cacheUpdate = addFile(FileNames.second,false)) ) {
        m_PrevFE.second = cacheUpdate;
        m_PrevFileName.second = FileNames.second;
      }


    }
Beispiel #18
0
 void ClangInternalState::printMacroDefinitions(llvm::raw_ostream& Out,
                           clang::Preprocessor& PP) {
   PP.printMacros(Out);
 }
Beispiel #19
0
void ParserProxy::EnterTokenStream(clang::Preprocessor& PP) {
    PP.EnterTokenStream(&(CurrentToken()), 1, true, false);
}
Beispiel #20
0
/// Classify the given Clang enumeration to describe how to import it.
void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl,
                            clang::Preprocessor &pp) {
  assert(decl);
  clang::PrettyStackTraceDecl trace(decl, clang::SourceLocation(),
                                    pp.getSourceManager(), "classifying");
  assert(decl->isThisDeclarationADefinition());

  // Anonymous enumerations simply get mapped to constants of the
  // underlying type of the enum, because there is no way to conjure up a
  // name for the Swift type.
  if (!decl->hasNameForLinkage()) {
    kind = EnumKind::Constants;
    return;
  }

  // First, check for attributes that denote the classification
  if (auto domainAttr = decl->getAttr<clang::NSErrorDomainAttr>()) {
    kind = EnumKind::Enum;
    nsErrorDomain = ctx.AllocateCopy(domainAttr->getErrorDomain()->getName());
    return;
  }
  if (decl->hasAttr<clang::FlagEnumAttr>()) {
    kind = EnumKind::Options;
    return;
  }
  if (decl->hasAttr<clang::EnumExtensibilityAttr>()) {
    // FIXME: Distinguish between open and closed enums.
    kind = EnumKind::Enum;
    return;
  }

  // If API notes have /removed/ a FlagEnum or EnumExtensibility attribute,
  // then we don't need to check the macros.
  for (auto *attr : decl->specific_attrs<clang::SwiftVersionedAttr>()) {
    if (!attr->getVersion().empty())
      continue;
    if (isa<clang::FlagEnumAttr>(attr->getAttrToAdd()) ||
        isa<clang::EnumExtensibilityAttr>(attr->getAttrToAdd())) {
      kind = EnumKind::Unknown;
      return;
    }
  }

  // Was the enum declared using *_ENUM or *_OPTIONS?
  // FIXME: Stop using these once flag_enum and enum_extensibility
  // have been adopted everywhere, or at least relegate them to Swift 3 mode
  // only.
  auto loc = decl->getLocStart();
  if (loc.isMacroID()) {
    StringRef MacroName = pp.getImmediateMacroName(loc);
    if (MacroName == "CF_ENUM" || MacroName == "__CF_NAMED_ENUM" ||
        MacroName == "OBJC_ENUM" || MacroName == "SWIFT_ENUM" ||
        MacroName == "SWIFT_ENUM_NAMED") {
      kind = EnumKind::Enum;
      return;
    }
    if (MacroName == "CF_OPTIONS" || MacroName == "OBJC_OPTIONS" ||
        MacroName == "SWIFT_OPTIONS") {
      kind = EnumKind::Options;
      return;
    }
  }

  // Hardcode a particular annoying case in the OS X headers.
  if (decl->getName() == "DYLD_BOOL") {
    kind = EnumKind::Enum;
    return;
  }

  // Fall back to the 'Unknown' path.
  kind = EnumKind::Unknown;
}