mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-15 15:33:56 +00:00
[ODRHash] Add IdentiferInfo and FieldDecl support.
IdentifierInfo is hashed based on the stored string. FieldDecl versus other Decl is now detected, as well as differently named fields. Differential Revision: https://reviews.llvm.org/D21675 llvm-svn: 295911
This commit is contained in:
parent
a55b86c0e5
commit
d0786099b1
@ -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}3">;
|
||||
"protected access specifier|static assert|field}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}1">;
|
||||
"protected access specifier|static assert|field}1">;
|
||||
|
||||
def err_module_odr_violation_mismatch_decl_diff : Error<
|
||||
"%q0 has different definitions in different modules; first difference is "
|
||||
@ -132,13 +132,15 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
|
||||
"%select{"
|
||||
"static assert with condition|"
|
||||
"static assert with message|"
|
||||
"static assert with %select{|no }4message}3">;
|
||||
"static assert with %select{|no }4message|"
|
||||
"field %4}3">;
|
||||
|
||||
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
||||
"%select{"
|
||||
"static assert with different condition|"
|
||||
"static assert with different message|"
|
||||
"static assert with %select{|no }2message}1">;
|
||||
"static assert with %select{|no }2message|"
|
||||
"field %2}1">;
|
||||
|
||||
def warn_module_uses_date_time : Warning<
|
||||
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
|
||||
|
@ -26,7 +26,12 @@ void ODRHash::AddStmt(const Stmt *S) {
|
||||
assert(S && "Expecting non-null pointer.");
|
||||
S->ProcessODRHash(ID, *this);
|
||||
}
|
||||
void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {}
|
||||
|
||||
void ODRHash::AddIdentifierInfo(const IdentifierInfo *II) {
|
||||
assert(II && "Expecting non-null pointer.");
|
||||
ID.AddString(II->getName());
|
||||
}
|
||||
|
||||
void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {}
|
||||
void ODRHash::AddTemplateName(TemplateName Name) {}
|
||||
void ODRHash::AddDeclarationName(DeclarationName Name) {}
|
||||
@ -90,11 +95,23 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void AddIdentifierInfo(const IdentifierInfo *II) {
|
||||
Hash.AddBoolean(II);
|
||||
if (II) {
|
||||
Hash.AddIdentifierInfo(II);
|
||||
}
|
||||
}
|
||||
|
||||
void Visit(const Decl *D) {
|
||||
ID.AddInteger(D->getKind());
|
||||
Inherited::Visit(D);
|
||||
}
|
||||
|
||||
void VisitNamedDecl(const NamedDecl *D) {
|
||||
AddIdentifierInfo(D->getIdentifier());
|
||||
Inherited::VisitNamedDecl(D);
|
||||
}
|
||||
|
||||
void VisitAccessSpecDecl(const AccessSpecDecl *D) {
|
||||
ID.AddInteger(D->getAccess());
|
||||
Inherited::VisitAccessSpecDecl(D);
|
||||
@ -106,6 +123,10 @@ public:
|
||||
|
||||
Inherited::VisitStaticAssertDecl(D);
|
||||
}
|
||||
|
||||
void VisitFieldDecl(const FieldDecl *D) {
|
||||
Inherited::VisitFieldDecl(D);
|
||||
}
|
||||
};
|
||||
|
||||
// Only allow a small portion of Decl's to be processed. Remove this once
|
||||
@ -118,6 +139,7 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
|
||||
default:
|
||||
return false;
|
||||
case Decl::AccessSpec:
|
||||
case Decl::Field:
|
||||
case Decl::StaticAssert:
|
||||
return true;
|
||||
}
|
||||
|
@ -8956,6 +8956,7 @@ void ASTReader::diagnoseOdrViolations() {
|
||||
PrivateSpecifer,
|
||||
ProtectedSpecifer,
|
||||
StaticAssert,
|
||||
Field,
|
||||
Other
|
||||
} FirstDiffType = Other,
|
||||
SecondDiffType = Other;
|
||||
@ -8979,6 +8980,8 @@ void ASTReader::diagnoseOdrViolations() {
|
||||
llvm_unreachable("Invalid access specifier");
|
||||
case Decl::StaticAssert:
|
||||
return StaticAssert;
|
||||
case Decl::Field:
|
||||
return Field;
|
||||
}
|
||||
};
|
||||
|
||||
@ -9058,6 +9061,7 @@ void ASTReader::diagnoseOdrViolations() {
|
||||
StaticAssertCondition,
|
||||
StaticAssertMessage,
|
||||
StaticAssertOnlyMessage,
|
||||
FieldName,
|
||||
};
|
||||
|
||||
// These lambdas have the common portions of the ODR diagnostics. This
|
||||
@ -9146,6 +9150,24 @@ void ASTReader::diagnoseOdrViolations() {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Field: {
|
||||
FieldDecl *FirstField = cast<FieldDecl>(FirstDecl);
|
||||
FieldDecl *SecondField = cast<FieldDecl>(SecondDecl);
|
||||
IdentifierInfo *FirstII = FirstField->getIdentifier();
|
||||
IdentifierInfo *SecondII = SecondField->getIdentifier();
|
||||
if (FirstII->getName() != SecondII->getName()) {
|
||||
ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
|
||||
FieldName)
|
||||
<< FirstII;
|
||||
ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
|
||||
FieldName)
|
||||
<< SecondII;
|
||||
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Diagnosed == true)
|
||||
|
@ -115,6 +115,41 @@ S4 s4;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace Field {
|
||||
#if defined(FIRST)
|
||||
struct S1 {
|
||||
int x;
|
||||
private:
|
||||
int y;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S1 {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
#else
|
||||
S1 s1;
|
||||
// expected-error@second.h:* {{'Field::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S2 {
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S2 {
|
||||
int y;
|
||||
int x;
|
||||
};
|
||||
#else
|
||||
S2 s2;
|
||||
// expected-error@second.h:* {{'Field::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found field 'x'}}
|
||||
#endif
|
||||
} // namespace Field
|
||||
|
||||
// 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 {
|
||||
@ -151,6 +186,9 @@ struct S {
|
||||
|
||||
static_assert(1 == 1, "Message");
|
||||
static_assert(2 == 2);
|
||||
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S {
|
||||
@ -160,6 +198,9 @@ struct S {
|
||||
|
||||
static_assert(1 == 1, "Message");
|
||||
static_assert(2 == 2);
|
||||
|
||||
int x;
|
||||
double y;
|
||||
};
|
||||
#else
|
||||
S s;
|
||||
@ -174,6 +215,9 @@ struct T {
|
||||
static_assert(1 == 1, "Message");
|
||||
static_assert(2 == 2);
|
||||
|
||||
int x;
|
||||
double y;
|
||||
|
||||
private:
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
@ -185,6 +229,9 @@ struct T {
|
||||
static_assert(1 == 1, "Message");
|
||||
static_assert(2 == 2);
|
||||
|
||||
int x;
|
||||
double y;
|
||||
|
||||
public:
|
||||
};
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user