summaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaDecl.cpp33
-rw-r--r--lib/Sema/SemaExpr.cpp29
-rw-r--r--lib/Sema/SemaExprCXX.cpp47
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--lib/Sema/SemaStmt.cpp24
-rw-r--r--lib/Sema/TreeTransform.h13
6 files changed, 74 insertions, 74 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index d14b10559d..5d8839a65b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4718,16 +4718,6 @@ 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)
@@ -4885,11 +4875,22 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewVD->setLexicalDeclContext(CurContext);
if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) {
- if (NewVD->hasLocalStorage())
- Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
- diag::err_thread_non_global)
- << DeclSpec::getSpecifierName(TSCS);
- else if (!Context.getTargetInfo().isTLSSupported())
+ if (NewVD->hasLocalStorage()) {
+ // 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 &&
+ TSCS == DeclSpec::TSCS_thread_local &&
+ DC->isFunctionOrMethod())
+ NewVD->setTSCSpec(TSCS);
+ else
+ Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
+ diag::err_thread_non_global)
+ << DeclSpec::getSpecifierName(TSCS);
+ } else if (!Context.getTargetInfo().isTLSSupported())
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
diag::err_thread_unsupported);
else
@@ -5237,7 +5238,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
if (NewVD->isFileVarDecl())
Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
<< SizeRange;
- else if (NewVD->getStorageClass() == SC_Static)
+ else if (NewVD->isStaticLocal())
Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
<< SizeRange;
else
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ef7e0f2e33..b6b6444738 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1230,25 +1230,23 @@ Sema::ActOnGenericSelectionExpr(SourceLocation KeyLoc,
SourceLocation DefaultLoc,
SourceLocation RParenLoc,
Expr *ControllingExpr,
- MultiTypeArg ArgTypes,
- MultiExprArg ArgExprs) {
+ ArrayRef<ParsedType> ArgTypes,
+ ArrayRef<Expr *> ArgExprs) {
unsigned NumAssocs = ArgTypes.size();
assert(NumAssocs == ArgExprs.size());
- ParsedType *ParsedTypes = ArgTypes.data();
- Expr **Exprs = ArgExprs.data();
-
TypeSourceInfo **Types = new TypeSourceInfo*[NumAssocs];
for (unsigned i = 0; i < NumAssocs; ++i) {
- if (ParsedTypes[i])
- (void) GetTypeFromParser(ParsedTypes[i], &Types[i]);
+ if (ArgTypes[i])
+ (void) GetTypeFromParser(ArgTypes[i], &Types[i]);
else
Types[i] = 0;
}
ExprResult ER = CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
- ControllingExpr, Types, Exprs,
- NumAssocs);
+ ControllingExpr,
+ llvm::makeArrayRef(Types, NumAssocs),
+ ArgExprs);
delete [] Types;
return ER;
}
@@ -1258,9 +1256,10 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
SourceLocation DefaultLoc,
SourceLocation RParenLoc,
Expr *ControllingExpr,
- TypeSourceInfo **Types,
- Expr **Exprs,
- unsigned NumAssocs) {
+ ArrayRef<TypeSourceInfo *> Types,
+ ArrayRef<Expr *> Exprs) {
+ unsigned NumAssocs = Types.size();
+ assert(NumAssocs == Exprs.size());
if (ControllingExpr->getType()->isPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(ControllingExpr);
if (result.isInvalid()) return ExprError();
@@ -1328,8 +1327,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
if (IsResultDependent)
return Owned(new (Context) GenericSelectionExpr(
Context, KeyLoc, ControllingExpr,
- llvm::makeArrayRef(Types, NumAssocs),
- llvm::makeArrayRef(Exprs, NumAssocs),
+ Types, Exprs,
DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack));
SmallVector<unsigned, 1> CompatIndices;
@@ -1384,8 +1382,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc,
return Owned(new (Context) GenericSelectionExpr(
Context, KeyLoc, ControllingExpr,
- llvm::makeArrayRef(Types, NumAssocs),
- llvm::makeArrayRef(Exprs, NumAssocs),
+ Types, Exprs,
DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack,
ResultIndex));
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index be5c00b8b9..cde2e4940b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -1306,16 +1306,13 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
FunctionDecl *OperatorNew = 0;
FunctionDecl *OperatorDelete = 0;
- Expr **PlaceArgs = PlacementArgs.data();
- unsigned NumPlaceArgs = PlacementArgs.size();
if (!AllocType->isDependentType() &&
- !Expr::hasAnyTypeDependentArguments(
- llvm::makeArrayRef(PlaceArgs, NumPlaceArgs)) &&
+ !Expr::hasAnyTypeDependentArguments(PlacementArgs) &&
FindAllocationFunctions(StartLoc,
SourceRange(PlacementLParen, PlacementRParen),
- UseGlobal, AllocType, ArraySize, PlaceArgs,
- NumPlaceArgs, OperatorNew, OperatorDelete))
+ UseGlobal, AllocType, ArraySize, PlacementArgs,
+ OperatorNew, OperatorDelete))
return ExprError();
// If this is an array allocation, compute whether the usual array
@@ -1333,25 +1330,21 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
VariadicCallType CallType =
Proto->isVariadic() ? VariadicFunction : VariadicDoesNotApply;
- if (GatherArgumentsForCall(PlacementLParen, OperatorNew,
- Proto, 1,
- llvm::makeArrayRef(PlaceArgs, NumPlaceArgs),
- AllPlaceArgs, CallType))
+ if (GatherArgumentsForCall(PlacementLParen, OperatorNew, Proto, 1,
+ PlacementArgs, AllPlaceArgs, CallType))
return ExprError();
- NumPlaceArgs = AllPlaceArgs.size();
- if (NumPlaceArgs > 0)
- PlaceArgs = &AllPlaceArgs[0];
+ if (!AllPlaceArgs.empty())
+ PlacementArgs = AllPlaceArgs;
- DiagnoseSentinelCalls(OperatorNew, PlacementLParen,
- llvm::makeArrayRef(PlaceArgs, NumPlaceArgs));
+ DiagnoseSentinelCalls(OperatorNew, PlacementLParen, PlacementArgs);
// FIXME: Missing call to CheckFunctionCall or equivalent
}
// Warn if the type is over-aligned and is being allocated by global operator
// new.
- if (NumPlaceArgs == 0 && OperatorNew &&
+ if (PlacementArgs.empty() && OperatorNew &&
(OperatorNew->isImplicit() ||
getSourceManager().isInSystemHeader(OperatorNew->getLocStart()))) {
if (unsigned Align = Context.getPreferredTypeAlign(AllocType.getTypePtr())){
@@ -1459,8 +1452,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
OperatorDelete,
UsualArrayDeleteWantsSize,
- llvm::makeArrayRef(PlaceArgs, NumPlaceArgs),
- TypeIdParens,
+ PlacementArgs, TypeIdParens,
ArraySize, initStyle, Initializer,
ResultType, AllocTypeInfo,
Range, DirectInitRange));
@@ -1521,8 +1513,7 @@ static bool isNonPlacementDeallocationFunction(FunctionDecl *FD) {
/// that are appropriate for the allocation.
bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
bool UseGlobal, QualType AllocType,
- bool IsArray, Expr **PlaceArgs,
- unsigned NumPlaceArgs,
+ bool IsArray, MultiExprArg PlaceArgs,
FunctionDecl *&OperatorNew,
FunctionDecl *&OperatorDelete) {
// --- Choosing an allocation function ---
@@ -1534,7 +1525,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// 3) The first argument is always size_t. Append the arguments from the
// placement form.
- SmallVector<Expr*, 8> AllocArgs(1 + NumPlaceArgs);
+ SmallVector<Expr*, 8> AllocArgs(1 + PlaceArgs.size());
// We don't care about the actual value of this argument.
// FIXME: Should the Sema create the expression and embed it in the syntax
// tree? Or should the consumer just recalculate the value?
@@ -1543,7 +1534,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
Context.getSizeType(),
SourceLocation());
AllocArgs[0] = &Size;
- std::copy(PlaceArgs, PlaceArgs + NumPlaceArgs, AllocArgs.begin() + 1);
+ std::copy(PlaceArgs.begin(), PlaceArgs.end(), AllocArgs.begin() + 1);
// C++ [expr.new]p8:
// If the allocated type is a non-array type, the allocation
@@ -1583,8 +1574,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// FindAllocationOverload can change the passed in arguments, so we need to
// copy them back.
- if (NumPlaceArgs > 0)
- std::copy(&AllocArgs[1], AllocArgs.end(), PlaceArgs);
+ if (!PlaceArgs.empty())
+ std::copy(AllocArgs.begin() + 1, AllocArgs.end(), PlaceArgs.data());
// C++ [expr.new]p19:
//
@@ -1618,7 +1609,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// we had explicit placement arguments. This matters for things like
// struct A { void *operator new(size_t, int = 0); ... };
// A *a = new A()
- bool isPlacementNew = (NumPlaceArgs > 0 || OperatorNew->param_size() != 1);
+ bool isPlacementNew = (!PlaceArgs.empty() || OperatorNew->param_size() != 1);
if (isPlacementNew) {
// C++ [expr.new]p20:
@@ -1693,11 +1684,11 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// as a placement deallocation function, would have been
// selected as a match for the allocation function, the program
// is ill-formed.
- if (NumPlaceArgs && getLangOpts().CPlusPlus11 &&
+ if (!PlaceArgs.empty() && getLangOpts().CPlusPlus11 &&
isNonPlacementDeallocationFunction(OperatorDelete)) {
Diag(StartLoc, diag::err_placement_new_non_placement_delete)
- << SourceRange(PlaceArgs[0]->getLocStart(),
- PlaceArgs[NumPlaceArgs - 1]->getLocEnd());
+ << SourceRange(PlaceArgs.front()->getLocStart(),
+ PlaceArgs.back()->getLocEnd());
Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
<< DeleteName;
} else {
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 3461f91ff3..dbe151c782 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1591,7 +1591,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
// Integral conversions (C++ 4.7).
SCS.Second = ICK_Integral_Conversion;
FromType = ToType.getUnqualifiedType();
- } else if (FromType->isAnyComplexType() && ToType->isComplexType()) {
+ } else if (FromType->isAnyComplexType() && ToType->isAnyComplexType()) {
// Complex conversions (C99 6.3.1.6)
SCS.Second = ICK_Complex_Conversion;
FromType = ToType.getUnqualifiedType();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index b5ff7a30a9..6d568c4d0b 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2362,22 +2362,37 @@ Sema::PerformMoveOrCopyInitialization(const InitializedEntity &Entity,
StmtResult
Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
// If this is the first return we've seen, infer the return type.
- // [expr.prim.lambda]p4 in C++11; block literals follow a superset of those
- // rules which allows multiple return statements.
+ // [expr.prim.lambda]p4 in C++11; block literals follow the same rules.
CapturingScopeInfo *CurCap = cast<CapturingScopeInfo>(getCurFunction());
QualType FnRetType = CurCap->ReturnType;
// For blocks/lambdas with implicit return types, we check each return
// statement individually, and deduce the common return type when the block
// or lambda is completed.
- if (CurCap->HasImplicitReturnType) {
+ if (AutoType *AT =
+ FnRetType.isNull() ? 0 : FnRetType->getContainedAutoType()) {
+ // In C++1y, the return type may involve 'auto'.
+ FunctionDecl *FD = cast<LambdaScopeInfo>(CurCap)->CallOperator;
+ if (CurContext->isDependentContext()) {
+ // C++1y [dcl.spec.auto]p12:
+ // Return type deduction [...] occurs when the definition is
+ // instantiated even if the function body contains a return
+ // statement with a non-type-dependent operand.
+ CurCap->ReturnType = FnRetType = Context.DependentTy;
+ } else if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
+ FD->setInvalidDecl();
+ return StmtError();
+ } else
+ CurCap->ReturnType = FnRetType = FD->getResultType();
+ } else if (CurCap->HasImplicitReturnType) {
+ // FIXME: Fold this into the 'auto' codepath above.
if (RetValExp && !isa<InitListExpr>(RetValExp)) {
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
RetValExp = Result.take();
- if (!RetValExp->isTypeDependent())
+ if (!CurContext->isDependentContext())
FnRetType = RetValExp->getType();
else
FnRetType = CurCap->ReturnType = Context.DependentTy;
@@ -2553,7 +2568,6 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
return StmtError();
- // FIXME: Unify this and C++1y auto function handling.
if (isa<CapturingScopeInfo>(getCurFunction()))
return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 89e23ef460..253135ff70 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1767,12 +1767,10 @@ public:
SourceLocation DefaultLoc,
SourceLocation RParenLoc,
Expr *ControllingExpr,
- TypeSourceInfo **Types,
- Expr **Exprs,
- unsigned NumAssocs) {
+ ArrayRef<TypeSourceInfo *> Types,
+ ArrayRef<Expr *> Exprs) {
return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
- ControllingExpr, Types, Exprs,
- NumAssocs);
+ ControllingExpr, Types, Exprs);
}
/// \brief Build a new overloaded operator call expression.
@@ -6289,9 +6287,8 @@ TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
E->getDefaultLoc(),
E->getRParenLoc(),
ControllingExpr.release(),
- AssocTypes.data(),
- AssocExprs.data(),
- E->getNumAssocs());
+ AssocTypes,
+ AssocExprs);
}
template<typename Derived>