r330571 - Use special new Clang flag 'FrontendTimesIsEnabled' instead of 'llvm::TimePassesIsEnabled' inside -ftime-report feature.

2018-04-23 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Mon Apr 23 02:22:30 2018
New Revision: 330571

URL: http://llvm.org/viewvc/llvm-project?rev=330571&view=rev
Log:
Use special new Clang flag 'FrontendTimesIsEnabled' instead of 
'llvm::TimePassesIsEnabled' inside -ftime-report feature.
Differential Revision: https://reviews.llvm.org/D45619

Added:
cfe/trunk/lib/Frontend/FrontendTiming.cpp
cfe/trunk/test/Frontend/ftime-report-template-decl.cpp
Modified:
cfe/trunk/include/clang/Frontend/Utils.h
cfe/trunk/lib/CodeGen/BackendUtil.cpp
cfe/trunk/lib/CodeGen/CodeGenAction.cpp
cfe/trunk/lib/Frontend/CMakeLists.txt

Modified: cfe/trunk/include/clang/Frontend/Utils.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Utils.h?rev=330571&r1=330570&r2=330571&view=diff
==
--- cfe/trunk/include/clang/Frontend/Utils.h (original)
+++ cfe/trunk/include/clang/Frontend/Utils.h Mon Apr 23 02:22:30 2018
@@ -234,6 +234,12 @@ template  void BuryPointer(s
   BuryPointer(Ptr.release());
 }
 
