getLocation() for a friend type declaration

Hello,

I’m trying to get a source location for a type name identifier in FriendDecl, but getLocation() method returns source location of keyword ‘friend’. Such behavior confused me a bit, because usually getLocation() returns an identifier location. I’ve released I can get location which I need through DeclSpec::getTypeSpecTypeNameLoc(). But could you explain me why getLocation() behavior differs from expected one (at least expected by me) in this case?

Hello,

I'm trying to get a source location for a type name identifier in
FriendDecl, but getLocation() method returns source location of keyword
'friend'. Such behavior confused me a bit, because usually getLocation()
returns an identifier location. I've released I can get location which I
need through DeclSpec::getTypeSpecTypeNameLoc(). But could you explain me
why getLocation() behavior differs from expected one (at least expected by
me) in this case?

From the code this shouldn't be the case. Unless you're calling

getFriendLoc() instead of getLocation().

Cheers,
/Manuel

Hello Manuel,

I’ve implemented RecursiveASTVisitor with the following VisitXXX method:

bool VisitFriendDecl(FriendDecl *Declaration) {
FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocation());
if (FullLocation.isValid()){
llvm::outs() << "Found friend declaration at "
<< FullLocation.getSpellingLineNumber() << “:”
<< FullLocation.getSpellingColumnNumber() << “\n”;
}
return true;
}

Then I run a tool which contains my visitor on the following (incorrect) code

1 template
2 class F{};
3 class F1{};
4 void f(){};
5
6 class classX
7 {
8 friend class classXfriend;
9 friend class F;
10 friend class F1;
11 friend void f();
12 };

Tool displayed the following:

Found friend declaration at 8:3
Found friend declaration at 9:3
Found friend declaration at 10:3
Found friend declaration at 11:15

As you can see getLocation() refers to a friend keyword token in the case of a friend type declaration. Tool works with compilable code in the same way.

Hello Manuel,

I've implemented RecursiveASTVisitor with the following VisitXXX method:

   bool VisitFriendDecl(FriendDecl *Declaration) {
      FullSourceLoc FullLocation =
Context->getFullLoc(Declaration->getLocation());
      if (FullLocation.isValid()){
        llvm::outs() << "Found friend declaration at "
                     << FullLocation.getSpellingLineNumber() << ":"
                     << FullLocation.getSpellingColumnNumber() << "\n";
      }
      return true;
    }

Then I run a tool which contains my visitor on the following (incorrect)
code

  1 template<typename T>
  2 class F{};
  3 class F1{};
  4 void f(){};
  5
  6 class classX
  7 {
  8 friend class classXfriend;
  9 friend class F<int>;
10 friend class F1;
11 friend void f();
12 };

Tool displayed the following:

Found friend declaration at 8:3
Found friend declaration at 9:3
Found friend declaration at 10:3
Found friend declaration at 11:15

As you can see getLocation() refers to a friend keyword token in the case
of a friend type declaration. Tool works with compilable code in the same
way.

After a short conversation with Richard Smith, we think this is a bug.
Filed http://llvm.org/bugs/show_bug.cgi?id=19352. Patches welcome :o)

Cheers,
/Manuel