r284885 - [Sema] Store a SourceRange for multi-token builtin types

Malcolm Parsons via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 21 14:13:57 PDT 2016


Author: malcolm.parsons
Date: Fri Oct 21 16:13:56 2016
New Revision: 284885

URL: http://llvm.org/viewvc/llvm-project?rev=284885&view=rev
Log:
[Sema] Store a SourceRange for multi-token builtin types

Summary:
clang-tidy's modernize-use-auto check uses the SourceRange of a
TypeLoc when replacing the type with auto.
This was producing the wrong result for multi-token builtin types
like long long:

-long long *ll = new long long();
+auto long *ll = new long long();

Reviewers: alexfh, hokein, rsmith, Prazek, aaron.ballman

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D25363

Modified:
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/Sema/DeclSpec.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/unittests/AST/SourceLocationTest.cpp

Modified: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=284885&r1=284884&r2=284885&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (original)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Fri Oct 21 16:13:56 2016
@@ -512,7 +512,7 @@ private:
 
 
 struct BuiltinLocInfo {
-  SourceLocation BuiltinLoc;
+  SourceRange BuiltinRange;
 };
 
 /// \brief Wrapper for source info for builtin types.
@@ -522,10 +522,19 @@ class BuiltinTypeLoc : public ConcreteTy
                                               BuiltinLocInfo> {
 public:
   SourceLocation getBuiltinLoc() const {
-    return getLocalData()->BuiltinLoc;
+    return getLocalData()->BuiltinRange.getBegin();
   }
   void setBuiltinLoc(SourceLocation Loc) {
-    getLocalData()->BuiltinLoc = Loc;
+    getLocalData()->BuiltinRange = Loc;
+  }
+  void expandBuiltinRange(SourceRange Range) {
+    SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
+    if (!BuiltinRange.getBegin().isValid()) {
+      BuiltinRange = Range;
+    } else {
+      BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
+      BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
+    }
   }
 
   SourceLocation getNameLoc() const { return getBuiltinLoc(); }
@@ -554,7 +563,7 @@ public:
   }
 
   SourceRange getLocalSourceRange() const {
-    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
+    return getLocalData()->BuiltinRange;
   }
 
   TypeSpecifierSign getWrittenSignSpec() const {

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=284885&r1=284884&r2=284885&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Fri Oct 21 16:13:56 2016
@@ -380,7 +380,8 @@ private:
   SourceRange Range;
 
   SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc;
-  SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
+  SourceRange TSWRange;
+  SourceLocation TSCLoc, TSSLoc, TSTLoc, AltiVecLoc;
   /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union,
   /// typename, then this is the location of the named type (if present);
   /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and
@@ -503,7 +504,8 @@ public:
   SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
   SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
 
-  SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
+  SourceLocation getTypeSpecWidthLoc() const { return TSWRange.getBegin(); }
+  SourceRange getTypeSpecWidthRange() const { return TSWRange; }
   SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
   SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
   SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; }

Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=284885&r1=284884&r2=284885&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
+++ cfe/trunk/lib/Sema/DeclSpec.cpp Fri Oct 21 16:13:56 2016
@@ -610,14 +610,16 @@ bool DeclSpec::SetTypeSpecWidth(TSW W, S
                                 const char *&PrevSpec,
                                 unsigned &DiagID,
                                 const PrintingPolicy &Policy) {
-  // Overwrite TSWLoc only if TypeSpecWidth was unspecified, so that
+  // Overwrite TSWRange.Begin only if TypeSpecWidth was unspecified, so that
   // for 'long long' we will keep the source location of the first 'long'.
   if (TypeSpecWidth == TSW_unspecified)
-    TSWLoc = Loc;
+    TSWRange.setBegin(Loc);
   // Allow turning long -> long long.
   else if (W != TSW_longlong || TypeSpecWidth != TSW_long)
     return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
   TypeSpecWidth = W;
+  // Remember location of the last 'long'
+  TSWRange.setEnd(Loc);
   return false;
 }
 