+// Frontend timing utils
+
+/// If the user specifies the -ftime-report argument on an Clang command line
+/// then the value of this boolean will be true, otherwise false.
+extern bool FrontendTimesIsEnabled;
+
 } // namespace clang
 
 #endif // LLVM_CLANG_FRONTEND_UTILS_H

Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=330571&r1=330570&r2=330571&view=diff
==
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Mon Apr 23 02:22:30 2018
@@ -728,7 +728,7 @@ bool EmitAssemblyHelper::AddEmitPasses(l
 
 void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
   std::unique_ptr OS) {
-  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
+  TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
 
   setCommandLineOpts(CodeGenOpts);
 
@@ -858,7 +858,7 @@ static PassBuilder::OptimizationLevel ma
 /// `EmitAssembly` at some point in the future when the default switches.
 void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
 BackendAction Action, std::unique_ptr OS) {
-  TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
+  TimeRegion Region(FrontendTimesIsEnabled ? &CodeGenerationTime : nullptr);
   setCommandLineOpts(CodeGenOpts);
 
   // The new pass manager always makes a target machine available to passes

Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=330571&r1=330570&r2=330571&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Mon Apr 23 02:22:30 2018
@@ -126,7 +126,7 @@ namespace clang {
   Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
 CodeGenOpts, C, CoverageInfo)),
   LinkModules(std::move(LinkModules)) {
-  llvm::TimePassesIsEnabled = TimePasses;
+  FrontendTimesIsEnabled = TimePasses;
 }
 llvm::Module *getModule() const { return Gen->GetModule(); }
 std::unique_ptr takeModule() {
@@ -144,12 +144,12 @@ namespace clang {
 
   Context = &Ctx;
 
-  if (llvm::TimePassesIsEnabled)
+  if (FrontendTimesIsEnabled)
 LLVMIRGeneration.startTimer();
 
   Gen->Initialize(Ctx);
 
-  if (llvm::TimePassesIsEnabled)
+  if (FrontendTimesIsEnabled)
 LLVMIRGeneration.stopTimer();
 }
 
@@ -159,7 +159,7 @@ namespace clang {
  "LLVM IR generation of declaration");
 
   // Recurse.
-  if (llvm::TimePassesIsEnabled) {
+  if (FrontendTimesIsEnabled) {
 LLVMIRGenerationRefCount += 1;
 if (LLVMIRGenerationRefCount == 1)
   LLVMIRGeneration.startTimer();
@@ -167,7 +167,7 @@ namespace clang {
 
   Gen->HandleTopLevelDecl(D);
 
-  if (llvm::TimePassesIsEnabled) {
+  if (FrontendTimesIsEnabled) {
 LLVMIRGenerationRefCount -= 1;
 if (LLVMIRGenerationRefCount == 0)
   LLVMIRGeneration.stopTimer();
@@ -180,12 +180,12 @@ namespace clang {
   PrettyStackTraceDecl CrashInfo(D, SourceLocation(),
  Context->getSourceManager(),
  "LLVM IR generation of inline function");
-  if (llvm::TimePassesIsEnabled)
+  if (FrontendTimesIsEnabled)
 LLVMIRGeneration.startTimer();
 
   Gen->HandleInlineFunctionDefinition(D);
 
-  if (llvm::TimePassesIsEnabled)
+  if (FrontendTimesIsEnabled)
 LLVMIRGeneration.stopTimer();
 }
 
@@ -227,7 +227,7 @@ namespace clang {
 void HandleTranslationUnit(ASTContext &C) override {

r329714 - I removed the failed test.

2018-04-10 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Tue Apr 10 08:45:43 2018
New Revision: 329714

URL: http://llvm.org/viewvc/llvm-project?rev=329714&view=rev
Log:
I removed the failed test.

Removed:
cfe/trunk/test/Frontend/ftime-report-template-decl.cpp

Removed: cfe/trunk/test/Frontend/ftime-report-template-decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/ftime-report-template-decl.cpp?rev=329713&view=auto
==
--- cfe/trunk/test/Frontend/ftime-report-template-decl.cpp (original)
+++ cfe/trunk/test/Frontend/ftime-report-template-decl.cpp (removed)
@@ -1,147 +0,0 @@
-// RUN: %clang %s -S -o - -ftime-report  2>&1 | FileCheck %s
-// RUN: %clang %s -S -o - -fdelayed-template-parsing 
-DDELAYED_TEMPLATE_PARSING -ftime-report  2>&1 | FileCheck %s
-
-// Template function declarations
-template 
-void foo();
-template 
-void foo();
-
-// Template function definitions.
-template 
-void foo() {}
-
-// Template class (forward) declarations
-template 
-struct A;
-template 
-struct b;
-template 
-struct C;
-template 
-struct D;
-
-// Forward declarations with default parameters?
-template 
-class X1;
-template 
-class X2;
-
-// Forward declarations w/template template parameters
-template  class T>
-class TTP1;
-template  class>
-class TTP2;
-template  class T>
-class TTP5;
-
-// Forward declarations with non-type params
-template 
-class NTP0;
-template 
-class NTP1;
-template 
-class NTP2;
-template 
-class NTP3;
-template 
-class NTP4;
-template 
-class NTP5;
-template 
-class NTP6;
-template 
-class NTP7;
-
-// Template class declarations
-template 
-struct A {};
-template 
-struct B {};
-
-namespace PR6184 {
-namespace N {
-template 
-void bar(typename T::x);
-}
-
-template 
-void N::bar(typename T::x) {}
-}
-
-// This PR occurred only in template parsing mode.
-namespace PR17637 {
-template 
-struct L {
-  template 
-  struct O {
-template 
-static void Fun(U);
-  };
-};
-
-template 
-template 
-template 
-void L::O::Fun(U) {}
-
-void Instantiate() { L<0>::O::Fun(0); }
-}
-
-namespace explicit_partial_specializations {
-typedef char (&oneT)[1];
-typedef char (&twoT)[2];
-typedef char (&threeT)[3];
-typedef char (&fourT)[4];
-typedef char (&fiveT)[5];
-typedef char (&sixT)[6];
-
-char one[1];
-char two[2];
-char three[3];
-char four[4];
-char five[5];
-char six[6];
-
-template 
-struct bool_ { typedef int type; };
-template <>
-struct bool_ {};
-
-#define XCAT(x, y) x##y
-#define CAT(x, y) XCAT(x, y)
-#define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__);
-
-template 
-struct L {
-  template 
-  struct O {
-template 
-static oneT Fun(U);
-  };
-};
-template 
-template 
-template 
-oneT L::O::Fun(U) { return one; }
-
-template <>
-template <>
-template 
-oneT L<0>::O::Fun(U) { return one; }
-
-void Instantiate() {
-  sassert(sizeof(L<0>::O::Fun(0)) == sizeof(one));
-  sassert(sizeof(L<0>::O::Fun(0)) == sizeof(one));
-}
-}
-
-// CHECK:   = Clang Parser =
-// CHECK:   ---User Time---
-// CHECK:   Parse Top Level Decl
-// CHECK:   Parse Template
-// CHECK:   Parse Function Definition
-// CHECK:   PP Append Macro
-// CHECK:   Scope manipulation
-// CHECK:   PP Find Handler
-// CHECK:   Total


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r329693 - The test was fixed.

2018-04-10 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Tue Apr 10 05:17:01 2018
New Revision: 329693

URL: http://llvm.org/viewvc/llvm-project?rev=329693&view=rev
Log:
The test was fixed.

Modified:
cfe/trunk/test/Frontend/ftime-report-template-decl.cpp

Modified: cfe/trunk/test/Frontend/ftime-report-template-decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/ftime-report-template-decl.cpp?rev=329693&r1=329692&r2=329693&view=diff
==
--- cfe/trunk/test/Frontend/ftime-report-template-decl.cpp (original)
+++ cfe/trunk/test/Frontend/ftime-report-template-decl.cpp Tue Apr 10 05:17:01 
2018
@@ -137,7 +137,7 @@ void Instantiate() {
 }
 
 // CHECK:   = Clang Parser =
-// CHECK:   ---User Time---   --User+System--   ---Wall Time---  --- Name ---
+// CHECK:   ---User Time---
 // CHECK:   Parse Top Level Decl
 // CHECK:   Parse Template
 // CHECK:   Parse Function Definition


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r329684 - -ftime-report switch support in Clang.

2018-04-10 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Tue Apr 10 03:34:13 2018
New Revision: 329684

URL: http://llvm.org/viewvc/llvm-project?rev=329684&view=rev
Log:
-ftime-report switch support in Clang.
The current support of the feature produces only 2 lines in report:
 -Some general Code Generation Time;
 -Total time of Backend Consumer actions.
This patch extends Clang time report with new lines related to Preprocessor, 
Include Filea Search, Parsing, etc.
Differential Revision: https://reviews.llvm.org/D43578

Added:
cfe/trunk/test/Frontend/ftime-report-template-decl.cpp
Modified:
cfe/trunk/include/clang/Frontend/FrontendAction.h
cfe/trunk/include/clang/Lex/HeaderSearch.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/CodeGen/CodeGenAction.cpp
cfe/trunk/lib/Frontend/ASTMerge.cpp
cfe/trunk/lib/Frontend/CompilerInstance.cpp
cfe/trunk/lib/Frontend/FrontendAction.cpp
cfe/trunk/lib/Frontend/FrontendActions.cpp
cfe/trunk/lib/Lex/HeaderSearch.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Lex/Pragma.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Frontend/FrontendAction.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendAction.h?rev=329684&r1=329683&r2=329684&view=diff
==
--- cfe/trunk/include/clang/Frontend/FrontendAction.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendAction.h Tue Apr 10 03:34:13 2018
@@ -45,6 +45,9 @@ private:
 StringRef InFile);
 
 protected:
+  static constexpr const char *GroupName = "factions";
+  static constexpr const char *GroupDescription =
+  "= Frontend Actions =";
   /// @name Implementation Action Interface
   /// @{
 

Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=329684&r1=329683&r2=329684&view=diff
==
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Tue Apr 10 03:34:13 2018
@@ -21,9 +21,10 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/Timer.h"
 #include 
 #include 
 #include 
@@ -31,6 +32,9 @@
 #include 
 #include 
 
+static const char *const IncGroupName = "includefiles";
+static const char *const IncGroupDescription = "= Include Files =";
+
 namespace clang {
 
 class DiagnosticsEngine;

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=329684&r1=329683&r2=329684&view=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Apr 10 03:34:13 2018
@@ -2851,4 +2851,6 @@ private:
 
 }  // end namespace clang
 
+static const char *const GroupName = "clangparser";
+static const char *const GroupDescription = "= Clang Parser =";
 #endif

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=329684&r1=329683&r2=329684&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Apr 10 03:34:13 2018
@@ -304,6 +304,9 @@ class Sema {
   bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New);
 
 public:
+  static constexpr const char *GroupName = "sema";
+  static constexpr const char *GroupDescription = "= Sema =";
+
   typedef OpaquePtr DeclGroupPtrTy;
   typedef OpaquePtr TemplateTy;
   typedef OpaquePtr TypeTy;

Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=329684&r1=329683&r2=329684&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Tue Apr 10 03:34:13 2018
@@ -23,6 +23,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
 #include "llvm/IR/Debu

r327618 - More warnings when double truncation to float: compound assignment is supported now.

2018-03-15 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Thu Mar 15 03:03:35 2018
New Revision: 327618

URL: http://llvm.org/viewvc/llvm-project?rev=327618&view=rev
Log:
More warnings when double truncation to float: compound assignment is supported 
now.

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/conversion.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=327618&r1=327617&r2=327618&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Mar 15 03:03:35 
2018
@@ -3093,6 +3093,9 @@ def err_impcast_complex_scalar : Error<
 def warn_impcast_float_precision : Warning<
   "implicit conversion loses floating-point precision: %0 to %1">,
   InGroup, DefaultIgnore;
+def warn_impcast_float_result_precision : Warning<
+  "implicit conversion when assigning computation result loses floating-point 
precision: %0 to %1">,
+  InGroup, DefaultIgnore;
 def warn_impcast_double_promotion : Warning<
   "implicit conversion increases floating-point precision: %0 to %1">,
   InGroup, DefaultIgnore;

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=327618&r1=327617&r2=327618&view=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Thu Mar 15 03:03:35 2018
@@ -9183,6 +9183,32 @@ static void DiagnoseImpCast(Sema &S, Exp
   DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);
 }
 
+/// Analyze the given compound assignment for the possible losing of
+/// floating-point precision.
+static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
+  assert(isa(E) &&
+ "Must be compound assignment operation");
+  // Recurse on the LHS and RHS in here
+  AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc());
+  AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc());
+
+  // Now check the outermost expression
+  const auto *ResultBT = E->getLHS()->getType()->getAs();
+  const auto *RBT = cast(E)
+->getComputationResultType()
+->getAs();
+
+  // If both source and target are floating points.
+  if (ResultBT && ResultBT->isFloatingPoint() && RBT && RBT->isFloatingPoint())
+// Builtin FP kinds are ordered by increasing FP rank.
+if (ResultBT->getKind() < RBT->getKind())
+  // We don't want to warn for system macro.
+  if (!S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
+// warn about dropping FP rank.
+DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(),
+E->getOperatorLoc(),
+diag::warn_impcast_float_result_precision);
+}
 
 /// Diagnose an implicit cast from a floating point value to an integer value.
 static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,
@@ -9550,7 +9576,7 @@ CheckImplicitConversion(Sema &S, Expr *E
 return;
   return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_vector_scalar);
 }
-
+
 // If the vector cast is cast between two vectors of the same size, it is
 // a bitcast, not a conversion.
 if (S.Context.getTypeSize(Source) == S.Context.getTypeSize(Target))
@@ -9827,7 +9853,7 @@ static void AnalyzeImplicitConversions(S
 
   if (E->isTypeDependent() || E->isValueDependent())
 return;
-  
+
   // For conditional operators, we analyze the arguments as if they
   // were being fed directly into the output.
   if (isa(E)) {
@@ -9871,6 +9897,9 @@ static void AnalyzeImplicitConversions(S
 // And with simple assignments.
 if (BO->getOpcode() == BO_Assign)
   return AnalyzeAssignment(S, BO);
+// And with compound assignments.
+if (BO->isAssignmentOp())
+  return AnalyzeCompoundAssignment(S, BO);
   }
 
   // These break the otherwise-useful invariant below.  Fortunately,

Modified: cfe/trunk/test/Sema/conversion.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conversion.c?rev=327618&r1=327617&r2=327618&view=diff
==
--- cfe/trunk/test/Sema/conversion.c (original)
+++ cfe/trunk/test/Sema/conversion.c Thu Mar 15 03:03:35 2018
@@ -436,10 +436,15 @@ float double2float_test1(double a) {
 }
 
 void double2float_test2(double a, float *b) {
-*b += a;
+  *b += a; // expected-warning {{implicit conversion when assigning 
computation result loses floating-point precision: 'double' to 'float'}}
 }
 
 float sinf (float x);
 double double2float_test3(double a) {
 return sinf(a); // expected-warning {{implicit conversion loses 
floating-point precision: 'double' to 'f

r325011 - An updated test to show the current warnings produced for implicit conversions from 'double' to 'float'.

2018-02-13 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Tue Feb 13 07:20:29 2018
New Revision: 325011

URL: http://llvm.org/viewvc/llvm-project?rev=325011&view=rev
Log:
An updated test to show the current warnings produced for implicit conversions 
from 'double' to 'float'.

Modified:
cfe/trunk/test/Sema/conversion.c

Modified: cfe/trunk/test/Sema/conversion.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/conversion.c?rev=325011&r1=325010&r2=325011&view=diff
==
--- cfe/trunk/test/Sema/conversion.c (original)
+++ cfe/trunk/test/Sema/conversion.c Tue Feb 13 07:20:29 2018
@@ -429,3 +429,17 @@ void test27(ushort16 constants) {
 ushort16 crCbScale = pairedConstants.s4; // expected-warning {{implicit 
conversion loses integer precision: 'uint32_t' (aka 'unsigned int') to 
'ushort16'}}
 ushort16 brBias = pairedConstants.s6; // expected-warning {{implicit 
conversion loses integer precision: 'uint32_t' (aka 'unsigned int') to 
'ushort16'}}
 }
