r184634 - Instantiation bug fix extension (cf. r184503) -- minor code fixes, including a typo that caused a runtime assertion after firing diagnosis for class definitions, with the 'template' keyword as template header, in friend declarations.

Larisse Voufo lvoufo at google.com
Sat Jun 22 06:56:11 PDT 2013


Author: lvoufo
Date: Sat Jun 22 08:56:11 2013
New Revision: 184634

URL: http://llvm.org/viewvc/llvm-project?rev=184634&view=rev
Log:
Instantiation bug fix extension (cf. r184503) -- minor code fixes, including a typo that caused a runtime assertion after firing diagnosis for class definitions, with the 'template' keyword as template header, in friend declarations.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=184634&r1=184633&r2=184634&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sat Jun 22 08:56:11 2013
@@ -595,6 +595,9 @@ def err_explicit_instantiation_with_defi
 def err_template_defn_explicit_instantiation : Error<
   "%select{function|class}0 cannot be defined in an explicit instantiation; if this "
   "declaration is meant to be a %select{function|class}0 definition, remove the 'template' keyword">;
+def err_friend_explicit_instantiation : Error<
+  "friend cannot be declared in an explicit instantiation; if this "
+  "declaration is meant to be a friend declaration, remove the 'template' keyword">;
 def err_explicit_instantiation_enum : Error<
     "enumerations cannot be explicitly instantiated">;
 def err_expected_template_parameter : Error<"expected template parameter">;

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=184634&r1=184633&r2=184634&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Sat Jun 22 08:56:11 2013
@@ -1465,7 +1465,6 @@ void Parser::ParseClassSpecifier(tok::To
       // This is an explicit specialization or a class template
       // partial specialization.
       TemplateParameterLists FakedParamLists;
-
       if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation) {
         // This looks like an explicit instantiation, because we have
         // something like
@@ -1475,25 +1474,35 @@ void Parser::ParseClassSpecifier(tok::To
         // but it actually has a definition. Most likely, this was
         // meant to be an explicit specialization, but the user forgot
         // the '<>' after 'template'.
-        assert(TUK == Sema::TUK_Definition && "Expected a definition here");
-
-        SourceLocation LAngleLoc
-          = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
-        Diag(TemplateId->TemplateNameLoc,
-             diag::err_explicit_instantiation_with_definition)
-          << SourceRange(TemplateInfo.TemplateLoc)
-          << FixItHint::CreateInsertion(LAngleLoc, "<>");
-
-        // Create a fake template parameter list that contains only
-        // "template<>", so that we treat this construct as a class
-        // template specialization.
-        FakedParamLists.push_back(
-          Actions.ActOnTemplateParameterList(0, SourceLocation(),
-                                             TemplateInfo.TemplateLoc,
-                                             LAngleLoc,
-                                             0, 0,
-                                             LAngleLoc));
-        TemplateParams = &FakedParamLists;
+	// It this is friend declaration however, since it cannot have a
+	// template header, it is most likely that the user meant to
+	// remove the 'template' keyword.
+        assert((TUK == Sema::TUK_Definition || TUK == Sema::TUK_Friend) &&
+	       "Expected a definition here");
+
+	if (TUK == Sema::TUK_Friend) {
+	  Diag(DS.getFriendSpecLoc(), 
+	       diag::err_friend_explicit_instantiation);
+	  TemplateParams = 0;
+	} else {
+	  SourceLocation LAngleLoc
+	    = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
+	  Diag(TemplateId->TemplateNameLoc,
+	       diag::err_explicit_instantiation_with_definition)
+	    << SourceRange(TemplateInfo.TemplateLoc)
+	    << FixItHint::CreateInsertion(LAngleLoc, "<>");
+	  
+	  // Create a fake template parameter list that contains only
+	  // "template<>", so that we treat this construct as a class
+	  // template specialization.
+	  FakedParamLists.push_back(
+	    Actions.ActOnTemplateParameterList(0, SourceLocation(),
+					       TemplateInfo.TemplateLoc,
+					       LAngleLoc,
+					       0, 0,
+					       LAngleLoc));
+	  TemplateParams = &FakedParamLists;
+	}
       }
 
       // Build the class template specialization.
@@ -1546,6 +1555,7 @@ void Parser::ParseClassSpecifier(tok::To
       // recover by ignoring the 'template' keyword.
       Diag(Tok, diag::err_template_defn_explicit_instantiation)
         << 1 << FixItHint::CreateRemoval(TemplateInfo.TemplateLoc);
+      TemplateParams = 0;
     }
 
     bool IsDependent = false;

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=184634&r1=184633&r2=184634&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Sat Jun 22 08:56:11 2013
@@ -242,6 +242,8 @@ Parser::ParseSingleDeclarationAfterTempl
         // If the declarator-id is not a template-id, issue a diagnostic and
         // recover by ignoring the 'template' keyword.
         Diag(Tok, diag::err_template_defn_explicit_instantiation) << 0;
+	return ParseFunctionDefinition(DeclaratorInfo, ParsedTemplateInfo(),
+				       &LateParsedAttrs);
       } else {
         SourceLocation LAngleLoc
           = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc);
@@ -251,24 +253,21 @@ Parser::ParseSingleDeclarationAfterTempl
           << FixItHint::CreateInsertion(LAngleLoc, "<>");
 
         // Recover as if it were an explicit specialization. 
-        TemplateParameterLists ParamLists;
-        SmallVector<Decl*, 4> TemplateParams;
-        ParamLists.push_back(
-            TemplateParameterList::Create(Actions.getASTContext(), 
-                                          TemplateInfo.TemplateLoc,
-                                          LAngleLoc, 
-                                          (NamedDecl**)TemplateParams.data(),
-                                          TemplateParams.size(), LAngleLoc));
+        TemplateParameterLists FakedParamLists;
+        FakedParamLists.push_back(
+	     Actions.ActOnTemplateParameterList(0, SourceLocation(),
+					        TemplateInfo.TemplateLoc, 
+						LAngleLoc, 0, 0, LAngleLoc));
 
         return ParseFunctionDefinition(DeclaratorInfo, 
-                                       ParsedTemplateInfo(&ParamLists,
+                                       ParsedTemplateInfo(&FakedParamLists,
                                            /*isSpecialization=*/true,
                                            /*LastParamListWasEmpty=*/true),
                                        &LateParsedAttrs);
       }
     }
     return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo,
-				                           &LateParsedAttrs);
+				   &LateParsedAttrs);
   }
 
   // Parse this declaration.





More information about the cfe-commits mailing list