From: Douglas Gregor Date: Thu, 27 Jan 2011 21:06:28 +0000 (+0000) Subject: Separate the access-control diagnostics from other diagnostics that do not have SFINA... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=418df343bb50802586d20aae3b83e2eb44c6c828;p=clang Separate the access-control diagnostics from other diagnostics that do not have SFINAE behavior. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124441 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index 7cbf3a5117..1ab53b3e91 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define ASTSTART #include "clang/Basic/DiagnosticASTKinds.inc" #undef DIAG diff --git a/include/clang/Analysis/AnalysisDiagnostic.h b/include/clang/Analysis/AnalysisDiagnostic.h index e98a3df472..295d0a2133 100644 --- a/include/clang/Analysis/AnalysisDiagnostic.h +++ b/include/clang/Analysis/AnalysisDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define ANALYSISSTART #include "clang/Basic/DiagnosticAnalysisKinds.inc" #undef DIAG diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td index fabf9ebb44..be510ed844 100644 --- a/include/clang/Basic/Diagnostic.td +++ b/include/clang/Basic/Diagnostic.td @@ -56,6 +56,7 @@ class Diagnostic { string Text = text; DiagClass Class = DC; bit SFINAE = 1; + bit AccessControl = 0; DiagMapping DefaultMapping = defaultmapping; DiagGroup Group; string CategoryName = ""; @@ -74,6 +75,7 @@ class DefaultError { DiagMapping DefaultMapping = MAP_ERROR; } class DefaultFatal { DiagMapping DefaultMapping = MAP_FATAL; } class NoSFINAE { bit SFINAE = 0; } +class AccessControl { bit AccessControl = 1; } // Definitions for Diagnostics. include "DiagnosticASTKinds.td" diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 9d18b0f9e9..5d84c7c887 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -42,7 +42,7 @@ namespace clang { // Get typedefs for common diagnostics. enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #include "clang/Basic/DiagnosticCommonKinds.inc" NUM_BUILTIN_COMMON_DIAGNOSTICS #undef DIAG @@ -157,7 +157,11 @@ public: /// /// The diagnostic should be reported. Various fatal errors (e.g., /// template instantiation depth exceeded) fall into this category. - SFINAE_Report + SFINAE_Report, + + /// \brief The diagnostic is an access-control diagnostic, which will be + /// substitution failures in some contexts and reported in others. + SFINAE_AccessControl }; /// \brief Determines whether the given built-in diagnostic ID is diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 17bbc68afb..7bec4c73da 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -541,65 +541,67 @@ def warn_missing_exception_specification : Warning< def err_class_redeclared_with_different_access : Error< "%0 redeclared with '%1' access">; def err_access : Error< - "%1 is a %select{private|protected}0 member of %3">, NoSFINAE; + "%1 is a %select{private|protected}0 member of %3">, AccessControl; def err_access_ctor : Error< - "calling a %select{private|protected}0 constructor of class %2">, NoSFINAE; + "calling a %select{private|protected}0 constructor of class %2">, + AccessControl; def ext_rvalue_to_reference_access_ctor : ExtWarn< "C++98 requires an accessible copy constructor for class %2 when binding " "a reference to a temporary; was %select{private|protected}0">, - NoSFINAE, InGroup; + AccessControl, InGroup; def err_access_base : Error< "%select{base class|inherited virtual base class}0 %1 has %select{private|" "protected}3 %select{constructor|copy constructor|copy assignment operator|" - "destructor}2">, NoSFINAE; + "destructor}2">, AccessControl; def err_access_field: Error< "field of type %0 has %select{private|protected}2 %select{constructor|copy " - "constructor|copy assignment operator|destructor}1">, NoSFINAE; + "constructor|copy assignment operator|destructor}1">, AccessControl; def err_access_ctor_field : Error<"field of type %1 has %select{private|protected}2 constructor">, - NoSFINAE; + AccessControl; def err_access_dtor_base : Error<"base class %0 has %select{private|protected}1 destructor">, - NoSFINAE; + AccessControl; def err_access_dtor_vbase : Error<"inherited virtual base class %0 has " "%select{private|protected}1 destructor">, - NoSFINAE; + AccessControl; def err_access_dtor_temp : Error<"temporary of type %0 has %select{private|protected}1 destructor">, - NoSFINAE; + AccessControl; def err_access_dtor_exception : Error<"exception object of type %0 has %select{private|protected}1 " - "destructor">, NoSFINAE; + "destructor">, AccessControl; def err_access_dtor_field : Error<"field of type %1 has %select{private|protected}2 destructor">, - NoSFINAE; + AccessControl; def err_access_dtor_var : Error<"variable of type %1 has %select{private|protected}2 destructor">, - NoSFINAE; + AccessControl; def err_access_assign_field : Error<"field of type %1 has %select{private|protected}2 copy assignment" " operator">, - NoSFINAE; + AccessControl; def err_access_assign_base : Error<"base class %0 has %select{private|protected}1 copy assignment" " operator">, - NoSFINAE; + AccessControl; def err_access_copy_field : Error<"field of type %1 has %select{private|protected}2 copy constructor">, - NoSFINAE; + AccessControl; def err_access_copy_base : Error<"base class %0 has %select{private|protected}1 copy constructor">, - NoSFINAE; + AccessControl; def err_access_dtor_ivar : Error<"instance variable of type %0 has %select{private|protected}1 " "destructor">, - NoSFINAE; + AccessControl; def note_previous_access_declaration : Note< "previously declared '%1' here">; def err_access_outside_class : Error< - "access to %select{private|protected}0 member outside any class context">; + "access to %select{private|protected}0 member outside any class context">, + AccessControl; def note_access_natural : Note< "%select{|implicitly }1declared %select{private|protected}0 here">; def note_access_constrained_by_path : Note< @@ -707,7 +709,7 @@ def note_overridden_virtual_function : Note< def err_covariant_return_inaccessible_base : Error< "invalid covariant return for virtual function: %1 is a " - "%select{private|protected}2 base class of %0">, NoSFINAE; + "%select{private|protected}2 base class of %0">, AccessControl; def err_covariant_return_ambiguous_derived_to_base_conv : Error< "return type of virtual function %3 is not covariant with the return type of " "the function it overrides (ambiguous conversion from derived class " @@ -3197,7 +3199,7 @@ def err_memptr_conv_via_virtual : Error< // C++ access control def err_conv_to_inaccessible_base : Error< - "conversion from %0 to inaccessible base class %1">, NoSFINAE; + "conversion from %0 to inaccessible base class %1">, AccessControl; def note_inheritance_specifier_here : Note< "'%0' inheritance specifier here">; def note_inheritance_implicitly_private_here : Note< @@ -3566,9 +3568,9 @@ def warn_ivar_use_hidden : Warning< def error_ivar_use_in_class_method : Error< "instance variable %0 accessed in class method">; def error_private_ivar_access : Error<"instance variable %0 is private">, - NoSFINAE; + AccessControl; def error_protected_ivar_access : Error<"instance variable %0 is protected">, - NoSFINAE; + AccessControl; def warn_maynot_respond : Warning<"%0 may not respond to %1">; def warn_attribute_method_def : Warning< "method attribute can only be specified on method declarations">; diff --git a/include/clang/Driver/DriverDiagnostic.h b/include/clang/Driver/DriverDiagnostic.h index c20d807b58..0733c51027 100644 --- a/include/clang/Driver/DriverDiagnostic.h +++ b/include/clang/Driver/DriverDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define DRIVERSTART #include "clang/Basic/DiagnosticDriverKinds.inc" #undef DIAG diff --git a/include/clang/Frontend/FrontendDiagnostic.h b/include/clang/Frontend/FrontendDiagnostic.h index 61ad22cabb..2efbc818de 100644 --- a/include/clang/Frontend/FrontendDiagnostic.h +++ b/include/clang/Frontend/FrontendDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define FRONTENDSTART #include "clang/Basic/DiagnosticFrontendKinds.inc" #undef DIAG diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h index 2d941e4cf4..5fcb8eb2d1 100644 --- a/include/clang/Lex/LexDiagnostic.h +++ b/include/clang/Lex/LexDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define LEXSTART #include "clang/Basic/DiagnosticLexKinds.inc" #undef DIAG diff --git a/include/clang/Parse/ParseDiagnostic.h b/include/clang/Parse/ParseDiagnostic.h index d7c5eee8d9..f640b37c19 100644 --- a/include/clang/Parse/ParseDiagnostic.h +++ b/include/clang/Parse/ParseDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define PARSESTART #include "clang/Basic/DiagnosticParseKinds.inc" #undef DIAG diff --git a/include/clang/Sema/SemaDiagnostic.h b/include/clang/Sema/SemaDiagnostic.h index a5a136427f..ae5aa33db7 100644 --- a/include/clang/Sema/SemaDiagnostic.h +++ b/include/clang/Sema/SemaDiagnostic.h @@ -15,7 +15,7 @@ namespace clang { namespace diag { enum { -#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM, +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM, #define SEMASTART #include "clang/Basic/DiagnosticSemaKinds.inc" #undef DIAG diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp index f4d7047a4b..8efeb6897d 100644 --- a/lib/Basic/DiagnosticIDs.cpp +++ b/lib/Basic/DiagnosticIDs.cpp @@ -42,7 +42,8 @@ struct StaticDiagInfoRec { unsigned short DiagID; unsigned Mapping : 3; unsigned Class : 3; - bool SFINAE : 1; + unsigned SFINAE : 1; + unsigned AccessControl : 1; unsigned Category : 5; const char *Description; @@ -56,8 +57,8 @@ struct StaticDiagInfoRec { } static const StaticDiagInfoRec StaticDiagInfo[] = { -#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE, CATEGORY) \ - { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, CATEGORY, DESC, GROUP }, +#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) \ + { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, CATEGORY, DESC, GROUP }, #include "clang/Basic/DiagnosticCommonKinds.inc" #include "clang/Basic/DiagnosticDriverKinds.inc" #include "clang/Basic/DiagnosticFrontendKinds.inc" @@ -66,7 +67,7 @@ static const StaticDiagInfoRec StaticDiagInfo[] = { #include "clang/Basic/DiagnosticASTKinds.inc" #include "clang/Basic/DiagnosticSemaKinds.inc" #include "clang/Basic/DiagnosticAnalysisKinds.inc" - { 0, 0, 0, 0, 0, 0, 0} + { 0, 0, 0, 0, 0, 0, 0, 0} }; #undef DIAG @@ -92,7 +93,7 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { #endif // Search the diagnostic table with a binary search. - StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0 }; + StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0 }; const StaticDiagInfoRec *Found = std::lower_bound(StaticDiagInfo, StaticDiagInfo + NumDiagEntries, Find); @@ -150,6 +151,9 @@ const char *DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) { DiagnosticIDs::SFINAEResponse DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) { if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID)) { + if (Info->AccessControl) + return SFINAE_AccessControl; + if (!Info->SFINAE) return SFINAE_Report; diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 60cfd47e0f..e37f617549 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -452,10 +452,12 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() { if (TemplateDeductionInfo *Info = SemaRef.isSFINAEContext()) { switch (DiagnosticIDs::getDiagnosticSFINAEResponse(getDiagID())) { + case DiagnosticIDs::SFINAE_AccessControl: case DiagnosticIDs::SFINAE_Report: // Fall through; we'll report the diagnostic below. break; + case DiagnosticIDs::SFINAE_SubstitutionFailure: // Count this failure so that we know that template argument deduction // has failed.