+
+
+float double2float_test1(double a) {
+return a; // expected-warning {{implicit conversion loses floating-point 
precision: 'double' to 'float'}}
+}
+
+void double2float_test2(double a, float *b) {
+*b += a;
+}
+
+float sinf (float x);
+double double2float_test3(double a) {
+return sinf(a); // expected-warning {{implicit conversion loses 
floating-point precision: 'double' to 'float'}}
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r324721 - Fif for an issue when Clang permits assignment to vector/extvector elements in a const method.

2018-02-09 Thread Andrew V. Tischenko via cfe-commits
Author: avt77
Date: Fri Feb  9 01:30:42 2018
New Revision: 324721

URL: http://llvm.org/viewvc/llvm-project?rev=324721&view=rev
Log:
Fif for an issue when Clang permits assignment to vector/extvector elements in 
a const method.

Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprMember.cpp
cfe/trunk/test/Sema/assign.c
cfe/trunk/test/Sema/typedef-retain.c
cfe/trunk/test/SemaCXX/err_typecheck_assign_const.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=324721&r1=324720&r2=324721&view=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb  9 01:30:42 2018
@@ -4395,8 +4395,13 @@ Sema::CreateBuiltinArraySubscriptExpr(Ex
 if (VK != VK_RValue)
   OK = OK_VectorComponent;
 
-// FIXME: need to deal with const...
 ResultType = VTy->getElementType();
+QualType BaseType = BaseExpr->getType();
+Qualifiers BaseQuals = BaseType.getQualifiers();
+Qualifiers MemberQuals = ResultType.getQualifiers();
+Qualifiers Combined = BaseQuals + MemberQuals;
+if (Combined != MemberQuals)
+  ResultType = Context.getQualifiedType(ResultType, Combined);
   } else if (LHSTy->isArrayType()) {
 // If we see an array that wasn't promoted by
 // DefaultFunctionArrayLvalueConversion, it must be an array that
@@ -10434,8 +10439,16 @@ static void DiagnoseConstAssignment(Sema
 // Static fields do not inherit constness from parents.
 break;
   }
-  break;
-} // End MemberExpr
+  break; // End MemberExpr
+} else if (const ArraySubscriptExpr *ASE =
+   dyn_cast(E)) {
+  E = ASE->getBase()->IgnoreParenImpCasts();
+  continue;
+} else if (const ExtVectorElementExpr *EVE =
+   dyn_cast(E)) {
+  E = EVE->getBase()->IgnoreParenImpCasts();
+  continue;
+}
 break;
   }
 

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=324721&r1=324720&r2=324721&view=diff
==
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Fri Feb  9 01:30:42 2018
@@ -1623,10 +1623,14 @@ static ExprResult LookupMemberExpr(Sema
   else
 VK = BaseExpr.get()->getValueKind();
 }
+
 QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
Member, MemberLoc);
 if (ret.isNull())
   return ExprError();
+Qualifiers BaseQ =
+S.Context.getCanonicalType(BaseExpr.get()->getType()).getQualifiers();
+ret = S.Context.getQualifiedType(ret, BaseQ);
 
 return new (S.Context)
 ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);

