diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index a53161245cac21cf1a8e4c4099e7928d172ba1b7..dcb2364b11c6ccdc29b80de909089d9e9927deda 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -167,6 +167,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
                 symbol->setTemplateParameters(_templateParameters);
                 _templateParameters = 0;
             }
+            if (ty.isDeprecated())
+                symbol->setDeprecated(true);
 
             _scope->enterSymbol(symbol);
             return false;
@@ -198,6 +200,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
             fun->setName(name);
             fun->setMethodKey(semantic()->currentMethodKey());
             fun->setVirtual(ty.isVirtual());
+            if (ty.isDeprecated())
+                fun->setDeprecated(true);
             if (isQ_SIGNAL)
                 fun->setMethodKey(Function::SignalMethod);
             else if (isQ_SLOT)
@@ -215,6 +219,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
         symbol->setEndOffset(tokenAt(ast->lastToken()).offset);
 
         symbol->setType(declTy);
+        if (declTy.isDeprecated())
+            symbol->setDeprecated(true);
 
         if (_templateParameters && it == ast->declarator_list) {
             symbol->setTemplateParameters(_templateParameters);
@@ -235,6 +241,8 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
             symbol->setStorage(Symbol::Mutable);
         else if (ty.isTypedef())
             symbol->setStorage(Symbol::Typedef);
+        else if (ty.isDeprecated())
+            symbol->setDeprecated(true);
 
         if (it->value && it->value->initializer) {
             FullySpecifiedType initTy = semantic()->check(it->value->initializer, _scope);
@@ -314,6 +322,8 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
 
     Function *fun = funTy->asFunctionType();
     fun->setVirtual(ty.isVirtual());
+    if (ty.isDeprecated())
+        fun->setDeprecated(true);
     fun->setStartOffset(tokenAt(ast->firstToken()).offset);
     fun->setEndOffset(tokenAt(ast->lastToken()).offset);
     if (ast->declarator)
@@ -703,6 +713,8 @@ bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast)
     symbol->setStartOffset(tokenAt(ast->firstToken()).offset);
     symbol->setEndOffset(tokenAt(ast->lastToken()).offset);
     symbol->setVisibility(semantic()->currentObjCVisibility());
+    if (ty.isDeprecated())
+        symbol->setDeprecated(true);
 
     _scope->enterSymbol(symbol);
 
diff --git a/src/shared/cplusplus/CheckDeclarator.cpp b/src/shared/cplusplus/CheckDeclarator.cpp
index 5b19b6cb5399ab84c894295f0e4510c176dd5610..dfb045b3a0684d2bc37f11229834cf27bf645bb1 100644
--- a/src/shared/cplusplus/CheckDeclarator.cpp
+++ b/src/shared/cplusplus/CheckDeclarator.cpp
@@ -195,17 +195,9 @@ bool CheckDeclarator::visit(FunctionDeclaratorAST *ast)
     }
 
     FullySpecifiedType funTy(fun);
-    _fullySpecifiedType = funTy;
-
-    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
-        SimpleSpecifierAST *cv = static_cast<SimpleSpecifierAST *>(it->value);
-        const int k = tokenKind(cv->specifier_token);
-        if (k == T_CONST)
-            fun->setConst(true);
-        else if (k == T_VOLATILE)
-            fun->setVolatile(true);
-    }
+    funTy = semantic()->check(ast->cv_qualifier_list, _scope, funTy);
 
+    _fullySpecifiedType = funTy;
     return false;
 }
 
@@ -289,6 +281,8 @@ bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
         method->setVariadic(true);
 
     _fullySpecifiedType = FullySpecifiedType(method);
+    _fullySpecifiedType = semantic()->check(ast->attribute_list, _scope,
+                                            _fullySpecifiedType);
 
     return false;
 }
diff --git a/src/shared/cplusplus/CheckSpecifier.cpp b/src/shared/cplusplus/CheckSpecifier.cpp
index 70cdcacd5a2c81c5ce09f173ba581becb766c232..2d1d2e404a9bbf949b19603cd1adf92ee604886f 100644
--- a/src/shared/cplusplus/CheckSpecifier.cpp
+++ b/src/shared/cplusplus/CheckSpecifier.cpp
@@ -69,9 +69,11 @@ CheckSpecifier::CheckSpecifier(Semantic *semantic)
 CheckSpecifier::~CheckSpecifier()
 { }
 
