diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index d0e5600523e04ab5ecab582e8d9e84823f75a276..98e8616f704b25aca6955678f030098443b87bd1 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -131,18 +131,6 @@ void CheckDeclaration::checkFunctionArguments(Function *fun)
     }
 }
 
-unsigned CheckDeclaration::locationOfDeclaratorId(DeclaratorAST *declarator) const
-{
-    if (declarator && declarator->core_declarator) {
-        if (DeclaratorIdAST *declaratorId = declarator->core_declarator->asDeclaratorId())
-            return declaratorId->firstToken();
-        else if (NestedDeclaratorAST *nested = declarator->core_declarator->asNestedDeclarator())
-            return locationOfDeclaratorId(nested->declarator);
-    }
-
-    return 0;
-}
-
 bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
 {
     FullySpecifiedType ty = semantic()->check(ast->decl_specifier_list, _scope);
@@ -198,7 +186,7 @@ bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
         FullySpecifiedType declTy = semantic()->check(it->value, qualTy,
                                                       _scope, &name);
 
-        unsigned location = locationOfDeclaratorId(it->value);
+        unsigned location = semantic()->location(it->value);
         if (! location) {
             if (it->value)
                 location = it->value->firstToken();
@@ -310,7 +298,7 @@ bool CheckDeclaration::visit(ExceptionDeclarationAST *ast)
     FullySpecifiedType declTy = semantic()->check(ast->declarator, qualTy,
                                                   _scope, &name);
 
-    unsigned location = locationOfDeclaratorId(ast->declarator);
+    unsigned location = semantic()->location(ast->declarator);
     if (! location) {
         if (ast->declarator)
             location = ast->declarator->firstToken();
@@ -351,8 +339,12 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
         fun->setUnavailable(true);
     fun->members()->setStartOffset(funStartOffset);
     fun->members()->setEndOffset(tokenAt(ast->lastToken() - 1).end());
-    if (ast->declarator)
-        fun->setSourceLocation(ast->declarator->firstToken(), translationUnit());
+    if (ast->declarator) {
+        unsigned loc = semantic()->location(ast->declarator);
+        if (! loc)
+            loc = ast->declarator->firstToken();
+        fun->setSourceLocation(loc, translationUnit());
+    }
     fun->setName(name);
     fun->setTemplateParameters(_templateParameters);
     fun->setVisibility(semantic()->currentVisibility());
@@ -450,7 +442,7 @@ bool CheckDeclaration::visit(NamespaceAliasDefinitionAST *ast)
 
 bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
 {
-    unsigned sourceLocation = locationOfDeclaratorId(ast->declarator);
+    unsigned sourceLocation = semantic()->location(ast->declarator);
     if (! sourceLocation) {
         if (ast->declarator)
             sourceLocation = ast->declarator->firstToken();
diff --git a/src/shared/cplusplus/CheckDeclaration.h b/src/shared/cplusplus/CheckDeclaration.h
index acd71c557bdc9f33fe55e36042e4fb1b8d9bdb23..90690d2720be0111de4ffd0f90a8ff8ff84c2834 100644
--- a/src/shared/cplusplus/CheckDeclaration.h
+++ b/src/shared/cplusplus/CheckDeclaration.h
@@ -73,8 +73,6 @@ protected:
 
     using ASTVisitor::visit;
 
-    unsigned locationOfDeclaratorId(DeclaratorAST *declarator) const;
-
     virtual bool visit(SimpleDeclarationAST *ast);
     virtual bool visit(EmptyDeclarationAST *ast);
     virtual bool visit(AccessDeclarationAST *ast);
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index be08ebdf7afc4fabc632e85a58b57d3af41d031b..019852cc7815edf2c20f96dd80c8499bc84187c9 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -316,4 +316,38 @@ int Semantic::visibilityForClassKey(int tokenKind) const
     }
 }
 
+unsigned Semantic::location(DeclaratorAST *ast) const
+{
+    if (! ast)
+        return 0;
+
+    else if (CPlusPlus::CoreDeclaratorAST *core = ast->core_declarator)
+        return location(core);
+
+    return ast->firstToken();
+}
+
+unsigned Semantic::location(CoreDeclaratorAST *ast) const
+{
+    if (! ast)
+        return 0;
+
+    else if (CPlusPlus::DeclaratorIdAST *declaratorId = ast->asDeclaratorId())
+        return location(declaratorId->name);
 
+    else if (CPlusPlus::NestedDeclaratorAST *nested = ast->asNestedDeclarator())
+        return location(nested->declarator);
+
+    return ast->firstToken();
+}
+
+unsigned Semantic::location(NameAST *ast) const
+{
+    if (! ast)
+        return 0;
+
+    else if (CPlusPlus::QualifiedNameAST *qualifiedName = ast->asQualifiedName())
+        return location(qualifiedName->unqualified_name);
+
+    return ast->firstToken();
+}
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index cc6e3454835d1f5c46c31510f36378a155dd57cc..69d5dce0b61976906c32bdde8c1c9ec4faeaad07 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -132,6 +132,10 @@ public:
     int visibilityForObjCAccessSpecifier(int tokenKind) const;
     bool isObjCClassMethod(int tokenKind) const;
 
+    unsigned location(DeclaratorAST *ast) const;
+    unsigned location(CoreDeclaratorAST *ast) const;
+    unsigned location(NameAST *ast) const;
+
 private:
     class Data;
     friend class Data;