Modified: cfe/trunk/test/Sema/assign.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/assign.c?rev=324721&r1=324720&r2=324721&view=diff
==
--- cfe/trunk/test/Sema/assign.c (original)
+++ cfe/trunk/test/Sema/assign.c Fri Feb  9 01:30:42 2018
@@ -11,10 +11,10 @@ void test2 (const struct {int a;} *x) {
 
 typedef int arr[10];
 void test3() {
-  const arr b;
-  const int b2[10]; 
-  b[4] = 1; // expected-error {{read-only variable is not assignable}}
-  b2[4] = 1; // expected-error {{read-only variable is not assignable}}
+  const arr b;  // expected-note {{variable 'b' declared const here}}
+  const int b2[10]; // expected-note {{variable 'b2' declared const here}}
+  b[4] = 1; // expected-error {{cannot assign to variable 'b' with 
const-qualified type 'const arr' (aka 'int const[10]')}}
+  b2[4] = 1;// expected-error {{cannot assign to variable 'b2' with 
const-qualified type 'const int [10]'}}
 }
 
 typedef struct I {

Modified: cfe/trunk/test/Sema/typedef-retain.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/typedef-retain.c?rev=324721&r1=324720&r2=324721&view=diff
==
--- cfe/trunk/test/Sema/typedef-retain.c (original)
+++ cfe/trunk/test/Sema/typedef-retain.c Fri Feb  9 01:30:42 2018
@@ -16,8 +16,8 @@ void test2(float4 a, int4p result, int i
 typedef int a[5];
 void test3() {
   typedef const a b;
-  b r;
-  r[0]=10;  // expected-error {{read-only variable is not assignable}}
+  b r;   // expected-note {{variable 'r' declared const here}}
+  r[0] = 10; // expected-error {{cannot assign to variable 'r' with 
const-qualified type 'b' (aka 'int const[5]')}}
 }
 
 int test4(const a y) {

Modified: cfe/trunk/test/SemaCXX/err_typecheck_assign_const.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/err_typecheck_assign_const.cpp?rev=324721&r1=324720&r2=324721&view=diff
=

Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-05-24 Thread Andrew V. Tischenko via cfe-commits
avt77 updated this revision to Diff 58233.
avt77 added a comment.

I built the project from scratch and found an issue in Clang build system. 
There was a problem with undefined DiagGroup in DiagnosticSemaKinds.td: the 
error message was generated but all executables were created that's why I was 
not aware about this issue (I missed the message at the time of  my first build 
and all next re-builds worked without any problems). I created a new warning 
group (MicrosoftInconsistentDllImport) in DiagnosticGroups.td and made the 
corresponding changes in DiagnosticSemaKinds.td (2 lines).

Sorry for inconvenience but review the above two files and confirm your LGTM if 
it is.

And I suppose I should create a new record in Bugzilla, right?


http://reviews.llvm.org/D18953

Files:
  include/clang/Basic/DiagnosticGroups.td
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/CodeGen/dllimport.c
  test/CodeGenCXX/dllimport-members.cpp
  test/CodeGenCXX/dllimport.cpp
  test/Sema/dllimport.c
  test/SemaCXX/dllimport.cpp

Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -5523,9 +5523,13 @@
 
 static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
NamedDecl *NewDecl,
-   bool IsSpecialization) {
-  if (TemplateDecl *OldTD = dyn_cast(OldDecl))
+   bool IsSpecialization,
+   bool IsDefinition) {
+  if (TemplateDecl *OldTD = dyn_cast(OldDecl)) {
 OldDecl = OldTD->getTemplatedDecl();
+if (!IsSpecialization)
+  IsDefinition = false;
+  }
   if (TemplateDecl *NewTD = dyn_cast(NewDecl))
 NewDecl = NewTD->getTemplatedDecl();
 
@@ -5581,30 +5585,43 @@
 
   // A redeclaration is not allowed to drop a dllimport attribute, the only
   // exceptions being inline function definitions, local extern declarations,
-  // and qualified friend declarations.
-  // NB: MSVC converts such a declaration to dllexport.
+  // qualified friend declarations or special MSVC extension: in the last case,
+  // the declaration is treated as if it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  if (const auto *VD = dyn_cast(NewDecl))
+  bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+  if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.
 IsStaticDataMember = VD->isStaticDataMember();
-  else if (const auto *FD = dyn_cast(NewDecl)) {
+IsDefinition = VD->isThisDeclarationADefinition(S.Context) !=
+   VarDecl::DeclarationOnly;
+  } else if (const auto *FD = dyn_cast(NewDecl)) {
 IsInline = FD->isInlined();
 IsQualifiedFriend = FD->getQualifier() &&
 FD->getFriendObjectKind() == Decl::FOK_Declared;
   }
 
   if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember &&
   !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {
-S.Diag(NewDecl->getLocation(),
-   diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-  << NewDecl << OldImportAttr;
-S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
-S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
-OldDecl->dropAttr();
-NewDecl->dropAttr();
-  } else if (IsInline && OldImportAttr &&
- !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+if (IsMicrosoft && IsDefinition) {
+  S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_import_attribute)
+  << NewDecl;
+  S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+  NewDecl->dropAttr();
+  NewDecl->addAttr(::new (S.Context) DLLExportAttr(
+  NewImportAttr->getRange(), S.Context,
+  NewImportAttr->getSpellingListIndex()));
+} else {
+  S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
+  << NewDecl << OldImportAttr;
+  S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+  S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
+  OldDecl->dropAttr();
+  NewDecl->dropAttr();
+}
+  } else if (IsInline && OldImportAttr && !IsMicrosoft) {
 // In MinGW, seeing a function declared inline drops the dllimport attribute.
 OldDecl->dropAttr();
 NewDecl->dropAttr();
@@ -6388,7 +6405,7 @@
   if (D.isRedeclaration() && !Previous.empty()) {
 checkDLLAttributeRedeclaration(
 *this, dyn_cast(Previous.getRepresentativeDecl()), NewVD,
-IsExplicitSpecialization);
+IsExplicitSpecialization, D.isFunctionDefinition());
   }
 
   if (NewTemplate) {
@@ -8419,7 +8436,8 @@
   if (D.isRedeclaration()

Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-05-23 Thread Andrew V. Tischenko via cfe-commits
avt77 added a comment.

OK, as I see all issues were resolved, right?
Could I commit the patch?


http://reviews.llvm.org/D18953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19479: 26748 - clang-cl fails to compile atlctrlw.h header from WTL

2016-05-20 Thread Andrew V. Tischenko via cfe-commits
avt77 added a comment.

It seems I gave up with this issue :-( We have 2 possible situations here:

1. A type from instantiated type used inside the template (like in the test I'm 
working on)
2. A feature from instantiated type used inside the template (like below)

struct A {

  int bar ();

}
template  struct B : public T {

  int foo () {return bar();}


}
void test (){

  B b;
  int c = b.foo();

}
We can't made any assumption about the unknown identificator: is it type or a 
feature? In the first case we should deal with ParsedType but in the second 
case we should deal with DependentScopeDeclRefExpr. Of course we could create 
something like TypeOrExpr but I'm not sure it's an acceptable solution. The 
best way here is real implementation of late parsing for all in-class defined 
features from templates: this parsing should be done at instantiation point 
only (when we can discover all involved entities.).

What do you think about? Could you give me a hint how to resolve the issue 
without really late parsing?


http://reviews.llvm.org/D19479



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19156: [ms][dll] #27212: Generating of implicit special members should take into account MSVC compatibility version

2016-05-12 Thread Andrew V. Tischenko via cfe-commits
avt77 marked 2 inline comments as done.


Comment at: lib/Sema/SemaDeclCXX.cpp:4813
@@ +4812,3 @@
+// and move constructor, so don't attempt to import/export them if
+// we have a definition.
+auto *CXXC = dyn_cast(MD);

rnk wrote:
> Oh, so we were already doing this check. I don't see what's wrong with our 
> current behavior, though. We export a few more symbols than MSVC 2013, but 
> there's no ABI problem with that.
Yes, it's a question about binary compatibility only


Comment at: lib/Sema/SemaDeclCXX.cpp:4816
@@ -4815,1 +4815,3 @@
+if ((MD->isMoveAssignmentOperator() ||
+ (CXXC && CXXC->isMoveConstructor())) &&
 !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))

rnk wrote:
> The move constructor part of this is definitely a good fix though.
And what's the decision? Could I commit the patch?


http://reviews.llvm.org/D19156



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19156: [ms][dll] #27212: Generating of implicit special members should take into account MSVC compatibility version

2016-04-29 Thread Andrew V. Tischenko via cfe-commits
avt77 updated this revision to Diff 55567.
avt77 added a comment.

Now it's really a micro-patch: please review.


http://reviews.llvm.org/D19156

Files:
  lib/Sema/SemaDeclCXX.cpp
  test/CodeGenCXX/dllexport.cpp

Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -4774,7 +4774,6 @@
 
   // The class is either imported or exported.
   const bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
-  const bool ClassImported = !ClassExported;
 
   TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind();
 
@@ -4809,9 +4808,12 @@
 if (!Context.getTargetInfo().getCXXABI().isMicrosoft())
   continue;
 
-// MSVC versions before 2015 don't export the move assignment 
operators,
-// so don't attempt to import them if we have a definition.
-if (ClassImported && MD->isMoveAssignmentOperator() &&
+// MSVC versions before 2015 don't export the move assignment operators
+// and move constructor, so don't attempt to import/export them if
+// we have a definition.
+auto *CXXC = dyn_cast(MD);
+if ((MD->isMoveAssignmentOperator() ||
+ (CXXC && CXXC->isMoveConstructor())) &&
 !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
   continue;
   }
Index: test/CodeGenCXX/dllexport.cpp
===
--- test/CodeGenCXX/dllexport.cpp
+++ test/CodeGenCXX/dllexport.cpp
@@ -1,5 +1,9 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases 
-disable-llvm-optzns -o - %s -w | FileCheck --check-prefix=MSC 
--check-prefix=M32 %s
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck 
--check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases 
-disable-llvm-optzns -o - %s -w -fms-compatibility-version=19.00 | FileCheck 
--check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases 
-disable-llvm-optzns -o - %s -w -fms-compatibility-version=18.00 | FileCheck 
--check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 %s
+
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w 
-fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC 
--check-prefix=M64 -check-prefix=MSVC2015 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w 
-fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC 
--check-prefix=M64 -check-prefix=MSVC2013 %s
+
 // RUN: %clang_cc1 -triple i686-windows-gnu-emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck 
--check-prefix=GNU --check-prefix=G32 %s
 // RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck 
--check-prefix=GNU --check-prefix=G64 %s
 
@@ -528,6 +532,8 @@
   SomeTemplate(T o = T()) : o(o) {}
   T o;
 };
+// MSVC2015-DAG: define weak_odr dllexport {{.+}} 
@"\01??4?$SomeTemplate@H@@Q{{.+}}@$$Q{{.+}}@@Z"
+// MSVC2013-DAG: define weak_odr dllexport {{.+}} 
@"\01??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z"
 struct __declspec(dllexport) InheritFromTemplate : SomeTemplate {};
 
 // M32-DAG: define weak_odr dllexport x86_thiscallcc void 
@"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) {{#[0-9]+}} comdat
@@ -616,7 +622,8 @@
 
 struct __declspec(dllexport) Y {
   // Move assignment operator:
-  // M32-DAG: define weak_odr dllexport x86_thiscallcc 
dereferenceable({{[0-9]+}}) %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
+  // MSVC2015-DAG: define weak_odr dllexport {{.+}} 
@"\01??4Y@@Q{{.+}}@$$Q{{.+}}@@Z"
+  // MSVC2013-DAG: define weak_odr dllexport {{.+}} 
@"\01??4Y@@Q{{.+}}0@A{{.+}}0@@Z"
 
   int x;
 };
@@ -933,3 +940,15 @@
 USEMEMFUNC(ExplicitInstantiationDeclTemplateBase2, func)
 // M32-DAG: define weak_odr dllexport x86_thiscallcc void 
@"\01?func@?$ExplicitInstantiationDeclTemplateBase2@H@@QAEXXZ"
 // G32-DAG: define weak_odr x86_thiscallcc void 
@_ZN38ExplicitInstantiationDeclTemplateBase2IiE4funcEv
+
+class __declspec(dllexport) ACE_Shared_Object {
+  public:
+virtual ~ACE_Shared_Object ();
+};
+
+class __declspec(dllexport) ACE_Service_Object: public ACE_Shared_Object {};
+
+// Implicit move constructor declaration.
+// MSVC2015-DAG: define weak_odr dllexport 
{{.+}}ACE_Service_Object@@Q{{.+}}@$$Q
+// The declarations should not be exported.
+// MSVC2013-NOT: define weak_odr dllexport 
{{.+}}ACE_Service_Object@@Q{{.+}}

Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-04-28 Thread Andrew V. Tischenko via cfe-commits
avt77 added inline comments.


Comment at: test/SemaCXX/dllimport.cpp:179
@@ -140,1 +178,3 @@
+template 
+int ExternVarTmplDeclInit = 1;
 

majnemer wrote:
> avt77 wrote:
> > rnk wrote:
> > > Can you check with MSVC 2015 update 2 actually does with definitions of 
> > > dllimport variable templates? I bet it doesn't export them.
> > They don't support variable templates at all:
> > 
> > error C2399: variable templates are not supported in this release
> Your compiler is too old, they are definitely supported.
> 
> > Previously a template declaration was only allowed to be a function, class, 
> > or alias. Now, in the MSVC compiler it can be a variable as well.
> 
> https://blogs.msdn.microsoft.com/vcblog/2016/02/11/compiler-improvements-in-vs-2015-update-2/
OK, I updated several additional components and now CL supports variable 
templates. I checked the issue again and got the following:

C:\_bugs>cl -c  t1.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23918 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

t1.cpp
t1.cpp(8): warning C4273: 'ExternVarTmplDeclInit': inconsistent dll linkage
t1.cpp(2): note: see previous definition of 'ExternVarTmplDeclInit'

C:\_bugs>dumpbin /directives t1.obj
Microsoft (R) COFF/PE Dumper Version 14.00.23918.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file t1.obj

File Type: COFF OBJECT

   Linker Directives
   -
   /DEFAULTLIB:LIBCMT
   /DEFAULTLIB:OLDNAMES
   /EXPORT:??$ExternVarTmplDeclInit@H@@3HA,DATA//

As you see they produce warning and change the export attribute. I suppose 
Clang should do the same, right?


Comment at: test/SemaCXX/dllimport.cpp:1137
@@ -1017,1 +1136,3 @@
+template 
+void ImportClassTmplMembers::normalDef() {}
 #ifdef GNU

avt77 wrote:
> rnk wrote:
> > I'm pretty sure MSVC considers all free function templates to be 'inline', 
> > i.e. they put them in comdats. I doubt MSVC exports these. Can you verify 
> > what it does?
> They prohibit such a definition in the latest MSVC: 
> 
> error C2491: 'ImportClassTmplMembers::normalDef': definition of dllimport 
> function not allowed
> 
> The same error I see for other definitions as well
With the latest compiler they disallow the definition of dllimport functions as 
well. I suppose Clang should do the same, right?


http://reviews.llvm.org/D18953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-04-26 Thread Andrew V. Tischenko via cfe-commits
avt77 added a comment.

It seems the latest MSVC changed the support of several features covering in 
this patch: more investigations needed.



Comment at: test/SemaCXX/dllimport.cpp:179
@@ -140,1 +178,3 @@
+template 
+int ExternVarTmplDeclInit = 1;
 

rnk wrote:
> Can you check with MSVC 2015 update 2 actually does with definitions of 
> dllimport variable templates? I bet it doesn't export them.
They don't support variable templates at all:

error C2399: variable templates are not supported in this release


Comment at: test/SemaCXX/dllimport.cpp:1137
@@ -1017,1 +1136,3 @@
+template 
+void ImportClassTmplMembers::normalDef() {}
 #ifdef GNU

rnk wrote:
> I'm pretty sure MSVC considers all free function templates to be 'inline', 
> i.e. they put them in comdats. I doubt MSVC exports these. Can you verify 
> what it does?
They prohibit such a definition in the latest MSVC: 

error C2491: 'ImportClassTmplMembers::normalDef': definition of dllimport 
function not allowed

The same error I see for other definitions as well


http://reviews.llvm.org/D18953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-04-26 Thread Andrew V. Tischenko via cfe-commits
avt77 added a comment.

In fact you introduced the plan of actions to fix the issue. Tnx.


http://reviews.llvm.org/D18953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19156: [ms][dll] #27212: Generating of implicit special members should take into account MSVC compatibility version

2016-04-26 Thread Andrew V. Tischenko via cfe-commits
avt77 added a comment.

It seems it will be even shorter if we do it via 
Sema::checkClassLevelDLLAttribute. Tnx.


http://reviews.llvm.org/D19156



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D19479: 26748 - clang-cl fails to compile atlctrlw.h header from WTL

2016-04-26 Thread Andrew V. Tischenko via cfe-commits
avt77 added a comment.

OK, I'll try to implement something like a DependentScopeDeclRefExpr but 
because of the latest changes in Intel I'm afraid it will take some more time 
from me.


http://reviews.llvm.org/D19479



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D19479: 26748 - clang-cl fails to compile atlctrlw.h header from WTL

2016-04-25 Thread Andrew V. Tischenko via cfe-commits
avt77 created this revision.
avt77 added a reviewer: rnk.
avt77 added a subscriber: cfe-commits.

This is the first patch to fix clang-cl incompatibility prohibited to compile 
the header file. The patch covers the following case:

class CCommandBarCtrlBase {
public:
  typedef int CMsgHookMap;
};

template 
class CCommandBarCtrlImpl : public T {
public:
  void foo() {
void *p = new CMsgHookMap; // "new typename T::CMsgHookMap" works fine
  }
};

void bar() {
  CCommandBarCtrlImpl x;
  x.foo();
}

http://reviews.llvm.org/D19479

Files:
  include/clang/Sema/Sema.h
  lib/Parse/ParseDecl.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaLookup.cpp
  test/Sema/dtp-lookup-in-base-classes.cpp

Index: lib/Parse/ParseDecl.cpp
===
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -2995,6 +2995,27 @@
 TypeRep = Actions.ActOnDelayedDefaultTemplateArg(
 *Tok.getIdentifierInfo(), Tok.getLocation());
   }
+  if (!TypeRep && DSContext == DSC_type_specifier &&
+  Actions.CurContext->isDependentContext() &&
+  getLangOpts().MSVCCompat) {
+IdentifierInfo *II = Tok.getIdentifierInfo();
+Actions.DiagnoseUnknownTypeName(II, Tok.getLocation(), getCurScope(),
+nullptr, TypeRep, true);
+if (TypeRep) {
+  // The action has suggested that the type TypeRep could be used.
+  // Set that as the type in the declaration specifiers,
+  // consume the would-be type name token, and we're done.
+  const char *PrevSpec;
+  unsigned DiagID;
+  DS.SetTypeSpecType(DeclSpec::TST_typename, Tok.getLocation(),
+ PrevSpec, DiagID, TypeRep,
+ Actions.getASTContext().getPrintingPolicy());
+  DS.SetRangeEnd(Tok.getLocation());
+  ConsumeToken();
+  // There may be other declaration specifiers after this.
+  continue;
+}
+  }
 
   // If this is not a typedef name, don't parse it as part of the declspec,
   // it must be an implicit int or an error.
Index: lib/Sema/SemaLookup.cpp
===
--- lib/Sema/SemaLookup.cpp
+++ lib/Sema/SemaLookup.cpp
@@ -4437,13 +4437,6 @@
   DisableTypoCorrection)
 return nullptr;
 
-  // In Microsoft mode, don't perform typo correction in a template member
-  // function dependent context because it interferes with the "lookup into
-  // dependent bases of class templates" feature.
-  if (getLangOpts().MSVCCompat && CurContext->isDependentContext() &&
-  isa(CurContext))
-return nullptr;
-
   // We only attempt to correct typos for identifiers.
   IdentifierInfo *Typo = TypoName.getName().getAsIdentifierInfo();
   if (!Typo)
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -207,9 +207,15 @@
 if (RD && RD->getDescribedClassTemplate())
   FoundTypeDecl = lookupUnqualifiedTypeNameInBase(S, II, NameLoc, RD);
   }
