Hi rnk, jpienaar,
Fixes https://llvm.org/bugs/show_bug.cgi?id=20744
struct A {
A() = default;
};
Previously the source range of the declaration of A ended at the ')'. It should
include the '= default' part as well. The same for '= delete'.
Note: this will break one of the clang-tidy fixers, which is going to be
addessed in a follow-up patch.
http://reviews.llvm.org/D8465
Files:
lib/Parse/ParseDeclCXX.cpp
test/Analysis/inlining/path-notes.cpp
test/Misc/ast-dump-decl.cpp
unittests/AST/SourceLocationTest.cpp
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -2329,6 +2329,13 @@
}
FunctionDefinitionKind DefinitionKind = FDK_Declaration;
+
+ // For explicitly deleted or defaulted declarations, we want to preserve the
+ // full source location of the declaration (including the "= delete" part).
+ // DeleteOrDefaultEndLoc saves this actual end location (end of the 'delete'
+ // or 'default' token).
+ SourceLocation DeleteOrDefaultEndLoc;
+
// function-definition:
//
// In C++11, a non-function declarator followed by an open brace is a
@@ -2341,10 +2348,16 @@
DefinitionKind = FDK_Definition;
} else if (Tok.is(tok::equal)) {
const Token &KW = NextToken();
- if (KW.is(tok::kw_default))
+ if (KW.is(tok::kw_default)) {
DefinitionKind = FDK_Defaulted;
- else if (KW.is(tok::kw_delete))
+ DeleteOrDefaultEndLoc =
+ KW.getLocation().getLocWithOffset(KW.getLength() - 1);
+ }
+ else if (KW.is(tok::kw_delete)) {
DefinitionKind = FDK_Deleted;
+ DeleteOrDefaultEndLoc =
+ KW.getLocation().getLocWithOffset(KW.getLength() - 1);
+ }
}
}
@@ -2388,6 +2401,14 @@
for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) {
LateParsedAttrs[i]->addDecl(FunDecl);
}
+
+ // If the declaration is explicitly defaulted or deleted, fix up its end
+ // location to include the defaulting/deleting.
+ if (DefinitionKind == FDK_Defaulted || DefinitionKind == FDK_Deleted) {
+ if (auto *DeclAsFunction = dyn_cast<FunctionDecl>(FunDecl)) {
+ DeclAsFunction->setRangeEnd(DeleteOrDefaultEndLoc);
+ }
+ }
}
LateParsedAttrs.clear();
Index: test/Analysis/inlining/path-notes.cpp
===================================================================
--- test/Analysis/inlining/path-notes.cpp
+++ test/Analysis/inlining/path-notes.cpp
@@ -2458,12 +2458,12 @@
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>105</integer>
-// CHECK-NEXT: <key>col</key><integer>53</integer>
+// CHECK-NEXT: <key>col</key><integer>63</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>105</integer>
-// CHECK-NEXT: <key>col</key><integer>53</integer>
+// CHECK-NEXT: <key>col</key><integer>63</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
@@ -2475,20 +2475,20 @@
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>105</integer>
-// CHECK-NEXT: <key>col</key><integer>53</integer>
+// CHECK-NEXT: <key>col</key><integer>63</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>105</integer>
-// CHECK-NEXT: <key>col</key><integer>53</integer>
+// CHECK-NEXT: <key>col</key><integer>63</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>105</integer>
-// CHECK-NEXT: <key>col</key><integer>53</integer>
+// CHECK-NEXT: <key>col</key><integer>63</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
Index: test/Misc/ast-dump-decl.cpp
===================================================================
--- test/Misc/ast-dump-decl.cpp
+++ test/Misc/ast-dump-decl.cpp
@@ -156,12 +156,12 @@
A = static_cast<TestMemberRanges &&>(B);
TestMemberRanges C(static_cast<TestMemberRanges &&>(A));
}
-// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:20>
-// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:49>
-// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:44>
-// CHECK: CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:21>
-// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:60>
-// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:55>
+// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:30>
+// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:59>
+// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:54>
+// CHECK: CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:31>
+// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:70>
+// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:65>
class TestCXXConversionDecl {
operator int() { return 0; }
Index: unittests/AST/SourceLocationTest.cpp
===================================================================
--- unittests/AST/SourceLocationTest.cpp
+++ unittests/AST/SourceLocationTest.cpp
@@ -122,6 +122,18 @@
EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl()));
}
+TEST(CXXConstructorDecl, DefaultedCtorLocRange) {
+ RangeVerifier<CXXConstructorDecl> Verifier;
+ Verifier.expectRange(1, 11, 1, 23);
+ EXPECT_TRUE(Verifier.match("class C { C() = default; };", functionDecl()));
+}
+
+TEST(CXXConstructorDecl, DeletedCtorLocRange) {
+ RangeVerifier<CXXConstructorDecl> Verifier;
+ Verifier.expectRange(1, 11, 1, 22);
+ EXPECT_TRUE(Verifier.match("class C { C() = delete; };", functionDecl()));
+}
+
TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) {
RangeVerifier<CompoundLiteralExpr> Verifier;
Verifier.expectRange(2, 11, 2, 22);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits