diff options
Diffstat (limited to 'lib/Transforms/Utils/SpecialCaseList.cpp')
-rw-r--r-- | lib/Transforms/Utils/SpecialCaseList.cpp | 97 |
1 files changed, 47 insertions, 50 deletions
diff --git a/lib/Transforms/Utils/SpecialCaseList.cpp b/lib/Transforms/Utils/SpecialCaseList.cpp index b98cb5b..2ef692c 100644 --- a/lib/Transforms/Utils/SpecialCaseList.cpp +++ b/lib/Transforms/Utils/SpecialCaseList.cpp @@ -49,29 +49,45 @@ struct SpecialCaseList::Entry { } }; -SpecialCaseList::SpecialCaseList(const StringRef Path) { - // Validate and open blacklist file. - if (Path.empty()) return; +SpecialCaseList::SpecialCaseList() : Entries() {} + +SpecialCaseList *SpecialCaseList::create( + const StringRef Path, std::string &Error) { + if (Path.empty()) + return new SpecialCaseList(); OwningPtr<MemoryBuffer> File; if (error_code EC = MemoryBuffer::getFile(Path, File)) { - report_fatal_error("Can't open blacklist file: " + Path + ": " + - EC.message()); + Error = (Twine("Can't open file '") + Path + "': " + EC.message()).str(); + return 0; } + return create(File.get(), Error); +} - init(File.get()); +SpecialCaseList *SpecialCaseList::create( + const MemoryBuffer *MB, std::string &Error) { + OwningPtr<SpecialCaseList> SCL(new SpecialCaseList()); + if (!SCL->parse(MB, Error)) + return 0; + return SCL.take(); } -SpecialCaseList::SpecialCaseList(const MemoryBuffer *MB) { - init(MB); +SpecialCaseList *SpecialCaseList::createOrDie(const StringRef Path) { + std::string Error; + if (SpecialCaseList *SCL = create(Path, Error)) + return SCL; + report_fatal_error(Error); } -void SpecialCaseList::init(const MemoryBuffer *MB) { +bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) { // Iterate through each line in the blacklist file. SmallVector<StringRef, 16> Lines; SplitString(MB->getBuffer(), Lines, "\n\r"); StringMap<StringMap<std::string> > Regexps; + assert(Entries.empty() && + "parse() should be called on an empty SpecialCaseList"); + int LineNo = 1; for (SmallVectorImpl<StringRef>::iterator I = Lines.begin(), E = Lines.end(); - I != E; ++I) { + I != E; ++I, ++LineNo) { // Ignore empty lines and lines starting with "#" if (I->empty() || I->startswith("#")) continue; @@ -80,7 +96,9 @@ void SpecialCaseList::init(const MemoryBuffer *MB) { StringRef Prefix = SplitLine.first; if (SplitLine.second.empty()) { // Missing ':' in the line. - report_fatal_error("malformed blacklist line: " + SplitLine.first); + Error = (Twine("Malformed line ") + Twine(LineNo) + ": '" + + SplitLine.first + "'").str(); + return false; } std::pair<StringRef, StringRef> SplitRegexp = SplitLine.second.split("="); @@ -113,10 +131,11 @@ void SpecialCaseList::init(const MemoryBuffer *MB) { // Check that the regexp is valid. Regex CheckRE(Regexp); - std::string Error; - if (!CheckRE.isValid(Error)) { - report_fatal_error("malformed blacklist regex: " + SplitLine.second + - ": " + Error); + std::string REError; + if (!CheckRE.isValid(REError)) { + Error = (Twine("Malformed regex in line ") + Twine(LineNo) + ": '" + + SplitLine.second + "': " + REError).str(); + return false; } // Add this regexp into the proper group by its prefix. @@ -135,6 +154,7 @@ void SpecialCaseList::init(const MemoryBuffer *MB) { Entries[I->getKey()][II->getKey()].RegEx = new Regex(II->getValue()); } } + return true; } SpecialCaseList::~SpecialCaseList() { @@ -149,18 +169,12 @@ SpecialCaseList::~SpecialCaseList() { } } -bool SpecialCaseList::findCategory(const Function &F, - StringRef &Category) const { - return findCategory(*F.getParent(), Category) || - findCategory("fun", F.getName(), Category); -} - bool SpecialCaseList::isIn(const Function& F, const StringRef Category) const { return isIn(*F.getParent(), Category) || inSectionCategory("fun", F.getName(), Category); } -static StringRef GetGVTypeString(const GlobalVariable &G) { +static StringRef GetGlobalTypeString(const GlobalValue &G) { // Types of GlobalVariables are always pointer types. Type *GType = G.getType()->getElementType(); // For now we support blacklisting struct types only. @@ -171,46 +185,29 @@ static StringRef GetGVTypeString(const GlobalVariable &G) { return "<unknown type>"; } -bool SpecialCaseList::findCategory(const GlobalVariable &G, - StringRef &Category) const { - return findCategory(*G.getParent(), Category) || - findCategory("global", G.getName(), Category) || - findCategory("type", GetGVTypeString(G), Category); -} - bool SpecialCaseList::isIn(const GlobalVariable &G, const StringRef Category) const { return isIn(*G.getParent(), Category) || inSectionCategory("global", G.getName(), Category) || - inSectionCategory("type", GetGVTypeString(G), Category); + inSectionCategory("type", GetGlobalTypeString(G), Category); } -bool SpecialCaseList::findCategory(const Module &M, StringRef &Category) const { - return findCategory("src", M.getModuleIdentifier(), Category); +bool SpecialCaseList::isIn(const GlobalAlias &GA, + const StringRef Category) const { + if (isIn(*GA.getParent(), Category)) + return true; + + if (isa<FunctionType>(GA.getType()->getElementType())) + return inSectionCategory("fun", GA.getName(), Category); + + return inSectionCategory("global", GA.getName(), Category) || + inSectionCategory("type", GetGlobalTypeString(GA), Category); } bool SpecialCaseList::isIn(const Module &M, const StringRef Category) const { return inSectionCategory("src", M.getModuleIdentifier(), Category); } -bool SpecialCaseList::findCategory(const StringRef Section, - const StringRef Query, - StringRef &Category) const { - StringMap<StringMap<Entry> >::const_iterator I = Entries.find(Section); - if (I == Entries.end()) return false; - - for (StringMap<Entry>::const_iterator II = I->second.begin(), - IE = I->second.end(); - II != IE; ++II) { - if (II->getValue().match(Query)) { - Category = II->first(); - return true; - } - } - - return false; -} - bool SpecialCaseList::inSectionCategory(const StringRef Section, const StringRef Query, const StringRef Category) const { |