-  if (FoundTypeDecl != UnqualifiedTypeNameLookupResult::FoundType)
-return nullptr;
-
+  if (FoundTypeDecl != UnqualifiedTypeNameLookupResult::FoundType) {
+ParsedType Result = nullptr;
+if (S.getLangOpts().MSVCCompat && S.CurContext->isDependentContext()) {
+  auto *II2 = const_cast(&II);
+  S.DiagnoseUnknownTypeName(II2, NameLoc, S.getCurScope(), nullptr, Result,
+false, true);
+}
+return Result;
+  }
   // We found some types in dependent base classes.  Recover as if the user
   // wrote 'typename MyClass::II' instead of 'II'.  We'll fully resolve the
   // lookup during template instantiation.
@@ -553,31 +559,31 @@
   return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
 }
 
-void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
-   SourceLocation IILoc,
-   Scope *S,
-   CXXScopeSpec *SS,
+void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc,
+   Scope *S, CXXScopeSpec *SS,
ParsedType &SuggestedType,
-   bool AllowClassTemplates) {
+   bool AllowClassTemplates,
+   bool AllowInvalid) {
   // We don't have anything to suggest (yet).
   SuggestedType = nullptr;
 
   // There may have been a typo in the name of the type. Look up typo
   // results, in case we have something that we can suggest.
   if (TypoCorrection Corrected =
   CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS,
   llvm::make_unique(
-  false, false, AllowClassTemplates),
+  AllowInvali

Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-04-15 Thread Andrew V. Tischenko via cfe-commits
avt77 changed the visibility of this Differential Revision from "All Users" to 
"Public (No Login Required)".
avt77 updated this revision to Diff 53870.
avt77 added a comment.

I fixed all issues discovered by Richard and Reid. As result the tests were 
updated as well. Please, review again.


http://reviews.llvm.org/D18953

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/CodeGen/dllimport.c
  test/CodeGenCXX/dllimport-members.cpp
  test/CodeGenCXX/dllimport.cpp
  test/Sema/dllimport.c
  test/SemaCXX/dllimport.cpp

Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -5505,9 +5505,13 @@
 
 static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
NamedDecl *NewDecl,
-   bool IsSpecialization) {
-  if (TemplateDecl *OldTD = dyn_cast(OldDecl))
+   bool IsSpecialization,
+   bool IsDefinition) {
+  if (TemplateDecl *OldTD = dyn_cast(OldDecl)) {
 OldDecl = OldTD->getTemplatedDecl();
+if (!IsSpecialization)
+  IsDefinition = false;
+  }
   if (TemplateDecl *NewTD = dyn_cast(NewDecl))
 NewDecl = NewTD->getTemplatedDecl();
 
@@ -5563,30 +5567,43 @@
 
   // A redeclaration is not allowed to drop a dllimport attribute, the only
   // exceptions being inline function definitions, local extern declarations,
-  // and qualified friend declarations.
-  // NB: MSVC converts such a declaration to dllexport.
+  // qualified friend declarations or special MSVC extension: in the last case,
+  // the declaration is treated as if it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  if (const auto *VD = dyn_cast(NewDecl))
+  bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+  if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.
 IsStaticDataMember = VD->isStaticDataMember();
-  else if (const auto *FD = dyn_cast(NewDecl)) {
+IsDefinition = !VD->isThisDeclarationADefinition(S.Context) ==
+   VarDecl::DeclarationOnly;
+  } else if (const auto *FD = dyn_cast(NewDecl)) {
 IsInline = FD->isInlined();
 IsQualifiedFriend = FD->getQualifier() &&
 FD->getFriendObjectKind() == Decl::FOK_Declared;
   }
 
   if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember &&
   !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {
-S.Diag(NewDecl->getLocation(),
-   diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-  << NewDecl << OldImportAttr;
-S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
-S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
-OldDecl->dropAttr();
-NewDecl->dropAttr();
-  } else if (IsInline && OldImportAttr &&
- !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+if (IsMicrosoft && IsDefinition) {
+  S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_import_attribute)
+  << NewDecl;
+  S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+  NewDecl->dropAttr();
+  NewDecl->addAttr(::new (S.Context) DLLExportAttr(
+  NewImportAttr->getRange(), S.Context,
+  NewImportAttr->getSpellingListIndex()));
+} else {
+  S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
+  << NewDecl << OldImportAttr;
+  S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+  S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
+  OldDecl->dropAttr();
+  NewDecl->dropAttr();
+}
+  } else if (IsInline && OldImportAttr && !IsMicrosoft) {
 // In MinGW, seeing a function declared inline drops the dllimport attribute.
 OldDecl->dropAttr();
 NewDecl->dropAttr();
@@ -6370,7 +6387,7 @@
   if (D.isRedeclaration() && !Previous.empty()) {
 checkDLLAttributeRedeclaration(
 *this, dyn_cast(Previous.getRepresentativeDecl()), NewVD,
-IsExplicitSpecialization);
+IsExplicitSpecialization, D.isFunctionDefinition());
   }
 
   if (NewTemplate) {
@@ -8369,7 +8386,8 @@
   if (D.isRedeclaration() && !Previous.empty()) {
 checkDLLAttributeRedeclaration(
 *this, dyn_cast(Previous.getRepresentativeDecl()), NewFD,
-isExplicitSpecialization || isFunctionTemplateSpecialization);
+isExplicitSpecialization || isFunctionTemplateSpecialization,
+D.isFunctionDefinition());
   }
 
   if (getLangOpts().CUDA) {
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/Diagnost

[PATCH] D19156: [ms][dll] #27212: Generating of implicit special members should take into account MSVC compatibility version

2016-04-15 Thread Andrew V. Tischenko via cfe-commits
avt77 created this revision.
avt77 added a reviewer: rnk.
avt77 added a subscriber: cfe-commits.

Clang creates implicit move constructor/assign operator in all cases if there 
is std=c++11. But MSVC supports such generation starting from version 1900 
only. As result we have some binary incompatibility.

http://reviews.llvm.org/D19156

Files:
  lib/Sema/SemaDeclCXX.cpp
  test/CodeGenCXX/dllexport.cpp

Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -10549,6 +10549,9 @@
 }
 
 CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+  !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
+return nullptr; // It's not supported before MSVC2015
   assert(ClassDecl->needsImplicitMoveAssignment());
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveAssignment);
@@ -11162,6 +11165,9 @@
 
 CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
 CXXRecordDecl *ClassDecl) {
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+  !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
+return nullptr; // It's not supported before MSVC2015
   assert(ClassDecl->needsImplicitMoveConstructor());
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveConstructor);
Index: test/CodeGenCXX/dllexport.cpp
===
--- test/CodeGenCXX/dllexport.cpp
+++ test/CodeGenCXX/dllexport.cpp
@@ -1,5 +1,9 @@
-// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases 
-disable-llvm-optzns -o - %s -w | FileCheck --check-prefix=MSC 
--check-prefix=M32 %s
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck 
--check-prefix=MSC --check-prefix=M64 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases 
-disable-llvm-optzns -o - %s -w -fms-compatibility-version=19.00 | FileCheck 
--check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2015 %s
+// RUN: %clang_cc1 -triple i686-windows-msvc   -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases 
-disable-llvm-optzns -o - %s -w -fms-compatibility-version=18.00 | FileCheck 
--check-prefix=MSC --check-prefix=M32 -check-prefix=MSVC2013 %s
+
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w 
-fms-compatibility-version=19.00 | FileCheck --check-prefix=MSC 
--check-prefix=M64 -check-prefix=MSVC2015 %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w 
-fms-compatibility-version=18.00 | FileCheck --check-prefix=MSC 
--check-prefix=M64 -check-prefix=MSVC2013 %s
+
 // RUN: %clang_cc1 -triple i686-windows-gnu-emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck 
