summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2017-06-12 21:58:22 +0000
committerRichard Trieu <rtrieu@google.com>2017-06-12 21:58:22 +0000
commit11d566acee0f58480dff03fdb6229e464cea5864 (patch)
tree0baef0bd8cea12ca1747767b7b71085a0b687cff
parent44f95c43023166a3fc0cfdfdb6884860834ed469 (diff)
downloadbcm5719-llvm-11d566acee0f58480dff03fdb6229e464cea5864.tar.gz
bcm5719-llvm-11d566acee0f58480dff03fdb6229e464cea5864.zip
[ODRHash] Add diagnostic messages for typedef and type alias.
llvm-svn: 305238
-rw-r--r--clang/include/clang/Basic/DiagnosticSerializationKinds.td16
-rw-r--r--clang/lib/Serialization/ASTReader.cpp41
-rw-r--r--clang/test/Modules/odr_hash.cpp102
3 files changed, 154 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
index 7c9e8c8980a..5d286ee83a3 100644
--- a/clang/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -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<
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 94a8f609f57..5bef65fc890 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -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)
diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp
index a6a0b74743a..cc953d0c054 100644
--- a/clang/test/Modules/odr_hash.cpp
+++ b/clang/test/Modules/odr_hash.cpp
@@ -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 {
OpenPOWER on IntegriCloud