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 }
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)"); }
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; }
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; }
/// 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; }
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()); }