Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -4922,13 +4922,6 @@ class Sema final : public SemaBase {
// handled later in the process, once we know how many exist.
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);

/// Check Target Version attrs
bool checkTargetVersionAttr(SourceLocation Loc, Decl *D, StringRef Str);
bool checkTargetClonesAttrString(
SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal,
Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault,
SmallVectorImpl<SmallString<64>> &StringsBuffer);

ErrorAttr *mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
StringRef NewUserDiagnostic);
FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Sema/SemaARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ class SemaARM : public SemaBase {
/// Return true if the given vector types are lax-compatible SVE vector types,
/// false otherwise.
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType);

bool checkTargetVersionAttr(StringRef Str, SourceLocation Loc);
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Strs,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &Buffer);
};

SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Sema/SemaRISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class SemaRISCV : public SemaBase {
bool DeclareAndesVectorBuiltins = false;

std::unique_ptr<sema::RISCVIntrinsicManager> IntrinsicManager;

bool checkTargetVersionAttr(StringRef Str, SourceLocation Loc);
bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Strs,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &Buffer);
};

std::unique_ptr<sema::RISCVIntrinsicManager>
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Sema/SemaX86.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ class SemaX86 : public SemaBase {

void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL);
void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL);

bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Strs,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &Buffer);
};
} // namespace clang

Expand Down
87 changes: 87 additions & 0 deletions clang/lib/Sema/SemaARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1535,4 +1535,91 @@ bool SemaARM::areLaxCompatibleSveTypes(QualType FirstType,
IsLaxCompatible(SecondType, FirstType);
}

enum FirstParam { Unsupported, Duplicate, Unknown };
enum SecondParam { None, CPU, Tune };
enum ThirdParam { Target, TargetClones, TargetVersion };

bool SemaARM::checkTargetVersionAttr(StringRef Str, SourceLocation Loc) {
llvm::SmallVector<StringRef, 8> Features;
Str.split(Features, '+');
for (StringRef Feat : Features) {
Feat = Feat.trim();
if (Feat == "default")
continue;
if (!getASTContext().getTargetInfo().validateCpuSupports(Feat))
return Diag(Loc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << Feat << TargetVersion;
}
return false;
}

bool SemaARM::checkTargetClonesAttr(SmallVectorImpl<StringRef> &Strs,
SmallVectorImpl<SourceLocation> &Locs,
SmallVectorImpl<SmallString<64>> &Buffer) {
if (!getASTContext().getTargetInfo().hasFeature("fmv"))
return true;

assert(Strs.size() == Locs.size() &&
"Mismatch between number of strings and locations");

bool HasDefault = false;
bool HasNonDefault = false;
for (unsigned I = 0; I < Strs.size(); ++I) {
StringRef Str = Strs[I].trim();
SourceLocation Loc = Locs[I];

if (Str.empty())
return Diag(Loc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << "" << TargetClones;

if (Str == "default") {
if (HasDefault)
Diag(Loc, diag::warn_target_clone_duplicate_options);
else {
Buffer.push_back(Str);
HasDefault = true;
}
continue;
}

bool HasCodeGenImpact = false;
llvm::SmallVector<StringRef, 8> Features;
llvm::SmallVector<StringRef, 8> ValidFeatures;
Str.split(Features, '+');
for (StringRef Feat : Features) {
Feat = Feat.trim();
if (!getASTContext().getTargetInfo().validateCpuSupports(Feat)) {
Diag(Loc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << Feat << TargetClones;
continue;
}
if (getASTContext().getTargetInfo().doesFeatureAffectCodeGen(Feat))
HasCodeGenImpact = true;
ValidFeatures.push_back(Feat);
}
// Canonize TargetClones Attributes
SmallString<64> NewStr;
llvm::sort(ValidFeatures);
for (StringRef Feat : ValidFeatures) {
if (!NewStr.empty())
NewStr.append("+");
NewStr.append(Feat);
}
if (llvm::is_contained(Buffer, NewStr))
Diag(Loc, diag::warn_target_clone_duplicate_options);
else if (!HasCodeGenImpact)
// Ignore features in target_clone attribute that don't impact
// code generation
Diag(Loc, diag::warn_target_clone_no_impact_options);
else if (!NewStr.empty()) {
Buffer.push_back(NewStr);
HasNonDefault = true;
}
}
if (!HasNonDefault)
return true;

return false;
}

} // namespace clang
Loading
Loading