@@ -997,9 +999,9 @@ void DeclSpec::Finish(Sema &S, const Pri
        TypeQualifiers)) {
     const unsigned NumLocs = 9;
     SourceLocation ExtraLocs[NumLocs] = {
-      TSWLoc, TSCLoc, TSSLoc, AltiVecLoc,
-      TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc, TQ_unalignedLoc
-    };
+        TSWRange.getBegin(), TSCLoc,       TSSLoc,
+        AltiVecLoc,          TQ_constLoc,  TQ_restrictLoc,
+        TQ_volatileLoc,      TQ_atomicLoc, TQ_unalignedLoc};
     FixItHint Hints[NumLocs];
     SourceLocation FirstLoc;
     for (unsigned I = 0; I != NumLocs; ++I) {
@@ -1041,8 +1043,8 @@ void DeclSpec::Finish(Sema &S, const Pri
       // Only 'short' and 'long long' are valid with vector bool. (PIM 2.1)
       if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short) &&
           (TypeSpecWidth != TSW_longlong))
-        S.Diag(TSWLoc, diag::err_invalid_vector_bool_decl_spec)
-          << getSpecifierName((TSW)TypeSpecWidth);
+        S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec)
+            << getSpecifierName((TSW)TypeSpecWidth);
 
       // vector bool long long requires VSX support or ZVector.
       if ((TypeSpecWidth == TSW_longlong) &&
@@ -1059,7 +1061,8 @@ void DeclSpec::Finish(Sema &S, const Pri
       // vector long double and vector long long double are never allowed.
       // vector double is OK for Power7 and later, and ZVector.
       if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong)
-        S.Diag(TSWLoc, diag::err_invalid_vector_long_double_decl_spec);
+        S.Diag(TSWRange.getBegin(),
+               diag::err_invalid_vector_long_double_decl_spec);
       else if (!S.Context.getTargetInfo().hasFeature("vsx") &&
                !S.getLangOpts().ZVector)
         S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec);
@@ -1070,10 +1073,11 @@ void DeclSpec::Finish(Sema &S, const Pri
     } else if (TypeSpecWidth == TSW_long) {
       // vector long is unsupported for ZVector and deprecated for AltiVec.
       if (S.getLangOpts().ZVector)
-        S.Diag(TSWLoc, diag::err_invalid_vector_long_decl_spec);
+        S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec);
       else
-        S.Diag(TSWLoc, diag::warn_vector_long_decl_spec_combination)
-          << getSpecifierName((TST)TypeSpecType, Policy);
+        S.Diag(TSWRange.getBegin(),
+               diag::warn_vector_long_decl_spec_combination)
+            << getSpecifierName((TST)TypeSpecType, Policy);
     }
 
     if (TypeAltiVecPixel) {
@@ -1106,8 +1110,8 @@ void DeclSpec::Finish(Sema &S, const Pri
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
     else if (TypeSpecType != TST_int) {
-      S.Diag(TSWLoc, diag::err_invalid_width_spec) << (int)TypeSpecWidth
-        <<  getSpecifierName((TST)TypeSpecType, Policy);
+      S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
+          << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecType = TST_int;
       TypeSpecOwned = false;
     }
@@ -1116,8 +1120,8 @@ void DeclSpec::Finish(Sema &S, const Pri
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int;  // long -> long int.
     else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
-      S.Diag(TSWLoc, diag::err_invalid_width_spec) << (int)TypeSpecWidth
-        << getSpecifierName((TST)TypeSpecType, Policy);
+      S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
+          << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecType = TST_int;
       TypeSpecOwned = false;
     }

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=284885&r1=284884&r2=284885&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri Oct 21 16:13:56 2016
@@ -4907,11 +4907,9 @@ namespace {
         TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs();
         // Try to have a meaningful source location.
         if (TL.getWrittenSignSpec() != TSS_unspecified)
-          // Sign spec loc overrides the others (e.g., 'unsigned long').
-          TL.setBuiltinLoc(DS.getTypeSpecSignLoc());
-        else if (TL.getWrittenWidthSpec() != TSW_unspecified)
-          // Width spec loc overrides type spec loc (e.g., 'short int').
-          TL.setBuiltinLoc(DS.getTypeSpecWidthLoc());
+          TL.expandBuiltinRange(DS.getTypeSpecSignLoc());
+        if (TL.getWrittenWidthSpec() != TSW_unspecified)
+          TL.expandBuiltinRange(DS.getTypeSpecWidthRange());
       }
     }
     void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {

Modified: cfe/trunk/unittests/AST/SourceLocationTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/SourceLocationTest.cpp?rev=284885&r1=284884&r2=284885&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/SourceLocationTest.cpp (original)
+++ cfe/trunk/unittests/AST/SourceLocationTest.cpp Fri Oct 21 16:13:56 2016
@@ -148,6 +148,96 @@ TEST(VarDecl, VMTypeFixedVarDeclRange) {
                              varDecl(), Lang_C89));
 }
 
