Fix/Improve SourceRange of explicitly defaulted members
When adding the implicit compound statement (required for Codegen?), the end location was previously overridden by the start location, probably based on the assumptions: * The location of the compound statement should be the member's location * The compound statement if present is the last element of a FunctionDecl This patch changes the location of the compound statement to the member's end location. Code review: http://reviews.llvm.org/D4175 llvm-svn: 211344
This commit is contained in:
parent
cd60ed53f6
commit
b3b0b8034c
|
@ -8407,7 +8407,9 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
|
|||
return;
|
||||
}
|
||||
|
||||
SourceLocation Loc = Constructor->getLocation();
|
||||
SourceLocation Loc = Constructor->getLocEnd().isValid()
|
||||
? Constructor->getLocEnd()
|
||||
: Constructor->getLocation();
|
||||
Constructor->setBody(new (Context) CompoundStmt(Loc));
|
||||
|
||||
Constructor->markUsed(Context);
|
||||
|
@ -8869,7 +8871,9 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
|
|||
return;
|
||||
}
|
||||
|
||||
SourceLocation Loc = Destructor->getLocation();
|
||||
SourceLocation Loc = Destructor->getLocEnd().isValid()
|
||||
? Destructor->getLocEnd()
|
||||
: Destructor->getLocation();
|
||||
Destructor->setBody(new (Context) CompoundStmt(Loc));
|
||||
Destructor->markUsed(Context);
|
||||
MarkVTableUsed(CurrentLocation, ClassDecl);
|
||||
|
@ -9569,8 +9573,10 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
|
|||
}
|
||||
|
||||
// Our location for everything implicitly-generated.
|
||||
SourceLocation Loc = CopyAssignOperator->getLocation();
|
||||
|
||||
SourceLocation Loc = CopyAssignOperator->getLocEnd().isValid()
|
||||
? CopyAssignOperator->getLocEnd()
|
||||
: CopyAssignOperator->getLocation();
|
||||
|
||||
// Builds a DeclRefExpr for the "other" object.
|
||||
RefBuilder OtherRef(Other, OtherRefType);
|
||||
|
||||
|
@ -9974,7 +9980,9 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
|
|||
"Bad argument type of defaulted move assignment");
|
||||
|
||||
// Our location for everything implicitly-generated.
|
||||
SourceLocation Loc = MoveAssignOperator->getLocation();
|
||||
SourceLocation Loc = MoveAssignOperator->getLocEnd().isValid()
|
||||
? MoveAssignOperator->getLocEnd()
|
||||
: MoveAssignOperator->getLocation();
|
||||
|
||||
// Builds a reference to the "other" object.
|
||||
RefBuilder OtherRef(Other, OtherRefType);
|
||||
|
@ -10111,8 +10119,9 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
|
|||
|
||||
if (!Invalid) {
|
||||
// Add a "return *this;"
|
||||
ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
|
||||
|
||||
ExprResult ThisObj =
|
||||
CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
|
||||
|
||||
StmtResult Return = BuildReturnStmt(Loc, ThisObj.get());
|
||||
if (Return.isInvalid())
|
||||
Invalid = true;
|
||||
|
@ -10288,10 +10297,12 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
|
|||
<< CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
|
||||
CopyConstructor->setInvalidDecl();
|
||||
} else {
|
||||
SourceLocation Loc = CopyConstructor->getLocEnd().isValid()
|
||||
? CopyConstructor->getLocEnd()
|
||||
: CopyConstructor->getLocation();
|
||||
Sema::CompoundScopeRAII CompoundScope(*this);
|
||||
CopyConstructor->setBody(ActOnCompoundStmt(
|
||||
CopyConstructor->getLocation(), CopyConstructor->getLocation(), None,
|
||||
/*isStmtExpr=*/ false).getAs<Stmt>());
|
||||
CopyConstructor->setBody(
|
||||
ActOnCompoundStmt(Loc, Loc, None, /*isStmtExpr=*/false).getAs<Stmt>());
|
||||
}
|
||||
|
||||
CopyConstructor->markUsed(Context);
|
||||
|
@ -10444,10 +10455,12 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation,
|
|||
<< CXXMoveConstructor << Context.getTagDeclType(ClassDecl);
|
||||
MoveConstructor->setInvalidDecl();
|
||||
} else {
|
||||
SourceLocation Loc = MoveConstructor->getLocEnd().isValid()
|
||||
? MoveConstructor->getLocEnd()
|
||||
: MoveConstructor->getLocation();
|
||||
Sema::CompoundScopeRAII CompoundScope(*this);
|
||||
MoveConstructor->setBody(ActOnCompoundStmt(
|
||||
MoveConstructor->getLocation(), MoveConstructor->getLocation(), None,
|
||||
/*isStmtExpr=*/ false).getAs<Stmt>());
|
||||
Loc, Loc, None, /*isStmtExpr=*/ false).getAs<Stmt>());
|
||||
}
|
||||
|
||||
MoveConstructor->markUsed(Context);
|
||||
|
|
|
@ -2452,12 +2452,12 @@ namespace PR17746 {
|
|||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>105</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>21</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>53</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>28</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>53</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
|
@ -2469,7 +2469,7 @@ namespace PR17746 {
|
|||
// CHECK-NEXT: <key>location</key>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>105</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>21</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>53</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: <key>ranges</key>
|
||||
|
@ -2477,12 +2477,12 @@ namespace PR17746 {
|
|||
// CHECK-NEXT: <array>
|
||||
// CHECK-NEXT: <dict>
|
||||
// CHECK-NEXT: <key>line</key><integer>105</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>21</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>53</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>28</integer>
|
||||
// CHECK-NEXT: <key>col</key><integer>53</integer>
|
||||
// CHECK-NEXT: <key>file</key><integer>0</integer>
|
||||
// CHECK-NEXT: </dict>
|
||||
// CHECK-NEXT: </array>
|
||||
|
|
|
@ -133,6 +133,31 @@ class TestCXXDestructorDecl {
|
|||
// CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void (void) noexcept'
|
||||
// CHECK-NEXT: CompoundStmt
|
||||
|
||||
// Test that the range of a defaulted members is computed correctly.
|
||||
// FIXME: This should include the "= default".
|
||||
class TestMemberRanges {
|
||||
public:
|
||||
TestMemberRanges() = default;
|
||||
TestMemberRanges(const TestMemberRanges &Other) = default;
|
||||
TestMemberRanges(TestMemberRanges &&Other) = default;
|
||||
~TestMemberRanges() = default;
|
||||
TestMemberRanges &operator=(const TestMemberRanges &Other) = default;
|
||||
TestMemberRanges &operator=(TestMemberRanges &&Other) = default;
|
||||
};
|
||||
void SomeFunction() {
|
||||
TestMemberRanges A;
|
||||
TestMemberRanges B(A);
|
||||
B = A;
|
||||
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>
|
||||
|
||||
class TestCXXConversionDecl {
|
||||
operator int() { return 0; }
|
||||
};
|
||||
|
|
|
@ -13,5 +13,5 @@ void f() {
|
|||
a1 = a2;
|
||||
|
||||
B b1, b2;
|
||||
b1 = b2;
|
||||
b1 = b2;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue