[PATCH] D39665: Support __has_c_attribute
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 5 13:57:10 PST 2017
aaron.ballman created this revision.
We have the __has_cpp_attribute builtin macro to determine when an attribute is supported with C++ [[]] syntax, and this patch adds the analogous __has_c_attribute builtin macro so that users can test whether a given [[]] attribute is available in C when -fdouble-square-bracket-attributes is specified.
https://reviews.llvm.org/D39665
Files:
clang/include/clang/Lex/Preprocessor.h
clang/lib/Lex/PPMacroExpansion.cpp
clang/test/Preprocessor/has_c_attribute.c
Index: clang/test/Preprocessor/has_c_attribute.c
===================================================================
--- clang/test/Preprocessor/has_c_attribute.c
+++ clang/test/Preprocessor/has_c_attribute.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fdouble-square-bracket-attributes -std=c11 -E %s -o - | FileCheck %s
+
+// CHECK: has_fallthrough
+#if __has_c_attribute(fallthrough)
+ int has_fallthrough();
+#endif
+
+// CHECK: does_not_have_selectany
+#if !__has_c_attribute(selectany)
+ int does_not_have_selectany();
+#endif
+
Index: clang/lib/Lex/PPMacroExpansion.cpp
===================================================================
--- clang/lib/Lex/PPMacroExpansion.cpp
+++ clang/lib/Lex/PPMacroExpansion.cpp
@@ -369,6 +369,7 @@
Ident__has_extension = RegisterBuiltinMacro(*this, "__has_extension");
Ident__has_builtin = RegisterBuiltinMacro(*this, "__has_builtin");
Ident__has_attribute = RegisterBuiltinMacro(*this, "__has_attribute");
+ Ident__has_c_attribute = RegisterBuiltinMacro(*this, "__has_c_attribute");
Ident__has_declspec = RegisterBuiltinMacro(*this, "__has_declspec_attribute");
Ident__has_include = RegisterBuiltinMacro(*this, "__has_include");
Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next");
@@ -1775,30 +1776,34 @@
return II ? hasAttribute(AttrSyntax::Declspec, nullptr, II,
getTargetInfo(), getLangOpts()) : 0;
});
- } else if (II == Ident__has_cpp_attribute) {
- EvaluateFeatureLikeBuiltinMacro(OS, Tok, II, *this,
- [this](Token &Tok, bool &HasLexedNextToken) -> int {
- IdentifierInfo *ScopeII = nullptr;
- IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this,
- diag::err_feature_check_malformed);
- if (!II)
- return false;
+ } else if (II == Ident__has_cpp_attribute ||
+ II == Ident__has_c_attribute) {
+ bool IsCXX = II == Ident__has_cpp_attribute;
+ EvaluateFeatureLikeBuiltinMacro(
+ OS, Tok, II, *this, [&](Token &Tok, bool &HasLexedNextToken) -> int {
+ IdentifierInfo *ScopeII = nullptr;
+ IdentifierInfo *II = ExpectFeatureIdentifierInfo(
+ Tok, *this, diag::err_feature_check_malformed);
+ if (!II)
+ return false;
- // It is possible to receive a scope token. Read the "::", if it is
- // available, and the subsequent identifier.
- LexUnexpandedToken(Tok);
- if (Tok.isNot(tok::coloncolon))
- HasLexedNextToken = true;
- else {
- ScopeII = II;
+ // It is possible to receive a scope token. Read the "::", if it is
+ // available, and the subsequent identifier.
LexUnexpandedToken(Tok);
- II = ExpectFeatureIdentifierInfo(Tok, *this,
- diag::err_feature_check_malformed);
- }
+ if (Tok.isNot(tok::coloncolon))
+ HasLexedNextToken = true;
+ else {
+ ScopeII = II;
+ LexUnexpandedToken(Tok);
+ II = ExpectFeatureIdentifierInfo(Tok, *this,
+ diag::err_feature_check_malformed);
+ }
- return II ? hasAttribute(AttrSyntax::CXX, ScopeII, II,
- getTargetInfo(), getLangOpts()) : 0;
- });
+ AttrSyntax Syntax = IsCXX ? AttrSyntax::CXX : AttrSyntax::C;
+ return II ? hasAttribute(Syntax, ScopeII, II, getTargetInfo(),
+ getLangOpts())
+ : 0;
+ });
} else if (II == Ident__has_include ||
II == Ident__has_include_next) {
// The argument to these two builtins should be a parenthesized
Index: clang/include/clang/Lex/Preprocessor.h
===================================================================
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -144,6 +144,7 @@
IdentifierInfo *Ident__building_module; // __building_module
IdentifierInfo *Ident__MODULE__; // __MODULE__
IdentifierInfo *Ident__has_cpp_attribute; // __has_cpp_attribute
+ IdentifierInfo *Ident__has_c_attribute; // __has_c_attribute
IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
SourceLocation DATELoc, TIMELoc;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39665.121662.patch
Type: text/x-patch
Size: 4511 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171105/e7eccd7b/attachment-0001.bin>
More information about the cfe-commits
mailing list