summaryrefslogtreecommitdiffstats
path: root/clang/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang')
-rw-r--r--clang/include/clang/AST/DeclBase.h3
-rw-r--r--clang/include/clang/AST/DeclCXX.h90
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def16
-rw-r--r--clang/include/clang/Parse/DeclSpec.h57
-rw-r--r--clang/include/clang/Parse/Parser.h1
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);
OpenPOWER on IntegriCloud