hlopko created this revision.
hlopko added a reviewer: gribozavr.
hlopko added a project: clang.
Herald added a subscriber: cfe-commits.

Copy of https://reviews.llvm.org/D72073?id=235842, submitting with 
ilya-biryukov's permission.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76061

Files:
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/unittests/AST/DeclTest.cpp


Index: clang/unittests/AST/DeclTest.cpp
===================================================================
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -107,3 +107,20 @@
   ASSERT_TRUE(0 == MangleF.compare("\x01" "foo"));
   ASSERT_TRUE(0 == MangleG.compare("goo"));
 }
+
+TEST(Decl, MemberPointerStarLoc) {
+  StringRef Code = R"(
+    struct X {};
+    int X::* a;
+  )";
+  auto AST = tooling::buildASTFromCodeWithArgs(Code, {});
+  SourceManager &SM = AST->getSourceManager();
+
+  SmallVector<Decl *, 1> Decls;
+  AST->findFileRegionDecls(SM.getMainFileID(), Code.find('X'), 0, Decls);
+  ASSERT_TRUE(Decls.size() == 2);
+  VarDecl *D = cast<VarDecl>(Decls[1]);
+  auto TL = 
D->getTypeSourceInfo()->getTypeLoc().castAs<MemberPointerTypeLoc>();
+  auto StarLoc = TL.getStarLoc().printToString(SM);
+  ASSERT_EQ(StarLoc, "input.cc:3:12");
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -5840,7 +5840,7 @@
       }
 
       // Finally fill in MemberPointerLocInfo fields.
-      TL.setStarLoc(Chunk.Loc);
+      TL.setStarLoc(SourceLocation::getFromRawEncoding(Chunk.Mem.StarLoc));
       TL.setClassTInfo(ClsTInfo);
     }
     void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5643,8 +5643,8 @@
         return;
       }
 
-      SourceLocation Loc = ConsumeToken();
-      D.SetRangeEnd(Loc);
+      SourceLocation StarLoc = ConsumeToken();
+      D.SetRangeEnd(StarLoc);
       DeclSpec DS(AttrFactory);
       ParseTypeQualifierListOpt(DS);
       D.ExtendWithDeclSpec(DS);
@@ -5655,7 +5655,7 @@
       // Sema will have to catch (syntactically invalid) pointers into global
       // scope. It has to catch pointers into namespace scope anyway.
       D.AddTypeInfo(DeclaratorChunk::getMemberPointer(
-                        SS, DS.getTypeQualifiers(), DS.getEndLoc()),
+                        SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()),
                     std::move(DS.getAttributes()),
                     /* Don't replace range end. */ SourceLocation());
       return;
Index: clang/include/clang/Sema/DeclSpec.h
===================================================================
--- clang/include/clang/Sema/DeclSpec.h
+++ clang/include/clang/Sema/DeclSpec.h
@@ -1518,6 +1518,8 @@
   struct MemberPointerTypeInfo {
     /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic.
     unsigned TypeQuals : 5;
+    /// Location of the '*' token.
+    unsigned StarLoc;
     // CXXScopeSpec has a constructor, so it can't be a direct member.
     // So we need some pointer-aligned storage and a bit of trickery.
     alignas(CXXScopeSpec) char ScopeMem[sizeof(CXXScopeSpec)];
@@ -1660,11 +1662,13 @@
 
   static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
                                           unsigned TypeQuals,
-                                          SourceLocation Loc) {
+                                          SourceLocation StarLoc,
+                                          SourceLocation EndLoc) {
     DeclaratorChunk I;
     I.Kind          = MemberPointer;
     I.Loc           = SS.getBeginLoc();
-    I.EndLoc        = Loc;
+    I.EndLoc        = EndLoc;
+    I.Mem.StarLoc   = StarLoc.getRawEncoding();
     I.Mem.TypeQuals = TypeQuals;
     new (I.Mem.ScopeMem) CXXScopeSpec(SS);
     return I;


Index: clang/unittests/AST/DeclTest.cpp
===================================================================
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -107,3 +107,20 @@
   ASSERT_TRUE(0 == MangleF.compare("\x01" "foo"));
   ASSERT_TRUE(0 == MangleG.compare("goo"));
 }
+
+TEST(Decl, MemberPointerStarLoc) {
+  StringRef Code = R"(
+    struct X {};
+    int X::* a;
+  )";
+  auto AST = tooling::buildASTFromCodeWithArgs(Code, {});
+  SourceManager &SM = AST->getSourceManager();
+
+  SmallVector<Decl *, 1> Decls;
+  AST->findFileRegionDecls(SM.getMainFileID(), Code.find('X'), 0, Decls);
+  ASSERT_TRUE(Decls.size() == 2);
+  VarDecl *D = cast<VarDecl>(Decls[1]);
+  auto TL = D->getTypeSourceInfo()->getTypeLoc().castAs<MemberPointerTypeLoc>();
+  auto StarLoc = TL.getStarLoc().printToString(SM);
+  ASSERT_EQ(StarLoc, "input.cc:3:12");
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -5840,7 +5840,7 @@
       }
 
       // Finally fill in MemberPointerLocInfo fields.
-      TL.setStarLoc(Chunk.Loc);
+      TL.setStarLoc(SourceLocation::getFromRawEncoding(Chunk.Mem.StarLoc));
       TL.setClassTInfo(ClsTInfo);
     }
     void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -5643,8 +5643,8 @@
         return;
       }
 
-      SourceLocation Loc = ConsumeToken();
-      D.SetRangeEnd(Loc);
+      SourceLocation StarLoc = ConsumeToken();
+      D.SetRangeEnd(StarLoc);
       DeclSpec DS(AttrFactory);
       ParseTypeQualifierListOpt(DS);
       D.ExtendWithDeclSpec(DS);
@@ -5655,7 +5655,7 @@
       // Sema will have to catch (syntactically invalid) pointers into global
       // scope. It has to catch pointers into namespace scope anyway.
       D.AddTypeInfo(DeclaratorChunk::getMemberPointer(
-                        SS, DS.getTypeQualifiers(), DS.getEndLoc()),
+                        SS, DS.getTypeQualifiers(), StarLoc, DS.getEndLoc()),
                     std::move(DS.getAttributes()),
                     /* Don't replace range end. */ SourceLocation());
       return;
Index: clang/include/clang/Sema/DeclSpec.h
===================================================================
--- clang/include/clang/Sema/DeclSpec.h
+++ clang/include/clang/Sema/DeclSpec.h
@@ -1518,6 +1518,8 @@
   struct MemberPointerTypeInfo {
     /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic.
     unsigned TypeQuals : 5;
+    /// Location of the '*' token.
+    unsigned StarLoc;
     // CXXScopeSpec has a constructor, so it can't be a direct member.
     // So we need some pointer-aligned storage and a bit of trickery.
     alignas(CXXScopeSpec) char ScopeMem[sizeof(CXXScopeSpec)];
@@ -1660,11 +1662,13 @@
 
   static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
                                           unsigned TypeQuals,
-                                          SourceLocation Loc) {
+                                          SourceLocation StarLoc,
+                                          SourceLocation EndLoc) {
     DeclaratorChunk I;
     I.Kind          = MemberPointer;
     I.Loc           = SS.getBeginLoc();
-    I.EndLoc        = Loc;
+    I.EndLoc        = EndLoc;
+    I.Mem.StarLoc   = StarLoc.getRawEncoding();
     I.Mem.TypeQuals = TypeQuals;
     new (I.Mem.ScopeMem) CXXScopeSpec(SS);
     return I;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to