diff options
author | Zachary Henkel <zachary.henkel@microsoft.com> | 2019-12-28 13:06:13 -0800 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2019-12-28 13:13:46 -0800 |
commit | 0acfc493171a880215327ecd70e3e01e1cd493df (patch) | |
tree | c929373ad4e9914dcf951d22f16b17941c5922e9 | |
parent | 7ca86ee6494d4307333b300bae80e42df4a5140f (diff) | |
download | bcm5719-llvm-0acfc493171a880215327ecd70e3e01e1cd493df.tar.gz bcm5719-llvm-0acfc493171a880215327ecd70e3e01e1cd493df.zip |
Allow redeclaration of __declspec(uuid)
msvc allows a subsequent declaration of a uuid attribute on a
struct/class. Mirror this behavior in clang-cl.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D71439
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 8 | ||||
-rw-r--r-- | clang/test/SemaCXX/ms-uuid.cpp | 6 |
3 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9ca7a80d3ad..92b115c8a3f 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2685,6 +2685,10 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { // C's _Noreturn is allowed to be added to a function after it is defined. ++I; continue; + } else if (isa<UuidAttr>(NewAttribute)) { + // msvc will allow a subsequent definition to add an uuid to a class + ++I; + continue; } else if (const AlignedAttr *AA = dyn_cast<AlignedAttr>(NewAttribute)) { if (AA->isAlignas()) { // C++11 [dcl.align]p6: diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ac83a9b156e..50951ad6022 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5394,9 +5394,11 @@ UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, if (const auto *UA = D->getAttr<UuidAttr>()) { if (UA->getGuid().equals_lower(Uuid)) return nullptr; - Diag(UA->getLocation(), diag::err_mismatched_uuid); - Diag(CI.getLoc(), diag::note_previous_uuid); - D->dropAttr<UuidAttr>(); + if (!UA->getGuid().empty()) { + Diag(UA->getLocation(), diag::err_mismatched_uuid); + Diag(CI.getLoc(), diag::note_previous_uuid); + D->dropAttr<UuidAttr>(); + } } return ::new (Context) UuidAttr(Context, CI, Uuid); diff --git a/clang/test/SemaCXX/ms-uuid.cpp b/clang/test/SemaCXX/ms-uuid.cpp index c177570682f..1de7aee90c4 100644 --- a/clang/test/SemaCXX/ms-uuid.cpp +++ b/clang/test/SemaCXX/ms-uuid.cpp @@ -106,3 +106,9 @@ void F2() { } } + +// Test class/struct redeclaration where the subsequent +// declaration has a uuid attribute +struct X{}; + +struct __declspec(uuid("00000000-0000-0000-0000-000000000000")) X;
\ No newline at end of file |