summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp8
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/AttributeList.cpp2
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp126
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/ScopeInfo.cpp1
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/Sema.cpp43
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp18
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp16
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp21
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp13
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp509
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp14
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp1156
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp93
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp10
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp398
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp145
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp71
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp78
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp402
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp10
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp58
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp49
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp328
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp131
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp308
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp314
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp4
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp270
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp7
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp132
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp1
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaType.cpp118
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/TreeTransform.h173
34 files changed, 3397 insertions, 1634 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp b/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 00d3c47..1295339 100644
--- a/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1333,8 +1333,12 @@ class ThreadSafetyReporter : public clang::thread_safety::ThreadSafetyHandler {
LocEndOfScope = FunEndLocation;
PartialDiagnosticAt Warning(LocEndOfScope, S.PDiag(DiagID) << LockName);
- PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here));
- Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
+ if (LocLocked.isValid()) {
+ PartialDiagnosticAt Note(LocLocked, S.PDiag(diag::note_locked_here));
+ Warnings.push_back(DelayedDiag(Warning, OptionalNotes(1, Note)));
+ return;
+ }
+ Warnings.push_back(DelayedDiag(Warning, OptionalNotes()));
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/AttributeList.cpp b/contrib/llvm/tools/clang/lib/Sema/AttributeList.cpp
index e227d4e..9ac4c63 100644
--- a/contrib/llvm/tools/clang/lib/Sema/AttributeList.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/AttributeList.cpp
@@ -23,6 +23,8 @@ size_t AttributeList::allocated_size() const {
if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
else if (IsTypeTagForDatatype)
return AttributeFactory::TypeTagForDatatypeAllocSize;
+ else if (IsProperty)
+ return AttributeFactory::PropertyAllocSize;
return (sizeof(AttributeList) + NumArgs * sizeof(Expr*));
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
index e1d55db..3b3ab2c 100644
--- a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
@@ -24,6 +24,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstring>
using namespace clang;
@@ -293,6 +294,11 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_event_t:
return false;
+ case TST_decltype_auto:
+ // This must have an initializer, so can't be a function declaration,
+ // even if the initializer has function type.
+ return false;
+
case TST_decltype:
case TST_typeofExpr:
if (Expr *E = DS.getRepAsExpr())
@@ -325,7 +331,7 @@ bool Declarator::isDeclarationOfFunction() const {
unsigned DeclSpec::getParsedSpecifiers() const {
unsigned Res = 0;
if (StorageClassSpec != SCS_unspecified ||
- SCS_thread_specified)
+ ThreadStorageClassSpec != TSCS_unspecified)
Res |= PQ_StorageClassSpecifier;
if (TypeQualifiers != TQ_unspecified)
@@ -367,6 +373,16 @@ const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
llvm_unreachable("Unknown typespec!");
}
+const char *DeclSpec::getSpecifierName(DeclSpec::TSCS S) {
+ switch (S) {
+ case DeclSpec::TSCS_unspecified: return "unspecified";
+ case DeclSpec::TSCS___thread: return "__thread";
+ case DeclSpec::TSCS_thread_local: return "thread_local";
+ case DeclSpec::TSCS__Thread_local: return "_Thread_local";
+ }
+ llvm_unreachable("Unknown typespec!");
+}
+
const char *DeclSpec::getSpecifierName(TSW W) {
switch (W) {
case TSW_unspecified: return "unspecified";
@@ -423,6 +439,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
case DeclSpec::TST_typeofExpr: return "typeof";
case DeclSpec::TST_auto: return "auto";
case DeclSpec::TST_decltype: return "(decltype)";
+ case DeclSpec::TST_decltype_auto: return "decltype(auto)";
case DeclSpec::TST_underlyingType: return "__underlying_type";
case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
case DeclSpec::TST_atomic: return "_Atomic";
@@ -483,7 +500,7 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
}
if (StorageClassSpec != SCS_unspecified) {
- // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
+ // Maybe this is an attempt to use C++11 'auto' outside of C++11 mode.
bool isInvalid = true;
if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
if (SC == SCS_auto)
@@ -510,16 +527,14 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc,
return false;
}
-bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
+bool DeclSpec::SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc,
const char *&PrevSpec,
unsigned &DiagID) {
- if (SCS_thread_specified) {
- PrevSpec = "__thread";
- DiagID = diag::ext_duplicate_declspec;
- return true;
- }
- SCS_thread_specified = true;
- SCS_threadLoc = Loc;
+ if (ThreadStorageClassSpec != TSCS_unspecified)
+ return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID);
+
+ ThreadStorageClassSpec = TSC;
+ ThreadStorageClassSpecLoc = Loc;
return false;
}
@@ -825,6 +840,39 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
// Check the type specifier components first.
+ // If decltype(auto) is used, no other type specifiers are permitted.
+ if (TypeSpecType == TST_decltype_auto &&
+ (TypeSpecWidth != TSW_unspecified ||
+ TypeSpecComplex != TSC_unspecified ||
+ TypeSpecSign != TSS_unspecified ||
+ TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool ||
+ TypeQualifiers)) {
+ const unsigned NumLocs = 8;
+ SourceLocation ExtraLocs[NumLocs] = {
+ TSWLoc, TSCLoc, TSSLoc, AltiVecLoc,
+ TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc
+ };
+ FixItHint Hints[NumLocs];
+ SourceLocation FirstLoc;
+ for (unsigned I = 0; I != NumLocs; ++I) {
+ if (!ExtraLocs[I].isInvalid()) {
+ if (FirstLoc.isInvalid() ||
+ PP.getSourceManager().isBeforeInTranslationUnit(ExtraLocs[I],
+ FirstLoc))
+ FirstLoc = ExtraLocs[I];
+ Hints[I] = FixItHint::CreateRemoval(ExtraLocs[I]);
+ }
+ }
+ TypeSpecWidth = TSW_unspecified;
+ TypeSpecComplex = TSC_unspecified;
+ TypeSpecSign = TSS_unspecified;
+ TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;
+ TypeQualifiers = 0;
+ Diag(D, TSTLoc, diag::err_decltype_auto_cannot_be_combined)
+ << Hints[0] << Hints[1] << Hints[2] << Hints[3]
+ << Hints[4] << Hints[5] << Hints[6] << Hints[7];
+ }
+
// Validate and finalize AltiVec vector declspec.
if (TypeAltiVecVector) {
if (TypeAltiVecBool) {
@@ -923,12 +971,39 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
}
}
+ // C11 6.7.1/3, C++11 [dcl.stc]p1, GNU TLS: __thread, thread_local and
+ // _Thread_local can only appear with the 'static' and 'extern' storage class
+ // specifiers. We also allow __private_extern__ as an extension.
+ if (ThreadStorageClassSpec != TSCS_unspecified) {
+ switch (StorageClassSpec) {
+ case SCS_unspecified:
+ case SCS_extern:
+ case SCS_private_extern:
+ case SCS_static:
+ break;
+ default:
+ if (PP.getSourceManager().isBeforeInTranslationUnit(
+ getThreadStorageClassSpecLoc(), getStorageClassSpecLoc()))
+ Diag(D, getStorageClassSpecLoc(),
+ diag::err_invalid_decl_spec_combination)
+ << DeclSpec::getSpecifierName(getThreadStorageClassSpec())
+ << SourceRange(getThreadStorageClassSpecLoc());
+ else
+ Diag(D, getThreadStorageClassSpecLoc(),
+ diag::err_invalid_decl_spec_combination)
+ << DeclSpec::getSpecifierName(getStorageClassSpec())
+ << SourceRange(getStorageClassSpecLoc());
+ // Discard the thread storage class specifier to recover.
+ ThreadStorageClassSpec = TSCS_unspecified;
+ ThreadStorageClassSpecLoc = SourceLocation();
+ }
+ }
+
// If no type specifier was provided and we're parsing a language where
// the type specifier is not optional, but we got 'auto' as a storage
// class specifier, then assume this is an attempt to use C++0x's 'auto'
// type specifier.
- // FIXME: Does Microsoft really support implicit int in C++?
- if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt &&
+ if (PP.getLangOpts().CPlusPlus &&
TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
TypeSpecType = TST_auto;
StorageClassSpec = SCS_unspecified;
@@ -936,7 +1011,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
StorageClassSpecLoc = SourceLocation();
}
// Diagnose if we've recovered from an ill-formed 'auto' storage class
- // specifier in a pre-C++0x dialect of C++.
+ // specifier in a pre-C++11 dialect of C++.
if (!PP.getLangOpts().CPlusPlus11 && TypeSpecType == TST_auto)
Diag(D, TSTLoc, diag::ext_auto_type_specifier);
if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus11 &&
@@ -952,16 +1027,27 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) {
// C++ [class.friend]p6:
// No storage-class-specifier shall appear in the decl-specifier-seq
// of a friend declaration.
- if (isFriendSpecified() && getStorageClassSpec()) {
- DeclSpec::SCS SC = getStorageClassSpec();
- const char *SpecName = getSpecifierName(SC);
+ if (isFriendSpecified() &&
+ (getStorageClassSpec() || getThreadStorageClassSpec())) {
+ SmallString<32> SpecName;
+ SourceLocation SCLoc;
+ FixItHint StorageHint, ThreadHint;
+
+ if (DeclSpec::SCS SC = getStorageClassSpec()) {
+ SpecName = getSpecifierName(SC);
+ SCLoc = getStorageClassSpecLoc();
+ StorageHint = FixItHint::CreateRemoval(SCLoc);
+ }
- SourceLocation SCLoc = getStorageClassSpecLoc();
- SourceLocation SCEndLoc = SCLoc.getLocWithOffset(strlen(SpecName));
+ if (DeclSpec::TSCS TSC = getThreadStorageClassSpec()) {
+ if (!SpecName.empty()) SpecName += " ";
+ SpecName += getSpecifierName(TSC);
+ SCLoc = getThreadStorageClassSpecLoc();
+ ThreadHint = FixItHint::CreateRemoval(SCLoc);
+ }
Diag(D, SCLoc, diag::err_friend_storage_spec)
- << SpecName
- << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
+ << SpecName << StorageHint << ThreadHint;
ClearStorageClassSpecs();
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/ScopeInfo.cpp b/contrib/llvm/tools/clang/lib/Sema/ScopeInfo.cpp
index 4d29a34..2f48bec 100644
--- a/contrib/llvm/tools/clang/lib/Sema/ScopeInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/ScopeInfo.cpp
@@ -187,3 +187,4 @@ void FunctionScopeInfo::markSafeWeakUse(const Expr *E) {
FunctionScopeInfo::~FunctionScopeInfo() { }
BlockScopeInfo::~BlockScopeInfo() { }
LambdaScopeInfo::~LambdaScopeInfo() { }
+CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { }
diff --git a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp
index 6bab9e8..e718be2 100644
--- a/contrib/llvm/tools/clang/lib/Sema/Sema.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/Sema.cpp
@@ -90,7 +90,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
CurrentInstantiationScope(0), TyposCorrected(0),
- AnalysisWarnings(*this), Ident_super(0)
+ AnalysisWarnings(*this), CurScope(0), Ident_super(0)
{
TUScope = 0;
@@ -590,12 +590,11 @@ void Sema::ActOnEndOfTranslationUnit() {
}
// Remove file scoped decls that turned out to be used.
- UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(0,
- true),
- UnusedFileScopedDecls.end(),
- std::bind1st(std::ptr_fun(ShouldRemoveFromUnused),
- this)),
- UnusedFileScopedDecls.end());
+ UnusedFileScopedDecls.erase(
+ std::remove_if(UnusedFileScopedDecls.begin(0, true),
+ UnusedFileScopedDecls.end(),
+ std::bind1st(std::ptr_fun(ShouldRemoveFromUnused), this)),
+ UnusedFileScopedDecls.end());
if (TUKind == TU_Prefix) {
// Translation unit prefixes don't need any of the checking below.
@@ -751,9 +750,13 @@ void Sema::ActOnEndOfTranslationUnit() {
if (DiagD->isReferenced()) {
Diag(DiagD->getLocation(), diag::warn_unneeded_internal_decl)
<< /*variable*/1 << DiagD->getDeclName();
- } else {
+ } else if (getSourceManager().isFromMainFile(DiagD->getLocation())) {
+ // If the declaration is in a header which is included into multiple
+ // TUs, it will declare one variable per TU, and one of the other
+ // variables may be used. So, only warn if the declaration is in the
+ // main file.
Diag(DiagD->getLocation(), diag::warn_unused_variable)
- << DiagD->getDeclName();
+ << DiagD->getDeclName();
}
}
}
@@ -798,7 +801,7 @@ DeclContext *Sema::getFunctionLevelDeclContext() {
DeclContext *DC = CurContext;
while (true) {
- if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) {
+ if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC) || isa<CapturedDecl>(DC)) {
DC = DC->getParent();
} else if (isa<CXXMethodDecl>(DC) &&
cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
@@ -1073,7 +1076,8 @@ void Sema::ActOnComment(SourceRange Comment) {
if (!LangOpts.RetainCommentsFromSystemHeaders &&
SourceMgr.isInSystemHeader(Comment.getBegin()))
return;
- RawComment RC(SourceMgr, Comment);
+ RawComment RC(SourceMgr, Comment, false,
+ LangOpts.CommentOpts.ParseAllComments);
if (RC.isAlmostTrailingComment()) {
SourceRange MagicMarkerRange(Comment.getBegin(),
Comment.getBegin().getLocWithOffset(3));
@@ -1292,7 +1296,7 @@ bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
// FIXME: Try this before emitting the fixit, and suppress diagnostics
// while doing so.
E = ActOnCallExpr(0, E.take(), ParenInsertionLoc,
- MultiExprArg(), ParenInsertionLoc.getLocWithOffset(1));
+ None, ParenInsertionLoc.getLocWithOffset(1));
return true;
}
@@ -1309,3 +1313,18 @@ IdentifierInfo *Sema::getSuperIdentifier() const {
Ident_super = &Context.Idents.get("super");
return Ident_super;
}
+
+void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD,
+ CapturedRegionKind K) {
+ CapturingScopeInfo *CSI = new CapturedRegionScopeInfo(getDiagnostics(), S, CD, RD,
+ CD->getContextParam(), K);
+ CSI->ReturnType = Context.VoidTy;
+ FunctionScopes.push_back(CSI);
+}
+
+CapturedRegionScopeInfo *Sema::getCurCapturedRegion() {
+ if (FunctionScopes.empty())
+ return 0;
+
+ return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back());
+}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp
index 79a9d3c..3ef1fde 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaAccess.cpp
@@ -84,10 +84,10 @@ struct EffectiveContext {
: Inner(DC),
Dependent(DC->isDependentContext()) {
- // C++ [class.access.nest]p1:
+ // C++11 [class.access.nest]p1:
// A nested class is a member and as such has the same access
// rights as any other member.
- // C++ [class.access]p2:
+ // C++11 [class.access]p2:
// A member of a class can also access all the names to which
// the class has access. A local class of a member function
// may access the same names that the member function itself
@@ -1476,18 +1476,18 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
llvm_unreachable("falling off end");
}
-void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *decl) {
+void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
// Access control for names used in the declarations of functions
// and function templates should normally be evaluated in the context
// of the declaration, just in case it's a friend of something.
// However, this does not apply to local extern declarations.
- DeclContext *DC = decl->getDeclContext();
- if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
- if (!DC->isFunctionOrMethod()) DC = fn;
- } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
- // Never a local declaration.
- DC = fnt->getTemplatedDecl();
+ DeclContext *DC = D->getDeclContext();
+ if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
+ if (!DC->isFunctionOrMethod())
+ DC = FN;
+ } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
+ DC = cast<DeclContext>(TD->getTemplatedDecl());
}
EffectiveContext EC(DC);
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
index e2a4084..eb11a57 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaCast.cpp
@@ -333,7 +333,7 @@ static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT,
: (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range,
listInitialization)
: InitializationKind::CreateCast(/*type range?*/ range);
- InitializationSequence sequence(S, entity, initKind, &src, 1);
+ InitializationSequence sequence(S, entity, initKind, src);
assert(sequence.Failed() && "initialization succeeded on second try?");
switch (sequence.getFailureKind()) {
@@ -1418,7 +1418,7 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType,
? InitializationKind::CreateFunctionalCast(OpRange, ListInitialization)
: InitializationKind::CreateCast(OpRange);
Expr *SrcExprRaw = SrcExpr.get();
- InitializationSequence InitSeq(Self, Entity, InitKind, &SrcExprRaw, 1);
+ InitializationSequence InitSeq(Self, Entity, InitKind, SrcExprRaw);
// At this point of CheckStaticCast, if the destination is a reference,
// or the expression is an overload expression this has to work.
@@ -1452,7 +1452,7 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
DestType = Self.Context.getCanonicalType(DestType);
QualType SrcType = SrcExpr->getType();
if (const ReferenceType *DestTypeTmp =DestType->getAs<ReferenceType>()) {
- if (DestTypeTmp->isLValueReferenceType() && !SrcExpr->isLValue()) {
+ if (isa<LValueReferenceType>(DestTypeTmp) && !SrcExpr->isLValue()) {
// Cannot const_cast non-lvalue to lvalue reference type. But if this
// is C-style, static_cast might find a way, so we simply suggest a
// message and tell the parent to keep searching.
@@ -1460,6 +1460,16 @@ static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
return TC_NotApplicable;
}
+ // It's not completely clear under the standard whether we can
+ // const_cast bit-field gl-values. Doing so would not be
+ // intrinsically complicated, but for now, we say no for
+ // consistency with other compilers and await the word of the
+ // committee.
+ if (SrcExpr->refersToBitField()) {
+ msg = diag::err_bad_cxx_cast_bitfield;
+ return TC_NotApplicable;
+ }
+
// C++ 5.2.11p4: An lvalue of type T1 can be [cast] to an lvalue of type T2
// [...] if a pointer to T1 can be [cast] to the type pointer to T2.
DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp
index 65d42e1..7b5f4f0 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaChecking.cpp
@@ -586,12 +586,11 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
}
bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac,
- Expr **Args, unsigned NumArgs) {
+ ArrayRef<const Expr *> Args) {
VariadicCallType CallType =
Method->isVariadic() ? VariadicMethod : VariadicDoesNotApply;
- checkCall(Method, llvm::makeArrayRef<const Expr *>(Args, NumArgs),
- Method->param_size(),
+ checkCall(Method, Args, Method->param_size(),
/*IsMemberFunction=*/false,
lbrac, Method->getSourceRange(), CallType);
@@ -2009,7 +2008,7 @@ public:
PartialDiagnostic PDiag,
SourceLocation StringLoc,
bool IsStringLocation, Range StringRange,
- ArrayRef<FixItHint> Fixit = ArrayRef<FixItHint>());
+ ArrayRef<FixItHint> Fixit = None);
protected:
bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc,
@@ -2036,7 +2035,7 @@ protected:
template <typename Range>
void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
bool IsStringLocation, Range StringRange,
- ArrayRef<FixItHint> Fixit = ArrayRef<FixItHint>());
+ ArrayRef<FixItHint> Fixit = None);
void CheckPositionalAndNonpositionalArgs(
const analyze_format_string::FormatSpecifier *FS);
@@ -2778,6 +2777,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
return true;
QualType ExprTy = E->getType();
+ while (const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
+ ExprTy = TET->getUnderlyingExpr()->getType();
+ }
+
if (AT.matchesType(S.Context, ExprTy))
return true;
@@ -4342,7 +4345,7 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
IntRange::forValueOfType(C, E->getType());
}
- if (FieldDecl *BitField = E->getBitField())
+ if (FieldDecl *BitField = E->getSourceBitField())
return IntRange(BitField->getBitWidthValue(C),
BitField->getType()->isUnsignedIntegerOrEnumerationType());
@@ -4719,7 +4722,7 @@ static void AnalyzeAssignment(Sema &S, BinaryOperator *E) {
// We want to recurse on the RHS as normal unless we're assigning to
// a bitfield.
- if (FieldDecl *Bitfield = E->getLHS()->getBitField()) {
+ if (FieldDecl *Bitfield = E->getLHS()->getSourceBitField()) {
if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(),
E->getOperatorLoc())) {
// Recurse, ignoring any implicit conversions on the RHS.
@@ -5733,12 +5736,14 @@ bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd,
// notation in their sequences of declarator specifiers to specify
// variable length array types.
QualType PType = Param->getOriginalType();
- if (const ArrayType *AT = Context.getAsArrayType(PType)) {
+ while (const ArrayType *AT = Context.getAsArrayType(PType)) {
if (AT->getSizeModifier() == ArrayType::Star) {
// FIXME: This diagnostic should point the '[*]' if source-location
// information is added for it.
Diag(Param->getLocation(), diag::err_array_star_in_function_definition);
+ break;
}
+ PType= AT->getElementType();
}
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
index 2db1e2a..fd2ce17 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaCodeComplete.cpp
@@ -3348,13 +3348,12 @@ void Sema::CodeCompleteDeclSpec(Scope *S, DeclSpec &DS,
// be a receiver of a class message, this may be a class message send with
// the initial opening bracket '[' missing. Add appropriate completions.
if (AllowNonIdentifiers && !AllowNestedNameSpecifiers &&
+ DS.getParsedSpecifiers() == DeclSpec::PQ_TypeSpecifier &&
DS.getTypeSpecType() == DeclSpec::TST_typename &&
- DS.getStorageClassSpec() == DeclSpec::SCS_unspecified &&
- !DS.isThreadSpecified() && !DS.isExternInLinkageSpec() &&
DS.getTypeSpecComplex() == DeclSpec::TSC_unspecified &&
DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
- DS.getTypeQualifiers() == 0 &&
- S &&
+ !DS.isTypeAltiVecVector() &&
+ S &&
(S->getFlags() & Scope::DeclScope) != 0 &&
(S->getFlags() & (Scope::ClassScope | Scope::TemplateParamScope |
Scope::FunctionPrototypeScope |
@@ -5472,7 +5471,7 @@ static void AddClassMessageCompletions(Sema &SemaRef, Scope *S,
M != MEnd; ++M) {
for (ObjCMethodList *MethList = &M->second.second;
MethList && MethList->Method;
- MethList = MethList->Next) {
+ MethList = MethList->getNext()) {
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
continue;
@@ -5645,7 +5644,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, Expr *Receiver,
M != MEnd; ++M) {
for (ObjCMethodList *MethList = &M->second.first;
MethList && MethList->Method;
- MethList = MethList->Next) {
+ MethList = MethList->getNext()) {
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
continue;
@@ -7086,7 +7085,7 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
&M->second.second;
MethList && MethList->Method;
- MethList = MethList->Next) {
+ MethList = MethList->getNext()) {
if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
NumSelIdents))
continue;
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
index adf3505..e0e8bd6 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp
@@ -129,7 +129,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
///
/// If name lookup results in an ambiguity, this routine will complain
/// and then return NULL.
-ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec *SS,
bool isClassName, bool HasTrailingDot,
ParsedType ObjectTypePtr,
@@ -1219,7 +1219,10 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
return false;
} else {
// 'static inline' functions are used in headers; don't warn.
- if (FD->getStorageClass() == SC_Static &&
+ // Make sure we get the storage class from the canonical declaration,
+ // since otherwise we will get spurious warnings on specialized
+ // static template functions.
+ if (FD->getCanonicalDecl()->getStorageClass() == SC_Static &&
FD->isInlineSpecified())
return false;
}
@@ -1613,20 +1616,7 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,
if (!old->isHidden())
continue;
- // If either has no-external linkage, ignore the old declaration.
- // If this declaration would have external linkage if it were the first
- // declaration of this name, then it may in fact be a redeclaration of
- // some hidden declaration, so include those too. We don't need to worry
- // about some previous visible declaration giving this declaration external
- // linkage, because in that case, we'll mark this declaration as a redecl
- // of the visible decl, and that decl will already be a redecl of the
- // hidden declaration if that's appropriate.
- //
- // Don't cache this linkage computation, because it's not yet correct: we
- // may later give this declaration a previous declaration which changes
- // its linkage.
- if (old->getLinkage() != ExternalLinkage ||
- !decl->hasExternalLinkageUncached())
+ if (old->getLinkage() != ExternalLinkage)
filter.erase();
}
@@ -2256,11 +2246,9 @@ static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) {
return false;
LanguageLinkage OldLinkage = Old->getLanguageLinkage();
- if (OldLinkage == CXXLanguageLinkage &&
- New->getDeclContext()->isExternCContext())
+ if (OldLinkage == CXXLanguageLinkage && New->isInExternCContext())
return true;
- if (OldLinkage == CLanguageLinkage &&
- New->getDeclContext()->isExternCXXContext())
+ if (OldLinkage == CLanguageLinkage && New->isInExternCXXContext())
return true;
return false;
}
@@ -2451,12 +2439,22 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
// Certain function declarations cannot be overloaded:
// -- Function declarations that differ only in the return type
// cannot be overloaded.
- QualType OldReturnType = OldType->getResultType();
- QualType NewReturnType = cast<FunctionType>(NewQType)->getResultType();
+
+ // Go back to the type source info to compare the declared return types,
+ // per C++1y [dcl.type.auto]p??:
+ // 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 ResQT;
- if (OldReturnType != NewReturnType) {
- if (NewReturnType->isObjCObjectPointerType()
- && OldReturnType->isObjCObjectPointerType())
+ if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType)) {
+ if (NewDeclaredReturnType->isObjCObjectPointerType() &&
+ OldDeclaredReturnType->isObjCObjectPointerType())
ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
if (ResQT.isNull()) {
if (New->isCXXClassMember() && New->isOutOfLine())
@@ -2471,8 +2469,21 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
NewQType = ResQT;
}
- const CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
- CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
+ QualType OldReturnType = OldType->getResultType();
+ QualType NewReturnType = cast<FunctionType>(NewQType)->getResultType();
+ 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();
+ if (OldAT && OldAT->isDeduced()) {
+ New->setType(SubstAutoType(New->getType(), OldAT->getDeducedType()));
+ NewQType = Context.getCanonicalType(
+ SubstAutoType(NewQType, OldAT->getDeducedType()));
+ }
+ }
+
+ const CXXMethodDecl *OldMethod = dyn_cast<CXXMethodDecl>(Old);
+ CXXMethodDecl *NewMethod = dyn_cast<CXXMethodDecl>(New);
if (OldMethod && NewMethod) {
// Preserve triviality.
NewMethod->setTrivial(OldMethod->isTrivial());
@@ -2697,21 +2708,31 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
// Fall through to diagnose conflicting types.
}
- // A function that has already been declared has been redeclared or defined
- // with a different type- show appropriate diagnostic
- if (unsigned BuiltinID = Old->getBuiltinID()) {
- // The user has declared a builtin function with an incompatible
- // signature.
+ // A function that has already been declared has been redeclared or
+ // defined with a different type; show an appropriate diagnostic.
+
+ // If the previous declaration was an implicitly-generated builtin
+ // declaration, then at the very least we should use a specialized note.
+ unsigned BuiltinID;
+ if (Old->isImplicit() && (BuiltinID = Old->getBuiltinID())) {
+ // If it's actually a library-defined builtin function like 'malloc'
+ // or 'printf', just warn about the incompatible redeclaration.
if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) {
- // The function the user is redeclaring is a library-defined
- // function like 'malloc' or 'printf'. Warn about the
- // redeclaration, then pretend that we don't know about this
- // library built-in.
Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New;
Diag(Old->getLocation(), diag::note_previous_builtin_declaration)
<< Old << Old->getType();
- New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);
- Old->setInvalidDecl();
+
+ // If this is a global redeclaration, just forget hereafter
+ // about the "builtin-ness" of the function.
+ //
+ // Doing this for local extern declarations is problematic. If
+ // the builtin declaration remains visible, a second invalid
+ // local declaration will produce a hard error; if it doesn't
+ // remain visible, a single bogus local redeclaration (which is
+ // actually only a warning) could break all the downstream code.
+ if (!New->getDeclContext()->isFunctionOrMethod())
+ New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin);
+
return false;
}
@@ -2769,7 +2790,10 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,
ObjCMethodDecl *oldMethod) {
// Merge the attributes, including deprecated/unavailable
- mergeDeclAttributes(newMethod, oldMethod, AMK_Override);
+ AvailabilityMergeKind MergeKind =
+ isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration
+ : AMK_Override;
+ mergeDeclAttributes(newMethod, oldMethod, MergeKind);
// Merge attributes from the parameters.
ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(),
@@ -2795,8 +2819,7 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldWasHidden) {
QualType MergedT;
if (getLangOpts().CPlusPlus) {
- AutoType *AT = New->getType()->getContainedAutoType();
- if (AT && !AT->isDeduced()) {
+ if (New->getType()->isUndeducedType()) {
// We don't know what the new type is until the initializer is attached.
return;
} else if (Context.hasSameType(New->getType(), Old->getType())) {
@@ -2868,6 +2891,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
return New->setInvalidDecl();
}
+ if (!shouldLinkPossiblyHiddenDecl(Old, New))
+ return;
+
// C++ [class.mem]p1:
// A member shall not be declared twice in the member-specification [...]
//
@@ -2950,12 +2976,22 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
return New->setInvalidDecl();
}
- if (New->isThreadSpecified() && !Old->isThreadSpecified()) {
- Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
- } else if (!New->isThreadSpecified() && Old->isThreadSpecified()) {
- Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ 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);
+ } else if (!New->getTLSKind()) {
+ Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ } else {
+ // Do not allow redeclaration to change the variable between requiring
+ // static and dynamic initialization.
+ // FIXME: GCC allows this, but uses the TLS keyword on the first
+ // 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);
+ }
}
// C++ doesn't have tentative definitions, so go right ahead and check here.
@@ -3179,8 +3215,9 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
Diag(DS.getStorageClassSpecLoc(), DiagID)
<< DeclSpec::getSpecifierName(SCS);
- if (DS.isThreadSpecified())
- Diag(DS.getThreadSpecLoc(), DiagID) << "__thread";
+ if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec())
+ Diag(DS.getThreadStorageClassSpecLoc(), DiagID)
+ << DeclSpec::getSpecifierName(TSCS);
if (DS.getTypeQualifiers()) {
if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
Diag(DS.getConstSpecLoc(), DiagID) << "const";
@@ -3333,10 +3370,16 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
/// a VarDecl::StorageClass. Any error reporting is up to the caller:
/// illegal input values are mapped to SC_None.
static StorageClass
-StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
+StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS) {
+ DeclSpec::SCS StorageClassSpec = DS.getStorageClassSpec();
+ assert(StorageClassSpec != DeclSpec::SCS_typedef &&
+ "Parser allowed 'typedef' as storage class VarDecl.");
switch (StorageClassSpec) {
case DeclSpec::SCS_unspecified: return SC_None;
- case DeclSpec::SCS_extern: return SC_Extern;
+ case DeclSpec::SCS_extern:
+ if (DS.isExternInLinkageSpec())
+ return SC_None;
+ return SC_Extern;
case DeclSpec::SCS_static: return SC_Static;
case DeclSpec::SCS_auto: return SC_Auto;
case DeclSpec::SCS_register: return SC_Register;
@@ -3534,9 +3577,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
FieldCollector->Add(cast<FieldDecl>(Anon));
} else {
DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
- assert(SCSpec != DeclSpec::SCS_typedef &&
- "Parser allowed 'typedef' as storage class VarDecl.");
- VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
+ VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(DS);
if (SCSpec == DeclSpec::SCS_mutable) {
// mutable can only appear on non-static class members, so it's always
// an error here
@@ -4324,34 +4365,6 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
"Decl is not a locally-scoped decl!");
// Note that we have a locally-scoped external with this name.
LocallyScopedExternCDecls[ND->getDeclName()] = ND;
-
- if (!Previous.isSingleResult())
- return;
-
- NamedDecl *PrevDecl = Previous.getFoundDecl();
-
- // If there was a previous declaration of this entity, it may be in
- // our identifier chain. Update the identifier chain with the new
- // declaration.
- if (S && IdResolver.ReplaceDecl(PrevDecl, ND)) {
- // The previous declaration was found on the identifer resolver
- // chain, so remove it from its scope.
-
- if (S->isDeclScope(PrevDecl)) {
- // Special case for redeclarations in the SAME scope.
- // Because this declaration is going to be added to the identifier chain
- // later, we should temporarily take it OFF the chain.
- IdResolver.RemoveDecl(ND);
-
- } else {
- // Find the scope for the original declaration.
- while (S && !S->isDeclScope(PrevDecl))
- S = S->getParent();
- }
-
- if (S)
- S->RemoveDecl(PrevDecl);
- }
}
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator
@@ -4408,8 +4421,6 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
DiagnoseFunctionSpecifiers(D.getDeclSpec());
- if (D.getDeclSpec().isThreadSpecified())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
if (D.getDeclSpec().isConstexprSpecified())
Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)
<< 1;
@@ -4603,7 +4614,7 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
if (VarDecl *var = dyn_cast<VarDecl>(decl)) {
// Thread-local variables cannot have lifetime.
if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone &&
- var->isThreadSpecified()) {
+ var->getTLSKind()) {
Diag(var->getLocation(), diag::err_arc_thread_ownership)
<< var->getType();
return true;
@@ -4689,12 +4700,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
DeclarationName Name = GetNameForDeclarator(D).getName();
DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
- assert(SCSpec != DeclSpec::SCS_typedef &&
- "Parser allowed 'typedef' as storage class VarDecl.");
- VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
+ VarDecl::StorageClass SC =
+ StorageClassSpecToVarDeclStorageClass(D.getDeclSpec());
- if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16)
- {
+ 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()) {
@@ -4711,6 +4720,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
SC = SC_None;
}
+ // C++11 [dcl.stc]p4:
+ // When thread_local is applied to a variable of block scope the
+ // storage-class-specifier static is implied if it does not appear
+ // explicitly.
+ // Core issue: 'static' is not implied if the variable is declared 'extern'.
+ if (SCSpec == DeclSpec::SCS_unspecified &&
+ D.getDeclSpec().getThreadStorageClassSpec() ==
+ DeclSpec::TSCS_thread_local && DC->isFunctionOrMethod())
+ SC = SC_Static;
+
IdentifierInfo *II = Name.getAsIdentifierInfo();
if (!II) {
Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
@@ -4845,8 +4864,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// If this decl has an auto type in need of deduction, make a note of the
// Decl so we can diagnose uses of it in its own initializer.
- if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
- R->getContainedAutoType())
+ if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType())
ParsingInitForAutoVars.insert(NewVD);
if (D.isInvalidType() || Invalid)
@@ -4868,13 +4886,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// lexical context will be different from the semantic context.
NewVD->setLexicalDeclContext(CurContext);
- if (D.getDeclSpec().isThreadSpecified()) {
+ if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) {
if (NewVD->hasLocalStorage())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_thread_non_global)
+ << DeclSpec::getSpecifierName(TSCS);
else if (!Context.getTargetInfo().isTLSSupported())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_unsupported);
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_thread_unsupported);
else
- NewVD->setThreadSpecified(true);
+ NewVD->setTSCSpec(TSCS);
}
// C99 6.7.4p3
@@ -5130,7 +5151,7 @@ static bool mayConflictWithNonVisibleExternC(const T *ND) {
// This code runs before the init of foo is set, and therefore before
// the type of foo is known. Not knowing the type we cannot know its linkage
// unless it is in an extern C block.
- if (!DC->isExternCContext()) {
+ if (!ND->isInExternCContext()) {
const ASTContext &Context = ND->getASTContext();
if (Context.getLangOpts().CPlusPlus)
return false;
@@ -5139,27 +5160,18 @@ static bool mayConflictWithNonVisibleExternC(const T *ND) {
return ND->isExternC();
}
-/// \brief Perform semantic checking on a newly-created variable
-/// declaration.
-///
-/// This routine performs all of the type-checking required for a
-/// variable declaration once it has been built. It is used both to
-/// check variables after they have been parsed and their declarators
-/// have been translated into a declaration, and to check variables
-/// that have been instantiated from a template.
-///
-/// Sets NewVD->isInvalidDecl() if an error was encountered.
-///
-/// Returns true if the variable declaration is a redeclaration.
-bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
- LookupResult &Previous) {
+void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
// If the decl is already known invalid, don't check it.
if (NewVD->isInvalidDecl())
- return false;
+ return;
TypeSourceInfo *TInfo = NewVD->getTypeSourceInfo();
QualType T = TInfo->getType();
+ // Defer checking an 'auto' type until its initializer is attached.
+ if (T->isUndeducedType())
+ return;
+
if (T->isObjCObjectType()) {
Diag(NewVD->getLocation(), diag::err_statically_allocated_object)
<< FixItHint::CreateInsertion(NewVD->getLocation(), "*");
@@ -5174,16 +5186,26 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
if (NewVD->hasLocalStorage() && T.getAddressSpace() != 0) {
Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
NewVD->setInvalidDecl();
- return false;
+ return;
}
+ // OpenCL v1.2 s6.5 - All program scope variables must be declared in the
+ // __constant address space.
+ if (getLangOpts().OpenCL && NewVD->isFileVarDecl()
+ && T.getAddressSpace() != LangAS::opencl_constant
+ && !T->isSamplerT()){
+ Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space);
+ NewVD->setInvalidDecl();
+ return;
+ }
+
// OpenCL v1.2 s6.8 -- The static qualifier is valid only in program
// scope.
if ((getLangOpts().OpenCLVersion >= 120)
&& NewVD->isStaticLocal()) {
Diag(NewVD->getLocation(), diag::err_static_function_scope);
NewVD->setInvalidDecl();
- return false;
+ return;
}
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
@@ -5224,7 +5246,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
Diag(NewVD->getLocation(), diag::err_vla_decl_has_extern_linkage)
<< SizeRange;
NewVD->setInvalidDecl();
- return false;
+ return;
}
if (FixedTInfo == 0) {
@@ -5233,7 +5255,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
else
Diag(NewVD->getLocation(), diag::err_vm_decl_has_extern_linkage);
NewVD->setInvalidDecl();
- return false;
+ return;
}
Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size);
@@ -5241,6 +5263,54 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
NewVD->setTypeSourceInfo(FixedTInfo);
}
+ if (T->isVoidType() && NewVD->isThisDeclarationADefinition()) {
+ Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type)
+ << T;
+ NewVD->setInvalidDecl();
+ return;
+ }
+
+ if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
+ Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
+ NewVD->setInvalidDecl();
+ return;
+ }
+
+ if (isVM && NewVD->hasAttr<BlocksAttr>()) {
+ Diag(NewVD->getLocation(), diag::err_block_on_vm);
+ NewVD->setInvalidDecl();
+ return;
+ }
+
+ 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;
+ }
+}
+
+/// \brief Perform semantic checking on a newly-created variable
+/// declaration.
+///
+/// This routine performs all of the type-checking required for a
+/// variable declaration once it has been built. It is used both to
+/// check variables after they have been parsed and their declarators
+/// have been translated into a declaration, and to check variables
+/// that have been instantiated from a template.
+///
+/// Sets NewVD->isInvalidDecl() if an error was encountered.
+///
+/// Returns true if the variable declaration is a redeclaration.
+bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
+ LookupResult &Previous) {
+ CheckVariableDeclarationType(NewVD);
+
+ // If the decl is already known invalid, don't check it.
+ if (NewVD->isInvalidDecl())
+ return false;
+
// If we did not find anything by this name, look for a non-visible
// extern "C" declaration with the same name.
//
@@ -5279,32 +5349,6 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
// Filter out any non-conflicting previous declarations.
filterNonConflictingPreviousDecls(Context, NewVD, Previous);
- if (T->isVoidType() && !NewVD->hasExternalStorage()) {
- Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type)
- << T;
- NewVD->setInvalidDecl();
- return false;
- }
-
- if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
- Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
- NewVD->setInvalidDecl();
- return false;
- }
-
- if (isVM && NewVD->hasAttr<BlocksAttr>()) {
- Diag(NewVD->getLocation(), diag::err_block_on_vm);
- NewVD->setInvalidDecl();
- return false;
- }
-
- if (NewVD->isConstexpr() && !T->isDependentType() &&
- RequireLiteralType(NewVD->getLocation(), T,
- diag::err_constexpr_var_non_literal)) {
- NewVD->setInvalidDecl();
- return false;
- }
-
if (!Previous.empty()) {
MergeVarDecl(NewVD, Previous, PreviousWasHidden);
return true;
@@ -5631,7 +5675,10 @@ static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef,
D.setInvalidType();
break;
case DeclSpec::SCS_unspecified: break;
- case DeclSpec::SCS_extern: return SC_Extern;
+ case DeclSpec::SCS_extern:
+ if (D.getDeclSpec().isExternInLinkageSpec())
+ return SC_None;
+ return SC_Extern;
case DeclSpec::SCS_static: {
if (SemaRef.CurContext->getRedeclContext()->isFunctionOrMethod()) {
// C99 6.7.1p5:
@@ -5823,8 +5870,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
DeclarationName Name = NameInfo.getName();
FunctionDecl::StorageClass SC = getFunctionStorageClass(*this, D);
- if (D.getDeclSpec().isThreadSpecified())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+ if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_invalid_thread)
+ << DeclSpec::getSpecifierName(TSCS);
// Do not allow returning a objc interface by-value.
if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) {
@@ -6017,6 +6066,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Okay: Add virtual to the method.
NewFD->setVirtualAsWritten(true);
}
+
+ if (getLangOpts().CPlusPlus1y &&
+ NewFD->getResultType()->isUndeducedType())
+ Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual);
}
// C++ [dcl.fct.spec]p3:
@@ -6521,9 +6574,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
EPI.Variadic = true;
EPI.ExtInfo = FT->getExtInfo();
- QualType R = Context.getFunctionType(FT->getResultType(),
- ArrayRef<QualType>(),
- EPI);
+ QualType R = Context.getFunctionType(FT->getResultType(), None, EPI);
NewFD->setType(R);
}
@@ -6667,8 +6718,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// there's no more work to do here; we'll just add the new
// function to the scope.
if (!AllowOverloadingOfFunction(Previous, Context)) {
- Redeclaration = true;
- OldDecl = Previous.getFoundDecl();
+ NamedDecl *Candidate = Previous.getFoundDecl();
+ if (shouldLinkPossiblyHiddenDecl(Candidate, NewFD)) {
+ Redeclaration = true;
+ OldDecl = Candidate;
+ }
} else {
switch (CheckOverload(S, NewFD, Previous, OldDecl,
/*NewIsUsingDecl*/ false)) {
@@ -6710,9 +6764,12 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
//
// This needs to be delayed until we know whether this is an out-of-line
// definition of a static member function.
+ //
+ // This rule is not present in C++1y, so we produce a backwards
+ // compatibility warning whenever it happens in C++11.
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD);
- if (MD && MD->isConstexpr() && !MD->isStatic() &&
- !isa<CXXConstructorDecl>(MD) &&
+ 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 =
@@ -6727,6 +6784,18 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
ArrayRef<QualType>(FPT->arg_type_begin(),
FPT->getNumArgs()),
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.
+ if (ActiveTemplateInstantiations.empty()) {
+ SourceLocation AddConstLoc;
+ if (FunctionTypeLoc FTL = MD->getTypeSourceInfo()->getTypeLoc()
+ .IgnoreParens().getAs<FunctionTypeLoc>())
+ AddConstLoc = PP.getLocForEndOfToken(FTL.getRParenLoc());
+
+ Diag(MD->getLocation(), diag::warn_cxx1y_compat_constexpr_not_const)
+ << FixItHint::CreateInsertion(AddConstLoc, " const");
+ }
}
}
@@ -7164,7 +7233,7 @@ namespace {
return;
}
Inherited::VisitUnaryOperator(E);
- }
+ }
void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; }
@@ -7248,10 +7317,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
// C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
- AutoType *Auto = 0;
- if (TypeMayContainAuto &&
- (Auto = VDecl->getType()->getContainedAutoType()) &&
- !Auto->isDeduced()) {
+ if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) {
Expr *DeduceInit = Init;
// Initializer could be a C++ direct-initializer. Deduction only works if it
// contains exactly one expression.
@@ -7289,17 +7355,16 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
Init = Result.take();
DefaultedToAuto = true;
}
-
- TypeSourceInfo *DeducedType = 0;
+
+ QualType DeducedType;
if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) ==
DAR_Failed)
DiagnoseAutoDeductionFailure(VDecl, DeduceInit);
- if (!DeducedType) {
+ if (DeducedType.isNull()) {
RealDecl->setInvalidDecl();
return;
}
- VDecl->setTypeSourceInfo(DeducedType);
- VDecl->setType(DeducedType->getType());
+ VDecl->setType(DeducedType);
assert(VDecl->isLinkageValid());
// In ARC, infer lifetime.
@@ -7311,8 +7376,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// We only want to warn outside of template instantiations, though:
// inside a template, the 'id' could have come from a parameter.
if (ActiveTemplateInstantiations.empty() && !DefaultedToAuto &&
- DeducedType->getType()->isObjCIdType()) {
- SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc();
+ DeducedType->isObjCIdType()) {
+ SourceLocation Loc =
+ VDecl->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
Diag(Loc, diag::warn_auto_var_is_id)
<< VDecl->getDeclName() << DeduceInit->getSourceRange();
}
@@ -7321,6 +7387,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// the previously declared type.
if (VarDecl *Old = VDecl->getPreviousDecl())
MergeVarDeclTypes(VDecl, Old, /*OldWasHidden*/ false);
+
+ // Check the deduced type is valid for a variable declaration.
+ CheckVariableDeclarationType(VDecl);
+ if (VDecl->isInvalidDecl())
+ return;
}
if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) {
@@ -7426,15 +7497,13 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
: InitializationKind::CreateCopy(VDecl->getLocation(),
Init->getLocStart());
- Expr **Args = &Init;
- unsigned NumArgs = 1;
- if (CXXDirectInit) {
- Args = CXXDirectInit->getExprs();
- NumArgs = CXXDirectInit->getNumExprs();
- }
- InitializationSequence InitSeq(*this, Entity, Kind, Args, NumArgs);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(Args, NumArgs), &DclT);
+ MultiExprArg Args = Init;
+ if (CXXDirectInit)
+ Args = MultiExprArg(CXXDirectInit->getExprs(),
+ CXXDirectInit->getNumExprs());
+
+ InitializationSequence InitSeq(*this, Entity, Kind, Args);
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
if (Result.isInvalid()) {
VDecl->setInvalidDecl();
return;
@@ -7595,7 +7664,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
}
// Suggest adding 'constexpr' in C++11 for literal types.
- } else if (getLangOpts().CPlusPlus11 && DclT->isLiteralType()) {
+ } else if (getLangOpts().CPlusPlus11 && DclT->isLiteralType(Context)) {
Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type)
<< DclT << Init->getSourceRange()
<< FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
@@ -7616,6 +7685,19 @@ 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:
@@ -7870,9 +7952,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
InitializationKind Kind
= InitializationKind::CreateDefault(Var->getLocation());
-
- InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
- ExprResult Init = InitSeq.Perform(*this, Entity, Kind, MultiExprArg());
+
+ InitializationSequence InitSeq(*this, Entity, Kind, None);
+ ExprResult Init = InitSeq.Perform(*this, Entity, Kind, None);
if (Init.isInvalid())
Var->setInvalidDecl();
else if (Init.get()) {
@@ -7961,6 +8043,16 @@ 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);
+ }
+
// All the following checks are C++ only.
if (!getLangOpts().CPlusPlus) return;
@@ -8106,7 +8198,7 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
getASTContext().addUnnamedTag(Tag);
return BuildDeclaratorGroup(Decls.data(), Decls.size(),
- DS.getTypeSpecType() == DeclSpec::TST_auto);
+ DS.containsPlaceholderType());
}
/// BuildDeclaratorGroup - convert a list of declarations into a declaration
@@ -8131,8 +8223,8 @@ Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls,
// Don't reissue diagnostics when instantiating a template.
if (AT && D->isInvalidDecl())
break;
- if (AT && AT->isDeduced()) {
- QualType U = AT->getDeducedType();
+ QualType U = AT ? AT->getDeducedType() : QualType();
+ if (!U.isNull()) {
CanQualType UCanon = Context.getCanonicalType(U);
if (Deduced.isNull()) {
Deduced = U;
@@ -8141,6 +8233,7 @@ Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls,
} else if (DeducedCanon != UCanon) {
Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
diag::err_auto_different_deductions)
+ << (AT->isDecltypeAuto() ? 1 : 0)
<< Deduced << DeducedDecl->getDeclName()
<< U << D->getDeclName()
<< DeducedDecl->getInit()->getSourceRange()
@@ -8222,13 +8315,14 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
D.getMutableDeclSpec().ClearStorageClassSpecs();
}
- if (D.getDeclSpec().isThreadSpecified())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
- if (D.getDeclSpec().isConstexprSpecified())
- Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)
+ if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec())
+ Diag(DS.getThreadStorageClassSpecLoc(), diag::err_invalid_thread)
+ << DeclSpec::getSpecifierName(TSCS);
+ if (DS.isConstexprSpecified())
+ Diag(DS.getConstexprSpecLoc(), diag::err_invalid_constexpr)
<< 0;
- DiagnoseFunctionSpecifiers(D.getDeclSpec());
+ DiagnoseFunctionSpecifiers(DS);
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType parmDeclType = TInfo->getType();
@@ -8787,6 +8881,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
if (FD) {
FD->setBody(Body);
+ if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() &&
+ !FD->isDependentContext()) {
+ if (FD->getResultType()->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>()) {
+ Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto)
+ << FD->getResultType();
+ FD->setInvalidDecl();
+ }
+ Context.adjustDeducedFunctionResultType(FD, Context.VoidTy);
+ }
+ }
+
// The only way to be included in UndefinedButUsed is if there is an
// ODR use before the definition. Avoid the expensive map lookup if this
// is the first declaration.
@@ -10348,8 +10457,10 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
DiagnoseFunctionSpecifiers(D.getDeclSpec());
- if (D.getDeclSpec().isThreadSpecified())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+ if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_invalid_thread)
+ << DeclSpec::getSpecifierName(TSCS);
// Check to see if this name was declared as a member previously
NamedDecl *PrevDecl = 0;
@@ -10557,8 +10668,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
// FIXME: We need to pass in the attributes given an AST
// representation, not a parser representation.
if (D) {
- // FIXME: What to pass instead of TUScope?
- ProcessDeclAttributes(TUScope, NewFD, *D);
+ // FIXME: The current scope is almost... but not entirely... correct here.
+ ProcessDeclAttributes(getCurScope(), NewFD, *D);
if (NewFD->hasAttrs())
CheckAlignasUnderalignment(NewFD);
@@ -11497,8 +11608,8 @@ struct DenseMapInfoDupKey {
// Emits a warning when an element is implicitly set a value that
// a previous element has already been set to.
-static void CheckForDuplicateEnumValues(Sema &S, Decl **Elements,
- unsigned NumElements, EnumDecl *Enum,
+static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
+ EnumDecl *Enum,
QualType EnumType) {
if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values,
Enum->getLocation()) ==
@@ -11524,8 +11635,8 @@ static void CheckForDuplicateEnumValues(Sema &S, Decl **Elements,
// Populate the EnumMap with all values represented by enum constants without
// an initialier.
- for (unsigned i = 0; i < NumElements; ++i) {
- EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]);
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+ EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
// Null EnumConstantDecl means a previous diagnostic has been emitted for
// this constant. Skip this enum since it may be ill-formed.
@@ -11545,7 +11656,7 @@ static void CheckForDuplicateEnumValues(Sema &S, Decl **Elements,
}
// Create vectors for any values that has duplicates.
- for (unsigned i = 0; i < NumElements; ++i) {
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]);
if (!ValidDuplicateEnum(ECD, Enum))
continue;
@@ -11609,7 +11720,7 @@ static void CheckForDuplicateEnumValues(Sema &S, Decl **Elements,
void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
SourceLocation RBraceLoc, Decl *EnumDeclX,
- Decl **Elements, unsigned NumElements,
+ ArrayRef<Decl *> Elements,
Scope *S, AttributeList *Attr) {
EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
QualType EnumType = Context.getTypeDeclType(Enum);
@@ -11618,7 +11729,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
ProcessDeclAttributeList(S, Enum, Attr);
if (Enum->isDependentType()) {
- for (unsigned i = 0; i != NumElements; ++i) {
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
EnumConstantDecl *ECD =
cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue;
@@ -11645,7 +11756,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
// Keep track of whether all elements have type int.
bool AllElementsInt = true;
- for (unsigned i = 0; i != NumElements; ++i) {
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
EnumConstantDecl *ECD =
cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue; // Already issued a diagnostic.
@@ -11762,7 +11873,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
// Loop over all of the enumerator constants, changing their types to match
// the type of the enum if needed.
- for (unsigned i = 0; i != NumElements; ++i) {
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
if (!ECD) continue; // Already issued a diagnostic.
@@ -11830,7 +11941,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
if (InFunctionDeclarator)
DeclsInPrototypeScope.push_back(Enum);
- CheckForDuplicateEnumValues(*this, Elements, NumElements, Enum, EnumType);
+ CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
// Now that the enum type is defined, ensure it's not been underaligned.
if (Enum->hasAttrs())
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
index 982e7a5..7b3345a 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
@@ -284,7 +284,7 @@ static bool mayBeSharedVariable(const Decl *D) {
if (isa<FieldDecl>(D))
return true;
if (const VarDecl *vd = dyn_cast<VarDecl>(D))
- return (vd->hasGlobalStorage() && !(vd->isThreadSpecified()));
+ return vd->hasGlobalStorage() && !vd->getTLSKind();
return false;
}
@@ -709,7 +709,7 @@ static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
// Check that all arguments are lockable objects.
checkAttrArgsAreLockableObjs(S, D, Attr, Args);
- if (Args.size() == 0)
+ if (Args.empty())
return false;
return true;
@@ -858,7 +858,7 @@ static bool checkLocksRequiredCommon(Sema &S, Decl *D,
// check that all arguments are lockable objects
checkAttrArgsAreLockableObjs(S, D, Attr, Args);
- if (Args.size() == 0)
+ if (Args.empty())
return false;
return true;
@@ -1656,7 +1656,7 @@ static void handleTLSModelAttr(Sema &S, Decl *D,
return;
}
- if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->isThreadSpecified()) {
+ if (!isa<VarDecl>(D) || !cast<VarDecl>(D)->getTLSKind()) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
<< Attr.getName() << ExpectedTLSVar;
return;
@@ -2246,8 +2246,11 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(NamedDecl *D, SourceRange Range,
MergedObsoleted == Obsoleted)
return NULL;
+ // Only create a new attribute if !Override, but we want to do
+ // the checking.
if (!checkAvailabilityAttr(*this, Range, Platform, MergedIntroduced,
- MergedDeprecated, MergedObsoleted)) {
+ MergedDeprecated, MergedObsoleted) &&
+ !Override) {
return ::new (Context) AvailabilityAttr(Range, Context, Platform,
Introduced, Deprecated,
Obsoleted, IsUnavailable, Message,
@@ -4886,6 +4889,7 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
break;
// Microsoft attributes:
+ case AttributeList::AT_MsProperty: break;
case AttributeList::AT_MsStruct:
handleMsStructAttr(S, D, Attr);
break;
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
index 35890e6..e6a131a 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp
@@ -65,6 +65,7 @@ namespace {
bool VisitDeclRefExpr(DeclRefExpr *DRE);
bool VisitCXXThisExpr(CXXThisExpr *ThisE);
bool VisitLambdaExpr(LambdaExpr *Lambda);
+ bool VisitPseudoObjectExpr(PseudoObjectExpr *POE);
};
/// VisitExpr - Visit all of the children of this expression.
@@ -115,6 +116,23 @@ namespace {
<< ThisE->getSourceRange();
}
+ bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
+ bool Invalid = false;
+ for (PseudoObjectExpr::semantics_iterator
+ i = POE->semantics_begin(), e = POE->semantics_end(); i != e; ++i) {
+ Expr *E = *i;
+
+ // Look through bindings.
+ if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
+ E = OVE->getSourceExpr();
+ assert(E && "pseudo-object binding without source expression?");
+ }
+
+ Invalid |= Visit(E);
+ }
+ return Invalid;
+ }
+
bool CheckDefaultArgumentVisitor::VisitLambdaExpr(LambdaExpr *Lambda) {
// C++11 [expr.lambda.prim]p13:
// A lambda-expression appearing in a default argument shall not
@@ -127,8 +145,9 @@ namespace {
}
}
-void Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
- CXXMethodDecl *Method) {
+void
+Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
+ const CXXMethodDecl *Method) {
// If we have an MSAny spec already, don't bother.
if (!Method || ComputedEST == EST_MSAny)
return;
@@ -246,7 +265,7 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
Param);
InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(),
EqualLoc);
- InitializationSequence InitSeq(*this, Entity, Kind, &Arg, 1);
+ InitializationSequence InitSeq(*this, Entity, Kind, Arg);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Arg);
if (Result.isInvalid())
return true;
@@ -614,25 +633,11 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
unsigned NumParams = FD->getNumParams();
unsigned p;
- bool IsLambda = FD->getOverloadedOperator() == OO_Call &&
- isa<CXXMethodDecl>(FD) &&
- cast<CXXMethodDecl>(FD)->getParent()->isLambda();
-
// Find first parameter with a default argument
for (p = 0; p < NumParams; ++p) {
ParmVarDecl *Param = FD->getParamDecl(p);
- if (Param->hasDefaultArg()) {
- // C++11 [expr.prim.lambda]p5:
- // [...] Default arguments (8.3.6) shall not be specified in the
- // parameter-declaration-clause of a lambda-declarator.
- //
- // FIXME: Core issue 974 strikes this sentence, we only provide an
- // extension warning.
- if (IsLambda)
- Diag(Param->getLocation(), diag::ext_lambda_default_arguments)
- << Param->getDefaultArgRange();
+ if (Param->hasDefaultArg())
break;
- }
}
// C++ [dcl.fct.default]p4:
@@ -770,12 +775,13 @@ bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) {
}
/// Check the given declaration statement is legal within a constexpr function
-/// body. C++0x [dcl.constexpr]p3,p4.
+/// body. C++11 [dcl.constexpr]p3,p4, and C++1y [dcl.constexpr]p3.
///
-/// \return true if the body is OK, false if we have diagnosed a problem.
+/// \return true if the body is OK (maybe only as an extension), false if we
+/// have diagnosed a problem.
static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,
- DeclStmt *DS) {
- // C++0x [dcl.constexpr]p3 and p4:
+ DeclStmt *DS, SourceLocation &Cxx1yLoc) {
+ // C++11 [dcl.constexpr]p3 and p4:
// The definition of a constexpr function(p3) or constructor(p4) [...] shall
// contain only
for (DeclStmt::decl_iterator DclIt = DS->decl_begin(),
@@ -786,6 +792,7 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,
case Decl::UsingShadow:
case Decl::UsingDirective:
case Decl::UnresolvedUsingTypename:
+ case Decl::UnresolvedUsingValue:
// - static_assert-declarations
// - using-declarations,
// - using-directives,
@@ -809,20 +816,63 @@ static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl,
case Decl::Enum:
case Decl::CXXRecord:
- // As an extension, we allow the declaration (but not the definition) of
- // classes and enumerations in all declarations, not just in typedef and
- // alias declarations.
- if (cast<TagDecl>(*DclIt)->isThisDeclarationADefinition()) {
- SemaRef.Diag(DS->getLocStart(), diag::err_constexpr_type_definition)
+ // C++1y allows types to be defined, not just declared.
+ if (cast<TagDecl>(*DclIt)->isThisDeclarationADefinition())
+ SemaRef.Diag(DS->getLocStart(),
+ SemaRef.getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_constexpr_type_definition
+ : diag::ext_constexpr_type_definition)
<< isa<CXXConstructorDecl>(Dcl);
- return false;
- }
continue;
- case Decl::Var:
- SemaRef.Diag(DS->getLocStart(), diag::err_constexpr_var_declaration)
+ case Decl::EnumConstant:
+ case Decl::IndirectField:
+ case Decl::ParmVar:
+ // These can only appear with other declarations which are banned in
+ // C++11 and permitted in C++1y, so ignore them.
+ continue;
+
+ case Decl::Var: {
+ // C++1y [dcl.constexpr]p3 allows anything except:
+ // a definition of a variable of non-literal type or of static or
+ // thread storage duration or for which no initialization is performed.
+ VarDecl *VD = cast<VarDecl>(*DclIt);
+ if (VD->isThisDeclarationADefinition()) {
+ if (VD->isStaticLocal()) {
+ SemaRef.Diag(VD->getLocation(),
+ diag::err_constexpr_local_var_static)
+ << isa<CXXConstructorDecl>(Dcl)
+ << (VD->getTLSKind() == VarDecl::TLS_Dynamic);
+ return false;
+ }
+ if (!VD->getType()->isDependentType() &&
+ SemaRef.RequireLiteralType(
+ VD->getLocation(), VD->getType(),
+ diag::err_constexpr_local_var_non_literal_type,
+ isa<CXXConstructorDecl>(Dcl)))
+ return false;
+ if (!VD->hasInit()) {
+ SemaRef.Diag(VD->getLocation(),
+ diag::err_constexpr_local_var_no_init)
+ << isa<CXXConstructorDecl>(Dcl);
+ return false;
+ }
+ }
+ SemaRef.Diag(VD->getLocation(),
+ SemaRef.getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_constexpr_local_var
+ : diag::ext_constexpr_local_var)
<< isa<CXXConstructorDecl>(Dcl);
- return false;
+ continue;
+ }
+
+ case Decl::NamespaceAlias:
+ case Decl::Function:
+ // These are disallowed in C++11 and permitted in C++1y. Allow them
+ // everywhere as an extension.
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = DS->getLocStart();
+ continue;
default:
SemaRef.Diag(DS->getLocStart(), diag::err_constexpr_body_invalid_stmt)
@@ -871,6 +921,124 @@ static void CheckConstexprCtorInitializer(Sema &SemaRef,
}
}
+/// Check the provided statement is allowed in a constexpr function
+/// definition.
+static bool
+CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
+ llvm::SmallVectorImpl<SourceLocation> &ReturnStmts,
+ SourceLocation &Cxx1yLoc) {
+ // - its function-body shall be [...] a compound-statement that contains only
+ switch (S->getStmtClass()) {
+ case Stmt::NullStmtClass:
+ // - null statements,
+ return true;
+
+ case Stmt::DeclStmtClass:
+ // - static_assert-declarations
+ // - using-declarations,
+ // - using-directives,
+ // - typedef declarations and alias-declarations that do not define
+ // classes or enumerations,
+ if (!CheckConstexprDeclStmt(SemaRef, Dcl, cast<DeclStmt>(S), Cxx1yLoc))
+ return false;
+ return true;
+
+ case Stmt::ReturnStmtClass:
+ // - and exactly one return statement;
+ if (isa<CXXConstructorDecl>(Dcl)) {
+ // C++1y allows return statements in constexpr constructors.
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+ return true;
+ }
+
+ ReturnStmts.push_back(S->getLocStart());
+ return true;
+
+ case Stmt::CompoundStmtClass: {
+ // C++1y allows compound-statements.
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+
+ CompoundStmt *CompStmt = cast<CompoundStmt>(S);
+ for (CompoundStmt::body_iterator BodyIt = CompStmt->body_begin(),
+ BodyEnd = CompStmt->body_end(); BodyIt != BodyEnd; ++BodyIt) {
+ if (!CheckConstexprFunctionStmt(SemaRef, Dcl, *BodyIt, ReturnStmts,
+ Cxx1yLoc))
+ return false;
+ }
+ return true;
+ }
+
+ case Stmt::AttributedStmtClass:
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+ return true;
+
+ case Stmt::IfStmtClass: {
+ // C++1y allows if-statements.
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+
+ IfStmt *If = cast<IfStmt>(S);
+ if (!CheckConstexprFunctionStmt(SemaRef, Dcl, If->getThen(), ReturnStmts,
+ Cxx1yLoc))
+ return false;
+ if (If->getElse() &&
+ !CheckConstexprFunctionStmt(SemaRef, Dcl, If->getElse(), ReturnStmts,
+ Cxx1yLoc))
+ return false;
+ return true;
+ }
+
+ case Stmt::WhileStmtClass:
+ case Stmt::DoStmtClass:
+ case Stmt::ForStmtClass:
+ case Stmt::CXXForRangeStmtClass:
+ case Stmt::ContinueStmtClass:
+ // C++1y allows all of these. We don't allow them as extensions in C++11,
+ // because they don't make sense without variable mutation.
+ if (!SemaRef.getLangOpts().CPlusPlus1y)
+ break;
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+ for (Stmt::child_range Children = S->children(); Children; ++Children)
+ if (*Children &&
+ !CheckConstexprFunctionStmt(SemaRef, Dcl, *Children, ReturnStmts,
+ Cxx1yLoc))
+ return false;
+ return true;
+
+ case Stmt::SwitchStmtClass:
+ case Stmt::CaseStmtClass:
+ case Stmt::DefaultStmtClass:
+ case Stmt::BreakStmtClass:
+ // C++1y allows switch-statements, and since they don't need variable
+ // mutation, we can reasonably allow them in C++11 as an extension.
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+ for (Stmt::child_range Children = S->children(); Children; ++Children)
+ if (*Children &&
+ !CheckConstexprFunctionStmt(SemaRef, Dcl, *Children, ReturnStmts,
+ Cxx1yLoc))
+ return false;
+ return true;
+
+ default:
+ if (!isa<Expr>(S))
+ break;
+
+ // C++1y allows expression-statements.
+ if (!Cxx1yLoc.isValid())
+ Cxx1yLoc = S->getLocStart();
+ return true;
+ }
+
+ SemaRef.Diag(S->getLocStart(), diag::err_constexpr_body_invalid_stmt)
+ << isa<CXXConstructorDecl>(Dcl);
+ return false;
+}
+
/// Check the body for the given constexpr function declaration only contains
/// the permitted types of statement. C++11 [dcl.constexpr]p3,p4.
///
@@ -891,43 +1059,24 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
return false;
}
+ SmallVector<SourceLocation, 4> ReturnStmts;
+
// - its function-body shall be [...] a compound-statement that contains only
+ // [... list of cases ...]
CompoundStmt *CompBody = cast<CompoundStmt>(Body);
-
- SmallVector<SourceLocation, 4> ReturnStmts;
+ SourceLocation Cxx1yLoc;
for (CompoundStmt::body_iterator BodyIt = CompBody->body_begin(),
BodyEnd = CompBody->body_end(); BodyIt != BodyEnd; ++BodyIt) {
- switch ((*BodyIt)->getStmtClass()) {
- case Stmt::NullStmtClass:
- // - null statements,
- continue;
-
- case Stmt::DeclStmtClass:
- // - static_assert-declarations
- // - using-declarations,
- // - using-directives,
- // - typedef declarations and alias-declarations that do not define
- // classes or enumerations,
- if (!CheckConstexprDeclStmt(*this, Dcl, cast<DeclStmt>(*BodyIt)))
- return false;
- continue;
-
- case Stmt::ReturnStmtClass:
- // - and exactly one return statement;
- if (isa<CXXConstructorDecl>(Dcl))
- break;
-
- ReturnStmts.push_back((*BodyIt)->getLocStart());
- continue;
-
- default:
- break;
- }
+ if (!CheckConstexprFunctionStmt(*this, Dcl, *BodyIt, ReturnStmts, Cxx1yLoc))
+ return false;
+ }
- Diag((*BodyIt)->getLocStart(), diag::err_constexpr_body_invalid_stmt)
+ if (Cxx1yLoc.isValid())
+ Diag(Cxx1yLoc,
+ getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_constexpr_body_invalid_stmt
+ : diag::ext_constexpr_body_invalid_stmt)
<< isa<CXXConstructorDecl>(Dcl);
- return false;
- }
if (const CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(Dcl)) {
@@ -983,14 +1132,23 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
}
} else {
if (ReturnStmts.empty()) {
- Diag(Dcl->getLocation(), diag::err_constexpr_body_no_return);
- return false;
+ // C++1y doesn't require constexpr functions to contain a 'return'
+ // statement. We still do, unless the return type is void, because
+ // otherwise if there's no return statement, the function cannot
+ // be used in a core constant expression.
+ bool OK = getLangOpts().CPlusPlus1y && Dcl->getResultType()->isVoidType();
+ Diag(Dcl->getLocation(),
+ OK ? diag::warn_cxx11_compat_constexpr_body_no_return
+ : diag::err_constexpr_body_no_return);
+ return OK;
}
if (ReturnStmts.size() > 1) {
- Diag(ReturnStmts.back(), diag::err_constexpr_body_multiple_return);
+ Diag(ReturnStmts.back(),
+ getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_constexpr_body_multiple_return
+ : diag::ext_constexpr_body_multiple_return);
for (unsigned I = 0; I < ReturnStmts.size() - 1; ++I)
Diag(ReturnStmts[I], diag::note_constexpr_body_previous_return);
- return false;
}
}
@@ -1584,6 +1742,13 @@ static bool InitializationHasSideEffects(const FieldDecl &FD) {
return false;
}
+static AttributeList *getMSPropertyAttr(AttributeList *list) {
+ for (AttributeList* it = list; it != 0; it = it->getNext())
+ if (it->isDeclspecPropertyAttribute())
+ return it;
+ return 0;
+}
+
/// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
/// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
/// bitfield width if there is one, 'InitExpr' specifies the initializer if
@@ -1660,30 +1825,24 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
// data members and cannot be applied to names declared const or static,
// and cannot be applied to reference members.
switch (DS.getStorageClassSpec()) {
- case DeclSpec::SCS_unspecified:
- case DeclSpec::SCS_typedef:
- case DeclSpec::SCS_static:
- // FALL THROUGH.
- break;
- case DeclSpec::SCS_mutable:
- if (isFunc) {
- if (DS.getStorageClassSpecLoc().isValid())
- Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_function);
- else
- Diag(DS.getThreadSpecLoc(), diag::err_mutable_function);
+ case DeclSpec::SCS_unspecified:
+ case DeclSpec::SCS_typedef:
+ case DeclSpec::SCS_static:
+ break;
+ case DeclSpec::SCS_mutable:
+ if (isFunc) {
+ Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_function);
- // FIXME: It would be nicer if the keyword was ignored only for this
- // declarator. Otherwise we could get follow-up errors.
- D.getMutableDeclSpec().ClearStorageClassSpecs();
- }
- break;
- default:
- if (DS.getStorageClassSpecLoc().isValid())
- Diag(DS.getStorageClassSpecLoc(),
- diag::err_storageclass_invalid_for_member);
- else
- Diag(DS.getThreadSpecLoc(), diag::err_storageclass_invalid_for_member);
+ // FIXME: It would be nicer if the keyword was ignored only for this
+ // declarator. Otherwise we could get follow-up errors.
D.getMutableDeclSpec().ClearStorageClassSpecs();
+ }
+ break;
+ default:
+ Diag(DS.getStorageClassSpecLoc(),
+ diag::err_storageclass_invalid_for_member);
+ D.getMutableDeclSpec().ClearStorageClassSpecs();
+ break;
}
bool isInstField = ((DS.getStorageClassSpec() == DeclSpec::SCS_unspecified ||
@@ -1769,8 +1928,16 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
SS.clear();
}
- Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
- InitStyle, AS);
+ AttributeList *MSPropertyAttr =
+ getMSPropertyAttr(D.getDeclSpec().getAttributes().getList());
+ if (MSPropertyAttr) {
+ Member = HandleMSProperty(S, cast<CXXRecordDecl>(CurContext), Loc, D,
+ BitWidth, InitStyle, AS, MSPropertyAttr);
+ isInstField = false;
+ } else {
+ Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D,
+ BitWidth, InitStyle, AS);
+ }
assert(Member && "HandleField never returns null");
} else {
assert(InitStyle == ICIS_NoInit || D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static);
@@ -1990,14 +2157,12 @@ Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation InitLoc,
Diag(FD->getLocation(), diag::warn_dangling_std_initializer_list)
<< /*at end of ctor*/1 << InitExpr->getSourceRange();
}
- Expr **Inits = &InitExpr;
- unsigned NumInits = 1;
InitializedEntity Entity = InitializedEntity::InitializeMember(FD);
InitializationKind Kind = FD->getInClassInitStyle() == ICIS_ListInit
? InitializationKind::CreateDirectList(InitExpr->getLocStart())
: InitializationKind::CreateCopy(InitExpr->getLocStart(), InitLoc);
- InitializationSequence Seq(*this, Entity, Kind, Inits, NumInits);
- Init = Seq.Perform(*this, Entity, Kind, MultiExprArg(Inits, NumInits));
+ InitializationSequence Seq(*this, Entity, Kind, InitExpr);
+ Init = Seq.Perform(*this, Entity, Kind, InitExpr);
if (Init.isInvalid()) {
FD->setInvalidDecl();
return;
@@ -2360,23 +2525,19 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
// foo(foo)
// where foo is not also a parameter to the constructor.
// TODO: implement -Wuninitialized and fold this into that framework.
- Expr **Args;
- unsigned NumArgs;
+ MultiExprArg Args;
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
- Args = ParenList->getExprs();
- NumArgs = ParenList->getNumExprs();
+ Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
} else if (InitListExpr *InitList = dyn_cast<InitListExpr>(Init)) {
- Args = InitList->getInits();
- NumArgs = InitList->getNumInits();
+ Args = MultiExprArg(InitList->getInits(), InitList->getNumInits());
} else {
// Template instantiation doesn't reconstruct ParenListExprs for us.
- Args = &Init;
- NumArgs = 1;
+ Args = Init;
}
if (getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit, IdLoc)
!= DiagnosticsEngine::Ignored)
- for (unsigned i = 0; i < NumArgs; ++i)
+ for (unsigned i = 0, e = Args.size(); i != e; ++i)
// FIXME: Warn about the case when other fields are used before being
// initialized. For example, let this field be the i'th field. When
// initializing the i'th field, throw a warning if any of the >= i'th
@@ -2397,8 +2558,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
bool InitList = false;
if (isa<InitListExpr>(Init)) {
InitList = true;
- Args = &Init;
- NumArgs = 1;
+ Args = Init;
if (isStdInitializerList(Member->getType(), 0)) {
Diag(IdLoc, diag::warn_dangling_std_initializer_list)
@@ -2415,10 +2575,8 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
: InitializationKind::CreateDirect(IdLoc, InitRange.getBegin(),
InitRange.getEnd());
- InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
- ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind,
- MultiExprArg(Args, NumArgs),
- 0);
+ InitializationSequence InitSeq(*this, MemberEntity, Kind, Args);
+ ExprResult MemberInit = InitSeq.Perform(*this, MemberEntity, Kind, Args, 0);
if (MemberInit.isInvalid())
return true;
@@ -2454,12 +2612,10 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
bool InitList = true;
- Expr **Args = &Init;
- unsigned NumArgs = 1;
+ MultiExprArg Args = Init;
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
InitList = false;
- Args = ParenList->getExprs();
- NumArgs = ParenList->getNumExprs();
+ Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
}
SourceRange InitRange = Init->getSourceRange();
@@ -2470,10 +2626,9 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
InitList ? InitializationKind::CreateDirectList(NameLoc)
: InitializationKind::CreateDirect(NameLoc, InitRange.getBegin(),
InitRange.getEnd());
- InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args, NumArgs);
+ InitializationSequence InitSeq(*this, DelegationEntity, Kind, Args);
ExprResult DelegationInit = InitSeq.Perform(*this, DelegationEntity, Kind,
- MultiExprArg(Args, NumArgs),
- 0);
+ Args, 0);
if (DelegationInit.isInvalid())
return true;
@@ -2593,12 +2748,10 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
// Initialize the base.
bool InitList = true;
- Expr **Args = &Init;
- unsigned NumArgs = 1;
+ MultiExprArg Args = Init;
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
InitList = false;
- Args = ParenList->getExprs();
- NumArgs = ParenList->getNumExprs();
+ Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
}
InitializedEntity BaseEntity =
@@ -2607,9 +2760,8 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
InitList ? InitializationKind::CreateDirectList(BaseLoc)
: InitializationKind::CreateDirect(BaseLoc, InitRange.getBegin(),
InitRange.getEnd());
- InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
- ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind,
- MultiExprArg(Args, NumArgs), 0);
+ InitializationSequence InitSeq(*this, BaseEntity, Kind, Args);
+ ExprResult BaseInit = InitSeq.Perform(*this, BaseEntity, Kind, Args, 0);
if (BaseInit.isInvalid())
return true;
@@ -2695,8 +2847,7 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
InitializationKind InitKind = InitializationKind::CreateDirect(
Constructor->getLocation(), SourceLocation(), SourceLocation());
- InitializationSequence InitSeq(SemaRef, InitEntity, InitKind,
- Args.data(), Args.size());
+ InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, Args);
BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, Args);
break;
}
@@ -2705,8 +2856,8 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
case IIK_Default: {
InitializationKind InitKind
= InitializationKind::CreateDefault(Constructor->getLocation());
- InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
- BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, MultiExprArg());
+ InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, None);
+ BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, None);
break;
}
@@ -2743,10 +2894,8 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
InitializationKind InitKind
= InitializationKind::CreateDirect(Constructor->getLocation(),
SourceLocation(), SourceLocation());
- InitializationSequence InitSeq(SemaRef, InitEntity, InitKind,
- &CopyCtorArg, 1);
- BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
- MultiExprArg(&CopyCtorArg, 1));
+ InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, CopyCtorArg);
+ BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, CopyCtorArg);
break;
}
}
@@ -2897,8 +3046,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation());
Expr *CtorArgE = CtorArg.takeAs<Expr>();
- InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind,
- &CtorArgE, 1);
+ InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, CtorArgE);
ExprResult MemberInit
= InitSeq.Perform(SemaRef, Entities.back(), InitKind,
@@ -2936,10 +3084,10 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
: InitializedEntity::InitializeMember(Field);
InitializationKind InitKind =
InitializationKind::CreateDefault(Loc);
-
- InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
- ExprResult MemberInit =
- InitSeq.Perform(SemaRef, InitEntity, InitKind, MultiExprArg());
+
+ InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, None);
+ ExprResult MemberInit =
+ InitSeq.Perform(SemaRef, InitEntity, InitKind, None);
MemberInit = SemaRef.MaybeCreateExprWithCleanups(MemberInit);
if (MemberInit.isInvalid())
@@ -3040,7 +3188,7 @@ struct BaseAndFieldInfo {
AllToInit.push_back(Init);
// Check whether this initializer makes the field "used".
- if (Init->getInit() && Init->getInit()->HasSideEffects(S.Context))
+ if (Init->getInit()->HasSideEffects(S.Context))
S.UnusedPrivateFields.remove(Init->getAnyMember());
return false;
@@ -3089,16 +3237,18 @@ static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info,
// has a brace-or-equal-initializer, the entity is initialized as specified
// in [dcl.init].
if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) {
+ Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,
+ Info.Ctor->getLocation(), Field);
CXXCtorInitializer *Init;
if (Indirect)
Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect,
SourceLocation(),
- SourceLocation(), 0,
+ SourceLocation(), DIE,
SourceLocation());
else
Init = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field,
SourceLocation(),
- SourceLocation(), 0,
+ SourceLocation(), DIE,
SourceLocation());
return Info.addFieldInitializer(Init);
}
@@ -4226,9 +4376,8 @@ updateExceptionSpec(Sema &S, FunctionDecl *FD, const FunctionProtoType *FPT,
const Sema::ImplicitExceptionSpecification &ExceptSpec) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
ExceptSpec.getEPI(EPI);
- const FunctionProtoType *NewFPT = cast<FunctionProtoType>(
- S.Context.getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI));
- FD->setType(QualType(NewFPT, 0));
+ FD->setType(S.Context.getFunctionType(FPT->getResultType(),
+ FPT->getArgTypes(), EPI));
}
void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) {
@@ -4427,7 +4576,7 @@ void Sema::CheckExplicitlyDefaultedMemberExceptionSpec(
FunctionProtoType::ExtProtoInfo EPI;
computeImplicitExceptionSpec(*this, MD->getLocation(), MD).getEPI(EPI);
const FunctionProtoType *ImplicitType = cast<FunctionProtoType>(
- Context.getFunctionType(Context.VoidTy, ArrayRef<QualType>(), EPI));
+ Context.getFunctionType(Context.VoidTy, None, EPI));
// Ensure that it matches.
CheckEquivalentExceptionSpec(
@@ -5409,8 +5558,10 @@ void Sema::DiagnoseHiddenVirtualMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
for (unsigned i = 0, e = Data.OverloadedMethods.size(); i != e; ++i) {
CXXMethodDecl *overloadedMD = Data.OverloadedMethods[i];
- Diag(overloadedMD->getLocation(),
+ PartialDiagnostic PD = PDiag(
diag::note_hidden_overloaded_virtual_declared_here) << overloadedMD;
+ HandleFunctionTypeMismatch(PD, MD->getType(), overloadedMD->getType());
+ Diag(overloadedMD->getLocation(), PD);
}
}
}
@@ -5860,7 +6011,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
EPI.Variadic = false;
EPI.TypeQuals = 0;
EPI.RefQualifier = RQ_None;
- return Context.getFunctionType(Context.VoidTy, ArrayRef<QualType>(), EPI);
+ return Context.getFunctionType(Context.VoidTy, None, EPI);
}
/// CheckConversionDeclarator - Called by ActOnDeclarator to check the
@@ -5941,8 +6092,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
// of the errors above fired) and with the conversion type as the
// return type.
if (D.isInvalidType())
- R = Context.getFunctionType(ConvType, ArrayRef<QualType>(),
- Proto->getExtProtoInfo());
+ R = Context.getFunctionType(ConvType, None, Proto->getExtProtoInfo());
// C++0x explicit conversion operators.
if (D.getDeclSpec().isExplicitSpecified())
@@ -7503,9 +7653,73 @@ Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
}
Sema::ImplicitExceptionSpecification
-Sema::ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD) {
+Sema::ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD) {
+ CXXRecordDecl *ClassDecl = CD->getParent();
+
+ // C++ [except.spec]p14:
+ // An inheriting constructor [...] shall have an exception-specification. [...]
ImplicitExceptionSpecification ExceptSpec(*this);
- // FIXME: Compute the exception spec.
+ if (ClassDecl->isInvalidDecl())
+ return ExceptSpec;
+
+ // Inherited constructor.
+ const CXXConstructorDecl *InheritedCD = CD->getInheritedConstructor();
+ const CXXRecordDecl *InheritedDecl = InheritedCD->getParent();
+ // FIXME: Copying or moving the parameters could add extra exceptions to the
+ // set, as could the default arguments for the inherited constructor. This
+ // will be addressed when we implement the resolution of core issue 1351.
+ ExceptSpec.CalledDecl(CD->getLocStart(), InheritedCD);
+
+ // Direct base-class constructors.
+ for (CXXRecordDecl::base_class_iterator B = ClassDecl->bases_begin(),
+ BEnd = ClassDecl->bases_end();
+ B != BEnd; ++B) {
+ if (B->isVirtual()) // Handled below.
+ continue;
+
+ if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+ CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+ if (BaseClassDecl == InheritedDecl)
+ continue;
+ CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
+ if (Constructor)
+ ExceptSpec.CalledDecl(B->getLocStart(), Constructor);
+ }
+ }
+
+ // Virtual base-class constructors.
+ for (CXXRecordDecl::base_class_iterator B = ClassDecl->vbases_begin(),
+ BEnd = ClassDecl->vbases_end();
+ B != BEnd; ++B) {
+ if (const RecordType *BaseType = B->getType()->getAs<RecordType>()) {
+ CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+ if (BaseClassDecl == InheritedDecl)
+ continue;
+ CXXConstructorDecl *Constructor = LookupDefaultConstructor(BaseClassDecl);
+ if (Constructor)
+ ExceptSpec.CalledDecl(B->getLocStart(), Constructor);
+ }
+ }
+
+ // Field constructors.
+ for (RecordDecl::field_iterator F = ClassDecl->field_begin(),
+ FEnd = ClassDecl->field_end();
+ F != FEnd; ++F) {
+ if (F->hasInClassInitializer()) {
+ if (Expr *E = F->getInClassInitializer())
+ ExceptSpec.CalledExpr(E);
+ else if (!F->isInvalidDecl())
+ Diag(CD->getLocation(),
+ diag::err_in_class_initializer_references_def_ctor) << CD;
+ } else if (const RecordType *RecordTy
+ = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
+ CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
+ CXXConstructorDecl *Constructor = LookupDefaultConstructor(FieldRecDecl);
+ if (Constructor)
+ ExceptSpec.CalledDecl(F->getLocation(), Constructor);
+ }
+ }
+
return ExceptSpec;
}
@@ -7577,9 +7791,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
FunctionProtoType::ExtProtoInfo EPI;
EPI.ExceptionSpecType = EST_Unevaluated;
EPI.ExceptionSpecDecl = DefaultCon;
- DefaultCon->setType(Context.getFunctionType(Context.VoidTy,
- ArrayRef<QualType>(),
- EPI));
+ DefaultCon->setType(Context.getFunctionType(Context.VoidTy, None, EPI));
// We don't need to use SpecialMemberIsTrivial here; triviality for default
// constructors is easy to compute.
@@ -7635,208 +7847,308 @@ void Sema::ActOnFinishDelayedMemberInitializers(Decl *D) {
CheckDelayedExplicitlyDefaultedMemberExceptionSpecs();
}
-void Sema::DeclareInheritingConstructors(CXXRecordDecl *ClassDecl) {
- // We start with an initial pass over the base classes to collect those that
- // inherit constructors from. If there are none, we can forgo all further
- // processing.
- typedef SmallVector<const RecordType *, 4> BasesVector;
- BasesVector BasesToInheritFrom;
- for (CXXRecordDecl::base_class_iterator BaseIt = ClassDecl->bases_begin(),
- BaseE = ClassDecl->bases_end();
- BaseIt != BaseE; ++BaseIt) {
- if (BaseIt->getInheritConstructors()) {
- QualType Base = BaseIt->getType();
- if (Base->isDependentType()) {
- // If we inherit constructors from anything that is dependent, just
- // abort processing altogether. We'll get another chance for the
- // instantiations.
- // FIXME: We need to ensure that any call to a constructor of this class
- // is considered instantiation-dependent in this case.
- return;
+namespace {
+/// Information on inheriting constructors to declare.
+class InheritingConstructorInfo {
+public:
+ InheritingConstructorInfo(Sema &SemaRef, CXXRecordDecl *Derived)
+ : SemaRef(SemaRef), Derived(Derived) {
+ // Mark the constructors that we already have in the derived class.
+ //
+ // C++11 [class.inhctor]p3: [...] a constructor is implicitly declared [...]
+ // unless there is a user-declared constructor with the same signature in
+ // the class where the using-declaration appears.
+ visitAll(Derived, &InheritingConstructorInfo::noteDeclaredInDerived);
+ }
+
+ void inheritAll(CXXRecordDecl *RD) {
+ visitAll(RD, &InheritingConstructorInfo::inherit);
+ }
+
+private:
+ /// Information about an inheriting constructor.
+ struct InheritingConstructor {
+ InheritingConstructor()
+ : DeclaredInDerived(false), BaseCtor(0), DerivedCtor(0) {}
+
+ /// If \c true, a constructor with this signature is already declared
+ /// in the derived class.
+ bool DeclaredInDerived;
+
+ /// The constructor which is inherited.
+ const CXXConstructorDecl *BaseCtor;
+
+ /// The derived constructor we declared.
+ CXXConstructorDecl *DerivedCtor;
+ };
+
+ /// Inheriting constructors with a given canonical type. There can be at
+ /// most one such non-template constructor, and any number of templated
+ /// constructors.
+ struct InheritingConstructorsForType {
+ InheritingConstructor NonTemplate;
+ llvm::SmallVector<
+ std::pair<TemplateParameterList*, InheritingConstructor>, 4> Templates;
+
+ InheritingConstructor &getEntry(Sema &S, const CXXConstructorDecl *Ctor) {
+ if (FunctionTemplateDecl *FTD = Ctor->getDescribedFunctionTemplate()) {
+ TemplateParameterList *ParamList = FTD->getTemplateParameters();
+ for (unsigned I = 0, N = Templates.size(); I != N; ++I)
+ if (S.TemplateParameterListsAreEqual(ParamList, Templates[I].first,
+ false, S.TPL_TemplateMatch))
+ return Templates[I].second;
+ Templates.push_back(std::make_pair(ParamList, InheritingConstructor()));
+ return Templates.back().second;
}
- BasesToInheritFrom.push_back(Base->castAs<RecordType>());
+
+ return NonTemplate;
}
+ };
+
+ /// Get or create the inheriting constructor record for a constructor.
+ InheritingConstructor &getEntry(const CXXConstructorDecl *Ctor,
+ QualType CtorType) {
+ return Map[CtorType.getCanonicalType()->castAs<FunctionProtoType>()]
+ .getEntry(SemaRef, Ctor);
}
- if (BasesToInheritFrom.empty())
- return;
- // FIXME: Constructor templates.
-
- // Now collect the constructors that we already have in the current class.
- // Those take precedence over inherited constructors.
- // C++11 [class.inhctor]p3: [...] a constructor is implicitly declared [...]
- // unless there is a user-declared constructor with the same signature in
- // the class where the using-declaration appears.
- llvm::SmallSet<const Type *, 8> ExistingConstructors;
- for (CXXRecordDecl::ctor_iterator CtorIt = ClassDecl->ctor_begin(),
- CtorE = ClassDecl->ctor_end();
- CtorIt != CtorE; ++CtorIt)
- ExistingConstructors.insert(
- Context.getCanonicalType(CtorIt->getType()).getTypePtr());
-
- DeclarationName CreatedCtorName =
- Context.DeclarationNames.getCXXConstructorName(
- ClassDecl->getTypeForDecl()->getCanonicalTypeUnqualified());
-
- // Now comes the true work.
- // First, we keep a map from constructor types to the base that introduced
- // them. Needed for finding conflicting constructors. We also keep the
- // actually inserted declarations in there, for pretty diagnostics.
- typedef std::pair<CanQualType, CXXConstructorDecl *> ConstructorInfo;
- typedef llvm::DenseMap<const Type *, ConstructorInfo> ConstructorToSourceMap;
- ConstructorToSourceMap InheritedConstructors;
- for (BasesVector::iterator BaseIt = BasesToInheritFrom.begin(),
- BaseE = BasesToInheritFrom.end();
- BaseIt != BaseE; ++BaseIt) {
- const RecordType *Base = *BaseIt;
- CanQualType CanonicalBase = Base->getCanonicalTypeUnqualified();
- CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(Base->getDecl());
- for (CXXRecordDecl::ctor_iterator CtorIt = BaseDecl->ctor_begin(),
- CtorE = BaseDecl->ctor_end();
- CtorIt != CtorE; ++CtorIt) {
- // Find the using declaration for inheriting this base's constructors.
- // FIXME: Don't perform name lookup just to obtain a source location!
- DeclarationName Name =
- Context.DeclarationNames.getCXXConstructorName(CanonicalBase);
- LookupResult Result(*this, Name, SourceLocation(), LookupUsingDeclName);
- LookupQualifiedName(Result, CurContext);
- UsingDecl *UD = Result.getAsSingle<UsingDecl>();
- SourceLocation UsingLoc = UD ? UD->getLocation() :
- ClassDecl->getLocation();
-
- // C++11 [class.inhctor]p1:
- // The candidate set of inherited constructors from the class X named in
- // the using-declaration consists of actual constructors and notional
- // constructors that result from the transformation of defaulted
- // parameters as follows:
- // - all non-template constructors of X, and
- // - for each non-template constructor of X that has at least one
- // parameter with a default argument, the set of constructors that
- // results from omitting any ellipsis parameter specification and
- // successively omitting parameters with a default argument from the
- // end of the parameter-type-list, and
- // FIXME: ...also constructor templates.
- CXXConstructorDecl *BaseCtor = *CtorIt;
- bool CanBeCopyOrMove = BaseCtor->isCopyOrMoveConstructor();
- const FunctionProtoType *BaseCtorType =
- BaseCtor->getType()->getAs<FunctionProtoType>();
-
- // Determine whether this would be a copy or move constructor for the
- // derived class.
- if (BaseCtorType->getNumArgs() >= 1 &&
- BaseCtorType->getArgType(0)->isReferenceType() &&
- Context.hasSameUnqualifiedType(
- BaseCtorType->getArgType(0)->getPointeeType(),
- Context.getTagDeclType(ClassDecl)))
- CanBeCopyOrMove = true;
-
- ArrayRef<QualType> ArgTypes(BaseCtorType->getArgTypes());
- FunctionProtoType::ExtProtoInfo EPI = BaseCtorType->getExtProtoInfo();
- // Core issue (no number yet): the ellipsis is always discarded.
- if (EPI.Variadic) {
- Diag(UsingLoc, diag::warn_using_decl_constructor_ellipsis);
- Diag(BaseCtor->getLocation(),
- diag::note_using_decl_constructor_ellipsis);
- EPI.Variadic = false;
- }
+ typedef void (InheritingConstructorInfo::*VisitFn)(const CXXConstructorDecl*);
- for (unsigned Params = BaseCtor->getMinRequiredArguments(),
- MaxParams = BaseCtor->getNumParams();
- Params <= MaxParams; ++Params) {
- // Skip default constructors. They're never inherited.
- if (Params == 0)
- continue;
+ /// Process all constructors for a class.
+ void visitAll(const CXXRecordDecl *RD, VisitFn Callback) {
+ for (CXXRecordDecl::ctor_iterator CtorIt = RD->ctor_begin(),
+ CtorE = RD->ctor_end();
+ CtorIt != CtorE; ++CtorIt)
+ (this->*Callback)(*CtorIt);
+ for (CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl>
+ I(RD->decls_begin()), E(RD->decls_end());
+ I != E; ++I) {
+ const FunctionDecl *FD = (*I)->getTemplatedDecl();
+ if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD))
+ (this->*Callback)(CD);
+ }
+ }
- // Skip copy and move constructors for both base and derived class
- // for the same reason.
- if (CanBeCopyOrMove && Params == 1)
- continue;
+ /// Note that a constructor (or constructor template) was declared in Derived.
+ void noteDeclaredInDerived(const CXXConstructorDecl *Ctor) {
+ getEntry(Ctor, Ctor->getType()).DeclaredInDerived = true;
+ }
- // Build up a function type for this particular constructor.
- QualType NewCtorType =
- Context.getFunctionType(Context.VoidTy, ArgTypes.slice(0, Params),
- EPI);
- const Type *CanonicalNewCtorType =
- Context.getCanonicalType(NewCtorType).getTypePtr();
-
- // C++11 [class.inhctor]p3:
- // ... a constructor is implicitly declared with the same constructor
- // characteristics unless there is a user-declared constructor with
- // the same signature in the class where the using-declaration appears
- if (ExistingConstructors.count(CanonicalNewCtorType))
- continue;
+ /// Inherit a single constructor.
+ void inherit(const CXXConstructorDecl *Ctor) {
+ const FunctionProtoType *CtorType =
+ Ctor->getType()->castAs<FunctionProtoType>();
+ ArrayRef<QualType> ArgTypes(CtorType->getArgTypes());
+ FunctionProtoType::ExtProtoInfo EPI = CtorType->getExtProtoInfo();
- // C++11 [class.inhctor]p7:
- // If two using-declarations declare inheriting constructors with the
- // same signature, the program is ill-formed
- std::pair<ConstructorToSourceMap::iterator, bool> result =
- InheritedConstructors.insert(std::make_pair(
- CanonicalNewCtorType,
- std::make_pair(CanonicalBase, (CXXConstructorDecl*)0)));
- if (!result.second) {
- // Already in the map. If it came from a different class, that's an
- // error. Not if it's from the same.
- CanQualType PreviousBase = result.first->second.first;
- if (CanonicalBase != PreviousBase) {
- const CXXConstructorDecl *PrevCtor = result.first->second.second;
- const CXXConstructorDecl *PrevBaseCtor =
- PrevCtor->getInheritedConstructor();
- assert(PrevBaseCtor && "Conflicting constructor was not inherited");
-
- Diag(UsingLoc, diag::err_using_decl_constructor_conflict);
- Diag(BaseCtor->getLocation(),
- diag::note_using_decl_constructor_conflict_current_ctor);
- Diag(PrevBaseCtor->getLocation(),
- diag::note_using_decl_constructor_conflict_previous_ctor);
- Diag(PrevCtor->getLocation(),
- diag::note_using_decl_constructor_conflict_previous_using);
- } else {
- // Core issue (no number): if the same inheriting constructor is
- // produced by multiple base class constructors from the same base
- // class, the inheriting constructor is defined as deleted.
- SetDeclDeleted(result.first->second.second, UsingLoc);
- }
- continue;
- }
+ SourceLocation UsingLoc = getUsingLoc(Ctor->getParent());
- // OK, we're there, now add the constructor.
- DeclarationNameInfo DNI(CreatedCtorName, UsingLoc);
- CXXConstructorDecl *NewCtor = CXXConstructorDecl::Create(
- Context, ClassDecl, UsingLoc, DNI, NewCtorType,
- /*TInfo=*/0, BaseCtor->isExplicit(), /*Inline=*/true,
- /*ImplicitlyDeclared=*/true, /*Constexpr=*/BaseCtor->isConstexpr());
- NewCtor->setAccess(BaseCtor->getAccess());
-
- // Build an unevaluated exception specification for this constructor.
- EPI.ExceptionSpecType = EST_Unevaluated;
- EPI.ExceptionSpecDecl = NewCtor;
- NewCtor->setType(Context.getFunctionType(Context.VoidTy,
- ArgTypes.slice(0, Params),
- EPI));
-
- // Build up the parameter decls and add them.
- SmallVector<ParmVarDecl *, 16> ParamDecls;
- for (unsigned i = 0; i < Params; ++i) {
- ParmVarDecl *PD = ParmVarDecl::Create(Context, NewCtor,
- UsingLoc, UsingLoc,
- /*IdentifierInfo=*/0,
- BaseCtorType->getArgType(i),
- /*TInfo=*/0, SC_None,
- /*DefaultArg=*/0);
- PD->setScopeInfo(0, i);
- PD->setImplicit();
- ParamDecls.push_back(PD);
- }
- NewCtor->setParams(ParamDecls);
- NewCtor->setInheritedConstructor(BaseCtor);
- if (BaseCtor->isDeleted())
- SetDeclDeleted(NewCtor, UsingLoc);
+ // Core issue (no number yet): the ellipsis is always discarded.
+ if (EPI.Variadic) {
+ SemaRef.Diag(UsingLoc, diag::warn_using_decl_constructor_ellipsis);
+ SemaRef.Diag(Ctor->getLocation(),
+ diag::note_using_decl_constructor_ellipsis);
+ EPI.Variadic = false;
+ }
- ClassDecl->addDecl(NewCtor);
- result.first->second.second = NewCtor;
+ // Declare a constructor for each number of parameters.
+ //
+ // C++11 [class.inhctor]p1:
+ // The candidate set of inherited constructors from the class X named in
+ // the using-declaration consists of [... modulo defects ...] for each
+ // constructor or constructor template of X, the set of constructors or
+ // constructor templates that results from omitting any ellipsis parameter
+ // specification and successively omitting parameters with a default
+ // argument from the end of the parameter-type-list
+ unsigned MinParams = minParamsToInherit(Ctor);
+ unsigned Params = Ctor->getNumParams();
+ if (Params >= MinParams) {
+ do
+ declareCtor(UsingLoc, Ctor,
+ SemaRef.Context.getFunctionType(
+ Ctor->getResultType(), ArgTypes.slice(0, Params), EPI));
+ while (Params > MinParams &&
+ Ctor->getParamDecl(--Params)->hasDefaultArg());
+ }
+ }
+
+ /// Find the using-declaration which specified that we should inherit the
+ /// constructors of \p Base.
+ SourceLocation getUsingLoc(const CXXRecordDecl *Base) {
+ // No fancy lookup required; just look for the base constructor name
+ // directly within the derived class.
+ ASTContext &Context = SemaRef.Context;
+ DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(Context.getRecordType(Base)));
+ DeclContext::lookup_const_result Decls = Derived->lookup(Name);
+ return Decls.empty() ? Derived->getLocation() : Decls[0]->getLocation();
+ }
+
+ unsigned minParamsToInherit(const CXXConstructorDecl *Ctor) {
+ // C++11 [class.inhctor]p3:
+ // [F]or each constructor template in the candidate set of inherited
+ // constructors, a constructor template is implicitly declared
+ if (Ctor->getDescribedFunctionTemplate())
+ return 0;
+
+ // For each non-template constructor in the candidate set of inherited
+ // constructors other than a constructor having no parameters or a
+ // copy/move constructor having a single parameter, a constructor is
+ // implicitly declared [...]
+ if (Ctor->getNumParams() == 0)
+ return 1;
+ if (Ctor->isCopyOrMoveConstructor())
+ return 2;
+
+ // Per discussion on core reflector, never inherit a constructor which
+ // would become a default, copy, or move constructor of Derived either.
+ const ParmVarDecl *PD = Ctor->getParamDecl(0);
+ const ReferenceType *RT = PD->getType()->getAs<ReferenceType>();
+ return (RT && RT->getPointeeCXXRecordDecl() == Derived) ? 2 : 1;
+ }
+
+ /// Declare a single inheriting constructor, inheriting the specified
+ /// constructor, with the given type.
+ void declareCtor(SourceLocation UsingLoc, const CXXConstructorDecl *BaseCtor,
+ QualType DerivedType) {
+ InheritingConstructor &Entry = getEntry(BaseCtor, DerivedType);
+
+ // C++11 [class.inhctor]p3:
+ // ... a constructor is implicitly declared with the same constructor
+ // characteristics unless there is a user-declared constructor with
+ // the same signature in the class where the using-declaration appears
+ if (Entry.DeclaredInDerived)
+ return;
+
+ // C++11 [class.inhctor]p7:
+ // If two using-declarations declare inheriting constructors with the
+ // same signature, the program is ill-formed
+ if (Entry.DerivedCtor) {
+ if (BaseCtor->getParent() != Entry.BaseCtor->getParent()) {
+ // Only diagnose this once per constructor.
+ if (Entry.DerivedCtor->isInvalidDecl())
+ return;
+ Entry.DerivedCtor->setInvalidDecl();
+
+ SemaRef.Diag(UsingLoc, diag::err_using_decl_constructor_conflict);
+ SemaRef.Diag(BaseCtor->getLocation(),
+ diag::note_using_decl_constructor_conflict_current_ctor);
+ SemaRef.Diag(Entry.BaseCtor->getLocation(),
+ diag::note_using_decl_constructor_conflict_previous_ctor);
+ SemaRef.Diag(Entry.DerivedCtor->getLocation(),
+ diag::note_using_decl_constructor_conflict_previous_using);
+ } else {
+ // Core issue (no number): if the same inheriting constructor is
+ // produced by multiple base class constructors from the same base
+ // class, the inheriting constructor is defined as deleted.
+ SemaRef.SetDeclDeleted(Entry.DerivedCtor, UsingLoc);
}
+
+ return;
}
+
+ ASTContext &Context = SemaRef.Context;
+ DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(Context.getRecordType(Derived)));
+ DeclarationNameInfo NameInfo(Name, UsingLoc);
+
+ TemplateParameterList *TemplateParams = 0;
+ if (const FunctionTemplateDecl *FTD =
+ BaseCtor->getDescribedFunctionTemplate()) {
+ TemplateParams = FTD->getTemplateParameters();
+ // We're reusing template parameters from a different DeclContext. This
+ // is questionable at best, but works out because the template depth in
+ // both places is guaranteed to be 0.
+ // FIXME: Rebuild the template parameters in the new context, and
+ // transform the function type to refer to them.
+ }
+
+ // Build type source info pointing at the using-declaration. This is
+ // required by template instantiation.
+ TypeSourceInfo *TInfo =
+ Context.getTrivialTypeSourceInfo(DerivedType, UsingLoc);
+ FunctionProtoTypeLoc ProtoLoc =
+ TInfo->getTypeLoc().IgnoreParens().castAs<FunctionProtoTypeLoc>();
+
+ CXXConstructorDecl *DerivedCtor = CXXConstructorDecl::Create(
+ Context, Derived, UsingLoc, NameInfo, DerivedType,
+ TInfo, BaseCtor->isExplicit(), /*Inline=*/true,
+ /*ImplicitlyDeclared=*/true, /*Constexpr=*/BaseCtor->isConstexpr());
+
+ // Build an unevaluated exception specification for this constructor.
+ const FunctionProtoType *FPT = DerivedType->castAs<FunctionProtoType>();
+ FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+ EPI.ExceptionSpecType = EST_Unevaluated;
+ EPI.ExceptionSpecDecl = DerivedCtor;
+ DerivedCtor->setType(Context.getFunctionType(FPT->getResultType(),
+ FPT->getArgTypes(), EPI));
+
+ // Build the parameter declarations.
+ SmallVector<ParmVarDecl *, 16> ParamDecls;
+ for (unsigned I = 0, N = FPT->getNumArgs(); I != N; ++I) {
+ TypeSourceInfo *TInfo =
+ Context.getTrivialTypeSourceInfo(FPT->getArgType(I), UsingLoc);
+ ParmVarDecl *PD = ParmVarDecl::Create(
+ Context, DerivedCtor, UsingLoc, UsingLoc, /*IdentifierInfo=*/0,
+ FPT->getArgType(I), TInfo, SC_None, /*DefaultArg=*/0);
+ PD->setScopeInfo(0, I);
+ PD->setImplicit();
+ ParamDecls.push_back(PD);
+ ProtoLoc.setArg(I, PD);
+ }
+
+ // Set up the new constructor.
+ DerivedCtor->setAccess(BaseCtor->getAccess());
+ DerivedCtor->setParams(ParamDecls);
+ DerivedCtor->setInheritedConstructor(BaseCtor);
+ if (BaseCtor->isDeleted())
+ SemaRef.SetDeclDeleted(DerivedCtor, UsingLoc);
+
+ // If this is a constructor template, build the template declaration.
+ if (TemplateParams) {
+ FunctionTemplateDecl *DerivedTemplate =
+ FunctionTemplateDecl::Create(SemaRef.Context, Derived, UsingLoc, Name,
+ TemplateParams, DerivedCtor);
+ DerivedTemplate->setAccess(BaseCtor->getAccess());
+ DerivedCtor->setDescribedFunctionTemplate(DerivedTemplate);
+ Derived->addDecl(DerivedTemplate);
+ } else {
+ Derived->addDecl(DerivedCtor);
+ }
+
+ Entry.BaseCtor = BaseCtor;
+ Entry.DerivedCtor = DerivedCtor;
}
+
+ Sema &SemaRef;
+ CXXRecordDecl *Derived;
+ typedef llvm::DenseMap<const Type *, InheritingConstructorsForType> MapType;
+ MapType Map;
+};
+}
+
+void Sema::DeclareInheritingConstructors(CXXRecordDecl *ClassDecl) {
+ // Defer declaring the inheriting constructors until the class is
+ // instantiated.
+ if (ClassDecl->isDependentContext())
+ return;
+
+ // Find base classes from which we might inherit constructors.
+ SmallVector<CXXRecordDecl*, 4> InheritedBases;
+ for (CXXRecordDecl::base_class_iterator BaseIt = ClassDecl->bases_begin(),
+ BaseE = ClassDecl->bases_end();
+ BaseIt != BaseE; ++BaseIt)
+ if (BaseIt->getInheritConstructors())
+ InheritedBases.push_back(BaseIt->getType()->getAsCXXRecordDecl());
+
+ // Go no further if we're not inheriting any constructors.
+ if (InheritedBases.empty())
+ return;
+
+ // Declare the inherited constructors.
+ InheritingConstructorInfo ICI(*this, ClassDecl);
+ for (unsigned I = 0, N = InheritedBases.size(); I != N; ++I)
+ ICI.inheritAll(InheritedBases[I]);
}
void Sema::DefineInheritingConstructor(SourceLocation CurrentLocation,
@@ -7943,9 +8255,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
FunctionProtoType::ExtProtoInfo EPI;
EPI.ExceptionSpecType = EST_Unevaluated;
EPI.ExceptionSpecDecl = Destructor;
- Destructor->setType(Context.getFunctionType(Context.VoidTy,
- ArrayRef<QualType>(),
- EPI));
+ Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI));
AddOverriddenMethods(ClassDecl, Destructor);
@@ -8049,9 +8359,7 @@ void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
FunctionProtoType::ExtProtoInfo EPI = DtorType->getExtProtoInfo();
EPI.ExceptionSpecType = EST_Unevaluated;
EPI.ExceptionSpecDecl = Destructor;
- Destructor->setType(Context.getFunctionType(Context.VoidTy,
- ArrayRef<QualType>(),
- EPI));
+ Destructor->setType(Context.getFunctionType(Context.VoidTy, None, EPI));
// FIXME: If the destructor has a body that could throw, and the newly created
// spec doesn't allow exceptions, we should emit a warning, because this
@@ -10174,7 +10482,8 @@ Decl *Sema::ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc,
// FIXME: Add all the various semantics of linkage specifications
LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext,
- ExternLoc, LangLoc, Language);
+ ExternLoc, LangLoc, Language,
+ LBraceLoc.isValid());
CurContext->addDecl(D);
PushDeclContext(S, D);
return D;
@@ -10307,9 +10616,8 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S,
Expr *opaqueValue =
new (Context) OpaqueValueExpr(Loc, initType, VK_LValue, OK_Ordinary);
- InitializationSequence sequence(*this, entity, initKind, &opaqueValue, 1);
- ExprResult result = sequence.Perform(*this, entity, initKind,
- MultiExprArg(&opaqueValue, 1));
+ InitializationSequence sequence(*this, entity, initKind, opaqueValue);
+ ExprResult result = sequence.Perform(*this, entity, initKind, opaqueValue);
if (result.isInvalid())
Invalid = true;
else {
@@ -10798,29 +11106,39 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
// Find the appropriate context according to the above.
DC = CurContext;
+
+ // Skip class contexts. If someone can cite chapter and verse
+ // for this behavior, that would be nice --- it's what GCC and
+ // EDG do, and it seems like a reasonable intent, but the spec
+ // really only says that checks for unqualified existing
+ // declarations should stop at the nearest enclosing namespace,
+ // not that they should only consider the nearest enclosing
+ // namespace.
+ while (DC->isRecord())
+ DC = DC->getParent();
+
+ DeclContext *LookupDC = DC;
+ while (LookupDC->isTransparentContext())
+ LookupDC = LookupDC->getParent();
+
while (true) {
- // Skip class contexts. If someone can cite chapter and verse
- // for this behavior, that would be nice --- it's what GCC and
- // EDG do, and it seems like a reasonable intent, but the spec
- // really only says that checks for unqualified existing
- // declarations should stop at the nearest enclosing namespace,
- // not that they should only consider the nearest enclosing
- // namespace.
- while (DC->isRecord() || DC->isTransparentContext())
- DC = DC->getParent();
-
- LookupQualifiedName(Previous, DC);
+ LookupQualifiedName(Previous, LookupDC);
// TODO: decide what we think about using declarations.
- if (isLocal || !Previous.empty())
+ if (isLocal)
+ break;
+
+ if (!Previous.empty()) {
+ DC = LookupDC;
break;
+ }
if (isTemplateId) {
- if (isa<TranslationUnitDecl>(DC)) break;
+ if (isa<TranslationUnitDecl>(LookupDC)) break;
} else {
- if (DC->isFileContext()) break;
+ if (LookupDC->isFileContext()) break;
}
- DC = DC->getParent();
+ LookupDC = LookupDC->getParent();
}
DCScope = getScopeForDeclContext(S, DC);
@@ -11373,8 +11691,7 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
// Ignore any vtable uses in unevaluated operands or for classes that do
// not have a vtable.
if (!Class->isDynamicClass() || Class->isDependentContext() ||
- CurContext->isDependentContext() ||
- ExprEvalContexts.back().Context == Unevaluated)
+ CurContext->isDependentContext() || isUnevaluatedContext())
return;
// Try to insert this class into the map.
@@ -11562,10 +11879,10 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field);
InitializationKind InitKind =
InitializationKind::CreateDefault(ObjCImplementation->getLocation());
-
- InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0);
- ExprResult MemberInit =
- InitSeq.Perform(*this, InitEntity, InitKind, MultiExprArg());
+
+ InitializationSequence InitSeq(*this, InitEntity, InitKind, None);
+ ExprResult MemberInit =
+ InitSeq.Perform(*this, InitEntity, InitKind, None);
MemberInit = MaybeCreateExprWithCleanups(MemberInit);
// Note, MemberInit could actually come back empty if no initialization
// is required (e.g., because it would call a trivial default constructor)
@@ -11921,3 +12238,94 @@ bool Sema::CheckCUDATarget(CUDAFunctionTarget CallerTarget,
return false;
}
+
+/// HandleMSProperty - Analyze a __delcspec(property) field of a C++ class.
+///
+MSPropertyDecl *Sema::HandleMSProperty(Scope *S, RecordDecl *Record,
+ SourceLocation DeclStart,
+ Declarator &D, Expr *BitWidth,
+ InClassInitStyle InitStyle,
+ AccessSpecifier AS,
+ AttributeList *MSPropertyAttr) {
+ IdentifierInfo *II = D.getIdentifier();
+ if (!II) {
+ Diag(DeclStart, diag::err_anonymous_property);
+ return NULL;
+ }
+ SourceLocation Loc = D.getIdentifierLoc();
+
+ TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
+ QualType T = TInfo->getType();
+ if (getLangOpts().CPlusPlus) {
+ CheckExtraCXXDefaultArguments(D);
+
+ if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo,
+ UPPC_DataMemberType)) {
+ D.setInvalidType();
+ T = Context.IntTy;
+ TInfo = Context.getTrivialTypeSourceInfo(T, Loc);
+ }
+ }
+
+ DiagnoseFunctionSpecifiers(D.getDeclSpec());
+
+ if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_invalid_thread)
+ << DeclSpec::getSpecifierName(TSCS);
+
+ // Check to see if this name was declared as a member previously
+ NamedDecl *PrevDecl = 0;
+ LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
+ LookupName(Previous, S);
+ switch (Previous.getResultKind()) {
+ case LookupResult::Found:
+ case LookupResult::FoundUnresolvedValue:
+ PrevDecl = Previous.getAsSingle<NamedDecl>();
+ break;
+
+ case LookupResult::FoundOverloaded:
+ PrevDecl = Previous.getRepresentativeDecl();
+ break;
+
+ case LookupResult::NotFound:
+ case LookupResult::NotFoundInCurrentInstantiation:
+ case LookupResult::Ambiguous:
+ break;
+ }
+
+ 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;
+ }
+
+ if (PrevDecl && !isDeclInScope(PrevDecl, Record, S))
+ PrevDecl = 0;
+
+ SourceLocation TSSL = D.getLocStart();
+ MSPropertyDecl *NewPD;
+ const AttributeList::PropertyData &Data = MSPropertyAttr->getPropertyData();
+ NewPD = new (Context) MSPropertyDecl(Record, Loc,
+ II, T, TInfo, TSSL,
+ Data.GetterId, Data.SetterId);
+ ProcessDeclAttributes(TUScope, NewPD, D);
+ NewPD->setAccess(AS);
+
+ if (NewPD->isInvalidDecl())
+ Record->setInvalidDecl();
+
+ if (D.getDeclSpec().isModulePrivateSpecified())
+ NewPD->setModulePrivate();
+
+ if (NewPD->isInvalidDecl() && PrevDecl) {
+ // Don't introduce NewFD into scope; there's already something
+ // with the same name in the same scope.
+ } else if (II) {
+ PushOnScopeChains(NewPD, S);
+ } else
+ Record->addDecl(NewPD);
+
+ return NewPD;
+}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp
index 5c26d7f..f33e7bc 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclObjC.cpp
@@ -745,7 +745,10 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
<< ProtocolId[i].first;
continue;
}
-
+ // If this is a forward protocol declaration, get its definition.
+ if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
+ PDecl = PDecl->getDefinition();
+
(void)DiagnoseUseOfDecl(PDecl, ProtocolId[i].second);
// If this is a forward declaration and we are supposed to warn in this
@@ -1042,7 +1045,7 @@ Decl *Sema::ActOnStartClassImplementation(
ObjCImplementationDecl* IMPDecl =
ObjCImplementationDecl::Create(Context, CurContext, IDecl, SDecl,
- ClassLoc, AtClassImplLoc);
+ ClassLoc, AtClassImplLoc, SuperClassLoc);
if (CheckObjCDeclScope(IMPDecl))
return ActOnObjCContainerStartDefinition(IMPDecl);
@@ -1833,7 +1836,7 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
if (!(LangOpts.ObjCDefaultSynthProperties &&
LangOpts.ObjCRuntime.isNonFragile()) ||
IDecl->isObjCRequiresPropertyDefs())
- DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);
+ DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
SelectorSet ClsMap;
for (ObjCImplementationDecl::classmeth_iterator
@@ -1880,17 +1883,7 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
E = C->protocol_end(); PI != E; ++PI)
CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
InsMap, ClsMap, CDecl);
- // Report unimplemented properties in the category as well.
- // When reporting on missing setter/getters, do not report when
- // setter/getter is implemented in category's primary class
- // implementation.
- if (ObjCInterfaceDecl *ID = C->getClassInterface())
- if (ObjCImplDecl *IMP = ID->getImplementation()) {
- for (ObjCImplementationDecl::instmeth_iterator
- I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
- InsMap.insert((*I)->getSelector());
- }
- DiagnoseUnimplementedProperties(S, IMPDecl, CDecl, InsMap);
+ DiagnoseUnimplementedProperties(S, IMPDecl, CDecl);
}
} else
llvm_unreachable("invalid ObjCContainerDecl type.");
@@ -2082,17 +2075,24 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *left,
}
void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {
+ // Record at the head of the list whether there were 0, 1, or >= 2 methods
+ // inside categories.
+ if (ObjCCategoryDecl *
+ CD = dyn_cast<ObjCCategoryDecl>(Method->getDeclContext()))
+ if (!CD->IsClassExtension() && List->getBits() < 2)
+ List->setBits(List->getBits()+1);
+
// If the list is empty, make it a singleton list.
if (List->Method == 0) {
List->Method = Method;
- List->Next = 0;
+ List->setNext(0);
return;
}
// We've seen a method with this name, see if we have already seen this type
// signature.
ObjCMethodList *Previous = List;
- for (; List; Previous = List, List = List->Next) {
+ for (; List; Previous = List, List = List->getNext()) {
if (!MatchTwoMethodDeclarations(Method, List->Method))
continue;
@@ -2121,7 +2121,7 @@ void Sema::addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method) {
// We have a new signature for an existing method - add it.
// This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
- Previous->Next = new (Mem) ObjCMethodList(Method, 0);
+ Previous->setNext(new (Mem) ObjCMethodList(Method, 0));
}
/// \brief Read the contents of the method pool for a given selector from
@@ -2183,7 +2183,7 @@ ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
// Gather the non-hidden methods.
ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
llvm::SmallVector<ObjCMethodDecl *, 4> Methods;
- for (ObjCMethodList *M = &MethList; M; M = M->Next) {
+ for (ObjCMethodList *M = &MethList; M; M = M->getNext()) {
if (M->Method && !M->Method->isHidden()) {
// If we're not supposed to warn about mismatches, we're done.
if (!warn)
@@ -2800,10 +2800,47 @@ void Sema::CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
i = overrides.begin(), e = overrides.end(); i != e; ++i) {
ObjCMethodDecl *overridden = *i;
- if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
- CurrentClass != overridden->getClassInterface() ||
- overridden->isOverriding())
- hasOverriddenMethodsInBaseOrProtocol = true;
+ if (!hasOverriddenMethodsInBaseOrProtocol) {
+ if (isa<ObjCProtocolDecl>(overridden->getDeclContext()) ||
+ CurrentClass != overridden->getClassInterface() ||
+ overridden->isOverriding()) {
+ hasOverriddenMethodsInBaseOrProtocol = true;
+
+ } else if (isa<ObjCImplDecl>(ObjCMethod->getDeclContext())) {
+ // OverrideSearch will return as "overridden" the same method in the
+ // interface. For hasOverriddenMethodsInBaseOrProtocol, we need to
+ // check whether a category of a base class introduced a method with the
+ // same selector, after the interface method declaration.
+ // To avoid unnecessary lookups in the majority of cases, we use the
+ // extra info bits in GlobalMethodPool to check whether there were any
+ // category methods with this selector.
+ GlobalMethodPool::iterator It =
+ MethodPool.find(ObjCMethod->getSelector());
+ if (It != MethodPool.end()) {
+ ObjCMethodList &List =
+ ObjCMethod->isInstanceMethod()? It->second.first: It->second.second;
+ unsigned CategCount = List.getBits();
+ if (CategCount > 0) {
+ // If the method is in a category we'll do lookup if there were at
+ // least 2 category methods recorded, otherwise only one will do.
+ if (CategCount > 1 ||
+ !isa<ObjCCategoryImplDecl>(overridden->getDeclContext())) {
+ OverrideSearch overrides(*this, overridden);
+ for (OverrideSearch::iterator
+ OI= overrides.begin(), OE= overrides.end(); OI!=OE; ++OI) {
+ ObjCMethodDecl *SuperOverridden = *OI;
+ if (isa<ObjCProtocolDecl>(SuperOverridden->getDeclContext()) ||
+ CurrentClass != SuperOverridden->getClassInterface()) {
+ hasOverriddenMethodsInBaseOrProtocol = true;
+ overridden->setOverriding(true);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
// Propagate down the 'related result type' bit from overridden methods.
if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
@@ -3187,12 +3224,14 @@ Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
Diag(DS.getStorageClassSpecLoc(), diag::warn_register_objc_catch_parm)
<< FixItHint::CreateRemoval(SourceRange(DS.getStorageClassSpecLoc()));
- } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
+ } else if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) {
Diag(DS.getStorageClassSpecLoc(), diag::err_storage_spec_on_catch_parm)
- << DS.getStorageClassSpec();
- }
- if (D.getDeclSpec().isThreadSpecified())
- Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+ << DeclSpec::getSpecifierName(SCS);
+ }
+ if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec())
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_invalid_thread)
+ << DeclSpec::getSpecifierName(TSCS);
D.getMutableDeclSpec().ClearStorageClassSpecs();
DiagnoseFunctionSpecifiers(D.getDeclSpec());
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp
index 26c3d35..1a5f482 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -1011,7 +1011,6 @@ CanThrowResult Sema::canThrow(const Expr *E) {
case Expr::ConditionalOperatorClass:
case Expr::CompoundLiteralExprClass:
case Expr::CXXConstCastExprClass:
- case Expr::CXXDefaultArgExprClass:
case Expr::CXXReinterpretCastExprClass:
case Expr::DesignatedInitExprClass:
case Expr::ExprWithCleanupsClass:
@@ -1044,6 +1043,12 @@ CanThrowResult Sema::canThrow(const Expr *E) {
case Expr::StmtExprClass:
return CT_Can;
+ case Expr::CXXDefaultArgExprClass:
+ return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr());
+
+ case Expr::CXXDefaultInitExprClass:
+ return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr());
+
case Expr::ChooseExprClass:
if (E->isTypeDependent() || E->isValueDependent())
return CT_Dependent;
@@ -1111,6 +1116,9 @@ CanThrowResult Sema::canThrow(const Expr *E) {
// These expressions can never throw.
return CT_Cannot;
+ case Expr::MSPropertyRefExprClass:
+ llvm_unreachable("Invalid class for expression");
+
#define STMT(CLASS, PARENT) case Expr::CLASS##Class:
#define STMT_RANGE(Base, First, Last)
#define LAST_STMT_RANGE(BASE, FIRST, LAST)
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
index 76330f5..dd05b82 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp
@@ -55,6 +55,12 @@ bool Sema::CanUseDecl(NamedDecl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->isDeleted())
return false;
+
+ // If the function has a deduced return type, and we can't deduce it,
+ // then we can't use it either.
+ if (getLangOpts().CPlusPlus1y && FD->getResultType()->isUndeducedType() &&
+ DeduceReturnType(FD, SourceLocation(), /*Diagnose*/false))
+ return false;
}
// See if this function is unavailable.
@@ -278,6 +284,12 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
NoteDeletedFunction(FD);
return true;
}
+
+ // If the function has a deduced return type, and we can't deduce it,
+ // then we can't use it either.
+ if (getLangOpts().CPlusPlus1y && FD->getResultType()->isUndeducedType() &&
+ DeduceReturnType(FD, Loc))
+ return true;
}
DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass);
@@ -806,7 +818,7 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
return ExprError();
ExprResult Call = ActOnCallExpr(TUScope, TrapFn.get(),
- E->getLocStart(), MultiExprArg(),
+ E->getLocStart(), None,
E->getLocEnd());
if (Call.isInvalid())
return ExprError();
@@ -1916,15 +1928,17 @@ ExprResult Sema::ActOnIdExpression(Scope *S,
// If this name wasn't predeclared and if this is not a function
// call, diagnose the problem.
if (R.empty()) {
-
// In Microsoft mode, if we are inside a template class member function
- // and we can't resolve an identifier then assume the identifier is type
- // dependent. The goal is to postpone name lookup to instantiation time
- // to be able to search into type dependent base classes.
- if (getLangOpts().MicrosoftMode && CurContext->isDependentContext() &&
- isa<CXXMethodDecl>(CurContext))
- return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo,
- IsAddressOfOperand, TemplateArgs);
+ // whose parent class has dependent base classes, and we can't resolve
+ // an identifier, then assume the identifier is type dependent. The
+ // goal is to postpone name lookup to instantiation time to be able to
+ // search into the type dependent base classes.
+ if (getLangOpts().MicrosoftMode) {
+ CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext);
+ if (MD && MD->getParent()->hasAnyDependentBases())
+ return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo,
+ IsAddressOfOperand, TemplateArgs);
+ }
CorrectionCandidateCallback DefaultValidator;
if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
@@ -2636,6 +2650,10 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
break;
}
+ case Decl::MSProperty:
+ valueKind = VK_LValue;
+ break;
+
case Decl::CXXMethod:
// If we're referring to a method with an __unknown_anytype
// result type, make the entire expression __unknown_anytype.
@@ -2760,8 +2778,7 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) {
// C++11 [lex.ext]p6: The literal L is treated as a call of the form
// operator "" X (ch)
return BuildCookedLiteralOperatorCall(*this, UDLScope, UDSuffix, UDSuffixLoc,
- llvm::makeArrayRef(&Lit, 1),
- Tok.getLocation());
+ Lit, Tok.getLocation());
}
ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
@@ -2858,7 +2875,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// Perform literal operator lookup to determine if we're building a raw
// literal or a cooked one.
LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName);
- switch (LookupLiteralOperator(UDLScope, R, llvm::makeArrayRef(&CookedTy, 1),
+ switch (LookupLiteralOperator(UDLScope, R, CookedTy,
/*AllowRawAndTemplate*/true)) {
case LOLR_Error:
return ExprError();
@@ -2874,8 +2891,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Lit = IntegerLiteral::Create(Context, ResultVal, CookedTy,
Tok.getLocation());
}
- return BuildLiteralOperatorCall(R, OpNameInfo,
- llvm::makeArrayRef(&Lit, 1),
+ return BuildLiteralOperatorCall(R, OpNameInfo, Lit,
Tok.getLocation());
}
@@ -2891,8 +2907,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Expr *Lit = StringLiteral::Create(
Context, StringRef(TokSpelling.data(), Length), StringLiteral::Ascii,
/*Pascal*/false, StrTy, &TokLoc, 1);
- return BuildLiteralOperatorCall(R, OpNameInfo,
- llvm::makeArrayRef(&Lit, 1), TokLoc);
+ return BuildLiteralOperatorCall(R, OpNameInfo, Lit, TokLoc);
}
case LOLR_Template:
@@ -2910,8 +2925,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
TemplateArgumentLocInfo ArgInfo;
ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo));
}
- return BuildLiteralOperatorCall(R, OpNameInfo, ArrayRef<Expr*>(),
- Tok.getLocation(), &ExplicitArgs);
+ return BuildLiteralOperatorCall(R, OpNameInfo, None, Tok.getLocation(),
+ &ExplicitArgs);
}
llvm_unreachable("unexpected literal operator lookup result");
@@ -3150,13 +3165,7 @@ static void warnOnSizeofOnArrayDecay(Sema &S, SourceLocation Loc, QualType T,
bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
UnaryExprOrTypeTrait ExprKind) {
QualType ExprTy = E->getType();
-
- // C++ [expr.sizeof]p2: "When applied to a reference or a reference type,
- // the result is the size of the referenced type."
- // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the
- // result shall be the alignment of the referenced type."
- if (const ReferenceType *Ref = ExprTy->getAs<ReferenceType>())
- ExprTy = Ref->getPointeeType();
+ assert(!ExprTy->isReferenceType());
if (ExprKind == UETT_VecStep)
return CheckVecStepTraitOperandType(*this, ExprTy, E->getExprLoc(),
@@ -3172,10 +3181,9 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
ExprKind, E->getSourceRange()))
return true;
- // Completeing the expression's type may have changed it.
+ // Completing the expression's type may have changed it.
ExprTy = E->getType();
- if (const ReferenceType *Ref = ExprTy->getAs<ReferenceType>())
- ExprTy = Ref->getPointeeType();
+ assert(!ExprTy->isReferenceType());
if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(),
E->getSourceRange(), ExprKind))
@@ -3260,25 +3268,67 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
static bool CheckAlignOfExpr(Sema &S, Expr *E) {
E = E->IgnoreParens();
- // alignof decl is always ok.
- if (isa<DeclRefExpr>(E))
- return false;
-
// Cannot know anything else if the expression is dependent.
if (E->isTypeDependent())
return false;
- if (E->getBitField()) {
+ if (E->getObjectKind() == OK_BitField) {
S.Diag(E->getExprLoc(), diag::err_sizeof_alignof_bitfield)
<< 1 << E->getSourceRange();
return true;
}
- // Alignment of a field access is always okay, so long as it isn't a
- // bit-field.
- if (MemberExpr *ME = dyn_cast<MemberExpr>(E))
- if (isa<FieldDecl>(ME->getMemberDecl()))
+ ValueDecl *D = 0;
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ D = DRE->getDecl();
+ } else if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+ D = ME->getMemberDecl();
+ }
+
+ // If it's a field, require the containing struct to have a
+ // complete definition so that we can compute the layout.
+ //
+ // This requires a very particular set of circumstances. For a
+ // field to be contained within an incomplete type, we must in the
+ // process of parsing that type. To have an expression refer to a
+ // field, it must be an id-expression or a member-expression, but
+ // the latter are always ill-formed when the base type is
+ // incomplete, including only being partially complete. An
+ // id-expression can never refer to a field in C because fields
+ // are not in the ordinary namespace. In C++, an id-expression
+ // can implicitly be a member access, but only if there's an
+ // implicit 'this' value, and all such contexts are subject to
+ // delayed parsing --- except for trailing return types in C++11.
+ // And if an id-expression referring to a field occurs in a
+ // context that lacks a 'this' value, it's ill-formed --- except,
+ // agian, in C++11, where such references are allowed in an
+ // unevaluated context. So C++11 introduces some new complexity.
+ //
+ // For the record, since __alignof__ on expressions is a GCC
+ // extension, GCC seems to permit this but always gives the
+ // nonsensical answer 0.
+ //
+ // We don't really need the layout here --- we could instead just
+ // directly check for all the appropriate alignment-lowing
+ // attributes --- but that would require duplicating a lot of
+ // logic that just isn't worth duplicating for such a marginal
+ // use-case.
+ if (FieldDecl *FD = dyn_cast_or_null<FieldDecl>(D)) {
+ // Fast path this check, since we at least know the record has a
+ // definition if we can find a member of it.
+ if (!FD->getParent()->isCompleteDefinition()) {
+ S.Diag(E->getExprLoc(), diag::err_alignof_member_of_incomplete_type)
+ << E->getSourceRange();
+ return true;
+ }
+
+ // Otherwise, if it's a field, and the field doesn't have
+ // reference type, then it must have a complete type (or be a
+ // flexible array member, which we explicitly want to
+ // white-list anyway), which makes the following checks trivial.
+ if (!FD->getType()->isReferenceType())
return false;
+ }
return S.CheckUnaryExprOrTypeTraitOperand(E, UETT_AlignOf);
}
@@ -3333,7 +3383,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
isInvalid = CheckAlignOfExpr(*this, E);
} else if (ExprKind == UETT_VecStep) {
isInvalid = CheckVecStepExpr(E);
- } else if (E->getBitField()) { // C99 6.5.3.4p1.
+ } else if (E->refersToBitField()) { // C99 6.5.3.4p1.
Diag(E->getExprLoc(), diag::err_sizeof_alignof_bitfield) << 0;
isInvalid = true;
} else {
@@ -3665,14 +3715,11 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
Param);
// Instantiate the expression.
- MultiLevelTemplateArgumentList ArgList
+ MultiLevelTemplateArgumentList MutiLevelArgList
= getTemplateInstantiationArgs(FD, 0, /*RelativeToPrimary=*/true);
- std::pair<const TemplateArgument *, unsigned> Innermost
- = ArgList.getInnermost();
InstantiatingTemplate Inst(*this, CallLoc, Param,
- ArrayRef<TemplateArgument>(Innermost.first,
- Innermost.second));
+ MutiLevelArgList.getInnermost());
if (Inst)
return ExprError();
@@ -3684,7 +3731,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
// default argument expression appears.
ContextRAII SavedContext(*this, FD);
LocalInstantiationScope Local(*this);
- Result = SubstExpr(UninstExpr, ArgList);
+ Result = SubstExpr(UninstExpr, MutiLevelArgList);
}
if (Result.isInvalid())
return ExprError();
@@ -3697,7 +3744,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
/*FIXME:EqualLoc*/UninstExpr->getLocStart());
Expr *ResultE = Result.takeAs<Expr>();
- InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
+ InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
if (Result.isInvalid())
return ExprError();
@@ -4023,6 +4070,63 @@ Sema::CheckStaticArrayArgument(SourceLocation CallLoc,
/// to have a function type.
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn);
+/// Is the given type a placeholder that we need to lower out
+/// immediately during argument processing?
+static bool isPlaceholderToRemoveAsArg(QualType type) {
+ // Placeholders are never sugared.
+ const BuiltinType *placeholder = dyn_cast<BuiltinType>(type);
+ if (!placeholder) return false;
+
+ switch (placeholder->getKind()) {
+ // Ignore all the non-placeholder types.
+#define PLACEHOLDER_TYPE(ID, SINGLETON_ID)
+#define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID:
+#include "clang/AST/BuiltinTypes.def"
+ return false;
+
+ // We cannot lower out overload sets; they might validly be resolved
+ // by the call machinery.
+ case BuiltinType::Overload:
+ return false;
+
+ // Unbridged casts in ARC can be handled in some call positions and
+ // should be left in place.
+ case BuiltinType::ARCUnbridgedCast:
+ return false;
+
+ // Pseudo-objects should be converted as soon as possible.
+ case BuiltinType::PseudoObject:
+ return true;
+
+ // The debugger mode could theoretically but currently does not try
+ // to resolve unknown-typed arguments based on known parameter types.
+ case BuiltinType::UnknownAny:
+ return true;
+
+ // These are always invalid as call arguments and should be reported.
+ case BuiltinType::BoundMember:
+ case BuiltinType::BuiltinFn:
+ return true;
+ }
+ llvm_unreachable("bad builtin type kind");
+}
+
+/// Check an argument list for placeholders that we won't try to
+/// handle later.
+static bool checkArgsForPlaceholders(Sema &S, MultiExprArg args) {
+ // Apply this processing to all the arguments at once instead of
+ // dying at the first failure.
+ bool hasInvalid = false;
+ for (size_t i = 0, e = args.size(); i != e; i++) {
+ if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
+ ExprResult result = S.CheckPlaceholderExpr(args[i]);
+ if (result.isInvalid()) hasInvalid = true;
+ else args[i] = result.take();
+ }
+ }
+ return hasInvalid;
+}
+
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
/// This provides the location of the left/right parens and a list of comma
/// locations.
@@ -4035,6 +4139,9 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
if (Result.isInvalid()) return ExprError();
Fn = Result.take();
+ if (checkArgsForPlaceholders(*this, ArgExprs))
+ return ExprError();
+
if (getLangOpts().CPlusPlus) {
// If this is a pseudo-destructor expression, build the call immediately.
if (isa<CXXPseudoDestructorExpr>(Fn)) {
@@ -4046,10 +4153,15 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
ArgExprs.back()->getLocEnd()));
}
- return Owned(new (Context) CallExpr(Context, Fn, MultiExprArg(),
+ return Owned(new (Context) CallExpr(Context, Fn, None,
Context.VoidTy, VK_RValue,
RParenLoc));
}
+ if (Fn->getType() == Context.PseudoObjectTy) {
+ ExprResult result = CheckPlaceholderExpr(Fn);
+ if (result.isInvalid()) return ExprError();
+ Fn = result.take();
+ }
// Determine whether this is a dependent call inside a C++ template,
// in which case we won't do any semantic analysis now.
@@ -4397,12 +4509,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
return ExprError();
InitializedEntity Entity
- = InitializedEntity::InitializeTemporary(literalType);
+ = InitializedEntity::InitializeCompoundLiteralInit(TInfo);
InitializationKind Kind
= InitializationKind::CreateCStyleCast(LParenLoc,
SourceRange(LParenLoc, RParenLoc),
/*InitList=*/true);
- InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1);
+ InitializationSequence InitSeq(*this, Entity, Kind, LiteralExpr);
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, LiteralExpr,
&literalType);
if (Result.isInvalid())
@@ -6823,18 +6935,6 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
bool IsCompAssign) {
checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false);
- // C99 6.5.7p2: Each of the operands shall have integer type.
- if (!LHS.get()->getType()->hasIntegerRepresentation() ||
- !RHS.get()->getType()->hasIntegerRepresentation())
- return InvalidOperands(Loc, LHS, RHS);
-
- // C++0x: Don't allow scoped enums. FIXME: Use something better than
- // hasIntegerRepresentation() above instead of this.
- if (isScopedEnumerationType(LHS.get()->getType()) ||
- isScopedEnumerationType(RHS.get()->getType())) {
- return InvalidOperands(Loc, LHS, RHS);
- }
-
// Vector shifts promote their scalar inputs to vector type.
if (LHS.get()->getType()->isVectorType() ||
RHS.get()->getType()->isVectorType())
@@ -6856,7 +6956,19 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS,
RHS = UsualUnaryConversions(RHS.take());
if (RHS.isInvalid())
return QualType();
+ QualType RHSType = RHS.get()->getType();
+
+ // C99 6.5.7p2: Each of the operands shall have integer type.
+ if (!LHSType->hasIntegerRepresentation() ||
+ !RHSType->hasIntegerRepresentation())
+ return InvalidOperands(Loc, LHS, RHS);
+ // C++0x: Don't allow scoped enums. FIXME: Use something better than
+ // hasIntegerRepresentation() above instead of this.
+ if (isScopedEnumerationType(LHSType) ||
+ isScopedEnumerationType(RHSType)) {
+ return InvalidOperands(Loc, LHS, RHS);
+ }
// Sanity-check shift operands
DiagnoseBadShiftValues(*this, LHS, RHS, Loc, Opc, LHSType);
@@ -7213,17 +7325,6 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
}
if (literalString) {
- std::string resultComparison;
- switch (Opc) {
- case BO_LT: resultComparison = ") < 0"; break;
- case BO_GT: resultComparison = ") > 0"; break;
- case BO_LE: resultComparison = ") <= 0"; break;
- case BO_GE: resultComparison = ") >= 0"; break;
- case BO_EQ: resultComparison = ") == 0"; break;
- case BO_NE: resultComparison = ") != 0"; break;
- default: llvm_unreachable("Invalid comparison operator");
- }
-
DiagRuntimeBehavior(Loc, 0,
PDiag(diag::warn_stringcompare)
<< isa<ObjCEncodeExpr>(literalStringStripped)
@@ -8246,6 +8347,9 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp,
<< op->getType() << op->getSourceRange();
if (sfinae)
return QualType();
+ // Materialize the temporary as an lvalue so that we can take its address.
+ OrigOp = op = new (S.Context)
+ MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true);
} else if (isa<ObjCSelectorExpr>(op)) {
return S.Context.getPointerType(op->getType());
} else if (lval == Expr::LV_MemberFunction) {
@@ -8501,6 +8605,36 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
<< LHSExpr->getSourceRange() << RHSExpr->getSourceRange();
}
+/// Check if a bitwise-& is performed on an Objective-C pointer. This
+/// is usually indicative of introspection within the Objective-C pointer.
+static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R,
+ SourceLocation OpLoc) {
+ if (!S.getLangOpts().ObjC1)
+ return;
+
+ const Expr *ObjCPointerExpr = 0, *OtherExpr = 0;
+ const Expr *LHS = L.get();
+ const Expr *RHS = R.get();
+
+ if (LHS->IgnoreParenCasts()->getType()->isObjCObjectPointerType()) {
+ ObjCPointerExpr = LHS;
+ OtherExpr = RHS;
+ }
+ else if (RHS->IgnoreParenCasts()->getType()->isObjCObjectPointerType()) {
+ ObjCPointerExpr = RHS;
+ OtherExpr = LHS;
+ }
+
+ // This warning is deliberately made very specific to reduce false
+ // positives with logic that uses '&' for hashing. This logic mainly
+ // looks for code trying to introspect into tagged pointers, which
+ // code should generally never do.
+ if (ObjCPointerExpr && isa<IntegerLiteral>(OtherExpr->IgnoreParenCasts())) {
+ S.Diag(OpLoc, diag::warn_objc_pointer_masking)
+ << ObjCPointerExpr->getSourceRange();
+ }
+}
+
/// CreateBuiltinBinOp - Creates a new built-in binary operation with
/// operator @p Opc at location @c TokLoc. This routine only supports
/// built-in operations; ActOnBinOp handles overloaded operators.
@@ -8518,7 +8652,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
InitializationKind::CreateDirectList(RHSExpr->getLocStart());
InitializedEntity Entity =
InitializedEntity::InitializeTemporary(LHSExpr->getType());
- InitializationSequence InitSeq(*this, Entity, Kind, &RHSExpr, 1);
+ InitializationSequence InitSeq(*this, Entity, Kind, RHSExpr);
ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
if (Init.isInvalid())
return Init;
@@ -8578,6 +8712,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
ResultTy = CheckCompareOperands(LHS, RHS, OpLoc, Opc, false);
break;
case BO_And:
+ checkObjCPointerIntrospection(*this, LHS, RHS, OpLoc);
case BO_Xor:
case BO_Or:
ResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc);
@@ -8819,6 +8954,33 @@ static void DiagnoseAdditionInShift(Sema &S, SourceLocation OpLoc,
}
}
+static void DiagnoseShiftCompare(Sema &S, SourceLocation OpLoc,
+ Expr *LHSExpr, Expr *RHSExpr) {
+ CXXOperatorCallExpr *OCE = dyn_cast<CXXOperatorCallExpr>(LHSExpr);
+ if (!OCE)
+ return;
+
+ FunctionDecl *FD = OCE->getDirectCallee();
+ if (!FD || !FD->isOverloadedOperator())
+ return;
+
+ OverloadedOperatorKind Kind = FD->getOverloadedOperator();
+ if (Kind != OO_LessLess && Kind != OO_GreaterGreater)
+ return;
+
+ S.Diag(OpLoc, diag::warn_overloaded_shift_in_comparison)
+ << LHSExpr->getSourceRange() << RHSExpr->getSourceRange()
+ << (Kind == OO_LessLess);
+ SuggestParentheses(S, OCE->getOperatorLoc(),
+ S.PDiag(diag::note_precedence_silence)
+ << (Kind == OO_LessLess ? "<<" : ">>"),
+ OCE->getSourceRange());
+ SuggestParentheses(S, OpLoc,
+ S.PDiag(diag::note_evaluate_comparison_first),
+ SourceRange(OCE->getArg(1)->getLocStart(),
+ RHSExpr->getLocEnd()));
+}
+
/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
/// precedence.
static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
@@ -8847,6 +9009,11 @@ static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
DiagnoseAdditionInShift(Self, OpLoc, LHSExpr, Shift);
DiagnoseAdditionInShift(Self, OpLoc, RHSExpr, Shift);
}
+
+ // Warn on overloaded shift operators and comparisons, such as:
+ // cout << 5 == 4;
+ if (BinaryOperator::isComparisonOp(Opc))
+ DiagnoseShiftCompare(Self, OpLoc, LHSExpr, RHSExpr);
}
// Binary Operators. 'Tok' is the token for the operator.
@@ -9611,7 +9778,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo,
FunctionProtoType::ExtProtoInfo EPI;
EPI.HasTrailingReturn = false;
EPI.TypeQuals |= DeclSpec::TQ_const;
- T = Context.getFunctionType(Context.DependentTy, ArrayRef<QualType>(), EPI);
+ T = Context.getFunctionType(Context.DependentTy, None, EPI);
Sig = Context.getTrivialTypeSourceInfo(T);
}
@@ -9790,7 +9957,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
if (isa<FunctionNoProtoType>(FTy)) {
FunctionProtoType::ExtProtoInfo EPI;
EPI.ExtInfo = Ext;
- BlockTy = Context.getFunctionType(RetTy, ArrayRef<QualType>(), EPI);
+ BlockTy = Context.getFunctionType(RetTy, None, EPI);
// Otherwise, if we don't need to change anything about the function type,
// preserve its sugar structure.
@@ -9815,7 +9982,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
} else {
FunctionProtoType::ExtProtoInfo EPI;
EPI.ExtInfo = FunctionType::ExtInfo().withNoReturn(NoReturn);
- BlockTy = Context.getFunctionType(RetTy, ArrayRef<QualType>(), EPI);
+ BlockTy = Context.getFunctionType(RetTy, None, EPI);
}
DiagnoseUnusedParameters(BSI->TheDecl->param_begin(),
@@ -10047,6 +10214,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
if (Hint.isNull() && !CheckInferredResultType) {
ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this);
}
+ else if (CheckInferredResultType) {
+ SrcType = SrcType.getUnqualifiedType();
+ DstType = DstType.getUnqualifiedType();
+ }
MayHaveConvFixit = true;
break;
case IncompatiblePointerSign:
@@ -10446,11 +10617,11 @@ namespace {
}
ExprResult Sema::TransformToPotentiallyEvaluated(Expr *E) {
- assert(ExprEvalContexts.back().Context == Unevaluated &&
+ assert(isUnevaluatedContext() &&
"Should only transform unevaluated expressions");
ExprEvalContexts.back().Context =
ExprEvalContexts[ExprEvalContexts.size()-2].Context;
- if (ExprEvalContexts.back().Context == Unevaluated)
+ if (isUnevaluatedContext())
return E;
return TransformToPE(*this).TransformExpr(E);
}
@@ -10482,7 +10653,7 @@ void Sema::PopExpressionEvaluationContext() {
ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
if (!Rec.Lambdas.empty()) {
- if (Rec.Context == Unevaluated) {
+ if (Rec.isUnevaluated()) {
// C++11 [expr.prim.lambda]p2:
// A lambda-expression shall not appear in an unevaluated operand
// (Clause 5).
@@ -10508,7 +10679,7 @@ void Sema::PopExpressionEvaluationContext() {
// temporaries that we may have created as part of the evaluation of
// the expression in that context: they aren't relevant because they
// will never be constructed.
- if (Rec.Context == Unevaluated || Rec.Context == ConstantEvaluated) {
+ if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) {
ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects,
ExprCleanupObjects.end());
ExprNeedsCleanups = Rec.ParentNeedsCleanups;
@@ -10547,6 +10718,7 @@ static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) {
switch (SemaRef.ExprEvalContexts.back().Context) {
case Sema::Unevaluated:
+ case Sema::UnevaluatedAbstract:
// We are in an expression that is not potentially evaluated; do nothing.
// (Depending on how you read the standard, we actually do need to do
// something here for null pointer constants, but the standard's
@@ -10793,6 +10965,34 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc,
// capture.
}
+/// \brief Capture the given variable in the captured region.
+static ExprResult captureInCapturedRegion(Sema &S, CapturedRegionScopeInfo *RSI,
+ VarDecl *Var, QualType FieldType,
+ QualType DeclRefType,
+ SourceLocation Loc,
+ bool RefersToEnclosingLocal) {
+ // The current implemention assumes that all variables are captured
+ // by references. Since there is no capture by copy, no expression evaluation
+ // will be needed.
+ //
+ RecordDecl *RD = RSI->TheRecordDecl;
+
+ FieldDecl *Field
+ = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, FieldType,
+ S.Context.getTrivialTypeSourceInfo(FieldType, Loc),
+ 0, false, ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ RD->addDecl(Field);
+
+ Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
+ DeclRefType, VK_LValue, Loc);
+ Var->setReferenced(true);
+ Var->setUsed(true);
+
+ return Ref;
+}
+
/// \brief Capture the given variable in the given lambda expression.
static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
VarDecl *Var, QualType FieldType,
@@ -10894,9 +11094,9 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI,
InitializationKind InitKind
= InitializationKind::CreateDirect(Loc, Loc, Loc);
- InitializationSequence Init(S, Entities.back(), InitKind, &Ref, 1);
+ InitializationSequence Init(S, Entities.back(), InitKind, Ref);
ExprResult Result(true);
- if (!Init.Diagnose(S, Entities.back(), InitKind, &Ref, 1))
+ if (!Init.Diagnose(S, Entities.back(), InitKind, Ref))
Result = Init.Perform(S, Entities.back(), InitKind, Ref);
// If this initialization requires any cleanups (e.g., due to a
@@ -10933,10 +11133,10 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
bool Explicit = (Kind != TryCapture_Implicit);
unsigned FunctionScopesIndex = FunctionScopes.size() - 1;
do {
- // Only block literals and lambda expressions can capture; other
- // scopes don't work.
+ // Only block literals, captured statements, and lambda expressions can
+ // capture; other scopes don't work.
DeclContext *ParentDC;
- if (isa<BlockDecl>(DC))
+ if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC))
ParentDC = DC->getParent();
else if (isa<CXXMethodDecl>(DC) &&
cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call &&
@@ -10970,7 +11170,7 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
}
bool IsBlock = isa<BlockScopeInfo>(CSI);
- bool IsLambda = !IsBlock;
+ bool IsLambda = isa<LambdaScopeInfo>(CSI);
// Lambdas are not allowed to capture unnamed variables
// (e.g. anonymous unions).
@@ -11130,8 +11330,31 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
SourceLocation(), CaptureType, CopyExpr);
Nested = true;
continue;
- }
-
+ }
+
+ if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) {
+ // By default, capture variables by reference.
+ bool ByRef = true;
+ // Using an LValue reference type is consistent with Lambdas (see below).
+ CaptureType = Context.getLValueReferenceType(DeclRefType);
+
+ Expr *CopyExpr = 0;
+ if (BuildAndDiagnose) {
+ ExprResult Result = captureInCapturedRegion(*this, RSI, Var,
+ CaptureType, DeclRefType,
+ Loc, Nested);
+ if (!Result.isInvalid())
+ CopyExpr = Result.take();
+ }
+
+ // Actually capture the variable.
+ if (BuildAndDiagnose)
+ CSI->addCapture(Var, /*isBlock*/false, ByRef, Nested, Loc,
+ SourceLocation(), CaptureType, CopyExpr);
+ Nested = true;
+ continue;
+ }
+
LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI);
// Determine whether we are capturing by reference or by value.
@@ -11580,6 +11803,7 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
const PartialDiagnostic &PD) {
switch (ExprEvalContexts.back().Context) {
case Unevaluated:
+ case UnevaluatedAbstract:
// The argument will never be evaluated, so don't complain.
break;
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp
index 3f2cb02..27032a9 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprCXX.cpp
@@ -684,7 +684,8 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E,
MarkFunctionReferenced(E->getExprLoc(), Destructor);
CheckDestructorAccess(E->getExprLoc(), Destructor,
PDiag(diag::err_access_dtor_exception) << Ty);
- DiagnoseUseOfDecl(Destructor, E->getExprLoc());
+ if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
+ return ExprError();
return Owned(E);
}
@@ -728,9 +729,21 @@ Sema::CXXThisScopeRAII::~CXXThisScopeRAII() {
}
}
+static Expr *captureThis(ASTContext &Context, RecordDecl *RD,
+ QualType ThisTy, SourceLocation Loc) {
+ FieldDecl *Field
+ = FieldDecl::Create(Context, RD, Loc, Loc, 0, ThisTy,
+ Context.getTrivialTypeSourceInfo(ThisTy, Loc),
+ 0, false, ICIS_NoInit);
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ RD->addDecl(Field);
+ return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit*/true);
+}
+
void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) {
// We don't need to capture this in an unevaluated context.
- if (ExprEvalContexts.back().Context == Unevaluated && !Explicit)
+ if (isUnevaluatedContext() && !Explicit)
return;
// Otherwise, check that we can capture 'this'.
@@ -746,6 +759,7 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) {
if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref ||
CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval ||
CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block ||
+ CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion ||
Explicit) {
// This closure can capture 'this'; continue looking upwards.
NumClosures++;
@@ -767,18 +781,13 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) {
CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]);
Expr *ThisExpr = 0;
QualType ThisTy = getCurrentThisType();
- if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+ if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI))
// For lambda expressions, build a field and an initializing expression.
- CXXRecordDecl *Lambda = LSI->Lambda;
- FieldDecl *Field
- = FieldDecl::Create(Context, Lambda, Loc, Loc, 0, ThisTy,
- Context.getTrivialTypeSourceInfo(ThisTy, Loc),
- 0, false, ICIS_NoInit);
- Field->setImplicit(true);
- Field->setAccess(AS_private);
- Lambda->addDecl(Field);
- ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true);
- }
+ ThisExpr = captureThis(Context, LSI->Lambda, ThisTy, Loc);
+ else if (CapturedRegionScopeInfo *RSI
+ = dyn_cast<CapturedRegionScopeInfo>(FunctionScopes[idx]))
+ ThisExpr = captureThis(Context, RSI->TheRecordDecl, ThisTy, Loc);
+
bool isNested = NumClosures > 1;
CSI->addThisCapture(isNested, Loc, ThisTy, ThisExpr);
}
@@ -831,23 +840,20 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
ExprResult
Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
SourceLocation LParenLoc,
- MultiExprArg exprs,
+ MultiExprArg Exprs,
SourceLocation RParenLoc) {
QualType Ty = TInfo->getType();
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
- if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(exprs)) {
+ if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo,
LParenLoc,
- exprs,
+ Exprs,
RParenLoc));
}
- unsigned NumExprs = exprs.size();
- Expr **Exprs = exprs.data();
-
bool ListInitialization = LParenLoc.isInvalid();
- assert((!ListInitialization || (NumExprs == 1 && isa<InitListExpr>(Exprs[0])))
+ assert((!ListInitialization || (Exprs.size() == 1 && isa<InitListExpr>(Exprs[0])))
&& "List initialization must have initializer list as expression.");
SourceRange FullRange = SourceRange(TyBeginLoc,
ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc);
@@ -856,7 +862,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
// If the expression list is a single expression, the type conversion
// expression is equivalent (in definedness, and if defined in meaning) to the
// corresponding cast expression.
- if (NumExprs == 1 && !ListInitialization) {
+ if (Exprs.size() == 1 && !ListInitialization) {
Expr *Arg = Exprs[0];
return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc);
}
@@ -879,15 +885,13 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
return ExprError();
InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo);
- InitializationKind Kind
- = NumExprs ? ListInitialization
- ? InitializationKind::CreateDirectList(TyBeginLoc)
- : InitializationKind::CreateDirect(TyBeginLoc,
- LParenLoc, RParenLoc)
- : InitializationKind::CreateValue(TyBeginLoc,
- LParenLoc, RParenLoc);
- InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
- ExprResult Result = InitSeq.Perform(*this, Entity, Kind, exprs);
+ InitializationKind Kind =
+ Exprs.size() ? ListInitialization
+ ? InitializationKind::CreateDirectList(TyBeginLoc)
+ : InitializationKind::CreateDirect(TyBeginLoc, LParenLoc, RParenLoc)
+ : InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc);
+ InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
if (!Result.isInvalid() && ListInitialization &&
isa<InitListExpr>(Result.get())) {
@@ -983,7 +987,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
SourceLocation PlacementRParen, SourceRange TypeIdParens,
Declarator &D, Expr *Initializer) {
- bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
+ bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType();
Expr *ArraySize = 0;
// If the specified type is an array, unwrap it and save the expression.
@@ -1110,9 +1114,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
HaveCompleteInit = true;
// C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
- AutoType *AT = 0;
- if (TypeMayContainAuto &&
- (AT = AllocType->getContainedAutoType()) && !AT->isDeduced()) {
+ if (TypeMayContainAuto && AllocType->isUndeducedType()) {
if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
<< AllocType << TypeRange);
@@ -1127,16 +1129,14 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
<< AllocType << TypeRange);
}
Expr *Deduce = Inits[0];
- TypeSourceInfo *DeducedType = 0;
+ QualType DeducedType;
if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
<< AllocType << Deduce->getType()
<< TypeRange << Deduce->getSourceRange());
- if (!DeducedType)
+ if (DeducedType.isNull())
return ExprError();
-
- AllocTypeInfo = DeducedType;
- AllocType = AllocTypeInfo->getType();
+ AllocType = DeducedType;
}
// Per C++0x [expr.new]p5, the type being constructed may be a
@@ -1170,6 +1170,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
QualType ResultType = Context.getPointerType(AllocType);
+ if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) {
+ ExprResult result = CheckPlaceholderExpr(ArraySize);
+ if (result.isInvalid()) return ExprError();
+ ArraySize = result.take();
+ }
// C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
// integral or enumeration type with a non-negative value."
// C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped
@@ -1405,7 +1410,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, InitType);
- InitializationSequence InitSeq(*this, Entity, Kind, Inits, NumInits);
+ InitializationSequence InitSeq(*this, Entity, Kind, MultiExprArg(Inits, NumInits));
ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
MultiExprArg(Inits, NumInits));
if (FullInit.isInvalid())
@@ -1422,11 +1427,13 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// Mark the new and delete operators as referenced.
if (OperatorNew) {
- DiagnoseUseOfDecl(OperatorNew, StartLoc);
+ if (DiagnoseUseOfDecl(OperatorNew, StartLoc))
+ return ExprError();
MarkFunctionReferenced(StartLoc, OperatorNew);
}
if (OperatorDelete) {
- DiagnoseUseOfDecl(OperatorDelete, StartLoc);
+ if (DiagnoseUseOfDecl(OperatorDelete, StartLoc))
+ return ExprError();
MarkFunctionReferenced(StartLoc, OperatorDelete);
}
@@ -1442,7 +1449,8 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
CheckDestructorAccess(StartLoc, dtor,
PDiag(diag::err_access_dtor)
<< BaseAllocType);
- DiagnoseUseOfDecl(dtor, StartLoc);
+ if (DiagnoseUseOfDecl(dtor, StartLoc))
+ return ExprError();
}
}
}
@@ -2200,7 +2208,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) {
MarkFunctionReferenced(StartLoc,
const_cast<CXXDestructorDecl*>(Dtor));
- DiagnoseUseOfDecl(Dtor, StartLoc);
+ if (DiagnoseUseOfDecl(Dtor, StartLoc))
+ return ExprError();
}
// C++ [expr.delete]p3:
@@ -2266,6 +2275,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
SourceLocation StmtLoc,
bool ConvertToBoolean) {
+ if (ConditionVar->isInvalidDecl())
+ return ExprError();
+
QualType T = ConditionVar->getType();
// C++ [stmt.select]p2:
@@ -3119,7 +3131,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT,
case UTT_IsPOD:
return T.isPODType(Self.Context);
case UTT_IsLiteral:
- return T->isLiteralType();
+ return T->isLiteralType(Self.Context);
case UTT_IsEmpty:
if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
return !RD->isUnion() && RD->isEmpty();
@@ -3486,8 +3498,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
InitializedEntity To(InitializedEntity::InitializeTemporary(Args[0]));
InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc,
RParenLoc));
- InitializationSequence Init(S, To, InitKind,
- ArgExprs.begin(), ArgExprs.size());
+ InitializationSequence Init(S, To, InitKind, ArgExprs);
if (Init.Failed())
return false;
@@ -3645,7 +3656,7 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
EnterExpressionEvaluationContext Unevaluated(Self, Sema::Unevaluated);
Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
- InitializationSequence Init(Self, To, Kind, &FromPtr, 1);
+ InitializationSequence Init(Self, To, Kind, FromPtr);
if (Init.Failed())
return false;
@@ -4045,7 +4056,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
QualType T = Self.Context.getLValueReferenceType(ToType);
InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
- InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
+ InitializationSequence InitSeq(Self, Entity, Kind, From);
if (InitSeq.isDirectReferenceBinding()) {
ToType = T;
HaveConversion = true;
@@ -4053,7 +4064,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
}
if (InitSeq.isAmbiguous())
- return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
+ return InitSeq.Diagnose(Self, Entity, Kind, From);
}
// -- If E2 is an rvalue, or if the conversion above cannot be done:
@@ -4073,14 +4084,14 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
if (FRec == TRec || FDerivedFromT) {
if (TTy.isAtLeastAsQualifiedAs(FTy)) {
InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
- InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
+ InitializationSequence InitSeq(Self, Entity, Kind, From);
if (InitSeq) {
HaveConversion = true;
return false;
}
if (InitSeq.isAmbiguous())
- return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
+ return InitSeq.Diagnose(Self, Entity, Kind, From);
}
}
@@ -4098,11 +4109,11 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
TTy = TTy.getUnqualifiedType();
InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy);
- InitializationSequence InitSeq(Self, Entity, Kind, &From, 1);
+ InitializationSequence InitSeq(Self, Entity, Kind, From);
HaveConversion = !InitSeq.Failed();
ToType = TTy;
if (InitSeq.isAmbiguous())
- return InitSeq.Diagnose(Self, Entity, Kind, &From, 1);
+ return InitSeq.Diagnose(Self, Entity, Kind, From);
return false;
}
@@ -4116,7 +4127,7 @@ static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS
SourceLocation QuestionLoc) {
Expr *Args[2] = { LHS.get(), RHS.get() };
OverloadCandidateSet CandidateSet(QuestionLoc);
- Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, 2,
+ Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args,
CandidateSet);
OverloadCandidateSet::iterator Best;
@@ -4175,7 +4186,7 @@ static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) {
InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(),
SourceLocation());
Expr *Arg = E.take();
- InitializationSequence InitSeq(Self, Entity, Kind, &Arg, 1);
+ InitializationSequence InitSeq(Self, Entity, Kind, Arg);
ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg);
if (Result.isInvalid())
return true;
@@ -4624,8 +4635,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
= InitializedEntity::InitializeTemporary(Composite1);
InitializationKind Kind
= InitializationKind::CreateCopy(Loc, SourceLocation());
- InitializationSequence E1ToC1(*this, Entity1, Kind, &E1, 1);
- InitializationSequence E2ToC1(*this, Entity1, Kind, &E2, 1);
+ InitializationSequence E1ToC1(*this, Entity1, Kind, E1);
+ InitializationSequence E2ToC1(*this, Entity1, Kind, E2);
if (E1ToC1 && E2ToC1) {
// Conversion to Composite1 is viable.
@@ -4634,8 +4645,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// Composite2 is also viable.
InitializedEntity Entity2
= InitializedEntity::InitializeTemporary(Composite2);
- InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1);
- InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
+ InitializationSequence E1ToC2(*this, Entity2, Kind, E1);
+ InitializationSequence E2ToC2(*this, Entity2, Kind, E2);
if (E1ToC2 && E2ToC2) {
// Both Composite1 and Composite2 are viable and are different;
// this is an ambiguity.
@@ -4663,8 +4674,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// Check whether Composite2 is viable.
InitializedEntity Entity2
= InitializedEntity::InitializeTemporary(Composite2);
- InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1);
- InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1);
+ InitializationSequence E1ToC2(*this, Entity2, Kind, E1);
+ InitializationSequence E2ToC2(*this, Entity2, Kind, E2);
if (!E1ToC2 || !E2ToC2)
return QualType();
@@ -4813,7 +4824,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
CheckDestructorAccess(E->getExprLoc(), Destructor,
PDiag(diag::err_access_dtor_temp)
<< E->getType());
- DiagnoseUseOfDecl(Destructor, E->getExprLoc());
+ if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
+ return ExprError();
// If destructor is trivial, we can avoid the extra copy.
if (Destructor->isTrivial())
@@ -4968,7 +4980,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
CheckDestructorAccess(Bind->getExprLoc(), Destructor,
PDiag(diag::err_access_dtor_temp)
<< Bind->getType());
- DiagnoseUseOfDecl(Destructor, Bind->getExprLoc());
+ if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()))
+ return ExprError();
// We need a cleanup, but we don't need to remember the temporary.
ExprNeedsCleanups = true;
@@ -5086,7 +5099,7 @@ ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
return ActOnCallExpr(/*Scope*/ 0,
MemExpr,
/*LPLoc*/ ExpectedLParenLoc,
- MultiExprArg(),
+ None,
/*RPLoc*/ ExpectedLParenLoc);
}
@@ -5434,7 +5447,7 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
ResultType = ResultType.getNonLValueExprType(Context);
CXXMemberCallExpr *CE =
- new (Context) CXXMemberCallExpr(Context, ME, MultiExprArg(), ResultType, VK,
+ new (Context) CXXMemberCallExpr(Context, ME, None, ResultType, VK,
Exp.get()->getLocEnd());
return CE;
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp
index 847db24..545ac27 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprMember.cpp
@@ -60,6 +60,9 @@ enum IMAKind {
/// The reference may be to an unresolved using declaration.
IMA_Unresolved,
+ /// The reference is a contextually-permitted abstract member reference.
+ IMA_Abstract,
+
/// The reference may be to an unresolved using declaration and the
/// context is not an instance method.
IMA_Unresolved_StaticContext,
@@ -105,7 +108,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
NamedDecl *D = *I;
if (D->isCXXInstanceMember()) {
- if (dyn_cast<FieldDecl>(D) || dyn_cast<IndirectFieldDecl>(D))
+ if (dyn_cast<FieldDecl>(D) || dyn_cast<MSPropertyDecl>(D)
+ || dyn_cast<IndirectFieldDecl>(D))
isField = true;
CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
@@ -119,19 +123,32 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
// member reference.
if (Classes.empty())
return IMA_Static;
-
- bool IsCXX11UnevaluatedField = false;
- if (SemaRef.getLangOpts().CPlusPlus11 && isField) {
- // C++11 [expr.prim.general]p12:
- // An id-expression that denotes a non-static data member or non-static
- // member function of a class can only be used:
- // (...)
- // - if that id-expression denotes a non-static data member and it
- // appears in an unevaluated operand.
- const Sema::ExpressionEvaluationContextRecord& record
- = SemaRef.ExprEvalContexts.back();
- if (record.Context == Sema::Unevaluated)
- IsCXX11UnevaluatedField = true;
+
+ // C++11 [expr.prim.general]p12:
+ // An id-expression that denotes a non-static data member or non-static
+ // member function of a class can only be used:
+ // (...)
+ // - if that id-expression denotes a non-static data member and it
+ // appears in an unevaluated operand.
+ //
+ // This rule is specific to C++11. However, we also permit this form
+ // in unevaluated inline assembly operands, like the operand to a SIZE.
+ IMAKind AbstractInstanceResult = IMA_Static; // happens to be 'false'
+ assert(!AbstractInstanceResult);
+ switch (SemaRef.ExprEvalContexts.back().Context) {
+ case Sema::Unevaluated:
+ if (isField && SemaRef.getLangOpts().CPlusPlus11)
+ AbstractInstanceResult = IMA_Field_Uneval_Context;
+ break;
+
+ case Sema::UnevaluatedAbstract:
+ AbstractInstanceResult = IMA_Abstract;
+ break;
+
+ case Sema::ConstantEvaluated:
+ case Sema::PotentiallyEvaluated:
+ case Sema::PotentiallyEvaluatedIfUsed:
+ break;
}
// If the current context is not an instance method, it can't be
@@ -140,8 +157,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
if (hasNonInstance)
return IMA_Mixed_StaticContext;
- return IsCXX11UnevaluatedField ? IMA_Field_Uneval_Context
- : IMA_Error_StaticContext;
+ return AbstractInstanceResult ? AbstractInstanceResult
+ : IMA_Error_StaticContext;
}
CXXRecordDecl *contextClass;
@@ -171,8 +188,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
// which case it's an error if any of those members are selected).
if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes))
return hasNonInstance ? IMA_Mixed_Unrelated :
- IsCXX11UnevaluatedField ? IMA_Field_Uneval_Context :
- IMA_Error_Unrelated;
+ AbstractInstanceResult ? AbstractInstanceResult :
+ IMA_Error_Unrelated;
return (hasNonInstance ? IMA_Mixed : IMA_Instance);
}
@@ -232,6 +249,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
<< R.getLookupNameInfo().getName();
// Fall through.
case IMA_Static:
+ case IMA_Abstract:
case IMA_Mixed_StaticContext:
case IMA_Unresolved_StaticContext:
if (TemplateArgs || TemplateKWLoc.isValid())
@@ -778,6 +796,19 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS,
return Owned(result);
}
+static ExprResult
+BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
+ const CXXScopeSpec &SS,
+ MSPropertyDecl *PD,
+ const DeclarationNameInfo &NameInfo) {
+ // Property names are always simple identifiers and therefore never
+ // require any interesting additional storage.
+ return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow,
+ S.Context.PseudoObjectTy, VK_LValue,
+ SS.getWithLocInContext(S.Context),
+ NameInfo.getLoc());
+}
+
/// \brief Build a MemberExpr AST node.
static MemberExpr *BuildMemberExpr(Sema &SemaRef,
ASTContext &C, Expr *Base, bool isArrow,
@@ -935,6 +966,10 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
SS, FD, FoundDecl, MemberNameInfo);
+ if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
+ return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD,
+ MemberNameInfo);
+
if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl))
// We may have found a field within an anonymous union or struct
// (C++ [class.union]).
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
index e7b5ec9..cf77896 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaExprObjC.cpp
@@ -239,7 +239,7 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
&CX.Idents.get("value"),
NumberType, /*TInfo=*/0, SC_None,
0);
- Method->setMethodParams(S.Context, value, ArrayRef<SourceLocation>());
+ Method->setMethodParams(S.Context, value, None);
}
if (!validateBoxingMethod(S, Loc, S.NSNumberDecl, Sel, Method))
@@ -343,7 +343,7 @@ static ExprResult CheckObjCCollectionLiteralElement(Sema &S, Expr *Element,
InitializationKind Kind
= InitializationKind::CreateCopy(Element->getLocStart(),
SourceLocation());
- InitializationSequence Seq(S, Entity, Kind, &Element, 1);
+ InitializationSequence Seq(S, Entity, Kind, Element);
if (!Seq.Failed())
return Seq.Perform(S, Entity, Kind, Element);
}
@@ -490,7 +490,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
Context.getPointerType(ConstCharType),
/*TInfo=*/0,
SC_None, 0);
- M->setMethodParams(Context, value, ArrayRef<SourceLocation>());
+ M->setMethodParams(Context, value, None);
BoxingMethod = M;
}
@@ -665,7 +665,7 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
Context.UnsignedLongTy,
/*TInfo=*/0, SC_None, 0);
Params.push_back(cnt);
- Method->setMethodParams(Context, Params, ArrayRef<SourceLocation>());
+ Method->setMethodParams(Context, Params, None);
}
if (!validateBoxingMethod(*this, SR.getBegin(), NSArrayDecl, Sel, Method))
@@ -788,7 +788,7 @@ ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
Context.UnsignedLongTy,
/*TInfo=*/0, SC_None, 0);
Params.push_back(cnt);
- Method->setMethodParams(Context, Params, ArrayRef<SourceLocation>());
+ Method->setMethodParams(Context, Params, None);
}
if (!validateBoxingMethod(*this, SR.getBegin(), NSDictionaryDecl, Sel,
@@ -1191,6 +1191,12 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
bool isClassMessage, bool isSuperMessage,
SourceLocation lbrac, SourceLocation rbrac,
QualType &ReturnType, ExprValueKind &VK) {
+ SourceLocation SelLoc;
+ if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+ SelLoc = SelectorLocs.front();
+ else
+ SelLoc = lbrac;
+
if (!Method) {
// Apply default argument promotion as for (C99 6.5.2.2p6).
for (unsigned i = 0; i != NumArgs; i++) {
@@ -1200,7 +1206,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
ExprResult result;
if (getLangOpts().DebuggerSupport) {
QualType paramTy; // ignored
- result = checkUnknownAnyArg(lbrac, Args[i], paramTy);
+ result = checkUnknownAnyArg(SelLoc, Args[i], paramTy);
} else {
result = DefaultArgumentPromotion(Args[i]);
}
@@ -1216,7 +1222,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
DiagID = isClassMessage ? diag::warn_class_method_not_found
: diag::warn_inst_method_not_found;
if (!getLangOpts().DebuggerSupport)
- Diag(lbrac, DiagID)
+ Diag(SelLoc, DiagID)
<< Sel << isClassMessage << SourceRange(SelectorLocs.front(),
SelectorLocs.back());
@@ -1242,7 +1248,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
NumNamedArgs = Method->param_size();
// FIXME. This need be cleaned up.
if (NumArgs < NumNamedArgs) {
- Diag(lbrac, diag::err_typecheck_call_too_few_args)
+ Diag(SelLoc, diag::err_typecheck_call_too_few_args)
<< 2 << NumNamedArgs << NumArgs;
return false;
}
@@ -1268,7 +1274,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
// from the argument.
if (param->getType() == Context.UnknownAnyTy) {
QualType paramType;
- ExprResult argE = checkUnknownAnyArg(lbrac, argExpr, paramType);
+ ExprResult argE = checkUnknownAnyArg(SelLoc, argExpr, paramType);
if (argE.isInvalid()) {
IsError = true;
} else {
@@ -1287,7 +1293,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
param);
- ExprResult ArgE = PerformCopyInitialization(Entity, lbrac, Owned(argExpr));
+ ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, Owned(argExpr));
if (ArgE.isInvalid())
IsError = true;
else
@@ -1317,10 +1323,11 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
}
}
- DiagnoseSentinelCalls(Method, lbrac, Args, NumArgs);
+ DiagnoseSentinelCalls(Method, SelLoc, Args, NumArgs);
// Do additional checkings on method.
- IsError |= CheckObjCMethodCall(Method, lbrac, Args, NumArgs);
+ IsError |= CheckObjCMethodCall(Method, SelLoc,
+ llvm::makeArrayRef<const Expr *>(Args, NumArgs));
return IsError;
}
@@ -1328,7 +1335,7 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType,
bool Sema::isSelfExpr(Expr *receiver) {
// 'self' is objc 'self' in an objc method only.
ObjCMethodDecl *method =
- dyn_cast<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
+ dyn_cast_or_null<ObjCMethodDecl>(CurContext->getNonClosureAncestor());
if (!method) return false;
receiver = receiver->IgnoreParenLValueCasts();
@@ -1993,7 +2000,12 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
<< FixItHint::CreateInsertion(Loc, "[");
LBracLoc = Loc;
}
-
+ SourceLocation SelLoc;
+ if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+ SelLoc = SelectorLocs.front();
+ else
+ SelLoc = Loc;
+
if (ReceiverType->isDependentType()) {
// If the receiver type is dependent, we can't type-check anything
// at this point. Build a dependent expression.
@@ -2018,7 +2030,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
assert(Class && "We don't know which class we're messaging?");
// objc++ diagnoses during typename annotation.
if (!getLangOpts().CPlusPlus)
- (void)DiagnoseUseOfDecl(Class, Loc);
+ (void)DiagnoseUseOfDecl(Class, SelLoc);
// Find the method we are messaging.
if (!Method) {
SourceRange TypeRange
@@ -2043,7 +2055,7 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
if (!Method)
Method = Class->lookupPrivateClassMethod(Sel);
- if (Method && DiagnoseUseOfDecl(Method, Loc))
+ if (Method && DiagnoseUseOfDecl(Method, SelLoc))
return ExprError();
}
@@ -2159,7 +2171,14 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
bool isImplicit) {
// The location of the receiver.
SourceLocation Loc = SuperLoc.isValid()? SuperLoc : Receiver->getLocStart();
-
+ SourceRange RecRange =
+ SuperLoc.isValid()? SuperLoc : Receiver->getSourceRange();
+ SourceLocation SelLoc;
+ if (!SelectorLocs.empty() && SelectorLocs.front().isValid())
+ SelLoc = SelectorLocs.front();
+ else
+ SelLoc = Loc;
+
if (LBracLoc.isInvalid()) {
Diag(Loc, diag::err_missing_open_square_message_send)
<< FixItHint::CreateInsertion(Loc, "[");
@@ -2264,7 +2283,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
// warn if instance method found for a Class message.
if (Method) {
- Diag(Loc, diag::warn_instance_method_on_class_found)
+ Diag(SelLoc, diag::warn_instance_method_on_class_found)
<< Method->getSelector() << Sel;
Diag(Method->getLocation(), diag::note_method_declared_at)
<< Method->getDeclName();
@@ -2279,7 +2298,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (!Method)
Method = ClassDecl->lookupPrivateClassMethod(Sel);
}
- if (Method && DiagnoseUseOfDecl(Method, Loc))
+ if (Method && DiagnoseUseOfDecl(Method, SelLoc))
return ExprError();
}
if (!Method) {
@@ -2298,7 +2317,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
if (const ObjCInterfaceDecl *ID =
dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
if (ID->getSuperClass())
- Diag(Loc, diag::warn_root_inst_method_not_found)
+ Diag(SelLoc, diag::warn_root_inst_method_not_found)
<< Sel << SourceRange(LBracLoc, RBracLoc);
}
}
@@ -2317,7 +2336,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
Method = LookupMethodInQualifiedType(Sel, QIdTy, true);
if (!Method)
Method = LookupMethodInQualifiedType(Sel, QIdTy, false);
- if (Method && DiagnoseUseOfDecl(Method, Loc))
+ if (Method && DiagnoseUseOfDecl(Method, SelLoc))
return ExprError();
} else if (const ObjCObjectPointerType *OCIType
= ReceiverType->getAsObjCInterfacePointerType()) {
@@ -2353,8 +2372,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
Method = ClassDecl->lookupPrivateMethod(Sel);
if (!Method && getLangOpts().ObjCAutoRefCount) {
- Diag(Loc, diag::err_arc_may_not_respond)
- << OCIType->getPointeeType() << Sel
+ Diag(SelLoc, diag::err_arc_may_not_respond)
+ << OCIType->getPointeeType() << Sel << RecRange
<< SourceRange(SelectorLocs.front(), SelectorLocs.back());
return ExprError();
}
@@ -2367,12 +2386,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
Method = LookupInstanceMethodInGlobalPool(Sel,
SourceRange(LBracLoc, RBracLoc));
if (Method && !forwardClass)
- Diag(Loc, diag::warn_maynot_respond)
- << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
+ Diag(SelLoc, diag::warn_maynot_respond)
+ << OCIType->getInterfaceDecl()->getIdentifier()
+ << Sel << RecRange;
}
}
}
- if (Method && DiagnoseUseOfDecl(Method, Loc, forwardClass))
+ if (Method && DiagnoseUseOfDecl(Method, SelLoc, forwardClass))
return ExprError();
} else {
// Reject other random receiver types (e.g. structs).
@@ -2401,8 +2421,6 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
diag::err_illegal_message_expr_incomplete_type))
return ExprError();
- SourceLocation SelLoc = SelectorLocs.front();
-
// In ARC, forbid the user from sending messages to
// retain/release/autorelease/dealloc/retainCount explicitly.
if (getLangOpts().ObjCAutoRefCount) {
@@ -2427,8 +2445,8 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
case OMF_release:
case OMF_autorelease:
case OMF_retainCount:
- Diag(Loc, diag::err_arc_illegal_explicit_message)
- << Sel << SelLoc;
+ Diag(SelLoc, diag::err_arc_illegal_explicit_message)
+ << Sel << RecRange;
break;
case OMF_performSelector:
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp
index 63309e3..9e8936e 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp
@@ -82,6 +82,24 @@ static Expr *IsStringInit(Expr *init, QualType declType, ASTContext &Context) {
return IsStringInit(init, arrayType, Context);
}
+/// Update the type of a string literal, including any surrounding parentheses,
+/// to match the type of the object which it is initializing.
+static void updateStringLiteralType(Expr *E, QualType Ty) {
+ while (true) {
+ E->setType(Ty);
+ if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E))
+ break;
+ else if (ParenExpr *PE = dyn_cast<ParenExpr>(E))
+ E = PE->getSubExpr();
+ else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E))
+ E = UO->getSubExpr();
+ else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E))
+ E = GSE->getResultExpr();
+ else
+ llvm_unreachable("unexpected expr in string literal init");
+ }
+}
+
static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
Sema &S) {
// Get the length of the string as parsed.
@@ -97,6 +115,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
ConstVal,
ArrayType::Normal, 0);
+ updateStringLiteralType(Str, DeclT);
return;
}
@@ -106,7 +125,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
// the size may be smaller or larger than the string we are initializing.
// FIXME: Avoid truncation for 64-bit length strings.
if (S.getLangOpts().CPlusPlus) {
- if (StringLiteral *SL = dyn_cast<StringLiteral>(Str)) {
+ if (StringLiteral *SL = dyn_cast<StringLiteral>(Str->IgnoreParens())) {
// For Pascal strings it's OK to strip off the terminating null character,
// so the example below is valid:
//
@@ -132,7 +151,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
// something like:
// char x[1] = "foo";
// then this will set the string literal's type to char[1].
- Str->setType(DeclT);
+ updateStringLiteralType(Str, DeclT);
}
//===----------------------------------------------------------------------===//
@@ -279,7 +298,7 @@ void InitListChecker::CheckValueInitializable(const InitializedEntity &Entity) {
SourceLocation Loc;
InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
true);
- InitializationSequence InitSeq(SemaRef, Entity, Kind, 0, 0);
+ InitializationSequence InitSeq(SemaRef, Entity, Kind, None);
if (InitSeq.Failed())
hadError = true;
}
@@ -293,6 +312,21 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
InitializedEntity MemberEntity
= InitializedEntity::InitializeMember(Field, &ParentEntity);
if (Init >= NumInits || !ILE->getInit(Init)) {
+ // If there's no explicit initializer but we have a default initializer, use
+ // that. This only happens in C++1y, since classes with default
+ // initializers are not aggregates in C++11.
+ if (Field->hasInClassInitializer()) {
+ Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,
+ ILE->getRBraceLoc(), Field);
+ if (Init < NumInits)
+ ILE->setInit(Init, DIE);
+ else {
+ ILE->updateInit(SemaRef.Context, Init, DIE);
+ RequiresSecondPass = true;
+ }
+ return;
+ }
+
// FIXME: We probably don't need to handle references
// specially here, since value-initialization of references is
// handled in InitializationSequence.
@@ -312,15 +346,15 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
true);
- InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, 0, 0);
+ InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, None);
if (!InitSeq) {
- InitSeq.Diagnose(SemaRef, MemberEntity, Kind, 0, 0);
+ InitSeq.Diagnose(SemaRef, MemberEntity, Kind, None);
hadError = true;
return;
}
ExprResult MemberInit
- = InitSeq.Perform(SemaRef, MemberEntity, Kind, MultiExprArg());
+ = InitSeq.Perform(SemaRef, MemberEntity, Kind, None);
if (MemberInit.isInvalid()) {
hadError = true;
return;
@@ -358,15 +392,24 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
Loc = ILE->getSyntacticForm()->getLocStart();
if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
- if (RType->getDecl()->isUnion() &&
- ILE->getInitializedFieldInUnion())
+ const RecordDecl *RDecl = RType->getDecl();
+ if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
FillInValueInitForField(0, ILE->getInitializedFieldInUnion(),
Entity, ILE, RequiresSecondPass);
- else {
+ else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&
+ cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {
+ for (RecordDecl::field_iterator Field = RDecl->field_begin(),
+ FieldEnd = RDecl->field_end();
+ Field != FieldEnd; ++Field) {
+ if (Field->hasInClassInitializer()) {
+ FillInValueInitForField(0, *Field, Entity, ILE, RequiresSecondPass);
+ break;
+ }
+ }
+ } else {
unsigned Init = 0;
- for (RecordDecl::field_iterator
- Field = RType->getDecl()->field_begin(),
- FieldEnd = RType->getDecl()->field_end();
+ for (RecordDecl::field_iterator Field = RDecl->field_begin(),
+ FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
@@ -381,7 +424,7 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
++Init;
// Only look at the first initialization of a union.
- if (RType->getDecl()->isUnion())
+ if (RDecl->isUnion())
break;
}
}
@@ -421,15 +464,15 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
if (!InitExpr && !ILE->hasArrayFiller()) {
InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
true);
- InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, 0, 0);
+ InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, None);
if (!InitSeq) {
- InitSeq.Diagnose(SemaRef, ElementEntity, Kind, 0, 0);
+ InitSeq.Diagnose(SemaRef, ElementEntity, Kind, None);
hadError = true;
return;
}
ExprResult ElementInit
- = InitSeq.Perform(SemaRef, ElementEntity, Kind, MultiExprArg());
+ = InitSeq.Perform(SemaRef, ElementEntity, Kind, None);
if (ElementInit.isInvalid()) {
hadError = true;
return;
@@ -784,12 +827,12 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
// FIXME: Better EqualLoc?
InitializationKind Kind =
InitializationKind::CreateCopy(expr->getLocStart(), SourceLocation());
- InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1);
+ InitializationSequence Seq(SemaRef, Entity, Kind, expr);
if (Seq) {
if (!VerifyOnly) {
ExprResult Result =
- Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
+ Seq.Perform(SemaRef, Entity, Kind, expr);
if (Result.isInvalid())
hadError = true;
@@ -819,8 +862,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
hadError = true;
else {
ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.take());
- if (ExprRes.isInvalid())
- hadError = true;
+ if (ExprRes.isInvalid())
+ hadError = true;
}
UpdateStructuredListElement(StructuredList, StructuredIndex,
ExprRes.takeAs<Expr>());
@@ -1323,8 +1366,23 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
}
if (DeclType->isUnionType() && IList->getNumInits() == 0) {
- // Value-initialize the first named member of the union.
RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
+
+ // If there's a default initializer, use it.
+ if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->hasInClassInitializer()) {
+ if (VerifyOnly)
+ return;
+ for (RecordDecl::field_iterator FieldEnd = RD->field_end();
+ Field != FieldEnd; ++Field) {
+ if (Field->hasInClassInitializer()) {
+ StructuredList->setInitializedFieldInUnion(*Field);
+ // FIXME: Actually build a CXXDefaultInitExpr?
+ return;
+ }
+ }
+ }
+
+ // Value-initialize the first named member of the union.
for (RecordDecl::field_iterator FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
if (Field->getDeclName()) {
@@ -1428,7 +1486,7 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
// Find first (if any) named field and emit warning.
for (RecordDecl::field_iterator it = Field, end = RD->field_end();
it != end; ++it) {
- if (!it->isUnnamedBitfield()) {
+ if (!it->isUnnamedBitfield() && !it->hasInClassInitializer()) {
SemaRef.Diag(IList->getSourceRange().getEnd(),
diag::warn_missing_field_initializers) << it->getName();
break;
@@ -1441,7 +1499,7 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity,
!Field->getType()->isIncompleteArrayType()) {
// FIXME: Should check for holes left by designated initializers too.
for (; Field != FieldEnd && !hadError; ++Field) {
- if (!Field->isUnnamedBitfield())
+ if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer())
CheckValueInitializable(
InitializedEntity::InitializeMember(*Field, &Entity));
}
@@ -2073,7 +2131,7 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
InitListExpr *Result
= new (SemaRef.Context) InitListExpr(SemaRef.Context,
- InitRange.getBegin(), MultiExprArg(),
+ InitRange.getBegin(), None,
InitRange.getEnd());
QualType ResultType = CurrentObjectType;
@@ -2336,6 +2394,7 @@ DeclarationName InitializedEntity::getName() const {
case EK_VectorElement:
case EK_ComplexElement:
case EK_BlockElement:
+ case EK_CompoundLiteralInit:
return DeclarationName();
}
@@ -2362,6 +2421,7 @@ DeclaratorDecl *InitializedEntity::getDecl() const {
case EK_ComplexElement:
case EK_BlockElement:
case EK_LambdaCapture:
+ case EK_CompoundLiteralInit:
return 0;
}
@@ -2379,6 +2439,7 @@ bool InitializedEntity::allowsNRVO() const {
case EK_Member:
case EK_New:
case EK_Temporary:
+ case EK_CompoundLiteralInit:
case EK_Base:
case EK_Delegating:
case EK_ArrayElement:
@@ -2409,6 +2470,7 @@ void InitializationSequence::Step::Destroy() {
case SK_QualificationConversionRValue:
case SK_QualificationConversionXValue:
case SK_QualificationConversionLValue:
+ case SK_LValueToRValue:
case SK_ListInitialization:
case SK_ListConstructorCall:
case SK_UnwrapInitList:
@@ -2555,6 +2617,15 @@ void InitializationSequence::AddQualificationConversionStep(QualType Ty,
Steps.push_back(S);
}
+void InitializationSequence::AddLValueToRValueStep(QualType Ty) {
+ assert(!Ty.hasQualifiers() && "rvalues may not have qualifiers");
+
+ Step S;
+ S.Kind = SK_LValueToRValue;
+ S.Type = Ty;
+ Steps.push_back(S);
+}
+
void InitializationSequence::AddConversionSequenceStep(
const ImplicitConversionSequence &ICS,
QualType T) {
@@ -2758,7 +2829,7 @@ static bool TryInitializerListConstruction(Sema &S,
static OverloadingResult
ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
- Expr **Args, unsigned NumArgs,
+ MultiExprArg Args,
OverloadCandidateSet &CandidateSet,
ArrayRef<NamedDecl *> Ctors,
OverloadCandidateSet::iterator &Best,
@@ -2784,7 +2855,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
// If we're performing copy initialization using a copy constructor, we
// suppress user-defined conversions on the arguments. We do the same for
// move constructors.
- if ((CopyInitializing || (InitListSyntax && NumArgs == 1)) &&
+ if ((CopyInitializing || (InitListSyntax && Args.size() == 1)) &&
Constructor->isCopyOrMoveConstructor())
SuppressUserConversions = true;
}
@@ -2794,8 +2865,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
(!OnlyListConstructors || S.isInitListConstructor(Constructor))) {
if (ConstructorTmpl)
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
- /*ExplicitArgs*/ 0,
- llvm::makeArrayRef(Args, NumArgs),
+ /*ExplicitArgs*/ 0, Args,
CandidateSet, SuppressUserConversions);
else {
// C++ [over.match.copy]p1:
@@ -2805,10 +2875,9 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
// context of direct-initialization, explicit conversion functions
// are also considered.
bool AllowExplicitConv = AllowExplicit && !CopyInitializing &&
- NumArgs == 1 &&
+ Args.size() == 1 &&
Constructor->isCopyOrMoveConstructor();
- S.AddOverloadCandidate(Constructor, FoundDecl,
- llvm::makeArrayRef(Args, NumArgs), CandidateSet,
+ S.AddOverloadCandidate(Constructor, FoundDecl, Args, CandidateSet,
SuppressUserConversions,
/*PartialOverloading=*/false,
/*AllowExplicit=*/AllowExplicitConv);
@@ -2828,11 +2897,10 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
static void TryConstructorInitialization(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- Expr **Args, unsigned NumArgs,
- QualType DestType,
+ MultiExprArg Args, QualType DestType,
InitializationSequence &Sequence,
bool InitListSyntax = false) {
- assert((!InitListSyntax || (NumArgs == 1 && isa<InitListExpr>(Args[0]))) &&
+ assert((!InitListSyntax || (Args.size() == 1 && isa<InitListExpr>(Args[0]))) &&
"InitListSyntax must come with a single initializer list argument.");
// The type we're constructing needs to be complete.
@@ -2881,15 +2949,14 @@ static void TryConstructorInitialization(Sema &S,
// If the initializer list has no elements and T has a default constructor,
// the first phase is omitted.
if (ILE->getNumInits() != 0 || !DestRecordDecl->hasDefaultConstructor())
- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs,
+ Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,
CandidateSet, Ctors, Best,
CopyInitialization, AllowExplicit,
/*OnlyListConstructor=*/true,
InitListSyntax);
// Time to unwrap the init list.
- Args = ILE->getInits();
- NumArgs = ILE->getNumInits();
+ Args = MultiExprArg(ILE->getInits(), ILE->getNumInits());
}
// C++11 [over.match.list]p1:
@@ -2899,7 +2966,7 @@ static void TryConstructorInitialization(Sema &S,
// elements of the initializer list.
if (Result == OR_No_Viable_Function) {
AsInitializerList = false;
- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs,
+ Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,
CandidateSet, Ctors, Best,
CopyInitialization, AllowExplicit,
/*OnlyListConstructors=*/false,
@@ -3106,8 +3173,8 @@ static void TryListInitialization(Sema &S,
return;
// - Otherwise, if T is a class type, constructors are considered.
- Expr *Arg = InitList;
- TryConstructorInitialization(S, Entity, Kind, &Arg, 1, DestType,
+ Expr *InitListAsExpr = InitList;
+ TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType,
Sequence, /*InitListSyntax*/true);
} else
Sequence.SetFailed(
@@ -3351,6 +3418,57 @@ static void TryReferenceInitialization(Sema &S,
T1Quals, cv2T2, T2, T2Quals, Sequence);
}
+/// Converts the target of reference initialization so that it has the
+/// appropriate qualifiers and value kind.
+///
+/// In this case, 'x' is an 'int' lvalue, but it needs to be 'const int'.
+/// \code
+/// int x;
+/// const int &r = x;
+/// \endcode
+///
+/// In this case the reference is binding to a bitfield lvalue, which isn't
+/// valid. Perform a load to create a lifetime-extended temporary instead.
+/// \code
+/// const int &r = someStruct.bitfield;
+/// \endcode
+static ExprValueKind
+convertQualifiersAndValueKindIfNecessary(Sema &S,
+ InitializationSequence &Sequence,
+ Expr *Initializer,
+ QualType cv1T1,
+ Qualifiers T1Quals,
+ Qualifiers T2Quals,
+ bool IsLValueRef) {
+ bool IsNonAddressableType = Initializer->refersToBitField() ||
+ Initializer->refersToVectorElement();
+
+ if (IsNonAddressableType) {
+ // C++11 [dcl.init.ref]p5: [...] Otherwise, the reference shall be an
+ // lvalue reference to a non-volatile const type, or the reference shall be
+ // an rvalue reference.
+ //
+ // If not, we can't make a temporary and bind to that. Give up and allow the
+ // error to be diagnosed later.
+ if (IsLValueRef && (!T1Quals.hasConst() || T1Quals.hasVolatile())) {
+ assert(Initializer->isGLValue());
+ return Initializer->getValueKind();
+ }
+
+ // Force a load so we can materialize a temporary.
+ Sequence.AddLValueToRValueStep(cv1T1.getUnqualifiedType());
+ return VK_RValue;
+ }
+
+ if (T1Quals != T2Quals) {
+ Sequence.AddQualificationConversionStep(cv1T1,
+ Initializer->getValueKind());
+ }
+
+ return Initializer->getValueKind();
+}
+
+
/// \brief Reference initialization without resolving overloaded functions.
static void TryReferenceInitializationCore(Sema &S,
const InitializedEntity &Entity,
@@ -3406,11 +3524,11 @@ static void TryReferenceInitializationCore(Sema &S,
Sequence.AddObjCObjectConversionStep(
S.Context.getQualifiedType(T1, T2Quals));
- if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1, VK_LValue);
- bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
- (Initializer->getBitField() || Initializer->refersToVectorElement());
- Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
+ ExprValueKind ValueKind =
+ convertQualifiersAndValueKindIfNecessary(S, Sequence, Initializer,
+ cv1T1, T1Quals, T2Quals,
+ isLValueRef);
+ Sequence.AddReferenceBindingStep(cv1T1, ValueKind == VK_RValue);
return;
}
@@ -3493,10 +3611,12 @@ static void TryReferenceInitializationCore(Sema &S,
Sequence.AddObjCObjectConversionStep(
S.Context.getQualifiedType(T1, T2Quals));
- if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1, ValueKind);
- Sequence.AddReferenceBindingStep(cv1T1,
- /*bindingTemporary=*/InitCategory.isPRValue());
+ ValueKind = convertQualifiersAndValueKindIfNecessary(S, Sequence,
+ Initializer, cv1T1,
+ T1Quals, T2Quals,
+ isLValueRef);
+
+ Sequence.AddReferenceBindingStep(cv1T1, ValueKind == VK_RValue);
return;
}
@@ -3668,12 +3788,11 @@ static void TryValueInitialization(Sema &S,
// building the constructor call. This affects the semantics of a few
// things (such as whether an explicit default constructor can be called).
Expr *InitListAsExpr = InitList;
- Expr **Args = InitList ? &InitListAsExpr : 0;
- unsigned NumArgs = InitList ? 1 : 0;
+ MultiExprArg Args(&InitListAsExpr, InitList ? 1 : 0);
bool InitListSyntax = InitList;
- return TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, T,
- Sequence, InitListSyntax);
+ return TryConstructorInitialization(S, Entity, Kind, Args, T, Sequence,
+ InitListSyntax);
}
}
@@ -3696,7 +3815,7 @@ static void TryDefaultInitialization(Sema &S,
// constructor for T is called (and the initialization is ill-formed if
// T has no accessible default constructor);
if (DestType->isRecordType() && S.getLangOpts().CPlusPlus) {
- TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, Sequence);
+ TryConstructorInitialization(S, Entity, Kind, None, DestType, Sequence);
return;
}
@@ -4068,11 +4187,25 @@ static bool TryOCLZeroEventInitialization(Sema &S,
InitializationSequence::InitializationSequence(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- Expr **Args,
- unsigned NumArgs)
+ MultiExprArg Args)
: FailedCandidateSet(Kind.getLocation()) {
ASTContext &Context = S.Context;
+ // Eliminate non-overload placeholder types in the arguments. We
+ // need to do this before checking whether types are dependent
+ // because lowering a pseudo-object expression might well give us
+ // something of dependent type.
+ for (unsigned I = 0, E = Args.size(); I != E; ++I)
+ if (Args[I]->getType()->isNonOverloadPlaceholderType()) {
+ // FIXME: should we be doing this here?
+ ExprResult result = S.CheckPlaceholderExpr(Args[I]);
+ if (result.isInvalid()) {
+ SetFailed(FK_PlaceholderType);
+ return;
+ }
+ Args[I] = result.take();
+ }
+
// C++0x [dcl.init]p16:
// The semantics of initializers are as follows. The destination type is
// the type of the object or reference being initialized and the source
@@ -4082,7 +4215,7 @@ InitializationSequence::InitializationSequence(Sema &S,
QualType DestType = Entity.getType();
if (DestType->isDependentType() ||
- Expr::hasAnyTypeDependentArguments(llvm::makeArrayRef(Args, NumArgs))) {
+ Expr::hasAnyTypeDependentArguments(Args)) {
SequenceKind = DependentSequence;
return;
}
@@ -4090,21 +4223,9 @@ InitializationSequence::InitializationSequence(Sema &S,
// Almost everything is a normal sequence.
setSequenceKind(NormalSequence);
- for (unsigned I = 0; I != NumArgs; ++I)
- if (Args[I]->getType()->isNonOverloadPlaceholderType()) {
- // FIXME: should we be doing this here?
- ExprResult result = S.CheckPlaceholderExpr(Args[I]);
- if (result.isInvalid()) {
- SetFailed(FK_PlaceholderType);
- return;
- }
- Args[I] = result.take();
- }
-
-
QualType SourceType;
Expr *Initializer = 0;
- if (NumArgs == 1) {
+ if (Args.size() == 1) {
Initializer = Args[0];
if (!isa<InitListExpr>(Initializer))
SourceType = Initializer->getType();
@@ -4126,7 +4247,7 @@ InitializationSequence::InitializationSequence(Sema &S,
// (8.3.2), shall be initialized by an object, or function, of type T or
// by an object that can be converted into a T.
// (Therefore, multiple arguments are not permitted.)
- if (NumArgs != 1)
+ if (Args.size() != 1)
SetFailed(FK_TooManyInitsForReference);
else
TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
@@ -4135,7 +4256,7 @@ InitializationSequence::InitializationSequence(Sema &S,
// - If the initializer is (), the object is value-initialized.
if (Kind.getKind() == InitializationKind::IK_Value ||
- (Kind.getKind() == InitializationKind::IK_Direct && NumArgs == 0)) {
+ (Kind.getKind() == InitializationKind::IK_Direct && Args.empty())) {
TryValueInitialization(S, Entity, Kind, *this);
return;
}
@@ -4232,7 +4353,7 @@ InitializationSequence::InitializationSequence(Sema &S,
(Kind.getKind() == InitializationKind::IK_Copy &&
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
S.IsDerivedFrom(SourceType, DestType))))
- TryConstructorInitialization(S, Entity, Kind, Args, NumArgs,
+ TryConstructorInitialization(S, Entity, Kind, Args,
Entity.getType(), *this);
// - Otherwise (i.e., for the remaining copy-initialization cases),
// user-defined conversion sequences that can convert from the source
@@ -4245,11 +4366,11 @@ InitializationSequence::InitializationSequence(Sema &S,
return;
}
- if (NumArgs > 1) {
+ if (Args.size() > 1) {
SetFailed(FK_TooManyInitsForScalar);
return;
}
- assert(NumArgs == 1 && "Zero-argument case handled above");
+ assert(Args.size() == 1 && "Zero-argument case handled above");
// - Otherwise, if the source type is a (possibly cv-qualified) class
// type, conversion functions are considered.
@@ -4350,6 +4471,7 @@ getAssignmentAction(const InitializedEntity &Entity) {
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_LambdaCapture:
+ case InitializedEntity::EK_CompoundLiteralInit:
return Sema::AA_Initializing;
}
@@ -4372,6 +4494,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) {
case InitializedEntity::EK_Exception:
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_LambdaCapture:
+ case InitializedEntity::EK_CompoundLiteralInit:
return false;
case InitializedEntity::EK_Parameter:
@@ -4402,6 +4525,7 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) {
case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_Exception:
+ case InitializedEntity::EK_CompoundLiteralInit:
return true;
}
@@ -4483,6 +4607,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity,
case InitializedEntity::EK_VectorElement:
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_BlockElement:
+ case InitializedEntity::EK_CompoundLiteralInit:
return Initializer->getLocStart();
}
llvm_unreachable("missed an InitializedEntity kind?");
@@ -4619,8 +4744,7 @@ static ExprResult CopyObject(Sema &S,
// Determine the arguments required to actually perform the
// constructor call (we might have derived-to-base conversions, or
// the copy constructor may have default arguments).
- if (S.CompleteConstructorCall(Constructor, MultiExprArg(&CurInitExpr, 1),
- Loc, ConstructorArgs))
+ if (S.CompleteConstructorCall(Constructor, CurInitExpr, Loc, ConstructorArgs))
return ExprError();
// Actually perform the constructor call.
@@ -4711,6 +4835,31 @@ static bool isReferenceBinding(const InitializationSequence::Step &s) {
s.Kind == InitializationSequence::SK_BindReferenceToTemporary;
}
+/// Returns true if the parameters describe a constructor initialization of
+/// an explicit temporary object, e.g. "Point(x, y)".
+static bool isExplicitTemporary(const InitializedEntity &Entity,
+ const InitializationKind &Kind,
+ unsigned NumArgs) {
+ switch (Entity.getKind()) {
+ case InitializedEntity::EK_Temporary:
+ case InitializedEntity::EK_CompoundLiteralInit:
+ break;
+ default:
+ return false;
+ }
+
+ switch (Kind.getKind()) {
+ case InitializationKind::IK_DirectList:
+ return true;
+ // FIXME: Hack to work around cast weirdness.
+ case InitializationKind::IK_Direct:
+ case InitializationKind::IK_Value:
+ return NumArgs != 1;
+ default:
+ return false;
+ }
+}
+
static ExprResult
PerformConstructorInitialization(Sema &S,
const InitializedEntity &Entity,
@@ -4761,14 +4910,11 @@ PerformConstructorInitialization(Sema &S,
return ExprError();
- if (Entity.getKind() == InitializedEntity::EK_Temporary &&
- (Kind.getKind() == InitializationKind::IK_DirectList ||
- (NumArgs != 1 && // FIXME: Hack to work around cast weirdness
- (Kind.getKind() == InitializationKind::IK_Direct ||
- Kind.getKind() == InitializationKind::IK_Value)))) {
+ if (isExplicitTemporary(Entity, Kind, NumArgs)) {
// An explicitly-constructed temporary, e.g., X(1, 2).
S.MarkFunctionReferenced(Loc, Constructor);
- S.DiagnoseUseOfDecl(Constructor, Loc);
+ if (S.DiagnoseUseOfDecl(Constructor, Loc))
+ return ExprError();
TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo();
if (!TSInfo)
@@ -4827,7 +4973,8 @@ PerformConstructorInitialization(Sema &S,
// Only check access if all of that succeeded.
S.CheckConstructorAccess(Loc, Constructor, Entity,
Step.Function.FoundDecl.getAccess());
- S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc);
+ if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
+ return ExprError();
if (shouldBindAsTemporary(Entity))
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
@@ -4865,6 +5012,7 @@ InitializedEntityOutlivesFullExpression(const InitializedEntity &Entity) {
case InitializedEntity::EK_Parameter:
case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_LambdaCapture:
+ case InitializedEntity::EK_CompoundLiteralInit:
// The entity being initialized might not outlive the full-expression.
return false;
}
@@ -4879,8 +5027,7 @@ InitializationSequence::Perform(Sema &S,
MultiExprArg Args,
QualType *ResultType) {
if (Failed()) {
- unsigned NumArgs = Args.size();
- Diagnose(S, Entity, Kind, Args.data(), NumArgs);
+ Diagnose(S, Entity, Kind, Args);
return ExprError();
}
@@ -4988,6 +5135,7 @@ InitializationSequence::Perform(Sema &S,
case SK_QualificationConversionLValue:
case SK_QualificationConversionXValue:
case SK_QualificationConversionRValue:
+ case SK_LValueToRValue:
case SK_ConversionSequence:
case SK_ListInitialization:
case SK_UnwrapInitList:
@@ -5030,7 +5178,8 @@ InitializationSequence::Perform(Sema &S,
// Overload resolution determined which function invoke; update the
// initializer to reflect that choice.
S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl);
- S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation());
+ if (S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()))
+ return ExprError();
CurInit = S.FixOverloadedFunctionReference(CurInit,
Step->Function.FoundDecl,
Step->Function.Function);
@@ -5076,13 +5225,18 @@ InitializationSequence::Perform(Sema &S,
}
case SK_BindReference:
- if (FieldDecl *BitField = CurInit.get()->getBitField()) {
- // References cannot bind to bit fields (C++ [dcl.init.ref]p5).
+ // References cannot bind to bit-fields (C++ [dcl.init.ref]p5).
+ if (CurInit.get()->refersToBitField()) {
+ // We don't necessarily have an unambiguous source bit-field.
+ FieldDecl *BitField = CurInit.get()->getSourceBitField();
S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
<< Entity.getType().isVolatileQualified()
- << BitField->getDeclName()
+ << (BitField ? BitField->getDeclName() : DeclarationName())
+ << (BitField != NULL)
<< CurInit.get()->getSourceRange();
- S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
+ if (BitField)
+ S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
+
return ExprError();
}
@@ -5104,6 +5258,9 @@ InitializationSequence::Perform(Sema &S,
break;
case SK_BindReferenceToTemporary:
+ // Make sure the "temporary" is actually an rvalue.
+ assert(CurInit.get()->isRValue() && "not a temporary");
+
// Check exception specifications
if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType))
return ExprError();
@@ -5163,7 +5320,8 @@ InitializationSequence::Perform(Sema &S,
S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
FoundFn.getAccess());
- S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
+ if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
+ return ExprError();
CastKind = CK_ConstructorConversion;
QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
@@ -5177,7 +5335,8 @@ InitializationSequence::Perform(Sema &S,
CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), 0,
FoundFn);
- S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
+ if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
+ return ExprError();
// FIXME: Should we move this initialization into a separate
// derived-to-base conversion? I believe the answer is "no", because
@@ -5211,7 +5370,8 @@ InitializationSequence::Perform(Sema &S,
S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor,
S.PDiag(diag::err_access_dtor_temp) << T);
S.MarkFunctionReferenced(CurInit.get()->getLocStart(), Destructor);
- S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart());
+ if (S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart()))
+ return ExprError();
}
}
@@ -5241,6 +5401,16 @@ InitializationSequence::Perform(Sema &S,
break;
}
+ case SK_LValueToRValue: {
+ assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");
+ CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type,
+ CK_LValueToRValue,
+ CurInit.take(),
+ /*BasePath=*/0,
+ VK_RValue));
+ break;
+ }
+
case SK_ConversionSequence: {
Sema::CheckedConversionKind CCK
= Kind.isCStyleCast()? Sema::CCK_CStyleCast
@@ -5483,7 +5653,8 @@ InitializationSequence::Perform(Sema &S,
S.MarkFunctionReferenced(Kind.getLocation(), Destructor);
S.CheckDestructorAccess(Kind.getLocation(), Destructor,
S.PDiag(diag::err_access_dtor_temp) << E);
- S.DiagnoseUseOfDecl(Destructor, Kind.getLocation());
+ if (S.DiagnoseUseOfDecl(Destructor, Kind.getLocation()))
+ return ExprError();
}
}
}
@@ -5621,7 +5792,7 @@ static void emitBadConversionNotes(Sema &S, const InitializedEntity &entity,
bool InitializationSequence::Diagnose(Sema &S,
const InitializedEntity &Entity,
const InitializationKind &Kind,
- Expr **Args, unsigned NumArgs) {
+ ArrayRef<Expr *> Args) {
if (!Failed())
return false;
@@ -5629,7 +5800,7 @@ bool InitializationSequence::Diagnose(Sema &S,
switch (Failure) {
case FK_TooManyInitsForReference:
// FIXME: Customize for the initialized entity?
- if (NumArgs == 0) {
+ if (Args.empty()) {
// Dig out the reference subobject which is uninitialized and diagnose it.
// If this is value-initialization, this could be nested some way within
// the target type.
@@ -5641,7 +5812,7 @@ bool InitializationSequence::Diagnose(Sema &S,
(void)Diagnosed;
} else // FIXME: diagnostic below could be better!
S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits)
- << SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd());
+ << SourceRange(Args.front()->getLocStart(), Args.back()->getLocEnd());
break;
case FK_ArrayNeedsInitList:
@@ -5688,16 +5859,14 @@ bool InitializationSequence::Diagnose(Sema &S,
<< DestType << Args[0]->getType()
<< Args[0]->getSourceRange();
- FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
- llvm::makeArrayRef(Args, NumArgs));
+ FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
break;
case OR_No_Viable_Function:
S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
<< Args[0]->getType() << DestType.getNonReferenceType()
<< Args[0]->getSourceRange();
- FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates,
- llvm::makeArrayRef(Args, NumArgs));
+ FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
break;
case OR_Deleted: {
@@ -5790,7 +5959,7 @@ bool InitializationSequence::Diagnose(Sema &S,
R = SourceRange(InitList->getInit(0)->getLocEnd(),
InitList->getLocEnd());
else
- R = SourceRange(Args[0]->getLocEnd(), Args[NumArgs - 1]->getLocEnd());
+ R = SourceRange(Args.front()->getLocEnd(), Args.back()->getLocEnd());
R.setBegin(S.PP.getLocForEndOfToken(R.getBegin()));
if (Kind.isCStyleOrFunctionalCast())
@@ -5815,15 +5984,14 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_ListConstructorOverloadFailed:
case FK_ConstructorOverloadFailed: {
SourceRange ArgsRange;
- if (NumArgs)
- ArgsRange = SourceRange(Args[0]->getLocStart(),
- Args[NumArgs - 1]->getLocEnd());
+ if (Args.size())
+ ArgsRange = SourceRange(Args.front()->getLocStart(),
+ Args.back()->getLocEnd());
if (Failure == FK_ListConstructorOverloadFailed) {
- assert(NumArgs == 1 && "List construction from other than 1 argument.");
+ assert(Args.size() == 1 && "List construction from other than 1 argument.");
InitListExpr *InitList = cast<InitListExpr>(Args[0]);
- Args = InitList->getInits();
- NumArgs = InitList->getNumInits();
+ Args = MultiExprArg(InitList->getInits(), InitList->getNumInits());
}
// FIXME: Using "DestType" for the entity we're printing is probably
@@ -5832,8 +6000,7 @@ bool InitializationSequence::Diagnose(Sema &S,
case OR_Ambiguous:
S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
<< DestType << ArgsRange;
- FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
- llvm::makeArrayRef(Args, NumArgs));
+ FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args);
break;
case OR_No_Viable_Function:
@@ -5880,8 +6047,7 @@ bool InitializationSequence::Diagnose(Sema &S,
S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
<< DestType << ArgsRange;
- FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates,
- llvm::makeArrayRef(Args, NumArgs));
+ FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args);
break;
case OR_Deleted: {
@@ -6185,6 +6351,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
OS << "qualification conversion (lvalue)";
break;
+ case SK_LValueToRValue:
+ OS << "load (lvalue to rvalue)";
+ break;
+
case SK_ConversionSequence:
OS << "implicit conversion sequence (";
S->ICS->DebugPrint(); // FIXME: use OS
@@ -6395,7 +6565,7 @@ Sema::CanPerformCopyInitialization(const InitializedEntity &Entity,
InitializationKind Kind
= InitializationKind::CreateCopy(InitE->getLocStart(), SourceLocation());
- InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
+ InitializationSequence Seq(*this, Entity, Kind, InitE);
return !Seq.Failed();
}
@@ -6417,10 +6587,10 @@ Sema::PerformCopyInitialization(const InitializedEntity &Entity,
InitializationKind Kind = InitializationKind::CreateCopy(InitE->getLocStart(),
EqualLoc,
AllowExplicit);
- InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
+ InitializationSequence Seq(*this, Entity, Kind, InitE);
Init.release();
- ExprResult Result = Seq.Perform(*this, Entity, Kind, MultiExprArg(&InitE, 1));
+ ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
if (!Result.isInvalid() && TopLevelOfInitList)
DiagnoseNarrowingInInitList(*this, Seq, Entity.getType(),
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
index 53fa6da..c7ba3cc 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaLambda.cpp
@@ -452,8 +452,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
FunctionProtoType::ExtProtoInfo EPI;
EPI.HasTrailingReturn = true;
EPI.TypeQuals |= DeclSpec::TQ_const;
- QualType MethodTy = Context.getFunctionType(Context.DependentTy,
- ArrayRef<QualType>(),
+ QualType MethodTy = Context.getFunctionType(Context.DependentTy, None,
EPI);
MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
ExplicitParams = false;
@@ -708,7 +707,7 @@ static void addFunctionPointerConversion(Sema &S,
FunctionProtoType::ExtProtoInfo ExtInfo;
ExtInfo.TypeQuals = Qualifiers::Const;
QualType ConvTy =
- S.Context.getFunctionType(FunctionPtrTy, ArrayRef<QualType>(), ExtInfo);
+ S.Context.getFunctionType(FunctionPtrTy, None, ExtInfo);
SourceLocation Loc = IntroducerRange.getBegin();
DeclarationName Name
@@ -779,8 +778,7 @@ static void addBlockPointerConversion(Sema &S,
FunctionProtoType::ExtProtoInfo ExtInfo;
ExtInfo.TypeQuals = Qualifiers::Const;
- QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, ArrayRef<QualType>(),
- ExtInfo);
+ QualType ConvTy = S.Context.getFunctionType(BlockPtrTy, None, ExtInfo);
SourceLocation Loc = IntroducerRange.getBegin();
DeclarationName Name
@@ -862,6 +860,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
CaptureDefault = LCD_ByCopy;
break;
+ case CapturingScopeInfo::ImpCap_CapturedRegion:
case CapturingScopeInfo::ImpCap_LambdaByref:
CaptureDefault = LCD_ByRef;
break;
@@ -949,6 +948,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
if (!CurContext->isDependentContext()) {
switch (ExprEvalContexts.back().Context) {
case Unevaluated:
+ case UnevaluatedAbstract:
// We don't actually diagnose this case immediately, because we
// could be within a context where we might find out later that
// the expression is potentially evaluated (e.g., for typeid).
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp
index f26b8ed..9ab3b2d 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaLookup.cpp
@@ -731,7 +731,7 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {
EPI.NumExceptions = 0;
QualType ExpectedType
= R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(),
- ArrayRef<QualType>(), EPI);
+ None, EPI);
// Perform template argument deduction against the type that we would
// expect the function to have.
@@ -884,6 +884,8 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
// }
// }
//
+ UnqualUsingDirectiveSet UDirs;
+ bool VisitedUsingDirectives = false;
DeclContext *OutsideOfTemplateParamDC = 0;
for (; S && !isNamespaceOrTranslationUnitScope(S); S = S->getParent()) {
DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity());
@@ -957,9 +959,28 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
// If this is a file context, we need to perform unqualified name
// lookup considering using directives.
if (Ctx->isFileContext()) {
- UnqualUsingDirectiveSet UDirs;
- UDirs.visit(Ctx, Ctx);
- UDirs.done();
+ // If we haven't handled using directives yet, do so now.
+ if (!VisitedUsingDirectives) {
+ // Add using directives from this context up to the top level.
+ for (DeclContext *UCtx = Ctx; UCtx; UCtx = UCtx->getParent()) {
+ if (UCtx->isTransparentContext())
+ continue;
+
+ UDirs.visit(UCtx, UCtx);
+ }
+
+ // Find the innermost file scope, so we can add using directives
+ // from local scopes.
+ Scope *InnermostFileScope = S;
+ while (InnermostFileScope &&
+ !isNamespaceOrTranslationUnitScope(InnermostFileScope))
+ InnermostFileScope = InnermostFileScope->getParent();
+ UDirs.visitScopeChain(Initial, InnermostFileScope);
+
+ UDirs.done();
+
+ VisitedUsingDirectives = true;
+ }
if (CppNamespaceLookup(*this, R, Context, Ctx, UDirs)) {
R.resolveKind();
@@ -994,11 +1015,11 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
//
// FIXME: Cache this sorted list in Scope structure, and DeclContext, so we
// don't build it for each lookup!
-
- UnqualUsingDirectiveSet UDirs;
- UDirs.visitScopeChain(Initial, S);
- UDirs.done();
-
+ if (!VisitedUsingDirectives) {
+ UDirs.visitScopeChain(Initial, S);
+ UDirs.done();
+ }
+
// Lookup namespace scope, and global scope.
// Unqualified name lookup in C++ requires looking into scopes
// that aren't strictly lexical, and therefore we walk through the
@@ -2066,6 +2087,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
case Type::Complex:
break;
+ // Non-deduced auto types only get here for error cases.
+ case Type::Auto:
+ break;
+
// If T is an Objective-C object or interface type, or a pointer to an
// object or interface type, the associated namespace is the global
// namespace.
@@ -2561,6 +2586,12 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
bool IsRaw = false;
bool IsExactMatch = false;
+ // If the declaration we found is invalid, skip it.
+ if (D->isInvalidDecl()) {
+ F.erase();
+ continue;
+ }
+
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->getNumParams() == 1 &&
FD->getParamDecl(0)->getType()->getAs<PointerType>())
@@ -3405,7 +3436,7 @@ class NamespaceSpecifierSet {
}
DeclContextList NamespaceSpecifierSet::BuildContextChain(DeclContext *Start) {
- assert(Start && "Bulding a context chain from a null context");
+ assert(Start && "Building a context chain from a null context");
DeclContextList Chain;
for (DeclContext *DC = Start->getPrimaryContext(); DC != NULL;
DC = DC->getLookupParent()) {
@@ -3761,13 +3792,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
if (S && S->isInObjcMethodScope() && Typo == getSuperIdentifier())
return TypoCorrection();
- // This is for testing.
- if (Diags.getWarnOnSpellCheck()) {
- unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
- "spell-checking initiated for %0");
- Diag(TypoName.getLoc(), DiagID) << TypoName.getName();
- }
-
NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
TypoCorrectionConsumer Consumer(*this, Typo);
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
index c348a9c..91f0881 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
@@ -996,8 +996,10 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
PropertyIvarType->getAs<ObjCObjectPointerType>()) {
const ObjCInterfaceDecl *ObjI = ObjT->getInterfaceDecl();
if (ObjI && ObjI->isArcWeakrefUnavailable()) {
- Diag(PropertyDiagLoc, diag::err_arc_weak_unavailable_property);
- Diag(property->getLocation(), diag::note_property_declare);
+ Diag(property->getLocation(),
+ diag::err_arc_weak_unavailable_property) << PropertyIvarType;
+ Diag(ClassImpDecl->getLocation(), diag::note_implemented_by_class)
+ << ClassImpDecl->getName();
err = true;
}
}
@@ -1660,8 +1662,7 @@ void Sema::DefaultSynthesizeProperties(Scope *S, Decl *D) {
}
void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
- ObjCContainerDecl *CDecl,
- const SelectorSet &InsMap) {
+ ObjCContainerDecl *CDecl) {
ObjCContainerDecl::PropertyMap NoNeedToImplPropMap;
ObjCInterfaceDecl *IDecl;
// Gather properties which need not be implemented in this class
@@ -1690,6 +1691,26 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
EI = IMPDecl->propimpl_end(); I != EI; ++I)
PropImplMap.insert(I->getPropertyDecl());
+ SelectorSet InsMap;
+ // Collect property accessors implemented in current implementation.
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
+ InsMap.insert((*I)->getSelector());
+
+ ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
+ ObjCInterfaceDecl *PrimaryClass = 0;
+ if (C && !C->IsClassExtension())
+ if ((PrimaryClass = C->getClassInterface()))
+ // Report unimplemented properties in the category as well.
+ if (ObjCImplDecl *IMP = PrimaryClass->getImplementation()) {
+ // When reporting on missing setter/getters, do not report when
+ // setter/getter is implemented in category's primary class
+ // implementation.
+ for (ObjCImplementationDecl::instmeth_iterator
+ I = IMP->instmeth_begin(), E = IMP->instmeth_end(); I!=E; ++I)
+ InsMap.insert((*I)->getSelector());
+ }
+
for (ObjCContainerDecl::PropertyMap::iterator
P = PropMap.begin(), E = PropMap.end(); P != E; ++P) {
ObjCPropertyDecl *Prop = P->second;
@@ -1699,7 +1720,13 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
PropImplMap.count(Prop) ||
Prop->getAvailability() == AR_Unavailable)
continue;
- if (!InsMap.count(Prop->getGetterName())) {
+ // When reporting on missing property getter implementation in
+ // categories, do not report when they are declared in primary class,
+ // class's protocol, or one of it super classes. This is because,
+ // the class is going to implement them.
+ if (!InsMap.count(Prop->getGetterName()) &&
+ (PrimaryClass == 0 ||
+ !PrimaryClass->lookupPropertyAccessor(Prop->getGetterName(), C))) {
Diag(IMPDecl->getLocation(),
isa<ObjCCategoryDecl>(CDecl) ?
diag::warn_setter_getter_impl_required_in_category :
@@ -1713,8 +1740,13 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
Diag(RID->getLocation(), diag::note_suppressed_class_declare);
}
-
- if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName())) {
+ // When reporting on missing property setter implementation in
+ // categories, do not report when they are declared in primary class,
+ // class's protocol, or one of it super classes. This is because,
+ // the class is going to implement them.
+ if (!Prop->isReadOnly() && !InsMap.count(Prop->getSetterName()) &&
+ (PrimaryClass == 0 ||
+ !PrimaryClass->lookupPropertyAccessor(Prop->getSetterName(), C))) {
Diag(IMPDecl->getLocation(),
isa<ObjCCategoryDecl>(CDecl) ?
diag::warn_setter_getter_impl_required_in_category :
@@ -1975,8 +2007,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
/*TInfo=*/0,
SC_None,
0);
- SetterMethod->setMethodParams(Context, Argument,
- ArrayRef<SourceLocation>());
+ SetterMethod->setMethodParams(Context, Argument, None);
AddPropertyAttrs(*this, SetterMethod, property);
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
index b8acb2d..c815d4f 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOpenMP.cpp
@@ -165,8 +165,8 @@ OMPThreadPrivateDecl *Sema::CheckOMPThreadPrivateDecl(
continue;
}
- // Check if threadspecified is set.
- if (VD->isThreadSpecified()) {
+ // Check if this is a TLS variable.
+ if (VD->getTLSKind()) {
Diag(ILoc, diag::err_omp_var_thread_local) << VD;
Diag(VD->getLocation(), diag::note_forward_declaration) << VD;
continue;
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
index 89d495d..529ba12 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaOverload.cpp
@@ -42,13 +42,15 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl,
bool HadMultipleCandidates,
SourceLocation Loc = SourceLocation(),
const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
+ if (S.DiagnoseUseOfDecl(FoundDecl, Loc))
+ return ExprError();
+
DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
VK_LValue, Loc, LocInfo);
if (HadMultipleCandidates)
DRE->setHadMultipleCandidates(true);
S.MarkDeclRefReferenced(DRE);
- S.DiagnoseUseOfDecl(FoundDecl, Loc);
ExprResult E = S.Owned(DRE);
E = S.DefaultFunctionArrayConversion(E.take());
@@ -940,6 +942,9 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
continue;
}
+ if (!shouldLinkPossiblyHiddenDecl(*I, New))
+ continue;
+
Match = *I;
return Ovl_Match;
}
@@ -1832,7 +1837,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
// conversion.
using llvm::APSInt;
if (From)
- if (FieldDecl *MemberDecl = From->getBitField()) {
+ if (FieldDecl *MemberDecl = From->getSourceBitField()) {
APSInt BitWidth;
if (FromType->isIntegralType(Context) &&
MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) {
@@ -5024,7 +5029,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T,
Expr::EvalResult Eval;
Eval.Diag = &Notes;
- if (!Result.get()->EvaluateAsRValue(Eval, Context)) {
+ if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) {
// The expression can't be folded, so we can't keep it at this position in
// the AST.
Result = ExprError();
@@ -5473,7 +5478,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns,
void Sema::AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr::Classification ObjectClassification,
- Expr **Args, unsigned NumArgs,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions) {
NamedDecl *Decl = FoundDecl.getDecl();
@@ -5488,12 +5493,12 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl,
AddMethodTemplateCandidate(TD, FoundDecl, ActingContext,
/*ExplicitArgs*/ 0,
ObjectType, ObjectClassification,
- llvm::makeArrayRef(Args, NumArgs), CandidateSet,
+ Args, CandidateSet,
SuppressUserConversions);
} else {
AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext,
ObjectType, ObjectClassification,
- llvm::makeArrayRef(Args, NumArgs),
+ Args,
CandidateSet, SuppressUserConversions);
}
}
@@ -5721,6 +5726,14 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
if (!CandidateSet.isNewCandidate(Conversion))
return;
+ // If the conversion function has an undeduced return type, trigger its
+ // deduction now.
+ if (getLangOpts().CPlusPlus1y && ConvType->isUndeducedType()) {
+ if (DeduceReturnType(Conversion, From->getExprLoc()))
+ return;
+ ConvType = Conversion->getConversionType().getNonReferenceType();
+ }
+
// Overload resolution is always an unevaluated context.
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
@@ -5800,7 +5813,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
// there are 0 arguments (i.e., nothing is allocated using ASTContext's
// allocator).
QualType CallResultType = ConversionType.getNonLValueExprType(Context);
- CallExpr Call(Context, &ConversionFn, MultiExprArg(), CallResultType, VK,
+ CallExpr Call(Context, &ConversionFn, None, CallResultType, VK,
From->getLocStart());
ImplicitConversionSequence ICS =
TryCopyInitialization(*this, &Call, ToType,
@@ -5963,7 +5976,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
// Determine the implicit conversion sequences for each of the
// arguments.
- for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) {
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
if (ArgIdx < NumArgsInProto) {
// (C++ 13.3.2p3): for F to be a viable function, there shall
// exist for each argument an implicit conversion sequence
@@ -6000,7 +6013,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
/// [over.match.oper]).
void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
SourceLocation OpLoc,
- Expr **Args, unsigned NumArgs,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
SourceRange OpRange) {
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
@@ -6015,13 +6028,15 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
// constructed as follows:
QualType T1 = Args[0]->getType();
- // -- If T1 is a class type, the set of member candidates is the
- // result of the qualified lookup of T1::operator@
- // (13.3.1.1.1); otherwise, the set of member candidates is
- // empty.
+ // -- If T1 is a complete class type or a class currently being
+ // defined, the set of member candidates is the result of the
+ // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
+ // the set of member candidates is empty.
if (const RecordType *T1Rec = T1->getAs<RecordType>()) {
- // Complete the type if it can be completed. Otherwise, we're done.
- if (RequireCompleteType(OpLoc, T1, 0))
+ // Complete the type if it can be completed.
+ RequireCompleteType(OpLoc, T1, 0);
+ // If the type is neither complete nor being defined, bail out now.
+ if (!T1Rec->getDecl()->getDefinition())
return;
LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName);
@@ -6033,7 +6048,8 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
Oper != OperEnd;
++Oper)
AddMethodCandidate(Oper.getPair(), Args[0]->getType(),
- Args[0]->Classify(Context), Args + 1, NumArgs - 1,
+ Args[0]->Classify(Context),
+ Args.slice(1),
CandidateSet,
/* SuppressUserConversions = */ false);
}
@@ -6048,7 +6064,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
/// (at the beginning of the argument list) that will be contextually
/// converted to bool.
void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
- Expr **Args, unsigned NumArgs,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
bool IsAssignmentOperator,
unsigned NumContextualBoolArguments) {
@@ -6056,20 +6072,20 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
// Add this candidate
- OverloadCandidate &Candidate = CandidateSet.addCandidate(NumArgs);
+ OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size());
Candidate.FoundDecl = DeclAccessPair::make(0, AS_none);
Candidate.Function = 0;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.BuiltinTypes.ResultTy = ResultTy;
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx)
Candidate.BuiltinTypes.ParamTypes[ArgIdx] = ParamTys[ArgIdx];
// Determine the implicit conversion sequences for each of the
// arguments.
Candidate.Viable = true;
- Candidate.ExplicitCallArguments = NumArgs;
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+ Candidate.ExplicitCallArguments = Args.size();
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
// C++ [over.match.oper]p4:
// For the built-in assignment operators, conversions of the
// left operand are restricted as follows:
@@ -6395,15 +6411,14 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
/// given type to the candidate set.
static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
QualType T,
- Expr **Args,
- unsigned NumArgs,
+ ArrayRef<Expr *> Args,
OverloadCandidateSet &CandidateSet) {
QualType ParamTypes[2];
// T& operator=(T&, T)
ParamTypes[0] = S.Context.getLValueReferenceType(T);
ParamTypes[1] = T;
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/true);
if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
@@ -6411,7 +6426,7 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
ParamTypes[0]
= S.Context.getLValueReferenceType(S.Context.getVolatileType(T));
ParamTypes[1] = T;
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/true);
}
}
@@ -6482,8 +6497,7 @@ namespace {
class BuiltinOperatorOverloadBuilder {
// Common instance state available to all overload candidate addition methods.
Sema &S;
- Expr **Args;
- unsigned NumArgs;
+ ArrayRef<Expr *> Args;
Qualifiers VisibleTypeConversionsQuals;
bool HasArithmeticOrEnumeralCandidateType;
SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes;
@@ -6606,10 +6620,10 @@ class BuiltinOperatorOverloadBuilder {
};
// Non-volatile version.
- if (NumArgs == 1)
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+ if (Args.size() == 1)
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
else
- S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet);
// Use a heuristic to reduce number of builtin candidates in the set:
// add volatile version only if there are conversions to a volatile type.
@@ -6617,10 +6631,10 @@ class BuiltinOperatorOverloadBuilder {
ParamTypes[0] =
S.Context.getLValueReferenceType(
S.Context.getVolatileType(CandidateTy));
- if (NumArgs == 1)
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+ if (Args.size() == 1)
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
else
- S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet);
}
// Add restrict version only if there are conversions to a restrict type
@@ -6630,10 +6644,10 @@ class BuiltinOperatorOverloadBuilder {
ParamTypes[0]
= S.Context.getLValueReferenceType(
S.Context.getCVRQualifiedType(CandidateTy, Qualifiers::Restrict));
- if (NumArgs == 1)
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
+ if (Args.size() == 1)
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
else
- S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet);
if (HasVolatile) {
ParamTypes[0]
@@ -6641,11 +6655,10 @@ class BuiltinOperatorOverloadBuilder {
S.Context.getCVRQualifiedType(CandidateTy,
(Qualifiers::Volatile |
Qualifiers::Restrict)));
- if (NumArgs == 1)
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1,
- CandidateSet);
+ if (Args.size() == 1)
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
else
- S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet);
}
}
@@ -6653,12 +6666,12 @@ class BuiltinOperatorOverloadBuilder {
public:
BuiltinOperatorOverloadBuilder(
- Sema &S, Expr **Args, unsigned NumArgs,
+ Sema &S, ArrayRef<Expr *> Args,
Qualifiers VisibleTypeConversionsQuals,
bool HasArithmeticOrEnumeralCandidateType,
SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes,
OverloadCandidateSet &CandidateSet)
- : S(S), Args(Args), NumArgs(NumArgs),
+ : S(S), Args(Args),
VisibleTypeConversionsQuals(VisibleTypeConversionsQuals),
HasArithmeticOrEnumeralCandidateType(
HasArithmeticOrEnumeralCandidateType),
@@ -6760,7 +6773,7 @@ public:
continue;
S.AddBuiltinCandidate(S.Context.getLValueReferenceType(PointeeTy),
- &ParamTy, Args, 1, CandidateSet);
+ &ParamTy, Args, CandidateSet);
}
}
@@ -6777,7 +6790,7 @@ public:
for (unsigned Arith = FirstPromotedArithmeticType;
Arith < LastPromotedArithmeticType; ++Arith) {
QualType ArithTy = getArithmeticType(Arith);
- S.AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet);
+ S.AddBuiltinCandidate(ArithTy, &ArithTy, Args, CandidateSet);
}
// Extension: We also add these operators for vector types.
@@ -6786,7 +6799,7 @@ public:
VecEnd = CandidateTypes[0].vector_end();
Vec != VecEnd; ++Vec) {
QualType VecTy = *Vec;
- S.AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet);
+ S.AddBuiltinCandidate(VecTy, &VecTy, Args, CandidateSet);
}
}
@@ -6801,7 +6814,7 @@ public:
PtrEnd = CandidateTypes[0].pointer_end();
Ptr != PtrEnd; ++Ptr) {
QualType ParamTy = *Ptr;
- S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet);
+ S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, CandidateSet);
}
}
@@ -6817,7 +6830,7 @@ public:
for (unsigned Int = FirstPromotedIntegralType;
Int < LastPromotedIntegralType; ++Int) {
QualType IntTy = getArithmeticType(Int);
- S.AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet);
+ S.AddBuiltinCandidate(IntTy, &IntTy, Args, CandidateSet);
}
// Extension: We also add this operator for vector types.
@@ -6826,7 +6839,7 @@ public:
VecEnd = CandidateTypes[0].vector_end();
Vec != VecEnd; ++Vec) {
QualType VecTy = *Vec;
- S.AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet);
+ S.AddBuiltinCandidate(VecTy, &VecTy, Args, CandidateSet);
}
}
@@ -6840,7 +6853,7 @@ public:
/// Set of (canonical) types that we've already handled.
llvm::SmallPtrSet<QualType, 8> AddedTypes;
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
for (BuiltinCandidateTypeSet::iterator
MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(),
MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end();
@@ -6851,8 +6864,7 @@ public:
continue;
QualType ParamTypes[2] = { *MemPtr, *MemPtr };
- S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2,
- CandidateSet);
+ S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet);
}
}
}
@@ -6884,7 +6896,7 @@ public:
llvm::DenseSet<std::pair<CanQualType, CanQualType> >
UserDefinedBinaryOperators;
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
if (CandidateTypes[ArgIdx].enumeration_begin() !=
CandidateTypes[ArgIdx].enumeration_end()) {
for (OverloadCandidateSet::iterator C = CandidateSet.begin(),
@@ -6917,7 +6929,7 @@ public:
/// Set of (canonical) types that we've already handled.
llvm::SmallPtrSet<QualType, 8> AddedTypes;
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
for (BuiltinCandidateTypeSet::iterator
Ptr = CandidateTypes[ArgIdx].pointer_begin(),
PtrEnd = CandidateTypes[ArgIdx].pointer_end();
@@ -6927,8 +6939,7 @@ public:
continue;
QualType ParamTypes[2] = { *Ptr, *Ptr };
- S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2,
- CandidateSet);
+ S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet);
}
for (BuiltinCandidateTypeSet::iterator
Enum = CandidateTypes[ArgIdx].enumeration_begin(),
@@ -6944,17 +6955,16 @@ public:
continue;
QualType ParamTypes[2] = { *Enum, *Enum };
- S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2,
- CandidateSet);
+ S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet);
}
if (CandidateTypes[ArgIdx].hasNullPtrType()) {
CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy);
if (AddedTypes.insert(NullPtrTy) &&
- !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy,
+ !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy,
NullPtrTy))) {
QualType ParamTypes[2] = { NullPtrTy, NullPtrTy };
- S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2,
+ S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args,
CandidateSet);
}
}
@@ -6999,8 +7009,7 @@ public:
if (Arg == 0 || Op == OO_Plus) {
// operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t)
// T* operator+(ptrdiff_t, T*);
- S.AddBuiltinCandidate(*Ptr, AsymetricParamTypes, Args, 2,
- CandidateSet);
+ S.AddBuiltinCandidate(*Ptr, AsymetricParamTypes, Args, CandidateSet);
}
if (Op == OO_Minus) {
// ptrdiff_t operator-(T, T);
@@ -7009,7 +7018,7 @@ public:
QualType ParamTypes[2] = { *Ptr, *Ptr };
S.AddBuiltinCandidate(S.Context.getPointerDiffType(), ParamTypes,
- Args, 2, CandidateSet);
+ Args, CandidateSet);
}
}
}
@@ -7057,7 +7066,7 @@ public:
QualType Result =
isComparison ? S.Context.BoolTy
: getUsualArithmeticConversions(Left, Right);
- S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet);
}
}
@@ -7080,7 +7089,7 @@ public:
Result = *Vec2;
}
- S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet);
}
}
}
@@ -7112,7 +7121,7 @@ public:
QualType Result = (Op == OO_LessLess || Op == OO_GreaterGreater)
? LandR[0]
: getUsualArithmeticConversions(Left, Right);
- S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet);
}
}
}
@@ -7136,8 +7145,7 @@ public:
if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum)))
continue;
- AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, 2,
- CandidateSet);
+ AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, CandidateSet);
}
for (BuiltinCandidateTypeSet::iterator
@@ -7147,8 +7155,7 @@ public:
if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr)))
continue;
- AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, 2,
- CandidateSet);
+ AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, CandidateSet);
}
}
}
@@ -7188,7 +7195,7 @@ public:
S.Context.getLValueReferenceType(*Ptr),
isEqualOp ? *Ptr : S.Context.getPointerDiffType(),
};
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/ isEqualOp);
bool NeedVolatile = !(*Ptr).isVolatileQualified() &&
@@ -7197,7 +7204,7 @@ public:
// volatile version
ParamTypes[0] =
S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
}
@@ -7206,7 +7213,7 @@ public:
// restrict version
ParamTypes[0]
= S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
if (NeedVolatile) {
@@ -7216,8 +7223,7 @@ public:
S.Context.getCVRQualifiedType(*Ptr,
(Qualifiers::Volatile |
Qualifiers::Restrict)));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
}
}
@@ -7238,7 +7244,7 @@ public:
};
// non-volatile version
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/true);
bool NeedVolatile = !(*Ptr).isVolatileQualified() &&
@@ -7247,8 +7253,8 @@ public:
// volatile version
ParamTypes[0] =
S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet, /*IsAssigmentOperator=*/true);
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
+ /*IsAssigmentOperator=*/true);
}
if (!(*Ptr).isRestrictQualified() &&
@@ -7256,8 +7262,8 @@ public:
// restrict version
ParamTypes[0]
= S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet, /*IsAssigmentOperator=*/true);
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
+ /*IsAssigmentOperator=*/true);
if (NeedVolatile) {
// volatile restrict version
@@ -7266,9 +7272,8 @@ public:
S.Context.getCVRQualifiedType(*Ptr,
(Qualifiers::Volatile |
Qualifiers::Restrict)));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet, /*IsAssigmentOperator=*/true);
-
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
+ /*IsAssigmentOperator=*/true);
}
}
}
@@ -7300,7 +7305,7 @@ public:
// Add this built-in operator as a candidate (VQ is empty).
ParamTypes[0] =
S.Context.getLValueReferenceType(getArithmeticType(Left));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
// Add this built-in operator as a candidate (VQ is 'volatile').
@@ -7308,8 +7313,7 @@ public:
ParamTypes[0] =
S.Context.getVolatileType(getArithmeticType(Left));
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
}
}
@@ -7328,15 +7332,14 @@ public:
ParamTypes[1] = *Vec2;
// Add this built-in operator as a candidate (VQ is empty).
ParamTypes[0] = S.Context.getLValueReferenceType(*Vec1);
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
// Add this built-in operator as a candidate (VQ is 'volatile').
if (VisibleTypeConversionsQuals.hasVolatile()) {
ParamTypes[0] = S.Context.getVolatileType(*Vec1);
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet,
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet,
/*IsAssigmentOperator=*/isEqualOp);
}
}
@@ -7368,14 +7371,13 @@ public:
// Add this built-in operator as a candidate (VQ is empty).
ParamTypes[0] =
S.Context.getLValueReferenceType(getArithmeticType(Left));
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
if (VisibleTypeConversionsQuals.hasVolatile()) {
// Add this built-in operator as a candidate (VQ is 'volatile').
ParamTypes[0] = getArithmeticType(Left);
ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]);
ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]);
- S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2,
- CandidateSet);
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet);
}
}
}
@@ -7390,13 +7392,13 @@ public:
// bool operator||(bool, bool);
void addExclaimOverload() {
QualType ParamTy = S.Context.BoolTy;
- S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet,
+ S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, CandidateSet,
/*IsAssignmentOperator=*/false,
/*NumContextualBoolArguments=*/1);
}
void addAmpAmpOrPipePipeOverload() {
QualType ParamTypes[2] = { S.Context.BoolTy, S.Context.BoolTy };
- S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, CandidateSet,
+ S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet,
/*IsAssignmentOperator=*/false,
/*NumContextualBoolArguments=*/2);
}
@@ -7424,7 +7426,7 @@ public:
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
// T& operator[](T*, ptrdiff_t)
- S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet);
}
for (BuiltinCandidateTypeSet::iterator
@@ -7439,7 +7441,7 @@ public:
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
// T& operator[](ptrdiff_t, T*)
- S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet);
}
}
@@ -7490,7 +7492,7 @@ public:
continue;
T = Q1.apply(S.Context, T);
QualType ResultTy = S.Context.getLValueReferenceType(T);
- S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet);
}
}
}
@@ -7518,7 +7520,7 @@ public:
continue;
QualType ParamTypes[2] = { *Ptr, *Ptr };
- S.AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(*Ptr, ParamTypes, Args, CandidateSet);
}
for (BuiltinCandidateTypeSet::iterator
@@ -7529,7 +7531,7 @@ public:
continue;
QualType ParamTypes[2] = { *MemPtr, *MemPtr };
- S.AddBuiltinCandidate(*MemPtr, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(*MemPtr, ParamTypes, Args, CandidateSet);
}
if (S.getLangOpts().CPlusPlus11) {
@@ -7544,7 +7546,7 @@ public:
continue;
QualType ParamTypes[2] = { *Enum, *Enum };
- S.AddBuiltinCandidate(*Enum, ParamTypes, Args, 2, CandidateSet);
+ S.AddBuiltinCandidate(*Enum, ParamTypes, Args, CandidateSet);
}
}
}
@@ -7561,7 +7563,7 @@ public:
void
Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
SourceLocation OpLoc,
- Expr **Args, unsigned NumArgs,
+ llvm::ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet) {
// Find all of the types that the arguments can convert to, but only
// if the operator we're looking at has built-in operator candidates
@@ -7569,13 +7571,13 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// candidate types or either arithmetic or enumeral candidate types.
Qualifiers VisibleTypeConversionsQuals;
VisibleTypeConversionsQuals.addConst();
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx)
VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]);
bool HasNonRecordCandidateType = false;
bool HasArithmeticOrEnumeralCandidateType = false;
SmallVector<BuiltinCandidateTypeSet, 2> CandidateTypes;
- for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) {
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
CandidateTypes.push_back(BuiltinCandidateTypeSet(*this));
CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(),
OpLoc,
@@ -7596,12 +7598,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// We can't exit early for !, ||, or &&, since there we have always have
// 'bool' overloads.
- if (!HasNonRecordCandidateType &&
+ if (!HasNonRecordCandidateType &&
!(Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe))
return;
// Setup an object to manage the common state for building overloads.
- BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, NumArgs,
+ BuiltinOperatorOverloadBuilder OpBuilder(*this, Args,
VisibleTypeConversionsQuals,
HasArithmeticOrEnumeralCandidateType,
CandidateTypes, CandidateSet);
@@ -7628,12 +7630,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
break;
case OO_Plus: // '+' is either unary or binary
- if (NumArgs == 1)
+ if (Args.size() == 1)
OpBuilder.addUnaryPlusPointerOverloads();
// Fall through.
case OO_Minus: // '-' is either unary or binary
- if (NumArgs == 1) {
+ if (Args.size() == 1) {
OpBuilder.addUnaryPlusOrMinusArithmeticOverloads();
} else {
OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op);
@@ -7642,7 +7644,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
break;
case OO_Star: // '*' is either unary or binary
- if (NumArgs == 1)
+ if (Args.size() == 1)
OpBuilder.addUnaryStarPointerOverloads();
else
OpBuilder.addGenericBinaryArithmeticOverloads(/*isComparison=*/false);
@@ -7680,7 +7682,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
break;
case OO_Amp: // '&' is either unary or binary
- if (NumArgs == 1)
+ if (Args.size() == 1)
// C++ [over.match.oper]p3:
// -- For the operator ',', the unary operator '&', or the
// operator '->', the built-in candidates set is empty.
@@ -8508,13 +8510,35 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
return;
}
- case Sema::TDK_NonDeducedMismatch:
+ case Sema::TDK_NonDeducedMismatch: {
// FIXME: Provide a source location to indicate what we couldn't match.
+ TemplateArgument FirstTA = *Cand->DeductionFailure.getFirstArg();
+ TemplateArgument SecondTA = *Cand->DeductionFailure.getSecondArg();
+ if (FirstTA.getKind() == TemplateArgument::Template &&
+ SecondTA.getKind() == TemplateArgument::Template) {
+ TemplateName FirstTN = FirstTA.getAsTemplate();
+ TemplateName SecondTN = SecondTA.getAsTemplate();
+ if (FirstTN.getKind() == TemplateName::Template &&
+ SecondTN.getKind() == TemplateName::Template) {
+ if (FirstTN.getAsTemplateDecl()->getName() ==
+ SecondTN.getAsTemplateDecl()->getName()) {
+ // FIXME: This fixes a bad diagnostic where both templates are named
+ // the same. This particular case is a bit difficult since:
+ // 1) It is passed as a string to the diagnostic printer.
+ // 2) The diagnostic printer only attempts to find a better
+ // name for types, not decls.
+ // Ideally, this should folded into the diagnostic printer.
+ S.Diag(Fn->getLocation(),
+ diag::note_ovl_candidate_non_deduced_mismatch_qualified)
+ << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl();
+ return;
+ }
+ }
+ }
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch)
- << *Cand->DeductionFailure.getFirstArg()
- << *Cand->DeductionFailure.getSecondArg();
+ << FirstTA << SecondTA;
return;
-
+ }
// TODO: diagnose these individually, then kill off
// note_ovl_candidate_bad_deduction, which is uselessly vague.
case Sema::TDK_MiscellaneousDeductionFailure:
@@ -9109,17 +9133,19 @@ private:
= S.DeduceTemplateArguments(FunctionTemplate,
&OvlExplicitTemplateArgs,
TargetFunctionType, Specialization,
- Info)) {
+ Info, /*InOverloadResolution=*/true)) {
// FIXME: make a note of the failed deduction for diagnostics.
(void)Result;
return false;
}
- // Template argument deduction ensures that we have an exact match.
+ // Template argument deduction ensures that we have an exact match or
+ // compatible pointer-to-function arguments that would be adjusted by ICS.
// This function template specicalization works.
Specialization = cast<FunctionDecl>(Specialization->getCanonicalDecl());
- assert(TargetFunctionType
- == Context.getCanonicalType(Specialization->getType()));
+ assert(S.isSameOrCompatibleFunctionType(
+ Context.getCanonicalType(Specialization->getType()),
+ Context.getCanonicalType(TargetFunctionType)));
Matches.push_back(std::make_pair(CurAccessFunPair, Specialization));
return true;
}
@@ -9141,6 +9167,13 @@ private:
if (S.CheckCUDATarget(Caller, FunDecl))
return false;
+ // If any candidate has a placeholder return type, trigger its deduction
+ // now.
+ if (S.getLangOpts().CPlusPlus1y &&
+ FunDecl->getResultType()->isUndeducedType() &&
+ S.DeduceReturnType(FunDecl, SourceExpr->getLocStart(), Complain))
+ return false;
+
QualType ResultTy;
if (Context.hasSameUnqualifiedType(TargetFunctionType,
FunDecl->getType()) ||
@@ -9384,7 +9417,8 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
TemplateDeductionInfo Info(ovl->getNameLoc());
if (TemplateDeductionResult Result
= DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs,
- Specialization, Info)) {
+ Specialization, Info,
+ /*InOverloadResolution=*/true)) {
// FIXME: make a note of the failed deduction for diagnostics.
(void)Result;
continue;
@@ -9406,6 +9440,11 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
if (FoundResult) *FoundResult = I.getPair();
}
+ if (Matched && getLangOpts().CPlusPlus1y &&
+ Matched->getResultType()->isUndeducedType() &&
+ DeduceReturnType(Matched, ovl->getExprLoc(), Complain))
+ return 0;
+
return Matched;
}
@@ -9932,7 +9971,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
case OR_Success: {
FunctionDecl *FDecl = (*Best)->Function;
SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
- SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc());
+ if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()))
+ return ExprError();
Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs,
RParenLoc, ExecConfig);
@@ -10065,6 +10105,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
NumArgs = 2;
}
+ ArrayRef<Expr *> ArgsArray(Args, NumArgs);
+
if (Input->isTypeDependent()) {
if (Fns.empty())
return Owned(new (Context) UnaryOperator(Input,
@@ -10079,8 +10121,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
NestedNameSpecifierLoc(), OpNameInfo,
/*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
- return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
- llvm::makeArrayRef(Args, NumArgs),
+ return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, ArgsArray,
Context.DependentTy,
VK_RValue,
OpLoc, false));
@@ -10090,20 +10131,18 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
OverloadCandidateSet CandidateSet(OpLoc);
// Add the candidates from the given function set.
- AddFunctionCandidates(Fns, llvm::makeArrayRef(Args, NumArgs), CandidateSet,
- false);
+ AddFunctionCandidates(Fns, ArgsArray, CandidateSet, false);
// Add operator candidates that are member functions.
- AddMemberOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
+ AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet);
// Add candidates from ADL.
- AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
- OpLoc, llvm::makeArrayRef(Args, NumArgs),
- /*ExplicitTemplateArgs*/ 0,
+ AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, OpLoc,
+ ArgsArray, /*ExplicitTemplateArgs*/ 0,
CandidateSet);
// Add builtin operator candidates.
- AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
+ AddBuiltinOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -10154,8 +10193,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
Args[0] = Input;
CallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
- llvm::makeArrayRef(Args, NumArgs),
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray,
ResultTy, VK, OpLoc, false);
if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall,
@@ -10181,8 +10219,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// This is an erroneous use of an operator which can be overloaded by
// a non-member function. Check for non-member operators which were
// defined too late to be candidates.
- if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc,
- llvm::makeArrayRef(Args, NumArgs)))
+ if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, ArgsArray))
// FIXME: Recover by calling the found function.
return ExprError();
@@ -10195,8 +10232,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getType()
<< Input->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
- llvm::makeArrayRef(Args, NumArgs),
+ CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, ArgsArray,
UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
@@ -10206,8 +10242,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
<< UnaryOperator::getOpcodeStr(Opc)
<< getDeletedOrUnavailableSuffix(Best->Function)
<< Input->getSourceRange();
- CandidateSet.NoteCandidates(*this, OCD_AllCandidates,
- llvm::makeArrayRef(Args, NumArgs),
+ CandidateSet.NoteCandidates(*this, OCD_AllCandidates, ArgsArray,
UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
}
@@ -10315,7 +10350,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
AddFunctionCandidates(Fns, Args, CandidateSet, false);
// Add operator candidates that are member functions.
- AddMemberOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
+ AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet);
// Add candidates from ADL.
AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true,
@@ -10324,7 +10359,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
CandidateSet);
// Add builtin operator candidates.
- AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
+ AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -10545,10 +10580,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Subscript can only be overloaded as a member function.
// Add operator candidates that are member functions.
- AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet);
+ AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet);
// Add builtin operator candidates.
- AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet);
+ AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -10815,7 +10850,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
Method = cast<CXXMethodDecl>(Best->Function);
FoundDecl = Best->FoundDecl;
CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl);
- DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc());
+ if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()))
+ return ExprError();
break;
case OR_No_Viable_Function:
@@ -10956,7 +10992,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
AddMethodCandidate(Oper.getPair(), Object.get()->getType(),
- Object.get()->Classify(Context), Args, NumArgs, CandidateSet,
+ Object.get()->Classify(Context),
+ llvm::makeArrayRef(Args, NumArgs), CandidateSet,
/*SuppressUserConversions=*/ false);
}
@@ -11066,7 +11103,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
Best->Conversions[0].UserDefined.ConversionFunction);
CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl);
- DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc);
+ if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc))
+ return ExprError();
// We selected one of the surrogate functions that converts the
// object parameter to a function pointer. Perform the conversion
@@ -11248,7 +11286,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
Oper != OperEnd; ++Oper) {
AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context),
- 0, 0, CandidateSet, /*SuppressUserConversions=*/false);
+ None, CandidateSet, /*SuppressUserConversions=*/false);
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
@@ -11363,7 +11401,7 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R,
// Check the argument types. This should almost always be a no-op, except
// that array-to-pointer decay is applied to string literals.
Expr *ConvArgs[2];
- for (unsigned ArgIdx = 0; ArgIdx != Args.size(); ++ArgIdx) {
+ for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
ExprResult InputInit = PerformCopyInitialization(
InitializedEntity::InitializeParameter(Context, FD->getParamDecl(ArgIdx)),
SourceLocation(), Args[ArgIdx]);
@@ -11420,7 +11458,7 @@ Sema::BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc,
<< RangeLoc << BEF << Range->getType();
return FRS_DiagnosticIssued;
}
- *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, MultiExprArg(), Loc, 0);
+ *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, None, Loc, 0);
if (CallExpr->isInvalid()) {
*CallExpr = ExprError();
Diag(Range->getLocStart(), diag::note_in_for_range)
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp
index b135507..054d557 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaPseudoObject.cpp
@@ -153,6 +153,23 @@ namespace {
refExpr->getRBracket());
}
};
+
+ struct MSPropertyRefRebuilder : Rebuilder<MSPropertyRefRebuilder> {
+ Expr *NewBase;
+ MSPropertyRefRebuilder(Sema &S, Expr *newBase)
+ : Rebuilder<MSPropertyRefRebuilder>(S), NewBase(newBase) {}
+
+ typedef MSPropertyRefExpr specific_type;
+ Expr *rebuildSpecific(MSPropertyRefExpr *refExpr) {
+ assert(refExpr->getBaseExpr());
+
+ return new (S.Context)
+ MSPropertyRefExpr(NewBase, refExpr->getPropertyDecl(),
+ refExpr->isArrow(), refExpr->getType(),
+ refExpr->getValueKind(), refExpr->getQualifierLoc(),
+ refExpr->getMemberLoc());
+ }
+ };
class PseudoOpBuilder {
public:
@@ -284,6 +301,18 @@ namespace {
ExprResult buildSet(Expr *op, SourceLocation, bool);
};
+ class MSPropertyOpBuilder : public PseudoOpBuilder {
+ MSPropertyRefExpr *RefExpr;
+
+ public:
+ MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
+ PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
+ RefExpr(refExpr) {}
+
+ Expr *rebuildAndCaptureObject(Expr *);
+ ExprResult buildGet();
+ ExprResult buildSet(Expr *op, SourceLocation, bool);
+ };
}
/// Capture the given expression in an OpaqueValueExpr.
@@ -412,7 +441,8 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
QualType resultType = result.get()->getType();
// That's the postfix result.
- if (UnaryOperator::isPostfix(opcode) && CanCaptureValueOfType(resultType)) {
+ if (UnaryOperator::isPostfix(opcode) &&
+ (result.get()->isTypeDependent() || CanCaptureValueOfType(resultType))) {
result = capture(result.take());
setResultToLastSemantic();
}
@@ -633,12 +663,11 @@ ExprResult ObjCPropertyOpBuilder::buildGet() {
assert(InstanceReceiver || RefExpr->isSuperReceiver());
msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
GenericLoc, Getter->getSelector(),
- Getter, MultiExprArg());
+ Getter, None);
} else {
msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
- GenericLoc,
- Getter->getSelector(), Getter,
- MultiExprArg());
+ GenericLoc, Getter->getSelector(),
+ Getter, None);
}
return msg;
}
@@ -1088,8 +1117,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
/*TInfo=*/0,
SC_None,
0);
- AtIndexGetter->setMethodParams(S.Context, Argument,
- ArrayRef<SourceLocation>());
+ AtIndexGetter->setMethodParams(S.Context, Argument, None);
}
if (!AtIndexGetter) {
@@ -1213,7 +1241,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
SC_None,
0);
Params.push_back(key);
- AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
+ AtIndexSetter->setMethodParams(S.Context, Params, None);
}
if (!AtIndexSetter) {
@@ -1324,6 +1352,77 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
}
//===----------------------------------------------------------------------===//
+// MSVC __declspec(property) references
+//===----------------------------------------------------------------------===//
+
+Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
+ Expr *NewBase = capture(RefExpr->getBaseExpr());
+
+ syntacticBase =
+ MSPropertyRefRebuilder(S, NewBase).rebuild(syntacticBase);
+
+ return syntacticBase;
+}
+
+ExprResult MSPropertyOpBuilder::buildGet() {
+ if (!RefExpr->getPropertyDecl()->hasGetter()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::err_no_getter_for_property)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ UnqualifiedId GetterName;
+ IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
+ GetterName.setIdentifier(II, RefExpr->getMemberLoc());
+ CXXScopeSpec SS;
+ SS.Adopt(RefExpr->getQualifierLoc());
+ ExprResult GetterExpr = S.ActOnMemberAccessExpr(
+ S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
+ RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
+ GetterName, 0, true);
+ if (GetterExpr.isInvalid()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_getter)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ MultiExprArg ArgExprs;
+ return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
+ RefExpr->getSourceRange().getBegin(), ArgExprs,
+ RefExpr->getSourceRange().getEnd());
+}
+
+ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
+ bool captureSetValueAsResult) {
+ if (!RefExpr->getPropertyDecl()->hasSetter()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::err_no_setter_for_property)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ UnqualifiedId SetterName;
+ IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
+ SetterName.setIdentifier(II, RefExpr->getMemberLoc());
+ CXXScopeSpec SS;
+ SS.Adopt(RefExpr->getQualifierLoc());
+ ExprResult SetterExpr = S.ActOnMemberAccessExpr(
+ S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
+ RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
+ SetterName, 0, true);
+ if (SetterExpr.isInvalid()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_setter)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ SmallVector<Expr*, 1> ArgExprs;
+ ArgExprs.push_back(op);
+ return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
+ RefExpr->getSourceRange().getBegin(), ArgExprs,
+ op->getSourceRange().getEnd());
+}
+
+//===----------------------------------------------------------------------===//
// General Sema routines.
//===----------------------------------------------------------------------===//
@@ -1338,6 +1437,10 @@ ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
ObjCSubscriptOpBuilder builder(*this, refExpr);
return builder.buildRValueOperation(E);
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ MSPropertyOpBuilder builder(*this, refExpr);
+ return builder.buildRValueOperation(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1360,6 +1463,10 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
} else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
Diag(opcLoc, diag::err_illegal_container_subscripting_op);
return ExprError();
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ MSPropertyOpBuilder builder(*this, refExpr);
+ return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1389,6 +1496,10 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
ObjCSubscriptOpBuilder builder(*this, refExpr);
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ MSPropertyOpBuilder builder(*this, refExpr);
+ return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1414,6 +1525,10 @@ static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
keyOVE->getSourceExpr()).rebuild(E);
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
+ return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
index ff1db82..248665a 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp
@@ -22,7 +22,6 @@
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
@@ -77,9 +76,22 @@ StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
- // If we have an invalid decl, just return.
- if (DG.isNull() || !DG.isSingleDecl()) return;
- VarDecl *var = cast<VarDecl>(DG.getSingleDecl());
+ // If we don't have a declaration, or we have an invalid declaration,
+ // just return.
+ if (DG.isNull() || !DG.isSingleDecl())
+ return;
+
+ Decl *decl = DG.getSingleDecl();
+ if (!decl || decl->isInvalidDecl())
+ return;
+
+ // Only variable declarations are permitted.
+ VarDecl *var = dyn_cast<VarDecl>(decl);
+ if (!var) {
+ Diag(decl->getLocation(), diag::err_non_variable_decl_in_for);
+ decl->setInvalidDecl();
+ return;
+ }
// suppress any potential 'unused variable' warning.
var->setUsed();
@@ -355,7 +367,7 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
// Recover from an error by just forgetting about it.
}
}
-
+
LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
getLangOpts().CPlusPlus11).take();
if (RHSVal)
@@ -1426,9 +1438,10 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
VarDecl *VD = dyn_cast<VarDecl>(*DI);
if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage())
VD = 0;
- if (VD == 0)
- Diag((*DI)->getLocation(), diag::err_non_variable_decl_in_for);
- // FIXME: mark decl erroneous!
+ if (VD == 0) {
+ Diag((*DI)->getLocation(), diag::err_non_local_variable_decl_in_for);
+ (*DI)->setInvalidDecl();
+ }
}
}
}
@@ -1562,14 +1575,41 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
return StmtError(Diag((*DS->decl_begin())->getLocation(),
diag::err_toomany_element_decls));
- VarDecl *D = cast<VarDecl>(DS->getSingleDecl());
+ VarDecl *D = dyn_cast<VarDecl>(DS->getSingleDecl());
+ if (!D || D->isInvalidDecl())
+ return StmtError();
+
FirstType = D->getType();
// C99 6.8.5p3: The declaration part of a 'for' statement shall only
// declare identifiers for objects having storage class 'auto' or
// 'register'.
if (!D->hasLocalStorage())
return StmtError(Diag(D->getLocation(),
- diag::err_non_variable_decl_in_for));
+ diag::err_non_local_variable_decl_in_for));
+
+ // If the type contained 'auto', deduce the 'auto' to 'id'.
+ if (FirstType->getContainedAutoType()) {
+ OpaqueValueExpr OpaqueId(D->getLocation(), Context.getObjCIdType(),
+ VK_RValue);
+ Expr *DeducedInit = &OpaqueId;
+ if (DeduceAutoType(D->getTypeSourceInfo(), DeducedInit, FirstType) ==
+ DAR_Failed)
+ DiagnoseAutoDeductionFailure(D, DeducedInit);
+ if (FirstType.isNull()) {
+ D->setInvalidDecl();
+ return StmtError();
+ }
+
+ D->setType(FirstType);
+
+ if (ActiveTemplateInstantiations.empty()) {
+ SourceLocation Loc =
+ D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
+ Diag(Loc, diag::warn_auto_var_is_id)
+ << D->getDeclName();
+ }
+ }
+
} else {
Expr *FirstE = cast<Expr>(First);
if (!FirstE->isTypeDependent() && !FirstE->isLValue())
@@ -1601,20 +1641,19 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
/// Finish building a variable declaration for a for-range statement.
/// \return true if an error occurs.
static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
- SourceLocation Loc, int diag) {
+ SourceLocation Loc, int DiagID) {
// Deduce the type for the iterator variable now rather than leaving it to
// AddInitializerToDecl, so we can produce a more suitable diagnostic.
- TypeSourceInfo *InitTSI = 0;
+ QualType InitType;
if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) ||
- SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTSI) ==
+ SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitType) ==
Sema::DAR_Failed)
- SemaRef.Diag(Loc, diag) << Init->getType();
- if (!InitTSI) {
+ SemaRef.Diag(Loc, DiagID) << Init->getType();
+ if (InitType.isNull()) {
Decl->setInvalidDecl();
return true;
}
- Decl->setTypeSourceInfo(InitTSI);
- Decl->setType(InitTSI->getType());
+ Decl->setType(InitType);
// In ARC, infer lifetime.
// FIXME: ARC may want to turn this into 'const __unsafe_unretained' if
@@ -1879,7 +1918,15 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
StmtResult BeginEndDecl = BeginEnd;
ExprResult NotEqExpr = Cond, IncrExpr = Inc;
- if (!BeginEndDecl.get() && !RangeVarType->isDependentType()) {
+ if (RangeVarType->isDependentType()) {
+ // The range is implicitly used as a placeholder when it is dependent.
+ RangeVar->setUsed();
+
+ // Deduce any 'auto's in the loop variable as 'DependentTy'. We'll fill
+ // them in properly when we instantiate the loop.
+ if (!LoopVar->isInvalidDecl() && Kind != BFRK_Check)
+ LoopVar->setType(SubstAutoType(LoopVar->getType(), Context.DependentTy));
+ } else if (!BeginEndDecl.get()) {
SourceLocation RangeLoc = RangeVar->getLocation();
const QualType RangeVarNonRefType = RangeVarType.getNonReferenceType();
@@ -1934,6 +1981,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
RangeLoc));
else if (const VariableArrayType *VAT =
dyn_cast<VariableArrayType>(UnqAT))
+ // FIXME: Need to build an OpaqueValueExpr for this rather than
+ // recomputing it!
BoundExpr = VAT->getSizeExpr();
else {
// Can't be a DependentSizedArrayType or an IncompleteArrayType since
@@ -2064,9 +2113,6 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
if (LoopVar->isInvalidDecl())
NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
}
- } else {
- // The range is implicitly used as a placeholder when it is dependent.
- RangeVar->setUsed();
}
// Don't bother to actually allocate the result if we're just trying to
@@ -2263,7 +2309,7 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
InitializationKind Kind
= InitializationKind::CreateCopy(Value->getLocStart(),
Value->getLocStart());
- InitializationSequence Seq(*this, Entity, Kind, &InitExpr, 1);
+ InitializationSequence Seq(*this, Entity, Kind, InitExpr);
// [...] If overload resolution fails, or if the type of the first
// parameter of the selected constructor is not an rvalue reference
@@ -2296,7 +2342,7 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
// Complete type-checking the initialization of the return type
// using the constructor we found.
- Res = Seq.Perform(*this, Entity, Kind, MultiExprArg(&Value, 1));
+ Res = Seq.Perform(*this, Entity, Kind, Value);
}
}
}
@@ -2359,6 +2405,10 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
return StmtError();
}
+ } else if (CapturedRegionScopeInfo *CurRegion =
+ dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
+ Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();
+ return StmtError();
} else {
LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CurCap);
if (LSI->CallOperator->getType()->getAs<FunctionType>()->getNoReturnAttr()){
@@ -2432,12 +2482,80 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
return Owned(Result);
}
+/// Deduce the return type for a function from a returned expression, per
+/// C++1y [dcl.spec.auto]p6.
+bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD,
+ SourceLocation ReturnLoc,
+ Expr *&RetExpr,
+ AutoType *AT) {
+ TypeLoc OrigResultType = FD->getTypeSourceInfo()->getTypeLoc().
+ IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
+ QualType Deduced;
+
+ if (RetExpr) {
+ // If the deduction is for a return statement and the initializer is
+ // a braced-init-list, the program is ill-formed.
+ if (isa<InitListExpr>(RetExpr)) {
+ Diag(RetExpr->getExprLoc(), diag::err_auto_fn_return_init_list);
+ return true;
+ }
+
+ // Otherwise, [...] deduce a value for U using the rules of template
+ // argument deduction.
+ DeduceAutoResult DAR = DeduceAutoType(OrigResultType, RetExpr, Deduced);
+
+ if (DAR == DAR_Failed && !FD->isInvalidDecl())
+ Diag(RetExpr->getExprLoc(), diag::err_auto_fn_deduction_failure)
+ << OrigResultType.getType() << RetExpr->getType();
+
+ if (DAR != DAR_Succeeded)
+ return true;
+ } else {
+ // In the case of a return with no operand, the initializer is considered
+ // to be void().
+ //
+ // Deduction here can only succeed if the return type is exactly 'cv auto'
+ // or 'decltype(auto)', so just check for that case directly.
+ if (!OrigResultType.getType()->getAs<AutoType>()) {
+ Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
+ << OrigResultType.getType();
+ return true;
+ }
+ // We always deduce U = void in this case.
+ Deduced = SubstAutoType(OrigResultType.getType(), Context.VoidTy);
+ if (Deduced.isNull())
+ return true;
+ }
+
+ // If a function with a declared return type that contains a placeholder type
+ // has multiple return statements, the return type is deduced for each return
+ // statement. [...] if the type deduced is not the same in each deduction,
+ // the program is ill-formed.
+ if (AT->isDeduced() && !FD->isInvalidDecl()) {
+ AutoType *NewAT = Deduced->getContainedAutoType();
+ if (!Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) {
+ Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
+ << (AT->isDecltypeAuto() ? 1 : 0)
+ << NewAT->getDeducedType() << AT->getDeducedType();
+ return true;
+ }
+ } else if (!FD->isInvalidDecl()) {
+ // Update all declarations of the function to have the deduced return type.
+ Context.adjustDeducedFunctionResultType(FD, Deduced);
+ }
+
+ return false;
+}
+
StmtResult
Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// Check for unexpanded parameter packs.
if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
return StmtError();
+ // FIXME: Unify this and C++1y auto function handling. In particular, we
+ // should allow 'return { 1, 2, 3 };' in a lambda to deduce
+ // 'std::initializer_list<int>'.
if (isa<CapturingScopeInfo>(getCurFunction()))
return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
@@ -2460,6 +2578,23 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
} else // If we don't have a function/method context, bail.
return StmtError();
+ // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing
+ // deduction.
+ bool HasDependentReturnType = FnRetType->isDependentType();
+ if (getLangOpts().CPlusPlus1y) {
+ if (AutoType *AT = FnRetType->getContainedAutoType()) {
+ FunctionDecl *FD = cast<FunctionDecl>(CurContext);
+ if (CurContext->isDependentContext())
+ HasDependentReturnType = true;
+ else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
+ FD->setInvalidDecl();
+ return StmtError();
+ } else {
+ FnRetType = FD->getResultType();
+ }
+ }
+ }
+
ReturnStmt *Result = 0;
if (FnRetType->isVoidType()) {
if (RetValExp) {
@@ -2525,7 +2660,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
- } else if (!RetValExp && !FnRetType->isDependentType()) {
+ } else if (!RetValExp && !HasDependentReturnType) {
unsigned DiagID = diag::warn_return_missing_expr; // C90 6.6.6.4p4
// C99 6.8.6.4p1 (ext_ since GCC warns)
if (getLangOpts().C99) DiagID = diag::ext_return_missing_expr;
@@ -2536,9 +2671,9 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
Result = new (Context) ReturnStmt(ReturnLoc);
} else {
- assert(RetValExp || FnRetType->isDependentType());
+ assert(RetValExp || HasDependentReturnType);
const VarDecl *NRVOCandidate = 0;
- if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
+ if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {
// we have a non-void function with an expression, continue checking
QualType RetType = (RelatedRetType.isNull() ? FnRetType : RelatedRetType);
@@ -2870,3 +3005,124 @@ StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
GetNameFromUnqualifiedId(Name),
Nested);
}
+
+RecordDecl*
+Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc,
+ unsigned NumParams) {
+ DeclContext *DC = CurContext;
+ while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext()))
+ DC = DC->getParent();
+
+ RecordDecl *RD = 0;
+ if (getLangOpts().CPlusPlus)
+ RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0);
+ else
+ RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0);
+
+ DC->addDecl(RD);
+ RD->setImplicit();
+ RD->startDefinition();
+
+ CD = CapturedDecl::Create(Context, CurContext, NumParams);
+ DC->addDecl(CD);
+
+ // Build the context parameter
+ assert(NumParams > 0 && "CapturedStmt requires context parameter");
+ DC = CapturedDecl::castToDeclContext(CD);
+ IdentifierInfo *VarName = &Context.Idents.get("__context");
+ QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+ ImplicitParamDecl *Param
+ = ImplicitParamDecl::Create(Context, DC, Loc, VarName, ParamType);
+ DC->addDecl(Param);
+
+ CD->setContextParam(Param);
+
+ return RD;
+}
+
+static void buildCapturedStmtCaptureList(
+ SmallVectorImpl<CapturedStmt::Capture> &Captures,
+ SmallVectorImpl<Expr *> &CaptureInits,
+ ArrayRef<CapturingScopeInfo::Capture> Candidates) {
+
+ typedef ArrayRef<CapturingScopeInfo::Capture>::const_iterator CaptureIter;
+ for (CaptureIter Cap = Candidates.begin(); Cap != Candidates.end(); ++Cap) {
+
+ if (Cap->isThisCapture()) {
+ Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
+ CapturedStmt::VCK_This));
+ CaptureInits.push_back(Cap->getCopyExpr());
+ continue;
+ }
+
+ assert(Cap->isReferenceCapture() &&
+ "non-reference capture not yet implemented");
+
+ Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
+ CapturedStmt::VCK_ByRef,
+ Cap->getVariable()));
+ CaptureInits.push_back(Cap->getCopyExpr());
+ }
+}
+
+void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
+ CapturedRegionKind Kind,
+ unsigned NumParams) {
+ CapturedDecl *CD = 0;
+ RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);
+
+ // Enter the capturing scope for this captured region.
+ PushCapturedRegionScope(CurScope, CD, RD, Kind);
+
+ if (CurScope)
+ PushDeclContext(CurScope, CD);
+ else
+ CurContext = CD;
+
+ PushExpressionEvaluationContext(PotentiallyEvaluated);
+}
+
+void Sema::ActOnCapturedRegionError() {
+ DiscardCleanupsInEvaluationContext();
+ PopExpressionEvaluationContext();
+
+ CapturedRegionScopeInfo *RSI = getCurCapturedRegion();
+ RecordDecl *Record = RSI->TheRecordDecl;
+ Record->setInvalidDecl();
+
+ SmallVector<Decl*, 4> Fields;
+ for (RecordDecl::field_iterator I = Record->field_begin(),
+ E = Record->field_end(); I != E; ++I)
+ Fields.push_back(*I);
+ ActOnFields(/*Scope=*/0, Record->getLocation(), Record, Fields,
+ SourceLocation(), SourceLocation(), /*AttributeList=*/0);
+
+ PopDeclContext();
+ PopFunctionScopeInfo();
+}
+
+StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) {
+ CapturedRegionScopeInfo *RSI = getCurCapturedRegion();
+
+ SmallVector<CapturedStmt::Capture, 4> Captures;
+ SmallVector<Expr *, 4> CaptureInits;
+ buildCapturedStmtCaptureList(Captures, CaptureInits, RSI->Captures);
+
+ CapturedDecl *CD = RSI->TheCapturedDecl;
+ RecordDecl *RD = RSI->TheRecordDecl;
+
+ CapturedStmt *Res = CapturedStmt::Create(getASTContext(), S,
+ RSI->CapRegionKind, Captures,
+ CaptureInits, CD, RD);
+
+ CD->setBody(Res->getCapturedStmt());
+ RD->completeDefinition();
+
+ DiscardCleanupsInEvaluationContext();
+ PopExpressionEvaluationContext();
+
+ PopDeclContext();
+ PopFunctionScopeInfo();
+
+ return Owned(Res);
+}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp
index da33bdf..fce95be 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmtAsm.cpp
@@ -22,18 +22,6 @@
#include "clang/Sema/ScopeInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MC/MCTargetAsmParser.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/TargetSelect.h"
using namespace clang;
using namespace sema;
@@ -381,158 +369,60 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
return Owned(NS);
}
-// getSpelling - Get the spelling of the AsmTok token.
-static StringRef getSpelling(Sema &SemaRef, Token AsmTok) {
- StringRef Asm;
- SmallString<512> TokenBuf;
- TokenBuf.resize(512);
- bool StringInvalid = false;
- Asm = SemaRef.PP.getSpelling(AsmTok, TokenBuf, &StringInvalid);
- assert (!StringInvalid && "Expected valid string!");
- return Asm;
-}
+ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
+ SourceLocation TemplateKWLoc,
+ UnqualifiedId &Id,
+ InlineAsmIdentifierInfo &Info,
+ bool IsUnevaluatedContext) {
+ Info.clear();
-// Build the inline assembly string. Returns true on error.
-static bool buildMSAsmString(Sema &SemaRef,
- SourceLocation AsmLoc,
- ArrayRef<Token> AsmToks,
- SmallVectorImpl<unsigned> &TokOffsets,
- std::string &AsmString) {
- assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
-
- SmallString<512> Asm;
- for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
- bool isNewAsm = ((i == 0) ||
- AsmToks[i].isAtStartOfLine() ||
- AsmToks[i].is(tok::kw_asm));
- if (isNewAsm) {
- if (i != 0)
- Asm += "\n\t";
-
- if (AsmToks[i].is(tok::kw_asm)) {
- i++; // Skip __asm
- if (i == e) {
- SemaRef.Diag(AsmLoc, diag::err_asm_empty);
- return true;
- }
+ if (IsUnevaluatedContext)
+ PushExpressionEvaluationContext(UnevaluatedAbstract,
+ ReuseLambdaContextDecl);
- }
- }
+ ExprResult Result = ActOnIdExpression(getCurScope(), SS, TemplateKWLoc, Id,
+ /*trailing lparen*/ false,
+ /*is & operand*/ false);
- if (i && AsmToks[i].hasLeadingSpace() && !isNewAsm)
- Asm += ' ';
+ if (IsUnevaluatedContext)
+ PopExpressionEvaluationContext();
- StringRef Spelling = getSpelling(SemaRef, AsmToks[i]);
- Asm += Spelling;
- TokOffsets.push_back(Asm.size());
- }
- AsmString = Asm.str();
- return false;
-}
+ if (!Result.isUsable()) return Result;
-namespace {
-
-class MCAsmParserSemaCallbackImpl : public llvm::MCAsmParserSemaCallback {
- Sema &SemaRef;
- SourceLocation AsmLoc;
- ArrayRef<Token> AsmToks;
- ArrayRef<unsigned> TokOffsets;
-
-public:
- MCAsmParserSemaCallbackImpl(Sema &Ref, SourceLocation Loc,
- ArrayRef<Token> Toks,
- ArrayRef<unsigned> Offsets)
- : SemaRef(Ref), AsmLoc(Loc), AsmToks(Toks), TokOffsets(Offsets) { }
- ~MCAsmParserSemaCallbackImpl() {}
-
- void *LookupInlineAsmIdentifier(StringRef Name, void *SrcLoc,
- unsigned &Length, unsigned &Size,
- unsigned &Type, bool &IsVarDecl){
- SourceLocation Loc = SourceLocation::getFromPtrEncoding(SrcLoc);
-
- NamedDecl *OpDecl = SemaRef.LookupInlineAsmIdentifier(Name, Loc, Length,
- Size, Type,
- IsVarDecl);
- return static_cast<void *>(OpDecl);
- }
+ Result = CheckPlaceholderExpr(Result.take());
+ if (!Result.isUsable()) return Result;
- bool LookupInlineAsmField(StringRef Base, StringRef Member,
- unsigned &Offset) {
- return SemaRef.LookupInlineAsmField(Base, Member, Offset, AsmLoc);
- }
+ QualType T = Result.get()->getType();
- static void MSAsmDiagHandlerCallback(const llvm::SMDiagnostic &D,
- void *Context) {
- ((MCAsmParserSemaCallbackImpl*)Context)->MSAsmDiagHandler(D);
- }
- void MSAsmDiagHandler(const llvm::SMDiagnostic &D) {
- // Compute an offset into the inline asm buffer.
- // FIXME: This isn't right if .macro is involved (but hopefully, no
- // real-world code does that).
- const llvm::SourceMgr &LSM = *D.getSourceMgr();
- const llvm::MemoryBuffer *LBuf =
- LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
- unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
-
- // Figure out which token that offset points into.
- const unsigned *OffsetPtr =
- std::lower_bound(TokOffsets.begin(), TokOffsets.end(), Offset);
- unsigned TokIndex = OffsetPtr - TokOffsets.begin();
-
- // If we come up with an answer which seems sane, use it; otherwise,
- // just point at the __asm keyword.
- // FIXME: Assert the answer is sane once we handle .macro correctly.
- SourceLocation Loc = AsmLoc;
- if (TokIndex < AsmToks.size()) {
- const Token *Tok = &AsmToks[TokIndex];
- Loc = Tok->getLocation();
- Loc = Loc.getLocWithOffset(Offset - (*OffsetPtr - Tok->getLength()));
- }
- SemaRef.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
+ // For now, reject dependent types.
+ if (T->isDependentType()) {
+ Diag(Id.getLocStart(), diag::err_asm_incomplete_type) << T;
+ return ExprError();
}
-};
-}
-
-NamedDecl *Sema::LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc,
- unsigned &Length, unsigned &Size,
- unsigned &Type, bool &IsVarDecl) {
- Length = 1;
- Size = 0;
- Type = 0;
- IsVarDecl = false;
- LookupResult Result(*this, &Context.Idents.get(Name), Loc,
- Sema::LookupOrdinaryName);
-
- if (!LookupName(Result, getCurScope())) {
- // If we don't find anything, return null; the AsmParser will assume
- // it is a label of some sort.
- return 0;
+ // Any sort of function type is fine.
+ if (T->isFunctionType()) {
+ return Result;
}
- if (!Result.isSingleResult()) {
- // FIXME: Diagnose result.
- return 0;
+ // Otherwise, it needs to be a complete type.
+ if (RequireCompleteExprType(Result.get(), diag::err_asm_incomplete_type)) {
+ return ExprError();
}
- NamedDecl *FoundDecl = Result.getFoundDecl();
- if (isa<FunctionDecl>(FoundDecl))
- return FoundDecl;
- if (VarDecl *Var = dyn_cast<VarDecl>(FoundDecl)) {
- QualType Ty = Var->getType();
- Type = Size = Context.getTypeSizeInChars(Ty).getQuantity();
- if (Ty->isArrayType()) {
- const ArrayType *ATy = Context.getAsArrayType(Ty);
- Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();
- Length = Size / Type;
- }
- IsVarDecl = true;
- return FoundDecl;
+ // Compute the type size (and array length if applicable?).
+ Info.Type = Info.Size = Context.getTypeSizeInChars(T).getQuantity();
+ if (T->isArrayType()) {
+ const ArrayType *ATy = Context.getAsArrayType(T);
+ Info.Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();
+ Info.Length = Info.Size / Info.Type;
}
- // FIXME: Handle other kinds of results? (FieldDecl, etc.)
- // FIXME: Diagnose if we find something we can't handle, like a typedef.
- return 0;
+ // We can work with the expression as long as it's not an r-value.
+ if (!Result.get()->isRValue())
+ Info.IsVarDecl = true;
+
+ return Result;
}
bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
@@ -579,124 +469,18 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
}
StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
- ArrayRef<Token> AsmToks,SourceLocation EndLoc) {
- SmallVector<IdentifierInfo*, 4> Names;
- SmallVector<StringRef, 4> ConstraintRefs;
- SmallVector<Expr*, 4> Exprs;
- SmallVector<StringRef, 4> ClobberRefs;
-
- llvm::Triple TheTriple = Context.getTargetInfo().getTriple();
- llvm::Triple::ArchType ArchTy = TheTriple.getArch();
- bool UnsupportedArch = ArchTy != llvm::Triple::x86 &&
- ArchTy != llvm::Triple::x86_64;
- if (UnsupportedArch)
- Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
-
- // Empty asm statements don't need to instantiate the AsmParser, etc.
- if (UnsupportedArch || AsmToks.empty()) {
- StringRef EmptyAsmStr;
- MSAsmStmt *NS =
- new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
- /*IsVolatile*/ true, AsmToks, /*NumOutputs*/ 0,
- /*NumInputs*/ 0, Names, ConstraintRefs, Exprs,
- EmptyAsmStr, ClobberRefs, EndLoc);
- return Owned(NS);
- }
-
- std::string AsmString;
- SmallVector<unsigned, 8> TokOffsets;
- if (buildMSAsmString(*this, AsmLoc, AsmToks, TokOffsets, AsmString))
- return StmtError();
-
- // Get the target specific parser.
- std::string Error;
- const std::string &TT = TheTriple.getTriple();
- const llvm::Target *TheTarget(llvm::TargetRegistry::lookupTarget(TT, Error));
-
- OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT));
- OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
- OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
- OwningPtr<llvm::MCSubtargetInfo>
- STI(TheTarget->createMCSubtargetInfo(TT, "", ""));
-
- llvm::SourceMgr SrcMgr;
- llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
- llvm::MemoryBuffer *Buffer =
- llvm::MemoryBuffer::getMemBuffer(AsmString, "<inline asm>");
-
- // Tell SrcMgr about this buffer, which is what the parser will pick up.
- SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
-
- OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
- OwningPtr<llvm::MCAsmParser>
- Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
- OwningPtr<llvm::MCTargetAsmParser>
- TargetParser(TheTarget->createMCAsmParser(*STI, *Parser));
-
- // Get the instruction descriptor.
- const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo();
- llvm::MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
-
- // Change to the Intel dialect.
- Parser->setAssemblerDialect(1);
- Parser->setTargetParser(*TargetParser.get());
- Parser->setParsingInlineAsm(true);
- TargetParser->setParsingInlineAsm(true);
-
- MCAsmParserSemaCallbackImpl MCAPSI(*this, AsmLoc, AsmToks, TokOffsets);
- TargetParser->setSemaCallback(&MCAPSI);
- SrcMgr.setDiagHandler(MCAsmParserSemaCallbackImpl::MSAsmDiagHandlerCallback,
- &MCAPSI);
-
- unsigned NumOutputs;
- unsigned NumInputs;
- std::string AsmStringIR;
- SmallVector<std::pair<void *, bool>, 4> OpDecls;
- SmallVector<std::string, 4> Constraints;
- SmallVector<std::string, 4> Clobbers;
- if (Parser->parseMSInlineAsm(AsmLoc.getPtrEncoding(), AsmStringIR,
- NumOutputs, NumInputs, OpDecls, Constraints,
- Clobbers, MII, IP, MCAPSI))
- return StmtError();
-
- // Build the vector of clobber StringRefs.
- unsigned NumClobbers = Clobbers.size();
- ClobberRefs.resize(NumClobbers);
- for (unsigned i = 0; i != NumClobbers; ++i)
- ClobberRefs[i] = StringRef(Clobbers[i]);
-
- // Recast the void pointers and build the vector of constraint StringRefs.
- unsigned NumExprs = NumOutputs + NumInputs;
- Names.resize(NumExprs);
- ConstraintRefs.resize(NumExprs);
- Exprs.resize(NumExprs);
- for (unsigned i = 0, e = NumExprs; i != e; ++i) {
- NamedDecl *OpDecl = static_cast<NamedDecl *>(OpDecls[i].first);
- if (!OpDecl)
- return StmtError();
-
- DeclarationNameInfo NameInfo(OpDecl->getDeclName(), AsmLoc);
- ExprResult OpExpr = BuildDeclarationNameExpr(CXXScopeSpec(), NameInfo,
- OpDecl);
- if (OpExpr.isInvalid())
- return StmtError();
-
- // Need address of variable.
- if (OpDecls[i].second)
- OpExpr = BuildUnaryOp(getCurScope(), AsmLoc, clang::UO_AddrOf,
- OpExpr.take());
-
- Names[i] = OpDecl->getIdentifier();
- ConstraintRefs[i] = StringRef(Constraints[i]);
- Exprs[i] = OpExpr.take();
- }
-
- bool IsSimple = NumExprs > 0;
+ ArrayRef<Token> AsmToks,
+ StringRef AsmString,
+ unsigned NumOutputs, unsigned NumInputs,
+ ArrayRef<StringRef> Constraints,
+ ArrayRef<StringRef> Clobbers,
+ ArrayRef<Expr*> Exprs,
+ SourceLocation EndLoc) {
+ bool IsSimple = (NumOutputs != 0 || NumInputs != 0);
MSAsmStmt *NS =
new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
/*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
- Names, ConstraintRefs, Exprs, AsmStringIR,
- ClobberRefs, EndLoc);
+ Constraints, Exprs, AsmString,
+ Clobbers, EndLoc);
return Owned(NS);
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp
index 9906261..b9695cc 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplate.cpp
@@ -3842,8 +3842,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
}
// A template argument must have static storage duration.
- // FIXME: Ensure this works for thread_local as well as __thread.
- if (Var->isThreadSpecified()) {
+ if (Var->getTLSKind()) {
S.Diag(Arg->getLocStart(), diag::err_template_arg_thread_local)
<< Arg->getSourceRange();
S.Diag(Var->getLocation(), diag::note_template_arg_refers_here);
@@ -6461,6 +6460,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// Set source locations for keywords.
Specialization->setExternLoc(ExternLoc);
Specialization->setTemplateKeywordLoc(TemplateLoc);
+ Specialization->setRBraceLoc(SourceLocation());
if (Attr)
ProcessDeclAttributeList(S, Specialization, Attr);
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp
index f3bbe8a..8efc7a0 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -52,7 +52,11 @@ namespace clang {
TDF_SkipNonDependent = 0x08,
/// \brief Whether we are performing template argument deduction for
/// parameters and arguments in a top-level template argument
- TDF_TopLevelParameterTypeList = 0x10
+ TDF_TopLevelParameterTypeList = 0x10,
+ /// \brief Within template argument deduction from overload resolution per
+ /// C++ [over.over] allow matching function types that are compatible in
+ /// terms of noreturn and default calling convention adjustments.
+ TDF_InOverloadResolution = 0x20
};
}
@@ -867,6 +871,32 @@ static bool hasInconsistentOrSupersetQualifiersOf(QualType ParamType,
== ParamQs.getCVRQualifiers());
}
+/// \brief Compare types for equality with respect to possibly compatible
+/// function types (noreturn adjustment, implicit calling conventions). If any
+/// of parameter and argument is not a function, just perform type comparison.
+///
+/// \param Param the template parameter type.
+///
+/// \param Arg the argument type.
+bool Sema::isSameOrCompatibleFunctionType(CanQualType Param,
+ CanQualType Arg) {
+ const FunctionType *ParamFunction = Param->getAs<FunctionType>(),
+ *ArgFunction = Arg->getAs<FunctionType>();
+
+ // Just compare if not functions.
+ if (!ParamFunction || !ArgFunction)
+ return Param == Arg;
+
+ // Noreturn adjustment.
+ QualType AdjustedParam;
+ if (IsNoReturnConversion(Param, Arg, AdjustedParam))
+ return Arg == Context.getCanonicalType(AdjustedParam);
+
+ // FIXME: Compatible calling conventions.
+
+ return Param == Arg;
+}
+
/// \brief Deduce the template arguments by comparing the parameter type and
/// the argument type (C++ [temp.deduct.type]).
///
@@ -1103,6 +1133,8 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
return Sema::TDK_Success;
// Check the cv-qualifiers on the parameter and argument types.
+ CanQualType CanParam = S.Context.getCanonicalType(Param);
+ CanQualType CanArg = S.Context.getCanonicalType(Arg);
if (!(TDF & TDF_IgnoreQualifiers)) {
if (TDF & TDF_ParamWithReferenceType) {
if (hasInconsistentOrSupersetQualifiersOf(Param, Arg))
@@ -1114,14 +1146,25 @@ DeduceTemplateArgumentsByTypeMatch(Sema &S,
// If the parameter type is not dependent, there is nothing to deduce.
if (!Param->isDependentType()) {
- if (!(TDF & TDF_SkipNonDependent) && Param != Arg)
- return Sema::TDK_NonDeducedMismatch;
-
+ if (!(TDF & TDF_SkipNonDependent)) {
+ bool NonDeduced = (TDF & TDF_InOverloadResolution)?
+ !S.isSameOrCompatibleFunctionType(CanParam, CanArg) :
+ Param != Arg;
+ if (NonDeduced) {
+ return Sema::TDK_NonDeducedMismatch;
+ }
+ }
return Sema::TDK_Success;
}
- } else if (!Param->isDependentType() &&
- Param.getUnqualifiedType() == Arg.getUnqualifiedType()) {
- return Sema::TDK_Success;
+ } else if (!Param->isDependentType()) {
+ CanQualType ParamUnqualType = CanParam.getUnqualifiedType(),
+ ArgUnqualType = CanArg.getUnqualifiedType();
+ bool Success = (TDF & TDF_InOverloadResolution)?
+ S.isSameOrCompatibleFunctionType(ParamUnqualType,
+ ArgUnqualType) :
+ ParamUnqualType == ArgUnqualType;
+ if (Success)
+ return Sema::TDK_Success;
}
switch (Param->getTypeClass()) {
@@ -2761,21 +2804,25 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
/// Gets the type of a function for template-argument-deducton
/// purposes when it's considered as part of an overload set.
-static QualType GetTypeOfFunction(ASTContext &Context,
- const OverloadExpr::FindResult &R,
+static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,
FunctionDecl *Fn) {
+ // We may need to deduce the return type of the function now.
+ if (S.getLangOpts().CPlusPlus1y && Fn->getResultType()->isUndeducedType() &&
+ S.DeduceReturnType(Fn, R.Expression->getExprLoc(), /*Diagnose*/false))
+ return QualType();
+
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
if (Method->isInstance()) {
// An instance method that's referenced in a form that doesn't
// look like a member pointer is just invalid.
if (!R.HasFormOfMemberPointer) return QualType();
- return Context.getMemberPointerType(Fn->getType(),
- Context.getTypeDeclType(Method->getParent()).getTypePtr());
+ return S.Context.getMemberPointerType(Fn->getType(),
+ S.Context.getTypeDeclType(Method->getParent()).getTypePtr());
}
if (!R.IsAddressOfOperand) return Fn->getType();
- return Context.getPointerType(Fn->getType());
+ return S.Context.getPointerType(Fn->getType());
}
/// Apply the deduction rules for overload sets.
@@ -2809,7 +2856,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
// But we can still look for an explicit specialization.
if (FunctionDecl *ExplicitSpec
= S.ResolveSingleFunctionTemplateSpecialization(Ovl))
- return GetTypeOfFunction(S.Context, R, ExplicitSpec);
+ return GetTypeOfFunction(S, R, ExplicitSpec);
}
return QualType();
@@ -2842,7 +2889,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
}
FunctionDecl *Fn = cast<FunctionDecl>(D);
- QualType ArgType = GetTypeOfFunction(S.Context, R, Fn);
+ QualType ArgType = GetTypeOfFunction(S, R, Fn);
if (ArgType.isNull()) continue;
// Function-to-pointer conversion.
@@ -3316,7 +3363,8 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo *ExplicitTemplateArgs,
QualType ArgFunctionType,
FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info) {
+ TemplateDeductionInfo &Info,
+ bool InOverloadResolution) {
if (FunctionTemplate->isInvalidDecl())
return TDK_Invalid;
@@ -3347,12 +3395,23 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
Deduced.resize(TemplateParams->size());
+ // If the function has a deduced return type, substitute it for a dependent
+ // type so that we treat it as a non-deduced context in what follows.
+ bool HasUndeducedReturnType = false;
+ if (getLangOpts().CPlusPlus1y && InOverloadResolution &&
+ Function->getResultType()->isUndeducedType()) {
+ FunctionType = SubstAutoType(FunctionType, Context.DependentTy);
+ HasUndeducedReturnType = true;
+ }
+
if (!ArgFunctionType.isNull()) {
+ unsigned TDF = TDF_TopLevelParameterTypeList;
+ if (InOverloadResolution) TDF |= TDF_InOverloadResolution;
// Deduce template arguments from the function type.
if (TemplateDeductionResult Result
= DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams,
- FunctionType, ArgFunctionType, Info,
- Deduced, TDF_TopLevelParameterTypeList))
+ FunctionType, ArgFunctionType,
+ Info, Deduced, TDF))
return Result;
}
@@ -3362,12 +3421,26 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
Specialization, Info))
return Result;
- // If the requested function type does not match the actual type of the
- // specialization, template argument deduction fails.
- if (!ArgFunctionType.isNull() &&
- !Context.hasSameType(ArgFunctionType, Specialization->getType()))
+ // If the function has a deduced return type, deduce it now, so we can check
+ // that the deduced function type matches the requested type.
+ if (HasUndeducedReturnType &&
+ Specialization->getResultType()->isUndeducedType() &&
+ DeduceReturnType(Specialization, Info.getLocation(), false))
return TDK_MiscellaneousDeductionFailure;
+ // If the requested function type does not match the actual type of the
+ // specialization with respect to arguments of compatible pointer to function
+ // types, template argument deduction fails.
+ if (!ArgFunctionType.isNull()) {
+ if (InOverloadResolution && !isSameOrCompatibleFunctionType(
+ Context.getCanonicalType(Specialization->getType()),
+ Context.getCanonicalType(ArgFunctionType)))
+ return TDK_MiscellaneousDeductionFailure;
+ else if(!InOverloadResolution &&
+ !Context.hasSameType(Specialization->getType(), ArgFunctionType))
+ return TDK_MiscellaneousDeductionFailure;
+ }
+
return TDK_Success;
}
@@ -3499,9 +3572,11 @@ Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
TemplateArgumentListInfo *ExplicitTemplateArgs,
FunctionDecl *&Specialization,
- TemplateDeductionInfo &Info) {
+ TemplateDeductionInfo &Info,
+ bool InOverloadResolution) {
return DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs,
- QualType(), Specialization, Info);
+ QualType(), Specialization, Info,
+ InOverloadResolution);
}
namespace {
@@ -3522,13 +3597,19 @@ namespace {
// auto &&lref = lvalue;
// must transform into "rvalue reference to T" not "rvalue reference to
// auto type deduced as T" in order for [temp.deduct.call]p3 to apply.
- if (isa<TemplateTypeParmType>(Replacement)) {
+ if (!Replacement.isNull() && isa<TemplateTypeParmType>(Replacement)) {
QualType Result = Replacement;
- TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
+ TemplateTypeParmTypeLoc NewTL =
+ TLB.push<TemplateTypeParmTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
} else {
- QualType Result = RebuildAutoType(Replacement);
+ bool Dependent =
+ !Replacement.isNull() && Replacement->isDependentType();
+ QualType Result =
+ SemaRef.Context.getAutoType(Dependent ? QualType() : Replacement,
+ TL.getTypePtr()->isDecltypeAuto(),
+ Dependent);
AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
@@ -3539,69 +3620,63 @@ namespace {
// Lambdas never need to be transformed.
return E;
}
- };
- /// Determine whether the specified type (which contains an 'auto' type
- /// specifier) is dependent. This is not trivial, because the 'auto' specifier
- /// itself claims to be type-dependent.
- bool isDependentAutoType(QualType Ty) {
- while (1) {
- QualType Pointee = Ty->getPointeeType();
- if (!Pointee.isNull()) {
- Ty = Pointee;
- } else if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>()){
- if (MPT->getClass()->isDependentType())
- return true;
- Ty = MPT->getPointeeType();
- } else if (const FunctionProtoType *FPT = Ty->getAs<FunctionProtoType>()){
- for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(),
- E = FPT->arg_type_end();
- I != E; ++I)
- if ((*I)->isDependentType())
- return true;
- Ty = FPT->getResultType();
- } else if (Ty->isDependentSizedArrayType()) {
- return true;
- } else if (const ArrayType *AT = Ty->getAsArrayTypeUnsafe()) {
- Ty = AT->getElementType();
- } else if (Ty->getAs<DependentSizedExtVectorType>()) {
- return true;
- } else if (const VectorType *VT = Ty->getAs<VectorType>()) {
- Ty = VT->getElementType();
- } else {
- break;
- }
+ QualType Apply(TypeLoc TL) {
+ // Create some scratch storage for the transformed type locations.
+ // FIXME: We're just going to throw this information away. Don't build it.
+ TypeLocBuilder TLB;
+ TLB.reserve(TL.getFullDataSize());
+ return TransformType(TLB, TL);
}
- assert(Ty->getAs<AutoType>() && "didn't find 'auto' in auto type");
- return false;
- }
+ };
+}
+
+Sema::DeduceAutoResult
+Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result) {
+ return DeduceAutoType(Type->getTypeLoc(), Init, Result);
}
-/// \brief Deduce the type for an auto type-specifier (C++0x [dcl.spec.auto]p6)
+/// \brief Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
///
/// \param Type the type pattern using the auto type-specifier.
-///
/// \param Init the initializer for the variable whose type is to be deduced.
-///
/// \param Result if type deduction was successful, this will be set to the
-/// deduced type. This may still contain undeduced autos if the type is
-/// dependent. This will be set to null if deduction succeeded, but auto
-/// substitution failed; the appropriate diagnostic will already have been
-/// produced in that case.
+/// deduced type.
Sema::DeduceAutoResult
-Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
- TypeSourceInfo *&Result) {
+Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result) {
if (Init->getType()->isNonOverloadPlaceholderType()) {
- ExprResult result = CheckPlaceholderExpr(Init);
- if (result.isInvalid()) return DAR_FailedAlreadyDiagnosed;
- Init = result.take();
+ ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
+ if (NonPlaceholder.isInvalid())
+ return DAR_FailedAlreadyDiagnosed;
+ Init = NonPlaceholder.take();
}
- if (Init->isTypeDependent() || isDependentAutoType(Type->getType())) {
- Result = Type;
+ if (Init->isTypeDependent() || Type.getType()->isDependentType()) {
+ Result = SubstituteAutoTransform(*this, Context.DependentTy).Apply(Type);
+ assert(!Result.isNull() && "substituting DependentTy can't fail");
return DAR_Succeeded;
}
+ // If this is a 'decltype(auto)' specifier, do the decltype dance.
+ // Since 'decltype(auto)' can only occur at the top of the type, we
+ // don't need to go digging for it.
+ if (const AutoType *AT = Type.getType()->getAs<AutoType>()) {
+ if (AT->isDecltypeAuto()) {
+ if (isa<InitListExpr>(Init)) {
+ Diag(Init->getLocStart(), diag::err_decltype_auto_initializer_list);
+ return DAR_FailedAlreadyDiagnosed;
+ }
+
+ QualType Deduced = BuildDecltypeType(Init, Init->getLocStart());
+ // FIXME: Support a non-canonical deduced type for 'auto'.
+ Deduced = Context.getCanonicalType(Deduced);
+ Result = SubstituteAutoTransform(*this, Deduced).Apply(Type);
+ if (Result.isNull())
+ return DAR_FailedAlreadyDiagnosed;
+ return DAR_Succeeded;
+ }
+ }
+
SourceLocation Loc = Init->getExprLoc();
LocalInstantiationScope InstScope(*this);
@@ -3615,10 +3690,9 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr,
Loc);
- TypeSourceInfo *FuncParamInfo =
- SubstituteAutoTransform(*this, TemplArg).TransformType(Type);
- assert(FuncParamInfo && "substituting template parameter for 'auto' failed");
- QualType FuncParam = FuncParamInfo->getType();
+ QualType FuncParam = SubstituteAutoTransform(*this, TemplArg).Apply(Type);
+ assert(!FuncParam.isNull() &&
+ "substituting template parameter for 'auto' failed");
// Deduce type of TemplParam in Func(Init)
SmallVector<DeducedTemplateArgument, 1> Deduced;
@@ -3659,21 +3733,27 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
return DAR_FailedAlreadyDiagnosed;
}
- Result = SubstituteAutoTransform(*this, DeducedType).TransformType(Type);
+ Result = SubstituteAutoTransform(*this, DeducedType).Apply(Type);
+ if (Result.isNull())
+ return DAR_FailedAlreadyDiagnosed;
// Check that the deduced argument type is compatible with the original
// argument type per C++ [temp.deduct.call]p4.
- if (!InitList && Result &&
- CheckOriginalCallArgDeduction(*this,
+ if (!InitList && !Result.isNull() &&
+ CheckOriginalCallArgDeduction(*this,
Sema::OriginalCallArg(FuncParam,0,InitType),
- Result->getType())) {
- Result = 0;
+ Result)) {
+ Result = QualType();
return DAR_Failed;
}
return DAR_Succeeded;
}
+QualType Sema::SubstAutoType(QualType Type, QualType Deduced) {
+ return SubstituteAutoTransform(*this, Deduced).TransformType(Type);
+}
+
void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
if (isa<InitListExpr>(Init))
Diag(VDecl->getLocation(),
@@ -3685,6 +3765,22 @@ void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
<< Init->getSourceRange();
}
+bool Sema::DeduceReturnType(FunctionDecl *FD, SourceLocation Loc,
+ bool Diagnose) {
+ assert(FD->getResultType()->isUndeducedType());
+
+ if (FD->getTemplateInstantiationPattern())
+ InstantiateFunctionDefinition(Loc, FD);
+
+ bool StillUndeduced = FD->getResultType()->isUndeducedType();
+ if (StillUndeduced && Diagnose && !FD->isInvalidDecl()) {
+ Diag(Loc, diag::err_auto_fn_used_before_defined) << FD;
+ Diag(FD->getLocation(), diag::note_callee_decl) << FD;
+ }
+
+ return StillUndeduced;
+}
+
static void
MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
bool OnlyDeduced,
@@ -4053,7 +4149,7 @@ static bool isSameTemplate(TemplateDecl *T1, TemplateDecl *T2) {
/// template argument deduction.
UnresolvedSetIterator
Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
- UnresolvedSetIterator SpecEnd,
+ UnresolvedSetIterator SpecEnd,
TemplatePartialOrderingContext TPOC,
unsigned NumCallArguments,
SourceLocation Loc,
@@ -4110,11 +4206,10 @@ Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
}
// Diagnose the ambiguity.
- if (Complain)
+ if (Complain) {
Diag(Loc, AmbigDiag);
- if (Complain)
- // FIXME: Can we order the candidates in some sane way?
+ // FIXME: Can we order the candidates in some sane way?
for (UnresolvedSetIterator I = SpecBegin; I != SpecEnd; ++I) {
PartialDiagnostic PD = CandidateDiag;
PD << getTemplateArgumentBindingsText(
@@ -4125,6 +4220,7 @@ Sema::getMostSpecialized(UnresolvedSetIterator SpecBegin,
TargetType);
Diag((*I)->getLocation(), PD);
}
+ }
return SpecEnd;
}
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
index f755b8c..7ef04e9 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2701,11 +2701,10 @@ void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = LocalDecls[D];
if (Stored.isNull())
Stored = Inst;
- else if (Stored.is<Decl *>()) {
+ else if (DeclArgumentPack *Pack = Stored.dyn_cast<DeclArgumentPack *>())
+ Pack->push_back(Inst);
+ else
assert(Stored.get<Decl *>() == Inst && "Already instantiated this local");
- Stored = Inst;
- } else
- LocalDecls[D].get<DeclArgumentPack *>()->push_back(Inst);
}
void LocalInstantiationScope::InstantiatedLocalPackArg(const Decl *D,
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 33e83d0..d1428c5 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -339,7 +339,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
D->getLocation(), D->getIdentifier(),
DI->getType(), DI,
D->getStorageClass());
- Var->setThreadSpecified(D->isThreadSpecified());
+ Var->setTSCSpec(D->getTSCSpec());
Var->setInitStyle(D->getInitStyle());
Var->setCXXForRangeDecl(D->isCXXForRangeDecl());
Var->setConstexpr(D->isConstexpr());
@@ -525,6 +525,53 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
return Field;
}
+Decl *TemplateDeclInstantiator::VisitMSPropertyDecl(MSPropertyDecl *D) {
+ bool Invalid = false;
+ TypeSourceInfo *DI = D->getTypeSourceInfo();
+
+ if (DI->getType()->isVariablyModifiedType()) {
+ SemaRef.Diag(D->getLocation(), diag::err_property_is_variably_modified)
+ << D->getName();
+ Invalid = true;
+ } else if (DI->getType()->isInstantiationDependentType()) {
+ DI = SemaRef.SubstType(DI, TemplateArgs,
+ D->getLocation(), D->getDeclName());
+ if (!DI) {
+ DI = D->getTypeSourceInfo();
+ Invalid = true;
+ } else if (DI->getType()->isFunctionType()) {
+ // C++ [temp.arg.type]p3:
+ // If a declaration acquires a function type through a type
+ // dependent on a template-parameter and this causes a
+ // declaration that does not use the syntactic form of a
+ // function declarator to have function type, the program is
+ // ill-formed.
+ SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
+ << DI->getType();
+ Invalid = true;
+ }
+ } else {
+ SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
+ }
+
+ MSPropertyDecl *Property = new (SemaRef.Context)
+ MSPropertyDecl(Owner, D->getLocation(),
+ D->getDeclName(), DI->getType(), DI,
+ D->getLocStart(),
+ D->getGetterId(), D->getSetterId());
+
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Property, LateAttrs,
+ StartingScope);
+
+ if (Invalid)
+ Property->setInvalidDecl();
+
+ Property->setAccess(D->getAccess());
+ Owner->addDecl(Property);
+
+ return Property;
+}
+
Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
NamedDecl **NamedChain =
new (SemaRef.Context)NamedDecl*[D->getChainingSize()];
@@ -754,7 +801,7 @@ void TemplateDeclInstantiator::InstantiateEnumDefinition(
// FIXME: Fixup LBraceLoc
SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(),
Enum->getRBraceLoc(), Enum,
- Enumerators.data(), Enumerators.size(),
+ Enumerators,
0, 0);
}
@@ -1105,12 +1152,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
// this declaration.
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
if (FunctionTemplate && !TemplateParams) {
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
void *InsertPos = 0;
FunctionDecl *SpecFunc
- = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ = FunctionTemplate->findSpecialization(Innermost.begin(), Innermost.size(),
InsertPos);
// If we already have a function template specialization, return it.
@@ -1162,7 +1208,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
FunctionDecl *Function =
FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(),
D->getNameInfo(), T, TInfo,
- D->getStorageClass(),
+ D->getCanonicalDecl()->getStorageClass(),
D->isInlineSpecified(), D->hasWrittenPrototype(),
D->isConstexpr());
@@ -1235,12 +1281,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
}
} else if (FunctionTemplate) {
// Record this function template specialization.
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
Function->setFunctionTemplateSpecialization(FunctionTemplate,
TemplateArgumentList::CreateCopy(SemaRef.Context,
- Innermost.first,
- Innermost.second),
+ Innermost.begin(),
+ Innermost.size()),
/*InsertPos=*/0);
} else if (isFriend) {
// Note, we need this connection even if the friend doesn't have a body.
@@ -1413,12 +1458,12 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
// We are creating a function template specialization from a function
// template. Check whether there is already a function template
// specialization for this particular set of template arguments.
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
void *InsertPos = 0;
FunctionDecl *SpecFunc
- = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ = FunctionTemplate->findSpecialization(Innermost.begin(),
+ Innermost.size(),
InsertPos);
// If we already have a function template specialization, return it.
@@ -1513,6 +1558,36 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Constructor->isExplicit(),
Constructor->isInlineSpecified(),
false, Constructor->isConstexpr());
+
+ // Claim that the instantiation of a constructor or constructor template
+ // inherits the same constructor that the template does.
+ if (CXXConstructorDecl *Inh = const_cast<CXXConstructorDecl *>(
+ Constructor->getInheritedConstructor())) {
+ // If we're instantiating a specialization of a function template, our
+ // "inherited constructor" will actually itself be a function template.
+ // Instantiate a declaration of it, too.
+ if (FunctionTemplate) {
+ assert(!TemplateParams && Inh->getDescribedFunctionTemplate() &&
+ !Inh->getParent()->isDependentContext() &&
+ "inheriting constructor template in dependent context?");
+ Sema::InstantiatingTemplate Inst(SemaRef, Constructor->getLocation(),
+ Inh);
+ if (Inst)
+ return 0;
+ Sema::ContextRAII SavedContext(SemaRef, Inh->getDeclContext());
+ LocalInstantiationScope LocalScope(SemaRef);
+
+ // Use the same template arguments that we deduced for the inheriting
+ // constructor. There's no way they could be deduced differently.
+ MultiLevelTemplateArgumentList InheritedArgs;
+ InheritedArgs.addOuterTemplateArguments(TemplateArgs.getInnermost());
+ Inh = cast_or_null<CXXConstructorDecl>(
+ SemaRef.SubstDecl(Inh, Inh->getDeclContext(), InheritedArgs));
+ if (!Inh)
+ return 0;
+ }
+ cast<CXXConstructorDecl>(Method)->setInheritedConstructor(Inh);
+ }
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
@@ -1526,10 +1601,10 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Conversion->isConstexpr(),
Conversion->getLocEnd());
} else {
+ StorageClass SC = D->isStatic() ? SC_Static : SC_None;
Method = CXXMethodDecl::Create(SemaRef.Context, Record,
StartLoc, NameInfo, T, TInfo,
- D->getStorageClass(),
- D->isInlineSpecified(),
+ SC, D->isInlineSpecified(),
D->isConstexpr(), D->getLocEnd());
}
@@ -1565,12 +1640,11 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
Method->setDescribedFunctionTemplate(FunctionTemplate);
} else if (FunctionTemplate) {
// Record this function template specialization.
- std::pair<const TemplateArgument *, unsigned> Innermost
- = TemplateArgs.getInnermost();
+ ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost();
Method->setFunctionTemplateSpecialization(FunctionTemplate,
TemplateArgumentList::CreateCopy(SemaRef.Context,
- Innermost.first,
- Innermost.second),
+ Innermost.begin(),
+ Innermost.size()),
/*InsertPos=*/0);
} else if (!isFriend) {
// Record that this is an instantiation of a member function.
@@ -2688,15 +2762,16 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
FunctionDecl *ExceptionSpecTemplate = Tmpl;
if (EPI.ExceptionSpecType == EST_Uninstantiated)
ExceptionSpecTemplate = EPI.ExceptionSpecTemplate;
- assert(EPI.ExceptionSpecType != EST_Unevaluated &&
- "instantiating implicitly-declared special member");
+ ExceptionSpecificationType NewEST = EST_Uninstantiated;
+ if (EPI.ExceptionSpecType == EST_Unevaluated)
+ NewEST = EST_Unevaluated;
// Mark the function has having an uninstantiated exception specification.
const FunctionProtoType *NewProto
= New->getType()->getAs<FunctionProtoType>();
assert(NewProto && "Template instantiation without function prototype?");
EPI = NewProto->getExtProtoInfo();
- EPI.ExceptionSpecType = EST_Uninstantiated;
+ EPI.ExceptionSpecType = NewEST;
EPI.ExceptionSpecDecl = New;
EPI.ExceptionSpecTemplate = ExceptionSpecTemplate;
New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(),
@@ -2733,7 +2808,6 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
if (Tmpl->isVirtualAsWritten())
New->setVirtualAsWritten(true);
- // FIXME: attributes
// FIXME: New needs a pointer to Tmpl
return false;
}
@@ -2820,13 +2894,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
return;
}
- // C++0x [temp.explicit]p9:
- // Except for inline functions, other explicit instantiation declarations
- // have the effect of suppressing the implicit instantiation of the entity
- // to which they refer.
+ // C++1y [temp.explicit]p10:
+ // Except for inline functions, declarations with types deduced from their
+ // initializer or return value, and class template specializations, other
+ // explicit instantiation declarations have the effect of suppressing the
+ // implicit instantiation of the entity to which they refer.
if (Function->getTemplateSpecializationKind()
== TSK_ExplicitInstantiationDeclaration &&
- !PatternDecl->isInlined())
+ !PatternDecl->isInlined() &&
+ !PatternDecl->getResultType()->isUndeducedType())
return;
if (PatternDecl->isInlined())
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp
index c0ad2be..db885ae 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -727,6 +727,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
case TST_interface:
case TST_class:
case TST_auto:
+ case TST_decltype_auto:
case TST_unknown_anytype:
case TST_image1d_t:
case TST_image1d_array_t:
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp
index 7169eea..0959f7d 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaType.cpp
@@ -793,9 +793,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
// "At least one type specifier shall be given in the declaration
// specifiers in each declaration, and in the specifier-qualifier list in
// each struct declaration and type name."
- // FIXME: Does Microsoft really have the implicit int extension in C++?
- if (S.getLangOpts().CPlusPlus &&
- !S.getLangOpts().MicrosoftExt) {
+ if (S.getLangOpts().CPlusPlus) {
S.Diag(DeclLoc, diag::err_missing_type_specifier)
<< DS.getSourceRange();
@@ -994,11 +992,14 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
}
break;
- case DeclSpec::TST_auto: {
+ case DeclSpec::TST_auto:
// TypeQuals handled by caller.
- Result = Context.getAutoType(QualType());
+ Result = Context.getAutoType(QualType(), /*decltype(auto)*/false);
+ break;
+
+ case DeclSpec::TST_decltype_auto:
+ Result = Context.getAutoType(QualType(), /*decltype(auto)*/true);
break;
- }
case DeclSpec::TST_unknown_anytype:
Result = Context.UnknownAnyTy;
@@ -1457,12 +1458,6 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
return QualType();
}
- if (T->getContainedAutoType()) {
- Diag(Loc, diag::err_illegal_decl_array_of_auto)
- << getPrintableNameForEntity(Entity) << T;
- return QualType();
- }
-
if (const RecordType *EltTy = T->getAs<RecordType>()) {
// If the element type is a struct or union that contains a variadic
// array, accept it as a GNU extension: C99 6.7.2.1p2.
@@ -1572,6 +1567,7 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
if (!getLangOpts().C99) {
if (T->isVariableArrayType()) {
// Prohibit the use of non-POD types in VLAs.
+ // FIXME: C++1y allows this.
QualType BaseT = Context.getBaseElementType(T);
if (!T->isDependentType() &&
!BaseT.isPODType(Context) &&
@@ -1587,7 +1583,9 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
}
// Just extwarn about VLAs.
else
- Diag(Loc, diag::ext_vla);
+ Diag(Loc, getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_array_of_runtime_bound
+ : diag::ext_vla);
} else if (ASM != ArrayType::Normal || Quals != 0)
Diag(Loc,
getLangOpts().CPlusPlus? diag::err_c99_array_usage_cxx
@@ -2020,6 +2018,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
// The TagDecl owned by the DeclSpec.
TagDecl *OwnedTagDecl = 0;
+ bool ContainsPlaceholderType = false;
+
switch (D.getName().getKind()) {
case UnqualifiedId::IK_ImplicitSelfParam:
case UnqualifiedId::IK_OperatorFunctionId:
@@ -2027,6 +2027,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedId::IK_TemplateId:
T = ConvertDeclSpecToType(state);
+ ContainsPlaceholderType = D.getDeclSpec().containsPlaceholderType();
if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
OwnedTagDecl = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
@@ -2050,6 +2051,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
// converts to.
T = SemaRef.GetTypeFromParser(D.getName().ConversionFunctionId,
&ReturnTypeInfo);
+ ContainsPlaceholderType = T->getContainedAutoType();
break;
}
@@ -2060,7 +2062,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
// In C++11, a function declarator using 'auto' must have a trailing return
// type (this is checked later) and we can skip this. In other languages
// using auto, we need to check regardless.
- if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
+ if (ContainsPlaceholderType &&
(!SemaRef.getLangOpts().CPlusPlus11 || !D.isFunctionDeclarator())) {
int Error = -1;
@@ -2103,10 +2105,15 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
Error = 10; // Type alias
break;
case Declarator::TrailingReturnContext:
- Error = 11; // Function return type
+ if (!SemaRef.getLangOpts().CPlusPlus1y)
+ Error = 11; // Function return type
+ break;
+ case Declarator::ConversionIdContext:
+ if (!SemaRef.getLangOpts().CPlusPlus1y)
+ Error = 12; // conversion-type-id
break;
case Declarator::TypeNameContext:
- Error = 12; // Generic
+ Error = 13; // Generic
break;
case Declarator::FileContext:
case Declarator::BlockContext:
@@ -2142,15 +2149,19 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
}
}
+ SourceRange AutoRange = D.getDeclSpec().getTypeSpecTypeLoc();
+ if (D.getName().getKind() == UnqualifiedId::IK_ConversionFunctionId)
+ AutoRange = D.getName().getSourceRange();
+
if (Error != -1) {
- SemaRef.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
- diag::err_auto_not_allowed)
- << Error;
+ SemaRef.Diag(AutoRange.getBegin(), diag::err_auto_not_allowed)
+ << Error << AutoRange;
T = SemaRef.Context.IntTy;
D.setInvalidType(true);
} else
- SemaRef.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
- diag::warn_cxx98_compat_auto_type_specifier);
+ SemaRef.Diag(AutoRange.getBegin(),
+ diag::warn_cxx98_compat_auto_type_specifier)
+ << AutoRange;
}
if (SemaRef.getLangOpts().CPlusPlus &&
@@ -2182,6 +2193,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
D.setInvalidType(true);
break;
case Declarator::TypeNameContext:
+ case Declarator::ConversionIdContext:
case Declarator::TemplateParamContext:
case Declarator::CXXNewContext:
case Declarator::CXXCatchContext:
@@ -2399,6 +2411,46 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
(T->castAs<FunctionProtoType>()->getTypeQuals() != 0 ||
T->castAs<FunctionProtoType>()->getRefQualifier() != RQ_None);
+ // If T is 'decltype(auto)', the only declarators we can have are parens
+ // and at most one function declarator if this is a function declaration.
+ if (const AutoType *AT = T->getAs<AutoType>()) {
+ if (AT->isDecltypeAuto()) {
+ for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) {
+ unsigned Index = E - I - 1;
+ DeclaratorChunk &DeclChunk = D.getTypeObject(Index);
+ unsigned DiagId = diag::err_decltype_auto_compound_type;
+ unsigned DiagKind = 0;
+ switch (DeclChunk.Kind) {
+ case DeclaratorChunk::Paren:
+ continue;
+ case DeclaratorChunk::Function: {
+ unsigned FnIndex;
+ if (D.isFunctionDeclarationContext() &&
+ D.isFunctionDeclarator(FnIndex) && FnIndex == Index)
+ continue;
+ DiagId = diag::err_decltype_auto_function_declarator_not_declaration;
+ break;
+ }
+ case DeclaratorChunk::Pointer:
+ case DeclaratorChunk::BlockPointer:
+ case DeclaratorChunk::MemberPointer:
+ DiagKind = 0;
+ break;
+ case DeclaratorChunk::Reference:
+ DiagKind = 1;
+ break;
+ case DeclaratorChunk::Array:
+ DiagKind = 2;
+ break;
+ }
+
+ S.Diag(DeclChunk.Loc, DiagId) << DiagKind;
+ D.setInvalidType(true);
+ break;
+ }
+ }
+ }
+
// Walk the DeclTypeInfo, building the recursive type as we go.
// DeclTypeInfos are ordered from the identifier out, which is
// opposite of what we want :).
@@ -2527,6 +2579,15 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
}
}
+ if (const AutoType *AT = T->getContainedAutoType()) {
+ // We've already diagnosed this for decltype(auto).
+ if (!AT->isDecltypeAuto())
+ S.Diag(DeclType.Loc, diag::err_illegal_decl_array_of_auto)
+ << getPrintableNameForEntity(Name) << T;
+ T = QualType();
+ break;
+ }
+
T = S.BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals,
SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
break;
@@ -2544,7 +2605,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// trailing-return-type is only required if we're declaring a function,
// and not, for instance, a pointer to a function.
if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
- !FTI.hasTrailingReturnType() && chunkIndex == 0) {
+ !FTI.hasTrailingReturnType() && chunkIndex == 0 &&
+ !S.getLangOpts().CPlusPlus1y) {
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
diag::err_auto_missing_trailing_return);
T = Context.IntTy;
@@ -2557,7 +2619,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
<< T << D.getDeclSpec().getSourceRange();
D.setInvalidType(true);
} else if (D.getContext() != Declarator::LambdaExprContext &&
- (T.hasQualifiers() || !isa<AutoType>(T))) {
+ (T.hasQualifiers() || !isa<AutoType>(T) ||
+ cast<AutoType>(T)->isDecltypeAuto())) {
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
diag::err_trailing_return_without_auto)
<< T << D.getDeclSpec().getSourceRange();
@@ -3044,6 +3107,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
case Declarator::ObjCCatchContext:
case Declarator::BlockLiteralContext:
case Declarator::LambdaExprContext:
+ case Declarator::ConversionIdContext:
case Declarator::TrailingReturnContext:
case Declarator::TemplateTypeArgContext:
// FIXME: We may want to allow parameter packs in block-literal contexts
@@ -3781,7 +3845,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
QualType &type) {
bool NonObjCPointer = false;
- if (!type->isDependentType()) {
+ if (!type->isDependentType() && !type->isUndeducedType()) {
if (const PointerType *ptr = type->getAs<PointerType>()) {
QualType pointee = ptr->getPointeeType();
if (pointee->isObjCRetainableType() || pointee->isPointerType())
@@ -4806,7 +4870,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
QualType ElemType = Context.getBaseElementType(T);
RequireCompleteType(Loc, ElemType, 0);
- if (T->isLiteralType())
+ if (T->isLiteralType(Context))
return false;
if (Diagnoser.Suppressed)
@@ -4848,7 +4912,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
} else if (RD->hasNonLiteralTypeFieldsOrBases()) {
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
E = RD->bases_end(); I != E; ++I) {
- if (!I->getType()->isLiteralType()) {
+ if (!I->getType()->isLiteralType(Context)) {
Diag(I->getLocStart(),
diag::note_non_literal_base_class)
<< RD << I->getType() << I->getSourceRange();
@@ -4857,7 +4921,7 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
}
for (CXXRecordDecl::field_iterator I = RD->field_begin(),
E = RD->field_end(); I != E; ++I) {
- if (!I->getType()->isLiteralType() ||
+ if (!I->getType()->isLiteralType(Context) ||
I->getType().isVolatileQualified()) {
Diag(I->getLocation(), diag::note_non_literal_field)
<< RD << *I << I->getType()
diff --git a/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h b/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h
index bdd68a7..89e23ef 100644
--- a/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h
+++ b/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h
@@ -754,17 +754,20 @@ public:
UnaryTransformType::UTTKind UKind,
SourceLocation Loc);
- /// \brief Build a new C++0x decltype type.
+ /// \brief Build a new C++11 decltype type.
///
/// By default, performs semantic analysis when building the decltype type.
/// Subclasses may override this routine to provide different behavior.
QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
- /// \brief Build a new C++0x auto type.
+ /// \brief Build a new C++11 auto type.
///
/// By default, builds a new AutoType with the given deduced type.
- QualType RebuildAutoType(QualType Deduced) {
- return SemaRef.Context.getAutoType(Deduced);
+ QualType RebuildAutoType(QualType Deduced, bool IsDecltypeAuto) {
+ // Note, IsDependent is always false here: we implicitly convert an 'auto'
+ // which has been deduced to a dependent type into an undeduced 'auto', so
+ // that we'll retry deduction after the transformation.
+ return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto);
}
/// \brief Build a new template specialization type.
@@ -1187,8 +1190,16 @@ public:
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
- ArrayRef<Token> AsmToks, SourceLocation EndLoc) {
- return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, EndLoc);
+ ArrayRef<Token> AsmToks,
+ StringRef AsmString,
+ unsigned NumOutputs, unsigned NumInputs,
+ ArrayRef<StringRef> Constraints,
+ ArrayRef<StringRef> Clobbers,
+ ArrayRef<Expr*> Exprs,
+ SourceLocation EndLoc) {
+ return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
+ NumOutputs, NumInputs,
+ Constraints, Clobbers, Exprs, EndLoc);
}
/// \brief Build a new Objective-C \@try statement.
@@ -1338,6 +1349,23 @@ public:
Expr *Cond, Expr *Inc,
Stmt *LoopVar,
SourceLocation RParenLoc) {
+ // If we've just learned that the range is actually an Objective-C
+ // collection, treat this as an Objective-C fast enumeration loop.
+ if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
+ if (RangeStmt->isSingleDecl()) {
+ if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
+ if (RangeVar->isInvalidDecl())
+ return StmtError();
+
+ Expr *RangeExpr = RangeVar->getInit();
+ if (!RangeExpr->isTypeDependent() &&
+ RangeExpr->getType()->isObjCObjectPointerType())
+ return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar, RangeExpr,
+ RParenLoc);
+ }
+ }
+ }
+
return getSema().BuildCXXForRangeStmt(ForLoc, ColonLoc, Range, BeginEnd,
Cond, Inc, LoopVar, RParenLoc,
Sema::BFRK_Rebuild);
@@ -1966,6 +1994,17 @@ public:
Param));
}
+ /// \brief Build a new C++11 default-initialization expression.
+ ///
+ /// By default, builds a new default field initialization expression, which
+ /// does not require any semantic analysis. Subclasses may override this
+ /// routine to provide different behavior.
+ ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
+ FieldDecl *Field) {
+ return getSema().Owned(CXXDefaultInitExpr::Create(getSema().Context, Loc,
+ Field));
+ }
+
/// \brief Build a new C++ zero-initialization expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -1974,7 +2013,7 @@ public:
SourceLocation LParenLoc,
SourceLocation RParenLoc) {
return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc,
- MultiExprArg(), RParenLoc);
+ None, RParenLoc);
}
/// \brief Build a new C++ "new" expression.
@@ -2609,13 +2648,13 @@ ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
// Revert value-initialization back to empty parens.
if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
SourceRange Parens = VIE->getSourceRange();
- return getDerived().RebuildParenListExpr(Parens.getBegin(), MultiExprArg(),
+ return getDerived().RebuildParenListExpr(Parens.getBegin(), None,
Parens.getEnd());
}
// FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
if (isa<ImplicitValueInitExpr>(Init))
- return getDerived().RebuildParenListExpr(SourceLocation(), MultiExprArg(),
+ return getDerived().RebuildParenListExpr(SourceLocation(), None,
SourceLocation());
// Revert initialization by constructor back to a parenthesized or braced list
@@ -3382,7 +3421,7 @@ TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
Qs.removeObjCLifetime();
Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(),
Qs);
- Result = SemaRef.Context.getAutoType(Deduced);
+ Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto());
TLB.TypeWasModifiedSafely(Result);
} else {
// Otherwise, complain about the addition of a qualifier to an
@@ -4475,8 +4514,9 @@ QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
}
QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced) {
- Result = getDerived().RebuildAutoType(NewDeduced);
+ if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
+ T->isDependentType()) {
+ Result = getDerived().RebuildAutoType(NewDeduced, T->isDecltypeAuto());
if (Result.isNull())
return QualType();
}
@@ -5617,8 +5657,30 @@ TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
ArrayRef<Token> AsmToks =
llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks());
+ bool HadError = false, HadChange = false;
+
+ ArrayRef<Expr*> SrcExprs = S->getAllExprs();
+ SmallVector<Expr*, 8> TransformedExprs;
+ TransformedExprs.reserve(SrcExprs.size());
+ for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
+ ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
+ if (!Result.isUsable()) {
+ HadError = true;
+ } else {
+ HadChange |= (Result.get() != SrcExprs[i]);
+ TransformedExprs.push_back(Result.take());
+ }
+ }
+
+ if (HadError) return StmtError();
+ if (!HadChange && !getDerived().AlwaysRebuild())
+ return Owned(S);
+
return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
- AsmToks, S->getEndLoc());
+ AsmToks, S->getAsmString(),
+ S->getNumOutputs(), S->getNumInputs(),
+ S->getAllConstraints(), S->getClobbers(),
+ TransformedExprs, S->getEndLoc());
}
template<typename Derived>
@@ -5919,12 +5981,15 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
BeginEnd.get() != S->getBeginEndStmt() ||
Cond.get() != S->getCond() ||
Inc.get() != S->getInc() ||
- LoopVar.get() != S->getLoopVarStmt())
+ LoopVar.get() != S->getLoopVarStmt()) {
NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
S->getColonLoc(), Range.get(),
BeginEnd.get(), Cond.get(),
Inc.get(), LoopVar.get(),
S->getRParenLoc());
+ if (NewStmt.isInvalid())
+ return StmtError();
+ }
StmtResult Body = getDerived().TransformStmt(S->getBody());
if (Body.isInvalid())
@@ -5932,12 +5997,15 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
// Body has changed but we didn't rebuild the for-range statement. Rebuild
// it now so we have a new statement to attach the body to.
- if (Body.get() != S->getBody() && NewStmt.get() == S)
+ if (Body.get() != S->getBody() && NewStmt.get() == S) {
NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
S->getColonLoc(), Range.get(),
BeginEnd.get(), Cond.get(),
Inc.get(), LoopVar.get(),
S->getRParenLoc());
+ if (NewStmt.isInvalid())
+ return StmtError();
+ }
if (NewStmt.get() == S)
return SemaRef.Owned(S);
@@ -6015,6 +6083,32 @@ TreeTransform<Derived>::TransformMSDependentExistsStmt(
}
template<typename Derived>
+ExprResult
+TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
+ NestedNameSpecifierLoc QualifierLoc;
+ if (E->getQualifierLoc()) {
+ QualifierLoc
+ = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
+ if (!QualifierLoc)
+ return ExprError();
+ }
+
+ MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
+ getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
+ if (!PD)
+ return ExprError();
+
+ ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
+ if (Base.isInvalid())
+ return ExprError();
+
+ return new (SemaRef.getASTContext())
+ MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
+ SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
+ QualifierLoc, E->getMemberLoc());
+}
+
+template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
StmtResult TryBlock; // = getDerived().TransformCompoundStmt(S->getTryBlock());
@@ -6159,6 +6253,8 @@ TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
+ if (FunctionDecl *FD = E->getDirectCallee())
+ SemaRef.MarkFunctionReferenced(E->getLocStart(), FD);
return SemaRef.MaybeBindToTemporary(E);
}
@@ -7220,6 +7316,21 @@ TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
template<typename Derived>
ExprResult
+TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
+ FieldDecl *Field
+ = cast_or_null<FieldDecl>(getDerived().TransformDecl(E->getLocStart(),
+ E->getField()));
+ if (!Field)
+ return ExprError();
+
+ if (!getDerived().AlwaysRebuild() && Field == E->getField())
+ return SemaRef.Owned(E);
+
+ return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
+}
+
+template<typename Derived>
+ExprResult
TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
CXXScalarValueInitExpr *E) {
TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
@@ -8592,16 +8703,11 @@ TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
template<typename Derived>
ExprResult TreeTransform<Derived>::
TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
- ExprResult result = getDerived().TransformExpr(E->getSubExpr());
- if (result.isInvalid()) return ExprError();
- Expr *subExpr = result.take();
-
- if (!getDerived().AlwaysRebuild() &&
- subExpr == E->getSubExpr())
- return SemaRef.Owned(E);
-
- return SemaRef.Owned(new(SemaRef.Context)
- ObjCIndirectCopyRestoreExpr(subExpr, E->getType(), E->shouldCopy()));
+ // This is a kind of implicit conversion, and it needs to get dropped
+ // and recomputed for the same general reasons that ImplicitCastExprs
+ // do, as well a more specific one: this expression is only valid when
+ // it appears *immediately* as an argument expression.
+ return getDerived().TransformExpr(E->getSubExpr());
}
template<typename Derived>
@@ -9340,6 +9446,23 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
/*TemplateArgs*/ 0);
}
+template<typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
+ SourceLocation Loc = S->getLocStart();
+ unsigned NumParams = S->getCapturedDecl()->getNumParams();
+ getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/0,
+ S->getCapturedRegionKind(), NumParams);
+ StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
+
+ if (Body.isInvalid()) {
+ getSema().ActOnCapturedRegionError();
+ return StmtError();
+ }
+
+ return getSema().ActOnCapturedRegionEnd(Body.take());
+}
+
} // end namespace clang
#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
OpenPOWER on IntegriCloud