-FullySpecifiedType CheckSpecifier::check(SpecifierListAST *specifier, Scope *scope)
+FullySpecifiedType CheckSpecifier::check(SpecifierListAST *specifier,
+                                         Scope *scope,
+                                         const FullySpecifiedType &ty)
 {
-    FullySpecifiedType previousType = switchFullySpecifiedType(FullySpecifiedType());
+    FullySpecifiedType previousType = switchFullySpecifiedType(ty);
     Scope *previousScope = switchScope(scope);
     SpecifierListAST *previousSpecifier = switchSpecifier(specifier);
     accept(specifier);
@@ -80,9 +82,11 @@ FullySpecifiedType CheckSpecifier::check(SpecifierListAST *specifier, Scope *sco
     return switchFullySpecifiedType(previousType);
 }
 
-FullySpecifiedType CheckSpecifier::check(ObjCTypeNameAST *typeName, Scope *scope)
+FullySpecifiedType CheckSpecifier::check(ObjCTypeNameAST *typeName,
+                                         Scope *scope,
+                                         const FullySpecifiedType &ty)
 {
-    FullySpecifiedType previousType = switchFullySpecifiedType(FullySpecifiedType());
+    FullySpecifiedType previousType = switchFullySpecifiedType(ty);
     Scope *previousScope = switchScope(scope);
 
     accept(typeName);
@@ -327,6 +331,9 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast)
     klass->setVisibility(semantic()->currentVisibility());
     _scope->enterSymbol(klass);
     _fullySpecifiedType.setType(klass);
+    accept(ast->attribute_list);
+    if (_fullySpecifiedType.isDeprecated())
+        klass->setDeprecated(true);
 
     for (BaseSpecifierListAST *it = ast->base_clause_list; it; it = it->next) {
         BaseSpecifierAST *base = it->value;
@@ -377,6 +384,7 @@ bool CheckSpecifier::visit(ElaboratedTypeSpecifierAST *ast)
 {
     const Name *name = semantic()->check(ast->name, _scope);
     _fullySpecifiedType.setType(control()->namedType(name));
+    accept(ast->attribute_list);
     return false;
 }
 
@@ -414,7 +422,11 @@ bool CheckSpecifier::visit(TypeofSpecifierAST *ast)
     return false;
 }
 
-bool CheckSpecifier::visit(AttributeSpecifierAST * /*ast*/)
+bool CheckSpecifier::visit(AttributeAST *ast)
 {
+    if (ast->identifier_token) {
+        if (identifier(ast->identifier_token) == control()->deprecatedId())
+            _fullySpecifiedType.setDeprecated(true);
+    }
     return false;
 }
diff --git a/src/shared/cplusplus/CheckSpecifier.h b/src/shared/cplusplus/CheckSpecifier.h
index b2653e1b9bf75eb06151471b1320311737be0141..e66b30603095dea604d78f135bed8710e022c4df 100644
--- a/src/shared/cplusplus/CheckSpecifier.h
+++ b/src/shared/cplusplus/CheckSpecifier.h
@@ -62,8 +62,10 @@ public:
     CheckSpecifier(Semantic *semantic);
     virtual ~CheckSpecifier();
 
-    FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope);
-    FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope);
+    FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope,
+                             const FullySpecifiedType &ty = FullySpecifiedType());
+    FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope,
+                             const FullySpecifiedType &ty = FullySpecifiedType());
 
 protected:
     SpecifierListAST *switchSpecifier(SpecifierListAST *specifier);
@@ -78,7 +80,7 @@ protected:
     virtual bool visit(ElaboratedTypeSpecifierAST *ast);
     virtual bool visit(EnumSpecifierAST *ast);
     virtual bool visit(TypeofSpecifierAST *ast);
-    virtual bool visit(AttributeSpecifierAST *ast);
+    virtual bool visit(AttributeAST *ast);
 
 private:
     SpecifierListAST *_specifier;
diff --git a/src/shared/cplusplus/FullySpecifiedType.cpp b/src/shared/cplusplus/FullySpecifiedType.cpp
index 7acff01c045dd04685769a15f611e41b8f53fc3e..7cbfdc88f02c3d48a32fcc1fe97f8d160e7c33c8 100644
--- a/src/shared/cplusplus/FullySpecifiedType.cpp
+++ b/src/shared/cplusplus/FullySpecifiedType.cpp
@@ -84,6 +84,8 @@ FullySpecifiedType FullySpecifiedType::qualifiedType() const
     ty.setInline(false);
     ty.setVirtual(false);
     ty.setExplicit(false);
+
+    ty.setDeprecated(false);
     return ty;
 }
 
@@ -165,6 +167,12 @@ bool FullySpecifiedType::isExplicit() const
 void FullySpecifiedType::setExplicit(bool isExplicit)
 { f._isExplicit = isExplicit; }
 
