]> granicus.if.org Git - clang/commitdiff
Fix __has_cpp_attribute expansion to produce trailing L and (where
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 21 Jun 2019 20:20:21 +0000 (20:20 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 21 Jun 2019 20:20:21 +0000 (20:20 +0000)
necessary) leading whitespace.

Simplify unit test and extend to cover no_unique_address attribute.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@364102 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/PPMacroExpansion.cpp
test/Preprocessor/has_attribute.cpp

index 72f8f48839d059a836673a817413c013ac1f784b..7e1f3b4dfdf3b00980475ef98af6e70cc5f4707c 100644 (file)
@@ -1330,9 +1330,13 @@ already_lexed:
 
         // The last ')' has been reached; return the value if one found or
         // a diagnostic and a dummy value.
-        if (Result.hasValue())
+        if (Result.hasValue()) {
           OS << Result.getValue();
-        else {
+          // For strict conformance to __has_cpp_attribute rules, use 'L'
+          // suffix for dated literals.
+          if (Result.getValue() > 1)
+            OS << 'L';
+        } else {
           OS << 0;
           if (!SuppressDiagnostic)
             PP.Diag(Tok.getLocation(), diag::err_too_few_args_in_macro_invoc);
@@ -1454,6 +1458,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
   // Set up the return result.
   Tok.setIdentifierInfo(nullptr);
   Tok.clearFlag(Token::NeedsCleaning);
+  bool IsAtStartOfLine = Tok.isAtStartOfLine();
+  bool HasLeadingSpace = Tok.hasLeadingSpace();
 
   if (II == Ident__LINE__) {
     // C99 6.10.8: "__LINE__: The presumed line number (within the current
@@ -1807,6 +1813,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
     llvm_unreachable("Unknown identifier!");
   }
   CreateString(OS.str(), Tok, Tok.getLocation(), Tok.getLocation());
+  Tok.setFlagValue(Token::StartOfLine, IsAtStartOfLine);
+  Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
 }
 
 void Preprocessor::markMacroAsUsed(MacroInfo *MI) {
index 91f3501666fc7e7d88e8404c6bc374147bdd9f7b..30544f2194ef1e3e82fbcbcb628ba66a770fadf5 100644 (file)
@@ -1,98 +1,80 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -fms-compatibility -std=c++11 -E %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -fms-compatibility -std=c++11 -E %s -o - | FileCheck %s --check-prefixes=CHECK,ITANIUM --implicit-check-not=:
+// RUN: %clang_cc1 -triple i386-windows -fms-compatibility -std=c++11 -E %s -o - | FileCheck %s --check-prefixes=CHECK,WINDOWS --implicit-check-not=:
 
-// CHECK: has_cxx11_carries_dep
-#if __has_cpp_attribute(carries_dependency)
-  int has_cxx11_carries_dep();
-#endif
+#define CXX11(x) x: __has_cpp_attribute(x)
 
-// CHECK: has_clang_fallthrough_1
-#if __has_cpp_attribute(clang::fallthrough)
-  int has_clang_fallthrough_1();
-#endif
+// CHECK: clang::fallthrough: 201603L
+CXX11(clang::fallthrough)
 
-// CHECK: does_not_have_selectany
-#if !__has_cpp_attribute(selectany)
-  int does_not_have_selectany();
-#endif
+// CHECK: selectany: 0
+CXX11(selectany)
 
 // The attribute name can be bracketed with double underscores.
-// CHECK: has_clang_fallthrough_2
-#if __has_cpp_attribute(clang::__fallthrough__)
-  int has_clang_fallthrough_2();
-#endif
+// CHECK: clang::__fallthrough__: 201603L
+CXX11(clang::__fallthrough__)
 
 // The scope cannot be bracketed with double underscores unless it is
 // for gnu or clang.
-// CHECK: does_not_have___gsl___suppress
-#if !__has_cpp_attribute(__gsl__::suppress)
-  int does_not_have___gsl___suppress();
-#endif
+// CHECK: __gsl__::suppress: 0
+CXX11(__gsl__::suppress)
 
 // We do somewhat support the __clang__ vendor namespace, but it is a
 // predefined macro and thus we encourage users to use _Clang instead.
 // Because of this, we do not support __has_cpp_attribute for that
 // vendor namespace.
-// CHECK: does_not_have___clang___fallthrough
-#if !__has_cpp_attribute(__clang__::fallthrough)
-  int does_not_have___clang___fallthrough();
-#endif
-
-// CHECK: does_have_Clang_fallthrough
-#if __has_cpp_attribute(_Clang::fallthrough)
-  int does_have_Clang_fallthrough();
-#endif
-
-// CHECK: has_gnu_const
-#if __has_cpp_attribute(__gnu__::__const__)
-  int has_gnu_const();
-#endif\r
-\r
-// Test that C++11, target-specific attributes behave properly.\r
-\r
-// CHECK: does_not_have_mips16
-#if !__has_cpp_attribute(gnu::mips16)
-  int does_not_have_mips16();
-#endif
-
-// Test that the version numbers of attributes listed in SD-6 are supported
-// correctly.
-
-// CHECK: has_cxx11_carries_dep_vers
-#if __has_cpp_attribute(carries_dependency) == 200809
-  int has_cxx11_carries_dep_vers();
-#endif
-
-// CHECK: has_cxx11_noreturn_vers
-#if __has_cpp_attribute(noreturn) == 200809
-  int has_cxx11_noreturn_vers();
-#endif
-
-// CHECK: has_cxx14_deprecated_vers
-#if __has_cpp_attribute(deprecated) == 201309
-  int has_cxx14_deprecated_vers();
-#endif
-
-// CHECK: has_cxx1z_nodiscard
-#if __has_cpp_attribute(nodiscard) == 201603
-  int has_cxx1z_nodiscard();
-#endif
-
-// CHECK: has_cxx1z_fallthrough
-#if __has_cpp_attribute(fallthrough) == 201603
-  int has_cxx1z_fallthrough();
-#endif
-
-// CHECK: has_declspec_uuid
-#if __has_declspec_attribute(uuid)
-  int has_declspec_uuid();
-#endif
-
-// CHECK: has_declspec_uuid2
-#if __has_declspec_attribute(__uuid__)
-  int has_declspec_uuid2();
-#endif
-
-// CHECK: does_not_have_declspec_fallthrough
-#if !__has_declspec_attribute(fallthrough)
-  int does_not_have_declspec_fallthrough();
-#endif
+//
+// Note, we can't use CXX11 here because it will expand __clang__ to 1
+// too early.
+// CHECK: 1::fallthrough: 0
+__clang__::fallthrough: __has_cpp_attribute(__clang__::fallthrough)
+
+// CHECK: _Clang::fallthrough: 201603L
+CXX11(_Clang::fallthrough)
+
+// CHECK: __gnu__::__const__: 1
+CXX11(__gnu__::__const__)
+
+// Test that C++11, target-specific attributes behave properly.
+
+// CHECK: gnu::mips16: 0
+CXX11(gnu::mips16)
+
+// Test for standard attributes as listed in C++2a [cpp.cond] paragraph 6.
+
+CXX11(assert)
+CXX11(carries_dependency)
+CXX11(deprecated)
+CXX11(ensures)
+CXX11(expects)
+CXX11(fallthrough)
+CXX11(likely)
+CXX11(maybe_unused)
+CXX11(no_unique_address)
+CXX11(nodiscard)
+CXX11(noreturn)
+CXX11(unlikely)
+// FIXME(201806L) CHECK: assert: 0
+// CHECK: carries_dependency: 200809L
+// CHECK: deprecated: 201309L
+// FIXME(201806L) CHECK: ensures: 0
+// FIXME(201806L) CHECK: expects: 0
+// CHECK: fallthrough: 201603L
+// FIXME(201803L) CHECK: likely: 0
+// CHECK: maybe_unused: 201603L
+// ITANIUM: no_unique_address: 201803L
+// WINDOWS: no_unique_address: 0
+// CHECK: nodiscard: 201603L
+// CHECK: noreturn: 200809L
+// FIXME(201803L) CHECK: unlikely: 0
+
+// Test for Microsoft __declspec attributes
+
+#define DECLSPEC(x) x: __has_declspec_attribute(x)
+
+// CHECK: uuid: 1
+// CHECK: __uuid__: 1
+DECLSPEC(uuid)
+DECLSPEC(__uuid__)
+
+// CHECK: fallthrough: 0
+DECLSPEC(fallthrough)