erichkeane created this revision. Record::getValueAsString returns a stringref to an interned string (apparently had been changed since most of tablegen was written). In this patch, I audited the usage of getValueAsString to find places where we can trivially stop storing 'std::string' and instead keep the stringref.
There was one instance where an unnecessary 'stringstream' was being used, so that has been removed as well to unblock the stringref replacing string fix. https://reviews.llvm.org/D38979 Files: utils/TableGen/ClangAttrEmitter.cpp
Index: utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -1440,7 +1440,7 @@ assert(!SpellingList.empty() && "Attribute with empty spelling list can't have accessors!"); for (const auto *Accessor : Accessors) { - std::string Name = Accessor->getValueAsString("Name"); + const StringRef Name = Accessor->getValueAsString("Name"); std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(*Accessor); OS << " bool " << Name << "() const { return SpellingListIndex == "; @@ -1589,7 +1589,7 @@ // Abstract rules are used only for sub-rules bool isAbstractRule() const { return getSubjects().empty(); } - std::string getName() const { + StringRef getName() const { return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name"); } @@ -1821,13 +1821,11 @@ // Generate a function that constructs a set of matching rules that describe // to which declarations the attribute should apply to. std::string FnName = "matchRulesFor" + Attr.getName().str(); - std::stringstream SS; - SS << "static void " << FnName << "(llvm::SmallVectorImpl<std::pair<" + OS << "static void " << FnName << "(llvm::SmallVectorImpl<std::pair<" << AttributeSubjectMatchRule::EnumName << ", bool>> &MatchRules, const LangOptions &LangOpts) {\n"; if (Attr.isValueUnset("Subjects")) { - SS << "}\n\n"; - OS << SS.str(); + OS << "}\n\n"; return FnName; } const Record *SubjectObj = Attr.getValueAsDef("Subjects"); @@ -1840,24 +1838,23 @@ // The rule might be language specific, so only subtract it from the given // rules if the specific language options are specified. std::vector<Record *> LangOpts = Rule.getLangOpts(); - SS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() + OS << " MatchRules.push_back(std::make_pair(" << Rule.getEnumValue() << ", /*IsSupported=*/"; if (!LangOpts.empty()) { for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { - std::string Part = (*I)->getValueAsString("Name"); + const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) - SS << "!"; - SS << "LangOpts." + Part; + OS << "!"; + OS << "LangOpts." << Part; if (I + 1 != E) - SS << " || "; + OS << " || "; } } else - SS << "true"; - SS << "));\n"; + OS << "true"; + OS << "));\n"; } } - SS << "}\n\n"; - OS << SS.str(); + OS << "}\n\n"; return FnName; } @@ -1913,7 +1910,8 @@ continue; std::string SubRuleFunction; if (SubMatchRules.count(Rule.MetaSubject)) - SubRuleFunction = "isAttributeSubjectMatchSubRuleFor_" + Rule.getName(); + SubRuleFunction = + ("isAttributeSubjectMatchSubRuleFor_" + Rule.getName()).str(); else SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor"; OS << " Case(\"" << Rule.getName() << "\", std::make_pair(" @@ -3030,7 +3028,7 @@ static std::string CalculateDiagnostic(const Record &S) { // If the SubjectList object has a custom diagnostic associated with it, // return that directly. - std::string CustomDiag = S.getValueAsString("CustomDiag"); + const StringRef CustomDiag = S.getValueAsString("CustomDiag"); if (!CustomDiag.empty()) return CustomDiag; @@ -3314,12 +3312,13 @@ // codegen efficiency). std::string FnName = "check", Test; for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) { - std::string Part = (*I)->getValueAsString("Name"); + const StringRef Part = (*I)->getValueAsString("Name"); if ((*I)->getValueAsBit("Negated")) { FnName += "Not"; Test += "!"; } - Test += "S.LangOpts." + Part; + Test += "S.LangOpts."; + Test += Part; if (I + 1 != E) Test += " || "; FnName += Part; @@ -3375,7 +3374,7 @@ // applies to multiple target architectures. In order for the attribute to be // considered valid, all of its architectures need to be included. if (!Attr.isValueUnset("ParseKind")) { - std::string APK = Attr.getValueAsString("ParseKind"); + const StringRef APK = Attr.getValueAsString("ParseKind"); for (const auto &I : Dupes) { if (I.first == APK) { std::vector<StringRef> DA = @@ -3675,13 +3674,13 @@ static void WriteCategoryHeader(const Record *DocCategory, raw_ostream &OS) { - const std::string &Name = DocCategory->getValueAsString("Name"); - OS << Name << "\n" << std::string(Name.length(), '=') << "\n"; + const StringRef Name = DocCategory->getValueAsString("Name"); + OS << Name << "\n" << std::string(Name.size(), '=') << "\n"; // If there is content, print that as well. - std::string ContentStr = DocCategory->getValueAsString("Content"); + const StringRef ContentStr = DocCategory->getValueAsString("Content"); // Trim leading and trailing newlines and spaces. - OS << StringRef(ContentStr).trim(); + OS << ContentStr.trim(); OS << "\n\n"; } @@ -3809,16 +3808,16 @@ OS << "This attribute has been deprecated, and may be removed in a future " << "version of Clang."; const Record &Deprecated = *Doc.Documentation->getValueAsDef("Deprecated"); - std::string Replacement = Deprecated.getValueAsString("Replacement"); + const StringRef Replacement = Deprecated.getValueAsString("Replacement"); if (!Replacement.empty()) OS << " This attribute has been superseded by ``" << Replacement << "``."; OS << "\n\n"; } - std::string ContentStr = Doc.Documentation->getValueAsString("Content"); + const StringRef ContentStr = Doc.Documentation->getValueAsString("Content"); // Trim leading and trailing newlines and spaces. - OS << StringRef(ContentStr).trim(); + OS << ContentStr.trim(); OS << "\n\n\n"; } @@ -3847,7 +3846,7 @@ // If the category is "undocumented", then there cannot be any other // documentation categories (otherwise, the attribute would become // documented). - std::string Cat = Category->getValueAsString("Name"); + const StringRef Cat = Category->getValueAsString("Name"); bool Undocumented = Cat == "Undocumented"; if (Undocumented && Docs.size() > 1) PrintFatalError(Doc.getLoc(),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits