[clang] Add no_builtin attribute
Summary:
This is a follow up on https://reviews.llvm.org/D61634
This patch is simpler and only adds the no_builtin attribute.
Reviewers: tejohnson, courbet, theraven, t.p.northover, jdoerfert
Subscribers: mgrang, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D68028
This is a re-submit after it got reverted in https://reviews.llvm.org/rGbd8791610948 since the breakage doesn't seem to come from this patch.
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index abbd597..99eb23c 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1069,6 +1069,56 @@
S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
}
+static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+ static constexpr const StringRef kWildcard = "*";
+
+ llvm::SmallVector<StringRef, 16> Names;
+ bool HasWildcard = false;
+
+ const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
+ if (Name == kWildcard)
+ HasWildcard = true;
+ Names.push_back(Name);
+ };
+
+ // Add previously defined attributes.
+ if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
+ for (StringRef BuiltinName : NBA->builtinNames())
+ AddBuiltinName(BuiltinName);
+
+ // Add current attributes.
+ if (AL.getNumArgs() == 0)
+ AddBuiltinName(kWildcard);
+ else
+ for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
+ StringRef BuiltinName;
+ SourceLocation LiteralLoc;
+ if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
+ return;
+
+ if (Builtin::Context::isBuiltinFunc(BuiltinName.data()))
+ AddBuiltinName(BuiltinName);
+ else
+ S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
+ << BuiltinName << AL.getAttrName()->getName();
+ }
+
+ // Repeating the same attribute is fine.
+ llvm::sort(Names);
+ Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
+
+ // Empty no_builtin must be on its own.
+ if (HasWildcard && Names.size() > 1)
+ S.Diag(D->getLocation(),
+ diag::err_attribute_no_builtin_wildcard_or_builtin_name)
+ << AL.getAttrName()->getName();
+
+ if (D->hasAttr<NoBuiltinAttr>())
+ D->dropAttr<NoBuiltinAttr>();
+ D->addAttr(::new (S.Context)
+ NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
+}
+
static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (D->hasAttr<PassObjectSizeAttr>()) {
S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
@@ -6608,6 +6658,9 @@
case ParsedAttr::AT_DiagnoseIf:
handleDiagnoseIfAttr(S, D, AL);
break;
+ case ParsedAttr::AT_NoBuiltin:
+ handleNoBuiltinAttr(S, D, AL);
+ break;
case ParsedAttr::AT_ExtVectorType:
handleExtVectorTypeAttr(S, D, AL);
break;