--check-prefix=GNU --check-prefix=G32 %s
 // RUN: %clang_cc1 -triple x86_64-windows-gnu  -emit-llvm -std=c++1y 
-fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck 
--check-prefix=GNU --check-prefix=G64 %s
 
@@ -528,6 +532,8 @@
   SomeTemplate(T o = T()) : o(o) {}
   T o;
 };
+// MSVC2015-DAG: define weak_odr dllexport {{.+}} 
@"\01??4?$SomeTemplate@H@@Q{{.+}}@$$Q{{.+}}@@Z"
+// MSVC2013-DAG: define weak_odr dllexport {{.+}} 
@"\01??4?$SomeTemplate@H@@Q{{.+}}0@A{{.+}}0@@Z"
 struct __declspec(dllexport) InheritFromTemplate : SomeTemplate {};
 
 // M32-DAG: define weak_odr dllexport x86_thiscallcc void 
@"\01??_F?$SomeTemplate@H@@QAEXXZ"({{.*}}) comdat
@@ -592,7 +598,8 @@
 
 struct __declspec(dllexport) Y {
   // Move assignment operator:
-  // M32-DAG: define weak_odr dllexport x86_thiscallcc 
dereferenceable({{[0-9]+}}) %struct.Y* @"\01??4Y@@QAEAAU0@$$QAU0@@Z"
+  // MSVC2015-DAG: define weak_odr dllexport {{.+}} 
@"\01??4Y@@Q{{.+}}@$$Q{{.+}}@@Z"
+  // MSVC2013-DAG: define weak_odr dllexport {{.+}} 
@"\01??4Y@@Q{{.+}}0@A{{.+}}0@@Z"
 
   int x;
 };


Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -10549,6 +10549,9 @@
 }
 
 CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+  !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
