Hi all,

the patch brings LangOptions to DeclSpec to make getSpecifierName() return proper type name for bool. It would be probably better to pass PrintingPolicy obtained from Sema::getPrintingPolicy() to getSpecifierName() but I failed to implement it trivially.
Please review and comment!

PR9812: http://llvm.org/bugs/show_bug.cgi?id=9812

--
Anton

Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h	(revision 150477)
+++ include/clang/Parse/Parser.h	(working copy)
@@ -1008,9 +1008,10 @@
     ParsingDeclRAIIObject ParsingRAII;
 
   public:
-    ParsingDeclSpec(Parser &P) : DeclSpec(P.AttrFactory), ParsingRAII(P) {}
+    ParsingDeclSpec(Parser &P) : DeclSpec(P.AttrFactory, P.getLang()), 
+      ParsingRAII(P) {}
     ParsingDeclSpec(Parser &P, ParsingDeclRAIIObject *RAII)
-      : DeclSpec(P.AttrFactory), ParsingRAII(P, RAII) {}
+      : DeclSpec(P.AttrFactory, P.getLang()), ParsingRAII(P, RAII) {}
 
     void complete(Decl *D) {
       ParsingRAII.complete(D);
Index: include/clang/Sema/DeclSpec.h
===================================================================
--- include/clang/Sema/DeclSpec.h	(revision 150477)
+++ include/clang/Sema/DeclSpec.h	(working copy)
@@ -324,6 +324,9 @@
   // attributes.
   ParsedAttributes Attrs;
 
+  // Used for generating proper type names. (_Bool vs bool)
+  const LangOptions *LangOpts;
+
   // Scope specifier for the type spec, if applicable.
   CXXScopeSpec TypeScope;
 
@@ -373,7 +376,7 @@
   void operator=(const DeclSpec&); // DO NOT IMPLEMENT
 public:
 
-  DeclSpec(AttributeFactory &attrFactory)
+  DeclSpec(AttributeFactory &attrFactory, const LangOptions &LO)
     : StorageClassSpec(SCS_unspecified),
       SCS_thread_specified(false),
       SCS_extern_in_linkage_spec(false),
@@ -393,6 +396,7 @@
       Constexpr_specified(false),
       StorageClassSpecAsWritten(SCS_unspecified),
       Attrs(attrFactory),
+      LangOpts(&LO),
       ProtocolQualifiers(0),
       NumProtocolQualifiers(0),
       ProtocolLocs(0),
@@ -463,7 +467,8 @@
 
   /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool"
   /// or "union".
-  static const char *getSpecifierName(DeclSpec::TST T);
+  const char *getSpecifierName(DeclSpec::TST T) const;
+  static const char *getSpecifierName(DeclSpec::TST T, const LangOptions &LO);
   static const char *getSpecifierName(DeclSpec::TQ Q);
   static const char *getSpecifierName(DeclSpec::TSS S);
   static const char *getSpecifierName(DeclSpec::TSC C);
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp	(revision 150477)
+++ lib/Parse/ParseDecl.cpp	(working copy)
@@ -37,7 +37,7 @@
                                  AccessSpecifier AS,
                                  Decl **OwnedType) {
   // Parse the common declaration-specifiers piece.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseSpecifierQualifierList(DS, AS);
   if (OwnedType)
     *OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
@@ -2755,14 +2755,14 @@
     // Check for extraneous top-level semicolon.
     if (Tok.is(tok::semi)) {
       Diag(Tok, diag::ext_extra_struct_semi)
-        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
+        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType, getLang())
         << FixItHint::CreateRemoval(Tok.getLocation());
       ConsumeToken();
       continue;
     }
 
     // Parse all the comma separated declarators.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
 
     if (!Tok.is(tok::at)) {
       struct CFieldCallback : FieldCallback {
@@ -3746,7 +3746,7 @@
 
       SourceLocation Loc = ConsumeToken();
       D.SetRangeEnd(Loc);
-      DeclSpec DS(AttrFactory);
+      DeclSpec DS(AttrFactory, getLang());
       ParseTypeQualifierListOpt(DS);
       D.ExtendWithDeclSpec(DS);
 
@@ -3781,7 +3781,7 @@
 
   if (Kind == tok::star || Kind == tok::caret) {
     // Is a pointer.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
 
     ParseTypeQualifierListOpt(DS);
     D.ExtendWithDeclSpec(DS);
@@ -3804,7 +3804,7 @@
                     SourceLocation());
   } else {
     // Is a reference
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
 
     // Complain about rvalue references in C++03, but then go on and build
     // the declarator.
@@ -4179,7 +4179,7 @@
   // Remember where we see an ellipsis, if any.
   SourceLocation EllipsisLoc;
 
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   bool RefQualifierIsLValueRef = true;
   SourceLocation RefQualifierLoc;
   SourceLocation ConstQualifierLoc;
@@ -4403,7 +4403,7 @@
 
     // Parse the declaration-specifiers.
     // Just use the ParsingDeclaration "scope" of the declarator.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
 
     // Skip any Microsoft attributes before a param.
     if (getLang().MicrosoftExt && Tok.is(tok::l_square))
@@ -4581,7 +4581,7 @@
 
   // If there is a type-qualifier-list, read it now.
   // Type qualifiers in an array subscript are a C99 feature.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseTypeQualifierListOpt(DS, false /*no attributes*/);
 
   // If we haven't already read 'static', check to see if there is one after the
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp	(revision 150477)
+++ lib/Parse/ParseDeclCXX.cpp	(working copy)
@@ -783,7 +783,7 @@
       Diag(SS.getBeginLoc(), diag::err_unexpected_scope_on_base_decltype)
         << FixItHint::CreateRemoval(SS.getRange());
     // Fake up a Declarator to use with ActOnTypeName.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
 
     EndLocation = ParseDecltypeSpecifier(DS);
 
@@ -871,7 +871,7 @@
   EndLocation = IdLoc;
 
   // Fake up a Declarator to use with ActOnTypeName.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   DS.SetRangeStart(IdLoc);
   DS.SetRangeEnd(EndLocation);
   DS.getTypeSpecScope() = SS;
@@ -1140,7 +1140,7 @@
     if (DS.getTypeSpecType() != DeclSpec::TST_error) {
       // We have a declaration or reference to an anonymous class.
       Diag(StartLoc, diag::err_anon_type_definition)
-        << DeclSpec::getSpecifierName(TagType);
+        << DS.getSpecifierName(TagType);
     }
 
     SkipUntil(tok::comma, true);
@@ -2237,7 +2237,7 @@
       // Check for extraneous top-level semicolon.
       if (Tok.is(tok::semi)) {
         Diag(Tok, diag::ext_extra_struct_semi)
-          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
+          << DeclSpec::getSpecifierName((DeclSpec::TST)TagType, getLang())
           << FixItHint::CreateRemoval(Tok.getLocation());
         ConsumeToken();
         continue;
@@ -2430,7 +2430,7 @@
   }
 
   IdentifierInfo *II = 0;
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   SourceLocation IdLoc = Tok.getLocation();
   if (Tok.is(tok::annot_decltype)) {
     // Get the decltype expression, if there is one.
@@ -2907,7 +2907,7 @@
     // Check for extraneous top-level semicolon.
     if (Tok.is(tok::semi)) {
       Diag(Tok, diag::ext_extra_struct_semi)
-        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType)
+        << DeclSpec::getSpecifierName((DeclSpec::TST)TagType, getLang())
         << FixItHint::CreateRemoval(Tok.getLocation());
       ConsumeToken();
       continue;
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp	(revision 150477)
+++ lib/Parse/ParseExpr.cpp	(working copy)
@@ -766,7 +766,7 @@
         if (ParsedType Typ = Actions.getTypeName(II, ILoc, getCurScope()))
           if (Typ.get()->isObjCObjectOrInterfaceType()) {
             // Fake up a Declarator to use with ActOnTypeName.
-            DeclSpec DS(AttrFactory);
+            DeclSpec DS(AttrFactory, getLang());
             DS.SetRangeStart(ILoc);
             DS.SetRangeEnd(ILoc);
             const char *PrevSpec = 0;
@@ -923,7 +923,7 @@
       ParsedType Type = getTypeAnnotation(Tok);
       
       // Fake up a Declarator to use with ActOnTypeName.
-      DeclSpec DS(AttrFactory);
+      DeclSpec DS(AttrFactory, getLang());
       DS.SetRangeStart(Tok.getLocation());
       DS.SetRangeEnd(Tok.getLastLoc());
 
@@ -978,7 +978,7 @@
     // postfix-expression: simple-type-specifier '(' expression-list[opt] ')'
     //                     simple-type-specifier braced-init-list
     //
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseCXXSimpleTypeSpecifier(DS);
     if (Tok.isNot(tok::l_paren) &&
         (!getLang().CPlusPlus0x || Tok.isNot(tok::l_brace)))
@@ -1920,7 +1920,7 @@
     }
 
     // Parse the type declarator.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseSpecifierQualifierList(DS);
     Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
     ParseDeclarator(DeclaratorInfo);
@@ -2239,7 +2239,7 @@
   }
   
   // Parse the specifier-qualifier-list piece.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseSpecifierQualifierList(DS);
 
   // Parse the block-declarator.
@@ -2283,7 +2283,7 @@
   Actions.ActOnBlockStart(CaretLoc, getCurScope());
 
   // Parse the return type if present.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
   // FIXME: Since the return type isn't actually parsed, it can't be used to
   // fill ParamInfo with an initial valid range, so do it manually.
Index: lib/Parse/ParseExprCXX.cpp
===================================================================
--- lib/Parse/ParseExprCXX.cpp	(revision 150477)
+++ lib/Parse/ParseExprCXX.cpp	(working copy)
@@ -170,7 +170,7 @@
   }
 
   if (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype)) {
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     SourceLocation DeclLoc = Tok.getLocation();
     SourceLocation EndLoc  = ParseDecltypeSpecifier(DS);
     if (Tok.isNot(tok::coloncolon)) {
@@ -711,7 +711,7 @@
                                 "lambda expression parsing");
 
   // Parse lambda-declarator[opt].
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   Declarator D(DS, Declarator::LambdaExprContext);
 
   if (Tok.is(tok::l_paren)) {
@@ -852,7 +852,7 @@
     return ExprError();
 
   // Parse the common declaration-specifiers piece.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseSpecifierQualifierList(DS);
 
   // Parse the abstract-declarator, if present.
@@ -1045,7 +1045,7 @@
   SourceLocation TildeLoc = ConsumeToken();
 
   if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) {
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseDecltypeSpecifier(DS);
     if (DS.getTypeSpecType() == TST_error)
       return ExprError();
@@ -1235,7 +1235,7 @@
   }
 
   // type-specifier-seq
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseSpecifierQualifierList(DS);
 
   // declarator
@@ -1834,7 +1834,7 @@
   //     ptr-operator conversion-declarator[opt]
   
   // Parse the type-specifier-seq.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
     return true;
   
@@ -2016,7 +2016,7 @@
     SourceLocation TildeLoc = ConsumeToken();
 
     if (SS.isEmpty() && Tok.is(tok::kw_decltype)) {
-      DeclSpec DS(AttrFactory);
+      DeclSpec DS(AttrFactory, getLang());
       SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
       if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) {
         Result.setDestructorName(TildeLoc, Type, EndLoc);
@@ -2100,7 +2100,7 @@
   SourceLocation PlacementLParen, PlacementRParen;
 
   SourceRange TypeIdParens;
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   Declarator DeclaratorInfo(DS, Declarator::CXXNewContext);
   if (Tok.is(tok::l_paren)) {
     // If it turns out to be a placement, we change the type location.
@@ -2586,7 +2586,7 @@
 
   if (ParseAs >= CompoundLiteral) {
     // Parse the type declarator.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseSpecifierQualifierList(DS);
     Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
     ParseDeclarator(DeclaratorInfo);
Index: lib/Parse/ParseObjc.cpp
===================================================================
--- lib/Parse/ParseObjc.cpp	(revision 150477)
+++ lib/Parse/ParseObjc.cpp	(working copy)
@@ -486,7 +486,7 @@
                                     OCDS, AtLoc, MethodImplKind);
 
       // Parse all the comma separated declarators.
-      DeclSpec DS(AttrFactory);
+      DeclSpec DS(AttrFactory, getLang());
       ParseStructDeclaration(DS, Callback);
 
       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
@@ -884,7 +884,7 @@
   ParsedType Ty;
   if (isTypeSpecifierQualifier()) {
     // Parse an abstract declarator.
-    DeclSpec declSpec(AttrFactory);
+    DeclSpec declSpec(AttrFactory, getLang());
     declSpec.setObjCQualifiers(&DS);
     ParseSpecifierQualifierList(declSpec);
     Declarator declarator(declSpec, context);
@@ -1107,7 +1107,7 @@
       ConsumeToken();
       break;
     }
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseDeclarationSpecifiers(DS);
     // Parse the declarator.
     Declarator ParmDecl(DS, Declarator::PrototypeContext);
@@ -1312,7 +1312,7 @@
     } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
     
     // Parse all the comma separated declarators.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseStructDeclaration(DS, Callback);
 
     if (Tok.is(tok::semi)) {
@@ -1818,7 +1818,7 @@
         ConsumeParen();
         ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope);
         if (Tok.isNot(tok::ellipsis)) {
-          DeclSpec DS(AttrFactory);
+          DeclSpec DS(AttrFactory, getLang());
           ParseDeclarationSpecifiers(DS);
           Declarator ParmDecl(DS, Declarator::ObjCCatchContext);
           ParseDeclarator(ParmDecl);
@@ -2070,7 +2070,7 @@
   //   typename-specifier
   //   simple-type-specifier
   //   expression (that starts with one of the above)
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseCXXSimpleTypeSpecifier(DS);
   
   if (Tok.is(tok::l_paren)) {
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp	(revision 150477)
+++ lib/Parse/Parser.cpp	(working copy)
@@ -992,7 +992,7 @@
     SourceLocation DSStart = Tok.getLocation();
 
     // Parse the common declaration-specifiers piece.
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     ParseDeclarationSpecifiers(DS);
 
     // C99 6.9.1p6: 'each declaration in the declaration list shall have at
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp	(revision 150477)
+++ lib/Parse/ParseStmt.cpp	(working copy)
@@ -738,7 +738,7 @@
       ConsumeToken();
     }
 
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     DeclGroupPtrTy Res = Actions.FinalizeDeclaratorGroup(getCurScope(), DS,
                                       DeclsInGroup.data(), DeclsInGroup.size());
     StmtResult R = Actions.ActOnDeclStmt(Res, LabelLoc, Tok.getLocation());
@@ -1758,7 +1758,7 @@
     msAsm = true;
     return ParseMicrosoftAsmStatement(AsmLoc);
   }
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   SourceLocation Loc = Tok.getLocation();
   ParseTypeQualifierListOpt(DS, true, false);
 
@@ -2133,7 +2133,7 @@
   // without default arguments.
   Decl *ExceptionDecl = 0;
   if (Tok.isNot(tok::ellipsis)) {
-    DeclSpec DS(AttrFactory);
+    DeclSpec DS(AttrFactory, getLang());
     if (ParseCXXTypeSpecifierSeq(DS))
       return StmtError();
     Declarator ExDecl(DS, Declarator::CXXCatchContext);
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp	(revision 150477)
+++ lib/Parse/ParseTemplate.cpp	(working copy)
@@ -607,7 +607,7 @@
   // Parse the declaration-specifiers (i.e., the type).
   // FIXME: The type should probably be restricted in some way... Not all
   // declarators (parts of declarators?) are accepted for parameters.
-  DeclSpec DS(AttrFactory);
+  DeclSpec DS(AttrFactory, getLang());
   ParseDeclarationSpecifiers(DS);
 
   // Parse this as a typename.
Index: lib/Sema/DeclSpec.cpp
===================================================================
--- lib/Sema/DeclSpec.cpp	(revision 150477)
+++ lib/Sema/DeclSpec.cpp	(working copy)
@@ -370,7 +370,12 @@
   llvm_unreachable("Unknown typespec!");
 }
 
-const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
+const char *DeclSpec::getSpecifierName(DeclSpec::TST T) const {
+  return getSpecifierName(T, *LangOpts);
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::TST T, 
+                                       const LangOptions &LO) {
   switch (T) {
   case DeclSpec::TST_unspecified: return "unspecified";
   case DeclSpec::TST_void:        return "void";
@@ -382,7 +387,8 @@
   case DeclSpec::TST_half:        return "half";
   case DeclSpec::TST_float:       return "float";
   case DeclSpec::TST_double:      return "double";
-  case DeclSpec::TST_bool:        return "_Bool";
+  case DeclSpec::TST_bool:        return (LO.Bool || LO.CPlusPlus) ? "bool" :
+                                                                     "_Bool";
   case DeclSpec::TST_decimal32:   return "_Decimal32";
   case DeclSpec::TST_decimal64:   return "_Decimal64";
   case DeclSpec::TST_decimal128:  return "_Decimal128";
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 150477)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -7028,7 +7028,7 @@
         // Implicitly declare the argument as type 'int' for lack of a better
         // type.
         AttributeFactory attrs;
-        DeclSpec DS(attrs);
+        DeclSpec DS(attrs, getLangOptions());
         const char* PrevSpec; // unused
         unsigned DiagID; // unused
         DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
@@ -7441,7 +7441,7 @@
   // Set a Declarator for the implicit definition: int foo();
   const char *Dummy;
   AttributeFactory attrFactory;
-  DeclSpec DS(attrFactory);
+  DeclSpec DS(attrFactory, getLangOptions());
   unsigned DiagID;
   bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
   (void)Error; // Silence warning.
Index: test/SemaCXX/bool.cpp
===================================================================
--- test/SemaCXX/bool.cpp	(revision 150477)
+++ test/SemaCXX/bool.cpp	(working copy)
@@ -31,3 +31,8 @@
   static_assert_arg_is_bool(n || 5);  // expected-warning {{use of logical '||' with constant operand}} \
                                       // expected-note {{use '|' for a bitwise operation}}
 }
+
+// PR9812 
+void test3() {
+  signed bool b; //expected-error{{'bool' cannot be signed or unsigned}}
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to