forked from OSchip/llvm-project
[ODRHash] Add basic support for CXXRecordDecl
llvm-svn: 296521
This commit is contained in:
parent
4d263f6f18
commit
48143749f8
clang
include/clang/Basic
lib
test/Modules
|
@ -121,10 +121,10 @@ def err_module_odr_violation_mismatch_decl : Error<
|
|||
"%q0 has different definitions in different modules; first difference is "
|
||||
"%select{definition in module '%2'|defined here}1 found "
|
||||
"%select{end of class|public access specifier|private access specifier|"
|
||||
"protected access specifier|static assert|field}3">;
|
||||
"protected access specifier|static assert|field|method}3">;
|
||||
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
|
||||
"%select{end of class|public access specifier|private access specifier|"
|
||||
"protected access specifier|static assert|field}1">;
|
||||
"protected access specifier|static assert|field|method}1">;
|
||||
|
||||
def err_module_odr_violation_mismatch_decl_diff : Error<
|
||||
"%q0 has different definitions in different modules; first difference is "
|
||||
|
@ -139,7 +139,8 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
|
|||
"bitfield %4 with one width expression|"
|
||||
"%select{non-|}5mutable field %4|"
|
||||
"field %4 with %select{no|an}5 initalizer|"
|
||||
"field %4 with an initializer}3">;
|
||||
"field %4 with an initializer|"
|
||||
"method %4}3">;
|
||||
|
||||
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
||||
"%select{"
|
||||
|
@ -152,7 +153,8 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
|||
"bitfield %2 with different width expression|"
|
||||
"%select{non-|}3mutable field %2|"
|
||||
"field %2 with %select{no|an}3 initializer|"
|
||||
"field %2 with a different initializer}1">;
|
||||
"field %2 with a different initializer|"
|
||||
"method %2}1">;
|
||||
|
||||
def warn_module_uses_date_time : Warning<
|
||||
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
|
||||
|
|
|
@ -194,6 +194,14 @@ public:
|
|||
|
||||
Inherited::VisitFieldDecl(D);
|
||||
}
|
||||
|
||||
void VisitFunctionDecl(const FunctionDecl *D) {
|
||||
Inherited::VisitFunctionDecl(D);
|
||||
}
|
||||
|
||||
void VisitCXXMethodDecl(const CXXMethodDecl *D) {
|
||||
Inherited::VisitCXXMethodDecl(D);
|
||||
}
|
||||
};
|
||||
|
||||
// Only allow a small portion of Decl's to be processed. Remove this once
|
||||
|
@ -206,6 +214,7 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
|
|||
default:
|
||||
return false;
|
||||
case Decl::AccessSpec:
|
||||
case Decl::CXXMethod:
|
||||
case Decl::Field:
|
||||
case Decl::StaticAssert:
|
||||
return true;
|
||||
|
|
|
@ -8957,6 +8957,7 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
ProtectedSpecifer,
|
||||
StaticAssert,
|
||||
Field,
|
||||
CXXMethod,
|
||||
Other
|
||||
} FirstDiffType = Other,
|
||||
SecondDiffType = Other;
|
||||
|
@ -8982,6 +8983,8 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
return StaticAssert;
|
||||
case Decl::Field:
|
||||
return Field;
|
||||
case Decl::CXXMethod:
|
||||
return CXXMethod;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9068,6 +9071,7 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
FieldSingleMutable,
|
||||
FieldSingleInitializer,
|
||||
FieldDifferentInitializers,
|
||||
MethodName,
|
||||
};
|
||||
|
||||
// These lambdas have the common portions of the ODR diagnostics. This
|
||||
|
@ -9288,6 +9292,25 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
|
||||
break;
|
||||
}
|
||||
case CXXMethod: {
|
||||
const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
|
||||
const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
|
||||
IdentifierInfo *FirstII = FirstMethod->getIdentifier();
|
||||
IdentifierInfo *SecondII = SecondMethod->getIdentifier();
|
||||
if (FirstII->getName() != SecondII->getName()) {
|
||||
ODRDiagError(FirstMethod->getLocation(),
|
||||
FirstMethod->getSourceRange(), MethodName)
|
||||
<< FirstII;
|
||||
ODRDiagNote(SecondMethod->getLocation(),
|
||||
SecondMethod->getSourceRange(), MethodName)
|
||||
<< SecondII;
|
||||
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Diagnosed == true)
|
||||
|
|
|
@ -277,6 +277,39 @@ S11 s11;
|
|||
|
||||
} // namespace Field
|
||||
|
||||
namespace Method {
|
||||
#if defined(FIRST)
|
||||
struct S1 {
|
||||
void A() {}
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S1 {
|
||||
private:
|
||||
void A() {}
|
||||
};
|
||||
#else
|
||||
S1 s1;
|
||||
// expected-error@second.h:* {{'Method::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found method}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S2 {
|
||||
void A() {}
|
||||
void B() {}
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S2 {
|
||||
void B() {}
|
||||
void A() {}
|
||||
};
|
||||
#else
|
||||
S2 s2;
|
||||
// expected-error@second.h:* {{'Method::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'B'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found method 'A'}}
|
||||
#endif
|
||||
} // namespace Method
|
||||
|
||||
// Naive parsing of AST can lead to cycles in processing. Ensure
|
||||
// self-references don't trigger an endless cycles of AST node processing.
|
||||
namespace SelfReference {
|
||||
|
@ -324,6 +357,8 @@ struct S {
|
|||
unsigned b : 2*2 + 5/2;
|
||||
|
||||
mutable int c = sizeof(x + y);
|
||||
|
||||
void method() {}
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
typedef int INT;
|
||||
|
@ -344,6 +379,8 @@ struct S {
|
|||
unsigned b : 2 * 2 + 5 / 2;
|
||||
|
||||
mutable int c = sizeof(x + y);
|
||||
|
||||
void method() {}
|
||||
};
|
||||
#else
|
||||
S s;
|
||||
|
@ -369,6 +406,8 @@ struct T {
|
|||
|
||||
mutable int c = sizeof(x + y);
|
||||
|
||||
void method() {}
|
||||
|
||||
private:
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
|
@ -391,6 +430,8 @@ struct T {
|
|||
|
||||
mutable int c = sizeof(x + y);
|
||||
|
||||
void method() {}
|
||||
|
||||
public:
|
||||
};
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue