diff --git a/src/shared/cplusplus/Bind.cpp b/src/shared/cplusplus/Bind.cpp
index 1bf40a53a83572cd0675c75d29ece023ab134408..793c6f72421ceeb3d399cf8ff66b307fd5a8564a 100644
--- a/src/shared/cplusplus/Bind.cpp
+++ b/src/shared/cplusplus/Bind.cpp
@@ -180,6 +180,13 @@ void Bind::attribute(AttributeAST *ast)
         return;
 
     // unsigned identifier_token = ast->identifier_token;
+    if (const Identifier *id = identifier(ast->identifier_token)) {
+        if (id == control()->deprecatedId())
+            _type.setDeprecated(true);
+        else if (id == control()->unavailableId())
+            _type.setUnavailable(true);
+    }
+
     // unsigned lparen_token = ast->lparen_token;
     // unsigned tag_token = ast->tag_token;
     for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
@@ -264,15 +271,25 @@ bool Bind::visit(BaseSpecifierAST *ast)
     return false;
 }
 
-void Bind::baseSpecifier(BaseSpecifierAST *ast)
+void Bind::baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *klass)
 {
     if (! ast)
         return;
 
-    // unsigned virtual_token = ast->virtual_token;
-    // unsigned access_specifier_token = ast->access_specifier_token;
-    /*const Name *name =*/ this->name(ast->name);
-    // BaseClass *symbol = ast->symbol;
+    unsigned sourceLocation = ast->firstToken();
+    if (! sourceLocation)
+        sourceLocation = std::max(colon_token, klass->sourceLocation());
+
+    const Name *baseClassName = this->name(ast->name);
+    BaseClass *baseClass = control()->newBaseClass(sourceLocation, baseClassName);
+    if (ast->virtual_token)
+        baseClass->setVirtual(true);
+    if (ast->access_specifier_token) {
+        const int visibility = visibilityForAccessSpecifier(tokenKind(ast->access_specifier_token));
+        baseClass->setVisibility(visibility); // ### well, not exactly.
+    }
+    klass->addMember(baseClass);
+    ast->symbol = baseClass;
 }
 
 bool Bind::visit(CtorInitializerAST *ast)
@@ -1931,8 +1948,177 @@ bool Bind::visit(TemplateIdAST *ast)
 // SpecifierAST
 bool Bind::visit(SimpleSpecifierAST *ast)
 {
-    (void) ast;
-    // unsigned specifier_token = ast->specifier_token;
+    switch (tokenKind(ast->specifier_token)) {
+        case T_CONST:
+            if (_type.isConst())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setConst(true);
+            break;
+
+        case T_VOLATILE:
+            if (_type.isVolatile())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setVolatile(true);
+            break;
+
+        case T_FRIEND:
+            if (_type.isFriend())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setFriend(true);
+            break;
+
+        case T_AUTO:
+            if (_type.isAuto())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setAuto(true);
+            break;
+
+        case T_REGISTER:
+            if (_type.isRegister())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setRegister(true);
+            break;
+
+        case T_STATIC:
+            if (_type.isStatic())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setStatic(true);
+            break;
+
+        case T_EXTERN:
+            if (_type.isExtern())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setExtern(true);
+            break;
+
+        case T_MUTABLE:
+            if (_type.isMutable())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setMutable(true);
+            break;
+
+        case T_TYPEDEF:
+            if (_type.isTypedef())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setTypedef(true);
+            break;
+
+        case T_INLINE:
+            if (_type.isInline())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setInline(true);
+            break;
+
+        case T_VIRTUAL:
+            if (_type.isVirtual())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setVirtual(true);
+            break;
+
+        case T_EXPLICIT:
+            if (_type.isExplicit())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setExplicit(true);
+            break;
+
+        case T_SIGNED:
+            if (_type.isSigned())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setSigned(true);
+            break;
+
+        case T_UNSIGNED:
+            if (_type.isUnsigned())
+                translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
+            _type.setUnsigned(true);
+            break;
+
+        case T_CHAR:
+            if (_type)
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            _type.setType(control()->integerType(IntegerType::Char));
+            break;
+
+        case T_WCHAR_T:
+            if (_type)
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            _type.setType(control()->integerType(IntegerType::WideChar));
+            break;
+
+        case T_BOOL:
+            if (_type)
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            _type.setType(control()->integerType(IntegerType::Bool));
+            break;
+
+        case T_SHORT:
+            if (_type) {
+                IntegerType *intType = control()->integerType(IntegerType::Int);
+                if (_type.type() != intType)
+                    translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            }
+            _type.setType(control()->integerType(IntegerType::Short));
+            break;
+
+        case T_INT:
+            if (_type) {
+                Type *tp = _type.type();
+                IntegerType *shortType = control()->integerType(IntegerType::Short);
+                IntegerType *longType = control()->integerType(IntegerType::Long);
+                IntegerType *longLongType = control()->integerType(IntegerType::LongLong);
+                if (tp == shortType || tp == longType || tp == longLongType)
+                    break;
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            }
+            _type.setType(control()->integerType(IntegerType::Int));
+            break;
+
+        case T_LONG:
+            if (_type) {
+                Type *tp = _type.type();
+                IntegerType *intType = control()->integerType(IntegerType::Int);
+                IntegerType *longType = control()->integerType(IntegerType::Long);
+                FloatType *doubleType = control()->floatType(FloatType::Double);
+                if (tp == longType) {
+                    _type.setType(control()->integerType(IntegerType::LongLong));
+                    break;
+                } else if (tp == doubleType) {
+                    _type.setType(control()->floatType(FloatType::LongDouble));
+                    break;
+                } else if (tp != intType) {
+                    translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+                }
+            }
+            _type.setType(control()->integerType(IntegerType::Long));
+            break;
+
+        case T_FLOAT:
+            if (_type)
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            _type.setType(control()->floatType(FloatType::Float));
+            break;
+
+        case T_DOUBLE:
+            if (_type) {
+                IntegerType *longType = control()->integerType(IntegerType::Long);
+                if (_type.type() == longType) {
+                    _type.setType(control()->floatType(FloatType::LongDouble));
+                    break;
+                }
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            }
+            _type.setType(control()->floatType(FloatType::Double));
+            break;
+
+        case T_VOID:
+            if (_type)
+                translationUnit()->error(ast->specifier_token, "duplicate data type in declaration");
+            _type.setType(control()->voidType());
+            break;
+
+        default:
+            break;
+    } // switch
     return false;
 }
 
@@ -1951,32 +2137,45 @@ bool Bind::visit(AttributeSpecifierAST *ast)
 
 bool Bind::visit(TypeofSpecifierAST *ast)
 {
-    // unsigned typeof_token = ast->typeof_token;
-    // unsigned lparen_token = ast->lparen_token;
     ExpressionTy expression = this->expression(ast->expression);
-    // unsigned rparen_token = ast->rparen_token;
+    _type = expression;
     return false;
 }
 
 bool Bind::visit(ClassSpecifierAST *ast)
 {
     // unsigned classkey_token = ast->classkey_token;
-    FullySpecifiedType type;
+    unsigned sourceLocation = ast->classkey_token;
+
     for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
-        type = this->specifier(it->value, type);
+        _type = this->specifier(it->value, _type);
     }
-    /*const Name *name =*/ this->name(ast->name);
-    // unsigned colon_token = ast->colon_token;
+
+    const Name *className = this->name(ast->name);
+
+    if (ast->name) {
+        sourceLocation = ast->name->firstToken();
+
+        if (QualifiedNameAST *q = ast->name->asQualifiedName()) {
+            if (q->unqualified_name)
+                sourceLocation = q->unqualified_name->firstToken();
+        }
+    }
+
+    Class *klass = control()->newClass(sourceLocation, className);
+    _type.setType(klass);
+
+    Scope *previousScope = switchScope(klass);
+
     for (BaseSpecifierListAST *it = ast->base_clause_list; it; it = it->next) {
-        this->baseSpecifier(it->value);
+        this->baseSpecifier(it->value, ast->colon_token, klass);
     }
     // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
-    // unsigned lbrace_token = ast->lbrace_token;
     for (DeclarationListAST *it = ast->member_specifier_list; it; it = it->next) {
         this->declaration(it->value);
     }
-    // unsigned rbrace_token = ast->rbrace_token;
-    // Class *symbol = ast->symbol;
+    (void) switchScope(previousScope);
+    ast->symbol = klass;
     return false;
 }
 
@@ -2148,3 +2347,18 @@ bool Bind::visit(ArrayDeclaratorAST *ast)
     return false;
 }
 
+int Bind::visibilityForAccessSpecifier(int tokenKind)
+{
+    switch (tokenKind) {
+    case T_PUBLIC:
+        return Symbol::Public;
+    case T_PROTECTED:
+        return Symbol::Protected;
+    case T_PRIVATE:
+        return Symbol::Private;
+    case T_Q_SIGNALS:
+        return Symbol::Protected;
+    default:
+        return Symbol::Public;
+    }
+}
diff --git a/src/shared/cplusplus/Bind.h b/src/shared/cplusplus/Bind.h
index 2dbdabb78bd932c70b9d651070581c78bb6c9b41..51cf61aa1231ce1d4e1b443d4723048a3f4a5497 100644
--- a/src/shared/cplusplus/Bind.h
+++ b/src/shared/cplusplus/Bind.h
@@ -78,12 +78,14 @@ public:
 protected:
     using ASTVisitor::translationUnit;
 
+    static int visibilityForAccessSpecifier(int tokenKind);
+
     const Name *objCSelectorArgument(ObjCSelectorArgumentAST *ast, bool *hasArg);
     void attribute(AttributeAST *ast);
     FullySpecifiedType declarator(DeclaratorAST *ast, const FullySpecifiedType &init, DeclaratorIdAST **declaratorId);
     void qtPropertyDeclarationItem(QtPropertyDeclarationItemAST *ast);
     void qtInterfaceName(QtInterfaceNameAST *ast);
-    void baseSpecifier(BaseSpecifierAST *ast);
+    void baseSpecifier(BaseSpecifierAST *ast, unsigned colon_token, Class *klass);
     void ctorInitializer(CtorInitializerAST *ast);
     void enumerator(EnumeratorAST *ast);
     FullySpecifiedType exceptionSpecification(ExceptionSpecificationAST *ast, const FullySpecifiedType &init);