summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp2814
1 files changed, 1685 insertions, 1129 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
index 328ce70..bbe6930 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
@@ -25,12 +25,14 @@
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/HeaderSearch.h" // FIXME: Sema shouldn't depend on Lex
-#include "clang/Lex/ModuleLoader.h" // FIXME: Sema shouldn't depend on Lex
-#include "clang/Lex/Preprocessor.h" // FIXME: Sema shouldn't depend on Lex
+#include "clang/Lex/HeaderSearch.h" // TODO: Sema shouldn't depend on Lex
+#include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering.
+#include "clang/Lex/ModuleLoader.h" // TODO: Sema shouldn't depend on Lex
+#include "clang/Lex/Preprocessor.h" // Included for isCodeCompletionEnabled()
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Sema/CXXFieldCollector.h"
#include "clang/Sema/DeclSpec.h"
@@ -62,24 +64,29 @@ namespace {
class TypeNameValidatorCCC : public CorrectionCandidateCallback {
public:
- TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false)
- : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) {
+ TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
+ bool AllowTemplates=false)
+ : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
+ AllowClassTemplates(AllowTemplates) {
WantExpressionKeywords = false;
WantCXXNamedCasts = false;
WantRemainingKeywords = false;
}
- virtual bool ValidateCandidate(const TypoCorrection &candidate) {
- if (NamedDecl *ND = candidate.getCorrectionDecl())
- return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
- (AllowInvalidDecl || !ND->isInvalidDecl());
- else
- return !WantClassName && candidate.isKeyword();
+ bool ValidateCandidate(const TypoCorrection &candidate) override {
+ if (NamedDecl *ND = candidate.getCorrectionDecl()) {
+ bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
+ bool AllowedTemplate = AllowClassTemplates && isa<ClassTemplateDecl>(ND);
+ return (IsType || AllowedTemplate) &&
+ (AllowInvalidDecl || !ND->isInvalidDecl());
+ }
+ return !WantClassName && candidate.isKeyword();
}
private:
bool AllowInvalidDecl;
bool WantClassName;
+ bool AllowClassTemplates;
};
}
@@ -121,6 +128,65 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
return false;
}
+static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
+ const IdentifierInfo &II,
+ SourceLocation NameLoc) {
+ // Find the first parent class template context, if any.
+ // FIXME: Perform the lookup in all enclosing class templates.
+ const CXXRecordDecl *RD = nullptr;
+ for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) {
+ RD = dyn_cast<CXXRecordDecl>(DC);
+ if (RD && RD->getDescribedClassTemplate())
+ break;
+ }
+ if (!RD)
+ return ParsedType();
+
+ // Look for type decls in dependent base classes that have known primary
+ // templates.
+ bool FoundTypeDecl = false;
+ for (const auto &Base : RD->bases()) {
+ auto *TST = Base.getType()->getAs<TemplateSpecializationType>();
+ if (!TST || !TST->isDependentType())
+ continue;
+ auto *TD = TST->getTemplateName().getAsTemplateDecl();
+ if (!TD)
+ continue;
+ auto *BasePrimaryTemplate = cast<CXXRecordDecl>(TD->getTemplatedDecl());
+ // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly
+ // by calling or integrating with the main LookupQualifiedName mechanism.
+ for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) {
+ if (FoundTypeDecl)
+ return ParsedType();
+ FoundTypeDecl = isa<TypeDecl>(ND);
+ if (!FoundTypeDecl)
+ return ParsedType();
+ }
+ }
+ if (!FoundTypeDecl)
+ return ParsedType();
+
+ // We found some types in dependent base classes. Recover as if the user
+ // wrote 'typename MyClass::II' instead of 'II'. We'll fully resolve the
+ // lookup during template instantiation.
+ S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II;
+
+ ASTContext &Context = S.Context;
+ auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false,
+ cast<Type>(Context.getRecordType(RD)));
+ QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II);
+
+ CXXScopeSpec SS;
+ SS.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+
+ TypeLocBuilder Builder;
+ DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+ DepTL.setNameLoc(NameLoc);
+ DepTL.setElaboratedKeywordLoc(SourceLocation());
+ DepTL.setQualifierLoc(SS.getWithLocInContext(Context));
+ return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
/// \brief If the identifier refers to a type name within this scope,
/// return the declaration of that type.
///
@@ -137,7 +203,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
bool WantNontrivialTypeSourceInfo,
IdentifierInfo **CorrectedII) {
// Determine where we will perform name lookup.
- DeclContext *LookupCtx = 0;
+ DeclContext *LookupCtx = nullptr;
if (ObjectTypePtr) {
QualType ObjectType = ObjectTypePtr.get();
if (ObjectType->isRecordType())
@@ -165,11 +231,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get();
NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context);
- QualType T =
- CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
- II, NameLoc);
-
- return ParsedType::make(T);
+ QualType T = CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc,
+ II, NameLoc);
+ return ParsedType::make(T);
}
return ParsedType();
@@ -204,16 +268,25 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
} else {
// Perform unqualified name lookup.
LookupName(Result, S);
+
+ // For unqualified lookup in a class template in MSVC mode, look into
+ // dependent base classes where the primary class template is known.
+ if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+ if (ParsedType TypeInBase =
+ recoverFromTypeInKnownDependentBase(*this, II, NameLoc))
+ return TypeInBase;
+ }
}
-
- NamedDecl *IIDecl = 0;
+
+ NamedDecl *IIDecl = nullptr;
switch (Result.getResultKind()) {
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
if (CorrectedII) {
TypeNameValidatorCCC Validator(true, isClassName);
TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(),
- Kind, S, SS, Validator);
+ Kind, S, SS, Validator,
+ CTK_ErrorRecovery);
IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
TemplateTy Template;
bool MemberOfUnknownSpecialization;
@@ -303,8 +376,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
DiagnoseUseOfDecl(IIDecl, NameLoc);
- if (T.isNull())
- T = Context.getTypeDeclType(TD);
+ T = Context.getTypeDeclType(TD);
// NOTE: avoid constructing an ElaboratedType(Loc) if this is a
// constructor or destructor name (in such a case, the scope specifier
@@ -338,6 +410,50 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
return ParsedType::make(T);
}
+// Builds a fake NNS for the given decl context.
+static NestedNameSpecifier *
+synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) {
+ for (;; DC = DC->getLookupParent()) {
+ DC = DC->getPrimaryContext();
+ auto *ND = dyn_cast<NamespaceDecl>(DC);
+ if (ND && !ND->isInline() && !ND->isAnonymousNamespace())
+ return NestedNameSpecifier::Create(Context, nullptr, ND);
+ else if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
+ return NestedNameSpecifier::Create(Context, nullptr, RD->isTemplateDecl(),
+ RD->getTypeForDecl());
+ else if (isa<TranslationUnitDecl>(DC))
+ return NestedNameSpecifier::GlobalSpecifier(Context);
+ }
+ llvm_unreachable("something isn't in TU scope?");
+}
+
+ParsedType Sema::ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+ SourceLocation NameLoc) {
+ // Accepting an undeclared identifier as a default argument for a template
+ // type parameter is a Microsoft extension.
+ Diag(NameLoc, diag::ext_ms_delayed_template_argument) << &II;
+
+ // Build a fake DependentNameType that will perform lookup into CurContext at
+ // instantiation time. The name specifier isn't dependent, so template
+ // instantiation won't transform it. It will retry the lookup, however.
+ NestedNameSpecifier *NNS =
+ synthesizeCurrentNestedNameSpecifier(Context, CurContext);
+ QualType T = Context.getDependentNameType(ETK_None, NNS, &II);
+
+ // Build type location information. We synthesized the qualifier, so we have
+ // to build a fake NestedNameSpecifierLoc.
+ NestedNameSpecifierLocBuilder NNSLocBuilder;
+ NNSLocBuilder.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+ NestedNameSpecifierLoc QualifierLoc = NNSLocBuilder.getWithLocInContext(Context);
+
+ TypeLocBuilder Builder;
+ DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+ DepTL.setNameLoc(NameLoc);
+ DepTL.setElaboratedKeywordLoc(SourceLocation());
+ DepTL.setQualifierLoc(QualifierLoc);
+ return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
/// isTagName() - This method is called *for error recovery purposes only*
/// to determine if the specified name is a valid tag name ("struct foo"). If
/// so, this returns the TST for the tag corresponding to it (TST_enum,
@@ -381,29 +497,29 @@ bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S) {
const Type *Ty = SS->getScopeRep()->getAsType();
CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext);
- for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
- BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base)
- if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base->getType()))
+ for (const auto &Base : RD->bases())
+ if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType()))
return true;
return S->isFunctionPrototypeScope();
}
return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
}
-bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
+void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
SourceLocation IILoc,
Scope *S,
CXXScopeSpec *SS,
- ParsedType &SuggestedType) {
+ ParsedType &SuggestedType,
+ bool AllowClassTemplates) {
// We don't have anything to suggest (yet).
SuggestedType = ParsedType();
// There may have been a typo in the name of the type. Look up typo
// results, in case we have something that we can suggest.
- TypeNameValidatorCCC Validator(false);
+ TypeNameValidatorCCC Validator(false, false, AllowClassTemplates);
if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc),
LookupOrdinaryName, S, SS,
- Validator)) {
+ Validator, CTK_ErrorRecovery)) {
if (Corrected.isKeyword()) {
// We corrected to a keyword.
diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II);
@@ -434,7 +550,7 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo=*/true);
}
- return true;
+ return;
}
if (getLangOpts().CPlusPlus) {
@@ -453,7 +569,7 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
Diag(TplDecl->getLocation(), diag::note_template_decl_here)
<< TplDecl->getTemplateParameters()->getSourceRange();
}
- return true;
+ return;
}
}
@@ -467,11 +583,11 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
<< II << DC << SS->getRange();
else if (isDependentScopeSpecifier(*SS)) {
unsigned DiagID = diag::err_typename_missing;
- if (getLangOpts().MicrosoftMode && isMicrosoftMissingTypename(SS, S))
- DiagID = diag::warn_typename_missing;
+ if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
+ DiagID = diag::ext_typename_missing;
Diag(SS->getRange().getBegin(), DiagID)
- << (NestedNameSpecifier *)SS->getScopeRep() << II->getName()
+ << SS->getScopeRep() << II->getName()
<< SourceRange(SS->getRange().getBegin(), IILoc)
<< FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");
SuggestedType = ActOnTypenameType(S, SourceLocation(),
@@ -480,8 +596,6 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
assert(SS && SS->isInvalid() &&
"Invalid scope specifier has already been diagnosed");
}
-
- return true;
}
/// \brief Determine whether the given result set contains either a type name
@@ -508,35 +622,30 @@ static bool isTagTypeWithMissingTag(Sema &SemaRef, LookupResult &Result,
LookupResult R(SemaRef, Name, NameLoc, Sema::LookupTagName);
SemaRef.LookupParsedName(R, S, &SS);
if (TagDecl *Tag = R.getAsSingle<TagDecl>()) {
- const char *TagName = 0;
- const char *FixItTagName = 0;
+ StringRef FixItTagName;
switch (Tag->getTagKind()) {
case TTK_Class:
- TagName = "class";
FixItTagName = "class ";
break;
case TTK_Enum:
- TagName = "enum";
FixItTagName = "enum ";
break;
case TTK_Struct:
- TagName = "struct";
FixItTagName = "struct ";
break;
case TTK_Interface:
- TagName = "__interface";
FixItTagName = "__interface ";
break;
case TTK_Union:
- TagName = "union";
FixItTagName = "union ";
break;
}
+ StringRef TagName = FixItTagName.drop_back();
SemaRef.Diag(NameLoc, diag::err_use_of_tag_name_without_tag)
<< Name << TagName << SemaRef.getLangOpts().CPlusPlus
<< FixItHint::CreateInsertion(NameLoc, FixItTagName);
@@ -579,16 +688,23 @@ Sema::NameClassification Sema::ClassifyName(Scope *S,
CorrectionCandidateCallback *CCC) {
DeclarationNameInfo NameInfo(Name, NameLoc);
ObjCMethodDecl *CurMethod = getCurMethodDecl();
-
+
if (NextToken.is(tok::coloncolon)) {
BuildCXXNestedNameSpecifier(S, *Name, NameLoc, NextToken.getLocation(),
- QualType(), false, SS, 0, false);
-
+ QualType(), false, SS, nullptr, false);
}
-
+
LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
LookupParsedName(Result, S, &SS, !CurMethod);
-
+
+ // For unqualified lookup in a class template in MSVC mode, look into
+ // dependent base classes where the primary class template is known.
+ if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) {
+ if (ParsedType TypeInBase =
+ recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc))
+ return TypeInBase;
+ }
+
// Perform lookup for Objective-C instance variables (including automatically
// synthesized instance variables), if we're in an Objective-C method.
// FIXME: This lookup really, really needs to be folded in to the normal
@@ -646,13 +762,14 @@ Corrected:
SecondTry = true;
if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
Result.getLookupKind(), S,
- &SS, *CCC)) {
+ &SS, *CCC,
+ CTK_ErrorRecovery)) {
unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
unsigned QualifiedDiag = diag::err_no_member_suggest;
NamedDecl *FirstDecl = Corrected.getCorrectionDecl();
NamedDecl *UnderlyingFirstDecl
- = FirstDecl? FirstDecl->getUnderlyingDecl() : 0;
+ = FirstDecl? FirstDecl->getUnderlyingDecl() : nullptr;
if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) {
UnqualifiedDiag = diag::err_no_template_suggest;
@@ -725,7 +842,7 @@ Corrected:
// keyword here.
return ActOnDependentIdExpression(SS, /*TemplateKWLoc=*/SourceLocation(),
NameInfo, IsAddressOfOperand,
- /*TemplateArgs=*/0);
+ /*TemplateArgs=*/nullptr);
}
case LookupResult::Found:
@@ -817,8 +934,8 @@ Corrected:
ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(FirstDecl);
if (!Class) {
// FIXME: It's unfortunate that we don't have a Type node for handling this.
- if (ObjCCompatibleAliasDecl *Alias
- = dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl))
+ if (ObjCCompatibleAliasDecl *Alias =
+ dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl))
Class = Alias->getClassInterface();
}
@@ -845,7 +962,8 @@ Corrected:
// seems likely a type is wanted instead of the non-type that was found.
bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star);
if ((NextToken.is(tok::identifier) ||
- (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) &&
+ (NextIsOp &&
+ FirstDecl->getUnderlyingDecl()->isFunctionOrFunctionTemplate())) &&
isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) {
TypeDecl *Type = Result.getAsSingle<TypeDecl>();
DiagnoseUseOfDecl(Type, NameLoc);
@@ -856,7 +974,8 @@ Corrected:
}
if (FirstDecl->isCXXClassMember())
- return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0);
+ return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result,
+ nullptr);
bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren));
return BuildDeclarationNameExpr(SS, Result, ADL);
@@ -962,12 +1081,9 @@ void Sema::ExitDeclaratorContext(Scope *S) {
void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) {
- FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
- if (FunctionTemplateDecl *TFD = dyn_cast_or_null<FunctionTemplateDecl>(D)) {
- // We assume that the caller has already called
- // ActOnReenterTemplateScope
- FD = TFD->getTemplatedDecl();
- }
+ // We assume that the caller has already called
+ // ActOnReenterTemplateScope so getTemplatedDecl() works.
+ FunctionDecl *FD = D->getAsFunction();
if (!FD)
return;
@@ -1086,9 +1202,8 @@ void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
}
bool Sema::isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S,
- bool ExplicitInstantiationOrSpecialization) {
- return IdResolver.isDeclInScope(D, Ctx, S,
- ExplicitInstantiationOrSpecialization);
+ bool AllowInlineNamespace) {
+ return IdResolver.isDeclInScope(D, Ctx, S, AllowInlineNamespace);
}
Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) {
@@ -1099,7 +1214,7 @@ Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) {
return S;
} while ((S = S->getParent()));
- return 0;
+ return nullptr;
}
static bool isOutOfScopePreviousDeclaration(NamedDecl *,
@@ -1108,21 +1223,19 @@ static bool isOutOfScopePreviousDeclaration(NamedDecl *,
/// Filters out lookup results that don't fall within the given scope
/// as determined by isDeclInScope.
-void Sema::FilterLookupForScope(LookupResult &R,
- DeclContext *Ctx, Scope *S,
+void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S,
bool ConsiderLinkage,
- bool ExplicitInstantiationOrSpecialization) {
+ bool AllowInlineNamespace) {
LookupResult::Filter F = R.makeFilter();
while (F.hasNext()) {
NamedDecl *D = F.next();
- if (isDeclInScope(D, Ctx, S, ExplicitInstantiationOrSpecialization))
+ if (isDeclInScope(D, Ctx, S, AllowInlineNamespace))
continue;
- if (ConsiderLinkage &&
- isOutOfScopePreviousDeclaration(D, Ctx, Context))
+ if (ConsiderLinkage && isOutOfScopePreviousDeclaration(D, Ctx, Context))
continue;
-
+
F.erase();
}
@@ -1173,8 +1286,8 @@ static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) {
//
// When we see foo we don't know if after the typedef we will get 'A' or '*A'
// for example. If 'A', foo will have external linkage. If we have '*A',
-// foo will have no linkage. Since we can't know untill we get to the end
-// of the typedef, this function finds out if D might have non external linkage.
+// foo will have no linkage. Since we can't know until we get to the end
+// of the typedef, this function finds out if D might have non-external linkage.
// Callers should verify at the end of the TU if it D has external linkage or
// not.
bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) {
@@ -1204,7 +1317,8 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>())
return false;
- // Ignore class templates.
+ // Ignore all entities declared within templates, and out-of-line definitions
+ // of members of class templates.
if (D->getDeclContext()->isDependentContext() ||
D->getLexicalDeclContext()->isDependentContext())
return false;
@@ -1218,8 +1332,7 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
return false;
} else {
// 'static inline' functions are defined in headers; don't warn.
- if (FD->isInlineSpecified() &&
- !isMainFileLoc(*this, FD->getLocation()))
+ if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation()))
return false;
}
@@ -1244,6 +1357,8 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
}
// Only warn for unused decls internal to the translation unit.
+ // FIXME: This seems like a bogus check; it suppresses -Wunused-function
+ // for inline functions defined in the main source file, for instance.
return mightHaveNonExternalLinkage(D);
}
@@ -1271,7 +1386,8 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
if (D->isInvalidDecl())
return false;
- if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>())
+ if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>() ||
+ D->hasAttr<ObjCPreciseLifetimeAttr>())
return false;
if (isa<LabelDecl>(D))
@@ -1309,7 +1425,8 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
return false;
if (const Expr *Init = VD->getInit()) {
- if (const ExprWithCleanups *Cleanups = dyn_cast<ExprWithCleanups>(Init))
+ if (const ExprWithCleanups *Cleanups =
+ dyn_cast<ExprWithCleanups>(Init))
Init = Cleanups->getSubExpr();
const CXXConstructExpr *Construct =
dyn_cast<CXXConstructExpr>(Init);
@@ -1344,10 +1461,10 @@ static void GenerateFixForUnusedDecl(const NamedDecl *D, ASTContext &Ctx,
/// DiagnoseUnusedDecl - Emit warnings about declarations that are not used
/// unless they are marked attr(unused).
void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
- FixItHint Hint;
if (!ShouldDiagnoseUnusedDecl(D))
return;
+ FixItHint Hint;
GenerateFixForUnusedDecl(D, Context, Hint);
unsigned DiagID;
@@ -1365,18 +1482,18 @@ static void CheckPoppedLabel(LabelDecl *L, Sema &S) {
// Verify that we have no forward references left. If so, there was a goto
// or address of a label taken, but no definition of it. Label fwd
// definitions are indicated with a null substmt.
- if (L->getStmt() == 0)
+ if (L->getStmt() == nullptr)
S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName();
}
void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
+ S->mergeNRVOIntoParent();
+
if (S->decl_empty()) return;
assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
"Scope shouldn't contain decls!");
- for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
- I != E; ++I) {
- Decl *TmpD = (*I);
+ for (auto *TmpD : S->decls()) {
assert(TmpD && "This decl didn't get pushed??");
assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
@@ -1395,16 +1512,6 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
// Remove this name from our lexical scope.
IdResolver.RemoveDecl(D);
}
- DiagnoseUnusedBackingIvarInAccessor(S);
-}
-
-void Sema::ActOnStartFunctionDeclarator() {
- ++InFunctionDeclarator;
-}
-
-void Sema::ActOnEndFunctionDeclarator() {
- assert(InFunctionDeclarator);
- --InFunctionDeclarator;
}
/// \brief Look for an Objective-C class in the translation unit.
@@ -1432,8 +1539,8 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
// find an Objective-C class name.
DeclFilterCCC<ObjCInterfaceDecl> Validator;
if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc),
- LookupOrdinaryName, TUScope, NULL,
- Validator)) {
+ LookupOrdinaryName, TUScope, nullptr,
+ Validator, CTK_ErrorRecovery)) {
diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id);
IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>();
Id = IDecl->getIdentifier();
@@ -1495,6 +1602,20 @@ static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S,
Context.setObjCSuperType(Context.getTagDeclType(TD));
}
+static StringRef getHeaderName(ASTContext::GetBuiltinTypeError Error) {
+ switch (Error) {
+ case ASTContext::GE_None:
+ return "";
+ case ASTContext::GE_Missing_stdio:
+ return "stdio.h";
+ case ASTContext::GE_Missing_setjmp:
+ return "setjmp.h";
+ case ASTContext::GE_Missing_ucontext:
+ return "ucontext.h";
+ }
+ llvm_unreachable("unhandled error kind");
+}
+
/// LazilyCreateBuiltin - The specified Builtin-ID was first used at
/// file scope. lazily create a decl for it. ForRedeclaration is true
/// if we're creating this built-in in anticipation of redeclaring the
@@ -1508,28 +1629,12 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
ASTContext::GetBuiltinTypeError Error;
QualType R = Context.GetBuiltinType(BID, Error);
- switch (Error) {
- case ASTContext::GE_None:
- // Okay
- break;
-
- case ASTContext::GE_Missing_stdio:
+ if (Error) {
if (ForRedeclaration)
- Diag(Loc, diag::warn_implicit_decl_requires_stdio)
- << Context.BuiltinInfo.GetName(BID);
- return 0;
-
- case ASTContext::GE_Missing_setjmp:
- if (ForRedeclaration)
- Diag(Loc, diag::warn_implicit_decl_requires_setjmp)
- << Context.BuiltinInfo.GetName(BID);
- return 0;
-
- case ASTContext::GE_Missing_ucontext:
- if (ForRedeclaration)
- Diag(Loc, diag::warn_implicit_decl_requires_ucontext)
- << Context.BuiltinInfo.GetName(BID);
- return 0;
+ Diag(Loc, diag::warn_implicit_decl_requires_sysheader)
+ << getHeaderName(Error)
+ << Context.BuiltinInfo.GetName(BID);
+ return nullptr;
}
if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) {
@@ -1537,11 +1642,10 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
<< Context.BuiltinInfo.GetName(BID)
<< R;
if (Context.BuiltinInfo.getHeaderName(BID) &&
- Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc)
- != DiagnosticsEngine::Ignored)
- Diag(Loc, diag::note_please_include_header)
- << Context.BuiltinInfo.getHeaderName(BID)
- << Context.BuiltinInfo.GetName(BID);
+ !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc))
+ Diag(Loc, diag::note_include_header_or_declare)
+ << Context.BuiltinInfo.getHeaderName(BID)
+ << Context.BuiltinInfo.GetName(BID);
}
DeclContext *Parent = Context.getTranslationUnitDecl();
@@ -1549,13 +1653,14 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
LinkageSpecDecl *CLinkageDecl =
LinkageSpecDecl::Create(Context, Parent, Loc, Loc,
LinkageSpecDecl::lang_c, false);
+ CLinkageDecl->setImplicit();
Parent->addDecl(CLinkageDecl);
Parent = CLinkageDecl;
}
FunctionDecl *New = FunctionDecl::Create(Context,
Parent,
- Loc, Loc, II, R, /*TInfo=*/0,
+ Loc, Loc, II, R, /*TInfo=*/nullptr,
SC_Extern,
false,
/*hasPrototype=*/true);
@@ -1565,12 +1670,11 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
// FunctionDecl.
if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) {
SmallVector<ParmVarDecl*, 16> Params;
- for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
+ for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
ParmVarDecl *parm =
- ParmVarDecl::Create(Context, New, SourceLocation(),
- SourceLocation(), 0,
- FT->getArgType(i), /*TInfo=*/0,
- SC_None, 0);
+ ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(),
+ nullptr, FT->getParamType(i), /*TInfo=*/nullptr,
+ SC_None, nullptr);
parm->setScopeInfo(0, i);
Params.push_back(parm);
}
@@ -1789,7 +1893,7 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) {
Context.getSourceManager().isInSystemHeader(New->getLocation())))
return;
- Diag(New->getLocation(), diag::warn_redefinition_of_typedef)
+ Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
<< New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
return;
@@ -1797,46 +1901,19 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) {
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
-static bool
-DeclHasAttr(const Decl *D, const Attr *A) {
- // There can be multiple AvailabilityAttr in a Decl. Make sure we copy
- // all of them. It is mergeAvailabilityAttr in SemaDeclAttr.cpp that is
- // responsible for making sure they are consistent.
- const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(A);
- if (AA)
- return false;
-
- // The following thread safety attributes can also be duplicated.
- switch (A->getKind()) {
- case attr::ExclusiveLocksRequired:
- case attr::SharedLocksRequired:
- case attr::LocksExcluded:
- case attr::ExclusiveLockFunction:
- case attr::SharedLockFunction:
- case attr::UnlockFunction:
- case attr::ExclusiveTrylockFunction:
- case attr::SharedTrylockFunction:
- case attr::GuardedBy:
- case attr::PtGuardedBy:
- case attr::AcquiredBefore:
- case attr::AcquiredAfter:
- return false;
- default:
- ;
- }
-
+static bool DeclHasAttr(const Decl *D, const Attr *A) {
const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
const AnnotateAttr *Ann = dyn_cast<AnnotateAttr>(A);
- for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
- if ((*i)->getKind() == A->getKind()) {
+ for (const auto *i : D->attrs())
+ if (i->getKind() == A->getKind()) {
if (Ann) {
- if (Ann->getAnnotation() == cast<AnnotateAttr>(*i)->getAnnotation())
+ if (Ann->getAnnotation() == cast<AnnotateAttr>(i)->getAnnotation())
return true;
continue;
}
// FIXME: Don't hardcode this check
- if (OA && isa<OwnershipAttr>(*i))
- return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
+ if (OA && isa<OwnershipAttr>(i))
+ return OA->getOwnKind() == cast<OwnershipAttr>(i)->getOwnKind();
return true;
}
@@ -1858,12 +1935,10 @@ static bool isAttributeTargetADefinition(Decl *D) {
static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
// Look for alignas attributes on Old, and pick out whichever attribute
// specifies the strictest alignment requirement.
- AlignedAttr *OldAlignasAttr = 0;
- AlignedAttr *OldStrictestAlignAttr = 0;
+ AlignedAttr *OldAlignasAttr = nullptr;
+ AlignedAttr *OldStrictestAlignAttr = nullptr;
unsigned OldAlign = 0;
- for (specific_attr_iterator<AlignedAttr>
- I = Old->specific_attr_begin<AlignedAttr>(),
- E = Old->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+ for (auto *I : Old->specific_attrs<AlignedAttr>()) {
// FIXME: We have no way of representing inherited dependent alignments
// in a case like:
// template<int A, int B> struct alignas(A) X;
@@ -1874,26 +1949,24 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
return false;
if (I->isAlignas())
- OldAlignasAttr = *I;
+ OldAlignasAttr = I;
unsigned Align = I->getAlignment(S.Context);
if (Align > OldAlign) {
OldAlign = Align;
- OldStrictestAlignAttr = *I;
+ OldStrictestAlignAttr = I;
}
}
// Look for alignas attributes on New.
- AlignedAttr *NewAlignasAttr = 0;
+ AlignedAttr *NewAlignasAttr = nullptr;
unsigned NewAlign = 0;
- for (specific_attr_iterator<AlignedAttr>
- I = New->specific_attr_begin<AlignedAttr>(),
- E = New->specific_attr_end<AlignedAttr>(); I != E; ++I) {
+ for (auto *I : New->specific_attrs<AlignedAttr>()) {
if (I->isAlignmentDependent())
return false;
if (I->isAlignas())
- NewAlignasAttr = *I;
+ NewAlignasAttr = I;
unsigned Align = I->getAlignment(S.Context);
if (Align > NewAlign)
@@ -1939,9 +2012,9 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
// specifier, any other declaration of that object shall also
// have no alignment specifier.
S.Diag(New->getLocation(), diag::err_alignas_missing_on_definition)
- << OldAlignasAttr->isC11();
+ << OldAlignasAttr;
S.Diag(OldAlignasAttr->getLocation(), diag::note_alignas_on_declaration)
- << OldAlignasAttr->isC11();
+ << OldAlignasAttr;
}
bool AnyAdded = false;
@@ -1966,40 +2039,46 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
return AnyAdded;
}
-static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr,
- bool Override) {
- InheritableAttr *NewAttr = NULL;
+static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
+ const InheritableAttr *Attr, bool Override) {
+ InheritableAttr *NewAttr = nullptr;
unsigned AttrSpellingListIndex = Attr->getSpellingListIndex();
- if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr))
+ if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr))
NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
AA->getIntroduced(), AA->getDeprecated(),
AA->getObsoleted(), AA->getUnavailable(),
AA->getMessage(), Override,
AttrSpellingListIndex);
- else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr))
+ else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))
NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
AttrSpellingListIndex);
- else if (TypeVisibilityAttr *VA = dyn_cast<TypeVisibilityAttr>(Attr))
+ else if (const auto *VA = dyn_cast<TypeVisibilityAttr>(Attr))
NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
AttrSpellingListIndex);
- else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
+ else if (const auto *ImportA = dyn_cast<DLLImportAttr>(Attr))
NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(),
AttrSpellingListIndex);
- else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr))
+ else if (const auto *ExportA = dyn_cast<DLLExportAttr>(Attr))
NewAttr = S.mergeDLLExportAttr(D, ExportA->getRange(),
AttrSpellingListIndex);
- else if (FormatAttr *FA = dyn_cast<FormatAttr>(Attr))
+ else if (const auto *FA = dyn_cast<FormatAttr>(Attr))
NewAttr = S.mergeFormatAttr(D, FA->getRange(), FA->getType(),
FA->getFormatIdx(), FA->getFirstArg(),
AttrSpellingListIndex);
- else if (SectionAttr *SA = dyn_cast<SectionAttr>(Attr))
+ else if (const auto *SA = dyn_cast<SectionAttr>(Attr))
NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(),
AttrSpellingListIndex);
+ else if (const auto *IA = dyn_cast<MSInheritanceAttr>(Attr))
+ NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(),
+ AttrSpellingListIndex,
+ IA->getSemanticSpelling());
else if (isa<AlignedAttr>(Attr))
// AlignedAttrs are handled separately, because we need to handle all
// such attributes on a declaration at the same time.
- NewAttr = 0;
- else if (!DeclHasAttr(D, Attr))
+ NewAttr = nullptr;
+ else if (isa<DeprecatedAttr>(Attr) && Override)
+ NewAttr = nullptr;
+ else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr))
NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));
if (NewAttr) {
@@ -2025,16 +2104,13 @@ static const Decl *getDefinition(const Decl *D) {
if (FD->isDefined(Def))
return Def;
}
- return NULL;
+ return nullptr;
}
static bool hasAttribute(const Decl *D, attr::Kind Kind) {
- for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end();
- I != E; ++I) {
- Attr *Attribute = *I;
+ for (const auto *Attribute : D->attrs())
if (Attribute->getKind() == Kind)
return true;
- }
return false;
}
@@ -2097,9 +2173,9 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
// specifier, any other declaration of that object shall also
// have no alignment specifier.
S.Diag(Def->getLocation(), diag::err_alignas_missing_on_definition)
- << AA->isC11();
+ << AA;
S.Diag(NewAttribute->getLocation(), diag::note_alignas_on_declaration)
- << AA->isC11();
+ << AA;
NewAttributes.erase(NewAttributes.begin() + I);
--E;
continue;
@@ -2138,15 +2214,12 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
// we process them.
if (!foundAny) New->setAttrs(AttrVec());
- for (specific_attr_iterator<InheritableAttr>
- i = Old->specific_attr_begin<InheritableAttr>(),
- e = Old->specific_attr_end<InheritableAttr>();
- i != e; ++i) {
+ for (auto *I : Old->specific_attrs<InheritableAttr>()) {
bool Override = false;
// Ignore deprecated/unavailable/availability attributes if requested.
- if (isa<DeprecatedAttr>(*i) ||
- isa<UnavailableAttr>(*i) ||
- isa<AvailabilityAttr>(*i)) {
+ if (isa<DeprecatedAttr>(I) ||
+ isa<UnavailableAttr>(I) ||
+ isa<AvailabilityAttr>(I)) {
switch (AMK) {
case AMK_None:
continue;
@@ -2161,10 +2234,10 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
}
// Already handled.
- if (isa<UsedAttr>(*i))
+ if (isa<UsedAttr>(I))
continue;
- if (mergeDeclAttribute(*this, New, *i, Override))
+ if (mergeDeclAttribute(*this, New, I, Override))
foundAny = true;
}
@@ -2183,9 +2256,9 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
// The first declaration of a function shall specify the
// carries_dependency attribute for its declarator-id if any declaration
// of the function specifies the carries_dependency attribute.
- if (newDecl->hasAttr<CarriesDependencyAttr>() &&
- !oldDecl->hasAttr<CarriesDependencyAttr>()) {
- S.Diag(newDecl->getAttr<CarriesDependencyAttr>()->getLocation(),
+ const CarriesDependencyAttr *CDA = newDecl->getAttr<CarriesDependencyAttr>();
+ if (CDA && !oldDecl->hasAttr<CarriesDependencyAttr>()) {
+ S.Diag(CDA->getLocation(),
diag::err_carries_dependency_missing_on_first_decl) << 1/*Param*/;
// Find the first declaration of the parameter.
// FIXME: Should we build redeclaration chains for function parameters?
@@ -2206,12 +2279,10 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
// done before we process them.
if (!foundAny) newDecl->setAttrs(AttrVec());
- for (specific_attr_iterator<InheritableParamAttr>
- i = oldDecl->specific_attr_begin<InheritableParamAttr>(),
- e = oldDecl->specific_attr_end<InheritableParamAttr>(); i != e; ++i) {
- if (!DeclHasAttr(newDecl, *i)) {
+ for (const auto *I : oldDecl->specific_attrs<InheritableParamAttr>()) {
+ if (!DeclHasAttr(newDecl, I)) {
InheritableAttr *newAttr =
- cast<InheritableParamAttr>((*i)->clone(S.Context));
+ cast<InheritableParamAttr>(I->clone(S.Context));
newAttr->setInherited(true);
newDecl->addAttr(newAttr);
foundAny = true;
@@ -2255,6 +2326,24 @@ Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
return Sema::CXXInvalid;
}
+// Determine whether the previous declaration was a definition, implicit
+// declaration, or a declaration.
+template <typename T>
+static std::pair<diag::kind, SourceLocation>
+getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) {
+ diag::kind PrevDiag;
+ SourceLocation OldLocation = Old->getLocation();
+ if (Old->isThisDeclarationADefinition())
+ PrevDiag = diag::note_previous_definition;
+ else if (Old->isImplicit()) {
+ PrevDiag = diag::note_previous_implicit_declaration;
+ if (OldLocation.isInvalid())
+ OldLocation = New->getLocation();
+ } else
+ PrevDiag = diag::note_previous_declaration;
+ return std::make_pair(PrevDiag, OldLocation);
+}
+
/// canRedefineFunction - checks if a function can be redefined. Currently,
/// only extern inline functions can be redefined, and even then only in
/// GNU89 mode.
@@ -2298,15 +2387,10 @@ static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) {
/// merged with.
///
/// Returns true if there was an error, false otherwise.
-bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
- bool MergeTypeWithOld) {
+bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
+ Scope *S, bool MergeTypeWithOld) {
// Verify the old decl was also a function.
- FunctionDecl *Old = 0;
- if (FunctionTemplateDecl *OldFunctionTemplate
- = dyn_cast<FunctionTemplateDecl>(OldD))
- Old = OldFunctionTemplate->getTemplatedDecl();
- else
- Old = dyn_cast<FunctionDecl>(OldD);
+ FunctionDecl *Old = OldD->getAsFunction();
if (!Old) {
if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) {
if (New->getFriendObjectKind()) {
@@ -2318,33 +2402,44 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
return true;
}
- Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
- Diag(Shadow->getTargetDecl()->getLocation(),
- diag::note_using_decl_target);
- Diag(Shadow->getUsingDecl()->getLocation(),
- diag::note_using_decl) << 0;
+ // C++11 [namespace.udecl]p14:
+ // If a function declaration in namespace scope or block scope has the
+ // same name and the same parameter-type-list as a function introduced
+ // by a using-declaration, and the declarations do not declare the same
+ // function, the program is ill-formed.
+
+ // Check whether the two declarations might declare the same function.
+ Old = dyn_cast<FunctionDecl>(Shadow->getTargetDecl());
+ if (Old &&
+ !Old->getDeclContext()->getRedeclContext()->Equals(
+ New->getDeclContext()->getRedeclContext()) &&
+ !(Old->isExternC() && New->isExternC()))
+ Old = nullptr;
+
+ if (!Old) {
+ Diag(New->getLocation(), diag::err_using_decl_conflict_reverse);
+ Diag(Shadow->getTargetDecl()->getLocation(),
+ diag::note_using_decl_target);
+ Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0;
+ return true;
+ }
+ OldD = Old;
+ } else {
+ Diag(New->getLocation(), diag::err_redefinition_different_kind)
+ << New->getDeclName();
+ Diag(OldD->getLocation(), diag::note_previous_definition);
return true;
}
-
- Diag(New->getLocation(), diag::err_redefinition_different_kind)
- << New->getDeclName();
- Diag(OldD->getLocation(), diag::note_previous_definition);
- return true;
}
// If the old declaration is invalid, just give up here.
if (Old->isInvalidDecl())
return true;
- // Determine whether the previous declaration was a definition,
- // implicit declaration, or a declaration.
diag::kind PrevDiag;
- if (Old->isThisDeclarationADefinition())
- PrevDiag = diag::note_previous_definition;
- else if (Old->isImplicit())
- PrevDiag = diag::note_previous_implicit_declaration;
- else
- PrevDiag = diag::note_previous_declaration;
+ SourceLocation OldLocation;
+ std::tie(PrevDiag, OldLocation) =
+ getNoteDiagForInvalidRedeclaration(Old, New);
// Don't complain about this if we're in GNU89 mode and the old function
// is an extern inline function.
@@ -2356,11 +2451,11 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
!New->getTemplateSpecializationInfo() &&
!canRedefineFunction(Old, getLangOpts())) {
if (getLangOpts().MicrosoftExt) {
- Diag(New->getLocation(), diag::warn_static_non_static) << New;
- Diag(Old->getLocation(), PrevDiag);
+ Diag(New->getLocation(), diag::ext_static_non_static) << New;
+ Diag(OldLocation, PrevDiag);
} else {
Diag(New->getLocation(), diag::err_static_non_static) << New;
- Diag(Old->getLocation(), PrevDiag);
+ Diag(OldLocation, PrevDiag);
return true;
}
}
@@ -2426,7 +2521,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
Diag(New->getLocation(), diag::err_regparm_mismatch)
<< NewType->getRegParmType()
<< OldType->getRegParmType();
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, diag::note_previous_declaration);
return true;
}
@@ -2438,7 +2533,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
if (OldTypeInfo.getProducesResult() != NewTypeInfo.getProducesResult()) {
if (NewTypeInfo.getProducesResult()) {
Diag(New->getLocation(), diag::err_returns_retained_mismatch);
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, diag::note_previous_declaration);
return true;
}
@@ -2482,12 +2577,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
// Redeclarations or specializations of a function or function template
// with a declared return type that uses a placeholder type shall also
// use that placeholder, not a deduced type.
- QualType OldDeclaredReturnType = (Old->getTypeSourceInfo()
- ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>()
- : OldType)->getResultType();
- QualType NewDeclaredReturnType = (New->getTypeSourceInfo()
- ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>()
- : NewType)->getResultType();
+ QualType OldDeclaredReturnType =
+ (Old->getTypeSourceInfo()
+ ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>()
+ : OldType)->getReturnType();
+ QualType NewDeclaredReturnType =
+ (New->getTypeSourceInfo()
+ ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>()
+ : NewType)->getReturnType();
QualType ResQT;
if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) &&
!((NewQType->isDependentType() || OldQType->isDependentType()) &&
@@ -2497,23 +2594,25 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
if (ResQT.isNull()) {
if (New->isCXXClassMember() && New->isOutOfLine())
- Diag(New->getLocation(),
- diag::err_member_def_does_not_match_ret_type) << New;
+ Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type)
+ << New << New->getReturnTypeSourceRange();
else
- Diag(New->getLocation(), diag::err_ovl_diff_return_type);
- Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+ Diag(New->getLocation(), diag::err_ovl_diff_return_type)
+ << New->getReturnTypeSourceRange();
+ Diag(OldLocation, PrevDiag) << Old << Old->getType()
+ << Old->getReturnTypeSourceRange();
return true;
}
else
NewQType = ResQT;
}
- QualType OldReturnType = OldType->getResultType();
- QualType NewReturnType = cast<FunctionType>(NewQType)->getResultType();
+ QualType OldReturnType = OldType->getReturnType();
+ QualType NewReturnType = cast<FunctionType>(NewQType)->getReturnType();
if (OldReturnType != NewReturnType) {
// If this function has a deduced return type and has already been
// defined, copy the deduced value from the old declaration.
- AutoType *OldAT = Old->getResultType()->getContainedAutoType();
+ AutoType *OldAT = Old->getReturnType()->getContainedAutoType();
if (OldAT && OldAT->isDeduced()) {
New->setType(
SubstAutoType(New->getType(),
@@ -2533,8 +2632,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
NewMethod->setTrivial(OldMethod->isTrivial());
// MSVC allows explicit template specialization at class scope:
- // 2 CXMethodDecls referring to the same function will be injected.
- // We don't want a redeclartion error.
+ // 2 CXXMethodDecls referring to the same function will be injected.
+ // We don't want a redeclaration error.
bool IsClassScopeExplicitSpecialization =
OldMethod->isFunctionTemplateSpecialization() &&
NewMethod->isFunctionTemplateSpecialization();
@@ -2547,7 +2646,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
// is a static member function declaration.
if (OldMethod->isStatic() != NewMethod->isStatic()) {
Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member);
- Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+ Diag(OldLocation, PrevDiag) << Old << Old->getType();
return true;
}
@@ -2571,7 +2670,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
Diag(New->getLocation(), diag::err_member_redeclared_in_instantiation)
<< New << New->getType();
}
- Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+ Diag(OldLocation, PrevDiag) << Old << Old->getType();
// Complain if this is an explicit declaration of a special
// member that was initially declared implicitly.
@@ -2599,10 +2698,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
// The first declaration of a function shall specify the noreturn
// attribute if any declaration of that function specifies the noreturn
// attribute.
- if (New->hasAttr<CXX11NoReturnAttr>() &&
- !Old->hasAttr<CXX11NoReturnAttr>()) {
- Diag(New->getAttr<CXX11NoReturnAttr>()->getLocation(),
- diag::err_noreturn_missing_on_first_decl);
+ const CXX11NoReturnAttr *NRA = New->getAttr<CXX11NoReturnAttr>();
+ if (NRA && !Old->hasAttr<CXX11NoReturnAttr>()) {
+ Diag(NRA->getLocation(), diag::err_noreturn_missing_on_first_decl);
Diag(Old->getFirstDecl()->getLocation(),
diag::note_noreturn_missing_first_decl);
}
@@ -2611,9 +2709,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
// The first declaration of a function shall specify the
// carries_dependency attribute for its declarator-id if any declaration
// of the function specifies the carries_dependency attribute.
- if (New->hasAttr<CarriesDependencyAttr>() &&
- !Old->hasAttr<CarriesDependencyAttr>()) {
- Diag(New->getAttr<CarriesDependencyAttr>()->getLocation(),
+ const CarriesDependencyAttr *CDA = New->getAttr<CarriesDependencyAttr>();
+ if (CDA && !Old->hasAttr<CarriesDependencyAttr>()) {
+ Diag(CDA->getLocation(),
diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/;
Diag(Old->getFirstDecl()->getLocation(),
diag::note_carries_dependency_missing_first_decl) << 0/*Function*/;
@@ -2645,10 +2743,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
// Check cautiously as the friend object kind isn't yet complete.
if (New->getFriendObjectKind() != Decl::FOK_None) {
Diag(New->getLocation(), diag::ext_retained_language_linkage) << New;
- Diag(Old->getLocation(), PrevDiag);
+ Diag(OldLocation, PrevDiag);
} else {
Diag(New->getLocation(), diag::err_different_language_linkage) << New;
- Diag(Old->getLocation(), PrevDiag);
+ Diag(OldLocation, PrevDiag);
return true;
}
}
@@ -2673,32 +2771,26 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
Context.typesAreCompatible(OldQType, NewQType)) {
const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
- const FunctionProtoType *OldProto = 0;
+ const FunctionProtoType *OldProto = nullptr;
if (MergeTypeWithOld && isa<FunctionNoProtoType>(NewFuncType) &&
(OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) {
// The old declaration provided a function prototype, but the
// new declaration does not. Merge in the prototype.
assert(!OldProto->hasExceptionSpec() && "Exception spec in C");
- SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(),
- OldProto->arg_type_end());
- NewQType = Context.getFunctionType(NewFuncType->getResultType(),
- ParamTypes,
- OldProto->getExtProtoInfo());
+ SmallVector<QualType, 16> ParamTypes(OldProto->param_types());
+ NewQType =
+ Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes,
+ OldProto->getExtProtoInfo());
New->setType(NewQType);
New->setHasInheritedPrototype();
- // Synthesize a parameter for each argument type.
+ // Synthesize parameters with the same types.
SmallVector<ParmVarDecl*, 16> Params;
- for (FunctionProtoType::arg_type_iterator
- ParamType = OldProto->arg_type_begin(),
- ParamEnd = OldProto->arg_type_end();
- ParamType != ParamEnd; ++ParamType) {
- ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
- SourceLocation(),
- SourceLocation(), 0,
- *ParamType, /*TInfo=*/0,
- SC_None,
- 0);
+ for (const auto &ParamType : OldProto->param_types()) {
+ ParmVarDecl *Param = ParmVarDecl::Create(Context, New, SourceLocation(),
+ SourceLocation(), nullptr,
+ ParamType, /*TInfo=*/nullptr,
+ SC_None, nullptr);
Param->setScopeInfo(0, Params.size());
Param->setImplicit();
Params.push_back(Param);
@@ -2733,21 +2825,21 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
= New->getType()->getAs<FunctionProtoType>();
// Determine whether this is the GNU C extension.
- QualType MergedReturn = Context.mergeTypes(OldProto->getResultType(),
- NewProto->getResultType());
+ QualType MergedReturn = Context.mergeTypes(OldProto->getReturnType(),
+ NewProto->getReturnType());
bool LooseCompatible = !MergedReturn.isNull();
for (unsigned Idx = 0, End = Old->getNumParams();
LooseCompatible && Idx != End; ++Idx) {
ParmVarDecl *OldParm = Old->getParamDecl(Idx);
ParmVarDecl *NewParm = New->getParamDecl(Idx);
if (Context.typesAreCompatible(OldParm->getType(),
- NewProto->getArgType(Idx))) {
+ NewProto->getParamType(Idx))) {
ArgTypes.push_back(NewParm->getType());
} else if (Context.typesAreCompatible(OldParm->getType(),
NewParm->getType(),
/*CompareUnqualified=*/true)) {
- GNUCompatibleParamWarning Warn
- = { OldParm, NewParm, NewProto->getArgType(Idx) };
+ GNUCompatibleParamWarning Warn = { OldParm, NewParm,
+ NewProto->getParamType(Idx) };
Warnings.push_back(Warn);
ArgTypes.push_back(NewParm->getType());
} else
@@ -2785,7 +2877,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
// or 'printf', just warn about the incompatible redeclaration.
if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
- Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
+ Diag(OldLocation, diag::note_previous_builtin_declaration)
<< Old << Old->getType();
// If this is a global redeclaration, just forget hereafter
@@ -2806,7 +2898,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S,
}
Diag(New->getLocation(), diag::err_conflicting_types) << New->getDeclName();
- Diag(Old->getLocation(), PrevDiag) << Old << Old->getType();
+ Diag(OldLocation, PrevDiag) << Old << Old->getType();
return true;
}
@@ -3003,14 +3095,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
if (New->isInvalidDecl())
return;
+ VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate();
+
// Verify the old decl was also a variable or variable template.
- VarDecl *Old = 0;
- if (Previous.isSingleResult() &&
- (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
- if (New->getDescribedVarTemplate())
- Old = Old->getDescribedVarTemplate() ? Old : 0;
- else
- Old = Old->getDescribedVarTemplate() ? 0 : Old;
+ VarDecl *Old = nullptr;
+ VarTemplateDecl *OldTemplate = nullptr;
+ if (Previous.isSingleResult()) {
+ if (NewTemplate) {
+ OldTemplate = dyn_cast<VarTemplateDecl>(Previous.getFoundDecl());
+ Old = OldTemplate ? OldTemplate->getTemplatedDecl() : nullptr;
+ } else
+ Old = dyn_cast<VarDecl>(Previous.getFoundDecl());
}
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
@@ -3023,6 +3118,13 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
if (!shouldLinkPossiblyHiddenDecl(Old, New))
return;
+ // Ensure the template parameters are compatible.
+ if (NewTemplate &&
+ !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+ OldTemplate->getTemplateParameters(),
+ /*Complain=*/true, TPL_TemplateMatch))
+ return;
+
// C++ [class.mem]p1:
// A member shall not be declared twice in the member-specification [...]
//
@@ -3037,9 +3139,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
mergeDeclAttributes(New, Old);
// Warn if an already-declared variable is made a weak_import in a subsequent
// declaration
- if (New->getAttr<WeakImportAttr>() &&
+ if (New->hasAttr<WeakImportAttr>() &&
Old->getStorageClass() == SC_None &&
- !Old->getAttr<WeakImportAttr>()) {
+ !Old->hasAttr<WeakImportAttr>()) {
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
// Remove weak_import attribute on new declaration.
@@ -3052,13 +3154,25 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
if (New->isInvalidDecl())
return;
+ diag::kind PrevDiag;
+ SourceLocation OldLocation;
+ std::tie(PrevDiag, OldLocation) =
+ getNoteDiagForInvalidRedeclaration(Old, New);
+
// [dcl.stc]p8: Check if we have a non-static decl followed by a static.
if (New->getStorageClass() == SC_Static &&
!New->isStaticDataMember() &&
Old->hasExternalFormalLinkage()) {
- Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
- return New->setInvalidDecl();
+ if (getLangOpts().MicrosoftExt) {
+ Diag(New->getLocation(), diag::ext_static_non_static)
+ << New->getDeclName();
+ Diag(OldLocation, PrevDiag);
+ } else {
+ Diag(New->getLocation(), diag::err_static_non_static)
+ << New->getDeclName();
+ Diag(OldLocation, PrevDiag);
+ return New->setInvalidDecl();
+ }
}
// C99 6.2.2p4:
// For an identifier declared with the storage-class specifier
@@ -3075,7 +3189,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
!New->isStaticDataMember() &&
Old->getCanonicalDecl()->getStorageClass() == SC_Static) {
Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
@@ -3083,13 +3197,13 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
if (New->hasExternalStorage() &&
!Old->hasLinkage() && Old->isLocalVarDecl()) {
Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
if (Old->hasLinkage() && New->isLocalVarDecl() &&
!New->hasExternalStorage()) {
Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
@@ -3102,17 +3216,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
!(Old->getLexicalDeclContext()->isRecord() &&
!New->getLexicalDeclContext()->isRecord())) {
Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
if (New->getTLSKind() != Old->getTLSKind()) {
if (!Old->getTLSKind()) {
Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, PrevDiag);
} else if (!New->getTLSKind()) {
Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, PrevDiag);
} else {
// Do not allow redeclaration to change the variable between requiring
// static and dynamic initialization.
@@ -3120,7 +3234,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
// declaration to determine the kind. Do we need to be compatible here?
Diag(New->getLocation(), diag::err_thread_thread_different_kind)
<< New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic);
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, PrevDiag);
}
}
@@ -3137,7 +3251,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
if (haveIncompatibleLanguageLinkages(Old, New)) {
Diag(New->getLocation(), diag::err_different_language_linkage) << New;
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
New->setInvalidDecl();
return;
}
@@ -3148,14 +3262,13 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
// Keep a chain of previous declarations.
New->setPreviousDecl(Old);
+ if (NewTemplate)
+ NewTemplate->setPreviousDecl(OldTemplate);
// Inherit access appropriately.
New->setAccess(Old->getAccess());
-
- if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) {
- if (New->isStaticDataMember() && New->isOutOfLine())
- VTD->setAccess(New->getAccess());
- }
+ if (NewTemplate)
+ NewTemplate->setAccess(New->getAccess());
}
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
@@ -3165,7 +3278,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg());
}
-static void HandleTagNumbering(Sema &S, const TagDecl *Tag) {
+static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) {
if (!S.Context.getLangOpts().CPlusPlus)
return;
@@ -3176,7 +3289,8 @@ static void HandleTagNumbering(Sema &S, const TagDecl *Tag) {
return;
MangleNumberingContext &MCtx =
S.Context.getManglingNumberContext(Tag->getParent());
- S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag));
+ S.Context.setManglingNumber(
+ Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
return;
}
@@ -3185,7 +3299,9 @@ static void HandleTagNumbering(Sema &S, const TagDecl *Tag) {
if (MangleNumberingContext *MCtx =
S.getCurrentMangleNumberContext(Tag->getDeclContext(),
ManglingContextDecl)) {
- S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag));
+ S.Context.setManglingNumber(
+ Tag,
+ MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
}
}
@@ -3196,8 +3312,8 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DeclSpec &DS,
MultiTemplateParamsArg TemplateParams,
bool IsExplicitInstantiation) {
- Decl *TagD = 0;
- TagDecl *Tag = 0;
+ Decl *TagD = nullptr;
+ TagDecl *Tag = nullptr;
if (DS.getTypeSpecType() == DeclSpec::TST_class ||
DS.getTypeSpecType() == DeclSpec::TST_struct ||
DS.getTypeSpecType() == DeclSpec::TST_interface ||
@@ -3206,7 +3322,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
TagD = DS.getRepAsDecl();
if (!TagD) // We probably had an error
- return 0;
+ return nullptr;
// Note that the above type specs guarantee that the
// type rep is a Decl, whereas in many of the others
@@ -3218,7 +3334,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
}
if (Tag) {
- HandleTagNumbering(*this, Tag);
+ HandleTagNumbering(*this, Tag, S);
Tag->setFreeStanding();
if (Tag->isInvalidDecl())
return Tag;
@@ -3254,7 +3370,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
// If we're dealing with a decl but not a TagDecl, assume that
// whatever routines created it handled the friendship aspect.
if (TagD && !Tag)
- return 0;
+ return nullptr;
return ActOnFriendTypeDecl(S, DS, TemplateParams);
}
@@ -3273,7 +3389,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DS.getTypeSpecType() == DeclSpec::TST_interface ? 2 :
DS.getTypeSpecType() == DeclSpec::TST_union ? 3 : 4)
<< SS.getRange();
- return 0;
+ return nullptr;
}
// Track whether this decl-specifier declares anything.
@@ -3285,7 +3401,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
if (getLangOpts().CPlusPlus ||
Record->getDeclContext()->isRecord())
- return BuildAnonymousStructOrUnion(S, DS, AS, Record);
+ return BuildAnonymousStructOrUnion(S, DS, AS, Record, Context.getPrintingPolicy());
DeclaresAnything = false;
}
@@ -3368,10 +3484,15 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
// Note that a linkage-specification sets a storage class, but
// 'extern "C" struct foo;' is actually valid and not theoretically
// useless.
- if (DeclSpec::SCS SCS = DS.getStorageClassSpec())
- if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef)
+ if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
+ if (SCS == DeclSpec::SCS_mutable)
+ // Since mutable is not a viable storage class specifier in C, there is
+ // no reason to treat it as an extension. Instead, diagnose as an error.
+ Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_nonmember);
+ else if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef)
Diag(DS.getStorageClassSpecLoc(), DiagID)
<< DeclSpec::getSpecifierName(SCS);
+ }
if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec())
Diag(DS.getThreadStorageClassSpecLoc(), DiagID)
@@ -3471,12 +3592,10 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
bool Invalid = false;
// Look every FieldDecl and IndirectFieldDecl with a name.
- for (RecordDecl::decl_iterator D = AnonRecord->decls_begin(),
- DEnd = AnonRecord->decls_end();
- D != DEnd; ++D) {
- if ((isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) &&
- cast<NamedDecl>(*D)->getDeclName()) {
- ValueDecl *VD = cast<ValueDecl>(*D);
+ for (auto *D : AnonRecord->decls()) {
+ if ((isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) &&
+ cast<NamedDecl>(D)->getDeclName()) {
+ ValueDecl *VD = cast<ValueDecl>(D);
if (CheckAnonMemberRedeclaration(SemaRef, S, Owner, VD->getDeclName(),
VD->getLocation(), diagKind)) {
// C++ [class.union]p2:
@@ -3492,9 +3611,8 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
// anonymous union is declared.
unsigned OldChainingSize = Chaining.size();
if (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(VD))
- for (IndirectFieldDecl::chain_iterator PI = IF->chain_begin(),
- PE = IF->chain_end(); PI != PE; ++PI)
- Chaining.push_back(*PI);
+ for (auto *PI : IF->chain())
+ Chaining.push_back(PI);
else
Chaining.push_back(VD);
@@ -3549,13 +3667,45 @@ StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS) {
llvm_unreachable("unknown storage class specifier");
}
+static SourceLocation findDefaultInitializer(const CXXRecordDecl *Record) {
+ assert(Record->hasInClassInitializer());
+
+ for (const auto *I : Record->decls()) {
+ const auto *FD = dyn_cast<FieldDecl>(I);
+ if (const auto *IFD = dyn_cast<IndirectFieldDecl>(I))
+ FD = IFD->getAnonField();
+ if (FD && FD->hasInClassInitializer())
+ return FD->getLocation();
+ }
+
+ llvm_unreachable("couldn't find in-class initializer");
+}
+
+static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent,
+ SourceLocation DefaultInitLoc) {
+ if (!Parent->isUnion() || !Parent->hasInClassInitializer())
+ return;
+
+ S.Diag(DefaultInitLoc, diag::err_multiple_mem_union_initialization);
+ S.Diag(findDefaultInitializer(Parent), diag::note_previous_initializer) << 0;
+}
+
+static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent,
+ CXXRecordDecl *AnonUnion) {
+ if (!Parent->isUnion() || !Parent->hasInClassInitializer())
+ return;
+
+ checkDuplicateDefaultInit(S, Parent, findDefaultInitializer(AnonUnion));
+}
+
/// BuildAnonymousStructOrUnion - Handle the declaration of an
/// anonymous structure or union. Anonymous unions are a C++ feature
/// (C++ [class.union]) and a C11 feature; anonymous structures
/// are a C11 feature and GNU C++ extension.
Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
- AccessSpecifier AS,
- RecordDecl *Record) {
+ AccessSpecifier AS,
+ RecordDecl *Record,
+ const PrintingPolicy &Policy) {
DeclContext *Owner = Record->getDeclContext();
// Diagnose whether this anonymous struct/union is an extension.
@@ -3570,7 +3720,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// structs/unions.
bool Invalid = false;
if (getLangOpts().CPlusPlus) {
- const char* PrevSpec = 0;
+ const char *PrevSpec = nullptr;
unsigned DiagID;
if (Record->isUnion()) {
// C++ [class.union]p6:
@@ -3585,7 +3735,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Recover by adding 'static'.
DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(),
- PrevSpec, DiagID);
+ PrevSpec, DiagID, Policy);
}
// C++ [class.union]p6:
// A storage class is not allowed in a declaration of an
@@ -3599,7 +3749,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Recover by removing the storage specifier.
DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified,
SourceLocation(),
- PrevSpec, DiagID);
+ PrevSpec, DiagID, Context.getPrintingPolicy());
}
}
@@ -3632,10 +3782,8 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// The member-specification of an anonymous union shall only
// define non-static data members. [Note: nested types and
// functions cannot be declared within an anonymous union. ]
- for (DeclContext::decl_iterator Mem = Record->decls_begin(),
- MemEnd = Record->decls_end();
- Mem != MemEnd; ++Mem) {
- if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem)) {
+ for (auto *Mem : Record->decls()) {
+ if (auto *FD = dyn_cast<FieldDecl>(Mem)) {
// C++ [class.union]p3:
// An anonymous union shall not have private or protected
// members (clause 11).
@@ -3653,14 +3801,14 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// array of such objects.
if (CheckNontrivialField(FD))
Invalid = true;
- } else if ((*Mem)->isImplicit()) {
+ } else if (Mem->isImplicit()) {
// Any implicit members are fine.
- } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) {
+ } else if (isa<TagDecl>(Mem) && Mem->getDeclContext() != Record) {
// This is a type that showed up in an
// elaborated-type-specifier inside the anonymous struct or
// union, but which actually declares a type outside of the
// anonymous struct or union. It's okay.
- } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) {
+ } else if (auto *MemRecord = dyn_cast<RecordDecl>(Mem)) {
if (!MemRecord->isAnonymousStructOrUnion() &&
MemRecord->getDeclName()) {
// Visual C++ allows type definition in anonymous struct or union.
@@ -3681,31 +3829,41 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
diag::ext_anonymous_record_with_anonymous_type)
<< (int)Record->isUnion();
}
- } else if (isa<AccessSpecDecl>(*Mem)) {
+ } else if (isa<AccessSpecDecl>(Mem)) {
// Any access specifier is fine.
+ } else if (isa<StaticAssertDecl>(Mem)) {
+ // In C++1z, static_assert declarations are also fine.
} else {
// We have something that isn't a non-static data
// member. Complain about it.
unsigned DK = diag::err_anonymous_record_bad_member;
- if (isa<TypeDecl>(*Mem))
+ if (isa<TypeDecl>(Mem))
DK = diag::err_anonymous_record_with_type;
- else if (isa<FunctionDecl>(*Mem))
+ else if (isa<FunctionDecl>(Mem))
DK = diag::err_anonymous_record_with_function;
- else if (isa<VarDecl>(*Mem))
+ else if (isa<VarDecl>(Mem))
DK = diag::err_anonymous_record_with_static;
// Visual C++ allows type definition in anonymous struct or union.
if (getLangOpts().MicrosoftExt &&
DK == diag::err_anonymous_record_with_type)
- Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type)
+ Diag(Mem->getLocation(), diag::ext_anonymous_record_with_type)
<< (int)Record->isUnion();
else {
- Diag((*Mem)->getLocation(), DK)
+ Diag(Mem->getLocation(), DK)
<< (int)Record->isUnion();
Invalid = true;
}
}
}
+
+ // C++11 [class.union]p8 (DR1460):
+ // At most one variant member of a union may have a
+ // brace-or-equal-initializer.
+ if (cast<CXXRecordDecl>(Record)->hasInClassInitializer() &&
+ Owner->isRecord())
+ checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Owner),
+ cast<CXXRecordDecl>(Record));
}
if (!Record->isUnion() && !Owner->isRecord()) {
@@ -3720,15 +3878,15 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
assert(TInfo && "couldn't build declarator info for anonymous struct/union");
// Create a declaration for this anonymous struct/union.
- NamedDecl *Anon = 0;
+ NamedDecl *Anon = nullptr;
if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) {
Anon = FieldDecl::Create(Context, OwningClass,
DS.getLocStart(),
Record->getLocation(),
- /*IdentifierInfo=*/0,
+ /*IdentifierInfo=*/nullptr,
Context.getTypeDeclType(Record),
TInfo,
- /*BitWidth=*/0, /*Mutable=*/false,
+ /*BitWidth=*/nullptr, /*Mutable=*/false,
/*InitStyle=*/ICIS_NoInit);
Anon->setAccess(AS);
if (getLangOpts().CPlusPlus)
@@ -3746,7 +3904,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
Anon = VarDecl::Create(Context, Owner,
DS.getLocStart(),
- Record->getLocation(), /*IdentifierInfo=*/0,
+ Record->getLocation(), /*IdentifierInfo=*/nullptr,
Context.getTypeDeclType(Record),
TInfo, SC);
@@ -3758,11 +3916,14 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
}
Anon->setImplicit();
+ // Mark this as an anonymous struct/union type.
+ Record->setAnonymousStructOrUnion(true);
+
// Add the anonymous struct/union object to the current
// context. We'll be referencing this object when we refer to one of
// its members.
Owner->addDecl(Anon);
-
+
// Inject the members of the anonymous struct/union into the owning
// context and into the identifier resolver chain for name lookup
// purposes.
@@ -3773,13 +3934,17 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
Chain, false))
Invalid = true;
- // Mark this as an anonymous struct/union type. Note that we do not
- // do this until after we have already checked and injected the
- // members of this anonymous struct/union type, because otherwise
- // the members could be injected twice: once by DeclContext when it
- // builds its lookup table, and once by
- // InjectAnonymousStructOrUnionMembers.
- Record->setAnonymousStructOrUnion(true);
+ if (VarDecl *NewVD = dyn_cast<VarDecl>(Anon)) {
+ if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) {
+ Decl *ManglingContextDecl;
+ if (MangleNumberingContext *MCtx =
+ getCurrentMangleNumberContext(NewVD->getDeclContext(),
+ ManglingContextDecl)) {
+ Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+ Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
+ }
+ }
+ }
if (Invalid)
Anon->setInvalidDecl();
@@ -3813,14 +3978,14 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
assert(TInfo && "couldn't build declarator info for anonymous struct");
// Create a declaration for this anonymous struct.
- NamedDecl* Anon = FieldDecl::Create(Context,
+ NamedDecl *Anon = FieldDecl::Create(Context,
cast<RecordDecl>(CurContext),
DS.getLocStart(),
DS.getLocStart(),
- /*IdentifierInfo=*/0,
+ /*IdentifierInfo=*/nullptr,
Context.getTypeDeclType(Record),
TInfo,
- /*BitWidth=*/0, /*Mutable=*/false,
+ /*BitWidth=*/nullptr, /*Mutable=*/false,
/*InitStyle=*/ICIS_NoInit);
Anon->setImplicit();
@@ -3922,7 +4087,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
Context.getCanonicalType(CurClassType)));
NameInfo.setLoc(Name.StartLocation);
// FIXME: should we retrieve TypeSourceInfo?
- NameInfo.setNamedTypeInfo(0);
+ NameInfo.setNamedTypeInfo(nullptr);
return NameInfo;
}
@@ -4018,7 +4183,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
case DeclSpec::TST_underlyingType:
case DeclSpec::TST_atomic: {
// Grab the type from the parser.
- TypeSourceInfo *TSI = 0;
+ TypeSourceInfo *TSI = nullptr;
QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
if (T.isNull() || !T->isDependentType()) break;
@@ -4117,33 +4282,31 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,
/// \returns true if we cannot safely recover from this error, false otherwise.
bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
DeclarationName Name,
- SourceLocation Loc) {
+ SourceLocation Loc) {
DeclContext *Cur = CurContext;
while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur))
Cur = Cur->getParent();
-
- // C++ [dcl.meaning]p1:
- // A declarator-id shall not be qualified except for the definition
- // of a member function (9.3) or static data member (9.4) outside of
- // its class, the definition or explicit instantiation of a function
- // or variable member of a namespace outside of its namespace, or the
- // definition of an explicit specialization outside of its namespace,
- // or the declaration of a friend function that is a member of
- // another class or namespace (11.3). [...]
-
- // The user provided a superfluous scope specifier that refers back to the
- // class or namespaces in which the entity is already declared.
+
+ // If the user provided a superfluous scope specifier that refers back to the
+ // class in which the entity is already declared, diagnose and ignore it.
//
// class X {
// void X::f();
// };
+ //
+ // Note, it was once ill-formed to give redundant qualification in all
+ // contexts, but that rule was removed by DR482.
if (Cur->Equals(DC)) {
- Diag(Loc, LangOpts.MicrosoftExt? diag::warn_member_extra_qualification
- : diag::err_member_extra_qualification)
- << Name << FixItHint::CreateRemoval(SS.getRange());
- SS.clear();
+ if (Cur->isRecord()) {
+ Diag(Loc, LangOpts.MicrosoftExt ? diag::warn_member_extra_qualification
+ : diag::err_member_extra_qualification)
+ << Name << FixItHint::CreateRemoval(SS.getRange());
+ SS.clear();
+ } else {
+ Diag(Loc, diag::warn_namespace_member_extra_qualification) << Name;
+ }
return false;
- }
+ }
// Check whether the qualifying scope encloses the scope of the original
// declaration.
@@ -4212,9 +4375,9 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
Diag(D.getDeclSpec().getLocStart(),
diag::err_declarator_need_ident)
<< D.getDeclSpec().getSourceRange() << D.getSourceRange();
- return 0;
+ return nullptr;
} else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType))
- return 0;
+ return nullptr;
// The scope passed in may not be a decl scope. Zip up the scope tree until
// we find one that is.
@@ -4228,7 +4391,7 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
else if (D.getCXXScopeSpec().isSet()) {
if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(),
UPPC_DeclarationQualifier))
- return 0;
+ return nullptr;
bool EnteringContext = !D.getDeclSpec().isFriendSpecified();
DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext);
@@ -4239,15 +4402,15 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
// and return early, to avoid the coming semantic disaster.
Diag(D.getIdentifierLoc(),
diag::err_template_qualified_declarator_no_match)
- << (NestedNameSpecifier*)D.getCXXScopeSpec().getScopeRep()
+ << D.getCXXScopeSpec().getScopeRep()
<< D.getCXXScopeSpec().getRange();
- return 0;
+ return nullptr;
}
bool IsDependentContext = DC->isDependentContext();
if (!IsDependentContext &&
RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
- return 0;
+ return nullptr;
if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
Diag(D.getIdentifierLoc(),
@@ -4258,8 +4421,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC,
Name, D.getIdentifierLoc())) {
if (DC->isRecord())
- return 0;
-
+ return nullptr;
+
D.setInvalidType();
}
}
@@ -4278,8 +4441,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
// If this is a typedef, we'll end up spewing multiple diagnostics.
// Just return early; it's safer.
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
- return 0;
-
+ return nullptr;
+
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType R = TInfo->getType();
@@ -4380,7 +4543,7 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
if (TemplateParamLists.size()) {
Diag(D.getIdentifierLoc(), diag::err_template_typedef);
- return 0;
+ return nullptr;
}
New = ActOnTypedefDeclarator(S, D, DC, TInfo, Previous);
@@ -4393,8 +4556,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,
AddToScope);
}
- if (New == 0)
- return 0;
+ if (!New)
+ return nullptr;
// If this has an identifier and is not an invalid redeclaration or
// function template specialization, add it to the scope stack.
@@ -4521,7 +4684,7 @@ TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo,
= TryToFixInvalidVariablyModifiedType(TInfo->getType(), Context,
SizeIsNegative, Oversized);
if (FixedTy.isNull())
- return 0;
+ return nullptr;
TypeSourceInfo *FixedTInfo = Context.getTrivialTypeSourceInfo(FixedTy);
FixInvalidVariablyModifiedTypeLoc(TInfo->getTypeLoc(),
FixedTInfo->getTypeLoc());
@@ -4560,7 +4723,7 @@ NamedDecl *Sema::findLocallyScopedExternCDecl(DeclarationName Name) {
}
NamedDecl *D = LocallyScopedExternCDecls.lookup(Name);
- return D ? D->getMostRecentDecl() : 0;
+ return D ? D->getMostRecentDecl() : nullptr;
}
/// \brief Diagnose function specifiers on a declaration of an identifier that
@@ -4607,11 +4770,11 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (D.getName().Kind != UnqualifiedId::IK_Identifier) {
Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
<< D.getName().getSourceRange();
- return 0;
+ return nullptr;
}
TypedefDecl *NewTD = ParseTypedefDecl(S, D, TInfo->getType(), TInfo);
- if (!NewTD) return 0;
+ if (!NewTD) return nullptr;
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewTD, D);
@@ -4635,7 +4798,7 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) {
if (T->isVariablyModifiedType()) {
getCurFunction()->setHasBranchProtectedScope();
- if (S->getFnParent() == 0) {
+ if (S->getFnParent() == nullptr) {
bool SizeIsNegative;
llvm::APSInt Oversized;
TypeSourceInfo *FixedTInfo =
@@ -4670,8 +4833,8 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
LookupResult &Previous, bool &Redeclaration) {
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
- FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/ false,
- /*ExplicitInstantiationOrSpecialization=*/false);
+ FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false,
+ /*AllowInlineNamespace*/false);
filterNonConflictingPreviousDecls(Context, NewTD, Previous);
if (!Previous.empty()) {
Redeclaration = true;
@@ -4804,6 +4967,10 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
}
static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
+ // Ensure that an auto decl is deduced otherwise the checks below might cache
+ // the wrong linkage.
+ assert(S.ParsingInitForAutoVars.count(&ND) == 0);
+
// 'weak' only applies to declarations with external linkage.
if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) {
if (!ND.isExternallyVisible()) {
@@ -4826,6 +4993,79 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) {
ND.dropAttr<SelectAnyAttr>();
}
}
+
+ // dll attributes require external linkage.
+ if (const DLLImportAttr *Attr = ND.getAttr<DLLImportAttr>()) {
+ if (!ND.isExternallyVisible()) {
+ S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
+ << &ND << Attr;
+ ND.setInvalidDecl();
+ }
+ }
+ if (const DLLExportAttr *Attr = ND.getAttr<DLLExportAttr>()) {
+ if (!ND.isExternallyVisible()) {
+ S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
+ << &ND << Attr;
+ ND.setInvalidDecl();
+ }
+ }
+}
+
+static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
+ NamedDecl *NewDecl,
+ bool IsSpecialization) {
+ if (TemplateDecl *OldTD = dyn_cast<TemplateDecl>(OldDecl))
+ OldDecl = OldTD->getTemplatedDecl();
+ if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl))
+ NewDecl = NewTD->getTemplatedDecl();
+
+ if (!OldDecl || !NewDecl)
+ return;
+
+ const DLLImportAttr *OldImportAttr = OldDecl->getAttr<DLLImportAttr>();
+ const DLLExportAttr *OldExportAttr = OldDecl->getAttr<DLLExportAttr>();
+ const DLLImportAttr *NewImportAttr = NewDecl->getAttr<DLLImportAttr>();
+ const DLLExportAttr *NewExportAttr = NewDecl->getAttr<DLLExportAttr>();
+
+ // dllimport and dllexport are inheritable attributes so we have to exclude
+ // inherited attribute instances.
+ bool HasNewAttr = (NewImportAttr && !NewImportAttr->isInherited()) ||
+ (NewExportAttr && !NewExportAttr->isInherited());
+
+ // A redeclaration is not allowed to add a dllimport or dllexport attribute,
+ // the only exception being explicit specializations.
+ // Implicitly generated declarations are also excluded for now because there
+ // is no other way to switch these to use dllimport or dllexport.
+ bool AddsAttr = !(OldImportAttr || OldExportAttr) && HasNewAttr;
+ if (AddsAttr && !IsSpecialization && !OldDecl->isImplicit()) {
+ S.Diag(NewDecl->getLocation(), diag::err_attribute_dll_redeclaration)
+ << NewDecl
+ << (NewImportAttr ? (const Attr *)NewImportAttr : NewExportAttr);
+ S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+ NewDecl->setInvalidDecl();
+ return;
+ }
+
+ // A redeclaration is not allowed to drop a dllimport attribute, the only
+ // exception being inline function definitions.
+ // NB: MSVC converts such a declaration to dllexport.
+ bool IsInline = false, IsStaticDataMember = false;
+ if (const auto *VD = dyn_cast<VarDecl>(NewDecl))
+ // Ignore static data because out-of-line definitions are diagnosed
+ // separately.
+ IsStaticDataMember = VD->isStaticDataMember();
+ else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl))
+ IsInline = FD->isInlined();
+
+ if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) {
+ S.Diag(NewDecl->getLocation(),
+ diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
+ << NewDecl << OldImportAttr;
+ S.Diag(OldDecl->getLocation(), diag::note_previous_declaration);
+ S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute);
+ OldDecl->dropAttr<DLLImportAttr>();
+ NewDecl->dropAttr<DLLImportAttr>();
+ }
}
/// Given that we are within the definition of the given function,
@@ -4851,7 +5091,8 @@ static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) {
FD->setLazyBody(1);
#endif
- bool isC99Inline = (S.Context.GetGVALinkageForFunction(FD) == GVA_C99Inline);
+ bool isC99Inline =
+ S.Context.GetGVALinkageForFunction(FD) == GVA_AvailableExternally;
#ifndef NDEBUG
FD->setLazyBody(0);
@@ -4906,6 +5147,31 @@ static bool shouldConsiderLinkage(const FunctionDecl *FD) {
llvm_unreachable("Unexpected context");
}
+static bool hasParsedAttr(Scope *S, const AttributeList *AttrList,
+ AttributeList::Kind Kind) {
+ for (const AttributeList *L = AttrList; L; L = L->getNext())
+ if (L->getKind() == Kind)
+ return true;
+ return false;
+}
+
+static bool hasParsedAttr(Scope *S, const Declarator &PD,
+ AttributeList::Kind Kind) {
+ // Check decl attributes on the DeclSpec.
+ if (hasParsedAttr(S, PD.getDeclSpec().getAttributes().getList(), Kind))
+ return true;
+
+ // Walk the declarator structure, checking decl attributes that were in a type
+ // position to the decl itself.
+ for (unsigned I = 0, E = PD.getNumTypeObjects(); I != E; ++I) {
+ if (hasParsedAttr(S, PD.getTypeObject(I).getAttrs(), Kind))
+ return true;
+ }
+
+ // Finally, check attributes on the decl itself.
+ return hasParsedAttr(S, PD.getAttributes(), Kind);
+}
+
/// Adjust the \c DeclContext for a function or variable that might be a
/// function-local external declaration.
bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) {
@@ -4942,16 +5208,36 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
VarDecl::StorageClass SC =
StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());
+ // dllimport globals without explicit storage class are treated as extern. We
+ // have to change the storage class this early to get the right DeclContext.
+ if (SC == SC_None && !DC->isRecord() &&
+ hasParsedAttr(S, D, AttributeList::AT_DLLImport) &&
+ !hasParsedAttr(S, D, AttributeList::AT_DLLExport))
+ SC = SC_Extern;
+
DeclContext *OriginalDC = DC;
bool IsLocalExternDecl = SC == SC_Extern &&
adjustContextForLocalExternDecl(DC);
- if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16) {
- // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
- // half array type (unless the cl_khr_fp16 extension is enabled).
- if (Context.getBaseElementType(R)->isHalfType()) {
- Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
- D.setInvalidType();
+ if (getLangOpts().OpenCL) {
+ // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
+ QualType NR = R;
+ while (NR->isPointerType()) {
+ if (NR->isFunctionPointerType()) {
+ Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer_variable);
+ D.setInvalidType();
+ break;
+ }
+ NR = NR->getPointeeType();
+ }
+
+ if (!getOpenCLOptions().cl_khr_fp16) {
+ // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and
+ // half array type (unless the cl_khr_fp16 extension is enabled).
+ if (Context.getBaseElementType(R)->isHalfType()) {
+ Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R;
+ D.setInvalidType();
+ }
}
}
@@ -4978,21 +5264,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!II) {
Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
<< Name;
- return 0;
+ return nullptr;
}
DiagnoseFunctionSpecifiers(D.getDeclSpec());
- if (!DC->isRecord() && S->getFnParent() == 0) {
+ if (!DC->isRecord() && S->getFnParent() == nullptr) {
// C99 6.9p2: The storage-class specifiers auto and register shall not
// appear in the declaration specifiers in an external declaration.
- if (SC == SC_Auto || SC == SC_Register) {
- // If this is a register variable with an asm label specified, then this
- // is a GNU extension.
- if (SC == SC_Register && D.getAsmLabel())
- Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
- else
- Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
+ // Global Register+Asm is a GNU extension we support.
+ if (SC == SC_Auto || (SC == SC_Register && !D.getAsmLabel())) {
+ Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
D.setInvalidType();
}
}
@@ -5017,7 +5299,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// The event type cannot be used with the __local, __constant and __global
// address space qualifiers.
if (R->isEventT()) {
- if (S->getParent() == 0) {
+ if (S->getParent() == nullptr) {
Diag(D.getLocStart(), diag::err_event_t_global_var);
D.setInvalidType();
}
@@ -5033,9 +5315,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
bool IsVariableTemplateSpecialization = false;
bool IsPartialSpecialization = false;
bool IsVariableTemplate = false;
- VarTemplateDecl *PrevVarTemplate = 0;
- VarDecl *NewVD = 0;
- VarTemplateDecl *NewTemplate = 0;
+ VarDecl *NewVD = nullptr;
+ VarTemplateDecl *NewTemplate = nullptr;
+ TemplateParameterList *TemplateParams = nullptr;
if (!getLangOpts().CPlusPlus) {
NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
D.getIdentifierLoc(), II,
@@ -5097,18 +5379,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
- NamedDecl *PrevDecl = 0;
- if (Previous.begin() != Previous.end())
- PrevDecl = (*Previous.begin())->getUnderlyingDecl();
- PrevVarTemplate = dyn_cast_or_null<VarTemplateDecl>(PrevDecl);
-
// Match up the template parameter lists with the scope specifier, then
// determine whether we have a template or a template specialization.
- TemplateParameterList *TemplateParams =
- MatchTemplateParametersToScopeSpecifier(
- D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
- D.getCXXScopeSpec(), TemplateParamLists,
- /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+ TemplateParams = MatchTemplateParametersToScopeSpecifier(
+ D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
+ D.getCXXScopeSpec(),
+ D.getName().getKind() == UnqualifiedId::IK_TemplateId
+ ? D.getName().TemplateId
+ : nullptr,
+ TemplateParamLists,
+ /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+
if (TemplateParams) {
if (!TemplateParams->size() &&
D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
@@ -5119,113 +5400,43 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
<< II
<< SourceRange(TemplateParams->getTemplateLoc(),
TemplateParams->getRAngleLoc());
+ TemplateParams = nullptr;
} else {
- // Only C++1y supports variable templates (N3651).
- Diag(D.getIdentifierLoc(),
- getLangOpts().CPlusPlus1y
- ? diag::warn_cxx11_compat_variable_template
- : diag::ext_variable_template);
-
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
// This is an explicit specialization or a partial specialization.
- // Check that we can declare a specialization here
-
+ // FIXME: Check that we can declare a specialization here.
IsVariableTemplateSpecialization = true;
IsPartialSpecialization = TemplateParams->size() > 0;
-
} else { // if (TemplateParams->size() > 0)
// This is a template declaration.
IsVariableTemplate = true;
// Check that we can declare a template here.
if (CheckTemplateDeclScope(S, TemplateParams))
- return 0;
-
- // If there is a previous declaration with the same name, check
- // whether this is a valid redeclaration.
- if (PrevDecl && !isDeclInScope(PrevDecl, DC, S))
- PrevDecl = PrevVarTemplate = 0;
-
- if (PrevVarTemplate) {
- // Ensure that the template parameter lists are compatible.
- if (!TemplateParameterListsAreEqual(
- TemplateParams, PrevVarTemplate->getTemplateParameters(),
- /*Complain=*/true, TPL_TemplateMatch))
- return 0;
- } else if (PrevDecl && PrevDecl->isTemplateParameter()) {
- // Maybe we will complain about the shadowed template parameter.
- DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
-
- // Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
- } else if (PrevDecl) {
- // C++ [temp]p5:
- // ... a template name declared in namespace scope or in class
- // scope shall be unique in that scope.
- Diag(D.getIdentifierLoc(), diag::err_redefinition_different_kind)
- << Name;
- Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- return 0;
- }
+ return nullptr;
- // Check the template parameter list of this declaration, possibly
- // merging in the template parameter list from the previous variable
- // template declaration.
- if (CheckTemplateParameterList(
- TemplateParams,
- PrevVarTemplate ? PrevVarTemplate->getTemplateParameters()
- : 0,
- (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() &&
- DC->isDependentContext())
- ? TPC_ClassTemplateMember
- : TPC_VarTemplate))
- Invalid = true;
-
- if (D.getCXXScopeSpec().isSet()) {
- // If the name of the template was qualified, we must be defining
- // the template out-of-line.
- if (!D.getCXXScopeSpec().isInvalid() && !Invalid &&
- !PrevVarTemplate) {
- Diag(D.getIdentifierLoc(), diag::err_member_decl_does_not_match)
- << Name << DC << /*IsDefinition*/true
- << D.getCXXScopeSpec().getRange();
- Invalid = true;
- }
- }
+ // Only C++1y supports variable templates (N3651).
+ Diag(D.getIdentifierLoc(),
+ getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_variable_template
+ : diag::ext_variable_template);
}
}
- } else if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
- TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
-
- // We have encountered something that the user meant to be a
- // specialization (because it has explicitly-specified template
- // arguments) but that was not introduced with a "template<>" (or had
- // too few of them).
- // FIXME: Differentiate between attempts for explicit instantiations
- // (starting with "template") and the rest.
- Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
- << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
- << FixItHint::CreateInsertion(D.getDeclSpec().getLocStart(),
- "template<> ");
- IsVariableTemplateSpecialization = true;
+ } else {
+ assert(D.getName().getKind() != UnqualifiedId::IK_TemplateId &&
+ "should have a 'template<>' for this decl");
}
if (IsVariableTemplateSpecialization) {
- if (!PrevVarTemplate) {
- Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template)
- << IsPartialSpecialization;
- return 0;
- }
-
SourceLocation TemplateKWLoc =
TemplateParamLists.size() > 0
? TemplateParamLists[0]->getTemplateLoc()
: SourceLocation();
DeclResult Res = ActOnVarTemplateSpecialization(
- S, PrevVarTemplate, D, TInfo, TemplateKWLoc, TemplateParams, SC,
+ S, D, TInfo, TemplateKWLoc, TemplateParams, SC,
IsPartialSpecialization);
if (Res.isInvalid())
- return 0;
+ return nullptr;
NewVD = cast<VarDecl>(Res.get());
AddToScope = false;
} else
@@ -5236,7 +5447,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (IsVariableTemplate) {
NewTemplate =
VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name,
- TemplateParams, NewVD, PrevVarTemplate);
+ TemplateParams, NewVD);
NewVD->setDescribedVarTemplate(NewTemplate);
}
@@ -5253,18 +5464,13 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
SetNestedNameSpecifier(NewVD, D);
- // FIXME: Do we need D.getCXXScopeSpec().isSet()?
- if (TemplateParams && TemplateParamLists.size() > 1 &&
- (!IsVariableTemplateSpecialization || D.getCXXScopeSpec().isSet())) {
+ // If we have any template parameter lists that don't directly belong to
+ // the variable (matching the scope specifier), store them.
+ unsigned VDTemplateParamLists = TemplateParams ? 1 : 0;
+ if (TemplateParamLists.size() > VDTemplateParamLists)
NewVD->setTemplateParameterListsInfo(
- Context, TemplateParamLists.size() - 1, TemplateParamLists.data());
- } else if (IsVariableTemplateSpecialization ||
- (!TemplateParams && TemplateParamLists.size() > 0 &&
- (D.getCXXScopeSpec().isSet()))) {
- NewVD->setTemplateParameterListsInfo(Context,
- TemplateParamLists.size(),
- TemplateParamLists.data());
- }
+ Context, TemplateParamLists.size() - VDTemplateParamLists,
+ TemplateParamLists.data());
if (D.getDeclSpec().isConstexprSpecified())
NewVD->setConstexpr(true);
@@ -5311,7 +5517,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// that a local variable with thread storage duration still has to
// be marked 'static'. Also note that it's possible to get these
// semantics in C++ using __attribute__((gnu_inline)).
- if (SC == SC_Static && S->getFnParent() != 0 &&
+ if (SC == SC_Static && S->getFnParent() != nullptr &&
!NewVD->getType().isConstQualified()) {
FunctionDecl *CurFD = getCurFunctionDecl();
if (CurFD && isFunctionDefinitionDiscarded(*this, CurFD)) {
@@ -5346,19 +5552,23 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(S, NewVD, D);
- if (NewVD->hasAttrs())
- CheckAlignasUnderalignment(NewVD);
-
if (getLangOpts().CUDA) {
// CUDA B.2.5: "__shared__ and __constant__ variables have implied static
// storage [duration]."
- if (SC == SC_None && S->getFnParent() != 0 &&
+ if (SC == SC_None && S->getFnParent() != nullptr &&
(NewVD->hasAttr<CUDASharedAttr>() ||
NewVD->hasAttr<CUDAConstantAttr>())) {
NewVD->setStorageClass(SC_Static);
}
}
+ // Ensure that dllimport globals without explicit storage class are treated as
+ // extern. The storage class is set above using parsed attributes. Now we can
+ // check the VarDecl itself.
+ assert(!NewVD->hasAttr<DLLImportAttr>() ||
+ NewVD->getAttr<DLLImportAttr>()->isInherited() ||
+ NewVD->isStaticDataMember() || NewVD->getStorageClass() != SC_None);
+
// In auto-retain/release, infer strong retension for variables of
// retainable type.
if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewVD))
@@ -5369,13 +5579,14 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
StringRef Label = SE->getString();
- if (S->getFnParent() != 0) {
+ if (S->getFnParent() != nullptr) {
switch (SC) {
case SC_None:
case SC_Auto:
Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
break;
case SC_Register:
+ // Local Named register
if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
break;
@@ -5385,10 +5596,18 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
case SC_OpenCLWorkGroupLocal:
break;
}
+ } else if (SC == SC_Register) {
+ // Global Named register
+ if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+ if (!R->isIntegralType(Context) && !R->isPointerType()) {
+ Diag(D.getLocStart(), diag::err_asm_bad_register_type);
+ NewVD->setInvalidDecl(true);
+ }
}
NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
- Context, Label));
+ Context, Label, 0));
} else if (!ExtnameUndeclaredIdentifiers.empty()) {
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -5399,15 +5618,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
// Diagnose shadowed variables before filtering for scope.
- if (!D.getCXXScopeSpec().isSet())
+ if (D.getCXXScopeSpec().isEmpty())
CheckShadow(S, NewVD, Previous);
// Don't consider existing declarations that are in a different
// scope and are out-of-semantic-context declarations (if the new
// declaration has linkage).
- FilterLookupForScope(
- Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),
- IsExplicitSpecialization || IsVariableTemplateSpecialization);
+ FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),
+ D.getCXXScopeSpec().isNotEmpty() ||
+ IsExplicitSpecialization ||
+ IsVariableTemplateSpecialization);
// Check whether the previous declaration is in the same block scope. This
// affects whether we merge types with it, per C++11 [dcl.array]p3.
@@ -5420,6 +5640,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!getLangOpts().CPlusPlus) {
D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
} else {
+ // If this is an explicit specialization of a static data member, check it.
+ if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
+ CheckMemberSpecialization(NewVD, Previous))
+ NewVD->setInvalidDecl();
+
// Merge the decl with the existing one if appropriate.
if (!Previous.empty()) {
if (Previous.isSingleResult() &&
@@ -5440,24 +5665,37 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewVD->setInvalidDecl();
}
- if (!IsVariableTemplateSpecialization) {
- if (PrevVarTemplate) {
- LookupResult PrevDecl(*this, GetNameForDeclarator(D),
- LookupOrdinaryName, ForRedeclaration);
- PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl());
- D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl));
- } else
- D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
- }
+ if (!IsVariableTemplateSpecialization)
+ D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
+
+ if (NewTemplate) {
+ VarTemplateDecl *PrevVarTemplate =
+ NewVD->getPreviousDecl()
+ ? NewVD->getPreviousDecl()->getDescribedVarTemplate()
+ : nullptr;
+
+ // Check the template parameter list of this declaration, possibly
+ // merging in the template parameter list from the previous variable
+ // template declaration.
+ if (CheckTemplateParameterList(
+ TemplateParams,
+ PrevVarTemplate ? PrevVarTemplate->getTemplateParameters()
+ : nullptr,
+ (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() &&
+ DC->isDependentContext())
+ ? TPC_ClassTemplateMember
+ : TPC_VarTemplate))
+ NewVD->setInvalidDecl();
- // This is an explicit specialization of a static data member. Check it.
- if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
- CheckMemberSpecialization(NewVD, Previous))
- NewVD->setInvalidDecl();
+ // If we are providing an explicit specialization of a static variable
+ // template, make a note of that.
+ if (PrevVarTemplate &&
+ PrevVarTemplate->getInstantiatedFromMemberTemplate())
+ PrevVarTemplate->setMemberSpecialization();
+ }
}
ProcessPragmaWeak(S, NewVD);
- checkAttributesAfterMerging(*this, *NewVD);
// If this is the first declaration of an extern C variable, update
// the map of such variables.
@@ -5470,16 +5708,21 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (MangleNumberingContext *MCtx =
getCurrentMangleNumberContext(NewVD->getDeclContext(),
ManglingContextDecl)) {
- Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD));
+ Context.setManglingNumber(
+ NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+ Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
}
}
- // If we are providing an explicit specialization of a static variable
- // template, make a note of that.
- if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate())
- PrevVarTemplate->setMemberSpecialization();
+ if (D.isRedeclaration() && !Previous.empty()) {
+ checkDLLAttributeRedeclaration(
+ *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD,
+ IsExplicitSpecialization);
+ }
if (NewTemplate) {
+ if (NewVD->isInvalidDecl())
+ NewTemplate->setInvalidDecl();
ActOnDocumentableDecl(NewTemplate);
return NewTemplate;
}
@@ -5498,8 +5741,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
///
void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
// Return if warning is ignored.
- if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, R.getNameLoc()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
return;
// Don't diagnose declarations at file scope.
@@ -5526,11 +5768,9 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
if (shadowedVar->isExternC()) {
// For shadowing external vars, make sure that we point to the global
// declaration, not a locally scoped extern declaration.
- for (VarDecl::redecl_iterator
- I = shadowedVar->redecls_begin(), E = shadowedVar->redecls_end();
- I != E; ++I)
+ for (auto I : shadowedVar->redecls())
if (I->isFileVarDecl()) {
- ShadowedDecl = *I;
+ ShadowedDecl = I;
break;
}
}
@@ -5566,14 +5806,15 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
DeclarationName Name = R.getLookupName();
// Emit warning and note.
+ if (getSourceManager().isInSystemMacro(R.getNameLoc()))
+ return;
Diag(R.getNameLoc(), diag::warn_decl_shadow) << Name << Kind << OldDC;
Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration);
}
/// \brief Check -Wshadow without the advantage of a previous lookup.
void Sema::CheckShadow(Scope *S, VarDecl *D) {
- if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, D->getLocation()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_decl_shadow, D->getLocation()))
return;
LookupResult R(*this, D->getDeclName(), D->getLocation(),
@@ -5711,6 +5952,9 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
if (T->isUndeducedType())
return;
+ if (NewVD->hasAttrs())
+ CheckAlignasUnderalignment(NewVD);
+
if (T->isObjCObjectType()) {
Diag(NewVD->getLocation(), diag::err_statically_allocated_object)
<< FixItHint::CreateInsertion(NewVD->getLocation(), "*");
@@ -5769,7 +6013,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
TypeSourceInfo *FixedTInfo =
TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context,
SizeIsNegative, Oversized);
- if (FixedTInfo == 0 && T->isVariableArrayType()) {
+ if (!FixedTInfo && T->isVariableArrayType()) {
const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
// FIXME: This won't give the correct result for
// int a[10][n];
@@ -5788,7 +6032,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
return;
}
- if (FixedTInfo == 0) {
+ if (!FixedTInfo) {
if (NewVD->isFileVarDecl())
Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope);
else
@@ -5828,7 +6072,6 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
if (NewVD->isConstexpr() && !T->isDependentType() &&
RequireLiteralType(NewVD->getLocation(), T,
diag::err_constexpr_var_non_literal)) {
- // Can't perform this check until the type is deduced.
NewVD->setInvalidDecl();
return;
}
@@ -5947,9 +6190,8 @@ bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
bool hasNonDeletedOverridenMethods = false;
bool AddedAny = false;
if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) {
- for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
- E = Paths.found_decls_end(); I != E; ++I) {
- if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
+ for (auto *I : Paths.found_decls()) {
+ if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(I)) {
MD->addOverriddenMethod(OldMD->getCanonicalDecl());
if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
!CheckOverridingFunctionAttributes(MD, OldMD) &&
@@ -5993,9 +6235,9 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
DifferentNameValidatorCCC(ASTContext &Context, FunctionDecl *TypoFD,
CXXRecordDecl *Parent)
: Context(Context), OriginalFD(TypoFD),
- ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {}
+ ExpectedParent(Parent ? Parent->getCanonicalDecl() : nullptr) {}
- virtual bool ValidateCandidate(const TypoCorrection &candidate) {
+ bool ValidateCandidate(const TypoCorrection &candidate) override {
if (candidate.getEditDistance() == 0)
return false;
@@ -6062,7 +6304,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
"Cannot have an ambiguity in previous-declaration lookup");
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
DifferentNameValidatorCCC Validator(SemaRef.Context, NewFD,
- MD ? MD->getParent() : 0);
+ MD ? MD->getParent() : nullptr);
if (!Prev.empty()) {
for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end();
Func != FuncEnd; ++Func) {
@@ -6080,7 +6322,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
} else if ((Correction = SemaRef.CorrectTypo(
Prev.getLookupNameInfo(), Prev.getLookupKind(), S,
&ExtraArgs.D.getCXXScopeSpec(), Validator,
- IsLocalFriend ? 0 : NewDC))) {
+ Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) {
// Set up everything for the call to ActOnFunctionDeclarator
ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(),
ExtraArgs.D.getIdentifierLoc());
@@ -6114,7 +6356,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
ExtraArgs.AddToScope);
if (Trap.hasErrorOccurred())
- Result = 0;
+ Result = nullptr;
}
if (Result) {
@@ -6174,7 +6416,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
IsMember ? diag::note_member_def_close_match
: diag::note_local_decl_close_match);
}
- return 0;
+ return nullptr;
}
static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef,
@@ -6221,7 +6463,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
DeclarationNameInfo NameInfo = SemaRef.GetNameForDeclarator(D);
DeclarationName Name = NameInfo.getName();
- FunctionDecl *NewFD = 0;
+ FunctionDecl *NewFD = nullptr;
bool isInline = D.getDeclSpec().isInlineSpecified();
if (!SemaRef.getLangOpts().CPlusPlus) {
@@ -6254,10 +6496,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// For record types, this is done by the AbstractClassUsageDiagnoser once
// the class has been completely parsed.
if (!DC->isRecord() &&
- SemaRef.RequireNonAbstractType(D.getIdentifierLoc(),
- R->getAs<FunctionType>()->getResultType(),
- diag::err_abstract_type_in_decl,
- SemaRef.AbstractReturnType))
+ SemaRef.RequireNonAbstractType(
+ D.getIdentifierLoc(), R->getAs<FunctionType>()->getReturnType(),
+ diag::err_abstract_type_in_decl, SemaRef.AbstractReturnType))
D.setInvalidType();
if (Name.getNameKind() == DeclarationName::CXXConstructorName) {
@@ -6292,15 +6533,6 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
SemaRef.AdjustDestructorExceptionSpec(Record, NewDD);
}
- // The Microsoft ABI requires that we perform the destructor body
- // checks (i.e. operator delete() lookup) at every declaration, as
- // any translation unit may need to emit a deleting destructor.
- if (SemaRef.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- !Record->isDependentType() && Record->getDefinition() &&
- !Record->isBeingDefined()) {
- SemaRef.CheckDestructor(NewDD);
- }
-
IsVirtualOkay = true;
return NewDD;
@@ -6321,7 +6553,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
if (!DC->isRecord()) {
SemaRef.Diag(D.getIdentifierLoc(),
diag::err_conv_function_not_member);
- return 0;
+ return nullptr;
}
SemaRef.CheckConversionDeclarator(D, R, SC);
@@ -6341,7 +6573,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
SemaRef.Diag(D.getIdentifierLoc(), diag::err_constructor_return_type)
<< SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
<< SourceRange(D.getIdentifierLoc());
- return 0;
+ return nullptr;
}
// This is a C++ method declaration.
@@ -6363,26 +6595,11 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
}
}
-void Sema::checkVoidParamDecl(ParmVarDecl *Param) {
- // In C++, the empty parameter-type-list must be spelled "void"; a
- // typedef of void is not permitted.
- if (getLangOpts().CPlusPlus &&
- Param->getType().getUnqualifiedType() != Context.VoidTy) {
- bool IsTypeAlias = false;
- if (const TypedefType *TT = Param->getType()->getAs<TypedefType>())
- IsTypeAlias = isa<TypeAliasDecl>(TT->getDecl());
- else if (const TemplateSpecializationType *TST =
- Param->getType()->getAs<TemplateSpecializationType>())
- IsTypeAlias = TST->isTypeAlias();
- Diag(Param->getLocation(), diag::err_param_typedef_of_void)
- << IsTypeAlias;
- }
-}
-
enum OpenCLParamType {
ValidKernelParam,
PtrPtrKernelParam,
PtrKernelParam,
+ PrivatePtrKernelParam,
InvalidKernelParam,
RecordKernelParam
};
@@ -6390,7 +6607,10 @@ enum OpenCLParamType {
static OpenCLParamType getOpenCLKernelParameterType(QualType PT) {
if (PT->isPointerType()) {
QualType PointeeType = PT->getPointeeType();
- return PointeeType->isPointerType() ? PtrPtrKernelParam : PtrKernelParam;
+ if (PointeeType->isPointerType())
+ return PtrPtrKernelParam;
+ return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam
+ : PtrKernelParam;
}
// TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can
@@ -6435,6 +6655,14 @@ static void checkIsValidOpenCLKernelParameter(
D.setInvalidType();
return;
+ case PrivatePtrKernelParam:
+ // OpenCL v1.2 s6.9.a:
+ // A kernel function argument cannot be declared as a
+ // pointer to the private address space.
+ S.Diag(Param->getLocation(), diag::err_opencl_private_ptr_kernel_param);
+ D.setInvalidType();
+ return;
+
// OpenCL v1.2 s6.9.k:
// Arguments to kernel functions in a program cannot be declared with the
// built-in scalar types bool, half, size_t, ptrdiff_t, intptr_t, and
@@ -6464,7 +6692,7 @@ static void checkIsValidOpenCLKernelParameter(
// Track where we are in the nested structs. Items will migrate from
// VisitStack to HistoryStack as we do the DFS for bad field.
SmallVector<const FieldDecl *, 4> HistoryStack;
- HistoryStack.push_back((const FieldDecl *) 0);
+ HistoryStack.push_back(nullptr);
const RecordDecl *PD = PT->castAs<RecordType>()->getDecl();
VisitStack.push_back(PD);
@@ -6493,11 +6721,9 @@ static void checkIsValidOpenCLKernelParameter(
}
// Add a null marker so we know when we've gone back up a level
- VisitStack.push_back((const Decl *) 0);
+ VisitStack.push_back(nullptr);
- for (RecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end(); I != E; ++I) {
- const FieldDecl *FD = *I;
+ for (const auto *FD : RD->fields()) {
QualType QT = FD->getType();
if (ValidTypes.count(QT.getTypePtr()))
@@ -6516,7 +6742,8 @@ static void checkIsValidOpenCLKernelParameter(
// Arguments to kernel functions that are declared to be a struct or union
// do not allow OpenCL objects to be passed as elements of the struct or
// union.
- if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) {
+ if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam ||
+ ParamType == PrivatePtrKernelParam) {
S.Diag(Param->getLocation(),
diag::err_record_with_pointers_kernel_param)
<< PT->isUnionType()
@@ -6569,7 +6796,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
adjustMemberFunctionCC(R, D.isStaticMember());
bool isFriend = false;
- FunctionTemplateDecl *FunctionTemplate = 0;
+ FunctionTemplateDecl *FunctionTemplate = nullptr;
bool isExplicitSpecialization = false;
bool isFunctionTemplateSpecialization = false;
@@ -6584,7 +6811,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC,
isVirtualOkay);
- if (!NewFD) return 0;
+ if (!NewFD) return nullptr;
if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer())
NewFD->setTopLevelDeclInObjCContainer();
@@ -6631,19 +6858,23 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (TemplateParameterList *TemplateParams =
MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
- D.getCXXScopeSpec(), TemplateParamLists, isFriend,
- isExplicitSpecialization, Invalid)) {
+ D.getCXXScopeSpec(),
+ D.getName().getKind() == UnqualifiedId::IK_TemplateId
+ ? D.getName().TemplateId
+ : nullptr,
+ TemplateParamLists, isFriend, isExplicitSpecialization,
+ Invalid)) {
if (TemplateParams->size() > 0) {
// This is a function template
// Check that we can declare a template here.
if (CheckTemplateDeclScope(S, TemplateParams))
- return 0;
+ return nullptr;
// A destructor cannot be a template.
if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
Diag(NewFD->getLocation(), diag::err_destructor_template);
- return 0;
+ return nullptr;
}
// If we're adding a template to a dependent context, we may need to
@@ -6673,9 +6904,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// This is a function template specialization.
isFunctionTemplateSpecialization = true;
// For source fidelity, store all the template param lists.
- NewFD->setTemplateParameterListsInfo(Context,
- TemplateParamLists.size(),
- TemplateParamLists.data());
+ if (TemplateParamLists.size() > 0)
+ NewFD->setTemplateParameterListsInfo(Context,
+ TemplateParamLists.size(),
+ TemplateParamLists.data());
// C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);".
if (isFriend) {
@@ -6690,7 +6922,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
SourceLocation InsertLoc;
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
InsertLoc = D.getName().getSourceRange().getEnd();
- InsertLoc = PP.getLocForEndOfToken(InsertLoc);
+ InsertLoc = getLocForEndOfToken(InsertLoc);
}
Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend)
@@ -6742,14 +6974,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
if (getLangOpts().CPlusPlus1y &&
- NewFD->getResultType()->isUndeducedType())
+ NewFD->getReturnType()->isUndeducedType())
Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual);
}
if (getLangOpts().CPlusPlus1y &&
(NewFD->isDependentContext() ||
(isFriend && CurContext->isDependentContext())) &&
- NewFD->getResultType()->isUndeducedType()) {
+ NewFD->getReturnType()->isUndeducedType()) {
// If the function template is referenced directly (for instance, as a
// member of the current instantiation), pretend it has a dependent type.
// This is not really justified by the standard, but is the only sane
@@ -6758,9 +6990,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// a friend yet, so 'isDependentContext' on the FD doesn't work.
const FunctionProtoType *FPT =
NewFD->getType()->castAs<FunctionProtoType>();
- QualType Result = SubstAutoType(FPT->getResultType(),
- Context.DependentTy);
- NewFD->setType(Context.getFunctionType(Result, FPT->getArgTypes(),
+ QualType Result =
+ SubstAutoType(FPT->getReturnType(), Context.DependentTy);
+ NewFD->setType(Context.getFunctionType(Result, FPT->getParamTypes(),
FPT->getExtProtoInfo()));
}
@@ -6833,6 +7065,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
// If a function is defined as defaulted or deleted, mark it as such now.
+ // FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function
+ // definition kind to FDK_Definition.
switch (D.getFunctionDefinitionKind()) {
case FDK_Declaration:
case FDK_Definition:
@@ -6878,13 +7112,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
getLangOpts().CPlusPlus11 && FPT && !FPT->hasExceptionSpec()) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExceptionSpecType = EST_BasicNoexcept;
- NewFD->setType(Context.getFunctionType(FPT->getResultType(),
- FPT->getArgTypes(), EPI));
+ NewFD->setType(Context.getFunctionType(FPT->getReturnType(),
+ FPT->getParamTypes(), EPI));
}
}
// Filter out previous declarations that don't match the scope.
FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD),
+ D.getCXXScopeSpec().isNotEmpty() ||
isExplicitSpecialization ||
isFunctionTemplateSpecialization);
@@ -6893,7 +7128,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
- SE->getString()));
+ SE->getString(), 0));
} else if (!ExtnameUndeclaredIdentifiers.empty()) {
llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier());
@@ -6914,14 +7149,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// single void argument.
// We let through "const void" here because Sema::GetTypeForDeclarator
// already checks for that case.
- if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
- FTI.ArgInfo[0].Param &&
- cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
- // Empty arg list, don't push any params.
- checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param));
- } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
- for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
- ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
+ if (FTIHasNonVoidParameters(FTI) && FTI.Params[0].Param) {
+ for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) {
+ ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param);
assert(Param->getDeclContext() != NewFD && "Was set before ?");
Param->setDeclContext(NewFD);
Params.push_back(Param);
@@ -6942,10 +7172,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// @endcode
// Synthesize a parameter for each argument type.
- for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
- AE = FT->arg_type_end(); AI != AE; ++AI) {
+ for (const auto &AI : FT->param_types()) {
ParmVarDecl *Param =
- BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), *AI);
+ BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), AI);
Param->setScopeInfo(0, Params.size());
Params.push_back(Param);
}
@@ -6969,30 +7198,53 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (D.getDeclSpec().isNoreturnSpecified())
NewFD->addAttr(
::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(),
- Context));
+ Context, 0));
// Functions returning a variably modified type violate C99 6.7.5.2p2
// because all functions have linkage.
if (!NewFD->isInvalidDecl() &&
- NewFD->getResultType()->isVariablyModifiedType()) {
+ NewFD->getReturnType()->isVariablyModifiedType()) {
Diag(NewFD->getLocation(), diag::err_vm_func_decl);
NewFD->setInvalidDecl();
}
+ if (D.isFunctionDefinition() && CodeSegStack.CurrentValue &&
+ !NewFD->hasAttr<SectionAttr>()) {
+ NewFD->addAttr(
+ SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate,
+ CodeSegStack.CurrentValue->getString(),
+ CodeSegStack.CurrentPragmaLocation));
+ if (UnifySection(CodeSegStack.CurrentValue->getString(),
+ PSF_Implicit | PSF_Execute | PSF_Read, NewFD))
+ NewFD->dropAttr<SectionAttr>();
+ }
+
// Handle attributes.
ProcessDeclAttributes(S, NewFD, D);
- QualType RetType = NewFD->getResultType();
+ QualType RetType = NewFD->getReturnType();
const CXXRecordDecl *Ret = RetType->isRecordType() ?
RetType->getAsCXXRecordDecl() : RetType->getPointeeCXXRecordDecl();
if (!NewFD->isInvalidDecl() && !NewFD->hasAttr<WarnUnusedResultAttr>() &&
Ret && Ret->hasAttr<WarnUnusedResultAttr>()) {
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
- // Attach the attribute to the new decl. Don't apply the attribute if it
- // returns an instance of the class (e.g. assignment operators).
- if (!MD || MD->getParent() != Ret) {
- NewFD->addAttr(new (Context) WarnUnusedResultAttr(SourceRange(),
- Context));
+ // Attach WarnUnusedResult to functions returning types with that attribute.
+ // Don't apply the attribute to that type's own non-static member functions
+ // (to avoid warning on things like assignment operators)
+ if (!MD || MD->getParent() != Ret)
+ NewFD->addAttr(WarnUnusedResultAttr::CreateImplicit(Context));
+ }
+
+ if (getLangOpts().OpenCL) {
+ // OpenCL v1.1 s6.5: Using an address space qualifier in a function return
+ // type declaration will generate a compilation error.
+ unsigned AddressSpace = RetType.getAddressSpace();
+ if (AddressSpace == LangAS::opencl_local ||
+ AddressSpace == LangAS::opencl_global ||
+ AddressSpace == LangAS::opencl_constant) {
+ Diag(NewFD->getLocation(),
+ diag::err_opencl_return_value_with_address_space);
+ NewFD->setInvalidDecl();
}
}
@@ -7050,21 +7302,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
<< SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc);
HasExplicitTemplateArgs = false;
- } else if (!isFunctionTemplateSpecialization &&
- !D.getDeclSpec().isFriendSpecified()) {
- // We have encountered something that the user meant to be a
- // specialization (because it has explicitly-specified template
- // arguments) but that was not introduced with a "template<>" (or had
- // too few of them).
- // FIXME: Differentiate between attempts for explicit instantiations
- // (starting with "template") and the rest.
- Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
- << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
- << FixItHint::CreateInsertion(
- D.getDeclSpec().getLocStart(),
- "template<> ");
- isFunctionTemplateSpecialization = true;
} else {
+ assert((isFunctionTemplateSpecialization ||
+ D.getDeclSpec().isFriendSpecified()) &&
+ "should have a 'template<>' for this decl");
// "friend void foo<>(int);" is an implicit specialization decl.
isFunctionTemplateSpecialization = true;
}
@@ -7076,7 +7317,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// friend void foo<>(int);
// Go ahead and fake up a template id.
HasExplicitTemplateArgs = true;
- TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
+ TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
TemplateArgs.setRAngleLoc(D.getIdentifierLoc());
}
@@ -7104,7 +7345,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
diag::err_function_specialization_in_class)
<< NewFD->getDeclName();
} else if (CheckFunctionTemplateSpecialization(NewFD,
- (HasExplicitTemplateArgs ? &TemplateArgs : 0),
+ (HasExplicitTemplateArgs ? &TemplateArgs
+ : nullptr),
Previous))
NewFD->setInvalidDecl();
@@ -7141,12 +7383,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!NewFD->isInvalidDecl() && NewFD->isMSVCRTEntryPoint())
CheckMSVCRTEntryPoint(NewFD);
- if (NewFD->isInvalidDecl()) {
- // If this is a class member, mark the class invalid immediately.
- // This avoids some consistency errors later.
- if (CXXMethodDecl* methodDecl = dyn_cast<CXXMethodDecl>(NewFD))
- methodDecl->getParent()->setInvalidDecl();
- } else
+ if (!NewFD->isInvalidDecl())
D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
isExplicitSpecialization));
}
@@ -7178,7 +7415,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
FunctionTemplateDecl *PrevTemplate =
FunctionTemplate->getPreviousDecl();
CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(),
- PrevTemplate ? PrevTemplate->getTemplateParameters() : 0,
+ PrevTemplate ? PrevTemplate->getTemplateParameters()
+ : nullptr,
D.getDeclSpec().isFriendSpecified()
? (D.isFunctionDefinition()
? TPC_FriendFunctionTemplateDefinition
@@ -7232,7 +7470,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// whether the parameter types are references).
if (NamedDecl *Result = DiagnoseInvalidRedeclaration(
- *this, Previous, NewFD, ExtraArgs, false, 0)) {
+ *this, Previous, NewFD, ExtraArgs, false, nullptr)) {
AddToScope = ExtraArgs.AddToScope;
return Result;
}
@@ -7248,11 +7486,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
- } else if (!D.isFunctionDefinition() && D.getCXXScopeSpec().isSet() &&
+ } else if (!D.isFunctionDefinition() &&
+ isa<CXXMethodDecl>(NewFD) && NewFD->isOutOfLine() &&
!isFriend && !isFunctionTemplateSpecialization &&
!isExplicitSpecialization) {
// An out-of-line member function declaration must also be a
- // definition (C++ [dcl.meaning]p1).
+ // definition (C++ [class.mfct]p2).
// Note that this is not the case for explicit specializations of
// function templates or member functions of class templates, per
// C++ [temp.expl.spec]p2. We also allow these declarations as an
@@ -7281,7 +7520,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
EPI.Variadic = true;
EPI.ExtInfo = FT->getExtInfo();
- QualType R = Context.getFunctionType(FT->getResultType(), None, EPI);
+ QualType R = Context.getFunctionType(FT->getReturnType(), None, EPI);
NewFD->setType(R);
}
@@ -7294,6 +7533,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// marking the function.
AddCFAuditedAttribute(NewFD);
+ // If this is a function definition, check if we have to apply optnone due to
+ // a pragma.
+ if(D.isFunctionDefinition())
+ AddRangeBasedOptnone(NewFD);
+
// If this is the first declaration of an extern C variable, update
// the map of such variables.
if (NewFD->isFirstDecl() && !NewFD->isInvalidDecl() &&
@@ -7303,6 +7547,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Set this FunctionDecl's range up to the right paren.
NewFD->setRangeEnd(D.getSourceRange().getEnd());
+ if (D.isRedeclaration() && !Previous.empty()) {
+ checkDLLAttributeRedeclaration(
+ *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD,
+ isExplicitSpecialization || isFunctionTemplateSpecialization);
+ }
+
if (getLangOpts().CPlusPlus) {
if (FunctionTemplate) {
if (NewFD->isInvalidDecl())
@@ -7320,18 +7570,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
// OpenCL v1.2, s6.9 -- Kernels can only have return type void.
- if (!NewFD->getResultType()->isVoidType()) {
- Diag(D.getIdentifierLoc(),
- diag::err_expected_kernel_void_return_type);
+ if (!NewFD->getReturnType()->isVoidType()) {
+ SourceRange RTRange = NewFD->getReturnTypeSourceRange();
+ Diag(D.getIdentifierLoc(), diag::err_expected_kernel_void_return_type)
+ << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+ : FixItHint());
D.setInvalidType();
}
llvm::SmallPtrSet<const Type *, 16> ValidTypes;
- for (FunctionDecl::param_iterator PI = NewFD->param_begin(),
- PE = NewFD->param_end(); PI != PE; ++PI) {
- ParmVarDecl *Param = *PI;
+ for (auto Param : NewFD->params())
checkIsValidOpenCLKernelParameter(*this, D, Param, ValidTypes);
- }
}
MarkUnusedFileScopedDecl(NewFD);
@@ -7341,7 +7590,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!NewFD->isInvalidDecl() &&
NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
if (II->isStr("cudaConfigureCall")) {
- if (!R->getAs<FunctionType>()->getResultType()->isScalarType())
+ if (!R->getAs<FunctionType>()->getReturnType()->isScalarType())
Diag(NewFD->getLocation(), diag::err_config_scalar_return);
Context.setcudaConfigureCallDecl(NewFD);
@@ -7383,8 +7632,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
LookupResult &Previous,
bool IsExplicitSpecialization) {
- assert(!NewFD->getResultType()->isVariablyModifiedType()
- && "Variably modified return types are not handled here");
+ assert(!NewFD->getReturnType()->isVariablyModifiedType() &&
+ "Variably modified return types are not handled here");
// Determine whether the type of this function should be merged with
// a previous visible declaration. This never happens for functions in C++,
@@ -7396,7 +7645,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
filterNonConflictingPreviousDecls(Context, NewFD, Previous);
bool Redeclaration = false;
- NamedDecl *OldDecl = 0;
+ NamedDecl *OldDecl = nullptr;
// Merge or overload the declaration with an existing declaration of
// the same name, if appropriate.
@@ -7432,7 +7681,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
<< Redeclaration << NewFD;
- NamedDecl *OverloadedDecl = 0;
+ NamedDecl *OverloadedDecl = nullptr;
if (Redeclaration)
OverloadedDecl = OldDecl;
else if (!Previous.empty())
@@ -7440,8 +7689,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
if (OverloadedDecl)
Diag(OverloadedDecl->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
- Context));
+ NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
}
}
}
@@ -7464,12 +7712,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
<< Redeclaration << NewFD;
Diag(Previous.getFoundDecl()->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(),
- Context));
+ NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
}
if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) {
Redeclaration = false;
- OldDecl = 0;
+ OldDecl = nullptr;
}
}
}
@@ -7488,17 +7735,16 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
if (!getLangOpts().CPlusPlus1y && MD && MD->isConstexpr() &&
!MD->isStatic() && !isa<CXXConstructorDecl>(MD) &&
(MD->getTypeQualifiers() & Qualifiers::Const) == 0) {
- CXXMethodDecl *OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl);
- if (FunctionTemplateDecl *OldTD =
- dyn_cast_or_null<FunctionTemplateDecl>(OldDecl))
- OldMD = dyn_cast<CXXMethodDecl>(OldTD->getTemplatedDecl());
+ CXXMethodDecl *OldMD = nullptr;
+ if (OldDecl)
+ OldMD = dyn_cast<CXXMethodDecl>(OldDecl->getAsFunction());
if (!OldMD || !OldMD->isStatic()) {
const FunctionProtoType *FPT =
MD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.TypeQuals |= Qualifiers::Const;
- MD->setType(Context.getFunctionType(FPT->getResultType(),
- FPT->getArgTypes(), EPI));
+ MD->setType(Context.getFunctionType(FPT->getReturnType(),
+ FPT->getParamTypes(), EPI));
// Warn that we did this, if we're not performing template instantiation.
// In that case, we'll have warned already when the template was defined.
@@ -7506,7 +7752,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
SourceLocation AddConstLoc;
if (FunctionTypeLoc FTL = MD->getTypeSourceInfo()->getTypeLoc()
.IgnoreParens().getAs<FunctionTypeLoc>())
- AddConstLoc = PP.getLocForEndOfToken(FTL.getRParenLoc());
+ AddConstLoc = getLocForEndOfToken(FTL.getRParenLoc());
Diag(MD->getLocation(), diag::warn_cxx1y_compat_constexpr_not_const)
<< FixItHint::CreateInsertion(AddConstLoc, " const");
@@ -7656,7 +7902,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// compatible, and if it does, warn the user.
// But, issue any diagnostic on the first declaration only.
if (NewFD->isExternC() && Previous.empty()) {
- QualType R = NewFD->getResultType();
+ QualType R = NewFD->getReturnType();
if (R->isIncompleteType() && !R->isVoidType())
Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete)
<< NewFD << R;
@@ -7668,26 +7914,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
return Redeclaration;
}
-static SourceRange getResultSourceRange(const FunctionDecl *FD) {
- const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
- if (!TSI)
- return SourceRange();
-
- TypeLoc TL = TSI->getTypeLoc();
- FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>();
- if (!FunctionTL)
- return SourceRange();
-
- TypeLoc ResultTL = FunctionTL.getResultLoc();
- if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>())
- return ResultTL.getSourceRange();
-
- return SourceRange();
-}
-
void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
- // C++11 [basic.start.main]p3: A program that declares main to be inline,
- // static or constexpr is ill-formed.
+ // C++11 [basic.start.main]p3:
+ // A program that [...] declares main to be inline, static or
+ // constexpr is ill-formed.
// C11 6.7.4p4: In a hosted environment, no function specifier(s) shall
// appear in a declaration of main.
// static main is not an error under C99, but we should warn about it.
@@ -7701,8 +7931,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
<< FixItHint::CreateRemoval(DS.getInlineSpecLoc());
if (DS.isNoreturnSpecified()) {
SourceLocation NoreturnLoc = DS.getNoreturnSpecLoc();
- SourceRange NoreturnRange(NoreturnLoc,
- PP.getLocForEndOfToken(NoreturnLoc));
+ SourceRange NoreturnRange(NoreturnLoc, getLocForEndOfToken(NoreturnLoc));
Diag(NoreturnLoc, diag::ext_noreturn_main);
Diag(NoreturnLoc, diag::note_main_remove_noreturn)
<< FixItHint::CreateRemoval(NoreturnRange);
@@ -7724,41 +7953,44 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
assert(T->isFunctionType() && "function decl is not of function type");
const FunctionType* FT = T->castAs<FunctionType>();
- // All the standards say that main() should should return 'int'.
- if (Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) {
+ if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
+ // In C with GNU extensions we allow main() to have non-integer return
+ // type, but we should warn about the extension, and we disable the
+ // implicit-return-zero rule.
+
+ // GCC in C mode accepts qualified 'int'.
+ if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy))
+ FD->setHasImplicitReturnZero(true);
+ else {
+ Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
+ SourceRange RTRange = FD->getReturnTypeSourceRange();
+ if (RTRange.isValid())
+ Diag(RTRange.getBegin(), diag::note_main_change_return_type)
+ << FixItHint::CreateReplacement(RTRange, "int");
+ }
+ } else {
// In C and C++, main magically returns 0 if you fall off the end;
// set the flag which tells us that.
// This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.
- FD->setHasImplicitReturnZero(true);
- // In C with GNU extensions we allow main() to have non-integer return
- // type, but we should warn about the extension, and we disable the
- // implicit-return-zero rule.
- } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
- Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
-
- SourceRange ResultRange = getResultSourceRange(FD);
- if (ResultRange.isValid())
- Diag(ResultRange.getBegin(), diag::note_main_change_return_type)
- << FixItHint::CreateReplacement(ResultRange, "int");
-
- // Otherwise, this is just a flat-out error.
- } else {
- SourceRange ResultRange = getResultSourceRange(FD);
- if (ResultRange.isValid())
+ // All the standards say that main() should return 'int'.
+ if (Context.hasSameType(FT->getReturnType(), Context.IntTy))
+ FD->setHasImplicitReturnZero(true);
+ else {
+ // Otherwise, this is just a flat-out error.
+ SourceRange RTRange = FD->getReturnTypeSourceRange();
Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)
- << FixItHint::CreateReplacement(ResultRange, "int");
- else
- Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
-
- FD->setInvalidDecl(true);
+ << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")
+ : FixItHint());
+ FD->setInvalidDecl(true);
+ }
}
// Treat protoless main() as nullary.
if (isa<FunctionNoProtoType>(FT)) return;
const FunctionProtoType* FTP = cast<const FunctionProtoType>(FT);
- unsigned nparams = FTP->getNumArgs();
+ unsigned nparams = FTP->getNumParams();
assert(FD->getNumParams() == nparams);
bool HasExtraParameters = (nparams > 3);
@@ -7783,7 +8015,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
QualType Expected[] = { Context.IntTy, CharPP, CharPP, CharPP };
for (unsigned i = 0; i < nparams; ++i) {
- QualType AT = FTP->getArgType(i);
+ QualType AT = FTP->getParamType(i);
bool mismatch = true;
@@ -7818,7 +8050,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
}
if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) {
- Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName();
+ Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD;
FD->setInvalidDecl();
}
}
@@ -7830,15 +8062,15 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) {
// Set an implicit return of 'zero' if the function can return some integral,
// enumeration, pointer or nullptr type.
- if (FT->getResultType()->isIntegralOrEnumerationType() ||
- FT->getResultType()->isAnyPointerType() ||
- FT->getResultType()->isNullPtrType())
+ if (FT->getReturnType()->isIntegralOrEnumerationType() ||
+ FT->getReturnType()->isAnyPointerType() ||
+ FT->getReturnType()->isNullPtrType())
// DllMain is exempt because a return value of zero means it failed.
if (FD->getName() != "DllMain")
FD->setHasImplicitReturnZero(true);
if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) {
- Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName();
+ Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD;
FD->setInvalidDecl();
}
}
@@ -7852,10 +8084,11 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
// "may accept other forms of constant expressions" exception.
// (We never end up here for C++, so the constant expression
// rules there don't matter.)
- if (Init->isConstantInitializer(Context, false))
+ const Expr *Culprit;
+ if (Init->isConstantInitializer(Context, false, &Culprit))
return false;
- Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
- << Init->getSourceRange();
+ Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant)
+ << Culprit->getSourceRange();
return true;
}
@@ -8029,7 +8262,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
bool DirectInit, bool TypeMayContainAuto) {
// If there is no declaration, there was an error parsing it. Just ignore
// the initializer.
- if (RealDecl == 0 || RealDecl->isInvalidDecl())
+ if (!RealDecl || RealDecl->isInvalidDecl())
return;
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
@@ -8084,6 +8317,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
return;
} else {
DeduceInit = CXXDirectInit->getExpr(0);
+ if (isa<InitListExpr>(DeduceInit))
+ Diag(CXXDirectInit->getLocStart(),
+ diag::err_auto_var_init_paren_braces)
+ << VDecl->getDeclName() << VDecl->getType()
+ << VDecl->getSourceRange();
}
}
@@ -8096,7 +8334,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
VDecl->setInvalidDecl();
return;
}
- Init = Result.take();
+ Init = Result.get();
DefaultedToAuto = true;
}
@@ -8141,6 +8379,13 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
return;
}
+ // dllimport cannot be used on variable definitions.
+ if (VDecl->hasAttr<DLLImportAttr>() && !VDecl->isStaticDataMember()) {
+ Diag(VDecl->getLocation(), diag::err_attribute_dllimport_data_definition);
+ VDecl->setInvalidDecl();
+ return;
+ }
+
if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) {
// C99 6.7.8p5. C++ has no such restriction, but that is a defect.
Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
@@ -8176,8 +8421,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
VDecl->setInvalidDecl();
return;
}
-
- const VarDecl* PrevInit = 0;
+
+ const VarDecl *PrevInit = nullptr;
if (getLangOpts().CPlusPlus) {
// C++ [class.static.data]p4
// If a static data member is of const integral or const
@@ -8192,9 +8437,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// data members we also need to check whether there was an in-class
// declaration with an initializer.
if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
- Diag(VDecl->getLocation(), diag::err_redefinition)
- << VDecl->getDeclName();
- Diag(PrevInit->getLocation(), diag::note_previous_definition);
+ Diag(Init->getExprLoc(), diag::err_static_data_member_reinitialization)
+ << VDecl->getDeclName();
+ Diag(PrevInit->getInit()->getExprLoc(), diag::note_previous_initializer) << 0;
return;
}
@@ -8228,7 +8473,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
VDecl->setInvalidDecl();
return;
}
- Init = Result.take();
+ Init = Result.get();
}
// Perform the initialization.
@@ -8256,7 +8501,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
return;
}
- Init = Result.takeAs<Expr>();
+ Init = Result.getAs<Expr>();
}
// Check for self-references within variable initializers.
@@ -8287,13 +8532,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// we do not warn to warn spuriously when 'x' and 'y' are on separate
// paths through the function. This should be revisited if
// -Wrepeated-use-of-weak is made flow-sensitive.
- if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- Init->getLocStart());
- if (Level != DiagnosticsEngine::Ignored)
+ if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+ Init->getLocStart()))
getCurFunction()->markSafeWeakUse(Init);
- }
}
// The initialization is usually a full-expression.
@@ -8314,7 +8556,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
VDecl->setInvalidDecl();
return;
}
- Init = Result.take();
+ Init = Result.get();
// Attach the initializer to the decl.
VDecl->setInit(Init);
@@ -8324,6 +8566,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// static storage duration shall be constant expressions or string literals.
// C++ does not have this restriction.
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) {
+ const Expr *Culprit;
if (VDecl->getStorageClass() == SC_Static)
CheckForConstantInitializer(Init, DclT);
// C89 is stricter than C99 for non-static aggregate types.
@@ -8332,10 +8575,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// constant expressions.
else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
isa<InitListExpr>(Init) &&
- !Init->isConstantInitializer(Context, false))
- Diag(Init->getExprLoc(),
+ !Init->isConstantInitializer(Context, false, &Culprit))
+ Diag(Culprit->getExprLoc(),
diag::ext_aggregate_init_not_constant)
- << Init->getSourceRange();
+ << Culprit->getSourceRange();
}
} else if (VDecl->isStaticDataMember() &&
VDecl->getLexicalDeclContext()->isRecord()) {
@@ -8444,19 +8687,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// C99 6.7.8p4. All file scoped initializers need to be constant.
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl())
CheckForConstantInitializer(Init, DclT);
- else if (VDecl->getTLSKind() == VarDecl::TLS_Static &&
- !VDecl->isInvalidDecl() && !DclT->isDependentType() &&
- !Init->isValueDependent() && !VDecl->isConstexpr() &&
- !Init->isConstantInitializer(
- Context, VDecl->getType()->isReferenceType())) {
- // GNU C++98 edits for __thread, [basic.start.init]p4:
- // An object of thread storage duration shall not require dynamic
- // initialization.
- // FIXME: Need strict checking here.
- Diag(VDecl->getLocation(), diag::err_thread_dynamic_init);
- if (getLangOpts().CPlusPlus11)
- Diag(VDecl->getLocation(), diag::note_use_thread_local);
- }
}
// We will represent direct-initialization similarly to copy-initialization:
@@ -8512,7 +8742,7 @@ void Sema::ActOnInitializerError(Decl *D) {
return;
}
- // Require an abstract type.
+ // Require a non-abstract type.
if (RequireNonAbstractType(VD->getLocation(), Ty,
diag::err_abstract_type_in_decl,
AbstractVariableType)) {
@@ -8527,7 +8757,7 @@ void Sema::ActOnInitializerError(Decl *D) {
void Sema::ActOnUninitializedDecl(Decl *RealDecl,
bool TypeMayContainAuto) {
// If there is no declaration, there was an error parsing it. Just ignore it.
- if (RealDecl == 0)
+ if (!RealDecl)
return;
if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) {
@@ -8558,6 +8788,16 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
return;
}
+ // OpenCL v1.1 s6.5.3: variables declared in the constant address space must
+ // be initialized.
+ if (!Var->isInvalidDecl() &&
+ Var->getType().getAddressSpace() == LangAS::opencl_constant &&
+ Var->getStorageClass() != SC_Extern && !Var->getInit()) {
+ Diag(Var->getLocation(), diag::err_opencl_constant_no_init);
+ Var->setInvalidDecl();
+ return;
+ }
+
switch (Var->isThisDeclarationADefinition()) {
case VarDecl::Definition:
if (!Var->isStaticDataMember() || !Var->getAnyInitializer())
@@ -8657,11 +8897,13 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
if (Var->isInvalidDecl())
return;
- if (RequireCompleteType(Var->getLocation(),
- Context.getBaseElementType(Type),
- diag::err_typecheck_decl_incomplete_type)) {
- Var->setInvalidDecl();
- return;
+ if (!Var->hasAttr<AliasAttr>()) {
+ if (RequireCompleteType(Var->getLocation(),
+ Context.getBaseElementType(Type),
+ diag::err_typecheck_decl_incomplete_type)) {
+ Var->setInvalidDecl();
+ return;
+ }
}
// The variable can not have an abstract class type.
@@ -8768,6 +9010,37 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) {
}
}
+StmtResult
+Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+ IdentifierInfo *Ident,
+ ParsedAttributes &Attrs,
+ SourceLocation AttrEnd) {
+ // C++1y [stmt.iter]p1:
+ // A range-based for statement of the form
+ // for ( for-range-identifier : for-range-initializer ) statement
+ // is equivalent to
+ // for ( auto&& for-range-identifier : for-range-initializer ) statement
+ DeclSpec DS(Attrs.getPool().getFactory());
+
+ const char *PrevSpec;
+ unsigned DiagID;
+ DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,
+ getPrintingPolicy());
+
+ Declarator D(DS, Declarator::ForContext);
+ D.SetIdentifier(Ident, IdentLoc);
+ D.takeAttributes(Attrs, AttrEnd);
+
+ ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
+ D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false),
+ EmptyAttrs, IdentLoc);
+ Decl *Var = ActOnDeclarator(S, D);
+ cast<VarDecl>(Var)->setCXXForRangeDecl(true);
+ FinalizeDeclaration(Var);
+ return ActOnDeclStmt(FinalizeDeclaratorGroup(S, DS, Var), IdentLoc,
+ AttrEnd.isValid() ? AttrEnd : IdentLoc);
+}
+
void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
if (var->isInvalidDecl()) return;
@@ -8788,11 +9061,16 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
}
}
+ // Warn about externally-visible variables being defined without a
+ // prior declaration. We only want to do this for global
+ // declarations, but we also specifically need to avoid doing it for
+ // class members because the linkage of an anonymous class can
+ // change if it's later given a typedef name.
if (var->isThisDeclarationADefinition() &&
+ var->getDeclContext()->getRedeclContext()->isFileContext() &&
var->isExternallyVisible() && var->hasLinkage() &&
- getDiagnostics().getDiagnosticLevel(
- diag::warn_missing_variable_declarations,
- var->getLocation())) {
+ !getDiagnostics().isIgnored(diag::warn_missing_variable_declarations,
+ var->getLocation())) {
// Find a previous declaration that's not a definition.
VarDecl *prev = var->getPreviousDecl();
while (prev && prev->isThisDeclarationADefinition())
@@ -8802,14 +9080,58 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var;
}
- if (var->getTLSKind() == VarDecl::TLS_Static &&
- var->getType().isDestructedType()) {
- // GNU C++98 edits for __thread, [basic.start.term]p3:
- // The type of an object with thread storage duration shall not
- // have a non-trivial destructor.
- Diag(var->getLocation(), diag::err_thread_nontrivial_dtor);
- if (getLangOpts().CPlusPlus11)
- Diag(var->getLocation(), diag::note_use_thread_local);
+ if (var->getTLSKind() == VarDecl::TLS_Static) {
+ const Expr *Culprit;
+ if (var->getType().isDestructedType()) {
+ // GNU C++98 edits for __thread, [basic.start.term]p3:
+ // The type of an object with thread storage duration shall not
+ // have a non-trivial destructor.
+ Diag(var->getLocation(), diag::err_thread_nontrivial_dtor);
+ if (getLangOpts().CPlusPlus11)
+ Diag(var->getLocation(), diag::note_use_thread_local);
+ } else if (getLangOpts().CPlusPlus && var->hasInit() &&
+ !var->getInit()->isConstantInitializer(
+ Context, var->getType()->isReferenceType(), &Culprit)) {
+ // GNU C++98 edits for __thread, [basic.start.init]p4:
+ // An object of thread storage duration shall not require dynamic
+ // initialization.
+ // FIXME: Need strict checking here.
+ Diag(Culprit->getExprLoc(), diag::err_thread_dynamic_init)
+ << Culprit->getSourceRange();
+ if (getLangOpts().CPlusPlus11)
+ Diag(var->getLocation(), diag::note_use_thread_local);
+ }
+
+ }
+
+ if (var->isThisDeclarationADefinition() &&
+ ActiveTemplateInstantiations.empty()) {
+ PragmaStack<StringLiteral *> *Stack = nullptr;
+ int SectionFlags = PSF_Implicit | PSF_Read;
+ if (var->getType().isConstQualified())
+ Stack = &ConstSegStack;
+ else if (!var->getInit()) {
+ Stack = &BSSSegStack;
+ SectionFlags |= PSF_Write;
+ } else {
+ Stack = &DataSegStack;
+ SectionFlags |= PSF_Write;
+ }
+ if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue)
+ var->addAttr(
+ SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate,
+ Stack->CurrentValue->getString(),
+ Stack->CurrentPragmaLocation));
+ if (const SectionAttr *SA = var->getAttr<SectionAttr>())
+ if (UnifySection(SA->getName(), SectionFlags, var))
+ var->dropAttr<SectionAttr>();
+
+ // Apply the init_seg attribute if this has an initializer. If the
+ // initializer turns out to not be dynamic, we'll end up ignoring this
+ // attribute.
+ if (CurInitSeg && var->getInit())
+ var->addAttr(InitSegAttr::CreateImplicit(Context, CurInitSeg->getString(),
+ CurInitSegLoc));
}
// All the following checks are C++ only.
@@ -8835,7 +9157,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
var, var->getType(), varRef, /*AllowNRVO=*/true);
if (!result.isInvalid()) {
result = MaybeCreateExprWithCleanups(result);
- Expr *init = result.takeAs<Expr>();
+ Expr *init = result.getAs<Expr>();
Context.setBlockVarCopyInits(var, init);
}
}
@@ -8848,9 +9170,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
if (!var->getDeclContext()->isDependentContext() &&
Init && !Init->isValueDependent()) {
if (IsGlobal && !var->isConstexpr() &&
- getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor,
- var->getLocation())
- != DiagnosticsEngine::Ignored) {
+ !getDiagnostics().isIgnored(diag::warn_global_constructor,
+ var->getLocation())) {
// Warn about globals which don't have a constant initializer. Don't
// warn about globals with a non-trivial destructor because we already
// warned about them.
@@ -8901,9 +9222,45 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
if (!VD)
return;
+ checkAttributesAfterMerging(*this, *VD);
+
+ // Static locals inherit dll attributes from their function.
+ if (VD->isStaticLocal()) {
+ if (FunctionDecl *FD =
+ dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) {
+ if (Attr *A = getDLLAttr(FD)) {
+ auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext()));
+ NewAttr->setInherited(true);
+ VD->addAttr(NewAttr);
+ }
+ }
+ }
+
+ // Imported static data members cannot be defined out-of-line.
+ if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
+ if (VD->isStaticDataMember() && VD->isOutOfLine() &&
+ VD->isThisDeclarationADefinition()) {
+ // We allow definitions of dllimport class template static data members
+ // with a warning.
+ CXXRecordDecl *Context =
+ cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext());
+ bool IsClassTemplateMember =
+ isa<ClassTemplatePartialSpecializationDecl>(Context) ||
+ Context->getDescribedClassTemplate();
+
+ Diag(VD->getLocation(),
+ IsClassTemplateMember
+ ? diag::warn_attribute_dllimport_static_field_definition
+ : diag::err_attribute_dllimport_static_field_definition);
+ Diag(IA->getLocation(), diag::note_attribute);
+ if (!IsClassTemplateMember)
+ VD->setInvalidDecl();
+ }
+ }
+
if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
- Diag(Attr->getLocation(), diag::warn_attribute_ignored) << "used";
+ Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
VD->dropAttr<UsedAttr>();
}
}
@@ -8923,10 +9280,12 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
const DeclContext *DC = VD->getDeclContext();
// If there's a #pragma GCC visibility in scope, and this isn't a class
// member, set the visibility of this variable.
- if (!DC->isRecord() && VD->isExternallyVisible())
+ if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible())
AddPushedVisibilityAttribute(VD);
- if (VD->isFileVarDecl())
+ // FIXME: Warn on unused templates.
+ if (VD->isFileVarDecl() && !VD->getDescribedVarTemplate() &&
+ !isa<VarTemplatePartialSpecializationDecl>(VD))
MarkUnusedFileScopedDecl(VD);
// Now we have parsed the initializer and can update the table of magic
@@ -8935,10 +9294,7 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
!VD->getType()->isIntegralOrEnumerationType())
return;
- for (specific_attr_iterator<TypeTagForDatatypeAttr>
- I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(),
- E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>();
- I != E; ++I) {
+ for (const auto *I : ThisDecl->specific_attrs<TypeTagForDatatypeAttr>()) {
const Expr *MagicValueExpr = VD->getInit();
if (!MagicValueExpr) {
continue;
@@ -8972,7 +9328,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
if (DS.isTypeSpecOwned())
Decls.push_back(DS.getRepAsDecl());
- DeclaratorDecl *FirstDeclaratorInGroup = 0;
+ DeclaratorDecl *FirstDeclaratorInGroup = nullptr;
for (unsigned i = 0, e = Group.size(); i != e; ++i)
if (Decl *D = Group[i]) {
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
@@ -8983,7 +9339,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
if (DeclSpec::isDeclRep(DS.getTypeSpecType())) {
if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) {
- HandleTagNumbering(*this, Tag);
+ HandleTagNumbering(*this, Tag, S);
if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl())
Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup);
}
@@ -8995,7 +9351,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
/// BuildDeclaratorGroup - convert a list of declarations into a declaration
/// group, performing any necessary semantic checking.
Sema::DeclGroupPtrTy
-Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
+Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
bool TypeMayContainAuto) {
// C++0x [dcl.spec.auto]p7:
// If the type deduced for the template parameter U is not the same in each
@@ -9007,7 +9363,7 @@ Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
if (TypeMayContainAuto && Group.size() > 1) {
QualType Deduced;
CanQualType DeducedCanon;
- VarDecl *DeducedDecl = 0;
+ VarDecl *DeducedDecl = nullptr;
for (unsigned i = 0, e = Group.size(); i != e; ++i) {
if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) {
AutoType *AT = D->getType()->getContainedAutoType();
@@ -9052,9 +9408,7 @@ void Sema::ActOnDocumentableDecls(ArrayRef<Decl *> Group) {
if (Group.empty() || !Group[0])
return;
- if (Diags.getDiagnosticLevel(diag::warn_doc_param_not_found,
- Group[0]->getLocation())
- == DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_doc_param_not_found, Group[0]->getLocation()))
return;
if (Group.size() >= 2) {
@@ -9133,12 +9487,12 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
}
// Ensure we have a valid name
- IdentifierInfo *II = 0;
+ IdentifierInfo *II = nullptr;
if (D.hasName()) {
II = D.getIdentifier();
if (!II) {
Diag(D.getIdentifierLoc(), diag::err_bad_parameter_name)
- << GetNameForDeclarator(D).getName().getAsString();
+ << GetNameForDeclarator(D).getName();
D.setInvalidType(true);
}
}
@@ -9154,14 +9508,14 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
// Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
+ PrevDecl = nullptr;
} else if (S->isDeclScope(PrevDecl)) {
Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II;
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
// Recover by removing the name
- II = 0;
- D.SetIdentifier(0, D.getIdentifierLoc());
+ II = nullptr;
+ D.SetIdentifier(nullptr, D.getIdentifierLoc());
D.setInvalidType(true);
}
}
@@ -9211,9 +9565,9 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC,
/* FIXME: setting StartLoc == Loc.
Would it be worth to modify callers so as to provide proper source
location for the unnamed parameters, embedding the parameter's type? */
- ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, 0,
+ ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, nullptr,
T, Context.getTrivialTypeSourceInfo(T, Loc),
- SC_None, 0);
+ SC_None, nullptr);
Param->setImplicit();
return Param;
}
@@ -9293,7 +9647,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,
Context.getAdjustedParameterType(T),
TSInfo,
- StorageClass, 0);
+ StorageClass, nullptr);
// Parameters can not be abstract class types.
// For record types, this is done by the AbstractClassUsageDiagnoser once
@@ -9319,8 +9673,12 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
// Since all parameters have automatic store duration, they can not have
// an address space.
if (T.getAddressSpace() != 0) {
- Diag(NameLoc, diag::err_arg_with_address_space);
- New->setInvalidDecl();
+ // OpenCL allows function arguments declared to be an array of a type
+ // to be qualified with an address space.
+ if (!(getLangOpts().OpenCL && T->isArrayType())) {
+ Diag(NameLoc, diag::err_arg_with_address_space);
+ New->setInvalidDecl();
+ }
}
return New;
@@ -9333,16 +9691,15 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
// Verify 6.9.1p6: 'every identifier in the identifier list shall be declared'
// for a K&R function.
if (!FTI.hasPrototype) {
- for (int i = FTI.NumArgs; i != 0; /* decrement in loop */) {
+ for (int i = FTI.NumParams; i != 0; /* decrement in loop */) {
--i;
- if (FTI.ArgInfo[i].Param == 0) {
+ if (FTI.Params[i].Param == nullptr) {
SmallString<256> Code;
- llvm::raw_svector_ostream(Code) << " int "
- << FTI.ArgInfo[i].Ident->getName()
- << ";\n";
- Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared)
- << FTI.ArgInfo[i].Ident
- << FixItHint::CreateInsertion(LocAfterDecls, Code.str());
+ llvm::raw_svector_ostream(Code)
+ << " int " << FTI.Params[i].Ident->getName() << ";\n";
+ Diag(FTI.Params[i].IdentLoc, diag::ext_param_not_declared)
+ << FTI.Params[i].Ident
+ << FixItHint::CreateInsertion(LocAfterDecls, Code.str());
// Implicitly declare the argument as type 'int' for lack of a better
// type.
@@ -9350,21 +9707,21 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
DeclSpec DS(attrs);
const char* PrevSpec; // unused
unsigned DiagID; // unused
- DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
- PrevSpec, DiagID);
+ DS.SetTypeSpecType(DeclSpec::TST_int, FTI.Params[i].IdentLoc, PrevSpec,
+ DiagID, Context.getPrintingPolicy());
// Use the identifier location for the type source range.
- DS.SetRangeStart(FTI.ArgInfo[i].IdentLoc);
- DS.SetRangeEnd(FTI.ArgInfo[i].IdentLoc);
+ DS.SetRangeStart(FTI.Params[i].IdentLoc);
+ DS.SetRangeEnd(FTI.Params[i].IdentLoc);
Declarator ParamD(DS, Declarator::KNRTypeListContext);
- ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc);
- FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD);
+ ParamD.SetIdentifier(FTI.Params[i].Ident, FTI.Params[i].IdentLoc);
+ FTI.Params[i].Param = ActOnParamDeclarator(S, ParamD);
}
}
}
}
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
- assert(getCurFunctionDecl() == 0 && "Function parsing confused");
+ assert(getCurFunctionDecl() == nullptr && "Function parsing confused");
assert(D.isFunctionDeclarator() && "Not a function declarator!");
Scope *ParentScope = FnBodyScope->getParent();
@@ -9373,6 +9730,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
return ActOnStartOfFunctionDef(FnBodyScope, DP);
}
+void Sema::ActOnFinishInlineMethodDef(CXXMethodDecl *D) {
+ Consumer.HandleInlineMethodDefinition(D);
+}
+
static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD,
const FunctionDecl*& PossibleZeroParamPrototype) {
// Don't warn about invalid declarations.
@@ -9456,7 +9817,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,
LambdaScopeInfo *LSI = S.PushLambdaScope();
LSI->CallOperator = CallOperator;
LSI->Lambda = LambdaClass;
- LSI->ReturnType = CallOperator->getResultType();
+ LSI->ReturnType = CallOperator->getReturnType();
const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault();
if (LCD == LCD_None)
@@ -9472,23 +9833,22 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,
// Add the captures to the LSI so they can be noted as already
// captured within tryCaptureVar.
- for (LambdaExpr::capture_iterator C = LambdaClass->captures_begin(),
- CEnd = LambdaClass->captures_end(); C != CEnd; ++C) {
- if (C->capturesVariable()) {
- VarDecl *VD = C->getCapturedVar();
+ for (const auto &C : LambdaClass->captures()) {
+ if (C.capturesVariable()) {
+ VarDecl *VD = C.getCapturedVar();
if (VD->isInitCapture())
S.CurrentInstantiationScope->InstantiatedLocal(VD, VD);
QualType CaptureType = VD->getType();
- const bool ByRef = C->getCaptureKind() == LCK_ByRef;
+ const bool ByRef = C.getCaptureKind() == LCK_ByRef;
LSI->addCapture(VD, /*IsBlock*/false, ByRef,
- /*RefersToEnclosingLocal*/true, C->getLocation(),
- /*EllipsisLoc*/C->isPackExpansion()
- ? C->getEllipsisLoc() : SourceLocation(),
- CaptureType, /*Expr*/ 0);
-
- } else if (C->capturesThis()) {
- LSI->addThisCapture(/*Nested*/ false, C->getLocation(),
- S.getCurrentThisType(), /*Expr*/ 0);
+ /*RefersToEnclosingLocal*/true, C.getLocation(),
+ /*EllipsisLoc*/C.isPackExpansion()
+ ? C.getEllipsisLoc() : SourceLocation(),
+ CaptureType, /*Expr*/ nullptr);
+
+ } else if (C.capturesThis()) {
+ LSI->addThisCapture(/*Nested*/ false, C.getLocation(),
+ S.getCurrentThisType(), /*Expr*/ nullptr);
}
}
}
@@ -9499,7 +9859,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
if (!D)
return D;
- FunctionDecl *FD = 0;
+ FunctionDecl *FD = nullptr;
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
FD = FunTmpl->getTemplatedDecl();
@@ -9539,7 +9899,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
// The return type of a function definition must be complete
// (C99 6.9.1p3, C++ [dcl.fct]p6).
- QualType ResultType = FD->getResultType();
+ QualType ResultType = FD->getReturnType();
if (!ResultType->isDependentType() && !ResultType->isVoidType() &&
!FD->isInvalidDecl() &&
RequireCompleteType(FD->getLocation(), ResultType,
@@ -9551,7 +9911,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
// prototype declaration. This warning is issued even if the
// definition itself provides a prototype. The aim is to detect
// global functions that fail to be declared in header files.
- const FunctionDecl *PossibleZeroParamPrototype = 0;
+ const FunctionDecl *PossibleZeroParamPrototype = nullptr;
if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) {
Diag(FD->getLocation(), diag::warn_missing_prototype) << FD;
@@ -9578,8 +9938,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
/*CheckParameterNames=*/true);
// Introduce our parameters into the function scope
- for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) {
- ParmVarDecl *Param = FD->getParamDecl(p);
+ for (auto Param : FD->params()) {
Param->setOwningFunction(FD);
// If this has an identifier, add it to the scope stack.
@@ -9604,9 +9963,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
// and reattach to the current context.
if (D->getLexicalDeclContext() == Context.getTranslationUnitDecl()) {
// Is the decl actually in the context?
- for (DeclContext::decl_iterator DI = Context.getTranslationUnitDecl()->decls_begin(),
- DE = Context.getTranslationUnitDecl()->decls_end(); DI != DE; ++DI) {
- if (*DI == D) {
+ for (const auto *DI : Context.getTranslationUnitDecl()->decls()) {
+ if (DI == D) {
Context.getTranslationUnitDecl()->removeDecl(D);
break;
}
@@ -9621,10 +9979,9 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
// Similarly, dive into enums and fish their constants out, making them
// accessible in this scope.
- if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
- for (EnumDecl::enumerator_iterator EI = ED->enumerator_begin(),
- EE = ED->enumerator_end(); EI != EE; ++EI)
- PushOnScopeChains(*EI, FnBodyScope, /*AddToContext=*/false);
+ if (auto *ED = dyn_cast<EnumDecl>(D)) {
+ for (auto *EI : ED->enumerators())
+ PushOnScopeChains(EI, FnBodyScope, /*AddToContext=*/false);
}
}
}
@@ -9633,35 +9990,22 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
if (const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>())
ResolveExceptionSpec(D->getLocation(), FPT);
- // Checking attributes of current function definition
- // dllimport attribute.
- DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
- if (DA && (!FD->getAttr<DLLExportAttr>())) {
- // dllimport attribute cannot be directly applied to definition.
- // Microsoft accepts dllimport for functions defined within class scope.
- if (!DA->isInherited() &&
- !(LangOpts.MicrosoftExt && FD->getLexicalDeclContext()->isRecord())) {
- Diag(FD->getLocation(),
- diag::err_attribute_can_be_applied_only_to_symbol_declaration)
- << "dllimport";
- FD->setInvalidDecl();
- return D;
- }
-
- // Visual C++ appears to not think this is an issue, so only issue
- // a warning when Microsoft extensions are disabled.
- if (!LangOpts.MicrosoftExt) {
- // If a symbol previously declared dllimport is later defined, the
- // attribute is ignored in subsequent references, and a warning is
- // emitted.
- Diag(FD->getLocation(),
- diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
- << FD->getName() << "dllimport";
- }
+ // dllimport cannot be applied to non-inline function definitions.
+ if (FD->hasAttr<DLLImportAttr>() && !FD->isInlined() &&
+ !FD->isTemplateInstantiation()) {
+ assert(!FD->hasAttr<DLLExportAttr>());
+ Diag(FD->getLocation(), diag::err_attribute_dllimport_function_definition);
+ FD->setInvalidDecl();
+ return D;
}
// We want to attach documentation to original Decl (which might be
// a function template).
ActOnDocumentableDecl(D);
+ if (getCurLexicalContext()->isObjCContainer() &&
+ getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+ getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation)
+ Diag(FD->getLocation(), diag::warn_function_def_in_objc_container);
+
return D;
}
@@ -9675,49 +10019,53 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
/// use the named return value optimization.
///
/// This function applies a very simplistic algorithm for NRVO: if every return
-/// statement in the function has the same NRVO candidate, that candidate is
-/// the NRVO variable.
-///
-/// FIXME: Employ a smarter algorithm that accounts for multiple return
-/// statements and the lifetimes of the NRVO candidates. We should be able to
-/// find a maximal set of NRVO variables.
+/// statement in the scope of a variable has the same NRVO candidate, that
+/// candidate is an NRVO variable.
void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
ReturnStmt **Returns = Scope->Returns.data();
- const VarDecl *NRVOCandidate = 0;
for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) {
- if (!Returns[I]->getNRVOCandidate())
- return;
-
- if (!NRVOCandidate)
- NRVOCandidate = Returns[I]->getNRVOCandidate();
- else if (NRVOCandidate != Returns[I]->getNRVOCandidate())
- return;
+ if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) {
+ if (!NRVOCandidate->isNRVOVariable())
+ Returns[I]->setNRVOCandidate(nullptr);
+ }
}
-
- if (NRVOCandidate)
- const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true);
}
-bool Sema::canSkipFunctionBody(Decl *D) {
- if (!Consumer.shouldSkipFunctionBody(D))
+bool Sema::canDelayFunctionBody(const Declarator &D) {
+ // We can't delay parsing the body of a constexpr function template (yet).
+ if (D.getDeclSpec().isConstexprSpecified())
return false;
- if (isa<ObjCMethodDecl>(D))
- return true;
+ // We can't delay parsing the body of a function template with a deduced
+ // return type (yet).
+ if (D.getDeclSpec().containsPlaceholderType()) {
+ // If the placeholder introduces a non-deduced trailing return type,
+ // we can still delay parsing it.
+ if (D.getNumTypeObjects()) {
+ const auto &Outer = D.getTypeObject(D.getNumTypeObjects() - 1);
+ if (Outer.Kind == DeclaratorChunk::Function &&
+ Outer.Fun.hasTrailingReturnType()) {
+ QualType Ty = GetTypeFromParser(Outer.Fun.getTrailingReturnType());
+ return Ty.isNull() || !Ty->isUndeducedType();
+ }
+ }
+ return false;
+ }
- FunctionDecl *FD = 0;
- if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
- FD = FTD->getTemplatedDecl();
- else
- FD = cast<FunctionDecl>(D);
+ return true;
+}
+bool Sema::canSkipFunctionBody(Decl *D) {
// We cannot skip the body of a function (or function template) which is
// constexpr, since we may need to evaluate its body in order to parse the
// rest of the file.
// We cannot skip the body of a function with an undeduced return type,
// because any callers of that function need to know the type.
- return !FD->isConstexpr() && !FD->getResultType()->isUndeducedType();
+ if (const FunctionDecl *FD = D->getAsFunction())
+ if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType())
+ return false;
+ return Consumer.shouldSkipFunctionBody(D);
}
Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
@@ -9725,7 +10073,7 @@ Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
FD->setHasSkippedBody();
else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Decl))
MD->setHasSkippedBody();
- return ActOnFinishFunctionBody(Decl, 0);
+ return ActOnFinishFunctionBody(Decl, nullptr);
}
Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
@@ -9734,32 +10082,27 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
bool IsInstantiation) {
- FunctionDecl *FD = 0;
- FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
- if (FunTmpl)
- FD = FunTmpl->getTemplatedDecl();
- else
- FD = dyn_cast_or_null<FunctionDecl>(dcl);
+ FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr;
sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
- sema::AnalysisBasedWarnings::Policy *ActivePolicy = 0;
+ sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr;
if (FD) {
FD->setBody(Body);
if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && Body &&
- !FD->isDependentContext() && FD->getResultType()->isUndeducedType()) {
+ !FD->isDependentContext() && FD->getReturnType()->isUndeducedType()) {
// If the function has a deduced result type but contains no 'return'
// statements, the result type as written must be exactly 'auto', and
// the deduced result type is 'void'.
- if (!FD->getResultType()->getAs<AutoType>()) {
+ if (!FD->getReturnType()->getAs<AutoType>()) {
Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto)
- << FD->getResultType();
+ << FD->getReturnType();
FD->setInvalidDecl();
} else {
// Substitute 'void' for the 'auto' in the type.
TypeLoc ResultType = FD->getTypeSourceInfo()->getTypeLoc().
- IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
+ IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc();
Context.adjustDeducedFunctionResultType(
FD, SubstAutoType(ResultType.getType(), Context.VoidTy));
}
@@ -9783,15 +10126,17 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
WP.disableCheckFallThrough();
// MSVC permits the use of pure specifier (=0) on function definition,
- // defined at class scope, warn about this non standard construct.
+ // defined at class scope, warn about this non-standard construct.
if (getLangOpts().MicrosoftExt && FD->isPure() && FD->isCanonicalDecl())
- Diag(FD->getLocation(), diag::warn_pure_function_definition);
+ Diag(FD->getLocation(), diag::ext_pure_function_definition);
if (!FD->isInvalidDecl()) {
- DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
+ // Don't diagnose unused parameters of defaulted or deleted functions.
+ if (Body)
+ DiagnoseUnusedParameters(FD->param_begin(), FD->param_end());
DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(),
- FD->getResultType(), FD);
-
+ FD->getReturnType(), FD);
+
// If this is a constructor, we need a vtable.
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
MarkVTableUsed(FD->getLocation(), Constructor->getParent());
@@ -9799,7 +10144,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// Try to apply the named return value optimization. We have to check
// if we can do this here because lambdas keep return statements around
// to deduce an implicit return type.
- if (getLangOpts().CPlusPlus && FD->getResultType()->isRecordType() &&
+ if (getLangOpts().CPlusPlus && FD->getReturnType()->isRecordType() &&
!FD->isDependentContext())
computeNRVO(Body, getCurFunction());
}
@@ -9812,8 +10157,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
if (!MD->isInvalidDecl()) {
DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
DiagnoseSizeOfParametersAndReturnValue(MD->param_begin(), MD->param_end(),
- MD->getResultType(), MD);
-
+ MD->getReturnType(), MD);
+
if (Body)
computeNRVO(Body, getCurFunction());
}
@@ -9822,8 +10167,41 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
<< MD->getSelector().getAsString();
getCurFunction()->ObjCShouldCallSuper = false;
}
+ if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) {
+ const ObjCMethodDecl *InitMethod = nullptr;
+ bool isDesignated =
+ MD->isDesignatedInitializerForTheInterface(&InitMethod);
+ assert(isDesignated && InitMethod);
+ (void)isDesignated;
+
+ auto superIsNSObject = [&](const ObjCMethodDecl *MD) {
+ auto IFace = MD->getClassInterface();
+ if (!IFace)
+ return false;
+ auto SuperD = IFace->getSuperClass();
+ if (!SuperD)
+ return false;
+ return SuperD->getIdentifier() ==
+ NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
+ };
+ // Don't issue this warning for unavailable inits or direct subclasses
+ // of NSObject.
+ if (!MD->isUnavailable() && !superIsNSObject(MD)) {
+ Diag(MD->getLocation(),
+ diag::warn_objc_designated_init_missing_super_call);
+ Diag(InitMethod->getLocation(),
+ diag::note_objc_designated_init_marked_here);
+ }
+ getCurFunction()->ObjCWarnForNoDesignatedInitChain = false;
+ }
+ if (getCurFunction()->ObjCWarnForNoInitDelegation) {
+ // Don't issue this warning for unavaialable inits.
+ if (!MD->isUnavailable())
+ Diag(MD->getLocation(), diag::warn_objc_secondary_init_missing_init_call);
+ getCurFunction()->ObjCWarnForNoInitDelegation = false;
+ }
} else {
- return 0;
+ return nullptr;
}
assert(!getCurFunction()->ObjCShouldCallSuper &&
@@ -9840,8 +10218,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// Verify that gotos and switch cases don't jump into scopes illegally.
if (getCurFunction()->NeedsScopeChecking() &&
- !dcl->isInvalidDecl() &&
- !hasAnyUnrecoverableErrorsInThisFunction() &&
!PP.isCodeCompletionEnabled())
DiagnoseInvalidJumps(Body);
@@ -9856,11 +10232,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
// If any errors have occurred, clear out any temporaries that may have
// been leftover. This ensures that these temporaries won't be picked up for
// deletion in some later function.
- if (PP.getDiagnostics().hasErrorOccurred() ||
- PP.getDiagnostics().getSuppressAllDiagnostics()) {
+ if (getDiagnostics().hasErrorOccurred() ||
+ getDiagnostics().getSuppressAllDiagnostics()) {
DiscardCleanupsInEvaluationContext();
}
- if (!PP.getDiagnostics().hasUncompilableErrorOccurred() &&
+ if (!getDiagnostics().hasUncompilableErrorOccurred() &&
!isa<FunctionTemplateDecl>(dcl)) {
// Since the body is valid, issue any analysis-based warnings that are
// enabled.
@@ -9938,7 +10314,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
TypoCorrection Corrected;
DeclFilterCCC<FunctionDecl> Validator;
if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc),
- LookupOrdinaryName, S, 0, Validator)))
+ LookupOrdinaryName, S, nullptr, Validator,
+ CTK_NonError)))
diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion),
/*ErrorRecovery*/false);
}
@@ -9948,16 +10325,17 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
AttributeFactory attrFactory;
DeclSpec DS(attrFactory);
unsigned DiagID;
- bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID);
+ bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID,
+ Context.getPrintingPolicy());
(void)Error; // Silence warning.
assert(!Error && "Error setting up implicit decl!");
SourceLocation NoLoc;
Declarator D(DS, Declarator::BlockContext);
D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false,
/*IsAmbiguous=*/false,
- /*RParenLoc=*/NoLoc,
- /*ArgInfo=*/0,
- /*NumArgs=*/0,
+ /*LParenLoc=*/NoLoc,
+ /*Params=*/nullptr,
+ /*NumParams=*/0,
/*EllipsisLoc=*/NoLoc,
/*RParenLoc=*/NoLoc,
/*TypeQuals=*/0,
@@ -9968,10 +10346,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
/*MutableLoc=*/NoLoc,
EST_None,
/*ESpecLoc=*/NoLoc,
- /*Exceptions=*/0,
- /*ExceptionRanges=*/0,
+ /*Exceptions=*/nullptr,
+ /*ExceptionRanges=*/nullptr,
/*NumExceptions=*/0,
- /*NoexceptExpr=*/0,
+ /*NoexceptExpr=*/nullptr,
Loc, Loc, D),
DS.getAttributes(),
SourceLocation());
@@ -10012,25 +10390,27 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
unsigned FormatIdx;
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
- if (!FD->getAttr<FormatAttr>()) {
+ if (!FD->hasAttr<FormatAttr>()) {
const char *fmt = "printf";
unsigned int NumParams = FD->getNumParams();
if (FormatIdx < NumParams && // NumParams may be 0 (e.g. vfprintf)
FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType())
fmt = "NSString";
- FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ FD->addAttr(FormatAttr::CreateImplicit(Context,
&Context.Idents.get(fmt),
FormatIdx+1,
- HasVAListArg ? 0 : FormatIdx+2));
+ HasVAListArg ? 0 : FormatIdx+2,
+ FD->getLocation()));
}
}
if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
HasVAListArg)) {
- if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ if (!FD->hasAttr<FormatAttr>())
+ FD->addAttr(FormatAttr::CreateImplicit(Context,
&Context.Idents.get("scanf"),
FormatIdx+1,
- HasVAListArg ? 0 : FormatIdx+2));
+ HasVAListArg ? 0 : FormatIdx+2,
+ FD->getLocation()));
}
// Mark const if we don't care about errno and that is the only
@@ -10038,17 +10418,18 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
// IRgen to use LLVM intrinsics for such functions.
if (!getLangOpts().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
- if (!FD->getAttr<ConstAttr>())
- FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
+ if (!FD->hasAttr<ConstAttr>())
+ FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
}
if (Context.BuiltinInfo.isReturnsTwice(BuiltinID) &&
- !FD->getAttr<ReturnsTwiceAttr>())
- FD->addAttr(::new (Context) ReturnsTwiceAttr(FD->getLocation(), Context));
- if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->getAttr<NoThrowAttr>())
- FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
- if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->getAttr<ConstAttr>())
- FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
+ !FD->hasAttr<ReturnsTwiceAttr>())
+ FD->addAttr(ReturnsTwiceAttr::CreateImplicit(Context,
+ FD->getLocation()));
+ if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->hasAttr<NoThrowAttr>())
+ FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation()));
+ if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->hasAttr<ConstAttr>())
+ FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation()));
}
IdentifierInfo *Name = FD->getIdentifier();
@@ -10067,17 +10448,19 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
// target-specific builtins, perhaps?
- if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ if (!FD->hasAttr<FormatAttr>())
+ FD->addAttr(FormatAttr::CreateImplicit(Context,
&Context.Idents.get("printf"), 2,
- Name->isStr("vasprintf") ? 0 : 3));
+ Name->isStr("vasprintf") ? 0 : 3,
+ FD->getLocation()));
}
if (Name->isStr("__CFStringMakeConstantString")) {
// We already have a __builtin___CFStringMakeConstantString,
// but builds that use -fno-constant-cfstrings don't go through that.
- if (!FD->getAttr<FormatArgAttr>())
- FD->addAttr(::new (Context) FormatArgAttr(FD->getLocation(), Context, 1));
+ if (!FD->hasAttr<FormatArgAttr>())
+ FD->addAttr(FormatArgAttr::CreateImplicit(Context, 1,
+ FD->getLocation()));
}
}
@@ -10140,6 +10523,26 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
if (!Context.hasSameType(T, Context.getTagDeclType(tagFromDeclSpec)))
break;
+ // If we've already computed linkage for the anonymous tag, then
+ // adding a typedef name for the anonymous decl can change that
+ // linkage, which might be a serious problem. Diagnose this as
+ // unsupported and ignore the typedef name. TODO: we should
+ // pursue this as a language defect and establish a formal rule
+ // for how to handle it.
+ if (tagFromDeclSpec->hasLinkageBeenComputed()) {
+ Diag(D.getIdentifierLoc(), diag::err_typedef_changes_linkage);
+
+ SourceLocation tagLoc = D.getDeclSpec().getTypeSpecTypeLoc();
+ tagLoc = getLocForEndOfToken(tagLoc);
+
+ llvm::SmallString<40> textToInsert;
+ textToInsert += ' ';
+ textToInsert += D.getIdentifier()->getName();
+ Diag(tagLoc, diag::note_typedef_changes_linkage)
+ << FixItHint::CreateInsertion(tagLoc, textToInsert);
+ break;
+ }
+
// Otherwise, set this is the anon-decl typedef for the tag.
tagFromDeclSpec->setTypedefNameForAnonDecl(NewTD);
break;
@@ -10179,7 +10582,7 @@ bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
if (IsScoped != Prev->isScoped()) {
Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch)
<< Prev->isScoped();
- Diag(Prev->getLocation(), diag::note_previous_use);
+ Diag(Prev->getLocation(), diag::note_previous_declaration);
return true;
}
@@ -10188,15 +10591,17 @@ bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
!Prev->getIntegerType()->isDependentType() &&
!Context.hasSameUnqualifiedType(EnumUnderlyingTy,
Prev->getIntegerType())) {
+ // TODO: Highlight the underlying type of the redeclaration.
Diag(EnumLoc, diag::err_enum_redeclare_type_mismatch)
<< EnumUnderlyingTy << Prev->getIntegerType();
- Diag(Prev->getLocation(), diag::note_previous_use);
+ Diag(Prev->getLocation(), diag::note_previous_declaration)
+ << Prev->getIntegerTypeRange();
return true;
}
} else if (IsFixed != Prev->isFixed()) {
Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch)
<< Prev->isFixed();
- Diag(Prev->getLocation(), diag::note_previous_use);
+ Diag(Prev->getLocation(), diag::note_previous_declaration);
return true;
}
@@ -10276,8 +10681,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
}
bool previousMismatch = false;
- for (TagDecl::redecl_iterator I(Previous->redecls_begin()),
- E(Previous->redecls_end()); I != E; ++I) {
+ for (auto I : Previous->redecls()) {
if (I->getTagKind() != NewTag) {
if (!previousMismatch) {
previousMismatch = true;
@@ -10308,7 +10712,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
<< getRedeclDiagFromTagKind(OldTag);
Diag(Redecl->getLocation(), diag::note_previous_use);
- // If there is a previous defintion, suggest a fix-it.
+ // If there is a previous definition, suggest a fix-it.
if (Previous->getDefinition()) {
Diag(NewTagLoc, diag::note_struct_class_suggestion)
<< getRedeclDiagFromTagKind(Redecl->getTagKind())
@@ -10321,10 +10725,56 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
return false;
}
+/// Add a minimal nested name specifier fixit hint to allow lookup of a tag name
+/// from an outer enclosing namespace or file scope inside a friend declaration.
+/// This should provide the commented out code in the following snippet:
+/// namespace N {
+/// struct X;
+/// namespace M {
+/// struct Y { friend struct /*N::*/ X; };
+/// }
+/// }
+static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S,
+ SourceLocation NameLoc) {
+ // While the decl is in a namespace, do repeated lookup of that name and see
+ // if we get the same namespace back. If we do not, continue until
+ // translation unit scope, at which point we have a fully qualified NNS.
+ SmallVector<IdentifierInfo *, 4> Namespaces;
+ DeclContext *DC = ND->getDeclContext()->getRedeclContext();
+ for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
+ // This tag should be declared in a namespace, which can only be enclosed by
+ // other namespaces. Bail if there's an anonymous namespace in the chain.
+ NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC);
+ if (!Namespace || Namespace->isAnonymousNamespace())
+ return FixItHint();
+ IdentifierInfo *II = Namespace->getIdentifier();
+ Namespaces.push_back(II);
+ NamedDecl *Lookup = SemaRef.LookupSingleName(
+ S, II, NameLoc, Sema::LookupNestedNameSpecifierName);
+ if (Lookup == Namespace)
+ break;
+ }
+
+ // Once we have all the namespaces, reverse them to go outermost first, and
+ // build an NNS.
+ SmallString<64> Insertion;
+ llvm::raw_svector_ostream OS(Insertion);
+ if (DC->isTranslationUnit())
+ OS << "::";
+ std::reverse(Namespaces.begin(), Namespaces.end());
+ for (auto *II : Namespaces)
+ OS << II->getName() << "::";
+ OS.flush();
+ return FixItHint::CreateInsertion(NameLoc, Insertion);
+}
+
/// ActOnTag - This is invoked when we see 'struct foo' or 'struct {'. In the
/// former case, Name will be non-null. In the later case, Name will be null.
/// TagSpec indicates what kind of tag this is. TUK indicates whether this is a
/// reference/declaration/definition of a tag.
+///
+/// IsTypeSpecifier is true if this is a type-specifier (or
+/// trailing-type-specifier) other than one in an alias-declaration.
Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
@@ -10334,10 +10784,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
bool &OwnedDecl, bool &IsDependent,
SourceLocation ScopedEnumKWLoc,
bool ScopedEnumUsesClassTag,
- TypeResult UnderlyingType) {
+ TypeResult UnderlyingType,
+ bool IsTypeSpecifier) {
// If this is not a definition, it must have a name.
IdentifierInfo *OrigName = Name;
- assert((Name != 0 || TUK == TUK_Definition) &&
+ assert((Name != nullptr || TUK == TUK_Definition) &&
"Nameless record must be a definition!");
assert(TemplateParameterLists.size() == 0 || TUK != TUK_Reference);
@@ -10356,11 +10807,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
(SS.isNotEmpty() && TUK != TUK_Reference)) {
if (TemplateParameterList *TemplateParams =
MatchTemplateParametersToScopeSpecifier(
- KWLoc, NameLoc, SS, TemplateParameterLists, TUK == TUK_Friend,
- isExplicitSpecialization, Invalid)) {
+ KWLoc, NameLoc, SS, nullptr, TemplateParameterLists,
+ TUK == TUK_Friend, isExplicitSpecialization, Invalid)) {
if (Kind == TTK_Enum) {
Diag(KWLoc, diag::err_enum_template);
- return 0;
+ return nullptr;
}
if (TemplateParams->size() > 0) {
@@ -10368,13 +10819,14 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// be a member of another template).
if (Invalid)
- return 0;
+ return nullptr;
OwnedDecl = false;
DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
SS, Name, NameLoc, Attr,
TemplateParams, AS,
ModulePrivateLoc,
+ /*FriendLoc*/SourceLocation(),
TemplateParameterLists.size()-1,
TemplateParameterLists.data());
return Result.get();
@@ -10400,7 +10852,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
else if (UnderlyingType.get()) {
// C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an
// integral type; any cv-qualification is ignored.
- TypeSourceInfo *TI = 0;
+ TypeSourceInfo *TI = nullptr;
GetTypeFromParser(UnderlyingType.get(), &TI);
EnumUnderlying = TI;
@@ -10412,7 +10864,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
UPPC_FixedUnderlyingType))
EnumUnderlying = Context.IntTy.getTypePtr();
- } else if (getLangOpts().MicrosoftMode)
+ } else if (getLangOpts().MSVCCompat)
// Microsoft enums are always of int type.
EnumUnderlying = Context.IntTy.getTypePtr();
}
@@ -10426,13 +10878,12 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Redecl = NotForRedeclaration;
LookupResult Previous(*this, Name, NameLoc, LookupTagName, Redecl);
- bool FriendSawTagOutsideEnclosingNamespace = false;
if (Name && SS.isNotEmpty()) {
// We have a nested-name tag ('struct foo::bar').
// Check for invalid 'foo::'.
if (SS.isInvalid()) {
- Name = 0;
+ Name = nullptr;
goto CreateNewDecl;
}
@@ -10442,26 +10893,26 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
DC = computeDeclContext(SS, false);
if (!DC) {
IsDependent = true;
- return 0;
+ return nullptr;
}
} else {
DC = computeDeclContext(SS, true);
if (!DC) {
Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
<< SS.getRange();
- return 0;
+ return nullptr;
}
}
if (RequireCompleteDeclContext(SS, DC))
- return 0;
+ return nullptr;
SearchDC = DC;
// Look-up name inside 'foo::'.
LookupQualifiedName(Previous, DC);
if (Previous.isAmbiguous())
- return 0;
+ return nullptr;
if (Previous.empty()) {
// Name lookup did not find anything. However, if the
@@ -10473,13 +10924,13 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (Previous.wasNotFoundInCurrentInstantiation() &&
(TUK == TUK_Reference || TUK == TUK_Friend)) {
IsDependent = true;
- return 0;
+ return nullptr;
}
// A tag 'foo::bar' must already exist.
Diag(NameLoc, diag::err_not_tag_in_scope)
<< Kind << Name << DC << SS.getRange();
- Name = 0;
+ Name = nullptr;
Invalid = true;
goto CreateNewDecl;
}
@@ -10511,26 +10962,41 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// the entity has been previously declared shall not consider
// any scopes outside the innermost enclosing namespace.
//
+ // MSVC doesn't implement the above rule for types, so a friend tag
+ // declaration may be a redeclaration of a type declared in an enclosing
+ // scope. They do implement this rule for friend functions.
+ //
// Does it matter that this should be by scope instead of by
// semantic context?
if (!Previous.empty() && TUK == TUK_Friend) {
DeclContext *EnclosingNS = SearchDC->getEnclosingNamespaceContext();
LookupResult::Filter F = Previous.makeFilter();
+ bool FriendSawTagOutsideEnclosingNamespace = false;
while (F.hasNext()) {
NamedDecl *ND = F.next();
DeclContext *DC = ND->getDeclContext()->getRedeclContext();
if (DC->isFileContext() &&
!EnclosingNS->Encloses(ND->getDeclContext())) {
- F.erase();
- FriendSawTagOutsideEnclosingNamespace = true;
+ if (getLangOpts().MSVCCompat)
+ FriendSawTagOutsideEnclosingNamespace = true;
+ else
+ F.erase();
}
}
F.done();
+
+ // Diagnose this MSVC extension in the easy case where lookup would have
+ // unambiguously found something outside the enclosing namespace.
+ if (Previous.isSingleResult() && FriendSawTagOutsideEnclosingNamespace) {
+ NamedDecl *ND = Previous.getFoundDecl();
+ Diag(NameLoc, diag::ext_friend_tag_redecl_outside_namespace)
+ << createFriendTagNNSFixIt(*this, ND, S, NameLoc);
+ }
}
-
+
// Note: there used to be some attempt at recovery here.
if (Previous.isAmbiguous())
- return 0;
+ return nullptr;
if (!getLangOpts().CPlusPlus && TUK != TUK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
@@ -10540,11 +11006,6 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
SearchDC = SearchDC->getParent();
}
- } else if (S->isFunctionPrototypeScope()) {
- // If this is an enum declaration in function prototype scope, set its
- // initial context to the translation unit.
- // FIXME: [citation needed]
- SearchDC = Context.getTranslationUnitDecl();
}
if (Previous.isSingleResult() &&
@@ -10634,7 +11095,9 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
}
if (!Previous.empty()) {
- NamedDecl *PrevDecl = (*Previous.begin())->getUnderlyingDecl();
+ NamedDecl *PrevDecl = Previous.getFoundDecl();
+ NamedDecl *DirectPrevDecl =
+ getLangOpts().MSVCCompat ? *Previous.begin() : PrevDecl;
// It's okay to have a tag decl in the same scope as a typedef
// which hides a tag decl in the same scope. Finding this
@@ -10666,7 +11129,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// in the same scope (so that the definition/declaration completes or
// rementions the tag), reuse the decl.
if (TUK == TUK_Reference || TUK == TUK_Friend ||
- isDeclInScope(PrevDecl, SearchDC, S, isExplicitSpecialization)) {
+ isDeclInScope(DirectPrevDecl, SearchDC, S,
+ SS.isNotEmpty() || isExplicitSpecialization)) {
// Make sure that this wasn't declared as an enum and now used as a
// struct or something similar.
if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind,
@@ -10688,7 +11152,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Kind = PrevTagDecl->getTagKind();
else {
// Recover by making this an anonymous redefinition.
- Name = 0;
+ Name = nullptr;
Previous.clear();
Invalid = true;
}
@@ -10709,7 +11173,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
QualType EnumUnderlyingTy;
if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>())
- EnumUnderlyingTy = TI->getType();
+ EnumUnderlyingTy = TI->getType().getUnqualifiedType();
else if (const Type *T = EnumUnderlying.dyn_cast<const Type*>())
EnumUnderlyingTy = QualType(T, 0);
@@ -10718,7 +11182,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// in which case we want the caller to bail out.
if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc,
ScopedEnum, EnumUnderlyingTy, PrevEnum))
- return TUK == TUK_Declaration ? PrevTagDecl : 0;
+ return TUK == TUK_Declaration ? PrevTagDecl : nullptr;
}
// C++11 [class.mem]p1:
@@ -10732,14 +11196,17 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
}
if (!Invalid) {
- // If this is a use, just return the declaration we found.
+ // If this is a use, just return the declaration we found, unless
+ // we have attributes.
// FIXME: In the future, return a variant or some other clue
// for the consumer of this Decl to know it doesn't own it.
// For our current ASTs this shouldn't be a problem, but will
// need to be changed with DeclGroups.
- if ((TUK == TUK_Reference && (!PrevTagDecl->getFriendObjectKind() ||
- getLangOpts().MicrosoftExt)) || TUK == TUK_Friend)
+ if (!Attr &&
+ ((TUK == TUK_Reference &&
+ (!PrevTagDecl->getFriendObjectKind() || getLangOpts().MicrosoftExt))
+ || TUK == TUK_Friend))
return PrevTagDecl;
// Diagnose attempts to redefine a tag.
@@ -10771,7 +11238,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// If this is a redefinition, recover by making this
// struct be anonymous, which will make any later
// references get the previous definition.
- Name = 0;
+ Name = nullptr;
Previous.clear();
Invalid = true;
}
@@ -10784,14 +11251,22 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Diag(NameLoc, diag::err_nested_redefinition) << Name;
Diag(PrevTagDecl->getLocation(),
diag::note_previous_definition);
- Name = 0;
+ Name = nullptr;
Previous.clear();
Invalid = true;
}
}
// Okay, this is definition of a previously declared or referenced
- // tag PrevDecl. We're going to create a new Decl for it.
+ // tag. We're going to create a new Decl for it.
+ }
+
+ // Okay, we're going to make a redeclaration. If this is some kind
+ // of reference, make sure we build the redeclaration in the same DC
+ // as the original, and ignore the current access specifier.
+ if (TUK == TUK_Friend || TUK == TUK_Reference) {
+ SearchDC = PrevTagDecl->getDeclContext();
+ AS = AS_none;
}
}
// If we get here we have (another) forward declaration or we
@@ -10827,8 +11302,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Invalid = true;
// Otherwise, only diagnose if the declaration is in scope.
- } else if (!isDeclInScope(PrevDecl, SearchDC, S,
- isExplicitSpecialization)) {
+ } else if (!isDeclInScope(PrevDecl, SearchDC, S,
+ SS.isNotEmpty() || isExplicitSpecialization)) {
// do nothing
// Diagnose implicit declarations introduced by elaborated types.
@@ -10857,7 +11332,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// issue an error and recover by making this tag be anonymous.
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- Name = 0;
+ Name = nullptr;
Invalid = true;
}
@@ -10869,7 +11344,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
CreateNewDecl:
- TagDecl *PrevDecl = 0;
+ TagDecl *PrevDecl = nullptr;
if (Previous.isSingleResult())
PrevDecl = cast<TagDecl>(Previous.getFoundDecl());
@@ -10904,7 +11379,7 @@ CreateNewDecl:
Diag(Def->getLocation(), diag::note_previous_definition);
} else {
unsigned DiagID = diag::ext_forward_ref_enum;
- if (getLangOpts().MicrosoftMode)
+ if (getLangOpts().MSVCCompat)
DiagID = diag::ext_ms_forward_ref_enum;
else if (getLangOpts().CPlusPlus)
DiagID = diag::err_forward_ref_enum;
@@ -10944,6 +11419,14 @@ CreateNewDecl:
cast_or_null<RecordDecl>(PrevDecl));
}
+ // C++11 [dcl.type]p3:
+ // A type-specifier-seq shall not define a class or enumeration [...].
+ if (getLangOpts().CPlusPlus && IsTypeSpecifier && TUK == TUK_Definition) {
+ Diag(New->getLocation(), diag::err_type_defined_in_type_specifier)
+ << Context.getTagDeclType(New);
+ Invalid = true;
+ }
+
// Maybe add qualifier info.
if (SS.isNotEmpty()) {
if (SS.isSet()) {
@@ -10995,23 +11478,37 @@ CreateNewDecl:
else if (!SearchDC->isFunctionOrMethod())
New->setModulePrivate();
}
-
+
// If this is a specialization of a member class (of a class template),
// check the specialization.
if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
Invalid = true;
-
+
+ // If we're declaring or defining a tag in function prototype scope in C,
+ // note that this type can only be used within the function and add it to
+ // the list of decls to inject into the function definition scope.
+ if ((Name || Kind == TTK_Enum) &&
+ getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
+ if (getLangOpts().CPlusPlus) {
+ // C++ [dcl.fct]p6:
+ // Types shall not be defined in return or parameter types.
+ if (TUK == TUK_Definition && !IsTypeSpecifier) {
+ Diag(Loc, diag::err_type_defined_in_param_type)
+ << Name;
+ Invalid = true;
+ }
+ } else {
+ Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+ }
+ DeclsInPrototypeScope.push_back(New);
+ }
+
if (Invalid)
New->setInvalidDecl();
if (Attr)
ProcessDeclAttributeList(S, New, Attr);
- // If we're declaring or defining a tag in function prototype scope
- // in C, note that this type can only be used within the function.
- if (Name && S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus)
- Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
-
// Set the lexical context. If the tag has a C++ scope specifier, the
// lexical context will be different from the semantic context.
New->setLexicalDeclContext(CurContext);
@@ -11021,8 +11518,7 @@ CreateNewDecl:
// declaration so we always pass true to setObjectOfFriendDecl to make
// the tag name visible.
if (TUK == TUK_Friend)
- New->setObjectOfFriendDecl(!FriendSawTagOutsideEnclosingNamespace &&
- getLangOpts().MicrosoftExt);
+ New->setObjectOfFriendDecl(getLangOpts().MSVCCompat);
// Set the access specifier.
if (!Invalid && SearchDC->isRecord())
@@ -11060,12 +11556,6 @@ CreateNewDecl:
II->isStr("FILE"))
Context.setFILEDecl(New);
- // If we were in function prototype scope (and not in C++ mode), add this
- // tag to the list of decls to inject into the function definition scope.
- if (S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus &&
- InFunctionDeclarator && Name)
- DeclsInPrototypeScope.push_back(New);
-
if (PrevDecl)
mergeDeclAttributes(New, PrevDecl);
@@ -11076,7 +11566,7 @@ CreateNewDecl:
OwnedDecl = true;
// In C++, don't return an invalid declaration. We can't recover well from
// the cases where we make the type anonymous.
- return (Invalid && getLangOpts().CPlusPlus) ? 0 : New;
+ return (Invalid && getLangOpts().CPlusPlus) ? nullptr : New;
}
void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
@@ -11128,7 +11618,7 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
= CXXRecordDecl::Create(Context, Record->getTagKind(), CurContext,
Record->getLocStart(), Record->getLocation(),
Record->getIdentifier(),
- /*PrevDecl=*/0,
+ /*PrevDecl=*/nullptr,
/*DelayTypeCreation=*/true);
Context.getTypeDeclType(InjectedClassName, Record);
InjectedClassName->setImplicit();
@@ -11181,7 +11671,7 @@ void Sema::ActOnObjCTemporaryExitContainerContext(DeclContext *DC) {
void Sema::ActOnObjCReenterContainerContext(DeclContext *DC) {
ActOnObjCContainerStartDefinition(cast<Decl>(DC));
- OriginalLexicalContext = 0;
+ OriginalLexicalContext = nullptr;
}
void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
@@ -11229,13 +11719,13 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
// If the bit-width is type- or value-dependent, don't try to check
// it now.
if (BitWidth->isValueDependent() || BitWidth->isTypeDependent())
- return Owned(BitWidth);
+ return BitWidth;
llvm::APSInt Value;
ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value);
if (ICE.isInvalid())
return ICE;
- BitWidth = ICE.take();
+ BitWidth = ICE.get();
if (Value != 0 && ZeroWidth)
*ZeroWidth = false;
@@ -11255,7 +11745,8 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
if (!FieldTy->isDependentType()) {
uint64_t TypeSize = Context.getTypeSize(FieldTy);
if (Value.getZExtValue() > TypeSize) {
- if (!getLangOpts().CPlusPlus || IsMsStruct) {
+ if (!getLangOpts().CPlusPlus || IsMsStruct ||
+ Context.getTargetInfo().getCXXABI().isMicrosoft()) {
if (FieldName)
return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
<< FieldName << (unsigned)Value.getZExtValue()
@@ -11275,7 +11766,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
}
}
- return Owned(BitWidth);
+ return BitWidth;
}
/// ActOnField - Each field of a C struct/union is passed into this in order
@@ -11333,7 +11824,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
<< DeclSpec::getSpecifierName(TSCS);
// Check to see if this name was declared as a member previously
- NamedDecl *PrevDecl = 0;
+ NamedDecl *PrevDecl = nullptr;
LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
LookupName(Previous, S);
switch (Previous.getResultKind()) {
@@ -11357,11 +11848,11 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
// Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
+ PrevDecl = nullptr;
}
if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
- PrevDecl = 0;
+ PrevDecl = nullptr;
bool Mutable
= (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable);
@@ -11474,10 +11965,10 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
// If this is declared as a bit-field, check the bit-field.
if (!InvalidDecl && BitWidth) {
BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
- &ZeroWidth).take();
+ &ZeroWidth).get();
if (!BitWidth) {
InvalidDecl = true;
- BitWidth = 0;
+ BitWidth = nullptr;
ZeroWidth = false;
}
}
@@ -11500,6 +11991,12 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
}
}
+ // C++11 [class.union]p8 (DR1460):
+ // At most one variant member of a union may have a
+ // brace-or-equal-initializer.
+ if (InitStyle != ICIS_NoInit)
+ checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Record), Loc);
+
FieldDecl *NewFD = FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo,
BitWidth, Mutable, InitStyle);
if (InvalidDecl)
@@ -11603,8 +12100,9 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) {
SourceLocation Loc = FD->getLocation();
if (getSourceManager().isInSystemHeader(Loc)) {
if (!FD->hasAttr<UnavailableAttr>())
- FD->addAttr(new (Context) UnavailableAttr(Loc, Context,
- "this system field has retaining ownership"));
+ FD->addAttr(UnavailableAttr::CreateImplicit(Context,
+ "this system field has retaining ownership",
+ Loc));
return false;
}
}
@@ -11655,7 +12153,7 @@ Decl *Sema::ActOnIvar(Scope *S,
if (BitWidth) {
// 6.7.2.1p3, 6.7.2.1p4
- BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).take();
+ BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get();
if (!BitWidth)
D.setInvalidType();
} else {
@@ -11682,7 +12180,7 @@ Decl *Sema::ActOnIvar(Scope *S,
// Must set ivar's DeclContext to its enclosing interface.
ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(CurContext);
if (!EnclosingDecl || EnclosingDecl->isInvalidDecl())
- return 0;
+ return nullptr;
ObjCContainerDecl *EnclosingContext;
if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
@@ -11698,7 +12196,7 @@ Decl *Sema::ActOnIvar(Scope *S,
dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
if (LangOpts.ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) {
Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
- return 0;
+ return nullptr;
}
}
EnclosingContext = EnclosingDecl;
@@ -11776,7 +12274,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,
Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc);
Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext),
- DeclLoc, DeclLoc, 0,
+ DeclLoc, DeclLoc, nullptr,
Context.CharTy,
Context.getTrivialTypeSourceInfo(Context.CharTy,
DeclLoc),
@@ -11813,9 +12311,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
// members of anonymous structs and unions in the total.
unsigned NumNamedMembers = 0;
if (Record) {
- for (RecordDecl::decl_iterator i = Record->decls_begin(),
- e = Record->decls_end(); i != e; i++) {
- if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*i))
+ for (const auto *I : Record->decls()) {
+ if (const auto *IFD = dyn_cast<IndirectFieldDecl>(I))
if (IFD->getDeclName())
++NumNamedMembers;
}
@@ -11902,9 +12399,14 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
<< FD->getDeclName() << Record->getTagKind();
- if (!FD->getType()->isDependentType() &&
- !Context.getBaseElementType(FD->getType()).isPODType(Context)) {
- Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type)
+ // If the element type has a non-trivial destructor, we would not
+ // implicitly destroy the elements, so disallow it for now.
+ //
+ // FIXME: GCC allows this. We should probably either implicitly delete
+ // the destructor of the containing class, or just allow this.
+ QualType BaseElem = Context.getBaseElementType(FD->getType());
+ if (!BaseElem->isDependentType() && BaseElem.isDestructedType()) {
+ Diag(FD->getLocation(), diag::err_flexible_array_has_nontrivial_dtor)
<< FD->getDeclName() << FD->getType();
FD->setInvalidDecl();
EnclosingDecl->setInvalidDecl();
@@ -11972,8 +12474,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
SourceLocation loc = FD->getLocation();
if (getSourceManager().isInSystemHeader(loc)) {
if (!FD->hasAttr<UnavailableAttr>()) {
- FD->addAttr(new (Context) UnavailableAttr(loc, Context,
- "this system field has retaining ownership"));
+ FD->addAttr(UnavailableAttr::CreateImplicit(Context,
+ "this system field has retaining ownership",
+ loc));
}
} else {
Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag)
@@ -12021,12 +12524,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
if (getLangOpts().CPlusPlus11)
AdjustDestructorExceptionSpec(CXXRecord,
CXXRecord->getDestructor());
-
- // The Microsoft ABI requires that we perform the destructor body
- // checks (i.e. operator delete() lookup) at every declaration, as
- // any translation unit may need to emit a deleting destructor.
- if (Context.getTargetInfo().getCXXABI().isMicrosoft())
- CheckDestructor(CXXRecord->getDestructor());
}
// Add any implicitly-declared members to this class.
@@ -12078,9 +12575,15 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
if (!Completed)
Record->completeDefinition();
- if (Record->hasAttrs())
+ if (Record->hasAttrs()) {
CheckAlignasUnderalignment(Record);
+ if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>())
+ checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record),
+ IA->getRange(), IA->getBestCase(),
+ IA->getSemanticSpelling());
+ }
+
// Check if the structure/union declaration is a type that can have zero
// size in C. For C this is a language extension, for C++ it may cause
// compatibility problems.
@@ -12175,10 +12678,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Diag(ClsIvar->getLocation(), diag::note_previous_definition);
continue;
}
- for (ObjCInterfaceDecl::known_extensions_iterator
- Ext = IDecl->known_extensions_begin(),
- ExtEnd = IDecl->known_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : IDecl->known_extensions()) {
if (const ObjCIvarDecl *ClsExtIvar
= Ext->getIvarDecl(ClsFields[i]->getIdentifier())) {
Diag(ClsFields[i]->getLocation(),
@@ -12251,10 +12751,10 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
QualType EltTy;
if (Val && DiagnoseUnexpandedParameterPack(Val, UPPC_EnumeratorValue))
- Val = 0;
+ Val = nullptr;
if (Val)
- Val = DefaultLvalueConversion(Val).take();
+ Val = DefaultLvalueConversion(Val).get();
if (Val) {
if (Enum->isDependentType() || Val->isTypeDependent())
@@ -12262,7 +12762,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
else {
SourceLocation ExpLoc;
if (getLangOpts().CPlusPlus11 && Enum->isFixed() &&
- !getLangOpts().MicrosoftMode) {
+ !getLangOpts().MSVCCompat) {
// C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the
// constant-expression in the enumerator-definition shall be a converted
// constant expression of the underlying type.
@@ -12271,12 +12771,12 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
CheckConvertedConstantExpression(Val, EltTy, EnumVal,
CCEK_Enumerator);
if (Converted.isInvalid())
- Val = 0;
+ Val = nullptr;
else
- Val = Converted.take();
+ Val = Converted.get();
} else if (!Val->isValueDependent() &&
!(Val = VerifyIntegerConstantExpression(Val,
- &EnumVal).take())) {
+ &EnumVal).get())) {
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
} else {
if (Enum->isFixed()) {
@@ -12287,13 +12787,13 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
// we perform a non-narrowing conversion as part of converted constant
// expression checking.
if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
- if (getLangOpts().MicrosoftMode) {
+ if (getLangOpts().MSVCCompat) {
Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
- Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+ Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
} else
Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
} else
- Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+ Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
} else if (getLangOpts().CPlusPlus) {
// C++11 [dcl.enum]p5:
// If the underlying type is not fixed, the type of each enumerator
@@ -12314,7 +12814,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
<< (EnumVal.isUnsigned() || EnumVal.isNonNegative());
else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
// Force the type of the expression to 'int'.
- Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
+ Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).get();
}
EltTy = Val->getType();
}
@@ -12371,7 +12871,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
<< EnumVal.toString(10)
<< EltTy;
else
- Diag(IdLoc, diag::warn_enumerator_too_large)
+ Diag(IdLoc, diag::ext_enumerator_increment_too_large)
<< EnumVal.toString(10);
} else {
EltTy = T;
@@ -12433,7 +12933,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
// Just pretend that we didn't see the previous declaration.
- PrevDecl = 0;
+ PrevDecl = nullptr;
}
if (PrevDecl) {
@@ -12447,7 +12947,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
else
Diag(IdLoc, diag::err_redefinition) << Id;
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
- return 0;
+ return nullptr;
}
}
@@ -12549,9 +13049,7 @@ struct DenseMapInfoDupKey {
static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
EnumDecl *Enum,
QualType EnumType) {
- if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values,
- Enum->getLocation()) ==
- DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation()))
return;
// Avoid anonymous enums
if (!Enum->getIdentifier())
@@ -12729,7 +13227,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
// The C99 rule is modified by a gcc extension
QualType BestPromotionType;
- bool Packed = Enum->getAttr<PackedAttr>() ? true : false;
+ bool Packed = Enum->hasAttr<PackedAttr>();
// -fshort-enums is the equivalent to specifying the packed attribute on all
// enum definitions.
if (LangOpts.ShortEnums)
@@ -12769,7 +13267,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
BestWidth = Context.getTargetInfo().getLongLongWidth();
if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
- Diag(Enum->getLocation(), diag::warn_enum_too_large);
+ Diag(Enum->getLocation(), diag::ext_enum_too_large);
BestType = Context.LongLongTy;
}
}
@@ -12860,7 +13358,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
CK_IntegralCast,
ECD->getInitExpr(),
- /*base paths*/ 0,
+ /*base paths*/ nullptr,
VK_RValue));
if (getLangOpts().CPlusPlus)
// C++ [dcl.enum]p4: Following the closing brace of an
@@ -12874,11 +13372,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
Enum->completeDefinition(BestType, BestPromotionType,
NumPositiveBits, NumNegativeBits);
- // If we're declaring a function, ensure this decl isn't forgotten about -
- // it needs to go into the function scope.
- if (InFunctionDeclarator)
- DeclsInPrototypeScope.push_back(Enum);
-
CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
// Now that the enum type is defined, ensure it's not been underaligned.
@@ -12898,15 +13391,54 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
return New;
}
+static void checkModuleImportContext(Sema &S, Module *M,
+ SourceLocation ImportLoc,
+ DeclContext *DC) {
+ if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
+ switch (LSD->getLanguage()) {
+ case LinkageSpecDecl::lang_c:
+ if (!M->IsExternC) {
+ S.Diag(ImportLoc, diag::err_module_import_in_extern_c)
+ << M->getFullModuleName();
+ S.Diag(LSD->getLocStart(), diag::note_module_import_in_extern_c);
+ return;
+ }
+ break;
+ case LinkageSpecDecl::lang_cxx:
+ break;
+ }
+ DC = LSD->getParent();
+ }
+
+ while (isa<LinkageSpecDecl>(DC))
+ DC = DC->getParent();
+ if (!isa<TranslationUnitDecl>(DC)) {
+ S.Diag(ImportLoc, diag::err_module_import_not_at_top_level)
+ << M->getFullModuleName() << DC;
+ S.Diag(cast<Decl>(DC)->getLocStart(),
+ diag::note_module_import_not_at_top_level)
+ << DC;
+ }
+}
+
DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc,
SourceLocation ImportLoc,
ModuleIdPath Path) {
- Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path,
- Module::AllVisible,
- /*IsIncludeDirective=*/false);
+ Module *Mod =
+ getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
+ /*IsIncludeDirective=*/false);
if (!Mod)
return true;
-
+
+ checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
+
+ // FIXME: we should support importing a submodule within a different submodule
+ // of the same top-level module. Until we do, make it an error rather than
+ // silently ignoring the import.
+ if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ Diag(ImportLoc, diag::err_module_self_import)
+ << Mod->getFullModuleName() << getLangOpts().CurrentModule;
+
SmallVector<SourceLocation, 2> IdentifierLocs;
Module *ModCheck = Mod;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
@@ -12928,12 +13460,19 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc,
}
void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
+ checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext);
+
// FIXME: Should we synthesize an ImportDecl here?
- PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc,
- /*Complain=*/true);
+ getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc,
+ /*Complain=*/true);
}
-void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) {
+void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
+ Module *Mod) {
+ // Bail if we're not allowed to implicitly import a module here.
+ if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery)
+ return;
+
// Create the implicit import declaration.
TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
@@ -12942,8 +13481,8 @@ void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) {
Consumer.HandleImplicitImportDecl(ImportD);
// Make the module visible.
- PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc,
- /*Complain=*/false);
+ getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc,
+ /*Complain=*/false);
}
void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
@@ -12953,8 +13492,8 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
SourceLocation AliasNameLoc) {
Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
LookupOrdinaryName);
- AsmLabelAttr *Attr =
- ::new (Context) AsmLabelAttr(AliasNameLoc, Context, AliasName->getName());
+ AsmLabelAttr *Attr = ::new (Context) AsmLabelAttr(AliasNameLoc, Context,
+ AliasName->getName(), 0);
if (PrevDecl)
PrevDecl->addAttr(Attr);
@@ -12969,11 +13508,11 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
if (PrevDecl) {
- PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
+ PrevDecl->addAttr(WeakAttr::CreateImplicit(Context, PragmaLoc));
} else {
(void)WeakUndeclaredIdentifiers.insert(
std::pair<IdentifierInfo*,WeakInfo>
- (Name, WeakInfo((IdentifierInfo*)0, NameLoc)));
+ (Name, WeakInfo((IdentifierInfo*)nullptr, NameLoc)));
}
}
@@ -13002,5 +13541,22 @@ Decl *Sema::getObjCDeclContext() const {
AvailabilityResult Sema::getCurContextAvailability() const {
const Decl *D = cast<Decl>(getCurObjCLexicalContext());
+ // If we are within an Objective-C method, we should consult
+ // both the availability of the method as well as the
+ // enclosing class. If the class is (say) deprecated,
+ // the entire method is considered deprecated from the
+ // purpose of checking if the current context is deprecated.
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ AvailabilityResult R = MD->getAvailability();
+ if (R != AR_Available)
+ return R;
+ D = MD->getClassInterface();
+ }
+ // If we are within an Objective-c @implementation, it
+ // gets the same availability context as the @interface.
+ else if (const ObjCImplementationDecl *ID =
+ dyn_cast<ObjCImplementationDecl>(D)) {
+ D = ID->getClassInterface();
+ }
return D->getAvailability();
}
OpenPOWER on IntegriCloud