aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp17
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp2
-rw-r--r--clang/lib/Parse/ParseExpr.cpp28
-rw-r--r--clang/lib/Sema/SemaDecl.cpp29
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp12
6 files changed, 57 insertions, 37 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 56e8038..e6812ac 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4965,14 +4965,15 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
bool IsDependent = false;
const char *PrevSpec = nullptr;
unsigned DiagID;
- Decl *TagDecl = Actions.ActOnTag(
- getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS, Name, NameLoc,
- attrs, AS, DS.getModulePrivateSpecLoc(), TParams, Owned, IsDependent,
- ScopedEnumKWLoc, IsScopedUsingClassTag, BaseType,
- DSC == DeclSpecContext::DSC_type_specifier,
- DSC == DeclSpecContext::DSC_template_param ||
- DSC == DeclSpecContext::DSC_template_type_arg,
- &SkipBody).get();
+ Decl *TagDecl =
+ Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS,
+ Name, NameLoc, attrs, AS, DS.getModulePrivateSpecLoc(),
+ TParams, Owned, IsDependent, ScopedEnumKWLoc,
+ IsScopedUsingClassTag,
+ BaseType, DSC == DeclSpecContext::DSC_type_specifier,
+ DSC == DeclSpecContext::DSC_template_param ||
+ DSC == DeclSpecContext::DSC_template_type_arg,
+ OffsetOfState, &SkipBody).get();
if (SkipBody.ShouldSkip) {
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 5d721f4..227c1df 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2074,7 +2074,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
- &SkipBody);
+ OffsetOfState, &SkipBody);
// If ActOnTag said the type was dependent, try again with the
// less common call.
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index b1bf988..392ed29 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2592,10 +2592,21 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
}
case tok::kw___builtin_offsetof: {
SourceLocation TypeLoc = Tok.getLocation();
- TypeResult Ty = ParseTypeName();
- if (Ty.isInvalid()) {
- SkipUntil(tok::r_paren, StopAtSemi);
- return ExprError();
+ auto OOK = Sema::OffsetOfKind::OOK_Builtin;
+ if (Tok.getLocation().isMacroID()) {
+ StringRef MacroName = Lexer::getImmediateMacroNameForDiagnostics(
+ Tok.getLocation(), PP.getSourceManager(), getLangOpts());
+ if (MacroName == "offsetof")
+ OOK = Sema::OffsetOfKind::OOK_Macro;
+ }
+ TypeResult Ty;
+ {
+ OffsetOfStateRAIIObject InOffsetof(*this, OOK);
+ Ty = ParseTypeName();
+ if (Ty.isInvalid()) {
+ SkipUntil(tok::r_paren, StopAtSemi);
+ return ExprError();
+ }
}
if (ExpectAndConsume(tok::comma)) {
@@ -2618,6 +2629,12 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
+ enum class Kind { MemberAccess, ArraySubscript };
+ auto DiagExt = [&](SourceLocation Loc, Kind K) {
+ Diag(Loc, diag::ext_offsetof_member_designator)
+ << (K == Kind::ArraySubscript) << (OOK == Sema::OOK_Macro);
+ };
+
// FIXME: This loop leaks the index expressions on error.
while (true) {
if (Tok.is(tok::period)) {
@@ -2631,9 +2648,9 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}
+ DiagExt(Comps.back().LocStart, Kind::MemberAccess);
Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
Comps.back().LocEnd = ConsumeToken();
-
} else if (Tok.is(tok::l_square)) {
if (CheckProhibitedCXX11Attribute())
return ExprError();
@@ -2649,6 +2666,7 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
SkipUntil(tok::r_paren, StopAtSemi);
return Res;
}
+ DiagExt(Comps.back().LocStart, Kind::ArraySubscript);
Comps.back().U.E = Res.get();
ST.consumeClose();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index af20c707..c94b7ec 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16583,17 +16583,16 @@ static bool isAcceptableTagRedeclContext(Sema &S, DeclContext *OldDC,
///
/// \param SkipBody If non-null, will be set to indicate if the caller should
/// skip the definition of this tag and treat it as if it were a declaration.
-DeclResult Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, CXXScopeSpec &SS,
- IdentifierInfo *Name, SourceLocation NameLoc,
- const ParsedAttributesView &Attrs, AccessSpecifier AS,
- SourceLocation ModulePrivateLoc,
- MultiTemplateParamsArg TemplateParameterLists,
- bool &OwnedDecl, bool &IsDependent,
- SourceLocation ScopedEnumKWLoc,
- bool ScopedEnumUsesClassTag,
- TypeResult UnderlyingType, bool IsTypeSpecifier,
- bool IsTemplateParamOrArg, SkipBodyInfo *SkipBody) {
+DeclResult
+Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
+ CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
+ const ParsedAttributesView &Attrs, AccessSpecifier AS,
+ SourceLocation ModulePrivateLoc,
+ MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl,
+ bool &IsDependent, SourceLocation ScopedEnumKWLoc,
+ bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
+ bool IsTypeSpecifier, bool IsTemplateParamOrArg,
+ OffsetOfKind OOK, SkipBodyInfo *SkipBody) {
// If this is not a definition, it must have a name.
IdentifierInfo *OrigName = Name;
assert((Name != nullptr || TUK == TUK_Definition) &&
@@ -17366,10 +17365,14 @@ CreateNewDecl:
cast_or_null<RecordDecl>(PrevDecl));
}
+ if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus)
+ Diag(New->getLocation(), diag::ext_type_defined_in_offsetof)
+ << (OOK == OOK_Macro) << New->getSourceRange();
+
// C++11 [dcl.type]p3:
// A type-specifier-seq shall not define a class or enumeration [...].
- if (getLangOpts().CPlusPlus && (IsTypeSpecifier || IsTemplateParamOrArg) &&
- TUK == TUK_Definition) {
+ if (!Invalid && getLangOpts().CPlusPlus &&
+ (IsTypeSpecifier || IsTemplateParamOrArg) && TUK == TUK_Definition) {
Diag(New->getLocation(), diag::err_type_defined_in_type_specifier)
<< Context.getTagDeclType(New);
Invalid = true;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e7dddc3..c8d384c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -16972,15 +16972,15 @@ DeclResult Sema::ActOnTemplatedFriendTag(
if (SS.isEmpty()) {
bool Owned = false;
bool IsDependent = false;
- return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc,
- Attr, AS_public,
+ return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr,
+ AS_public,
/*ModulePrivateLoc=*/SourceLocation(),
MultiTemplateParamsArg(), Owned, IsDependent,
/*ScopedEnumKWLoc=*/SourceLocation(),
/*ScopedEnumUsesClassTag=*/false,
/*UnderlyingType=*/TypeResult(),
/*IsTypeSpecifier=*/false,
- /*IsTemplateParamOrArg=*/false);
+ /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside);
}
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 6b49c3f..b40bd09 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -10181,13 +10181,11 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
bool Owned = false;
bool IsDependent = false;
- Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
- KWLoc, SS, Name, NameLoc, Attr, AS_none,
- /*ModulePrivateLoc=*/SourceLocation(),
- MultiTemplateParamsArg(), Owned, IsDependent,
- SourceLocation(), false, TypeResult(),
- /*IsTypeSpecifier*/false,
- /*IsTemplateParamOrArg*/false).get();
+ Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name,
+ NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(),
+ MultiTemplateParamsArg(), Owned, IsDependent, SourceLocation(),
+ false, TypeResult(), /*IsTypeSpecifier*/ false,
+ /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside).get();
assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
if (!TagD)