+return nullptr; // It's not supported before MSVC2015
   assert(ClassDecl->needsImplicitMoveAssignment());
 
   DeclaringSpecialMember DSM(*this, ClassDecl, CXXMoveAssignment);
@@ -11162,6 +11165,9 @@
 
 CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
  

Re: [PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-04-12 Thread Andrew V. Tischenko via cfe-commits
avt77 marked an inline comment as done.


Comment at: lib/Sema/SemaDecl.cpp:5570
@@ -5565,3 +5569,3 @@
   // and qualified friend declarations.
-  // NB: MSVC converts such a declaration to dllexport.
+  // NB: MSVC converts such a declaration to dllexport that's why we do it 
also.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;

rsmith wrote:
> Just describe this as the semantics of this situation rather than suggesting 
> this is some MSVC oddity we're emulating. "In such a case, the declaration is 
> treated as if it were marked dllexport." or similar.
> 
> It also seems bizarre for this behavior to apply for local extern 
> declarations and qualified friend declarations. Does the "dllimport gets 
> turned into dllexport" behavior actually only apply to the definition case? 
> And does the definition need to be inline?
Yes, I see "dllimport gets turned into dllexport" for definitions only. 
No, the definition should not be inline: 
   if (OldImportAttr && !HasNewAttr && **!IsInline**


Comment at: lib/Sema/SemaDecl.cpp:5595
@@ +5594,3 @@
+  // Replace DLLImportAttr with DLLExportAttr
+  OldDecl->dropAttr();
+  NewDecl->dropAttr();

rsmith wrote:
> Don't change attributes on a prior declaration; AST nodes should generally be 
> immutable once created (this would lose source fidelity, and break under 
> PCH/modules). Instead, make sure that anyone who looks at this gets the 
> attribute from the appropriate (most recent) declaration and only change the 
> attributes there.
 I don't understand how I could "make sure that anyone...". Please, clarify. 


Comment at: lib/Sema/SemaDecl.cpp:5596
@@ +5595,3 @@
+  OldDecl->dropAttr();
+  NewDecl->dropAttr();
+  OldDecl->addAttr(::new (S.Context) DLLExportAttr(

rsmith wrote:
> Is this really valid and treated as `__dllexport` if the new declaration 
> explicitly specifies `__dllimport` (rather than inheriting it)?
The new declaration does not have explicitly specified __dllimport attribute: 
if (OldImportAttr && **!HasNewAttr**. It's inherited.


Comment at: lib/Sema/SemaDecl.cpp:5600-5602
@@ +5599,5 @@
+  OldImportAttr->getSpellingListIndex()));
+  NewDecl->addAttr(::new (S.Context) DLLExportAttr(
+  NewImportAttr->getRange(), S.Context,
+  NewImportAttr->getSpellingListIndex()));
+} else {

rsmith wrote:
> The new attribute should be marked implicit.
What do you mean? Please, clarify.


http://reviews.llvm.org/D18953



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D18953: [ms][dll] #26935 Defining a dllimport function should cause it to be exported

2016-04-11 Thread Andrew V. Tischenko via cfe-commits
avt77 created this revision.
avt77 added a reviewer: rnk.
avt77 added a subscriber: cfe-commits.
avt77 changed the visibility of this Differential Revision from "Public (No 
Login Required)" to "All Users".

If we have some function with dllimport attribute and then we have the function 
definition in the same module but without dllimport attribute we should add 
dllexport attribute to this function definition. The same should be done for 
variables. Example:

struct __declspec(dllimport) C3 {
   ~C3();
};

C3::~C3() {;} // we should export this definition

http://reviews.llvm.org/D18953

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/CodeGen/dllimport.c
  test/CodeGenCXX/dllimport-members.cpp
  test/CodeGenCXX/dllimport.cpp
  test/Sema/dllimport.c
  test/SemaCXX/dllimport.cpp

Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -5504,9 +5504,13 @@
 
 static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
NamedDecl *NewDecl,
-   bool IsSpecialization) {
-  if (TemplateDecl *OldTD = dyn_cast(OldDecl))
+   bool IsSpecialization,
+   bool IsDefinition = false) {
+  if (TemplateDecl *OldTD = dyn_cast(OldDecl)) {
 OldDecl = OldTD->getTemplatedDecl();
+if (!IsSpecialization)
+  IsDefinition = false;
+  }
   if (TemplateDecl *NewTD = dyn_cast(NewDecl))
 NewDecl = NewTD->getTemplatedDecl();
 
@@ -5563,29 +5567,49 @@
   // A redeclaration is not allowed to drop a dllimport attribute, the only
   // exceptions being inline function definitions, local extern declarations,
   // and qualified friend declarations.
-  // NB: MSVC converts such a declaration to dllexport.
+  // NB: MSVC converts such a declaration to dllexport that's why we do it also.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  if (const auto *VD = dyn_cast(NewDecl))
+  bool isMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+  if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.
 IsStaticDataMember = VD->isStaticDataMember();
+IsDefinition =
+  !VD->isThisDeclarationADefinition(S.Context) == VarDecl::DeclarationOnly;
+  }
   else if (const auto *FD = dyn_cast(NewDecl)) {
 IsInline = FD->isInlined();
 IsQualifiedFriend = FD->getQualifier() &&
 FD->getFriendObjectKind() == Decl::FOK_Declared;
   }
 
   if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember &&
   !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {
-S.Diag(NewDecl->getLocation(),
-   diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-  << NewDecl << OldImportAttr;
-S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
-S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
-OldDecl->dropAttr();
-NewDecl->dropAttr();
-  } else if (IsInline && OldImportAttr &&
- !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+if (isMicrosoft && IsDefinition) {
+  S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_import_attribute) << NewDecl;
+  S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+  S.Diag(OldImportAttr->getLocation(),
+ diag::note_previous_attribute_replaced);
+  // Replace DLLImportAttr with DLLExportAttr
+  OldDecl->dropAttr();
+  NewDecl->dropAttr();
+  OldDecl->addAttr(::new (S.Context) DLLExportAttr(
+  OldImportAttr->getRange(), S.Context,
+  OldImportAttr->getSpellingListIndex()));
+  NewDecl->addAttr(::new (S.Context) DLLExportAttr(
+  NewImportAttr->getRange(), S.Context,
+  NewImportAttr->getSpellingListIndex()));
+} else {
+  S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
+  << NewDecl << OldImportAttr;
+  S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+  S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
+  OldDecl->dropAttr();
+  NewDecl->dropAttr();
+}
+  } else if (IsInline && OldImportAttr && !isMicrosoft) {
 // In MinGW, seeing a function declared inline drops the dllimport attribute.
 OldDecl->dropAttr();
 NewDecl->dropAttr();
@@ -6369,7 +6393,8 @@
   if (D.isRedeclaration() && !Previous.empty()) {
 checkDLLAttributeRedeclaration(
 *this, dyn_cast(Previous.getRepresentativeDecl()), NewVD,
-IsExplicitSpecialization);
+IsExplicitSpecialization,
+D.isFunctionDefinition());
   }
 
   if (NewTemplate) {
@@ -8368,7 +8393,8 @@
   if (D.isRedeclaration() && !Prev