forked from OSchip/llvm-project
[ODRHash] Add diagnostic messages for typedef and type alias.
llvm-svn: 305238
This commit is contained in:
parent
44f95c4302
commit
11d566acee
|
@ -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|method}3">;
|
||||
"protected access specifier|static assert|field|method|type alias|typedef}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|method}1">;
|
||||
"protected access specifier|static assert|field|method|type alias|typedef}1">;
|
||||
|
||||
def err_module_odr_violation_mismatch_decl_diff : Error<
|
||||
"%q0 has different definitions in different modules; first difference is "
|
||||
|
@ -149,7 +149,9 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
|
|||
"method %4 is %select{not inline|inline}5|"
|
||||
"method %4 that has %5 parameter%s5|"
|
||||
"method %4 with %ordinal5 parameter of type %6%select{| decayed from %8}7|"
|
||||
"method %4 with %ordinal5 parameter named %6}3">;
|
||||
"method %4 with %ordinal5 parameter named %6|"
|
||||
"%select{typedef|type alias}4 name %5|"
|
||||
"%select{typedef|type alias}4 %5 with underlying type %6}3">;
|
||||
|
||||
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
||||
"%select{"
|
||||
|
@ -172,15 +174,19 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
|||
"method %2 is %select{not inline|inline}3|"
|
||||
"method %2 that has %3 parameter%s3|"
|
||||
"method %2 with %ordinal3 parameter of type %4%select{| decayed from %6}5|"
|
||||
"method %2 with %ordinal3 parameter named %4}1">;
|
||||
"method %2 with %ordinal3 parameter named %4|"
|
||||
"%select{typedef|type alias}2 name %3|"
|
||||
"%select{typedef|type alias}2 %3 with different underlying type %4}1">;
|
||||
|
||||
def err_module_odr_violation_mismatch_decl_unknown : Error<
|
||||
"%q0 %select{with definition in module '%2'|defined here}1 has different "
|
||||
"definitions in different modules; first difference is this "
|
||||
"%select{||||static assert|field|method|unexpected decl}3">;
|
||||
"%select{||||static assert|field|method|type alias|typedef|"
|
||||
"unexpected decl}3">;
|
||||
def note_module_odr_violation_mismatch_decl_unknown : Note<
|
||||
"but in '%0' found "
|
||||
"%select{||||different static assert|different field|different method|"
|
||||
"different type alias|different typedef|"
|
||||
"another unexpected decl}1">;
|
||||
|
||||
def warn_duplicate_module_file_extension : Warning<
|
||||
|
|
|
@ -9242,6 +9242,7 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
|
||||
// Used with err_module_odr_violation_mismatch_decl and
|
||||
// note_module_odr_violation_mismatch_decl
|
||||
// This list should be the same Decl's as in ODRHash::isWhiteListedDecl
|
||||
enum {
|
||||
EndOfClass,
|
||||
PublicSpecifer,
|
||||
|
@ -9250,6 +9251,8 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
StaticAssert,
|
||||
Field,
|
||||
CXXMethod,
|
||||
TypeAlias,
|
||||
TypeDef,
|
||||
Other
|
||||
} FirstDiffType = Other,
|
||||
SecondDiffType = Other;
|
||||
|
@ -9277,6 +9280,10 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
return Field;
|
||||
case Decl::CXXMethod:
|
||||
return CXXMethod;
|
||||
case Decl::TypeAlias:
|
||||
return TypeAlias;
|
||||
case Decl::Typedef:
|
||||
return TypeDef;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -9373,6 +9380,8 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
MethodNumberParameters,
|
||||
MethodParameterType,
|
||||
MethodParameterName,
|
||||
TypedefName,
|
||||
TypedefType,
|
||||
};
|
||||
|
||||
// These lambdas have the common portions of the ODR diagnostics. This
|
||||
|
@ -9748,6 +9757,38 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
|
||||
break;
|
||||
}
|
||||
case TypeAlias:
|
||||
case TypeDef: {
|
||||
TypedefNameDecl *FirstTD = cast<TypedefNameDecl>(FirstDecl);
|
||||
TypedefNameDecl *SecondTD = cast<TypedefNameDecl>(SecondDecl);
|
||||
auto FirstName = FirstTD->getDeclName();
|
||||
auto SecondName = SecondTD->getDeclName();
|
||||
if (FirstName != SecondName) {
|
||||
ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
|
||||
TypedefName)
|
||||
<< (FirstDiffType == TypeAlias) << FirstName;
|
||||
ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
|
||||
TypedefName)
|
||||
<< (FirstDiffType == TypeAlias) << SecondName;
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
QualType FirstType = FirstTD->getUnderlyingType();
|
||||
QualType SecondType = SecondTD->getUnderlyingType();
|
||||
if (ComputeQualTypeODRHash(FirstType) !=
|
||||
ComputeQualTypeODRHash(SecondType)) {
|
||||
ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
|
||||
TypedefType)
|
||||
<< (FirstDiffType == TypeAlias) << FirstName << FirstType;
|
||||
ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
|
||||
TypedefType)
|
||||
<< (FirstDiffType == TypeAlias) << SecondName << SecondType;
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Diagnosed == true)
|
||||
|
|
|
@ -586,6 +586,57 @@ S3 s3;
|
|||
// expected-error@first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
|
||||
// expected-note@second.h:* {{declaration of 'a' does not match}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S4 {
|
||||
typedef int a;
|
||||
typedef int b;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S4 {
|
||||
typedef int b;
|
||||
typedef int a;
|
||||
};
|
||||
#else
|
||||
S4 s4;
|
||||
// expected-error@second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found typedef name 'a'}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S5 {
|
||||
typedef int a;
|
||||
typedef int b;
|
||||
int x;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S5 {
|
||||
int x;
|
||||
typedef int b;
|
||||
typedef int a;
|
||||
};
|
||||
#else
|
||||
S5 s5;
|
||||
// expected-error@second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found typedef}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
typedef float F;
|
||||
struct S6 {
|
||||
typedef int a;
|
||||
typedef F b;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S6 {
|
||||
typedef int a;
|
||||
typedef float b;
|
||||
};
|
||||
#else
|
||||
S6 s6;
|
||||
// expected-error@second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
|
||||
#endif
|
||||
} // namespace TypeDef
|
||||
|
||||
namespace Using {
|
||||
|
@ -632,6 +683,57 @@ S3 s3;
|
|||
// expected-error@first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
|
||||
// expected-note@second.h:* {{declaration of 'a' does not match}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S4 {
|
||||
using a = int;
|
||||
using b = int;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S4 {
|
||||
using b = int;
|
||||
using a = int;
|
||||
};
|
||||
#else
|
||||
S4 s4;
|
||||
// expected-error@second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found type alias name 'a'}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S5 {
|
||||
using a = int;
|
||||
using b = int;
|
||||
int x;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S5 {
|
||||
int x;
|
||||
using b = int;
|
||||
using a = int;
|
||||
};
|
||||
#else
|
||||
S5 s5;
|
||||
// expected-error@second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found type alias}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
typedef float F;
|
||||
struct S6 {
|
||||
using a = int;
|
||||
using b = F;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S6 {
|
||||
using a = int;
|
||||
using b = float;
|
||||
};
|
||||
#else
|
||||
S6 s6;
|
||||
// expected-error@second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
|
||||
#endif
|
||||
} // namespace Using
|
||||
|
||||
namespace RecordType {
|
||||
|
|
Loading…
Reference in New Issue