+TEST(TypeLoc, IntRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 1);
+  EXPECT_TRUE(Verifier.match("int a;", typeLoc()));
+}
+
+TEST(TypeLoc, LongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 1);
+  EXPECT_TRUE(Verifier.match("long a;", typeLoc()));
+}
+
+TEST(TypeLoc, LongDoubleRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 6);
+  EXPECT_TRUE(Verifier.match("long double a;", typeLoc()));
+}
+
+TEST(TypeLoc, DoubleLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 8);
+  EXPECT_TRUE(Verifier.match("double long a;", typeLoc()));
+}
+
+TEST(TypeLoc, LongIntRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 6);
+  EXPECT_TRUE(Verifier.match("long int a;", typeLoc()));
+}
+
+TEST(TypeLoc, IntLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 5);
+  EXPECT_TRUE(Verifier.match("int long a;", typeLoc()));
+}
+
+TEST(TypeLoc, UnsignedIntRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 10);
+  EXPECT_TRUE(Verifier.match("unsigned int a;", typeLoc()));
+}
+
+TEST(TypeLoc, IntUnsignedRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 5);
+  EXPECT_TRUE(Verifier.match("int unsigned a;", typeLoc()));
+}
+
+TEST(TypeLoc, LongLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 6);
+  EXPECT_TRUE(Verifier.match("long long a;", typeLoc()));
+}
+
+TEST(TypeLoc, UnsignedLongLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 15);
+  EXPECT_TRUE(Verifier.match("unsigned long long a;", typeLoc()));
+}
+
+TEST(TypeLoc, LongUnsignedLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 15);
+  EXPECT_TRUE(Verifier.match("long unsigned long a;", typeLoc()));
+}
+
+TEST(TypeLoc, LongLongUnsignedRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 11);
+  EXPECT_TRUE(Verifier.match("long long unsigned a;", typeLoc()));
+}
+
+TEST(TypeLoc, ConstLongLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 7, 1, 12);
+  EXPECT_TRUE(Verifier.match("const long long a = 0;", typeLoc()));
+}
+
+TEST(TypeLoc, LongConstLongRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 12);
+  EXPECT_TRUE(Verifier.match("long const long a = 0;", typeLoc()));
+}
+
+TEST(TypeLoc, LongLongConstRange) {
+  RangeVerifier<TypeLoc> Verifier;
+  Verifier.expectRange(1, 1, 1, 6);
+  EXPECT_TRUE(Verifier.match("long long const a = 0;", typeLoc()));
+}
+
 TEST(CXXConstructorDecl, NoRetFunTypeLocRange) {
   RangeVerifier<CXXConstructorDecl> Verifier;
   Verifier.expectRange(1, 11, 1, 13);




More information about the cfe-commits mailing list