diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 82f7094a2a6d..e7f90ee29a39 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -50,6 +50,7 @@ LANGOPT(Borland , 1, 0, "Borland extensions") LANGOPT(CPlusPlus , 1, 0, "C++") LANGOPT(CPlusPlus11 , 1, 0, "C++11") LANGOPT(CPlusPlus1y , 1, 0, "C++1y") +LANGOPT(CPlusPlus1z , 1, 0, "C++1z") LANGOPT(ObjC1 , 1, 0, "Objective-C 1") LANGOPT(ObjC2 , 1, 0, "Objective-C 2") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, diff --git a/clang/include/clang/Frontend/LangStandard.h b/clang/include/clang/Frontend/LangStandard.h index 1124d53eafd5..9680e1f2e04c 100644 --- a/clang/include/clang/Frontend/LangStandard.h +++ b/clang/include/clang/Frontend/LangStandard.h @@ -25,10 +25,11 @@ enum LangFeatures { CPlusPlus = (1 << 4), CPlusPlus11 = (1 << 5), CPlusPlus1y = (1 << 6), - Digraphs = (1 << 7), - GNUMode = (1 << 8), - HexFloat = (1 << 9), - ImplicitInt = (1 << 10) + CPlusPlus1z = (1 << 7), + Digraphs = (1 << 8), + GNUMode = (1 << 9), + HexFloat = (1 << 10), + ImplicitInt = (1 << 11) }; } @@ -69,12 +70,15 @@ public: /// isCPlusPlus - Language is a C++ variant. bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; } - /// isCPlusPlus11 - Language is a C++0x variant. + /// isCPlusPlus11 - Language is a C++11 variant (or later). bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; } - /// isCPlusPlus1y - Language is a C++1y variant. + /// isCPlusPlus1y - Language is a C++14 variant (or later). bool isCPlusPlus1y() const { return Flags & frontend::CPlusPlus1y; } + /// isCPlusPlus1z - Language is a C++17 variant (or later). + bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; } + /// hasDigraphs - Language supports digraphs. bool hasDigraphs() const { return Flags & frontend::Digraphs; } diff --git a/clang/include/clang/Frontend/LangStandards.def b/clang/include/clang/Frontend/LangStandards.def index 7b2516b0e3ef..da9a11849967 100644 --- a/clang/include/clang/Frontend/LangStandards.def +++ b/clang/include/clang/Frontend/LangStandards.def @@ -115,6 +115,15 @@ LANGSTANDARD(gnucxx1y, "gnu++1y", LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | Digraphs | GNUMode) +LANGSTANDARD(cxx1z, "c++1z", + "Working draft for ISO C++ 2017", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z | + Digraphs) +LANGSTANDARD(gnucxx1z, "gnu++1z", + "Working draft for ISO C++ 2017 with GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus1y | CPlusPlus1z | + Digraphs | GNUMode) + // OpenCL LANGSTANDARD(opencl, "cl", "OpenCL 1.0", diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 68c7176a5f25..d0cf8a3301bf 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1135,6 +1135,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CPlusPlus = Std.isCPlusPlus(); Opts.CPlusPlus11 = Std.isCPlusPlus11(); Opts.CPlusPlus1y = Std.isCPlusPlus1y(); + Opts.CPlusPlus1z = Std.isCPlusPlus1z(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Std.isC99(); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index dbb59b4f9f1f..d4943e736599 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -315,10 +315,13 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, else if (!LangOpts.GNUMode && LangOpts.Digraphs) Builder.defineMacro("__STDC_VERSION__", "199409L"); } else { + // FIXME: Use correct value for C++17. + if (LangOpts.CPlusPlus1z) + Builder.defineMacro("__cplusplus", "201406L"); // C++1y [cpp.predefined]p1: // The name __cplusplus is defined to the value 201402L when compiling a // C++ translation unit. - if (LangOpts.CPlusPlus1y) + else if (LangOpts.CPlusPlus1y) Builder.defineMacro("__cplusplus", "201402L"); // C++11 [cpp.predefined]p1: // The name __cplusplus is defined to the value 201103L when compiling a diff --git a/clang/test/Driver/std.cpp b/clang/test/Driver/std.cpp index e98fd2c6bf18..aceda017a4e1 100644 --- a/clang/test/Driver/std.cpp +++ b/clang/test/Driver/std.cpp @@ -7,6 +7,8 @@ // RUN: not %clang -std=gnu++11 %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX11 %s // RUN: not %clang -std=c++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Y %s // RUN: not %clang -std=gnu++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Y %s +// RUN: not %clang -std=c++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Z %s +// RUN: not %clang -std=gnu++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Z %s void f(int n) { typeof(n)(); @@ -30,3 +32,9 @@ void f(int n) { // GNUXX1Y-NOT: undeclared identifier 'typeof' // GNUXX1Y-NOT: undeclared identifier 'decltype' + +// CXX1Z: undeclared identifier 'typeof' +// CXX1Z-NOT: undeclared identifier 'decltype' + +// GNUXX1Z-NOT: undeclared identifier 'typeof' +// GNUXX1Z-NOT: undeclared identifier 'decltype' diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index 2c5b736544ab..ed0885429527 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -9,6 +9,16 @@ // BLOCKS:#define __block __attribute__((__blocks__(byref))) // // +// RUN: %clang_cc1 -x c++ -std=c++1z -E -dM < /dev/null | FileCheck -check-prefix CXX1Z %s +// +// CXX1Z:#define __GNUG__ +// CXX1Z:#define __GXX_EXPERIMENTAL_CXX0X__ 1 +// CXX1Z:#define __GXX_RTTI 1 +// CXX1Z:#define __GXX_WEAK__ 1 +// CXX1Z:#define __cplusplus 201406L +// CXX1Z:#define __private_extern__ extern +// +// // RUN: %clang_cc1 -x c++ -std=c++1y -E -dM < /dev/null | FileCheck -check-prefix CXX1Y %s // // CXX1Y:#define __GNUG__ @@ -85,6 +95,14 @@ // FREESTANDING:#define __STDC_HOSTED__ 0 // // +// RUN: %clang_cc1 -x c++ -std=gnu++1z -E -dM < /dev/null | FileCheck -check-prefix GXX1Z %s +// +// GXX1Z:#define __GNUG__ +// GXX1Z:#define __GXX_WEAK__ 1 +// GXX1Z:#define __cplusplus 201406L +// GXX1Z:#define __private_extern__ extern +// +// // RUN: %clang_cc1 -x c++ -std=gnu++1y -E -dM < /dev/null | FileCheck -check-prefix GXX1Y %s // // GXX1Y:#define __GNUG__