aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-04-13 21:30:24 +0000
committerDouglas Gregor <dgregor@apple.com>2008-04-13 21:30:24 +0000
commite37ac4ff1620ed2d7026f52baccbfa022d79ced1 (patch)
treeacc5704dc77d184e356feceeabd435c91f584a5d /lib/Sema/SemaDeclCXX.cpp
parent2ce52f3fb95bf544db6bd3d91a72bce7d9cceb6c (diff)
This patch adds very basic support for parsing and type-checking class
inheritance in C++. It'll parse the base-specifier list, e.g., class D : public B1, virtual public B2 { }; and do some of the simpler semantic checks (B1 and B2 are classes; they aren't unions or incomplete types, etc). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49623 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 89440c0cf4..7202d2f2f1 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -13,6 +13,7 @@
#include "Sema.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Type.h"
@@ -234,3 +235,51 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
}
}
}
+
+/// ActOnBaseSpecifier - Parsed a base specifier. A base specifier is
+/// one entry in the base class list of a class specifier, for
+/// example:
+/// class foo : public bar, virtual private baz {
+/// 'public bar' and 'virtual private baz' are each base-specifiers.
+void Sema::ActOnBaseSpecifier(DeclTy *classdecl, SourceRange SpecifierRange,
+ bool Virtual, AccessSpecifier Access,
+ DeclTy *basetype, SourceLocation BaseLoc) {
+ RecordDecl *Decl = (RecordDecl*)classdecl;
+ QualType BaseType = Context.getTypeDeclType((TypeDecl*)basetype);
+
+ // Base specifiers must be record types.
+ if (!BaseType->isRecordType()) {
+ Diag(BaseLoc, diag::err_base_must_be_class, SpecifierRange);
+ return;
+ }
+
+ // C++ [class.union]p1:
+ // A union shall not be used as a base class.
+ if (BaseType->isUnionType()) {
+ Diag(BaseLoc, diag::err_union_as_base_class, SpecifierRange);
+ return;
+ }
+
+ // C++ [class.union]p1:
+ // A union shall not have base classes.
+ if (Decl->getKind() == Decl::Union) {
+ Diag(Decl->getLocation(), diag::err_base_clause_on_union,
+ SpecifierRange);
+ Decl->setInvalidDecl();
+ return;
+ }
+
+ // C++ [class.derived]p2:
+ // The class-name in a base-specifier shall not be an incompletely
+ // defined class.
+ if (BaseType->isIncompleteType()) {
+ Diag(BaseLoc, diag::err_incomplete_base_class, SpecifierRange);
+ return;
+ }
+
+ // FIXME: C++ [class.mi]p3:
+ // A class shall not be specified as a direct base class of a
+ // derived class more than once.
+
+ // FIXME: Attach base class to the record.
+}