From: Chris Lattner Date: Sun, 13 Apr 2008 18:59:07 +0000 (+0000) Subject: This patch is just the easy part of the class names patch, which X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=99dc91422144483c20d1c7381bc9ac634b646b04;p=clang This patch is just the easy part of the class names patch, which allows the parsing of "class" in addition to "struct" and "union" to declare a record. So this patch allows: class C { }; class C c1; But it does not contain the lookup bits, so this won't work yet: C c2; Patch by Doug Gregor! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49613 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 2ee479fd8a..5d36b759a3 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -315,6 +315,7 @@ public: bool isFunctionPointerType() const; bool isArrayType() const; bool isRecordType() const; + bool isClassType() const; bool isStructureType() const; bool isUnionType() const; bool isComplexIntegerType() const; // GCC _Complex integer type. diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 4de4628950..4bd6204b04 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -73,6 +73,7 @@ public: TST_enum, TST_union, TST_struct, + TST_class, // C++ class type TST_typedef, TST_typeofType, TST_typeofExpr @@ -106,7 +107,7 @@ private: /*TSW*/unsigned TypeSpecWidth : 2; /*TSC*/unsigned TypeSpecComplex : 2; /*TSS*/unsigned TypeSpecSign : 2; - /*TST*/unsigned TypeSpecType : 4; + /*TST*/unsigned TypeSpecType : 5; // type-qualifiers unsigned TypeQualifiers : 3; // Bitwise OR of TQ. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 637061c499..5040b95e09 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -60,6 +60,12 @@ bool Type::isDerivedType() const { } } +bool Type::isClassType() const { + if (const RecordType *RT = dyn_cast(CanonicalType)) + if (RT->getDecl()->getKind() == Decl::Class) + return true; + return false; +} bool Type::isStructureType() const { if (const RecordType *RT = dyn_cast(CanonicalType)) if (RT->getDecl()->getKind() == Decl::Struct) diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 1cd350893f..52c6a33954 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -95,6 +95,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { case DeclSpec::TST_decimal64: return "_Decimal64"; case DeclSpec::TST_decimal128: return "_Decimal128"; case DeclSpec::TST_enum: return "enum"; + case DeclSpec::TST_class: return "class"; case DeclSpec::TST_union: return "union"; case DeclSpec::TST_struct: return "struct"; case DeclSpec::TST_typedef: return "typedef"; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 7eeb64d578..8a0dcce31c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -515,7 +515,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { case tok::kw__Decimal128: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec); break; - + + case tok::kw_class: case tok::kw_struct: case tok::kw_union: ParseStructUnionSpecifier(DS); @@ -620,9 +621,12 @@ bool Parser::ParseTag(DeclTy *&Decl, unsigned TagType, SourceLocation StartLoc){ /// 'union' /// void Parser::ParseStructUnionSpecifier(DeclSpec &DS) { - assert((Tok.is(tok::kw_struct) || Tok.is(tok::kw_union)) && - "Not a struct/union specifier"); + assert((Tok.is(tok::kw_class) || + Tok.is(tok::kw_struct) || + Tok.is(tok::kw_union)) && + "Not a class/struct/union specifier"); DeclSpec::TST TagType = + Tok.is(tok::kw_class) ? DeclSpec::TST_class : Tok.is(tok::kw_union) ? DeclSpec::TST_union : DeclSpec::TST_struct; SourceLocation StartLoc = ConsumeToken(); @@ -923,7 +927,8 @@ bool Parser::isTypeSpecifierQualifier() const { case tok::kw__Decimal64: case tok::kw__Decimal128: - // struct-or-union-specifier + // struct-or-union-specifier (C99) or class-specifier (C++) + case tok::kw_class: case tok::kw_struct: case tok::kw_union: // enum-specifier @@ -973,7 +978,8 @@ bool Parser::isDeclarationSpecifier() const { case tok::kw__Decimal64: case tok::kw__Decimal128: - // struct-or-union-specifier + // struct-or-union-specifier (C99) or class-specifier (C++) + case tok::kw_class: case tok::kw_struct: case tok::kw_union: // enum-specifier diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7a86a8e7d3..c47a027fec 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1299,7 +1299,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, default: assert(0 && "Unknown tag type!"); case DeclSpec::TST_struct: Kind = Decl::Struct; break; case DeclSpec::TST_union: Kind = Decl::Union; break; -//case DeclSpec::TST_class: Kind = Decl::Class; break; + case DeclSpec::TST_class: Kind = Decl::Class; break; case DeclSpec::TST_enum: Kind = Decl::Enum; break; } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 5e155f8817..223cb56636 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -95,11 +95,12 @@ QualType Sema::ConvertDeclSpecToType(DeclSpec &DS) { case DeclSpec::TST_decimal64: // _Decimal64 case DeclSpec::TST_decimal128: // _Decimal128 assert(0 && "FIXME: GNU decimal extensions not supported yet!"); + case DeclSpec::TST_class: case DeclSpec::TST_enum: case DeclSpec::TST_union: case DeclSpec::TST_struct: { Decl *D = static_cast(DS.getTypeRep()); - assert(D && "Didn't get a decl for a enum/union/struct?"); + assert(D && "Didn't get a decl for a class/enum/union/struct?"); assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 && DS.getTypeSpecSign() == 0 && "Can't handle qualifiers on typedef names yet!");