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