let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [TargetDocs];
let AdditionalMembers = [{
- StringRef CPU;
- std::vector<std::string> Features;
- bool Parsed = false;
- StringRef getCPU() {
- if (!Parsed)
- parse();
- return CPU;
- }
- std::vector<std::string> &getFeatures() {
- if (!Parsed)
- parse();
- return Features;
- }
- void parse() {
+ typedef std::pair<std::vector<std::string>, StringRef> ParsedTargetAttr;
+ ParsedTargetAttr parse() const {
+ ParsedTargetAttr Ret;
SmallVector<StringRef, 1> AttrFeatures;
getFeaturesStr().split(AttrFeatures, ",");
// While we're here iterating check for a different target cpu.
if (Feature.startswith("arch="))
- CPU = Feature.split("=").second.trim();
+ Ret.second = Feature.split("=").second.trim();
else if (Feature.startswith("no-"))
- Features.push_back("-" + Feature.split("-").second.str());
+ Ret.first.push_back("-" + Feature.split("-").second.str());
else
- Features.push_back("+" + Feature.str());
+ Ret.first.push_back("+" + Feature.str());
}
- Parsed = true;
+ return Ret;
}
}];
}
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
if (FD && FD->hasAttr<TargetAttr>()) {
llvm::StringMap<bool> FeatureMap;
- auto *TD = FD->getAttr<TargetAttr>();
+ const auto *TD = FD->getAttr<TargetAttr>();
+ TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse();
- // Make a copy of the features as passed on the command line.
- std::vector<std::string> FnFeatures =
- getTarget().getTargetOpts().FeaturesAsWritten;
+ // Make a copy of the features as passed on the command line into the
+ // beginning of the additional features from the function to override.
+ ParsedAttr.first.insert(
+ ParsedAttr.first.begin(),
+ getTarget().getTargetOpts().FeaturesAsWritten.begin(),
+ getTarget().getTargetOpts().FeaturesAsWritten.end());
- std::vector<std::string> &AttrFeatures = TD->getFeatures();
- std::copy(AttrFeatures.begin(), AttrFeatures.end(),
- std::back_inserter(FnFeatures));
-
- if (TD->getCPU() != "")
- TargetCPU = TD->getCPU();
+ if (ParsedAttr.second != "")
+ TargetCPU = ParsedAttr.second;
// Now populate the feature map, first with the TargetCPU which is either
// the default or a new one from the target attribute string. Then we'll
// use the passed in features (FeaturesAsWritten) along with the new ones
// from the attribute.
- getTarget().initFeatureMap(FeatureMap, Diags, TargetCPU, FnFeatures);
+ getTarget().initFeatureMap(FeatureMap, Diags, TargetCPU, ParsedAttr.first);
// Produce the canonical string for this set of features.
std::vector<std::string> Features;