diff options
author | Anders Carlsson <andersca@mac.com> | 2010-10-20 02:31:43 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-10-20 02:31:43 +0000 |
commit | 274a70ed7f4315c83273173fce4c3b0e097958d6 (patch) | |
tree | fccdd5042be19eff3d1c109477cdf047af8c70b8 | |
parent | 23c8341c3dfbb9b453cc3857eabc2405207887cf (diff) | |
download | bcm5719-llvm-274a70ed7f4315c83273173fce4c3b0e097958d6.tar.gz bcm5719-llvm-274a70ed7f4315c83273173fce4c3b0e097958d6.zip |
Add a __has_attribute macro that works much like __has_feature and __has_builtin.
llvm-svn: 116906
-rw-r--r-- | clang/clang.xcodeproj/project.pbxproj | 1 | ||||
-rw-r--r-- | clang/docs/LanguageExtensions.html | 24 | ||||
-rw-r--r-- | clang/include/clang/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/include/clang/Lex/CMakeLists.txt | 6 | ||||
-rw-r--r-- | clang/include/clang/Lex/Makefile | 13 | ||||
-rw-r--r-- | clang/include/clang/Lex/Preprocessor.h | 1 | ||||
-rw-r--r-- | clang/include/clang/Makefile | 2 | ||||
-rw-r--r-- | clang/lib/Lex/CMakeLists.txt | 2 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 16 | ||||
-rw-r--r-- | clang/test/Lexer/has_attribute.cpp | 12 |
10 files changed, 74 insertions, 4 deletions
diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 9c95d0a3dee..fa1e24574e8 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -2039,6 +2039,7 @@ isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; compatibilityVersion = "Xcode 2.4"; + developmentRegion = English; hasScannedForEncodings = 1; knownRegions = ( English, diff --git a/clang/docs/LanguageExtensions.html b/clang/docs/LanguageExtensions.html index 27d90c5cd3c..f27a5705398 100644 --- a/clang/docs/LanguageExtensions.html +++ b/clang/docs/LanguageExtensions.html @@ -136,6 +136,30 @@ can be used like this:</p> <p>The feature tag is described along with the language feature below.</p> <!-- ======================================================================= --> +<h3 id="__has_attribute">__has_attribute</h3> +<!-- ======================================================================= --> + +<p>This function-like macro takes a single identifier argument that is the name +of an attribute. It evaluates to 1 if the attribute is supported or 0 if not. It +can be used like this:</p> + +<blockquote> +<pre> +#ifndef __has_attribute // Optional of course. + #define __has_attribute(x) 0 // Compatibility with non-clang compilers. +#endif + +... +#if __has_attribute(override) || \ +#define OVERRIDE __attribute__((override)) +#else +#define OVERRIDE +#endif +... +</pre> +</blockquote> + +<!-- ======================================================================= --> <h2 id="has_include">Include File Checking Macros</h2> <!-- ======================================================================= --> diff --git a/clang/include/clang/CMakeLists.txt b/clang/include/clang/CMakeLists.txt index e82cf429eec..375ae5bdabc 100644 --- a/clang/include/clang/CMakeLists.txt +++ b/clang/include/clang/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(AST) add_subdirectory(Basic) add_subdirectory(Driver) +add_subdirectory(Lex) add_subdirectory(Serialization) diff --git a/clang/include/clang/Lex/CMakeLists.txt b/clang/include/clang/Lex/CMakeLists.txt new file mode 100644 index 00000000000..b823e83f906 --- /dev/null +++ b/clang/include/clang/Lex/CMakeLists.txt @@ -0,0 +1,6 @@ +set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td) +tablegen(AttrSpellings.inc + -gen-clang-attr-spelling-list + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../) +add_custom_target(ClangAttrSpellings + DEPENDS AttrSpellings.inc) diff --git a/clang/include/clang/Lex/Makefile b/clang/include/clang/Lex/Makefile new file mode 100644 index 00000000000..9874bcffb3e --- /dev/null +++ b/clang/include/clang/Lex/Makefile @@ -0,0 +1,13 @@ +CLANG_LEVEL := ../../.. +TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic +BUILT_SOURCES = AttrSpellings.inc + +TABLEGEN_INC_FILES_COMMON = 1 + +include $(CLANG_LEVEL)/Makefile + +$(ObjDir)/AttrSpellings.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \ + $(ObjDir)/.dir + $(Echo) "Building Clang attribute spellings with tblgen" + $(Verb) $(TableGen) -gen-clang-attr-spelling-list -o $(call SYSPATH, $@) \ + -I $(PROJ_SRC_DIR)/../../ $< diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 42e2daac2f2..1ee0fec1c52 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -83,6 +83,7 @@ class Preprocessor { IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__ IdentifierInfo *Ident__has_feature; // __has_feature IdentifierInfo *Ident__has_builtin; // __has_builtin + IdentifierInfo *Ident__has_attribute; // __has_attribute IdentifierInfo *Ident__has_include; // __has_include IdentifierInfo *Ident__has_include_next; // __has_include_next diff --git a/clang/include/clang/Makefile b/clang/include/clang/Makefile index 030b0720fd8..d6b9844285d 100644 --- a/clang/include/clang/Makefile +++ b/clang/include/clang/Makefile @@ -1,5 +1,5 @@ CLANG_LEVEL := ../.. -DIRS := AST Basic Driver Serialization +DIRS := AST Basic Driver Lex Serialization include $(CLANG_LEVEL)/Makefile diff --git a/clang/lib/Lex/CMakeLists.txt b/clang/lib/Lex/CMakeLists.txt index 0476384eff3..aa2c93af8ba 100644 --- a/clang/lib/Lex/CMakeLists.txt +++ b/clang/lib/Lex/CMakeLists.txt @@ -26,4 +26,4 @@ add_clang_library(clangLex TokenLexer.cpp ) -add_dependencies(clangLex ClangDiagnosticLex) +add_dependencies(clangLex ClangDiagnosticLex ClangAttrSpellings) diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 24a0f39b05d..19a6ca85211 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -70,6 +70,7 @@ void Preprocessor::RegisterBuiltinMacros() { // Clang Extensions. Ident__has_feature = RegisterBuiltinMacro(*this, "__has_feature"); Ident__has_builtin = RegisterBuiltinMacro(*this, "__has_builtin"); + Ident__has_attribute = RegisterBuiltinMacro(*this, "__has_attribute"); Ident__has_include = RegisterBuiltinMacro(*this, "__has_include"); Ident__has_include_next = RegisterBuiltinMacro(*this, "__has_include_next"); @@ -535,6 +536,14 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Default(false); } +/// HasAttribute - Return true if we recognize and implement the attribute +/// specified by the given identifier. +static bool HasAttribute(const IdentifierInfo *II) { + return llvm::StringSwitch<bool>(II->getName()) +#include "clang/Lex/AttrSpellings.inc" + .Default(false); +} + /// EvaluateHasIncludeCommon - Process a '__has_include("path")' /// or '__has_include_next("path")' expression. /// Returns true if successful. @@ -767,7 +776,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { OS << CounterValue++; Tok.setKind(tok::numeric_constant); } else if (II == Ident__has_feature || - II == Ident__has_builtin) { + II == Ident__has_builtin || + II == Ident__has_attribute) { // The argument to these two builtins should be a parenthesized identifier. SourceLocation StartLoc = Tok.getLocation(); @@ -795,7 +805,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { else if (II == Ident__has_builtin) { // Check for a builtin is trivial. Value = FeatureII->getBuiltinID() != 0; - } else { + } else if (II == Ident__has_attribute) + Value = HasAttribute(FeatureII); + else { assert(II == Ident__has_feature && "Must be feature check"); Value = HasFeature(*this, FeatureII); } diff --git a/clang/test/Lexer/has_attribute.cpp b/clang/test/Lexer/has_attribute.cpp new file mode 100644 index 00000000000..9a58a3013fb --- /dev/null +++ b/clang/test/Lexer/has_attribute.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -E %s -o - | FileCheck %s + +// CHECK: always_inline +#if __has_attribute(always_inline) +int always_inline(); +#endif + +// CHECK: no_dummy_attribute +#if !__has_attribute(dummy_attribute) +int no_dummy_attribute(); +#endif + |