From b2dba4bc0eee144baa60e36599a0887496d1295e Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Mon, 2 May 2011 19:24:53 +0000 Subject: [PATCH] When using -std= flag added check to make sure language and standard are compatable git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130710 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/LangStandard.h | 20 ++++++++------ include/clang/Frontend/LangStandards.def | 11 ++++---- lib/Frontend/CompilerInvocation.cpp | 34 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h index 74ca5191dd..ea37bdd102 100644 --- a/include/clang/Frontend/LangStandard.h +++ b/include/clang/Frontend/LangStandard.h @@ -18,14 +18,15 @@ namespace frontend { enum LangFeatures { BCPLComment = (1 << 0), - C99 = (1 << 1), - C1X = (1 << 2), - CPlusPlus = (1 << 3), - CPlusPlus0x = (1 << 4), - Digraphs = (1 << 5), - GNUMode = (1 << 6), - HexFloat = (1 << 7), - ImplicitInt = (1 << 8) + C89 = (1 << 1), + C99 = (1 << 2), + C1X = (1 << 3), + CPlusPlus = (1 << 4), + CPlusPlus0x = (1 << 5), + Digraphs = (1 << 6), + GNUMode = (1 << 7), + HexFloat = (1 << 8), + ImplicitInt = (1 << 9) }; } @@ -54,6 +55,9 @@ public: /// hasBCPLComments - Language supports '//' comments. bool hasBCPLComments() const { return Flags & frontend::BCPLComment; } + /// isC89 - Language is a superset of C89. + bool isC89() const { return Flags & frontend::C89; } + /// isC99 - Language is a superset of C99. bool isC99() const { return Flags & frontend::C99; } diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def index 586e5c8fa2..6055ad5182 100644 --- a/include/clang/Frontend/LangStandards.def +++ b/include/clang/Frontend/LangStandards.def @@ -22,21 +22,21 @@ // C89-ish modes. LANGSTANDARD(c89, "c89", "ISO C 1990", - ImplicitInt) + C89 | ImplicitInt) LANGSTANDARD(c90, "c90", "ISO C 1990", - ImplicitInt) + C89 | ImplicitInt) LANGSTANDARD(iso9899_1990, "iso9899:1990", "ISO C 1990", - ImplicitInt) + C89 | ImplicitInt) LANGSTANDARD(c94, "iso9899:199409", "ISO C 1990 with amendment 1", - Digraphs | ImplicitInt) + C89 | Digraphs | ImplicitInt) LANGSTANDARD(gnu89, "gnu89", "ISO C 1990 with GNU extensions", - BCPLComment | Digraphs | GNUMode | ImplicitInt) + BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt) // C99-ish modes LANGSTANDARD(c99, "c99", @@ -87,7 +87,6 @@ LANGSTANDARD(gnucxx0x, "gnu++0x", BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) // OpenCL - LANGSTANDARD(opencl, "cl", "OpenCL 1.0", BCPLComment | C99 | Digraphs | HexFloat) diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 1d4cd15ac4..b84e4c82b3 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1397,6 +1397,40 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, if (LangStd == LangStandard::lang_unspecified) Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue(Args); + else { + // Valid standard, check to make sure language and standard are compatable. + const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); + switch (IK) { + case IK_C: + case IK_ObjC: + case IK_PreprocessedC: + case IK_PreprocessedObjC: + if (!(Std.isC89() || Std.isC99())) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "C/ObjC"; + break; + case IK_CXX: + case IK_ObjCXX: + case IK_PreprocessedCXX: + case IK_PreprocessedObjCXX: + if (!Std.isCPlusPlus()) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "C++/ObjC++"; + break; + case IK_OpenCL: + if (!Std.isC99()) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "OpenCL"; + break; + case IK_CUDA: + if (!Std.isCPlusPlus()) + Diags.Report(diag::err_drv_argument_not_allowed_with) + << A->getAsString(Args) << "CUDA"; + break; + default: + break; + } + } } if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {