r209511 - PR19352 - getLocation() points to the wrong position for FriendDecls

Nikola Smiljanic popizdeh at gmail.com
Mon Sep 1 21:57:07 PDT 2014


Changing getLocStart to getLocEnd would indeed fix the first issue, are you
OK with this Richard?

As for the second example, this type of declaration appears unsupported
(not sure what this exactly means), but I wouldn't be surprised if ast is
incomplete because of this. Namely NumTPLists is 0 when FriendDecl is
coming from the instantiation. This is from getSourceRange:

    else if (TypeSourceInfo *TInfo = getFriendType()) {
      SourceLocation StartL = (NumTPLists == 0)
        ? getFriendLoc()
        : getTPLists()[0]->getTemplateLoc();
      return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc())

On Sat, Aug 30, 2014 at 4:43 PM, Abramo Bagnara <abramo.bagnara at bugseng.com>
wrote:

> Il 30/08/2014 03:02, Nikola Smiljanic ha scritto:
> >     > This seems wrong to me.
> >     >
> >     > Did you mean to write getLocEnd() instead? (Under the assumption
> that
> >     > identifier should comes last in class type)
> >
> >
> > This was done so that 'friend struct A' and 'friend A' (C++11) have
> > different location since former is also a forward declaration. Does that
> > make sense or have I misunderstood your question?
>
> AFAIK this is not correct: getLocation() should always return the
> location of identifier token.
>
> >
> >     It is useful to know that currently for:
> >
> >     template <class U> class C {
> >       template<class T> friend struct A<T>::B;
> >     };
> >
> >
> > Not really sure what A is supposed to be here but this code is
> > ill-formed: explicit specialization of non-template struct 'A'
>
> This was only the part containing shown location, full code is
>
> template <class T> struct A
> {
>   struct B { };
> };
>
> template <class U> class C {
>   template <class T> friend struct A<T>::B;
> };
>
>
> --
> Abramo Bagnara
>
> BUGSENG srl - http://bugseng.com
> mailto:abramo.bagnara at bugseng.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140902/d94013dd/attachment.html>
-------------- next part --------------
diff --git lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaDeclCXX.cpp
index 6a48162..a844f42 100644
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -11651,9 +11651,8 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation LocStart,
   //   If the type specifier in a friend declaration designates a (possibly
   //   cv-qualified) class type, that class is declared as a friend; otherwise,
   //   the friend declaration is ignored.
-  return FriendDecl::Create(Context, CurContext,
-                            TSInfo->getTypeLoc().getLocStart(), TSInfo,
-                            FriendLoc);
+  return FriendDecl::Create(
+      Context, CurContext, TSInfo->getTypeLoc().getLocEnd(), TSInfo, FriendLoc);
 }
 
 /// Handle a friend tag declaration where the scope specifier was
diff --git unittests/AST/SourceLocationTest.cpp unittests/AST/SourceLocationTest.cpp
index ca5a889..f3ce758 100644
--- unittests/AST/SourceLocationTest.cpp
+++ unittests/AST/SourceLocationTest.cpp
@@ -301,7 +301,7 @@ TEST(FriendDecl, FriendNonMemberFunctionDefinitionRange) {
 
 TEST(FriendDecl, FriendElaboratedTypeLocation) {
   LocationVerifier<FriendDecl> Verifier;
-  Verifier.expectLocation(2, 8);
+  Verifier.expectLocation(2, 14);
   EXPECT_TRUE(Verifier.match("struct A {\n"
                              "friend class B;\n"
                              "};\n",


More information about the cfe-commits mailing list