diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-10-08 10:04:46 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-10-08 10:04:46 +0000 |
| commit | dc9be216c0f20dcf49f885ba26af845c709a3b50 (patch) | |
| tree | e273456666c1ea262002f2f06801f01cadf21116 | |
| parent | 4069730c75152f082ae61b0ab1526f1a685e9587 (diff) | |
| download | bcm5719-llvm-dc9be216c0f20dcf49f885ba26af845c709a3b50.tar.gz bcm5719-llvm-dc9be216c0f20dcf49f885ba26af845c709a3b50.zip | |
[MSVC Compat] Try to treat an implicit, fixed enum as an unfixed enum
consider the following:
enum E *p;
enum E { e };
The above snippet is not ANSI C because 'enum E' has not bee defined
when we are processing the declaration of 'p'; however, it is a popular
extension to make the above work. This would fail using the Microsoft
enum semantics because the definition of 'E' would implicitly have a
fixed underlying type of 'int' which would trigger diagnostic messages
about a mismatch between the declaration and the definition.
Instead, treat fixed underlying types as not fixed for the purposes of
the diagnostic.
llvm-svn: 249674
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 | ||||
| -rw-r--r-- | clang/test/Sema/bitfield.c | 2 | ||||
| -rw-r--r-- | clang/test/Sema/decl-in-prototype.c | 2 | ||||
| -rw-r--r-- | clang/test/SemaObjC/default-synthesize-1.m | 2 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/instantiate-local-class.cpp | 4 |
7 files changed, 21 insertions, 11 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 332f8eac449..3f118e72682 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1984,7 +1984,9 @@ public: Expr *val); bool CheckEnumUnderlyingType(TypeSourceInfo *TI); bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, - QualType EnumUnderlyingTy, const EnumDecl *Prev); + QualType EnumUnderlyingTy, + bool EnumUnderlyingIsImplicit, + const EnumDecl *Prev); /// Determine whether the body of an anonymous enumeration should be skipped. /// \param II The name of the first enumerator. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fcc40955836..a12ff3a02e9 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11454,9 +11454,9 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) { /// Check whether this is a valid redeclaration of a previous enumeration. /// \return true if the redeclaration was invalid. -bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, - QualType EnumUnderlyingTy, - const EnumDecl *Prev) { +bool Sema::CheckEnumRedeclaration( + SourceLocation EnumLoc, bool IsScoped, QualType EnumUnderlyingTy, + bool EnumUnderlyingIsImplicit, const EnumDecl *Prev) { bool IsFixed = !EnumUnderlyingTy.isNull(); if (IsScoped != Prev->isScoped()) { @@ -11478,6 +11478,10 @@ bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, << Prev->getIntegerTypeRange(); return true; } + } else if (IsFixed && !Prev->isFixed() && EnumUnderlyingIsImplicit) { + ; + } else if (!IsFixed && Prev->isFixed() && !Prev->getIntegerTypeSourceInfo()) { + ; } else if (IsFixed != Prev->isFixed()) { Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch) << Prev->isFixed(); @@ -11747,6 +11751,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // this early, because it's needed to detect if this is an incompatible // redeclaration. llvm::PointerUnion<const Type*, TypeSourceInfo*> EnumUnderlying; + bool EnumUnderlyingIsImplicit = false; if (Kind == TTK_Enum) { if (UnderlyingType.isInvalid() || (!UnderlyingType.get() && ScopedEnum)) @@ -11772,6 +11777,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (getLangOpts().MSVCCompat || TUK == TUK_Definition) { // Microsoft enums are always of int type. EnumUnderlying = Context.IntTy.getTypePtr(); + EnumUnderlyingIsImplicit = true; } } } @@ -12119,7 +12125,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // returning the previous declaration, unless this is a definition, // in which case we want the caller to bail out. if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc, - ScopedEnum, EnumUnderlyingTy, PrevEnum)) + ScopedEnum, EnumUnderlyingTy, + EnumUnderlyingIsImplicit, PrevEnum)) return TUK == TUK_Declaration ? PrevTagDecl : nullptr; } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 029af186fdc..1789855c40f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -835,7 +835,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { SemaRef.SubstType(TI->getType(), TemplateArgs, UnderlyingLoc, DeclarationName()); SemaRef.CheckEnumRedeclaration(Def->getLocation(), Def->isScoped(), - DefnUnderlying, Enum); + DefnUnderlying, + /*EnumUnderlyingIsImplicit=*/false, Enum); } } diff --git a/clang/test/Sema/bitfield.c b/clang/test/Sema/bitfield.c index 60a6fcf10a5..ba8460d3f6c 100644 --- a/clang/test/Sema/bitfield.c +++ b/clang/test/Sema/bitfield.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple %itanium_abi_triple %s -fsyntax-only -verify -std=c11 -Wno-unused-value +// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11 -Wno-unused-value enum e0; // expected-note{{forward declaration of 'enum e0'}} diff --git a/clang/test/Sema/decl-in-prototype.c b/clang/test/Sema/decl-in-prototype.c index e185d19b544..4f581aa54e5 100644 --- a/clang/test/Sema/decl-in-prototype.c +++ b/clang/test/Sema/decl-in-prototype.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple %ms_abi_triple -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s const int AA = 5; diff --git a/clang/test/SemaObjC/default-synthesize-1.m b/clang/test/SemaObjC/default-synthesize-1.m index aa92e4a3ffc..731aa863e10 100644 --- a/clang/test/SemaObjC/default-synthesize-1.m +++ b/clang/test/SemaObjC/default-synthesize-1.m @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class %s // rdar://11295716 @interface NSObject diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp index 7fdc6ce0c28..c0ea6a0bc87 100644 --- a/clang/test/SemaTemplate/instantiate-local-class.cpp +++ b/clang/test/SemaTemplate/instantiate-local-class.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple %itanium_abi_triple -verify -std=c++11 %s -// RUN: %clang_cc1 -triple %itanium_abi_triple -verify -std=c++11 -fdelayed-template-parsing %s +// RUN: %clang_cc1 -verify -std=c++11 %s +// RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s template<typename T> void f0() { |

