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
}
示例#2
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;
		}
// 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)");
}
示例#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;
}
示例#5
0
    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;
    }
示例#6
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;
}
示例#7
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());
}