summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-10-08 10:04:46 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-10-08 10:04:46 +0000
commitdc9be216c0f20dcf49f885ba26af845c709a3b50 (patch)
treee273456666c1ea262002f2f06801f01cadf21116 /clang/lib/Sema/SemaDecl.cpp
parent4069730c75152f082ae61b0ab1526f1a685e9587 (diff)
downloadbcm5719-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
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp15
1 files changed, 11 insertions, 4 deletions
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;
}
OpenPOWER on IntegriCloud