diff options
Diffstat (limited to 'clang/include/clang')
| -rw-r--r-- | clang/include/clang/AST/DeclBase.h | 3 | ||||
| -rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 90 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 16 | ||||
| -rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 57 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Parser.h | 1 |
5 files changed, 159 insertions, 8 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index e6d4df1cb30..5a07c48d4ab 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -67,6 +67,7 @@ public: Function, // [DeclContext] CXXMethod, CXXConstructor, + CXXDestructor, Var, ImplicitParam, CXXClassVar, @@ -90,7 +91,7 @@ public: TagFirst = Enum , TagLast = CXXRecord, RecordFirst = Record , RecordLast = CXXRecord, ValueFirst = EnumConstant , ValueLast = ParmVar, - FunctionFirst = Function , FunctionLast = CXXConstructor, + FunctionFirst = Function , FunctionLast = CXXDestructor, VarFirst = Var , VarLast = ParmVar }; diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 9d0065e4fbb..2065677c7a7 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -20,6 +20,7 @@ namespace clang { class CXXRecordDecl; class CXXConstructorDecl; +class CXXDestructorDecl; /// OverloadedFunctionDecl - An instance of this class represents a /// set of overloaded functions. All of the functions have the same @@ -230,11 +231,15 @@ class CXXRecordDecl : public RecordDecl, public DeclContext { /// CXXConstructorDecl. OverloadedFunctionDecl Constructors; + // Destructor - The destructor of this C++ class. + CXXDestructorDecl *Destructor; + CXXRecordDecl(TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id) : RecordDecl(CXXRecord, TK, DC, L, Id), DeclContext(CXXRecord), UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false), - Aggregate(true), Bases(0), NumBases(0), Constructors(DC, Id) { } + Aggregate(true), Bases(0), NumBases(0), Constructors(DC, Id), + Destructor(0) { } ~CXXRecordDecl(); @@ -303,6 +308,15 @@ public: return UserDeclaredCopyConstructor; } + /// getDestructor - Retrieve the destructor for this class. + CXXDestructorDecl *getDestructor() const { return Destructor; } + + /// setDestructor - Set the destructor for this class. + void setDestructor(CXXDestructorDecl *Destructor) { + assert(!this->Destructor && "Already have a destructor!"); + this->Destructor = Destructor; + } + /// isAggregate - Whether this class is an aggregate (C++ /// [dcl.init.aggr]), which is a class with no user-declared /// constructors, no private or protected non-static data members, @@ -620,6 +634,80 @@ public: static CXXConstructorDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; +/// CXXDestructorDecl - Represents a C++ destructor within a +/// class. For example: +/// +/// @code +/// class X { +/// public: +/// ~X(); // represented by a CXXDestructorDecl. +/// }; +/// @endcode +class CXXDestructorDecl : public CXXMethodDecl { + /// ImplicitlyDeclared - Whether this destructor was implicitly + /// declared. When false, the destructor was declared by the user. + bool ImplicitlyDeclared : 1; + + /// ImplicitlyDefined - Whether this destructor was implicitly + /// defined by the compiler. When false, the destructor was defined + /// by the user. In C++03, this flag will have the same value as + /// ImplicitlyDeclared. In C++0x, however, a destructor that is + /// explicitly defaulted (i.e., defined with " = default") will have + /// @c !ImplicitlyDeclared && ImplicitlyDefined. + bool ImplicitlyDefined : 1; + + CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L, + IdentifierInfo *Id, QualType T, + bool isInline, bool isImplicitlyDeclared) + : CXXMethodDecl(CXXDestructor, RD, L, Id, T, false, isInline, + /*PrevDecl=*/0), + ImplicitlyDeclared(isImplicitlyDeclared), + ImplicitlyDefined(false) { } + +public: + static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation L, IdentifierInfo *Id, + QualType T, bool isInline, + bool isImplicitlyDeclared); + + /// isImplicitlyDeclared - Whether this destructor was implicitly + /// declared. If false, then this destructor was explicitly + /// declared by the user. + bool isImplicitlyDeclared() const { return ImplicitlyDeclared; } + + /// isImplicitlyDefined - Whether this destructor was implicitly + /// defined. If false, then this destructor was defined by the + /// user. This operation can only be invoked if the destructor has + /// already been defined. + bool isImplicitlyDefined() const { + assert(getBody() != 0 && + "Can only get the implicit-definition flag once the destructor has been defined"); + return ImplicitlyDefined; + } + + /// setImplicitlyDefined - Set whether this destructor was + /// implicitly defined or not. + void setImplicitlyDefined(bool ID) { + assert(getBody() != 0 && + "Can only set the implicit-definition flag once the destructor has been defined"); + ImplicitlyDefined = ID; + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { + return D->getKind() == CXXDestructor; + } + static bool classof(const CXXDestructorDecl *D) { return true; } + + /// EmitImpl - Serialize this CXXDestructorDecl. Called by Decl::Emit. + // FIXME: Implement this. + //virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a CXXDestructorDecl. Called by Decl::Create. + // FIXME: Implement this. + static CXXDestructorDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); +}; + /// CXXClassVarDecl - Represents a static data member of a struct/union/class. class CXXClassVarDecl : public VarDecl { diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index c4c3d0c9868..1972716e1d5 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -688,6 +688,22 @@ DIAG(err_constructor_redeclared, ERROR, DIAG(err_constructor_byvalue_arg, ERROR, "copy constructor must pass its first argument by reference") +// C++ destructors +DIAG(err_destructor_cannot_be, ERROR, + "destructor cannot be declared '%0'") +DIAG(err_invalid_qualified_destructor, ERROR, + "'%0' qualifier is not allowed on a destructor") +DIAG(err_destructor_return_type, ERROR, + "destructor cannot have a return type") +DIAG(err_destructor_redeclared, ERROR, + "destructor cannot be redeclared") +DIAG(err_destructor_with_params, ERROR, + "destructor cannot have any parameters") +DIAG(err_destructor_variadic, ERROR, + "destructor cannot be variadic") +DIAG(err_destructor_typedef_name, ERROR, + "destructor cannot be declared using a typedef '%0' of the class name") + // C++ initialization DIAG(err_not_reference_to_const_init, ERROR, "non-const reference to type '%0' cannot be initialized with a %1 of type '%2'") diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index 2f1ac370484..fab6ec3c34f 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -604,11 +604,23 @@ public: ForContext, // Declaration within first part of a for loop. ConditionContext // Condition declaration in a C++ if/switch/while/for. }; + + /// DeclaratorKind - The kind of declarator this represents. + enum DeclaratorKind { + DK_Abstract, // An abstract declarator (has no identifier) + DK_Normal, // A normal declarator (has an identifier). + DK_Constructor, // A C++ constructor (identifier is the class name) + DK_Destructor // A C++ destructor (has no identifier) + }; + private: /// Context - Where we are parsing this declarator. /// TheContext Context; - + + /// Kind - What kind of declarator this is. + DeclaratorKind Kind; + /// DeclTypeInfo - This holds each type that the declarator includes as it is /// parsed. This is pushed from the identifier out, which means that element /// #0 will be the most closely bound to the identifier, and @@ -626,11 +638,15 @@ private: /// AsmLabel - The asm label, if specified. Action::ExprTy *AsmLabel; - + + // When Kind is DK_Constructor or DK_Destructor, the type associated + // with the constructor or destructor. + Action::TypeTy *Type; + public: Declarator(const DeclSpec &ds, TheContext C) - : DS(ds), Identifier(0), Context(C), InvalidType(false), - GroupingParens(false), AttrList(0), AsmLabel(0) { + : DS(ds), Identifier(0), Context(C), Kind(DK_Abstract), InvalidType(false), + GroupingParens(false), AttrList(0), AsmLabel(0), Type(0) { } ~Declarator() { @@ -649,7 +665,8 @@ public: DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); } TheContext getContext() const { return Context; } - + DeclaratorKind getKind() const { return Kind; } + // getSourceRange - FIXME: This should be implemented. const SourceRange getSourceRange() const { return SourceRange(); } @@ -657,7 +674,8 @@ public: void clear() { Identifier = 0; IdentifierLoc = SourceLocation(); - + Kind = DK_Abstract; + for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) { if (DeclTypeInfo[i].Kind == DeclaratorChunk::Function) DeclTypeInfo[i].Fun.destroy(); @@ -676,6 +694,7 @@ public: delete AttrList; AttrList = 0; AsmLabel = 0; + Type = 0; } /// mayOmitIdentifier - Return true if the identifier is either optional or @@ -710,8 +729,32 @@ public: void SetIdentifier(IdentifierInfo *ID, SourceLocation Loc) { Identifier = ID; IdentifierLoc = Loc; + if (ID) + Kind = DK_Normal; + else + Kind = DK_Abstract; } + /// SetConstructor - Set this declarator to be a C++ constructor + /// declarator. + void SetConstructor(Action::TypeTy *Ty, IdentifierInfo *ID, + SourceLocation Loc) { + Identifier = ID; + IdentifierLoc = Loc; + Kind = DK_Constructor; + Type = Ty; + } + + /// SetDestructor - Set this declarator to be a C++ destructor + /// declarator. + void SetDestructor(Action::TypeTy *Ty, IdentifierInfo *ID, + SourceLocation Loc) { + Identifier = ID; + IdentifierLoc = Loc; + Kind = DK_Destructor; + Type = Ty; + } + void AddTypeInfo(const DeclaratorChunk &TI) { DeclTypeInfo.push_back(TI); } @@ -759,6 +802,8 @@ public: void setAsmLabel(Action::ExprTy *E) { AsmLabel = E; } Action::ExprTy *getAsmLabel() const { return AsmLabel; } + Action::TypeTy *getDeclaratorIdType() const { return Type; } + void setInvalidType(bool flag) { InvalidType = flag; } bool getInvalidType() const { return InvalidType; } diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 897c09d0bc4..adcc936216b 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -715,6 +715,7 @@ private: //===--------------------------------------------------------------------===// // C++ 9: classes [class] and C structs/unions. + TypeTy *ParseClassName(); void ParseClassSpecifier(DeclSpec &DS); void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType, DeclTy *TagDecl); |

