r312572 - [ms] Implement the __annotation intrinsic

Reid Kleckner via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 5 13:27:35 PDT 2017


Author: rnk
Date: Tue Sep  5 13:27:35 2017
New Revision: 312572

URL: http://llvm.org/viewvc/llvm-project?rev=312572&view=rev
Log:
[ms] Implement the __annotation intrinsic

Added:
    cfe/trunk/test/CodeGen/ms-annotation.c
    cfe/trunk/test/Sema/ms-annotation.c
Modified:
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=312572&r1=312571&r2=312572&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Tue Sep  5 13:27:35 2017
@@ -732,6 +732,7 @@ BUILTIN(__builtin_rindex, "c*cC*i", "Fn"
 
 // Microsoft builtins.  These are only active with -fms-extensions.
 LANGBUILTIN(_alloca,          "v*z", "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__annotation,     "wC*.","n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__assume,         "vb",  "n", ALL_MS_LANGUAGES)
 LIBBUILTIN(_byteswap_ushort, "UsUs",     "fnc", "stdlib.h", ALL_MS_LANGUAGES)
 LIBBUILTIN(_byteswap_ulong,  "UNiUNi",   "fnc", "stdlib.h", ALL_MS_LANGUAGES)

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=312572&r1=312571&r2=312572&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Sep  5 13:27:35 2017
@@ -7902,6 +7902,8 @@ def err_builtin_annotation_first_arg : E
   "first argument to __builtin_annotation must be an integer">;
 def err_builtin_annotation_second_arg : Error<
   "second argument to __builtin_annotation must be a non-wide string constant">;
+def err_msvc_annotation_wide_str : Error<
+  "arguments to __annotation must be wide string constants">;
 
 // CFString checking
 def err_cfstring_literal_not_string_constant : Error<

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=312572&r1=312571&r2=312572&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Sep  5 13:27:35 2017
@@ -30,6 +30,7 @@
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/MDBuilder.h"
+#include "llvm/Support/ConvertUTF.h"
 #include <sstream>
 
 using namespace clang;
@@ -1953,6 +1954,28 @@ RValue CodeGenFunction::EmitBuiltinExpr(
         Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))),
                            ConvertType(E->getType())));
   }
+  case Builtin::BI__annotation: {
+    // Re-encode each wide string to UTF8 and make an MDString.
+    SmallVector<Metadata *, 1> Strings;
+    for (const Expr *Arg : E->arguments()) {
+      const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
+      assert(Str->getCharByteWidth() == 2);
+      StringRef WideBytes = Str->getBytes();
+      std::string StrUtf8;
+      if (!convertUTF16ToUTF8String(
+              makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
+        CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
+        continue;
+      }
+      Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
+    }
+
+    // Build and MDTuple of MDStrings and emit the intrinsic call.
+    llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::label_annotation, {});
+    MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings);
+    Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple));
+    return RValue::getIgnored();
+  }
   case Builtin::BI__builtin_annotation: {
     llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
     llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=312572&r1=312571&r2=312572&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Sep  5 13:27:35 2017
@@ -99,6 +99,28 @@ static bool SemaBuiltinAnnotation(Sema &
   return false;
 }
 
+static bool SemaBuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall) {
+  // We need at least one argument.
+  if (TheCall->getNumArgs() < 1) {
+    S.Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least)
+        << 0 << 1 << TheCall->getNumArgs()
+        << TheCall->getCallee()->getSourceRange();
+    return true;
+  }
+
+  // All arguments should be wide string literals.
+  for (Expr *Arg : TheCall->arguments()) {
+    auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
+    if (!Literal || !Literal->isWide()) {
+      S.Diag(Arg->getLocStart(), diag::err_msvc_annotation_wide_str)
+          << Arg->getSourceRange();
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /// Check that the argument to __builtin_addressof is a glvalue, and set the
 /// result type to the corresponding pointer type.
 static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) {
@@ -1000,6 +1022,10 @@ Sema::CheckBuiltinFunctionCall(FunctionD
   case Builtin::BI##ID: \
     return SemaAtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
 #include "clang/Basic/Builtins.def"
+  case Builtin::BI__annotation:
+    if (SemaBuiltinMSVCAnnotation(*this, TheCall))
+      return ExprError();
+    break;
   case Builtin::BI__builtin_annotation:
     if (SemaBuiltinAnnotation(*this, TheCall))
       return ExprError();

Added: cfe/trunk/test/CodeGen/ms-annotation.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-annotation.c?rev=312572&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/ms-annotation.c (added)
+++ cfe/trunk/test/CodeGen/ms-annotation.c Tue Sep  5 13:27:35 2017
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-windows %s -fms-extensions -emit-llvm -o - | FileCheck %s
+//
+// Test that LLVM optimizations leave these intrinsics alone, for the most part.
+// RUN: %clang_cc1 -O2 -triple i686-windows %s -fms-extensions -emit-llvm -o - | FileCheck %s
+
+void test1(void) {
+  __annotation(L"a1");
+  __annotation(L"a1", L"a2");
+  __annotation(L"a1", L"a2", L"a3");
+  __annotation(L"multi " L"part " L"string");
+  __annotation(L"unicode: \u0ca0_\u0ca0");
+}
+
+// CHECK-LABEL: define void @test1()
+// CHECK: call void @llvm.label.annotation(metadata ![[A1:[0-9]+]])
+// CHECK: call void @llvm.label.annotation(metadata ![[A2:[0-9]+]])
+// CHECK: call void @llvm.label.annotation(metadata ![[A3:[0-9]+]])
+// CHECK: call void @llvm.label.annotation(metadata ![[A4:[0-9]+]])
+// CHECK: call void @llvm.label.annotation(metadata ![[A5:[0-9]+]])
+// CHECK: ret void
+
+// CHECK: ![[A1]] = !{!"a1"}
+// CHECK: ![[A2]] = !{!"a1", !"a2"}
+// CHECK: ![[A3]] = !{!"a1", !"a2", !"a3"}
+// CHECK: ![[A4]] = !{!"multi part string"}
+// CHECK: ![[A5]] = !{!"unicode: \E0\B2\A0_\E0\B2\A0"}

Added: cfe/trunk/test/Sema/ms-annotation.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms-annotation.c?rev=312572&view=auto
==============================================================================
--- cfe/trunk/test/Sema/ms-annotation.c (added)
+++ cfe/trunk/test/Sema/ms-annotation.c Tue Sep  5 13:27:35 2017
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-windows %s -verify -fms-extensions
+// RUN: %clang_cc1 -x c++ -std=c++11 -triple i686-windows %s -verify -fms-extensions
+// RUN: %clang_cc1 -x c++ -std=c++14 -triple i686-windows %s -verify -fms-extensions
+
+void test1(void) {
+  __annotation(); // expected-error {{too few arguments to function call, expected at least 1, have 0}}
+  __annotation(1); // expected-error {{must be wide string constants}}
+  __annotation(L"a1");
+  __annotation(L"a1", L"a2");
+  __annotation(L"a1", L"a2", 42); // expected-error {{must be wide string constants}}
+  __annotation(L"a1", L"a2", L"a3");
+  __annotation(L"multi " L"part " L"string");
+}




More information about the cfe-commits mailing list