r201927 - Do not add enums to prototype scope in C++ modes.

Peter Collingbourne peter at pcc.me.uk
Fri Feb 21 19:05:49 PST 2014


Author: pcc
Date: Fri Feb 21 21:05:49 2014
New Revision: 201927

URL: http://llvm.org/viewvc/llvm-project?rev=201927&view=rev
Log:
Do not add enums to prototype scope in C++ modes.

The language forbids defining enums in prototypes, so this check is normally
redundant, but if an enum is defined during template instantiation it should
not be added to the prototype scope.

While at it, clean up the code that deals with tag definitions in prototype
scope and expand the visibility warning to cover the case where an anonymous
enum is defined.

Differential Revision: http://llvm-reviews.chandlerc.com/D2742

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/decl-in-prototype.c
    cfe/trunk/test/SemaTemplate/instantiate-enum.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=201927&r1=201926&r2=201927&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 21 21:05:49 2014
@@ -1512,8 +1512,6 @@ public:
   void CheckVariableDeclarationType(VarDecl *NewVD);
   void CheckCompleteVariableDeclaration(VarDecl *var);
   void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
-  void ActOnStartFunctionDeclarator();
-  void ActOnEndFunctionDeclarator();
 
   NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                                      TypeSourceInfo *TInfo,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=201927&r1=201926&r2=201927&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Feb 21 21:05:49 2014
@@ -5069,7 +5069,6 @@ void Parser::ParseFunctionDeclarator(Dec
   ParsedAttributes FnAttrs(AttrFactory);
   TypeResult TrailingReturnType;
 
-  Actions.ActOnStartFunctionDeclarator();
   /* LocalEndLoc is the end location for the local FunctionTypeLoc.
      EndLoc is the end location for the function declarator.
      They differ for trailing return types. */
@@ -5198,8 +5197,6 @@ void Parser::ParseFunctionDeclarator(Dec
                                              StartLoc, LocalEndLoc, D,
                                              TrailingReturnType),
                 FnAttrs, EndLoc);
-
-  Actions.ActOnEndFunctionDeclarator();
 }
 
 /// isFunctionDeclaratorIdentifierList - This parameter list may have an

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=201927&r1=201926&r2=201927&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Feb 21 21:05:49 2014
@@ -1399,15 +1399,6 @@ void Sema::ActOnPopScope(SourceLocation
   }
 }
 
-void Sema::ActOnStartFunctionDeclarator() {
-  ++InFunctionDeclarator;
-}
-
-void Sema::ActOnEndFunctionDeclarator() {
-  assert(InFunctionDeclarator);
-  --InFunctionDeclarator;
-}
-
 /// \brief Look for an Objective-C class in the translation unit.
 ///
 /// \param Id The name of the Objective-C class we're looking for. If
@@ -11071,10 +11062,14 @@ CreateNewDecl:
   if (Attr)
     ProcessDeclAttributeList(S, New, Attr);
 
-  // If we're declaring or defining a tag in function prototype scope
-  // in C, note that this type can only be used within the function.
-  if (Name && S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus)
+  // If we're declaring or defining a tag in function prototype scope in C,
+  // note that this type can only be used within the function and add it to
+  // the list of decls to inject into the function definition scope.
+  if (!getLangOpts().CPlusPlus && (Name || Kind == TTK_Enum) &&
+      getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
     Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+    DeclsInPrototypeScope.push_back(New);
+  }
 
   // Set the lexical context. If the tag has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
@@ -11124,12 +11119,6 @@ CreateNewDecl:
         II->isStr("FILE"))
       Context.setFILEDecl(New);
 
-  // If we were in function prototype scope (and not in C++ mode), add this
-  // tag to the list of decls to inject into the function definition scope.
-  if (S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus &&
-      InFunctionDeclarator && Name)
-    DeclsInPrototypeScope.push_back(New);
-
   if (PrevDecl)
     mergeDeclAttributes(New, PrevDecl);
 
@@ -12952,11 +12941,6 @@ void Sema::ActOnEnumBody(SourceLocation
   Enum->completeDefinition(BestType, BestPromotionType,
                            NumPositiveBits, NumNegativeBits);
 
-  // If we're declaring a function, ensure this decl isn't forgotten about -
-  // it needs to go into the function scope.
-  if (InFunctionDeclarator)
-    DeclsInPrototypeScope.push_back(Enum);
-
   CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
 
   // Now that the enum type is defined, ensure it's not been underaligned.

Modified: cfe/trunk/test/Sema/decl-in-prototype.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/decl-in-prototype.c?rev=201927&r1=201926&r2=201927&view=diff
==============================================================================
--- cfe/trunk/test/Sema/decl-in-prototype.c (original)
+++ cfe/trunk/test/Sema/decl-in-prototype.c Fri Feb 21 21:05:49 2014
@@ -2,11 +2,11 @@
 
 const int AA = 5;
 
-int f1(enum {AA,BB} E) {
+int f1(enum {AA,BB} E) { // expected-warning {{will not be visible outside of this function}}
     return BB;
 }
 
-int f2(enum {AA=7,BB} E) {
+int f2(enum {AA=7,BB} E) { // expected-warning {{will not be visible outside of this function}}
     return AA;
 }
 

Modified: cfe/trunk/test/SemaTemplate/instantiate-enum.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-enum.cpp?rev=201927&r1=201926&r2=201927&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-enum.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-enum.cpp Fri Feb 21 21:05:49 2014
@@ -25,3 +25,18 @@ namespace PR6375 {
 
   template void f<int>();
 }
+
+namespace EnumScoping {
+
+template <typename T>
+class C {
+  enum {
+    value = 42
+  };
+};
+
+void f(int i, C<int>::C c) {
+  int value;
+}
+
+}





More information about the cfe-commits mailing list