+bool FullySpecifiedType::isDeprecated() const
+{ return f._isDeprecated; }
+
+void FullySpecifiedType::setDeprecated(bool isDeprecated)
+{ f._isDeprecated = isDeprecated; }
+
 bool FullySpecifiedType::isEqualTo(const FullySpecifiedType &other) const
 {
     if (_flags != other._flags)
diff --git a/src/shared/cplusplus/FullySpecifiedType.h b/src/shared/cplusplus/FullySpecifiedType.h
index 17959bf10dfb19c553d11ac28b030713c24094e7..7001bca63a9db966dafe18ed8ad08e097bdf8daf 100644
--- a/src/shared/cplusplus/FullySpecifiedType.h
+++ b/src/shared/cplusplus/FullySpecifiedType.h
@@ -107,6 +107,9 @@ public:
     bool isExplicit() const;
     void setExplicit(bool isExplicit);
 
+    bool isDeprecated() const;
+    void setDeprecated(bool isDeprecated);
+
     bool isEqualTo(const FullySpecifiedType &other) const;
 
     Type &operator*();
@@ -148,6 +151,9 @@ private:
         unsigned _isInline: 1;
         unsigned _isVirtual: 1;
         unsigned _isExplicit: 1;
+
+        // speficiers from attributes
+        unsigned _isDeprecated: 1;
     };
     union {
         unsigned _flags;
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index c03e059009cb4f75f2062fc9fa4c923faaf3d736..ebd3aacec258757d93daf072e0dd2c5b41190cee 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -125,8 +125,9 @@ TranslationUnit *Semantic::translationUnit() const
 Control *Semantic::control() const
 { return d->control; }
 
-FullySpecifiedType Semantic::check(SpecifierListAST *specifier, Scope *scope)
-{ return d->checkSpecifier->check(specifier, scope); }
+FullySpecifiedType Semantic::check(SpecifierListAST *specifier, Scope *scope,
+                                   const FullySpecifiedType &type)
+{ return d->checkSpecifier->check(specifier, scope, type); }
 
 void Semantic::check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters)
 { d->checkDeclaration->check(declaration, scope, templateParameters); }
@@ -142,8 +143,9 @@ FullySpecifiedType Semantic::check(PtrOperatorListAST *ptrOperators, const Fully
 FullySpecifiedType Semantic::check(ObjCMethodPrototypeAST *methodPrototype, Scope *scope)
 { return d->checkDeclarator->check(methodPrototype, scope); }
 
-FullySpecifiedType Semantic::check(ObjCTypeNameAST *typeName, Scope *scope)
-{ return d->checkSpecifier->check(typeName, scope); }
+FullySpecifiedType Semantic::check(ObjCTypeNameAST *typeName, Scope *scope,
+                                   const FullySpecifiedType &type)
+{ return d->checkSpecifier->check(typeName, scope, type); }
 
 void Semantic::check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope)
 { return d->checkName->check(arg, scope); }
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index c9e1c5263f0a8122d9ae2c56269f9cd41b2cadf7..a804a72328e8a895e11941e59185c4dd3805ceec 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -51,7 +51,7 @@
 
 #include "CPlusPlusForwardDeclarations.h"
 #include "ASTfwd.h"
-
+#include "FullySpecifiedType.h"
 
 namespace CPlusPlus {
 
@@ -67,7 +67,8 @@ public:
     TranslationUnit *translationUnit() const;
     Control *control() const;
 
-    FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope);
+    FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope,
+                             const FullySpecifiedType &type = FullySpecifiedType());
 
     FullySpecifiedType check(DeclaratorAST *declarator, const FullySpecifiedType &type,
                              Scope *scope, const Name **name = 0); // ### ugly
@@ -87,7 +88,8 @@ public:
 
     const Name *check(NestedNameSpecifierListAST *name, Scope *scope);
 
-    FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope);
+    FullySpecifiedType check(ObjCTypeNameAST *typeName, Scope *scope,
+                             const FullySpecifiedType &type = FullySpecifiedType());
 
     void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope);
 
diff --git a/src/shared/cplusplus/Symbol.cpp b/src/shared/cplusplus/Symbol.cpp
index 90ce0557379152b26067e9657e0b55db90b362e7..2da2aa9c23767232b212e609735f64df7b42bc1d 100644
--- a/src/shared/cplusplus/Symbol.cpp
+++ b/src/shared/cplusplus/Symbol.cpp
@@ -212,6 +212,12 @@ unsigned Symbol::sourceOffset() const
 bool Symbol::isGenerated() const
 { return _isGenerated; }
 
+bool Symbol::isDeprecated() const
+{ return _isDeprecated; }
+
+void Symbol::setDeprecated(bool isDeprecated)
+{ _isDeprecated = isDeprecated; }
+
 void Symbol::setSourceLocation(unsigned sourceLocation)
 {
     _sourceLocation = sourceLocation;
diff --git a/src/shared/cplusplus/Symbol.h b/src/shared/cplusplus/Symbol.h
index b1dab975e7d9a66ba8332b1d134094697eb60b39..33bd7c92e8bca22f372a61a3c583da6f07902af6 100644
--- a/src/shared/cplusplus/Symbol.h
+++ b/src/shared/cplusplus/Symbol.h
@@ -291,6 +291,9 @@ public:
 
     bool isGenerated() const;
 
+    bool isDeprecated() const;
+    void setDeprecated(bool isDeprecated);
+
     Symbol *enclosingSymbol() const;
 
     /// Returns the eclosing namespace scope.
@@ -334,6 +337,7 @@ private:
     Symbol *_next;
 
     bool _isGenerated: 1;
+    bool _isDeprecated: 1;
 
     class IdentityForName;
     class HashCode;