Update Clang for rebase to r212749.
This also fixes a small issue with arm_neon.h not being generated always.
Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android
Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 7f2748e..213d6fb 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -477,14 +477,13 @@
bool HasNoReturn) const {
if (funMode == Function) {
return (ReturnsVoid ||
- D.getDiagnosticLevel(diag::warn_maybe_falloff_nonvoid_function,
- FuncLoc) == DiagnosticsEngine::Ignored)
- && (!HasNoReturn ||
- D.getDiagnosticLevel(diag::warn_noreturn_function_has_return_expr,
- FuncLoc) == DiagnosticsEngine::Ignored)
- && (!ReturnsVoid ||
- D.getDiagnosticLevel(diag::warn_suggest_noreturn_block, FuncLoc)
- == DiagnosticsEngine::Ignored);
+ D.isIgnored(diag::warn_maybe_falloff_nonvoid_function,
+ FuncLoc)) &&
+ (!HasNoReturn ||
+ D.isIgnored(diag::warn_noreturn_function_has_return_expr,
+ FuncLoc)) &&
+ (!ReturnsVoid ||
+ D.isIgnored(diag::warn_suggest_noreturn_block, FuncLoc));
}
// For blocks / lambdas.
@@ -612,8 +611,9 @@
QualType VariableTy = VD->getType().getCanonicalType();
if (VariableTy->isBlockPointerType() &&
!VD->hasAttr<BlocksAttr>()) {
- S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization) << VD->getDeclName()
- << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
+ S.Diag(VD->getLocation(), diag::note_block_var_fixit_add_initialization)
+ << VD->getDeclName()
+ << FixItHint::CreateInsertion(VD->getLocation(), "__block ");
return true;
}
@@ -1026,6 +1026,9 @@
// methods separately.
bool TraverseDecl(Decl *D) { return true; }
+ // We analyze lambda bodies separately. Skip them here.
+ bool TraverseLambdaBody(LambdaExpr *LE) { return true; }
+
private:
static const AttributedStmt *asFallThroughAttr(const Stmt *S) {
@@ -1713,8 +1716,7 @@
}
static unsigned isEnabled(DiagnosticsEngine &D, unsigned diag) {
- return (unsigned) D.getDiagnosticLevel(diag, SourceLocation()) !=
- DiagnosticsEngine::Ignored;
+ return (unsigned)!D.isIgnored(diag, SourceLocation());
}
clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
@@ -1819,8 +1821,8 @@
// Install the logical handler for -Wtautological-overlap-compare
std::unique_ptr<LogicalErrorHandler> LEH;
- if (Diags.getDiagnosticLevel(diag::warn_tautological_overlap_comparison,
- D->getLocStart())) {
+ if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
+ D->getLocStart())) {
LEH.reset(new LogicalErrorHandler(S));
AC.getCFGBuildOptions().Observer = LEH.get();
}
@@ -1895,8 +1897,7 @@
SourceLocation FL = AC.getDecl()->getLocation();
SourceLocation FEL = AC.getDecl()->getLocEnd();
thread_safety::ThreadSafetyReporter Reporter(S, FL, FEL);
- if (Diags.getDiagnosticLevel(diag::warn_thread_safety_beta,D->getLocStart())
- != DiagnosticsEngine::Ignored)
+ if (!Diags.isIgnored(diag::warn_thread_safety_beta, D->getLocStart()))
Reporter.setIssueBetaWarnings(true);
thread_safety::runThreadSafetyAnalysis(AC, Reporter);
@@ -1910,12 +1911,9 @@
Analyzer.run(AC);
}
- if (Diags.getDiagnosticLevel(diag::warn_uninit_var, D->getLocStart())
- != DiagnosticsEngine::Ignored ||
- Diags.getDiagnosticLevel(diag::warn_sometimes_uninit_var,D->getLocStart())
- != DiagnosticsEngine::Ignored ||
- Diags.getDiagnosticLevel(diag::warn_maybe_uninit_var, D->getLocStart())
- != DiagnosticsEngine::Ignored) {
+ if (!Diags.isIgnored(diag::warn_uninit_var, D->getLocStart()) ||
+ !Diags.isIgnored(diag::warn_sometimes_uninit_var, D->getLocStart()) ||
+ !Diags.isIgnored(diag::warn_maybe_uninit_var, D->getLocStart())) {
if (CFG *cfg = AC.getCFG()) {
UninitValsDiagReporter reporter(S);
UninitVariablesAnalysisStats stats;
@@ -1938,25 +1936,21 @@
}
bool FallThroughDiagFull =
- Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough,
- D->getLocStart()) != DiagnosticsEngine::Ignored;
- bool FallThroughDiagPerFunction =
- Diags.getDiagnosticLevel(diag::warn_unannotated_fallthrough_per_function,
- D->getLocStart()) != DiagnosticsEngine::Ignored;
+ !Diags.isIgnored(diag::warn_unannotated_fallthrough, D->getLocStart());
+ bool FallThroughDiagPerFunction = !Diags.isIgnored(
+ diag::warn_unannotated_fallthrough_per_function, D->getLocStart());
if (FallThroughDiagFull || FallThroughDiagPerFunction) {
DiagnoseSwitchLabelsFallthrough(S, AC, !FallThroughDiagFull);
}
if (S.getLangOpts().ObjCARCWeak &&
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- D->getLocStart()) != DiagnosticsEngine::Ignored)
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, D->getLocStart()))
diagnoseRepeatedUseOfWeak(S, fscope, D, AC.getParentMap());
// Check for infinite self-recursion in functions
- if (Diags.getDiagnosticLevel(diag::warn_infinite_recursive_function,
- D->getLocStart())
- != DiagnosticsEngine::Ignored) {
+ if (!Diags.isIgnored(diag::warn_infinite_recursive_function,
+ D->getLocStart())) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
checkRecursiveFunction(S, FD, Body, AC);
}
@@ -1964,7 +1958,7 @@
// If none of the previous checks caused a CFG build, trigger one here
// for -Wtautological-overlap-compare
- if (Diags.getDiagnosticLevel(diag::warn_tautological_overlap_comparison,
+ if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
D->getLocStart())) {
AC.getCFG();
}
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 69415ce..d7372b7 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -178,7 +178,7 @@
I.Kind = Function;
I.Loc = LocalRangeBegin;
I.EndLoc = LocalRangeEnd;
- I.Fun.AttrList = 0;
+ I.Fun.AttrList = nullptr;
I.Fun.hasPrototype = hasProto;
I.Fun.isVariadic = EllipsisLoc.isValid();
I.Fun.isAmbiguous = isAmbiguous;
@@ -188,7 +188,7 @@
I.Fun.DeleteParams = false;
I.Fun.TypeQuals = TypeQuals;
I.Fun.NumParams = NumParams;
- I.Fun.Params = 0;
+ I.Fun.Params = nullptr;
I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef;
I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding();
I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding();
@@ -197,8 +197,8 @@
I.Fun.ExceptionSpecType = ESpecType;
I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding();
I.Fun.NumExceptions = 0;
- I.Fun.Exceptions = 0;
- I.Fun.NoexceptExpr = 0;
+ I.Fun.Exceptions = nullptr;
+ I.Fun.NoexceptExpr = nullptr;
I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() ||
TrailingReturnType.isInvalid();
I.Fun.TrailingReturnType = TrailingReturnType.get();
@@ -657,7 +657,7 @@
DeclRep = Rep;
TSTLoc = TagKwLoc;
TSTNameLoc = TagNameLoc;
- TypeSpecOwned = Owned && Rep != 0;
+ TypeSpecOwned = Owned && Rep != nullptr;
return false;
}
@@ -1169,7 +1169,7 @@
bool DeclSpec::isMissingDeclaratorOk() {
TST tst = getTypeSpecType();
- return isDeclRep(tst) && getRepAsDecl() != 0 &&
+ return isDeclRep(tst) && getRepAsDecl() != nullptr &&
StorageClassSpec != DeclSpec::SCS_typedef;
}
diff --git a/lib/Sema/DelayedDiagnostic.cpp b/lib/Sema/DelayedDiagnostic.cpp
index 13a428c..664a6b1 100644
--- a/lib/Sema/DelayedDiagnostic.cpp
+++ b/lib/Sema/DelayedDiagnostic.cpp
@@ -25,7 +25,8 @@
const NamedDecl *D,
const ObjCInterfaceDecl *UnknownObjCClass,
const ObjCPropertyDecl *ObjCProperty,
- StringRef Msg) {
+ StringRef Msg,
+ bool ObjCPropertyAccess) {
DelayedDiagnostic DD;
switch (AD) {
case Sema::AD_Deprecation:
@@ -48,6 +49,7 @@
DD.DeprecationData.Message = MessageData;
DD.DeprecationData.MessageLen = Msg.size();
+ DD.DeprecationData.ObjCPropertyAccess = ObjCPropertyAccess;
return DD;
}
diff --git a/lib/Sema/Scope.cpp b/lib/Sema/Scope.cpp
index 278b087..6c79778 100644
--- a/lib/Sema/Scope.cpp
+++ b/lib/Sema/Scope.cpp
@@ -39,6 +39,10 @@
BlockParent = parent->BlockParent;
TemplateParamParent = parent->TemplateParamParent;
MSLocalManglingParent = parent->MSLocalManglingParent;
+ if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
+ FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
+ 0)
+ Flags |= parent->getFlags() & OpenMPSimdDirectiveScope;
} else {
Depth = 0;
PrototypeDepth = 0;
@@ -63,6 +67,7 @@
// If this is a prototype scope, record that.
if (flags & FunctionPrototypeScope) PrototypeDepth++;
+
if (flags & DeclScope) {
if (flags & FunctionPrototypeScope)
; // Prototype scopes are uninteresting.
@@ -70,6 +75,8 @@
; // Nested class scopes aren't ambiguous.
else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
; // Classes inside of namespaces aren't ambiguous.
+ else if ((flags & EnumScope))
+ ; // Don't increment for enum scopes.
else
incrementMSLocalManglingNumber();
}
@@ -175,9 +182,18 @@
} else if (Flags & FnTryCatchScope) {
OS << "FnTryCatchScope";
Flags &= ~FnTryCatchScope;
+ } else if (Flags & SEHTryScope) {
+ OS << "SEHTryScope";
+ Flags &= ~SEHTryScope;
} else if (Flags & OpenMPDirectiveScope) {
OS << "OpenMPDirectiveScope";
Flags &= ~OpenMPDirectiveScope;
+ } else if (Flags & OpenMPLoopDirectiveScope) {
+ OS << "OpenMPLoopDirectiveScope";
+ Flags &= ~OpenMPLoopDirectiveScope;
+ } else if (Flags & OpenMPSimdDirectiveScope) {
+ OS << "OpenMPSimdDirectiveScope";
+ Flags &= ~OpenMPSimdDirectiveScope;
}
if (Flags)
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index d9b2ca3..4d079e7 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -158,8 +158,14 @@
// Has this weak object been seen before?
FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
- if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E))
- Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+ if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
+ if (isa<OpaqueValueExpr>(RefExpr->getBase()))
+ Uses = WeakObjectUses.find(WeakObjectProfileTy(RefExpr));
+ else {
+ markSafeWeakUse(RefExpr->getBase());
+ return;
+ }
+ }
else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index e8b487e..478c34f 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -313,7 +313,8 @@
if (VK == VK_RValue && !E->isRValue()) {
switch (Kind) {
default:
- assert(0 && "can't implicitly cast lvalue to rvalue with this cast kind");
+ llvm_unreachable("can't implicitly cast lvalue to rvalue with this cast "
+ "kind");
case CK_LValueToRValue:
case CK_ArrayToPointerDecay:
case CK_FunctionToPointerDecay:
@@ -328,7 +329,7 @@
QualType TypeTy = Context.getCanonicalType(Ty);
if (ExprTy == TypeTy)
- return Owned(E);
+ return E;
// If this is a derived-to-base cast to a through a virtual base, we
// need a vtable.
@@ -346,11 +347,11 @@
if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
ImpCast->setType(Ty);
ImpCast->setValueKind(VK);
- return Owned(E);
+ return E;
}
}
- return Owned(ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK));
+ return ImplicitCastExpr::Create(Context, Ty, Kind, E, BasePath, VK);
}
/// ScalarTypeToBooleanCastKind - Returns the cast kind corresponding
@@ -681,9 +682,7 @@
}
if (LangOpts.CPlusPlus11 &&
- Diags.getDiagnosticLevel(diag::warn_delegating_ctor_cycle,
- SourceLocation())
- != DiagnosticsEngine::Ignored)
+ !Diags.isIgnored(diag::warn_delegating_ctor_cycle, SourceLocation()))
CheckDelegatingCtorCycles();
if (TUKind == TU_Module) {
@@ -823,9 +822,7 @@
checkUndefinedButUsed(*this);
}
- if (Diags.getDiagnosticLevel(diag::warn_unused_private_field,
- SourceLocation())
- != DiagnosticsEngine::Ignored) {
+ if (!Diags.isIgnored(diag::warn_unused_private_field, SourceLocation())) {
RecordCompleteMap RecordsComplete;
RecordCompleteMap MNCComplete;
for (NamedDeclSetType::iterator I = UnusedPrivateFields.begin(),
@@ -1408,7 +1405,7 @@
// FIXME: Try this before emitting the fixit, and suppress diagnostics
// while doing so.
- E = ActOnCallExpr(nullptr, E.take(), Range.getEnd(), None,
+ E = ActOnCallExpr(nullptr, E.get(), Range.getEnd(), None,
Range.getEnd().getLocWithOffset(1));
return true;
}
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index dc574f1..ffdb0aa 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1252,7 +1252,8 @@
<< (base->getAccessSpecifierAsWritten() == AS_none);
if (entity.isMemberAccess())
- S.Diag(entity.getTargetDecl()->getLocation(), diag::note_field_decl);
+ S.Diag(entity.getTargetDecl()->getLocation(),
+ diag::note_member_declared_at);
}
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 8c42335..a70aca2 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -532,9 +532,7 @@
Diag(R.getNameLoc(), diag::err_expected_class_or_namespace)
<< &Identifier << getLangOpts().CPlusPlus;
if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
- Diag(ND->getLocation(),
- diag::note_expected_class_or_namespace_declared_here)
- << &Identifier;
+ Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
return true;
}
}
@@ -718,9 +716,7 @@
Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
<< &Identifier << getLangOpts().CPlusPlus;
if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
- Diag(ND->getLocation(),
- diag::note_expected_class_or_namespace_declared_here)
- << &Identifier;
+ Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
}
} else if (SS.isSet())
Diag(IdentifierLoc, diag::err_no_member) << &Identifier << LookupCtx
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index df4e823..ae5436c 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -93,7 +93,7 @@
CK_Dependent, castExpr, nullptr,
castExpr->getValueKind());
}
- return Self.Owned(castExpr);
+ return castExpr;
}
// Internal convenience methods.
@@ -134,7 +134,7 @@
if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))
return;
- SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+ SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
if (SrcExpr.isInvalid())
return;
PlaceholderKind = (BuiltinType::Kind) 0;
@@ -239,7 +239,7 @@
Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
TypeSourceInfo *DestTInfo, Expr *E,
SourceRange AngleBrackets, SourceRange Parens) {
- ExprResult Ex = Owned(E);
+ ExprResult Ex = E;
QualType DestType = DestTInfo->getType();
// If the type is dependent, we won't do the semantic analysis now.
@@ -262,7 +262,7 @@
return ExprError();
}
return Op.complete(CXXConstCastExpr::Create(Context, Op.ResultType,
- Op.ValueKind, Op.SrcExpr.take(), DestTInfo,
+ Op.ValueKind, Op.SrcExpr.get(), DestTInfo,
OpLoc, Parens.getEnd(),
AngleBrackets));
@@ -273,7 +273,7 @@
return ExprError();
}
return Op.complete(CXXDynamicCastExpr::Create(Context, Op.ResultType,
- Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+ Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
&Op.BasePath, DestTInfo,
OpLoc, Parens.getEnd(),
AngleBrackets));
@@ -285,7 +285,7 @@
return ExprError();
}
return Op.complete(CXXReinterpretCastExpr::Create(Context, Op.ResultType,
- Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+ Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
nullptr, DestTInfo, OpLoc,
Parens.getEnd(),
AngleBrackets));
@@ -298,7 +298,7 @@
}
return Op.complete(CXXStaticCastExpr::Create(Context, Op.ResultType,
- Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+ Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
&Op.BasePath, DestTInfo,
OpLoc, Parens.getEnd(),
AngleBrackets));
@@ -535,9 +535,9 @@
/// checked downcasts in class hierarchies.
void CastOperation::CheckDynamicCast() {
if (ValueKind == VK_RValue)
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
else if (isPlaceholder())
- SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+ SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
@@ -600,6 +600,11 @@
}
SrcPointee = SrcType;
} else {
+ // If we're dynamic_casting from a prvalue to an rvalue reference, we need
+ // to materialize the prvalue before we bind the reference to it.
+ if (SrcExpr.get()->isRValue())
+ SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
+ SrcType, SrcExpr.get(), /*IsLValueReference*/false);
SrcPointee = SrcType;
}
@@ -648,7 +653,7 @@
SrcExpr = ExprError();
return;
}
-
+
Kind = CK_DerivedToBase;
// If we are casting to or through a virtual base class, we need a
@@ -690,9 +695,9 @@
/// legacy_function(const_cast\<char*\>(str));
void CastOperation::CheckConstCast() {
if (ValueKind == VK_RValue)
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
else if (isPlaceholder())
- SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.take());
+ SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
@@ -805,7 +810,7 @@
/// char *bytes = reinterpret_cast\<char*\>(int_ptr);
void CastOperation::CheckReinterpretCast() {
if (ValueKind == VK_RValue && !isPlaceholder(BuiltinType::Overload))
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
else
checkNonOverloadPlaceholders();
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
@@ -864,13 +869,13 @@
return;
}
- SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+ SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
return;
}
if (ValueKind == VK_RValue && !DestType->isRecordType() &&
!isPlaceholder(BuiltinType::Overload)) {
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
if (SrcExpr.isInvalid()) // if conversion failed, don't report another error
return;
}
@@ -1156,6 +1161,9 @@
QualType DestPointee = DestReference->getPointeeType();
+ // FIXME: If the source is a prvalue, we should issue a warning (because the
+ // cast always has undefined behavior), and for AST consistency, we should
+ // materialize a temporary.
return TryStaticDowncast(Self,
Self.Context.getCanonicalType(SrcExpr->getType()),
Self.Context.getCanonicalType(DestPointee), CStyle,
@@ -1589,7 +1597,7 @@
// This is a const_cast from a class prvalue to an rvalue reference type.
// Materialize a temporary to store the result of the conversion.
SrcExpr = new (Self.Context) MaterializeTemporaryExpr(
- SrcType, SrcExpr.take(), /*IsLValueReference*/ false);
+ SrcType, SrcExpr.get(), /*IsLValueReference*/ false);
return TC_Success;
}
@@ -1606,10 +1614,8 @@
diag::warn_pointer_indirection_from_incompatible_type :
diag::warn_undefined_reinterpret_cast;
- if (Diags.getDiagnosticLevel(DiagID, Range.getBegin()) ==
- DiagnosticsEngine::Ignored) {
+ if (Diags.isIgnored(DiagID, Range.getBegin()))
return;
- }
QualType SrcTy, DestTy;
if (IsDereference) {
@@ -2024,7 +2030,7 @@
return;
}
- SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+ SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
return;
}
@@ -2037,7 +2043,7 @@
if (ValueKind == VK_RValue && !DestType->isRecordType() &&
!isPlaceholder(BuiltinType::Overload)) {
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
if (SrcExpr.isInvalid())
return;
}
@@ -2127,9 +2133,8 @@
/// pointer; etc. Cast to 'void' is an exception.
static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr,
QualType DestType) {
- if (Self.Diags.getDiagnosticLevel(diag::warn_bad_function_cast,
- SrcExpr.get()->getExprLoc())
- == DiagnosticsEngine::Ignored)
+ if (Self.Diags.isIgnored(diag::warn_bad_function_cast,
+ SrcExpr.get()->getExprLoc()))
return;
if (!isa<CallExpr>(SrcExpr.get()))
@@ -2175,7 +2180,7 @@
// type needs to be scalar.
if (DestType->isVoidType()) {
// We don't necessarily do lvalue-to-rvalue conversions on this.
- SrcExpr = Self.IgnoredValueConversions(SrcExpr.take());
+ SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());
if (SrcExpr.isInvalid())
return;
@@ -2184,7 +2189,7 @@
return;
}
- SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.take());
+ SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());
if (SrcExpr.isInvalid())
return;
QualType SrcType = SrcExpr.get()->getType();
@@ -2265,7 +2270,7 @@
}
if (DestType->isExtVectorType()) {
- SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.take(), Kind);
+ SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);
return;
}
@@ -2387,7 +2392,7 @@
return ExprError();
return Op.complete(CStyleCastExpr::Create(Context, Op.ResultType,
- Op.ValueKind, Op.Kind, Op.SrcExpr.take(),
+ Op.ValueKind, Op.Kind, Op.SrcExpr.get(),
&Op.BasePath, CastTypeInfo, LPLoc, RPLoc));
}
@@ -2409,5 +2414,5 @@
return Op.complete(CXXFunctionalCastExpr::Create(Context, Op.ResultType,
Op.ValueKind, CastTypeInfo, Op.Kind,
- Op.SrcExpr.take(), &Op.BasePath, LPLoc, RPLoc));
+ Op.SrcExpr.get(), &Op.BasePath, LPLoc, RPLoc));
}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 83fb1d7..f7d5623 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -101,19 +101,19 @@
if (checkArgCount(S, TheCall, 1))
return true;
- ExprResult Arg(S.Owned(TheCall->getArg(0)));
+ ExprResult Arg(TheCall->getArg(0));
QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getLocStart());
if (ResultType.isNull())
return true;
- TheCall->setArg(0, Arg.take());
+ TheCall->setArg(0, Arg.get());
TheCall->setType(ResultType);
return false;
}
ExprResult
Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
- ExprResult TheCallResult(Owned(TheCall));
+ ExprResult TheCallResult(TheCall);
// Find out if any arguments are required to be integer constant expressions.
unsigned ICEArguments = 0;
@@ -296,8 +296,22 @@
if (SemaBuiltinAddressof(*this, TheCall))
return ExprError();
break;
+ case Builtin::BI__builtin_operator_new:
+ case Builtin::BI__builtin_operator_delete:
+ if (!getLangOpts().CPlusPlus) {
+ Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language)
+ << (BuiltinID == Builtin::BI__builtin_operator_new
+ ? "__builtin_operator_new"
+ : "__builtin_operator_delete")
+ << "C++";
+ return ExprError();
+ }
+ // CodeGen assumes it can find the global new and delete to call,
+ // so ensure that they are declared.
+ DeclareGlobalNewDelete();
+ break;
}
-
+
// Since the target specific builtins for each arch overlap, only check those
// of the arch we are compiling for.
if (BuiltinID >= Builtin::FirstTSBuiltin) {
@@ -472,12 +486,18 @@
bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,
unsigned MaxWidth) {
assert((BuiltinID == ARM::BI__builtin_arm_ldrex ||
+ BuiltinID == ARM::BI__builtin_arm_ldaex ||
BuiltinID == ARM::BI__builtin_arm_strex ||
+ BuiltinID == ARM::BI__builtin_arm_stlex ||
BuiltinID == AArch64::BI__builtin_arm_ldrex ||
- BuiltinID == AArch64::BI__builtin_arm_strex) &&
+ BuiltinID == AArch64::BI__builtin_arm_ldaex ||
+ BuiltinID == AArch64::BI__builtin_arm_strex ||
+ BuiltinID == AArch64::BI__builtin_arm_stlex) &&
"unexpected ARM builtin");
bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex ||
- BuiltinID == AArch64::BI__builtin_arm_ldrex;
+ BuiltinID == ARM::BI__builtin_arm_ldaex ||
+ BuiltinID == AArch64::BI__builtin_arm_ldrex ||
+ BuiltinID == AArch64::BI__builtin_arm_ldaex;
DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
@@ -493,7 +513,7 @@
ExprResult PointerArgRes = DefaultFunctionArrayLvalueConversion(PointerArg);
if (PointerArgRes.isInvalid())
return true;
- PointerArg = PointerArgRes.take();
+ PointerArg = PointerArgRes.get();
const PointerType *pointerType = PointerArg->getType()->getAs<PointerType>();
if (!pointerType) {
@@ -525,7 +545,7 @@
PointerArgRes = ImpCastExprToType(PointerArg, AddrType, CastNeeded);
if (PointerArgRes.isInvalid())
return true;
- PointerArg = PointerArgRes.take();
+ PointerArg = PointerArgRes.get();
TheCall->setArg(IsLdrex ? 0 : 1, PointerArg);
@@ -584,15 +604,17 @@
llvm::APSInt Result;
if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
- BuiltinID == ARM::BI__builtin_arm_strex) {
+ BuiltinID == ARM::BI__builtin_arm_ldaex ||
+ BuiltinID == ARM::BI__builtin_arm_strex ||
+ BuiltinID == ARM::BI__builtin_arm_stlex) {
return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64);
}
if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall))
return true;
- // For NEON intrinsics which take an immediate value as part of the
- // instruction, range check them here.
+ // For intrinsics which take an immediate value as part of the instruction,
+ // range check them here.
unsigned i = 0, l = 0, u = 0;
switch (BuiltinID) {
default: return false;
@@ -601,7 +623,8 @@
case ARM::BI__builtin_arm_vcvtr_f:
case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
case ARM::BI__builtin_arm_dmb:
- case ARM::BI__builtin_arm_dsb: l = 0; u = 15; break;
+ case ARM::BI__builtin_arm_dsb:
+ case ARM::BI__builtin_arm_isb: l = 0; u = 15; break;
}
// FIXME: VFP Intrinsics should error if VFP not present.
@@ -613,7 +636,9 @@
llvm::APSInt Result;
if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
- BuiltinID == AArch64::BI__builtin_arm_strex) {
+ BuiltinID == AArch64::BI__builtin_arm_ldaex ||
+ BuiltinID == AArch64::BI__builtin_arm_strex ||
+ BuiltinID == AArch64::BI__builtin_arm_stlex) {
return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128);
}
@@ -1219,7 +1244,7 @@
Diag(AE->getLocStart(), diag::err_atomic_load_store_uses_lib) <<
((Op == AtomicExpr::AO__c11_atomic_load) ? 0 : 1);
- return Owned(AE);
+ return AE;
}
@@ -1243,7 +1268,7 @@
if (Arg.isInvalid())
return true;
- E->setArg(ArgIndex, Arg.take());
+ E->setArg(ArgIndex, Arg.get());
return false;
}
@@ -1278,7 +1303,7 @@
ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg);
if (FirstArgResult.isInvalid())
return ExprError();
- FirstArg = FirstArgResult.take();
+ FirstArg = FirstArgResult.get();
TheCall->setArg(0, FirstArg);
const PointerType *pointerType = FirstArg->getType()->getAs<PointerType>();
@@ -1556,7 +1581,7 @@
// pass in 42. The 42 gets converted to char. This is even more strange
// for things like 45.123 -> char, etc.
// FIXME: Do this check.
- TheCall->setArg(i+1, Arg.take());
+ TheCall->setArg(i+1, Arg.get());
}
ASTContext& Context = this->getASTContext();
@@ -1577,7 +1602,7 @@
QualType CalleePtrTy = Context.getPointerType(NewBuiltinDecl->getType());
ExprResult PromotedCall = ImpCastExprToType(NewDRE, CalleePtrTy,
CK_BuiltinFnToFnPtr);
- TheCall->setCallee(PromotedCall.take());
+ TheCall->setCallee(PromotedCall.get());
// Change the result type of the call to match the original value type. This
// is arbitrary, but the codegen for these builtins ins design to handle it
@@ -1861,9 +1886,9 @@
TheCall->setArg(i, nullptr);
}
- return Owned(new (Context) ShuffleVectorExpr(Context, exprs, resType,
- TheCall->getCallee()->getLocStart(),
- TheCall->getRParenLoc()));
+ return new (Context) ShuffleVectorExpr(Context, exprs, resType,
+ TheCall->getCallee()->getLocStart(),
+ TheCall->getRParenLoc());
}
/// SemaConvertVectorExpr - Handle __builtin_convertvector
@@ -1892,9 +1917,8 @@
<< E->getSourceRange());
}
- return Owned(new (Context) ConvertVectorExpr(E, TInfo, DstTy, VK, OK,
- BuiltinLoc, RParenLoc));
-
+ return new (Context)
+ ConvertVectorExpr(E, TInfo, DstTy, VK, OK, BuiltinLoc, RParenLoc);
}
/// SemaBuiltinPrefetch - Handle __builtin_prefetch.
@@ -3111,6 +3135,13 @@
ExprTy = S.Context.CharTy;
}
+ // Look through enums to their underlying type.
+ bool IsEnum = false;
+ if (auto EnumTy = ExprTy->getAs<EnumType>()) {
+ ExprTy = EnumTy->getDecl()->getIntegerType();
+ IsEnum = true;
+ }
+
// %C in an Objective-C context prints a unichar, not a wchar_t.
// If the argument is an integer of some kind, believe the %C and suggest
// a cast instead of changing the conversion specifier.
@@ -3183,8 +3214,8 @@
// In this case, the specifier is wrong and should be changed to match
// the argument.
EmitFormatDiagnostic(
- S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
- << AT.getRepresentativeTypeName(S.Context) << IntendedTy
+ S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+ << AT.getRepresentativeTypeName(S.Context) << IntendedTy << IsEnum
<< E->getSourceRange(),
E->getLocStart(),
/*IsStringLocation*/false,
@@ -3236,7 +3267,7 @@
StringRef Name = cast<TypedefType>(ExprTy)->getDecl()->getName();
EmitFormatDiagnostic(S.PDiag(diag::warn_format_argument_needs_cast)
- << Name << IntendedTy
+ << Name << IntendedTy << IsEnum
<< E->getSourceRange(),
E->getLocStart(), /*IsStringLocation=*/false,
SpecRange, Hints);
@@ -3245,8 +3276,8 @@
// specifier, but we've decided that the specifier is probably correct
// and we should cast instead. Just use the normal warning message.
EmitFormatDiagnostic(
- S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
- << AT.getRepresentativeTypeName(S.Context) << ExprTy
+ S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+ << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum
<< E->getSourceRange(),
E->getLocStart(), /*IsStringLocation*/false,
SpecRange, Hints);
@@ -3262,8 +3293,8 @@
case Sema::VAK_Valid:
case Sema::VAK_ValidInCXX11:
EmitFormatDiagnostic(
- S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
- << AT.getRepresentativeTypeName(S.Context) << ExprTy
+ S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+ << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum
<< CSR
<< E->getSourceRange(),
E->getLocStart(), /*IsStringLocation*/false, CSR);
@@ -3454,8 +3485,8 @@
fixedFS.toString(os);
EmitFormatDiagnostic(
- S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
- << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+ S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+ << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false
<< Ex->getSourceRange(),
Ex->getLocStart(),
/*IsStringLocation*/false,
@@ -3465,8 +3496,8 @@
os.str()));
} else {
EmitFormatDiagnostic(
- S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
- << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+ S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
+ << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false
<< Ex->getSourceRange(),
Ex->getLocStart(),
/*IsStringLocation*/false,
@@ -3963,15 +3994,35 @@
return true;
}
-/// \brief Determine whether the given type is a dynamic class type (e.g.,
-/// whether it has a vtable).
-static bool isDynamicClassType(QualType T) {
- if (CXXRecordDecl *Record = T->getAsCXXRecordDecl())
- if (CXXRecordDecl *Definition = Record->getDefinition())
- if (Definition->isDynamicClass())
- return true;
-
- return false;
+/// \brief Determine whether the given type is or contains a dynamic class type
+/// (e.g., whether it has a vtable).
+static const CXXRecordDecl *getContainedDynamicClass(QualType T,
+ bool &IsContained) {
+ // Look through array types while ignoring qualifiers.
+ const Type *Ty = T->getBaseElementTypeUnsafe();
+ IsContained = false;
+
+ const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+ RD = RD ? RD->getDefinition() : nullptr;
+ if (!RD)
+ return nullptr;
+
+ if (RD->isDynamicClass())
+ return RD;
+
+ // Check all the fields. If any bases were dynamic, the class is dynamic.
+ // It's impossible for a class to transitively contain itself by value, so
+ // infinite recursion is impossible.
+ for (auto *FD : RD->fields()) {
+ bool SubContained;
+ if (const CXXRecordDecl *ContainedRD =
+ getContainedDynamicClass(FD->getType(), SubContained)) {
+ IsContained = true;
+ return ContainedRD;
+ }
+ }
+
+ return nullptr;
}
/// \brief If E is a sizeof expression, returns its argument expression,
@@ -4045,8 +4096,8 @@
// expression IDs can be expensive, we only do this if the diagnostic is
// enabled.
if (SizeOfArg &&
- Diags.getDiagnosticLevel(diag::warn_sizeof_pointer_expr_memaccess,
- SizeOfArg->getExprLoc())) {
+ !Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
+ SizeOfArg->getExprLoc())) {
// We only compute IDs for expressions if the warning is enabled, and
// cache the sizeof arg's ID.
if (SizeOfArgID == llvm::FoldingSetNodeID())
@@ -4115,7 +4166,9 @@
}
// Always complain about dynamic classes.
- if (isDynamicClassType(PointeeTy)) {
+ bool IsContained;
+ if (const CXXRecordDecl *ContainedRD =
+ getContainedDynamicClass(PointeeTy, IsContained)) {
unsigned OperationType = 0;
// "overwritten" if we're warning about the destination for any call
@@ -4133,8 +4186,7 @@
Dest->getExprLoc(), Dest,
PDiag(diag::warn_dyn_class_memaccess)
<< (BId == Builtin::BImemcmp ? ArgIdx + 2 : ArgIdx)
- << FnName << PointeeTy
- << OperationType
+ << FnName << IsContained << ContainedRD << OperationType
<< Call->getCallee()->getSourceRange());
} else if (PointeeTy.hasNonTrivialObjCLifetime() &&
BId != Builtin::BImemset)
@@ -4572,7 +4624,6 @@
case Stmt::CXXReinterpretCastExprClass: {
Expr* SubExpr = cast<CastExpr>(E)->getSubExpr();
switch (cast<CastExpr>(E)->getCastKind()) {
- case CK_BitCast:
case CK_LValueToRValue:
case CK_NoOp:
case CK_BaseToDerived:
@@ -4587,6 +4638,14 @@
case CK_ArrayToPointerDecay:
return EvalVal(SubExpr, refVars, ParentDecl);
+ case CK_BitCast:
+ if (SubExpr->getType()->isAnyPointerType() ||
+ SubExpr->getType()->isBlockPointerType() ||
+ SubExpr->getType()->isObjCQualifiedIdType())
+ return EvalAddr(SubExpr, refVars, ParentDecl);
+ else
+ return nullptr;
+
default:
return nullptr;
}
@@ -5350,7 +5409,9 @@
if (OtherRange.NonNegative) {
if (OtherWidth >= Value.getActiveBits())
return;
- } else if (!OtherRange.NonNegative && !ConstantSigned) {
+ } else { // OtherSigned
+ assert(!ConstantSigned &&
+ "Two signed types converted to unsigned types.");
// Check to see if the constant is representable in OtherT.
if (OtherWidth > Value.getActiveBits())
return;
@@ -5364,8 +5425,6 @@
// after conversion. Relational comparison still works, but equality
// comparisons will be tautological.
EqualityOnly = true;
- } else { // OtherSigned && ConstantSigned
- assert(0 && "Two signed types converted to unsigned types.");
}
}
@@ -6047,8 +6106,7 @@
if (!Suspicious) return;
// ...but it's currently ignored...
- if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional,
- CC))
+ if (!S.Diags.isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
return;
// ...then check whether it would have warned about either of the
@@ -6152,6 +6210,38 @@
ArrayPointer
};
+// Helper function for Sema::DiagnoseAlwaysNonNullPointer.
+// Returns true when emitting a warning about taking the address of a reference.
+static bool CheckForReference(Sema &SemaRef, const Expr *E,
+ PartialDiagnostic PD) {
+ E = E->IgnoreParenImpCasts();
+
+ const FunctionDecl *FD = nullptr;
+
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (!DRE->getDecl()->getType()->isReferenceType())
+ return false;
+ } else if (const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
+ if (!M->getMemberDecl()->getType()->isReferenceType())
+ return false;
+ } else if (const CallExpr *Call = dyn_cast<CallExpr>(E)) {
+ if (!Call->getCallReturnType()->isReferenceType())
+ return false;
+ FD = Call->getDirectCallee();
+ } else {
+ return false;
+ }
+
+ SemaRef.Diag(E->getExprLoc(), PD);
+
+ // If possible, point to location of function.
+ if (FD) {
+ SemaRef.Diag(FD->getLocation(), diag::note_reference_is_return_value) << FD;
+ }
+
+ return true;
+}
+
/// \brief Diagnose pointers that are always non-null.
/// \param E the expression containing the pointer
/// \param NullKind NPCK_NotNull if E is a cast to bool, otherwise, E is
@@ -6161,6 +6251,8 @@
void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
Expr::NullPointerConstantKind NullKind,
bool IsEqual, SourceRange Range) {
+ if (!E)
+ return;
// Don't warn inside macros.
if (E->getExprLoc().isMacroID())
@@ -6169,6 +6261,13 @@
const bool IsCompare = NullKind != Expr::NPCK_NotNull;
+ if (isa<CXXThisExpr>(E)) {
+ unsigned DiagID = IsCompare ? diag::warn_this_null_compare
+ : diag::warn_this_bool_conversion;
+ Diag(E->getExprLoc(), DiagID) << E->getSourceRange() << Range << IsEqual;
+ return;
+ }
+
bool IsAddressOf = false;
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
@@ -6178,6 +6277,17 @@
E = UO->getSubExpr();
}
+ if (IsAddressOf) {
+ unsigned DiagID = IsCompare
+ ? diag::warn_address_of_reference_null_compare
+ : diag::warn_address_of_reference_bool_conversion;
+ PartialDiagnostic PD = PDiag(DiagID) << E->getSourceRange() << Range
+ << IsEqual;
+ if (CheckForReference(*this, E, PD)) {
+ return;
+ }
+ }
+
// Expect to find a single Decl. Skip anything more complicated.
ValueDecl *D = nullptr;
if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {
@@ -6194,13 +6304,9 @@
const bool IsArray = T->isArrayType();
const bool IsFunction = T->isFunctionType();
- if (IsAddressOf) {
- // Address of function is used to silence the function warning.
- if (IsFunction)
- return;
- // Address of reference can be null.
- if (T->isReferenceType())
- return;
+ // Address of function is used to silence the function warning.
+ if (IsAddressOf && IsFunction) {
+ return;
}
// Found nothing.
@@ -6882,9 +6988,7 @@
void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
// This is actually a lot of work to potentially be doing on every
// cast; don't do it if we're ignoring -Wcast_align (as is the default).
- if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align,
- TRange.getBegin())
- == DiagnosticsEngine::Ignored)
+ if (getDiagnostics().isIgnored(diag::warn_cast_align, TRange.getBegin()))
return;
// Ignore dependent types.
@@ -7252,10 +7356,12 @@
struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> {
FindCaptureVisitor(ASTContext &Context, VarDecl *variable)
: EvaluatedExprVisitor<FindCaptureVisitor>(Context),
- Variable(variable), Capturer(nullptr) {}
-
+ Context(Context), Variable(variable), Capturer(nullptr),
+ VarWillBeReased(false) {}
+ ASTContext &Context;
VarDecl *Variable;
Expr *Capturer;
+ bool VarWillBeReased;
void VisitDeclRefExpr(DeclRefExpr *ref) {
if (ref->getDecl() == Variable && !Capturer)
@@ -7280,6 +7386,21 @@
if (OVE->getSourceExpr())
Visit(OVE->getSourceExpr());
}
+ void VisitBinaryOperator(BinaryOperator *BinOp) {
+ if (!Variable || VarWillBeReased || BinOp->getOpcode() != BO_Assign)
+ return;
+ Expr *LHS = BinOp->getLHS();
+ if (const DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(LHS)) {
+ if (DRE->getDecl() != Variable)
+ return;
+ if (Expr *RHS = BinOp->getRHS()) {
+ RHS = RHS->IgnoreParenCasts();
+ llvm::APSInt Value;
+ VarWillBeReased =
+ (RHS && RHS->isIntegerConstantExpr(Value, Context) && Value == 0);
+ }
+ }
+ }
};
}
@@ -7317,7 +7438,7 @@
FindCaptureVisitor visitor(S.Context, owner.Variable);
visitor.Visit(block->getBlockDecl()->getBody());
- return visitor.Capturer;
+ return visitor.VarWillBeReased ? nullptr : visitor.Capturer;
}
static void diagnoseRetainCycle(Sema &S, Expr *capturer,
@@ -7476,9 +7597,7 @@
Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime();
if (LT == Qualifiers::OCL_Weak) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc);
- if (Level != DiagnosticsEngine::Ignored)
+ if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
getCurFunction()->markSafeWeakUse(LHS);
}
@@ -7603,8 +7722,7 @@
return;
// Skip expensive checks if diagnostic is disabled.
- if (Diags.getDiagnosticLevel(DiagID, NBody->getSemiLoc()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(DiagID, NBody->getSemiLoc()))
return;
// Do the usual checks.
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index c075c92..3d250e3 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -480,6 +480,16 @@
return Result;
}
+/// Determine whether \p Id is a name reserved for the implementation (C99
+/// 7.1.3, C++ [lib.global.names]).
+static bool isReservedName(const IdentifierInfo *Id) {
+ if (Id->getLength() < 2)
+ return false;
+ const char *Name = Id->getNameStart();
+ return Name[0] == '_' &&
+ (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z'));
+}
+
bool ResultBuilder::isInterestingDecl(const NamedDecl *ND,
bool &AsNestedNameSpecifier) const {
AsNestedNameSpecifier = false;
@@ -506,25 +516,15 @@
return false;
// Some declarations have reserved names that we don't want to ever show.
- if (const IdentifierInfo *Id = ND->getIdentifier()) {
- // __va_list_tag is a freak of nature. Find it and skip it.
- if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
- return false;
-
- // Filter out names reserved for the implementation (C99 7.1.3,
- // C++ [lib.global.names]) if they come from a system header.
- //
- // FIXME: Add predicate for this.
- if (Id->getLength() >= 2) {
- const char *Name = Id->getNameStart();
- if (Name[0] == '_' &&
- (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')) &&
- (ND->getLocation().isInvalid() ||
- SemaRef.SourceMgr.isInSystemHeader(
- SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
+ // Filter out names reserved for the implementation if they come from a
+ // system header.
+ // TODO: Add a predicate for this.
+ if (const IdentifierInfo *Id = ND->getIdentifier())
+ if (isReservedName(Id) &&
+ (ND->getLocation().isInvalid() ||
+ SemaRef.SourceMgr.isInSystemHeader(
+ SemaRef.SourceMgr.getSpellingLoc(ND->getLocation()))))
return false;
- }
- }
if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
@@ -3428,7 +3428,7 @@
if (E.isInvalid())
CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
else if (getLangOpts().ObjC1)
- CodeCompleteObjCInstanceMessage(S, E.take(), None, false);
+ CodeCompleteObjCInstanceMessage(S, E.get(), None, false);
}
/// \brief The set of properties that have already been added, referenced by
@@ -5322,7 +5322,7 @@
if (R.Priority <= BestPriority) {
const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(R.Declaration);
if (NumSelIdents <= Method->param_size()) {
- QualType MyPreferredType = Method->param_begin()[NumSelIdents - 1]
+ QualType MyPreferredType = Method->parameters()[NumSelIdents - 1]
->getType();
if (R.Priority < BestPriority || PreferredType.isNull()) {
BestPriority = R.Priority;
@@ -5466,7 +5466,7 @@
ExprResult Conv = DefaultFunctionArrayLvalueConversion(RecExpr);
if (Conv.isInvalid()) // conversion failed. bail.
return;
- RecExpr = Conv.take();
+ RecExpr = Conv.get();
}
QualType ReceiverType = RecExpr? RecExpr->getType()
: Super? Context.getObjCObjectPointerType(
@@ -5490,7 +5490,7 @@
} else if (RecExpr && getLangOpts().CPlusPlus) {
ExprResult Conv = PerformContextuallyConvertToObjCPointer(RecExpr);
if (Conv.isUsable()) {
- RecExpr = Conv.take();
+ RecExpr = Conv.get();
ReceiverType = RecExpr->getType();
}
}
@@ -6994,7 +6994,7 @@
// Suggest parameter names we've seen before.
unsigned NumSelIdents = SelIdents.size();
if (NumSelIdents && NumSelIdents <= MethList->Method->param_size()) {
- ParmVarDecl *Param = MethList->Method->param_begin()[NumSelIdents-1];
+ ParmVarDecl *Param = MethList->Method->parameters()[NumSelIdents-1];
if (Param->getIdentifier()) {
CodeCompletionBuilder Builder(Results.getAllocator(),
Results.getCodeCompletionTUInfo());
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index a0ce766..13a77f1 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -128,6 +128,65 @@
return false;
}
+static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
+ const IdentifierInfo &II,
+ SourceLocation NameLoc) {
+ // Find the first parent class template context, if any.
+ // FIXME: Perform the lookup in all enclosing class templates.
+ const CXXRecordDecl *RD = nullptr;
+ for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) {
+ RD = dyn_cast<CXXRecordDecl>(DC);
+ if (RD && RD->getDescribedClassTemplate())
+ break;
+ }
+ if (!RD)
+ return ParsedType();
+
+ // Look for type decls in dependent base classes that have known primary
+ // templates.
+ bool FoundTypeDecl = false;
+ for (const auto &Base : RD->bases()) {
+ auto *TST = Base.getType()->getAs<TemplateSpecializationType>();
+ if (!TST || !TST->isDependentType())
+ continue;
+ auto *TD = TST->getTemplateName().getAsTemplateDecl();
+ if (!TD)
+ continue;
+ auto *BasePrimaryTemplate = cast<CXXRecordDecl>(TD->getTemplatedDecl());
+ // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly
+ // by calling or integrating with the main LookupQualifiedName mechanism.
+ for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) {
+ if (FoundTypeDecl)
+ return ParsedType();
+ FoundTypeDecl = isa<TypeDecl>(ND);
+ if (!FoundTypeDecl)
+ return ParsedType();
+ }
+ }
+ if (!FoundTypeDecl)
+ return ParsedType();
+
+ // We found some types in dependent base classes. Recover as if the user
+ // wrote 'typename MyClass::II' instead of 'II'. We'll fully resolve the
+ // lookup during template instantiation.
+ S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II;
+
+ ASTContext &Context = S.Context;
+ auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false,
+ cast<Type>(Context.getRecordType(RD)));
+ QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II);
+
+ CXXScopeSpec SS;
+ SS.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+
+ TypeLocBuilder Builder;
+ DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+ DepTL.setNameLoc(NameLoc);
+ DepTL.setElaboratedKeywordLoc(SourceLocation());
+ DepTL.setQualifierLoc(SS.getWithLocInContext(Context));
+ return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
/// \brief If the identifier refers to a type name within this scope,
/// return the declaration of that type.
///
@@ -209,6 +268,14 @@
} else {
// Perform unqualified name lookup.
LookupName(Result, S);
+
+ // For unqualified lookup in a class template in MSVC mode, look into
+ // dependent base classes where the primary class template is known.
+ if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) {
+ if (ParsedType TypeInBase =
+ recoverFromTypeInKnownDependentBase(*this, II, NameLoc))
+ return TypeInBase;
+ }
}
NamedDecl *IIDecl = nullptr;
@@ -343,6 +410,50 @@
return ParsedType::make(T);
}
+// Builds a fake NNS for the given decl context.
+static NestedNameSpecifier *
+synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) {
+ for (;; DC = DC->getLookupParent()) {
+ DC = DC->getPrimaryContext();
+ auto *ND = dyn_cast<NamespaceDecl>(DC);
+ if (ND && !ND->isInline() && !ND->isAnonymousNamespace())
+ return NestedNameSpecifier::Create(Context, nullptr, ND);
+ else if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
+ return NestedNameSpecifier::Create(Context, nullptr, RD->isTemplateDecl(),
+ RD->getTypeForDecl());
+ else if (isa<TranslationUnitDecl>(DC))
+ return NestedNameSpecifier::GlobalSpecifier(Context);
+ }
+ llvm_unreachable("something isn't in TU scope?");
+}
+
+ParsedType Sema::ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II,
+ SourceLocation NameLoc) {
+ // Accepting an undeclared identifier as a default argument for a template
+ // type parameter is a Microsoft extension.
+ Diag(NameLoc, diag::ext_ms_delayed_template_argument) << &II;
+
+ // Build a fake DependentNameType that will perform lookup into CurContext at
+ // instantiation time. The name specifier isn't dependent, so template
+ // instantiation won't transform it. It will retry the lookup, however.
+ NestedNameSpecifier *NNS =
+ synthesizeCurrentNestedNameSpecifier(Context, CurContext);
+ QualType T = Context.getDependentNameType(ETK_None, NNS, &II);
+
+ // Build type location information. We synthesized the qualifier, so we have
+ // to build a fake NestedNameSpecifierLoc.
+ NestedNameSpecifierLocBuilder NNSLocBuilder;
+ NNSLocBuilder.MakeTrivial(Context, NNS, SourceRange(NameLoc));
+ NestedNameSpecifierLoc QualifierLoc = NNSLocBuilder.getWithLocInContext(Context);
+
+ TypeLocBuilder Builder;
+ DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T);
+ DepTL.setNameLoc(NameLoc);
+ DepTL.setElaboratedKeywordLoc(SourceLocation());
+ DepTL.setQualifierLoc(QualifierLoc);
+ return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
/// isTagName() - This method is called *for error recovery purposes only*
/// to determine if the specified name is a valid tag name ("struct foo"). If
/// so, this returns the TST for the tag corresponding to it (TST_enum,
@@ -394,7 +505,7 @@
return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
}
-bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
+void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
SourceLocation IILoc,
Scope *S,
CXXScopeSpec *SS,
@@ -439,7 +550,7 @@
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo=*/true);
}
- return true;
+ return;
}
if (getLangOpts().CPlusPlus) {
@@ -458,7 +569,7 @@
Diag(TplDecl->getLocation(), diag::note_template_decl_here)
<< TplDecl->getTemplateParameters()->getSourceRange();
}
- return true;
+ return;
}
}
@@ -473,7 +584,7 @@
else if (isDependentScopeSpecifier(*SS)) {
unsigned DiagID = diag::err_typename_missing;
if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
- DiagID = diag::warn_typename_missing;
+ DiagID = diag::ext_typename_missing;
Diag(SS->getRange().getBegin(), DiagID)
<< SS->getScopeRep() << II->getName()
@@ -485,8 +596,6 @@
assert(SS && SS->isInvalid() &&
"Invalid scope specifier has already been diagnosed");
}
-
- return true;
}
/// \brief Determine whether the given result set contains either a type name
@@ -588,6 +697,14 @@
LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
LookupParsedName(Result, S, &SS, !CurMethod);
+ // For unqualified lookup in a class template in MSVC mode, look into
+ // dependent base classes where the primary class template is known.
+ if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) {
+ if (ParsedType TypeInBase =
+ recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc))
+ return TypeInBase;
+ }
+
// Perform lookup for Objective-C instance variables (including automatically
// synthesized instance variables), if we're in an Objective-C method.
// FIXME: This lookup really, really needs to be folded in to the normal
@@ -1527,8 +1644,7 @@
<< Context.BuiltinInfo.GetName(BID)
<< R;
if (Context.BuiltinInfo.getHeaderName(BID) &&
- Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc)
- != DiagnosticsEngine::Ignored)
+ !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc))
Diag(Loc, diag::note_please_include_header)
<< Context.BuiltinInfo.getHeaderName(BID)
<< Context.BuiltinInfo.GetName(BID);
@@ -2210,6 +2326,24 @@
return Sema::CXXInvalid;
}
+// Determine whether the previous declaration was a definition, implicit
+// declaration, or a declaration.
+template <typename T>
+static std::pair<diag::kind, SourceLocation>
+getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) {
+ diag::kind PrevDiag;
+ SourceLocation OldLocation = Old->getLocation();
+ if (Old->isThisDeclarationADefinition())
+ PrevDiag = diag::note_previous_definition;
+ else if (Old->isImplicit()) {
+ PrevDiag = diag::note_previous_implicit_declaration;
+ if (OldLocation.isInvalid())
+ OldLocation = New->getLocation();
+ } else
+ PrevDiag = diag::note_previous_declaration;
+ return std::make_pair(PrevDiag, OldLocation);
+}
+
/// canRedefineFunction - checks if a function can be redefined. Currently,
/// only extern inline functions can be redefined, and even then only in
/// GNU89 mode.
@@ -2302,18 +2436,10 @@
if (Old->isInvalidDecl())
return true;
- // Determine whether the previous declaration was a definition,
- // implicit declaration, or a declaration.
diag::kind PrevDiag;
- SourceLocation OldLocation = Old->getLocation();
- if (Old->isThisDeclarationADefinition())
- PrevDiag = diag::note_previous_definition;
- else if (Old->isImplicit()) {
- PrevDiag = diag::note_previous_implicit_declaration;
- if (OldLocation.isInvalid())
- OldLocation = New->getLocation();
- } else
- PrevDiag = diag::note_previous_declaration;
+ SourceLocation OldLocation;
+ std::tie(PrevDiag, OldLocation) =
+ getNoteDiagForInvalidRedeclaration(Old, New);
// Don't complain about this if we're in GNU89 mode and the old function
// is an extern inline function.
@@ -2325,7 +2451,7 @@
!New->getTemplateSpecializationInfo() &&
!canRedefineFunction(Old, getLangOpts())) {
if (getLangOpts().MicrosoftExt) {
- Diag(New->getLocation(), diag::warn_static_non_static) << New;
+ Diag(New->getLocation(), diag::ext_static_non_static) << New;
Diag(OldLocation, PrevDiag);
} else {
Diag(New->getLocation(), diag::err_static_non_static) << New;
@@ -2468,11 +2594,13 @@
ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType);
if (ResQT.isNull()) {
if (New->isCXXClassMember() && New->isOutOfLine())
- Diag(New->getLocation(),
- diag::err_member_def_does_not_match_ret_type) << New;
+ Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type)
+ << New << New->getReturnTypeSourceRange();
else
- Diag(New->getLocation(), diag::err_ovl_diff_return_type);
- Diag(OldLocation, PrevDiag) << Old << Old->getType();
+ Diag(New->getLocation(), diag::err_ovl_diff_return_type)
+ << New->getReturnTypeSourceRange();
+ Diag(OldLocation, PrevDiag) << Old << Old->getType()
+ << Old->getReturnTypeSourceRange();
return true;
}
else
@@ -3026,13 +3154,25 @@
if (New->isInvalidDecl())
return;
+ diag::kind PrevDiag;
+ SourceLocation OldLocation;
+ std::tie(PrevDiag, OldLocation) =
+ getNoteDiagForInvalidRedeclaration(Old, New);
+
// [dcl.stc]p8: Check if we have a non-static decl followed by a static.
if (New->getStorageClass() == SC_Static &&
!New->isStaticDataMember() &&
Old->hasExternalFormalLinkage()) {
- Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
- return New->setInvalidDecl();
+ if (getLangOpts().MicrosoftExt) {
+ Diag(New->getLocation(), diag::ext_static_non_static)
+ << New->getDeclName();
+ Diag(OldLocation, PrevDiag);
+ } else {
+ Diag(New->getLocation(), diag::err_static_non_static)
+ << New->getDeclName();
+ Diag(OldLocation, PrevDiag);
+ return New->setInvalidDecl();
+ }
}
// C99 6.2.2p4:
// For an identifier declared with the storage-class specifier
@@ -3049,7 +3189,7 @@
!New->isStaticDataMember() &&
Old->getCanonicalDecl()->getStorageClass() == SC_Static) {
Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
@@ -3057,13 +3197,13 @@
if (New->hasExternalStorage() &&
!Old->hasLinkage() && Old->isLocalVarDecl()) {
Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
if (Old->hasLinkage() && New->isLocalVarDecl() &&
!New->hasExternalStorage()) {
Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
@@ -3076,17 +3216,17 @@
!(Old->getLexicalDeclContext()->isRecord() &&
!New->getLexicalDeclContext()->isRecord())) {
Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
return New->setInvalidDecl();
}
if (New->getTLSKind() != Old->getTLSKind()) {
if (!Old->getTLSKind()) {
Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, PrevDiag);
} else if (!New->getTLSKind()) {
Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, PrevDiag);
} else {
// Do not allow redeclaration to change the variable between requiring
// static and dynamic initialization.
@@ -3094,7 +3234,7 @@
// declaration to determine the kind. Do we need to be compatible here?
Diag(New->getLocation(), diag::err_thread_thread_different_kind)
<< New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic);
- Diag(Old->getLocation(), diag::note_previous_declaration);
+ Diag(OldLocation, PrevDiag);
}
}
@@ -3111,7 +3251,7 @@
if (haveIncompatibleLanguageLinkages(Old, New)) {
Diag(New->getLocation(), diag::err_different_language_linkage) << New;
- Diag(Old->getLocation(), diag::note_previous_definition);
+ Diag(OldLocation, PrevDiag);
New->setInvalidDecl();
return;
}
@@ -3691,6 +3831,8 @@
}
} else if (isa<AccessSpecDecl>(Mem)) {
// Any access specifier is fine.
+ } else if (isa<StaticAssertDecl>(Mem)) {
+ // In C++1z, static_assert declarations are also fine.
} else {
// We have something that isn't a non-static data
// member. Complain about it.
@@ -4907,10 +5049,15 @@
// A redeclaration is not allowed to drop a dllimport attribute, the only
// exception being inline function definitions.
// NB: MSVC converts such a declaration to dllexport.
- bool IsInline =
- isa<FunctionDecl>(NewDecl) && cast<FunctionDecl>(NewDecl)->isInlined();
+ bool IsInline = false, IsStaticDataMember = false;
+ if (const auto *VD = dyn_cast<VarDecl>(NewDecl))
+ // Ignore static data because out-of-line definitions are diagnosed
+ // separately.
+ IsStaticDataMember = VD->isStaticDataMember();
+ else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl))
+ IsInline = FD->isInlined();
- if (OldImportAttr && !HasNewAttr && !IsInline) {
+ if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) {
S.Diag(NewDecl->getLocation(),
diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
<< NewDecl << OldImportAttr;
@@ -5453,6 +5600,10 @@
// Global Named register
if (!Context.getTargetInfo().isValidGCCRegisterName(Label))
Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+ if (!R->isIntegralType(Context) && !R->isPointerType()) {
+ Diag(D.getLocStart(), diag::err_asm_bad_register_type);
+ NewVD->setInvalidDecl(true);
+ }
}
NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
@@ -5590,8 +5741,7 @@
///
void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) {
// Return if warning is ignored.
- if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, R.getNameLoc()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
return;
// Don't diagnose declarations at file scope.
@@ -5664,8 +5814,7 @@
/// \brief Check -Wshadow without the advantage of a previous lookup.
void Sema::CheckShadow(Scope *S, VarDecl *D) {
- if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, D->getLocation()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_decl_shadow, D->getLocation()))
return;
LookupResult R(*this, D->getDeclName(), D->getLocation(),
@@ -7422,8 +7571,10 @@
// OpenCL v1.2, s6.9 -- Kernels can only have return type void.
if (!NewFD->getReturnType()->isVoidType()) {
- Diag(D.getIdentifierLoc(),
- diag::err_expected_kernel_void_return_type);
+ SourceRange RTRange = NewFD->getReturnTypeSourceRange();
+ Diag(D.getIdentifierLoc(), diag::err_expected_kernel_void_return_type)
+ << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+ : FixItHint());
D.setInvalidType();
}
@@ -7763,23 +7914,6 @@
return Redeclaration;
}
-static SourceRange getResultSourceRange(const FunctionDecl *FD) {
- const TypeSourceInfo *TSI = FD->getTypeSourceInfo();
- if (!TSI)
- return SourceRange();
-
- TypeLoc TL = TSI->getTypeLoc();
- FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>();
- if (!FunctionTL)
- return SourceRange();
-
- TypeLoc ResultTL = FunctionTL.getReturnLoc();
- if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>())
- return ResultTL.getSourceRange();
-
- return SourceRange();
-}
-
void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
// C++11 [basic.start.main]p3:
// A program that [...] declares main to be inline, static or
@@ -7819,34 +7953,37 @@
assert(T->isFunctionType() && "function decl is not of function type");
const FunctionType* FT = T->castAs<FunctionType>();
- // All the standards say that main() should should return 'int'.
- if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) {
+ if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
+ // In C with GNU extensions we allow main() to have non-integer return
+ // type, but we should warn about the extension, and we disable the
+ // implicit-return-zero rule.
+
+ // GCC in C mode accepts qualified 'int'.
+ if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy))
+ FD->setHasImplicitReturnZero(true);
+ else {
+ Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
+ SourceRange RTRange = FD->getReturnTypeSourceRange();
+ if (RTRange.isValid())
+ Diag(RTRange.getBegin(), diag::note_main_change_return_type)
+ << FixItHint::CreateReplacement(RTRange, "int");
+ }
+ } else {
// In C and C++, main magically returns 0 if you fall off the end;
// set the flag which tells us that.
// This is C++ [basic.start.main]p5 and C99 5.1.2.2.3.
- FD->setHasImplicitReturnZero(true);
- // In C with GNU extensions we allow main() to have non-integer return
- // type, but we should warn about the extension, and we disable the
- // implicit-return-zero rule.
- } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
- Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
-
- SourceRange ResultRange = getResultSourceRange(FD);
- if (ResultRange.isValid())
- Diag(ResultRange.getBegin(), diag::note_main_change_return_type)
- << FixItHint::CreateReplacement(ResultRange, "int");
-
- // Otherwise, this is just a flat-out error.
- } else {
- SourceRange ResultRange = getResultSourceRange(FD);
- if (ResultRange.isValid())
+ // All the standards say that main() should return 'int'.
+ if (Context.hasSameType(FT->getReturnType(), Context.IntTy))
+ FD->setHasImplicitReturnZero(true);
+ else {
+ // Otherwise, this is just a flat-out error.
+ SourceRange RTRange = FD->getReturnTypeSourceRange();
Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint)
- << FixItHint::CreateReplacement(ResultRange, "int");
- else
- Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint);
-
- FD->setInvalidDecl(true);
+ << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int")
+ : FixItHint());
+ FD->setInvalidDecl(true);
+ }
}
// Treat protoless main() as nullary.
@@ -8197,7 +8334,7 @@
VDecl->setInvalidDecl();
return;
}
- Init = Result.take();
+ Init = Result.get();
DefaultedToAuto = true;
}
@@ -8336,7 +8473,7 @@
VDecl->setInvalidDecl();
return;
}
- Init = Result.take();
+ Init = Result.get();
}
// Perform the initialization.
@@ -8364,7 +8501,7 @@
return;
}
- Init = Result.takeAs<Expr>();
+ Init = Result.getAs<Expr>();
}
// Check for self-references within variable initializers.
@@ -8395,13 +8532,10 @@
// we do not warn to warn spuriously when 'x' and 'y' are on separate
// paths through the function. This should be revisited if
// -Wrepeated-use-of-weak is made flow-sensitive.
- if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- Init->getLocStart());
- if (Level != DiagnosticsEngine::Ignored)
+ if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+ Init->getLocStart()))
getCurFunction()->markSafeWeakUse(Init);
- }
}
// The initialization is usually a full-expression.
@@ -8422,7 +8556,7 @@
VDecl->setInvalidDecl();
return;
}
- Init = Result.take();
+ Init = Result.get();
// Attach the initializer to the decl.
VDecl->setInit(Init);
@@ -8763,11 +8897,13 @@
if (Var->isInvalidDecl())
return;
- if (RequireCompleteType(Var->getLocation(),
- Context.getBaseElementType(Type),
- diag::err_typecheck_decl_incomplete_type)) {
- Var->setInvalidDecl();
- return;
+ if (!Var->hasAttr<AliasAttr>()) {
+ if (RequireCompleteType(Var->getLocation(),
+ Context.getBaseElementType(Type),
+ diag::err_typecheck_decl_incomplete_type)) {
+ Var->setInvalidDecl();
+ return;
+ }
}
// The variable can not have an abstract class type.
@@ -8874,6 +9010,37 @@
}
}
+StmtResult
+Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,
+ IdentifierInfo *Ident,
+ ParsedAttributes &Attrs,
+ SourceLocation AttrEnd) {
+ // C++1y [stmt.iter]p1:
+ // A range-based for statement of the form
+ // for ( for-range-identifier : for-range-initializer ) statement
+ // is equivalent to
+ // for ( auto&& for-range-identifier : for-range-initializer ) statement
+ DeclSpec DS(Attrs.getPool().getFactory());
+
+ const char *PrevSpec;
+ unsigned DiagID;
+ DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,
+ getPrintingPolicy());
+
+ Declarator D(DS, Declarator::ForContext);
+ D.SetIdentifier(Ident, IdentLoc);
+ D.takeAttributes(Attrs, AttrEnd);
+
+ ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory());
+ D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false),
+ EmptyAttrs, IdentLoc);
+ Decl *Var = ActOnDeclarator(S, D);
+ cast<VarDecl>(Var)->setCXXForRangeDecl(true);
+ FinalizeDeclaration(Var);
+ return ActOnDeclStmt(FinalizeDeclaratorGroup(S, DS, Var), IdentLoc,
+ AttrEnd.isValid() ? AttrEnd : IdentLoc);
+}
+
void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
if (var->isInvalidDecl()) return;
@@ -8902,9 +9069,8 @@
if (var->isThisDeclarationADefinition() &&
var->getDeclContext()->getRedeclContext()->isFileContext() &&
var->isExternallyVisible() && var->hasLinkage() &&
- getDiagnostics().getDiagnosticLevel(
- diag::warn_missing_variable_declarations,
- var->getLocation())) {
+ !getDiagnostics().isIgnored(diag::warn_missing_variable_declarations,
+ var->getLocation())) {
// Find a previous declaration that's not a definition.
VarDecl *prev = var->getPreviousDecl();
while (prev && prev->isThisDeclarationADefinition())
@@ -8984,7 +9150,7 @@
var, var->getType(), varRef, /*AllowNRVO=*/true);
if (!result.isInvalid()) {
result = MaybeCreateExprWithCleanups(result);
- Expr *init = result.takeAs<Expr>();
+ Expr *init = result.getAs<Expr>();
Context.setBlockVarCopyInits(var, init);
}
}
@@ -8997,9 +9163,8 @@
if (!var->getDeclContext()->isDependentContext() &&
Init && !Init->isValueDependent()) {
if (IsGlobal && !var->isConstexpr() &&
- getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor,
- var->getLocation())
- != DiagnosticsEngine::Ignored) {
+ !getDiagnostics().isIgnored(diag::warn_global_constructor,
+ var->getLocation())) {
// Warn about globals which don't have a constant initializer. Don't
// warn about globals with a non-trivial destructor because we already
// warned about them.
@@ -9052,6 +9217,40 @@
checkAttributesAfterMerging(*this, *VD);
+ // Static locals inherit dll attributes from their function.
+ if (VD->isStaticLocal()) {
+ if (FunctionDecl *FD =
+ dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) {
+ if (Attr *A = getDLLAttr(FD)) {
+ auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext()));
+ NewAttr->setInherited(true);
+ VD->addAttr(NewAttr);
+ }
+ }
+ }
+
+ // Imported static data members cannot be defined out-of-line.
+ if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
+ if (VD->isStaticDataMember() && VD->isOutOfLine() &&
+ VD->isThisDeclarationADefinition()) {
+ // We allow definitions of dllimport class template static data members
+ // with a warning.
+ CXXRecordDecl *Context =
+ cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext());
+ bool IsClassTemplateMember =
+ isa<ClassTemplatePartialSpecializationDecl>(Context) ||
+ Context->getDescribedClassTemplate();
+
+ Diag(VD->getLocation(),
+ IsClassTemplateMember
+ ? diag::warn_attribute_dllimport_static_field_definition
+ : diag::err_attribute_dllimport_static_field_definition);
+ Diag(IA->getLocation(), diag::note_attribute);
+ if (!IsClassTemplateMember)
+ VD->setInvalidDecl();
+ }
+ }
+
if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
@@ -9145,7 +9344,7 @@
/// BuildDeclaratorGroup - convert a list of declarations into a declaration
/// group, performing any necessary semantic checking.
Sema::DeclGroupPtrTy
-Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group,
+Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group,
bool TypeMayContainAuto) {
// C++0x [dcl.spec.auto]p7:
// If the type deduced for the template parameter U is not the same in each
@@ -9202,9 +9401,7 @@
if (Group.empty() || !Group[0])
return;
- if (Diags.getDiagnosticLevel(diag::warn_doc_param_not_found,
- Group[0]->getLocation())
- == DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_doc_param_not_found, Group[0]->getLocation()))
return;
if (Group.size() >= 2) {
@@ -9797,6 +9994,11 @@
// We want to attach documentation to original Decl (which might be
// a function template).
ActOnDocumentableDecl(D);
+ if (getCurLexicalContext()->isObjCContainer() &&
+ getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+ getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation)
+ Diag(FD->getLocation(), diag::warn_function_def_in_objc_container);
+
return D;
}
@@ -10739,11 +10941,6 @@
while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC))
SearchDC = SearchDC->getParent();
}
- } else if (S->isFunctionPrototypeScope()) {
- // If this is an enum declaration in function prototype scope, set its
- // initial context to the translation unit.
- // FIXME: [citation needed]
- SearchDC = Context.getTranslationUnitDecl();
}
if (Previous.isSingleResult() &&
@@ -11216,27 +11413,37 @@
else if (!SearchDC->isFunctionOrMethod())
New->setModulePrivate();
}
-
+
// If this is a specialization of a member class (of a class template),
// check the specialization.
if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
Invalid = true;
-
+
+ // If we're declaring or defining a tag in function prototype scope in C,
+ // note that this type can only be used within the function and add it to
+ // the list of decls to inject into the function definition scope.
+ if ((Name || Kind == TTK_Enum) &&
+ getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
+ if (getLangOpts().CPlusPlus) {
+ // C++ [dcl.fct]p6:
+ // Types shall not be defined in return or parameter types.
+ if (TUK == TUK_Definition && !IsTypeSpecifier) {
+ Diag(Loc, diag::err_type_defined_in_param_type)
+ << Name;
+ Invalid = true;
+ }
+ } else {
+ Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+ }
+ DeclsInPrototypeScope.push_back(New);
+ }
+
if (Invalid)
New->setInvalidDecl();
if (Attr)
ProcessDeclAttributeList(S, New, Attr);
- // If we're declaring or defining a tag in function prototype scope in C,
- // note that this type can only be used within the function and add it to
- // the list of decls to inject into the function definition scope.
- if (!getLangOpts().CPlusPlus && (Name || Kind == TTK_Enum) &&
- getNonFieldDeclScope(S)->isFunctionPrototypeScope()) {
- Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
- DeclsInPrototypeScope.push_back(New);
- }
-
// Set the lexical context. If the tag has a C++ scope specifier, the
// lexical context will be different from the semantic context.
New->setLexicalDeclContext(CurContext);
@@ -11448,13 +11655,13 @@
// If the bit-width is type- or value-dependent, don't try to check
// it now.
if (BitWidth->isValueDependent() || BitWidth->isTypeDependent())
- return Owned(BitWidth);
+ return BitWidth;
llvm::APSInt Value;
ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value);
if (ICE.isInvalid())
return ICE;
- BitWidth = ICE.take();
+ BitWidth = ICE.get();
if (Value != 0 && ZeroWidth)
*ZeroWidth = false;
@@ -11495,7 +11702,7 @@
}
}
- return Owned(BitWidth);
+ return BitWidth;
}
/// ActOnField - Each field of a C struct/union is passed into this in order
@@ -11694,7 +11901,7 @@
// If this is declared as a bit-field, check the bit-field.
if (!InvalidDecl && BitWidth) {
BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth,
- &ZeroWidth).take();
+ &ZeroWidth).get();
if (!BitWidth) {
InvalidDecl = true;
BitWidth = nullptr;
@@ -11882,7 +12089,7 @@
if (BitWidth) {
// 6.7.2.1p3, 6.7.2.1p4
- BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).take();
+ BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get();
if (!BitWidth)
D.setInvalidType();
} else {
@@ -12483,7 +12690,7 @@
Val = nullptr;
if (Val)
- Val = DefaultLvalueConversion(Val).take();
+ Val = DefaultLvalueConversion(Val).get();
if (Val) {
if (Enum->isDependentType() || Val->isTypeDependent())
@@ -12502,10 +12709,10 @@
if (Converted.isInvalid())
Val = nullptr;
else
- Val = Converted.take();
+ Val = Converted.get();
} else if (!Val->isValueDependent() &&
!(Val = VerifyIntegerConstantExpression(Val,
- &EnumVal).take())) {
+ &EnumVal).get())) {
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
} else {
if (Enum->isFixed()) {
@@ -12518,11 +12725,11 @@
if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
if (getLangOpts().MSVCCompat) {
Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
- Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+ Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
} else
Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
} else
- Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
+ Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get();
} else if (getLangOpts().CPlusPlus) {
// C++11 [dcl.enum]p5:
// If the underlying type is not fixed, the type of each enumerator
@@ -12543,7 +12750,7 @@
<< (EnumVal.isUnsigned() || EnumVal.isNonNegative());
else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
// Force the type of the expression to 'int'.
- Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take();
+ Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).get();
}
EltTy = Val->getType();
}
@@ -12778,9 +12985,7 @@
static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
EnumDecl *Enum,
QualType EnumType) {
- if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values,
- Enum->getLocation()) ==
- DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation()))
return;
// Avoid anonymous enums
if (!Enum->getIdentifier())
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 6a85c38..31beb0b 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -85,7 +85,7 @@
if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
return BD->getParamDecl(Idx)->getType();
- return cast<ObjCMethodDecl>(D)->param_begin()[Idx]->getType();
+ return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
}
static QualType getFunctionOrMethodResultType(const Decl *D) {
@@ -751,7 +751,7 @@
ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
if (Converted.isInvalid())
return;
- Cond = Converted.take();
+ Cond = Converted.get();
}
StringRef Msg;
@@ -2797,7 +2797,7 @@
}
AlignedAttr *AA = ::new (Context) AlignedAttr(AttrRange, Context, true,
- ICE.take(), SpellingListIndex);
+ ICE.get(), SpellingListIndex);
AA->setPackExpansion(IsPackExpansion);
D->addAttr(AA);
}
@@ -3039,16 +3039,11 @@
static void handleGlobalAttr(Sema &S, Decl *D, const AttributeList &Attr) {
FunctionDecl *FD = cast<FunctionDecl>(D);
if (!FD->getReturnType()->isVoidType()) {
- TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
- if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
- S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
+ SourceRange RTRange = FD->getReturnTypeSourceRange();
+ S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
<< FD->getType()
- << FixItHint::CreateReplacement(FTL.getReturnLoc().getSourceRange(),
- "void");
- } else {
- S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
- << FD->getType();
- }
+ << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
+ : FixItHint());
return;
}
@@ -3358,6 +3353,11 @@
// Checker-specific attribute handlers.
//===----------------------------------------------------------------------===//
+static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType type) {
+ return type->isDependentType() ||
+ type->isObjCRetainableType();
+}
+
static bool isValidSubjectOfNSAttribute(Sema &S, QualType type) {
return type->isDependentType() ||
type->isObjCObjectPointerType() ||
@@ -3422,8 +3422,12 @@
bool cf;
switch (Attr.getKind()) {
default: llvm_unreachable("invalid ownership attribute");
- case AttributeList::AT_NSReturnsAutoreleased:
case AttributeList::AT_NSReturnsRetained:
+ typeOK = isValidSubjectOfNSReturnsRetainedAttribute(returnType);
+ cf = false;
+ break;
+
+ case AttributeList::AT_NSReturnsAutoreleased:
case AttributeList::AT_NSReturnsNotRetained:
typeOK = isValidSubjectOfNSAttribute(S, returnType);
cf = false;
@@ -3845,13 +3849,6 @@
return ::new (Context) DLLImportAttr(Range, Context, AttrSpellingListIndex);
}
-static void handleDLLImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- unsigned Index = Attr.getAttributeSpellingListIndex();
- DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
- if (NewAttr)
- D->addAttr(NewAttr);
-}
-
DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
unsigned AttrSpellingListIndex) {
if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
@@ -3865,9 +3862,18 @@
return ::new (Context) DLLExportAttr(Range, Context, AttrSpellingListIndex);
}
-static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- unsigned Index = Attr.getAttributeSpellingListIndex();
- DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
+static void handleDLLAttr(Sema &S, Decl *D, const AttributeList &A) {
+ if (isa<ClassTemplatePartialSpecializationDecl>(D) &&
+ S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored)
+ << A.getName();
+ return;
+ }
+
+ unsigned Index = A.getAttributeSpellingListIndex();
+ Attr *NewAttr = A.getKind() == AttributeList::AT_DLLExport
+ ? (Attr *)S.mergeDLLExportAttr(D, A.getRange(), Index)
+ : (Attr *)S.mergeDLLImportAttr(D, A.getRange(), Index);
if (NewAttr)
D->addAttr(NewAttr);
}
@@ -4071,10 +4077,8 @@
handleX86ForceAlignArgPointerAttr(S, D, Attr);
break;
case AttributeList::AT_DLLExport:
- handleDLLExportAttr(S, D, Attr);
- break;
case AttributeList::AT_DLLImport:
- handleDLLImportAttr(S, D, Attr);
+ handleDLLAttr(S, D, Attr);
break;
case AttributeList::AT_Mips16:
handleSimpleAttribute<Mips16Attr>(S, D, Attr);
@@ -4854,7 +4858,8 @@
StringRef Message,
SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty) {
+ const ObjCPropertyDecl *ObjCProperty,
+ bool ObjCPropertyAccess) {
// Diagnostics for deprecated or unavailable.
unsigned diag, diag_message, diag_fwdclass_message;
@@ -4870,7 +4875,8 @@
case DelayedDiagnostic::Deprecation:
if (isDeclDeprecated(Ctx))
return;
- diag = diag::warn_deprecated;
+ diag = !ObjCPropertyAccess ? diag::warn_deprecated
+ : diag::warn_property_method_deprecated;
diag_message = diag::warn_deprecated_message;
diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
property_note_select = /* deprecated */ 0;
@@ -4880,7 +4886,8 @@
case DelayedDiagnostic::Unavailable:
if (isDeclUnavailable(Ctx))
return;
- diag = diag::err_unavailable;
+ diag = !ObjCPropertyAccess ? diag::err_unavailable
+ : diag::err_property_method_unavailable;
diag_message = diag::err_unavailable_message;
diag_fwdclass_message = diag::warn_unavailable_fwdclass_message;
property_note_select = /* unavailable */ 1;
@@ -4921,20 +4928,22 @@
DD.getDeprecationMessage(),
DD.Loc,
DD.getUnknownObjCClass(),
- DD.getObjCProperty());
+ DD.getObjCProperty(), false);
}
void Sema::EmitAvailabilityWarning(AvailabilityDiagnostic AD,
NamedDecl *D, StringRef Message,
SourceLocation Loc,
const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty) {
+ const ObjCPropertyDecl *ObjCProperty,
+ bool ObjCPropertyAccess) {
// Delay if we're currently parsing a declaration.
if (DelayedDiagnostics.shouldDelayDiagnostics()) {
DelayedDiagnostics.add(DelayedDiagnostic::makeAvailability(AD, Loc, D,
UnknownObjCClass,
ObjCProperty,
- Message));
+ Message,
+ ObjCPropertyAccess));
return;
}
@@ -4950,5 +4959,5 @@
}
DoEmitAvailabilityWarning(*this, K, Ctx, D, Message, Loc,
- UnknownObjCClass, ObjCProperty);
+ UnknownObjCClass, ObjCProperty, ObjCPropertyAccess);
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 2f9f982..99eedf3 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -268,7 +268,7 @@
ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Arg);
if (Result.isInvalid())
return true;
- Arg = Result.takeAs<Expr>();
+ Arg = Result.getAs<Expr>();
CheckCompletedExpr(Arg, EqualLoc);
Arg = MaybeCreateExprWithCleanups(Arg);
@@ -1296,6 +1296,57 @@
return false;
}
+/// \brief Perform propagation of DLL attributes from a derived class to a
+/// templated base class for MS compatibility.
+static void propagateDLLAttrToBaseClassTemplate(
+ Sema &S, CXXRecordDecl *Class, Attr *ClassAttr,
+ ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc) {
+ if (getDLLAttr(
+ BaseTemplateSpec->getSpecializedTemplate()->getTemplatedDecl())) {
+ // If the base class template has a DLL attribute, don't try to change it.
+ return;
+ }
+
+ if (BaseTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
+ // If the base class is not already specialized, we can do the propagation.
+ auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+ NewAttr->setInherited(true);
+ BaseTemplateSpec->addAttr(NewAttr);
+ return;
+ }
+
+ bool DifferentAttribute = false;
+ if (Attr *SpecializationAttr = getDLLAttr(BaseTemplateSpec)) {
+ if (!SpecializationAttr->isInherited()) {
+ // The template has previously been specialized or instantiated with an
+ // explicit attribute. We should not try to change it.
+ return;
+ }
+ if (SpecializationAttr->getKind() == ClassAttr->getKind()) {
+ // The specialization already has the right attribute.
+ return;
+ }
+ DifferentAttribute = true;
+ }
+
+ // The template was previously instantiated or explicitly specialized without
+ // a dll attribute, or the template was previously instantiated with a
+ // different inherited attribute. It's too late for us to change the
+ // attribute, so warn that this is unsupported.
+ S.Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class)
+ << BaseTemplateSpec->isExplicitSpecialization() << DifferentAttribute;
+ S.Diag(ClassAttr->getLocation(), diag::note_attribute);
+ if (BaseTemplateSpec->isExplicitSpecialization()) {
+ S.Diag(BaseTemplateSpec->getLocation(),
+ diag::note_template_class_explicit_specialization_was_here)
+ << BaseTemplateSpec;
+ } else {
+ S.Diag(BaseTemplateSpec->getPointOfInstantiation(),
+ diag::note_template_class_instantiation_was_here)
+ << BaseTemplateSpec;
+ }
+}
+
/// \brief Check the validity of a C++ base class specifier.
///
/// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics
@@ -1362,6 +1413,17 @@
return nullptr;
}
+ // For the MS ABI, propagate DLL attributes to base class templates.
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ if (Attr *ClassAttr = getDLLAttr(Class)) {
+ if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
+ BaseType->getAsCXXRecordDecl())) {
+ propagateDLLAttrToBaseClassTemplate(*this, Class, ClassAttr,
+ BaseTemplate, BaseLoc);
+ }
+ }
+ }
+
// C++ [class.derived]p2:
// The class-name in a base-specifier shall not be an incompletely
// defined class.
@@ -1398,8 +1460,8 @@
Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
<< CXXBaseDecl->getDeclName()
<< FA->isSpelledAsSealed();
- Diag(CXXBaseDecl->getLocation(), diag::note_previous_decl)
- << CXXBaseDecl->getDeclName();
+ Diag(CXXBaseDecl->getLocation(), diag::note_entity_declared_at)
+ << CXXBaseDecl->getDeclName() << FA->getRange();
return nullptr;
}
@@ -1431,6 +1493,9 @@
if (!Class)
return true;
+ // We haven't yet attached the base specifiers.
+ Class->setIsParsingBaseSpecifiers();
+
// We do not support any C++11 attributes on base-specifiers yet.
// Diagnose any attributes we see.
if (!Attributes.empty()) {
@@ -2116,9 +2181,7 @@
FieldDecl *FD = cast<FieldDecl>(Member);
FieldCollector->Add(FD);
- if (Diags.getDiagnosticLevel(diag::warn_unused_private_field,
- FD->getLocation())
- != DiagnosticsEngine::Ignored) {
+ if (!Diags.isIgnored(diag::warn_unused_private_field, FD->getLocation())) {
// Remember all explicit private FieldDecls that have a name, no side
// effects and are not part of a dependent type declaration.
if (!FD->isImplicit() && FD->getDeclName() &&
@@ -2306,9 +2369,8 @@
static void DiagnoseUninitializedFields(
Sema &SemaRef, const CXXConstructorDecl *Constructor) {
- if (SemaRef.getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit,
- Constructor->getLocation())
- == DiagnosticsEngine::Ignored) {
+ if (SemaRef.getDiagnostics().isIgnored(diag::warn_field_is_uninit,
+ Constructor->getLocation())) {
return;
}
@@ -2392,13 +2454,13 @@
// C++11 [class.base.init]p7:
// The initialization of each base and member constitutes a
// full-expression.
- Init = ActOnFinishFullExpr(Init.take(), InitLoc);
+ Init = ActOnFinishFullExpr(Init.get(), InitLoc);
if (Init.isInvalid()) {
FD->setInvalidDecl();
return;
}
- InitExpr = Init.release();
+ InitExpr = Init.get();
FD->setInClassInitializer(InitExpr);
}
@@ -2833,10 +2895,10 @@
// initializer. However, deconstructing the ASTs is a dicey process,
// and this approach is far more likely to get the corner cases right.
if (CurContext->isDependentContext())
- DelegationInit = Owned(Init);
+ DelegationInit = Init;
return new (Context) CXXCtorInitializer(Context, TInfo, InitRange.getBegin(),
- DelegationInit.takeAs<Expr>(),
+ DelegationInit.getAs<Expr>(),
InitRange.getEnd());
}
@@ -2962,12 +3024,12 @@
// initializer. However, deconstructing the ASTs is a dicey process,
// and this approach is far more likely to get the corner cases right.
if (CurContext->isDependentContext())
- BaseInit = Owned(Init);
+ BaseInit = Init;
return new (Context) CXXCtorInitializer(Context, BaseTInfo,
BaseSpec->isVirtual(),
InitRange.getBegin(),
- BaseInit.takeAs<Expr>(),
+ BaseInit.getAs<Expr>(),
InitRange.getEnd(), EllipsisLoc);
}
@@ -2982,7 +3044,7 @@
return SemaRef.BuildCXXNamedCast(ExprLoc, tok::kw_static_cast, TargetLoc, E,
SourceRange(ExprLoc, ExprLoc),
- E->getSourceRange()).take();
+ E->getSourceRange()).get();
}
/// ImplicitInitializerKind - How an implicit base or member initializer should
@@ -3024,7 +3086,7 @@
VK_LValue, SourceLocation());
if (ArgExpr.isInvalid())
return true;
- Args.push_back(CastForMoving(SemaRef, ArgExpr.take(), PD->getType()));
+ Args.push_back(CastForMoving(SemaRef, ArgExpr.get(), PD->getType()));
}
InitializationKind InitKind = InitializationKind::CreateDirect(
@@ -3071,7 +3133,7 @@
CopyCtorArg = SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
CK_UncheckedDerivedToBase,
Moving ? VK_XValue : VK_LValue,
- &BasePath).take();
+ &BasePath).get();
InitializationKind InitKind
= InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -3092,7 +3154,7 @@
SourceLocation()),
BaseSpec->isVirtual(),
SourceLocation(),
- BaseInit.takeAs<Expr>(),
+ BaseInit.getAs<Expr>(),
SourceLocation(),
SourceLocation());
@@ -3157,7 +3219,7 @@
// - if a member m has rvalue reference type T&&, it is direct-initialized
// with static_cast<T&&>(x.m);
if (RefersToRValueRef(CtorArg.get())) {
- CtorArg = CastForMoving(SemaRef, CtorArg.take());
+ CtorArg = CastForMoving(SemaRef, CtorArg.get());
}
// When the field we are copying is an array, create index variables for
@@ -3191,13 +3253,13 @@
= SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
assert(!IterationVarRef.isInvalid() &&
"Reference to invented variable cannot fail!");
- IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.take());
+ IterationVarRef = SemaRef.DefaultLvalueConversion(IterationVarRef.get());
assert(!IterationVarRef.isInvalid() &&
"Conversion of invented variable cannot fail!");
// Subscript the array with this iteration variable.
- CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.take(), Loc,
- IterationVarRef.take(),
+ CtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CtorArg.get(), Loc,
+ IterationVarRef.get(),
Loc);
if (CtorArg.isInvalid())
return true;
@@ -3207,7 +3269,7 @@
// The array subscript expression is an lvalue, which is wrong for moving.
if (Moving && InitializingArray)
- CtorArg = CastForMoving(SemaRef, CtorArg.take());
+ CtorArg = CastForMoving(SemaRef, CtorArg.get());
// Construct the entity that we will be initializing. For an array, this
// will be first element in the array, which may require several levels
@@ -3227,7 +3289,7 @@
InitializationKind InitKind =
InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation());
- Expr *CtorArgE = CtorArg.takeAs<Expr>();
+ Expr *CtorArgE = CtorArg.getAs<Expr>();
InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, CtorArgE);
ExprResult MemberInit
@@ -3243,11 +3305,11 @@
CXXMemberInit
= new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Indirect,
Loc, Loc,
- MemberInit.takeAs<Expr>(),
+ MemberInit.getAs<Expr>(),
Loc);
} else
CXXMemberInit = CXXCtorInitializer::Create(SemaRef.Context, Field, Loc,
- Loc, MemberInit.takeAs<Expr>(),
+ Loc, MemberInit.getAs<Expr>(),
Loc,
IndexVariables.data(),
IndexVariables.size());
@@ -3731,9 +3793,8 @@
bool ShouldCheckOrder = false;
for (unsigned InitIndex = 0; InitIndex != Inits.size(); ++InitIndex) {
CXXCtorInitializer *Init = Inits[InitIndex];
- if (SemaRef.Diags.getDiagnosticLevel(diag::warn_initializer_out_of_order,
- Init->getSourceLocation())
- != DiagnosticsEngine::Ignored) {
+ if (!SemaRef.Diags.isIgnored(diag::warn_initializer_out_of_order,
+ Init->getSourceLocation())) {
ShouldCheckOrder = true;
break;
}
@@ -4348,6 +4409,77 @@
}
}
+/// \brief Check class-level dllimport/dllexport attribute.
+static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
+ Attr *ClassAttr = getDLLAttr(Class);
+ if (!ClassAttr)
+ return;
+
+ bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
+
+ // Force declaration of implicit members so they can inherit the attribute.
+ S.ForceDeclarationOfImplicitMembers(Class);
+
+ // FIXME: MSVC's docs say all bases must be exportable, but this doesn't
+ // seem to be true in practice?
+
+ for (Decl *Member : Class->decls()) {
+ VarDecl *VD = dyn_cast<VarDecl>(Member);
+ CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
+
+ // Only methods and static fields inherit the attributes.
+ if (!VD && !MD)
+ continue;
+
+ // Don't process deleted methods.
+ if (MD && MD->isDeleted())
+ continue;
+
+ if (MD && MD->isMoveAssignmentOperator() && !ClassExported &&
+ MD->isInlined()) {
+ // Current MSVC versions don't export the move assignment operators, so
+ // don't attempt to import them if we have a definition.
+ continue;
+ }
+
+ if (InheritableAttr *MemberAttr = getDLLAttr(Member)) {
+ if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ !MemberAttr->isInherited() && !ClassAttr->isInherited()) {
+ S.Diag(MemberAttr->getLocation(),
+ diag::err_attribute_dll_member_of_dll_class)
+ << MemberAttr << ClassAttr;
+ S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute);
+ Member->setInvalidDecl();
+ continue;
+ }
+ } else {
+ auto *NewAttr =
+ cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+ NewAttr->setInherited(true);
+ Member->addAttr(NewAttr);
+ }
+
+ if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
+ if (ClassExported) {
+ if (MD->isUserProvided()) {
+ // Instantiate non-default methods.
+ S.MarkFunctionReferenced(Class->getLocation(), MD);
+ } else if (!MD->isTrivial() || MD->isExplicitlyDefaulted() ||
+ MD->isCopyAssignmentOperator() ||
+ MD->isMoveAssignmentOperator()) {
+ // Instantiate non-trivial or explicitly defaulted methods, and the
+ // copy assignment / move assignment operators.
+ S.MarkFunctionReferenced(Class->getLocation(), MD);
+ // Resolve its exception specification; CodeGen needs it.
+ auto *FPT = MD->getType()->getAs<FunctionProtoType>();
+ S.ResolveExceptionSpec(Class->getLocation(), FPT);
+ S.ActOnFinishInlineMethodDef(MD);
+ }
+ }
+ }
+ }
+}
+
/// \brief Perform semantic checks on a class definition that has been
/// completing, introducing implicitly-declared members, checking for
/// abstract types, etc.
@@ -4512,6 +4644,8 @@
// instantiated (e.g. meta-functions). This doesn't apply to classes that
// have inheriting constructors.
DeclareInheritingConstructors(Record);
+
+ checkDLLAttribute(*this, Record);
}
/// Look up the special member function that would be called by a special
@@ -5881,8 +6015,7 @@
if (MD->isInvalidDecl())
return;
- if (Diags.getDiagnosticLevel(diag::warn_overloaded_virtual,
- MD->getLocation()) == DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_overloaded_virtual, MD->getLocation()))
return;
SmallVector<CXXMethodDecl *, 8> OverloadedMethods;
@@ -6146,6 +6279,15 @@
SC = SC_None;
}
+ if (unsigned TypeQuals = D.getDeclSpec().getTypeQualifiers()) {
+ diagnoseIgnoredQualifiers(
+ diag::err_constructor_return_type, TypeQuals, SourceLocation(),
+ D.getDeclSpec().getConstSpecLoc(), D.getDeclSpec().getVolatileSpecLoc(),
+ D.getDeclSpec().getRestrictSpecLoc(),
+ D.getDeclSpec().getAtomicSpecLoc());
+ D.setInvalidType();
+ }
+
DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
if (FTI.TypeQuals != 0) {
if (FTI.TypeQuals & Qualifiers::Const)
@@ -6293,7 +6435,7 @@
SC = SC_None;
}
- if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
+ if (!D.isInvalidType()) {
// Destructors don't have return types, but the parser will
// happily parse something like:
//
@@ -6302,9 +6444,19 @@
// };
//
// The return type will be eliminated later.
- Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
- << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
- << SourceRange(D.getIdentifierLoc());
+ if (D.getDeclSpec().hasTypeSpecifier())
+ Diag(D.getIdentifierLoc(), diag::err_destructor_return_type)
+ << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+ << SourceRange(D.getIdentifierLoc());
+ else if (unsigned TypeQuals = D.getDeclSpec().getTypeQualifiers()) {
+ diagnoseIgnoredQualifiers(diag::err_destructor_return_type, TypeQuals,
+ SourceLocation(),
+ D.getDeclSpec().getConstSpecLoc(),
+ D.getDeclSpec().getVolatileSpecLoc(),
+ D.getDeclSpec().getRestrictSpecLoc(),
+ D.getDeclSpec().getAtomicSpecLoc());
+ D.setInvalidType();
+ }
}
DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
@@ -8333,7 +8485,9 @@
return;
}
- SourceLocation Loc = Constructor->getLocation();
+ SourceLocation Loc = Constructor->getLocEnd().isValid()
+ ? Constructor->getLocEnd()
+ : Constructor->getLocation();
Constructor->setBody(new (Context) CompoundStmt(Loc));
Constructor->markUsed(Context);
@@ -8795,7 +8949,9 @@
return;
}
- SourceLocation Loc = Destructor->getLocation();
+ SourceLocation Loc = Destructor->getLocEnd().isValid()
+ ? Destructor->getLocEnd()
+ : Destructor->getLocation();
Destructor->setBody(new (Context) CompoundStmt(Loc));
Destructor->markUsed(Context);
MarkVTableUsed(CurrentLocation, ClassDecl);
@@ -8874,7 +9030,7 @@
public:
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
- return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).take());
+ return assertNotNull(S.BuildDeclRefExpr(Var, VarType, VK_LValue, Loc).get());
}
RefBuilder(VarDecl *Var, QualType VarType)
@@ -8884,7 +9040,7 @@
class ThisBuilder: public ExprBuilder {
public:
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
- return assertNotNull(S.ActOnCXXThis(Loc).takeAs<Expr>());
+ return assertNotNull(S.ActOnCXXThis(Loc).getAs<Expr>());
}
};
@@ -8898,7 +9054,7 @@
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
return assertNotNull(S.ImpCastExprToType(Builder.build(S, Loc), Type,
CK_UncheckedDerivedToBase, Kind,
- &Path).take());
+ &Path).get());
}
CastBuilder(const ExprBuilder &Builder, QualType Type, ExprValueKind Kind,
@@ -8912,7 +9068,7 @@
public:
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
return assertNotNull(
- S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).take());
+ S.CreateBuiltinUnaryOp(Loc, UO_Deref, Builder.build(S, Loc)).get());
}
DerefBuilder(const ExprBuilder &Builder) : Builder(Builder) {}
@@ -8929,7 +9085,7 @@
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
return assertNotNull(S.BuildMemberReferenceExpr(
Builder.build(S, Loc), Type, Loc, IsArrow, SS, SourceLocation(),
- nullptr, MemberLookup, nullptr).take());
+ nullptr, MemberLookup, nullptr).get());
}
MemberBuilder(const ExprBuilder &Builder, QualType Type, bool IsArrow,
@@ -8955,7 +9111,7 @@
public:
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
return assertNotNull(
- S.DefaultLvalueConversion(Builder.build(S, Loc)).take());
+ S.DefaultLvalueConversion(Builder.build(S, Loc)).get());
}
LvalueConvBuilder(const ExprBuilder &Builder) : Builder(Builder) {}
@@ -8968,7 +9124,7 @@
public:
virtual Expr *build(Sema &S, SourceLocation Loc) const override {
return assertNotNull(S.CreateBuiltinArraySubscriptExpr(
- Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).take());
+ Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).get());
}
SubscriptBuilder(const ExprBuilder &Base, const ExprBuilder &Index)
@@ -9026,11 +9182,11 @@
Expr *CallArgs[] = {
To, From, IntegerLiteral::Create(S.Context, Size, SizeType, Loc)
};
- ExprResult Call = S.ActOnCallExpr(/*Scope=*/nullptr, MemCpyRef.take(),
+ ExprResult Call = S.ActOnCallExpr(/*Scope=*/nullptr, MemCpyRef.get(),
Loc, CallArgs, Loc);
assert(!Call.isInvalid() && "Call to __builtin_memcpy cannot fail!");
- return S.Owned(Call.takeAs<Stmt>());
+ return Call.getAs<Stmt>();
}
/// \brief Builds a statement that copies/moves the given entity from \p From to
@@ -9148,7 +9304,7 @@
Expr *FromInst = From.build(S, Loc);
ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/nullptr,
- OpEqualRef.takeAs<Expr>(),
+ OpEqualRef.getAs<Expr>(),
Loc, FromInst, Loc);
if (Call.isInvalid())
return StmtError();
@@ -9247,7 +9403,7 @@
return S.ActOnForStmt(Loc, Loc, InitStmt,
S.MakeFullExpr(Comparison),
nullptr, S.MakeFullDiscardedValueExpr(Increment),
- Loc, Copy.take());
+ Loc, Copy.get());
}
static StmtResult
@@ -9495,8 +9651,10 @@
}
// Our location for everything implicitly-generated.
- SourceLocation Loc = CopyAssignOperator->getLocation();
-
+ SourceLocation Loc = CopyAssignOperator->getLocEnd().isValid()
+ ? CopyAssignOperator->getLocEnd()
+ : CopyAssignOperator->getLocation();
+
// Builds a DeclRefExpr for the "other" object.
RefBuilder OtherRef(Other, OtherRefType);
@@ -9542,7 +9700,7 @@
}
// Success! Record the copy.
- Statements.push_back(Copy.takeAs<Expr>());
+ Statements.push_back(Copy.getAs<Expr>());
}
// Assign non-static members.
@@ -9613,7 +9771,7 @@
}
// Success! Record the copy.
- Statements.push_back(Copy.takeAs<Stmt>());
+ Statements.push_back(Copy.getAs<Stmt>());
}
if (!Invalid) {
@@ -9624,7 +9782,7 @@
if (Return.isInvalid())
Invalid = true;
else {
- Statements.push_back(Return.takeAs<Stmt>());
+ Statements.push_back(Return.getAs<Stmt>());
if (Trap.hasErrorOccurred()) {
Diag(CurrentLocation, diag::note_member_synthesized_at)
@@ -9646,7 +9804,7 @@
/*isStmtExpr=*/false);
assert(!Body.isInvalid() && "Compound statement creation cannot fail");
}
- CopyAssignOperator->setBody(Body.takeAs<Stmt>());
+ CopyAssignOperator->setBody(Body.getAs<Stmt>());
if (ASTMutationListener *L = getASTMutationListener()) {
L->CompletedImplicitDefinition(CopyAssignOperator);
@@ -9900,7 +10058,9 @@
"Bad argument type of defaulted move assignment");
// Our location for everything implicitly-generated.
- SourceLocation Loc = MoveAssignOperator->getLocation();
+ SourceLocation Loc = MoveAssignOperator->getLocEnd().isValid()
+ ? MoveAssignOperator->getLocEnd()
+ : MoveAssignOperator->getLocation();
// Builds a reference to the "other" object.
RefBuilder OtherRef(Other, OtherRefType);
@@ -9958,7 +10118,7 @@
}
// Success! Record the move.
- Statements.push_back(Move.takeAs<Expr>());
+ Statements.push_back(Move.getAs<Expr>());
}
// Assign non-static members.
@@ -10032,18 +10192,19 @@
}
// Success! Record the copy.
- Statements.push_back(Move.takeAs<Stmt>());
+ Statements.push_back(Move.getAs<Stmt>());
}
if (!Invalid) {
// Add a "return *this;"
- ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
-
+ ExprResult ThisObj =
+ CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
+
StmtResult Return = BuildReturnStmt(Loc, ThisObj.get());
if (Return.isInvalid())
Invalid = true;
else {
- Statements.push_back(Return.takeAs<Stmt>());
+ Statements.push_back(Return.getAs<Stmt>());
if (Trap.hasErrorOccurred()) {
Diag(CurrentLocation, diag::note_member_synthesized_at)
@@ -10065,7 +10226,7 @@
/*isStmtExpr=*/false);
assert(!Body.isInvalid() && "Compound statement creation cannot fail");
}
- MoveAssignOperator->setBody(Body.takeAs<Stmt>());
+ MoveAssignOperator->setBody(Body.getAs<Stmt>());
if (ASTMutationListener *L = getASTMutationListener()) {
L->CompletedImplicitDefinition(MoveAssignOperator);
@@ -10214,10 +10375,12 @@
<< CXXCopyConstructor << Context.getTagDeclType(ClassDecl);
CopyConstructor->setInvalidDecl();
} else {
+ SourceLocation Loc = CopyConstructor->getLocEnd().isValid()
+ ? CopyConstructor->getLocEnd()
+ : CopyConstructor->getLocation();
Sema::CompoundScopeRAII CompoundScope(*this);
- CopyConstructor->setBody(ActOnCompoundStmt(
- CopyConstructor->getLocation(), CopyConstructor->getLocation(), None,
- /*isStmtExpr=*/ false).takeAs<Stmt>());
+ CopyConstructor->setBody(
+ ActOnCompoundStmt(Loc, Loc, None, /*isStmtExpr=*/false).getAs<Stmt>());
}
CopyConstructor->markUsed(Context);
@@ -10370,10 +10533,12 @@
<< CXXMoveConstructor << Context.getTagDeclType(ClassDecl);
MoveConstructor->setInvalidDecl();
} else {
+ SourceLocation Loc = MoveConstructor->getLocEnd().isValid()
+ ? MoveConstructor->getLocEnd()
+ : MoveConstructor->getLocation();
Sema::CompoundScopeRAII CompoundScope(*this);
MoveConstructor->setBody(ActOnCompoundStmt(
- MoveConstructor->getLocation(), MoveConstructor->getLocation(), None,
- /*isStmtExpr=*/ false).takeAs<Stmt>());
+ Loc, Loc, None, /*isStmtExpr=*/ false).getAs<Stmt>());
}
MoveConstructor->markUsed(Context);
@@ -10406,8 +10571,7 @@
DeducedTemplateArgs = Conv->getTemplateSpecializationArgs();
void *InsertPos = nullptr;
FunctionDecl *CallOpSpec = CallOpTemplate->findSpecialization(
- DeducedTemplateArgs->data(),
- DeducedTemplateArgs->size(),
+ DeducedTemplateArgs->asArray(),
InsertPos);
assert(CallOpSpec &&
"Conversion operator must have a corresponding call operator");
@@ -10433,8 +10597,7 @@
Invoker->getDescribedFunctionTemplate();
void *InsertPos = nullptr;
FunctionDecl *InvokeSpec = InvokeTemplate->findSpecialization(
- DeducedTemplateArgs->data(),
- DeducedTemplateArgs->size(),
+ DeducedTemplateArgs->asArray(),
InsertPos);
assert(InvokeSpec &&
"Must have a corresponding static invoker specialization");
@@ -10442,9 +10605,9 @@
}
// Construct the body of the conversion function { return __invoke; }.
Expr *FunctionRef = BuildDeclRefExpr(Invoker, Invoker->getType(),
- VK_LValue, Conv->getLocation()).take();
+ VK_LValue, Conv->getLocation()).get();
assert(FunctionRef && "Can't refer to __invoke function?");
- Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).take();
+ Stmt *Return = BuildReturnStmt(Conv->getLocation(), FunctionRef).get();
Conv->setBody(new (Context) CompoundStmt(Context, Return,
Conv->getLocation(),
Conv->getLocation()));
@@ -10478,8 +10641,8 @@
DiagnosticErrorTrap Trap(Diags);
// Copy-initialize the lambda object as needed to capture it.
- Expr *This = ActOnCXXThis(CurrentLocation).take();
- Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take();
+ Expr *This = ActOnCXXThis(CurrentLocation).get();
+ Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).get();
ExprResult BuildBlock = BuildBlockForLambdaConversion(CurrentLocation,
Conv->getLocation(),
@@ -10510,7 +10673,7 @@
}
// Set the body of the conversion function.
- Stmt *ReturnS = Return.take();
+ Stmt *ReturnS = Return.get();
Conv->setBody(new (Context) CompoundStmt(Context, ReturnS,
Conv->getLocation(),
Conv->getLocation()));
@@ -10585,12 +10748,11 @@
unsigned ConstructKind,
SourceRange ParenRange) {
MarkFunctionReferenced(ConstructLoc, Constructor);
- return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
- Constructor, Elidable, ExprArgs,
- HadMultipleCandidates,
- IsListInitialization, RequiresZeroInit,
- static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
- ParenRange));
+ return CXXConstructExpr::Create(
+ Context, DeclInitType, ConstructLoc, Constructor, Elidable, ExprArgs,
+ HadMultipleCandidates, IsListInitialization, RequiresZeroInit,
+ static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
+ ParenRange);
}
void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
@@ -11242,7 +11404,7 @@
else {
// If the constructor used was non-trivial, set this as the
// "initializer".
- CXXConstructExpr *construct = result.takeAs<CXXConstructExpr>();
+ CXXConstructExpr *construct = result.getAs<CXXConstructExpr>();
if (!construct->getConstructor()->isTrivial()) {
Expr *init = MaybeCreateExprWithCleanups(construct);
ExDecl->setInit(init);
@@ -11279,13 +11441,17 @@
LookupOrdinaryName,
ForRedeclaration)) {
// The scope should be freshly made just for us. There is just no way
- // it contains any previous declaration.
+ // it contains any previous declaration, except for function parameters in
+ // a function-try-block's catch statement.
assert(!S->isDeclScope(PrevDecl));
- if (PrevDecl->isTemplateParameter()) {
+ if (isDeclInScope(PrevDecl, CurContext, S)) {
+ Diag(D.getIdentifierLoc(), diag::err_redefinition)
+ << D.getIdentifier();
+ Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+ Invalid = true;
+ } else if (PrevDecl->isTemplateParameter())
// Maybe we will complain about the shadowed template parameter.
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
- PrevDecl = nullptr;
- }
}
if (D.getCXXScopeSpec().isSet() && !Invalid) {
@@ -11315,7 +11481,8 @@
Expr *AssertExpr,
Expr *AssertMessageExpr,
SourceLocation RParenLoc) {
- StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr);
+ StringLiteral *AssertMessage =
+ AssertMessageExpr ? cast<StringLiteral>(AssertMessageExpr) : nullptr;
if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
return nullptr;
@@ -11329,6 +11496,7 @@
StringLiteral *AssertMessage,
SourceLocation RParenLoc,
bool Failed) {
+ assert(AssertExpr != nullptr && "Expected non-null condition");
if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent() &&
!Failed) {
// In a static_assert-declaration, the constant-expression shall be a
@@ -11346,9 +11514,10 @@
if (!Failed && !Cond) {
SmallString<256> MsgBuffer;
llvm::raw_svector_ostream Msg(MsgBuffer);
- AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
+ if (AssertMessage)
+ AssertMessage->printPretty(Msg, nullptr, getPrintingPolicy());
Diag(StaticAssertLoc, diag::err_static_assert_failed)
- << Msg.str() << AssertExpr->getSourceRange();
+ << !AssertMessage << Msg.str() << AssertExpr->getSourceRange();
Failed = true;
}
}
@@ -11462,7 +11631,7 @@
TemplateParams, AS_public,
/*ModulePrivateLoc=*/SourceLocation(),
TempParamLists.size() - 1,
- TempParamLists.data()).take();
+ TempParamLists.data()).get();
} else {
// The "template<>" header is extraneous.
Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
@@ -11972,6 +12141,12 @@
Fn = Fn->getCanonicalDecl();
}
+ // dllimport/dllexport cannot be deleted.
+ if (const InheritableAttr *DLLAttr = getDLLAttr(Fn)) {
+ Diag(Fn->getLocation(), diag::err_attribute_dll_deleted) << DLLAttr;
+ Fn->setInvalidDecl();
+ }
+
if (Fn->isDeleted())
return;
@@ -12148,8 +12323,10 @@
if (NewClassTy.isNull()) {
Diag(New->getLocation(),
diag::err_different_return_type_for_overriding_virtual_function)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
}
@@ -12169,25 +12346,27 @@
if (!Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
// Check if the new class derives from the old class.
if (!IsDerivedFrom(NewClassTy, OldClassTy)) {
- Diag(New->getLocation(),
- diag::err_covariant_return_not_derived)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ Diag(New->getLocation(), diag::err_covariant_return_not_derived)
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
}
// Check if we the conversion from derived to base is valid.
- if (CheckDerivedToBaseConversion(NewClassTy, OldClassTy,
- diag::err_covariant_return_inaccessible_base,
- diag::err_covariant_return_ambiguous_derived_to_base_conv,
- // FIXME: Should this point to the return type?
- New->getLocation(), SourceRange(), New->getDeclName(),
- nullptr)) {
+ if (CheckDerivedToBaseConversion(
+ NewClassTy, OldClassTy,
+ diag::err_covariant_return_inaccessible_base,
+ diag::err_covariant_return_ambiguous_derived_to_base_conv,
+ New->getLocation(), New->getReturnTypeSourceRange(),
+ New->getDeclName(), nullptr)) {
// FIXME: this note won't trigger for delayed access control
// diagnostics, and it's impossible to get an undelayed error
// here from access control during the original parse because
// the ParsingDeclSpec/ParsingDeclarator are still in scope.
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
}
}
@@ -12196,8 +12375,10 @@
if (NewTy.getLocalCVRQualifiers() != OldTy.getLocalCVRQualifiers()) {
Diag(New->getLocation(),
diag::err_covariant_return_type_different_qualifications)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
};
@@ -12206,8 +12387,10 @@
if (NewClassTy.isMoreQualifiedThan(OldClassTy)) {
Diag(New->getLocation(),
diag::err_covariant_return_type_class_type_more_qualified)
- << New->getDeclName() << NewTy << OldTy;
- Diag(Old->getLocation(), diag::note_overridden_virtual_function);
+ << New->getDeclName() << NewTy << OldTy
+ << New->getReturnTypeSourceRange();
+ Diag(Old->getLocation(), diag::note_overridden_virtual_function)
+ << Old->getReturnTypeSourceRange();
return true;
};
@@ -12364,7 +12547,9 @@
Class->hasUserDeclaredDestructor() &&
!Class->getDestructor()->isDefined() &&
!Class->getDestructor()->isDeleted()) {
- CheckDestructor(Class->getDestructor());
+ CXXDestructorDecl *DD = Class->getDestructor();
+ ContextRAII SavedContext(*this, DD);
+ CheckDestructor(DD);
}
}
@@ -12540,7 +12725,7 @@
Member =
new (Context) CXXCtorInitializer(Context, Field, SourceLocation(),
SourceLocation(),
- MemberInit.takeAs<Expr>(),
+ MemberInit.getAs<Expr>(),
SourceLocation());
AllToInit.push_back(Member);
@@ -12823,7 +13008,7 @@
if (!NoexceptExpr->isValueDependent())
NoexceptExpr = VerifyIntegerConstantExpression(NoexceptExpr, nullptr,
diag::err_noexcept_needs_constant_expression,
- /*AllowFold*/ false).take();
+ /*AllowFold*/ false).get();
EPI.NoexceptExpr = NoexceptExpr;
}
return;
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index fc9fdb1..b5205b3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1770,8 +1770,7 @@
if (C || MethodInClass->isPropertyAccessor())
continue;
unsigned DIAG = diag::warn_unimplemented_protocol_method;
- if (S.Diags.getDiagnosticLevel(DIAG, ImpLoc)
- != DiagnosticsEngine::Ignored) {
+ if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
PDecl);
}
@@ -1794,8 +1793,7 @@
continue;
unsigned DIAG = diag::warn_unimplemented_protocol_method;
- if (S.Diags.getDiagnosticLevel(DIAG, ImpLoc) !=
- DiagnosticsEngine::Ignored) {
+ if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
}
}
@@ -2349,10 +2347,8 @@
// We support a warning which complains about *any* difference in
// method signature.
bool strictSelectorMatch =
- (receiverIdOrClass && warn &&
- (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl,
- R.getBegin())
- != DiagnosticsEngine::Ignored));
+ receiverIdOrClass && warn &&
+ !Diags.isIgnored(diag::warn_strict_multiple_method_decl, R.getBegin());
if (strictSelectorMatch) {
for (unsigned I = 1, N = Methods.size(); I != N; ++I) {
if (!MatchTwoMethodDeclarations(Methods[0], Methods[I], MMS_strict)) {
@@ -3527,7 +3523,7 @@
for (const auto *CurMethod : ImplD->instance_methods()) {
unsigned DIAG = diag::warn_unused_property_backing_ivar;
SourceLocation Loc = CurMethod->getLocation();
- if (Diags.getDiagnosticLevel(DIAG, Loc) == DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(DIAG, Loc))
continue;
const ObjCPropertyDecl *PDecl;
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 24d8222..6eccb9f 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -283,6 +283,7 @@
case EST_ComputedNoexcept:
OS << "noexcept(";
+ assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
OS << ")";
break;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a9f1197..67e839c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -83,9 +83,16 @@
static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S,
NamedDecl *D, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass) {
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ bool ObjCPropertyAccess) {
// See if this declaration is unavailable or deprecated.
std::string Message;
+
+ // Forward class declarations get their attributes from their definition.
+ if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
+ if (IDecl->getDefinition())
+ D = IDecl->getDefinition();
+ }
AvailabilityResult Result = D->getAvailability(&Message);
if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
if (Result == AR_Available) {
@@ -113,13 +120,15 @@
case AR_Deprecated:
if (S.getCurContextAvailability() != AR_Deprecated)
S.EmitAvailabilityWarning(Sema::AD_Deprecation,
- D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+ D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+ ObjCPropertyAccess);
break;
case AR_Unavailable:
if (S.getCurContextAvailability() != AR_Unavailable)
S.EmitAvailabilityWarning(Sema::AD_Unavailable,
- D, Message, Loc, UnknownObjCClass, ObjCPDecl);
+ D, Message, Loc, UnknownObjCClass, ObjCPDecl,
+ ObjCPropertyAccess);
break;
}
@@ -223,9 +232,8 @@
S.MaybeSuggestAddingStaticToDecl(Current);
- S.Diag(D->getCanonicalDecl()->getLocation(),
- diag::note_internal_decl_declared_here)
- << D;
+ S.Diag(D->getCanonicalDecl()->getLocation(), diag::note_entity_declared_at)
+ << D;
}
void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) {
@@ -252,7 +260,8 @@
/// referenced), false otherwise.
///
bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass) {
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ bool ObjCPropertyAccess) {
if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) {
// If there were any diagnostics suppressed by template argument deduction,
// emit them now.
@@ -297,7 +306,7 @@
DeduceReturnType(FD, Loc))
return true;
}
- DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass);
+ DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass, ObjCPropertyAccess);
DiagnoseUnusedOfDecl(*this, D, Loc);
@@ -426,7 +435,7 @@
if (E->getType()->isPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
- E = result.take();
+ E = result.get();
}
QualType Ty = E->getType();
@@ -440,7 +449,7 @@
return ExprError();
}
E = ImpCastExprToType(E, Context.getPointerType(Ty),
- CK_FunctionToPointerDecay).take();
+ CK_FunctionToPointerDecay).get();
} else if (Ty->isArrayType()) {
// In C90 mode, arrays only promote to pointers if the array expression is
// an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -455,9 +464,9 @@
//
if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue())
E = ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
- CK_ArrayToPointerDecay).take();
+ CK_ArrayToPointerDecay).get();
}
- return Owned(E);
+ return E;
}
static void CheckForNullPointerDereference(Sema &S, Expr *E) {
@@ -540,13 +549,13 @@
if (E->getType()->isPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
- E = result.take();
+ E = result.get();
}
// C++ [conv.lval]p1:
// A glvalue of a non-function, non-array type T can be
// converted to a prvalue.
- if (!E->isGLValue()) return Owned(E);
+ if (!E->isGLValue()) return E;
QualType T = E->getType();
assert(!T.isNull() && "r-value conversion on typeless expression?");
@@ -557,7 +566,7 @@
(E->getType() == Context.OverloadTy ||
T->isDependentType() ||
T->isRecordType()))
- return Owned(E);
+ return E;
// The C standard is actually really unclear on this point, and
// DR106 tells us what the result should be but not why. It's
@@ -565,7 +574,7 @@
// lvalue-to-rvalue at all. Note that expressions of unqualified
// 'void' type are never l-values, but qualified void can be.
if (T->isVoidType())
- return Owned(E);
+ return E;
// OpenCL usually rejects direct accesses to values of 'half' type.
if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16 &&
@@ -612,16 +621,16 @@
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
ExprNeedsCleanups = true;
- ExprResult Res = Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue,
- E, nullptr, VK_RValue));
+ ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
+ nullptr, VK_RValue);
// C11 6.3.2.1p2:
// ... if the lvalue has atomic type, the value has the non-atomic version
// of the type of the lvalue ...
if (const AtomicType *Atomic = T->getAs<AtomicType>()) {
T = Atomic->getValueType().getUnqualifiedType();
- Res = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic,
- Res.get(), nullptr, VK_RValue));
+ Res = ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, Res.get(),
+ nullptr, VK_RValue);
}
return Res;
@@ -631,7 +640,7 @@
ExprResult Res = DefaultFunctionArrayConversion(E);
if (Res.isInvalid())
return ExprError();
- Res = DefaultLvalueConversion(Res.take());
+ Res = DefaultLvalueConversion(Res.get());
if (Res.isInvalid())
return ExprError();
return Res;
@@ -646,14 +655,14 @@
// to function type.
if (Ty->isFunctionType()) {
Res = ImpCastExprToType(E, Context.getPointerType(Ty),
- CK_FunctionToPointerDecay).take();
+ CK_FunctionToPointerDecay).get();
if (Res.isInvalid())
return ExprError();
}
- Res = DefaultLvalueConversion(Res.take());
+ Res = DefaultLvalueConversion(Res.get());
if (Res.isInvalid())
return ExprError();
- return Owned(Res.take());
+ return Res.get();
}
/// UsualUnaryConversions - Performs various conversions that are common to most
@@ -666,14 +675,14 @@
ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
if (Res.isInvalid())
return ExprError();
- E = Res.take();
+ E = Res.get();
QualType Ty = E->getType();
assert(!Ty.isNull() && "UsualUnaryConversions - missing type");
// Half FP have to be promoted to float unless it is natively supported
if (Ty->isHalfType() && !getLangOpts().NativeHalfType)
- return ImpCastExprToType(Res.take(), Context.FloatTy, CK_FloatingCast);
+ return ImpCastExprToType(Res.get(), Context.FloatTy, CK_FloatingCast);
// Try to perform integral promotions if the object has a theoretically
// promotable type.
@@ -694,16 +703,16 @@
QualType PTy = Context.isPromotableBitField(E);
if (!PTy.isNull()) {
- E = ImpCastExprToType(E, PTy, CK_IntegralCast).take();
- return Owned(E);
+ E = ImpCastExprToType(E, PTy, CK_IntegralCast).get();
+ return E;
}
if (Ty->isPromotableIntegerType()) {
QualType PT = Context.getPromotedIntegerType(Ty);
- E = ImpCastExprToType(E, PT, CK_IntegralCast).take();
- return Owned(E);
+ E = ImpCastExprToType(E, PT, CK_IntegralCast).get();
+ return E;
}
}
- return Owned(E);
+ return E;
}
/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
@@ -717,14 +726,14 @@
ExprResult Res = UsualUnaryConversions(E);
if (Res.isInvalid())
return ExprError();
- E = Res.take();
+ E = Res.get();
// If this is a 'float' or '__fp16' (CVR qualified or typedef) promote to
// double.
const BuiltinType *BTy = Ty->getAs<BuiltinType>();
if (BTy && (BTy->getKind() == BuiltinType::Half ||
BTy->getKind() == BuiltinType::Float))
- E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).take();
+ E = ImpCastExprToType(E, Context.DoubleTy, CK_FloatingCast).get();
// C++ performs lvalue-to-rvalue conversion as a default argument
// promotion, even on class types, but note:
@@ -740,14 +749,13 @@
if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
ExprResult Temp = PerformCopyInitialization(
InitializedEntity::InitializeTemporary(E->getType()),
- E->getExprLoc(),
- Owned(E));
+ E->getExprLoc(), E);
if (Temp.isInvalid())
return ExprError();
E = Temp.get();
}
- return Owned(E);
+ return E;
}
/// Determine the degree of POD-ness for an expression.
@@ -856,14 +864,14 @@
ExprResult ExprRes = CheckPlaceholderExpr(E);
if (ExprRes.isInvalid())
return ExprError();
- E = ExprRes.take();
+ E = ExprRes.get();
}
}
ExprResult ExprRes = DefaultArgumentPromotion(E);
if (ExprRes.isInvalid())
return ExprError();
- E = ExprRes.take();
+ E = ExprRes.get();
// Diagnostics regarding non-POD argument types are
// emitted along with format string checking in Sema::CheckFunctionCall().
@@ -897,7 +905,7 @@
diag::err_call_incomplete_argument))
return ExprError();
- return Owned(E);
+ return E;
}
/// \brief Converts an integer to complex float type. Helper function of
@@ -914,12 +922,12 @@
if (SkipCast) return false;
if (IntTy->isIntegerType()) {
QualType fpTy = cast<ComplexType>(ComplexTy)->getElementType();
- IntExpr = S.ImpCastExprToType(IntExpr.take(), fpTy, CK_IntegralToFloating);
- IntExpr = S.ImpCastExprToType(IntExpr.take(), ComplexTy,
+ IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
+ IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
CK_FloatingRealToComplex);
} else {
assert(IntTy->isComplexIntegerType());
- IntExpr = S.ImpCastExprToType(IntExpr.take(), ComplexTy,
+ IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
CK_IntegralComplexToFloatingComplex);
}
return false;
@@ -937,12 +945,12 @@
if (order < 0) {
// _Complex float -> _Complex double
if (!IsCompAssign)
- LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_FloatingComplexCast);
+ LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingComplexCast);
return RHSType;
}
if (order > 0)
// _Complex float -> _Complex double
- RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_FloatingComplexCast);
+ RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingComplexCast);
return LHSType;
}
@@ -963,8 +971,8 @@
// float -> _Complex double
if (ConvertOtherExpr) {
QualType fp = cast<ComplexType>(ComplexTy)->getElementType();
- OtherExpr = S.ImpCastExprToType(OtherExpr.take(), fp, CK_FloatingCast);
- OtherExpr = S.ImpCastExprToType(OtherExpr.take(), ComplexTy,
+ OtherExpr = S.ImpCastExprToType(OtherExpr.get(), fp, CK_FloatingCast);
+ OtherExpr = S.ImpCastExprToType(OtherExpr.get(), ComplexTy,
CK_FloatingRealToComplex);
}
return ComplexTy;
@@ -976,12 +984,12 @@
// double -> _Complex double
if (ConvertOtherExpr)
- OtherExpr = S.ImpCastExprToType(OtherExpr.take(), result,
+ OtherExpr = S.ImpCastExprToType(OtherExpr.get(), result,
CK_FloatingRealToComplex);
// _Complex float -> _Complex double
if (ConvertComplexExpr && order < 0)
- ComplexExpr = S.ImpCastExprToType(ComplexExpr.take(), result,
+ ComplexExpr = S.ImpCastExprToType(ComplexExpr.get(), result,
CK_FloatingComplexCast);
return result;
@@ -1043,7 +1051,7 @@
if (IntTy->isIntegerType()) {
if (ConvertInt)
// Convert intExpr to the lhs floating point type.
- IntExpr = S.ImpCastExprToType(IntExpr.take(), FloatTy,
+ IntExpr = S.ImpCastExprToType(IntExpr.get(), FloatTy,
CK_IntegralToFloating);
return FloatTy;
}
@@ -1054,12 +1062,12 @@
// _Complex int -> _Complex float
if (ConvertInt)
- IntExpr = S.ImpCastExprToType(IntExpr.take(), result,
+ IntExpr = S.ImpCastExprToType(IntExpr.get(), result,
CK_IntegralComplexToFloatingComplex);
// float -> _Complex float
if (ConvertFloat)
- FloatExpr = S.ImpCastExprToType(FloatExpr.take(), result,
+ FloatExpr = S.ImpCastExprToType(FloatExpr.get(), result,
CK_FloatingRealToComplex);
return result;
@@ -1078,13 +1086,13 @@
if (LHSFloat && RHSFloat) {
int order = S.Context.getFloatingTypeOrder(LHSType, RHSType);
if (order > 0) {
- RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_FloatingCast);
+ RHS = S.ImpCastExprToType(RHS.get(), LHSType, CK_FloatingCast);
return LHSType;
}
assert(order < 0 && "illegal float comparison");
if (!IsCompAssign)
- LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_FloatingCast);
+ LHS = S.ImpCastExprToType(LHS.get(), RHSType, CK_FloatingCast);
return RHSType;
}
@@ -1126,29 +1134,29 @@
if (LHSSigned == RHSSigned) {
// Same signedness; use the higher-ranked type
if (order >= 0) {
- RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+ RHS = (*doRHSCast)(S, RHS.get(), LHSType);
return LHSType;
} else if (!IsCompAssign)
- LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+ LHS = (*doLHSCast)(S, LHS.get(), RHSType);
return RHSType;
} else if (order != (LHSSigned ? 1 : -1)) {
// The unsigned type has greater than or equal rank to the
// signed type, so use the unsigned type
if (RHSSigned) {
- RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+ RHS = (*doRHSCast)(S, RHS.get(), LHSType);
return LHSType;
} else if (!IsCompAssign)
- LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+ LHS = (*doLHSCast)(S, LHS.get(), RHSType);
return RHSType;
} else if (S.Context.getIntWidth(LHSType) != S.Context.getIntWidth(RHSType)) {
// The two types are different widths; if we are here, that
// means the signed type is larger than the unsigned type, so
// use the signed type.
if (LHSSigned) {
- RHS = (*doRHSCast)(S, RHS.take(), LHSType);
+ RHS = (*doRHSCast)(S, RHS.get(), LHSType);
return LHSType;
} else if (!IsCompAssign)
- LHS = (*doLHSCast)(S, LHS.take(), RHSType);
+ LHS = (*doLHSCast)(S, LHS.get(), RHSType);
return RHSType;
} else {
// The signed type is higher-ranked than the unsigned type,
@@ -1157,9 +1165,9 @@
// to the signed type.
QualType result =
S.Context.getCorrespondingUnsignedType(LHSSigned ? LHSType : RHSType);
- RHS = (*doRHSCast)(S, RHS.take(), result);
+ RHS = (*doRHSCast)(S, RHS.get(), result);
if (!IsCompAssign)
- LHS = (*doLHSCast)(S, LHS.take(), result);
+ LHS = (*doLHSCast)(S, LHS.get(), result);
return result;
}
}
@@ -1189,7 +1197,7 @@
handleIntegerConversion<doComplexIntegralCast, doIntegralCast>
(S, LHS, RHS, LHSEltType, RHSType, IsCompAssign);
QualType ComplexType = S.Context.getComplexType(ScalarType);
- RHS = S.ImpCastExprToType(RHS.take(), ComplexType,
+ RHS = S.ImpCastExprToType(RHS.get(), ComplexType,
CK_IntegralRealToComplex);
return ComplexType;
@@ -1204,7 +1212,7 @@
QualType ComplexType = S.Context.getComplexType(ScalarType);
if (!IsCompAssign)
- LHS = S.ImpCastExprToType(LHS.take(), ComplexType,
+ LHS = S.ImpCastExprToType(LHS.get(), ComplexType,
CK_IntegralRealToComplex);
return ComplexType;
}
@@ -1216,12 +1224,12 @@
QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
bool IsCompAssign) {
if (!IsCompAssign) {
- LHS = UsualUnaryConversions(LHS.take());
+ LHS = UsualUnaryConversions(LHS.get());
if (LHS.isInvalid())
return QualType();
}
- RHS = UsualUnaryConversions(RHS.take());
+ RHS = UsualUnaryConversions(RHS.get());
if (RHS.isInvalid())
return QualType();
@@ -1253,7 +1261,7 @@
if (!LHSBitfieldPromoteTy.isNull())
LHSType = LHSBitfieldPromoteTy;
if (LHSType != LHSUnpromotedType && !IsCompAssign)
- LHS = ImpCastExprToType(LHS.take(), LHSType, CK_IntegralCast);
+ LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast);
// If both types are identical, no conversion is needed.
if (LHSType == RHSType)
@@ -1325,7 +1333,7 @@
if (ControllingExpr->getType()->isPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(ControllingExpr);
if (result.isInvalid()) return ExprError();
- ControllingExpr = result.take();
+ ControllingExpr = result.get();
}
bool TypeErrorFound = false,
@@ -1387,10 +1395,9 @@
// If we determined that the generic selection is result-dependent, don't
// try to compute the result expression.
if (IsResultDependent)
- return Owned(new (Context) GenericSelectionExpr(
- Context, KeyLoc, ControllingExpr,
- Types, Exprs,
- DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack));
+ return new (Context) GenericSelectionExpr(
+ Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
+ ContainsUnexpandedParameterPack);
SmallVector<unsigned, 1> CompatIndices;
unsigned DefaultIndex = -1U;
@@ -1442,11 +1449,9 @@
unsigned ResultIndex =
CompatIndices.size() ? CompatIndices[0] : DefaultIndex;
- return Owned(new (Context) GenericSelectionExpr(
- Context, KeyLoc, ControllingExpr,
- Types, Exprs,
- DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack,
- ResultIndex));
+ return new (Context) GenericSelectionExpr(
+ Context, KeyLoc, ControllingExpr, Types, Exprs, DefaultLoc, RParenLoc,
+ ContainsUnexpandedParameterPack, ResultIndex);
}
/// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the
@@ -1494,16 +1499,15 @@
/// string.
///
ExprResult
-Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
- Scope *UDLScope) {
- assert(NumStringToks && "Must have at least one string!");
+Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) {
+ assert(!StringToks.empty() && "Must have at least one string!");
- StringLiteralParser Literal(StringToks, NumStringToks, PP);
+ StringLiteralParser Literal(StringToks, PP);
if (Literal.hadError)
return ExprError();
SmallVector<SourceLocation, 4> StringTokLocs;
- for (unsigned i = 0; i != NumStringToks; ++i)
+ for (unsigned i = 0; i != StringToks.size(); ++i)
StringTokLocs.push_back(StringToks[i].getLocation());
QualType CharTy = Context.CharTy;
@@ -1546,7 +1550,7 @@
&StringTokLocs[0],
StringTokLocs.size());
if (Literal.getUDSuffix().empty())
- return Owned(Lit);
+ return Lit;
// We're building a user-defined literal.
IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
@@ -1671,20 +1675,16 @@
MarkDeclRefReferenced(E);
if (getLangOpts().ObjCARCWeak && isa<VarDecl>(D) &&
- Ty.getObjCLifetime() == Qualifiers::OCL_Weak) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- E->getLocStart());
- if (Level != DiagnosticsEngine::Ignored)
+ Ty.getObjCLifetime() == Qualifiers::OCL_Weak &&
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getLocStart()))
recordUseOfEvaluatedWeak(E);
- }
// Just in case we're building an illegal pointer-to-member.
FieldDecl *FD = dyn_cast<FieldDecl>(D);
if (FD && FD->isBitField())
E->setObjectKind(OK_BitField);
- return Owned(E);
+ return E;
}
/// Decomposes the given name into a DeclarationNameInfo, its location, and
@@ -1767,7 +1767,7 @@
// TODO: fixit for inserting 'Base<T>::' in the other cases.
// Actually quite difficult!
if (getLangOpts().MSVCCompat)
- diagnostic = diag::warn_found_via_dependent_bases_lookup;
+ diagnostic = diag::ext_found_via_dependent_bases_lookup;
if (isInstance) {
Diag(R.getNameLoc(), diagnostic) << Name
<< FixItHint::CreateInsertion(R.getNameLoc(), "this->");
@@ -1882,6 +1882,17 @@
}
}
R.addDecl(ND);
+ if (getLangOpts().CPlusPlus && ND->isCXXClassMember()) {
+ CXXRecordDecl *Record = nullptr;
+ if (Corrected.getCorrectionSpecifier()) {
+ const Type *Ty = Corrected.getCorrectionSpecifier()->getAsType();
+ Record = Ty->getAsCXXRecordDecl();
+ }
+ if (!Record)
+ Record = cast<CXXRecordDecl>(
+ ND->getDeclContext()->getRedeclContext());
+ R.setNamingClass(Record);
+ }
AcceptableWithRecovery =
isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND);
@@ -1932,6 +1943,53 @@
return true;
}
+/// In Microsoft mode, if we are inside a template class whose parent class has
+/// dependent base classes, and we can't resolve an unqualified identifier, then
+/// assume the identifier is a member of a dependent base class. We can only
+/// recover successfully in static methods, instance methods, and other contexts
+/// where 'this' is available. This doesn't precisely match MSVC's
+/// instantiation model, but it's close enough.
+static Expr *
+recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context,
+ DeclarationNameInfo &NameInfo,
+ SourceLocation TemplateKWLoc,
+ const TemplateArgumentListInfo *TemplateArgs) {
+ // Only try to recover from lookup into dependent bases in static methods or
+ // contexts where 'this' is available.
+ QualType ThisType = S.getCurrentThisType();
+ const CXXRecordDecl *RD = nullptr;
+ if (!ThisType.isNull())
+ RD = ThisType->getPointeeType()->getAsCXXRecordDecl();
+ else if (auto *MD = dyn_cast<CXXMethodDecl>(S.CurContext))
+ RD = MD->getParent();
+ if (!RD || !RD->hasAnyDependentBases())
+ return nullptr;
+
+ // Diagnose this as unqualified lookup into a dependent base class. If 'this'
+ // is available, suggest inserting 'this->' as a fixit.
+ SourceLocation Loc = NameInfo.getLoc();
+ auto DB = S.Diag(Loc, diag::ext_undeclared_unqual_id_with_dependent_base);
+ DB << NameInfo.getName() << RD;
+
+ if (!ThisType.isNull()) {
+ DB << FixItHint::CreateInsertion(Loc, "this->");
+ return CXXDependentScopeMemberExpr::Create(
+ Context, /*This=*/nullptr, ThisType, /*IsArrow=*/true,
+ /*Op=*/SourceLocation(), NestedNameSpecifierLoc(), TemplateKWLoc,
+ /*FirstQualifierInScope=*/nullptr, NameInfo, TemplateArgs);
+ }
+
+ // Synthesize a fake NNS that points to the derived class. This will
+ // perform name lookup during template instantiation.
+ CXXScopeSpec SS;
+ auto *NNS =
+ NestedNameSpecifier::Create(Context, nullptr, true, RD->getTypeForDecl());
+ SS.MakeTrivial(Context, NNS, SourceRange(Loc, Loc));
+ return DependentScopeDeclRefExpr::Create(
+ Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+ TemplateArgs);
+}
+
ExprResult Sema::ActOnIdExpression(Scope *S,
CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
@@ -2019,77 +2077,59 @@
if (E.isInvalid())
return ExprError();
- if (Expr *Ex = E.takeAs<Expr>())
- return Owned(Ex);
+ if (Expr *Ex = E.getAs<Expr>())
+ return Ex;
}
}
if (R.isAmbiguous())
return ExprError();
+ // This could be an implicitly declared function reference (legal in C90,
+ // extension in C99, forbidden in C++).
+ if (R.empty() && HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
+ NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
+ if (D) R.addDecl(D);
+ }
+
// Determine whether this name might be a candidate for
// argument-dependent lookup.
bool ADL = UseArgumentDependentLookup(SS, R, HasTrailingLParen);
if (R.empty() && !ADL) {
-
- // Otherwise, this could be an implicitly declared function reference (legal
- // in C90, extension in C99, forbidden in C++).
- if (HasTrailingLParen && II && !getLangOpts().CPlusPlus) {
- NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S);
- if (D) R.addDecl(D);
+ if (SS.isEmpty() && getLangOpts().MSVCCompat) {
+ if (Expr *E = recoverFromMSUnqualifiedLookup(*this, Context, NameInfo,
+ TemplateKWLoc, TemplateArgs))
+ return E;
}
+ // Don't diagnose an empty lookup for inline assembly.
+ if (IsInlineAsmIdentifier)
+ return ExprError();
+
// 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
- // whose parent class has dependent base classes, and we can't resolve
- // an unqualified identifier, then assume the identifier is a member of a
- // dependent base class. The goal is to postpone name lookup to
- // instantiation time to be able to search into the type dependent base
- // classes.
- // FIXME: If we want 100% compatibility with MSVC, we will have delay all
- // unqualified name lookup. Any name lookup during template parsing means
- // clang might find something that MSVC doesn't. For now, we only handle
- // the common case of members of a dependent base class.
- if (SS.isEmpty() && getLangOpts().MSVCCompat) {
- CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext);
- if (MD && MD->isInstance() && MD->getParent()->hasAnyDependentBases()) {
- QualType ThisType = MD->getThisType(Context);
- // Since the 'this' expression is synthesized, we don't need to
- // perform the double-lookup check.
- NamedDecl *FirstQualifierInScope = nullptr;
- return Owned(CXXDependentScopeMemberExpr::Create(
- Context, /*This=*/nullptr, ThisType, /*IsArrow=*/true,
- /*Op=*/SourceLocation(), SS.getWithLocInContext(Context),
- TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs));
- }
- }
+ CorrectionCandidateCallback DefaultValidator;
+ DefaultValidator.IsAddressOfOperand = IsAddressOfOperand;
+ assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&
+ "Typo correction callback misconfigured");
+ if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
+ return ExprError();
- // Don't diagnose an empty lookup for inline assmebly.
- if (IsInlineAsmIdentifier)
+ assert(!R.empty() &&
+ "DiagnoseEmptyLookup returned false but added no results");
+
+ // If we found an Objective-C instance variable, let
+ // LookupInObjCMethod build the appropriate expression to
+ // reference the ivar.
+ if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
+ R.clear();
+ ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+ // In a hopelessly buggy code, Objective-C instance variable
+ // lookup fails and no expression will be built to reference it.
+ if (!E.isInvalid() && !E.get())
return ExprError();
-
- CorrectionCandidateCallback DefaultValidator;
- if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator))
- return ExprError();
-
- assert(!R.empty() &&
- "DiagnoseEmptyLookup returned false but added no results");
-
- // If we found an Objective-C instance variable, let
- // LookupInObjCMethod build the appropriate expression to
- // reference the ivar.
- if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
- R.clear();
- ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
- // In a hopelessly buggy code, Objective-C instance variable
- // lookup fails and no expression will be built to reference it.
- if (!E.isInvalid() && !E.get())
- return ExprError();
- return E;
- }
+ return E;
}
}
@@ -2164,7 +2204,8 @@
ExprResult
Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
const DeclarationNameInfo &NameInfo,
- bool IsAddressOfOperand) {
+ bool IsAddressOfOperand,
+ TypeSourceInfo **RecoveryTSI) {
DeclContext *DC = computeDeclContext(SS, false);
if (!DC)
return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
@@ -2189,6 +2230,41 @@
return ExprError();
}
+ if (const TypeDecl *TD = R.getAsSingle<TypeDecl>()) {
+ // Diagnose a missing typename if this resolved unambiguously to a type in
+ // a dependent context. If we can recover with a type, downgrade this to
+ // a warning in Microsoft compatibility mode.
+ unsigned DiagID = diag::err_typename_missing;
+ if (RecoveryTSI && getLangOpts().MSVCCompat)
+ DiagID = diag::ext_typename_missing;
+ SourceLocation Loc = SS.getBeginLoc();
+ auto D = Diag(Loc, DiagID);
+ D << SS.getScopeRep() << NameInfo.getName().getAsString()
+ << SourceRange(Loc, NameInfo.getEndLoc());
+
+ // Don't recover if the caller isn't expecting us to or if we're in a SFINAE
+ // context.
+ if (!RecoveryTSI)
+ return ExprError();
+
+ // Only issue the fixit if we're prepared to recover.
+ D << FixItHint::CreateInsertion(Loc, "typename ");
+
+ // Recover by pretending this was an elaborated type.
+ QualType Ty = Context.getTypeDeclType(TD);
+ TypeLocBuilder TLB;
+ TLB.pushTypeSpec(Ty).setNameLoc(NameInfo.getLoc());
+
+ QualType ET = getElaboratedType(ETK_None, SS, Ty);
+ ElaboratedTypeLoc QTL = TLB.push<ElaboratedTypeLoc>(ET);
+ QTL.setElaboratedKeywordLoc(SourceLocation());
+ QTL.setQualifierLoc(SS.getWithLocInContext(Context));
+
+ *RecoveryTSI = TLB.getTypeSourceInfo(Context, ET);
+
+ return ExprEmpty();
+ }
+
// Defend against this resolving to an implicit member access. We usually
// won't get here if this might be a legitimate a class member (we end up in
// BuildMemberReferenceExpr instead), but this can be valid if we're forming
@@ -2277,7 +2353,7 @@
if (SelfExpr.isInvalid())
return ExprError();
- SelfExpr = DefaultLvalueConversion(SelfExpr.take());
+ SelfExpr = DefaultLvalueConversion(SelfExpr.get());
if (SelfExpr.isInvalid())
return ExprError();
@@ -2290,14 +2366,12 @@
ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
Loc, IV->getLocation(),
- SelfExpr.take(),
+ SelfExpr.get(),
true, true);
if (getLangOpts().ObjCAutoRefCount) {
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc);
- if (Level != DiagnosticsEngine::Ignored)
+ if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
recordUseOfEvaluatedWeak(Result);
}
if (CurContext->isClosure())
@@ -2305,7 +2379,7 @@
<< FixItHint::CreateInsertion(Loc, "self->");
}
- return Owned(Result);
+ return Result;
}
} else if (CurMethod->isInstanceMethod()) {
// We should warn if a local variable hides an ivar.
@@ -2338,7 +2412,7 @@
}
}
// Sentinel value saying that we didn't do anything special.
- return Owned((Expr*) nullptr);
+ return ExprResult((Expr *)nullptr);
}
/// \brief Cast a base object to a member's actual type.
@@ -2365,7 +2439,7 @@
NamedDecl *Member) {
CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
if (!RD)
- return Owned(From);
+ return From;
QualType DestRecordType;
QualType DestType;
@@ -2385,7 +2459,7 @@
}
} else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) {
if (Method->isStatic())
- return Owned(From);
+ return From;
DestType = Method->getThisType(Context);
DestRecordType = DestType->getPointeeType();
@@ -2399,15 +2473,15 @@
}
} else {
// No conversion necessary.
- return Owned(From);
+ return From;
}
if (DestType->isDependentType() || FromType->isDependentType())
- return Owned(From);
+ return From;
// If the unqualified types are the same, no conversion is necessary.
if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
- return Owned(From);
+ return From;
SourceRange FromRange = From->getSourceRange();
SourceLocation FromLoc = FromRange.getBegin();
@@ -2450,7 +2524,7 @@
if (PointerConversions)
QType = Context.getPointerType(QType);
From = ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
- VK, &BasePath).take();
+ VK, &BasePath).get();
FromType = QType;
FromRecordType = QRecordType;
@@ -2458,7 +2532,7 @@
// If the qualifier type was the same as the destination type,
// we're done.
if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
- return Owned(From);
+ return From;
}
}
@@ -2487,7 +2561,7 @@
if (PointerConversions)
UType = Context.getPointerType(UType);
From = ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
- VK, &BasePath).take();
+ VK, &BasePath).get();
FromType = UType;
FromRecordType = URecordType;
}
@@ -2615,7 +2689,7 @@
NeedsADL, R.isOverloadedResult(),
R.begin(), R.end());
- return Owned(ULE);
+ return ULE;
}
/// \brief Complete semantic analysis for a reference to the given declaration.
@@ -2862,7 +2936,7 @@
ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
}
- return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
+ return new (Context) PredefinedExpr(Loc, ResTy, IT);
}
ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
@@ -2917,7 +2991,7 @@
Tok.getLocation());
if (Literal.getUDSuffix().empty())
- return Owned(Lit);
+ return Lit;
// We're building a user-defined literal.
IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix());
@@ -2936,8 +3010,8 @@
ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) {
unsigned IntSize = Context.getTargetInfo().getIntWidth();
- return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
- Context.IntTy, Loc));
+ return IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val),
+ Context.IntTy, Loc);
}
static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
@@ -3102,10 +3176,10 @@
if (Ty == Context.DoubleTy) {
if (getLangOpts().SinglePrecisionConstants) {
- Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take();
+ Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
} else if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp64) {
Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64);
- Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take();
+ Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).get();
}
}
} else if (!Literal.isIntegerLiteral()) {
@@ -3129,7 +3203,7 @@
// may be wider than [u]intmax_t.
// FIXME: Actually, they don't. We seem to have accidentally invented the
// i128 suffix.
- if (Literal.isMicrosoftInteger && MaxWidth < 128 &&
+ if (Literal.MicrosoftInteger == 128 && MaxWidth < 128 &&
Context.getTargetInfo().hasInt128Type())
MaxWidth = 128;
llvm::APInt ResultVal(MaxWidth, 0);
@@ -3150,7 +3224,22 @@
// Check from smallest to largest, picking the smallest type we can.
unsigned Width = 0;
- if (!Literal.isLong && !Literal.isLongLong) {
+
+ // Microsoft specific integer suffixes are explicitly sized.
+ if (Literal.MicrosoftInteger) {
+ if (Literal.MicrosoftInteger > MaxWidth) {
+ // If this target doesn't support __int128, error and force to ull.
+ Diag(Tok.getLocation(), diag::err_int128_unsupported);
+ Width = MaxWidth;
+ Ty = Context.getIntMaxType();
+ } else {
+ Width = Literal.MicrosoftInteger;
+ Ty = Context.getIntTypeForBitwidth(Width,
+ /*Signed=*/!Literal.isUnsigned);
+ }
+ }
+
+ if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) {
// Are int/unsigned possibilities?
unsigned IntSize = Context.getTargetInfo().getIntWidth();
@@ -3197,17 +3286,6 @@
Width = LongLongSize;
}
}
-
- // If it doesn't fit in unsigned long long, and we're using Microsoft
- // extensions, then its a 128-bit integer literal.
- if (Ty.isNull() && Literal.isMicrosoftInteger &&
- Context.getTargetInfo().hasInt128Type()) {
- if (Literal.isUnsigned)
- Ty = Context.UnsignedInt128Ty;
- else
- Ty = Context.Int128Ty;
- Width = 128;
- }
// If we still couldn't decide a type, we probably have something that
// does not fit in a signed long long, but has no U suffix.
@@ -3228,12 +3306,12 @@
Res = new (Context) ImaginaryLiteral(Res,
Context.getComplexType(Res->getType()));
- return Owned(Res);
+ return Res;
}
ExprResult Sema::ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E) {
assert(E && "ActOnParenExpr() missing expr");
- return Owned(new (Context) ParenExpr(L, R, E));
+ return new (Context) ParenExpr(L, R, E);
}
static bool CheckVecStepTraitOperandType(Sema &S, QualType T,
@@ -3338,10 +3416,21 @@
E->getSourceRange(), ExprKind))
return false;
- if (RequireCompleteExprType(E,
- diag::err_sizeof_alignof_incomplete_type,
- ExprKind, E->getSourceRange()))
- return true;
+ // 'alignof' applied to an expression only requires the base element type of
+ // the expression to be complete. 'sizeof' requires the expression's type to
+ // be complete (and will attempt to complete it if it's an array of unknown
+ // bound).
+ if (ExprKind == UETT_AlignOf) {
+ if (RequireCompleteType(E->getExprLoc(),
+ Context.getBaseElementType(E->getType()),
+ diag::err_sizeof_alignof_incomplete_type, ExprKind,
+ E->getSourceRange()))
+ return true;
+ } else {
+ if (RequireCompleteExprType(E, diag::err_sizeof_alignof_incomplete_type,
+ ExprKind, E->getSourceRange()))
+ return true;
+ }
// Completing the expression's type may have changed it.
ExprTy = E->getType();
@@ -3406,13 +3495,21 @@
if (ExprType->isDependentType())
return false;
- // 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."
+ // C++ [expr.sizeof]p2:
+ // When applied to a reference or a reference type, the result
+ // is the size of the referenced type.
+ // C++11 [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 = ExprType->getAs<ReferenceType>())
ExprType = Ref->getPointeeType();
+ // C11 6.5.3.4/3, C++11 [expr.alignof]p3:
+ // When alignof or _Alignof is applied to an array type, the result
+ // is the alignment of the element type.
+ if (ExprKind == UETT_AlignOf)
+ ExprType = Context.getBaseElementType(ExprType);
+
if (ExprKind == UETT_VecStep)
return CheckVecStepTraitOperandType(*this, ExprType, OpLoc, ExprRange);
@@ -3462,21 +3559,10 @@
// 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,
- // again, in C++11, where such references are allowed in an
- // unevaluated context. So C++11 introduces some new complexity.
+ // This can happen in C++11 onwards, either by naming the member
+ // in a way that is not transformed into a member access expression
+ // (in an unevaluated operand, for instance), or by naming the member
+ // in a trailing-return-type.
//
// For the record, since __alignof__ on expressions is a GCC
// extension, GCC seems to permit this but always gives the
@@ -3533,9 +3619,8 @@
return ExprError();
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
- return Owned(new (Context) UnaryExprOrTypeTraitExpr(ExprKind, TInfo,
- Context.getSizeType(),
- OpLoc, R.getEnd()));
+ return new (Context) UnaryExprOrTypeTraitExpr(
+ ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
}
/// \brief Build a sizeof or alignof expression given an expression
@@ -3570,13 +3655,12 @@
if (ExprKind == UETT_SizeOf && E->getType()->isVariableArrayType()) {
PE = TransformToPotentiallyEvaluated(E);
if (PE.isInvalid()) return ExprError();
- E = PE.take();
+ E = PE.get();
}
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
- return Owned(new (Context) UnaryExprOrTypeTraitExpr(
- ExprKind, E, Context.getSizeType(), OpLoc,
- E->getSourceRange().getEnd()));
+ return new (Context) UnaryExprOrTypeTraitExpr(
+ ExprKind, E, Context.getSizeType(), OpLoc, E->getSourceRange().getEnd());
}
/// ActOnUnaryExprOrTypeTraitExpr - Handle @c sizeof(type) and @c sizeof @c
@@ -3607,7 +3691,7 @@
// _Real and _Imag are only l-values for normal l-values.
if (V.get()->getObjectKind() != OK_Ordinary) {
- V = S.DefaultLvalueConversion(V.take());
+ V = S.DefaultLvalueConversion(V.get());
if (V.isInvalid())
return QualType();
}
@@ -3649,7 +3733,7 @@
// Since this might is a postfix expression, get rid of ParenListExprs.
ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input);
if (Result.isInvalid()) return ExprError();
- Input = Result.take();
+ Input = Result.get();
return BuildUnaryOp(S, OpLoc, Opc, Input);
}
@@ -3678,7 +3762,7 @@
if (isa<ParenListExpr>(base)) {
ExprResult result = MaybeConvertParenListExprToParenExpr(S, base);
if (result.isInvalid()) return ExprError();
- base = result.take();
+ base = result.get();
}
// Handle any non-overload placeholder types in the base and index
@@ -3689,21 +3773,19 @@
if (base->getType()->isNonOverloadPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(base);
if (result.isInvalid()) return ExprError();
- base = result.take();
+ base = result.get();
}
if (idx->getType()->isNonOverloadPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(idx);
if (result.isInvalid()) return ExprError();
- idx = result.take();
+ idx = result.get();
}
// Build an unanalyzed expression if either operand is type-dependent.
if (getLangOpts().CPlusPlus &&
(base->isTypeDependent() || idx->isTypeDependent())) {
- return Owned(new (Context) ArraySubscriptExpr(base, idx,
- Context.DependentTy,
- VK_LValue, OK_Ordinary,
- rbLoc));
+ return new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy,
+ VK_LValue, OK_Ordinary, rbLoc);
}
// Use C++ overloaded-operator rules if either operand has record
@@ -3735,12 +3817,12 @@
ExprResult Result = DefaultFunctionArrayLvalueConversion(LHSExp);
if (Result.isInvalid())
return ExprError();
- LHSExp = Result.take();
+ LHSExp = Result.get();
}
ExprResult Result = DefaultFunctionArrayLvalueConversion(RHSExp);
if (Result.isInvalid())
return ExprError();
- RHSExp = Result.take();
+ RHSExp = Result.get();
QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
ExprValueKind VK = VK_LValue;
@@ -3806,7 +3888,7 @@
Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
LHSExp->getSourceRange();
LHSExp = ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
- CK_ArrayToPointerDecay).take();
+ CK_ArrayToPointerDecay).get();
LHSTy = LHSExp->getType();
BaseExpr = LHSExp;
@@ -3817,7 +3899,7 @@
Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
RHSExp->getSourceRange();
RHSExp = ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
- CK_ArrayToPointerDecay).take();
+ CK_ArrayToPointerDecay).get();
RHSTy = RHSExp->getType();
BaseExpr = RHSExp;
@@ -3863,8 +3945,8 @@
assert(VK == VK_RValue || LangOpts.CPlusPlus ||
!ResultType.isCForbiddenLValueType());
- return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
- ResultType, VK, OK, RLoc));
+ return new (Context)
+ ArraySubscriptExpr(LHSExp, RHSExp, ResultType, VK, OK, RLoc);
}
ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
@@ -3913,17 +3995,17 @@
InitializationKind Kind
= InitializationKind::CreateCopy(Param->getLocation(),
/*FIXME:EqualLoc*/UninstExpr->getLocStart());
- Expr *ResultE = Result.takeAs<Expr>();
+ Expr *ResultE = Result.getAs<Expr>();
InitializationSequence InitSeq(*this, Entity, Kind, ResultE);
Result = InitSeq.Perform(*this, Entity, Kind, ResultE);
if (Result.isInvalid())
return ExprError();
- Expr *Arg = Result.takeAs<Expr>();
+ Expr *Arg = Result.getAs<Expr>();
CheckCompletedExpr(Arg, Param->getOuterLocStart());
// Build the default argument expression.
- return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg));
+ return CXXDefaultArgExpr::Create(Context, CallLoc, Param, Arg);
}
// If the default expression creates temporaries, we need to
@@ -3950,7 +4032,7 @@
// as being "referenced".
MarkDeclarationsReferencedInExpr(Param->getDefaultArg(),
/*SkipLocalVariables=*/true);
- return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
+ return CXXDefaultArgExpr::Create(Context, CallLoc, Param);
}
@@ -4202,15 +4284,12 @@
if (CFAudited)
Entity.setParameterCFAudited();
- ExprResult ArgE = PerformCopyInitialization(Entity,
- SourceLocation(),
- Owned(Arg),
- IsListInitialization,
- AllowExplicit);
+ ExprResult ArgE = PerformCopyInitialization(
+ Entity, SourceLocation(), Arg, IsListInitialization, AllowExplicit);
if (ArgE.isInvalid())
return true;
- Arg = ArgE.takeAs<Expr>();
+ Arg = ArgE.getAs<Expr>();
} else {
assert(Param && "can't use default arguments without a known callee");
@@ -4219,7 +4298,7 @@
if (ArgExpr.isInvalid())
return true;
- Arg = ArgExpr.takeAs<Expr>();
+ Arg = ArgExpr.getAs<Expr>();
}
// Check for array bounds violations for each argument to the call. This
@@ -4243,7 +4322,7 @@
QualType paramType; // ignored
ExprResult arg = checkUnknownAnyArg(CallLoc, Args[i], paramType);
Invalid |= arg.isInvalid();
- AllArgs.push_back(arg.take());
+ AllArgs.push_back(arg.get());
}
// Otherwise do argument promotion, (C99 6.5.2.2p7).
@@ -4252,7 +4331,7 @@
ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], CallType,
FDecl);
Invalid |= Arg.isInvalid();
- AllArgs.push_back(Arg.take());
+ AllArgs.push_back(Arg.get());
}
}
@@ -4374,7 +4453,7 @@
if (isPlaceholderToRemoveAsArg(args[i]->getType())) {
ExprResult result = S.CheckPlaceholderExpr(args[i]);
if (result.isInvalid()) hasInvalid = true;
- else args[i] = result.take();
+ else args[i] = result.get();
}
}
return hasInvalid;
@@ -4390,7 +4469,7 @@
// Since this might be a postfix expression, get rid of ParenListExprs.
ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
if (Result.isInvalid()) return ExprError();
- Fn = Result.take();
+ Fn = Result.get();
if (checkArgsForPlaceholders(*this, ArgExprs))
return ExprError();
@@ -4406,14 +4485,13 @@
ArgExprs.back()->getLocEnd()));
}
- return Owned(new (Context) CallExpr(Context, Fn, None,
- Context.VoidTy, VK_RValue,
- RParenLoc));
+ return 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();
+ Fn = result.get();
}
// Determine whether this is a dependent call inside a C++ template,
@@ -4428,25 +4506,24 @@
if (Dependent) {
if (ExecConfig) {
- return Owned(new (Context) CUDAKernelCallExpr(
+ return new (Context) CUDAKernelCallExpr(
Context, Fn, cast<CallExpr>(ExecConfig), ArgExprs,
- Context.DependentTy, VK_RValue, RParenLoc));
+ Context.DependentTy, VK_RValue, RParenLoc);
} else {
- return Owned(new (Context) CallExpr(Context, Fn, ArgExprs,
- Context.DependentTy, VK_RValue,
- RParenLoc));
+ return new (Context) CallExpr(
+ Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
}
}
// Determine whether this is a call to an object (C++ [over.call.object]).
if (Fn->getType()->isRecordType())
- return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc,
- ArgExprs, RParenLoc));
+ return BuildCallToObjectOfClassType(S, Fn, LParenLoc, ArgExprs,
+ RParenLoc);
if (Fn->getType() == Context.UnknownAnyTy) {
ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
if (result.isInvalid()) return ExprError();
- Fn = result.take();
+ Fn = result.get();
}
if (Fn->getType() == Context.BoundMemberTy) {
@@ -4476,7 +4553,7 @@
if (Fn->getType() == Context.UnknownAnyTy) {
ExprResult result = rebuildUnknownAnyFunction(*this, Fn);
if (result.isInvalid()) return ExprError();
- Fn = result.take();
+ Fn = result.get();
}
Expr *NakedFn = Fn->IgnoreParens();
@@ -4544,8 +4621,7 @@
<< DstTy
<< SrcTy
<< E->getSourceRange());
- return Owned(new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc,
- RParenLoc));
+ return new (Context) AsTypeExpr(E, DstTy, VK, OK, BuiltinLoc, RParenLoc);
}
/// ActOnConvertVectorExpr - create a new convert-vector expression from the
@@ -4583,13 +4659,13 @@
if (BuiltinID &&
Fn->getType()->isSpecificBuiltinType(BuiltinType::BuiltinFn)) {
Result = ImpCastExprToType(Fn, Context.getPointerType(FDecl->getType()),
- CK_BuiltinFnToFnPtr).take();
+ CK_BuiltinFnToFnPtr).get();
} else {
Result = CallExprUnaryConversions(Fn);
}
if (Result.isInvalid())
return ExprError();
- Fn = Result.take();
+ Fn = Result.get();
// Make the call expr early, before semantic checks. This guarantees cleanup
// of arguments and function on error.
@@ -4624,7 +4700,7 @@
if (Fn->getType() == Context.UnknownAnyTy) {
ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn);
if (rewrite.isInvalid()) return ExprError();
- Fn = rewrite.take();
+ Fn = rewrite.get();
TheCall->setCallee(Fn);
goto retry;
}
@@ -4693,13 +4769,12 @@
if (Proto && i < Proto->getNumParams()) {
InitializedEntity Entity = InitializedEntity::InitializeParameter(
Context, Proto->getParamType(i), Proto->isParamConsumed(i));
- ExprResult ArgE = PerformCopyInitialization(Entity,
- SourceLocation(),
- Owned(Arg));
+ ExprResult ArgE =
+ PerformCopyInitialization(Entity, SourceLocation(), Arg);
if (ArgE.isInvalid())
return true;
- Arg = ArgE.takeAs<Expr>();
+ Arg = ArgE.getAs<Expr>();
} else {
ExprResult ArgE = DefaultArgumentPromotion(Arg);
@@ -4707,7 +4782,7 @@
if (ArgE.isInvalid())
return true;
- Arg = ArgE.takeAs<Expr>();
+ Arg = ArgE.getAs<Expr>();
}
if (RequireCompleteType(Arg->getLocStart(),
@@ -4824,7 +4899,7 @@
// of one failure would be terrible for indexing/etc.
if (result.isInvalid()) continue;
- InitArgList[I] = result.take();
+ InitArgList[I] = result.get();
}
}
@@ -4834,7 +4909,7 @@
InitListExpr *E = new (Context) InitListExpr(Context, LBraceLoc, InitArgList,
RBraceLoc);
E->setType(Context.VoidTy); // FIXME: just a place holder for now.
- return Owned(E);
+ return E;
}
/// Do an explicit extend of the given block pointer if we're in ARC.
@@ -4931,12 +5006,12 @@
case Type::STK_Floating:
return CK_IntegralToFloating;
case Type::STK_IntegralComplex:
- Src = ImpCastExprToType(Src.take(),
+ Src = ImpCastExprToType(Src.get(),
DestTy->castAs<ComplexType>()->getElementType(),
CK_IntegralCast);
return CK_IntegralRealToComplex;
case Type::STK_FloatingComplex:
- Src = ImpCastExprToType(Src.take(),
+ Src = ImpCastExprToType(Src.get(),
DestTy->castAs<ComplexType>()->getElementType(),
CK_IntegralToFloating);
return CK_FloatingRealToComplex;
@@ -4954,12 +5029,12 @@
case Type::STK_Integral:
return CK_FloatingToIntegral;
case Type::STK_FloatingComplex:
- Src = ImpCastExprToType(Src.take(),
+ Src = ImpCastExprToType(Src.get(),
DestTy->castAs<ComplexType>()->getElementType(),
CK_FloatingCast);
return CK_FloatingRealToComplex;
case Type::STK_IntegralComplex:
- Src = ImpCastExprToType(Src.take(),
+ Src = ImpCastExprToType(Src.get(),
DestTy->castAs<ComplexType>()->getElementType(),
CK_FloatingToIntegral);
return CK_IntegralRealToComplex;
@@ -4982,13 +5057,13 @@
QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
if (Context.hasSameType(ET, DestTy))
return CK_FloatingComplexToReal;
- Src = ImpCastExprToType(Src.take(), ET, CK_FloatingComplexToReal);
+ Src = ImpCastExprToType(Src.get(), ET, CK_FloatingComplexToReal);
return CK_FloatingCast;
}
case Type::STK_Bool:
return CK_FloatingComplexToBoolean;
case Type::STK_Integral:
- Src = ImpCastExprToType(Src.take(),
+ Src = ImpCastExprToType(Src.get(),
SrcTy->castAs<ComplexType>()->getElementType(),
CK_FloatingComplexToReal);
return CK_FloatingToIntegral;
@@ -5011,13 +5086,13 @@
QualType ET = SrcTy->castAs<ComplexType>()->getElementType();
if (Context.hasSameType(ET, DestTy))
return CK_IntegralComplexToReal;
- Src = ImpCastExprToType(Src.take(), ET, CK_IntegralComplexToReal);
+ Src = ImpCastExprToType(Src.get(), ET, CK_IntegralComplexToReal);
return CK_IntegralCast;
}
case Type::STK_Bool:
return CK_IntegralComplexToBoolean;
case Type::STK_Floating:
- Src = ImpCastExprToType(Src.take(),
+ Src = ImpCastExprToType(Src.get(),
SrcTy->castAs<ComplexType>()->getElementType(),
CK_IntegralComplexToReal);
return CK_IntegralToFloating;
@@ -5116,7 +5191,7 @@
return ExprError();
}
Kind = CK_BitCast;
- return Owned(CastExpr);
+ return CastExpr;
}
// All non-pointer scalars can be cast to ExtVector type. The appropriate
@@ -5128,14 +5203,14 @@
<< DestTy << SrcTy << R;
QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
- ExprResult CastExprRes = Owned(CastExpr);
+ ExprResult CastExprRes = CastExpr;
CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy);
if (CastExprRes.isInvalid())
return ExprError();
- CastExpr = ImpCastExprToType(CastExprRes.take(), DestElemTy, CK).take();
+ CastExpr = ImpCastExprToType(CastExprRes.get(), DestElemTy, CK).get();
Kind = CK_VectorSplat;
- return Owned(CastExpr);
+ return CastExpr;
}
ExprResult
@@ -5191,7 +5266,7 @@
if (isa<ParenListExpr>(CastExpr)) {
ExprResult Result = MaybeConvertParenListExprToParenExpr(S, CastExpr);
if (Result.isInvalid()) return ExprError();
- CastExpr = Result.take();
+ CastExpr = Result.get();
}
if (getLangOpts().CPlusPlus && !castType->isVoidType() &&
@@ -5199,7 +5274,9 @@
Diag(LParenLoc, diag::warn_old_style_cast) << CastExpr->getSourceRange();
CheckTollFreeBridgeCast(castType, CastExpr);
-
+
+ CheckObjCBridgeRelatedCast(castType, CastExpr);
+
return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, CastExpr);
}
@@ -5246,9 +5323,9 @@
ExprResult Literal = DefaultLvalueConversion(exprs[0]);
if (Literal.isInvalid())
return ExprError();
- Literal = ImpCastExprToType(Literal.take(), ElemTy,
+ Literal = ImpCastExprToType(Literal.get(), ElemTy,
PrepareScalarCast(Literal, ElemTy));
- return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
+ return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
}
else if (numExprs < numElems) {
Diag(E->getExprLoc(),
@@ -5268,9 +5345,9 @@
ExprResult Literal = DefaultLvalueConversion(exprs[0]);
if (Literal.isInvalid())
return ExprError();
- Literal = ImpCastExprToType(Literal.take(), ElemTy,
+ Literal = ImpCastExprToType(Literal.get(), ElemTy,
PrepareScalarCast(Literal, ElemTy));
- return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take());
+ return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.get());
}
initExprs.append(exprs, exprs + numExprs);
@@ -5289,7 +5366,7 @@
Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) {
ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr);
if (!E)
- return Owned(OrigExpr);
+ return OrigExpr;
ExprResult Result(E->getExpr(0));
@@ -5306,7 +5383,7 @@
SourceLocation R,
MultiExprArg Val) {
Expr *expr = new (Context) ParenListExpr(Context, L, Val, R);
- return Owned(expr);
+ return expr;
}
/// \brief Emit a specialized diagnostic when one expression is a null pointer
@@ -5387,8 +5464,8 @@
}
// Implicity convert these scalars to the type of the condition.
- LHS = S.ImpCastExprToType(LHS.take(), CondTy, CK_IntegralCast);
- RHS = S.ImpCastExprToType(RHS.take(), CondTy, CK_IntegralCast);
+ LHS = S.ImpCastExprToType(LHS.get(), CondTy, CK_IntegralCast);
+ RHS = S.ImpCastExprToType(RHS.get(), CondTy, CK_IntegralCast);
return false;
}
@@ -5404,8 +5481,8 @@
if (!RHSExpr->getType()->isVoidType())
S.Diag(LHSExpr->getLocStart(), diag::ext_typecheck_cond_one_void)
<< LHSExpr->getSourceRange();
- LHS = S.ImpCastExprToType(LHS.take(), S.Context.VoidTy, CK_ToVoid);
- RHS = S.ImpCastExprToType(RHS.take(), S.Context.VoidTy, CK_ToVoid);
+ LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid);
+ RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid);
return S.Context.VoidTy;
}
@@ -5418,7 +5495,7 @@
Expr::NPC_ValueDependentIsNull))
return true;
- NullExpr = S.ImpCastExprToType(NullExpr.take(), PointerTy, CK_NullToPointer);
+ NullExpr = S.ImpCastExprToType(NullExpr.get(), PointerTy, CK_NullToPointer);
return false;
}
@@ -5477,8 +5554,8 @@
// reason, but this is what gcc does, and we do have to pick
// to get a consistent AST.
QualType incompatTy = S.Context.getPointerType(S.Context.VoidTy);
- LHS = S.ImpCastExprToType(LHS.take(), incompatTy, CK_BitCast);
- RHS = S.ImpCastExprToType(RHS.take(), incompatTy, CK_BitCast);
+ LHS = S.ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
+ RHS = S.ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
return incompatTy;
}
@@ -5489,11 +5566,41 @@
else
ResultTy = S.Context.getPointerType(ResultTy);
- LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast);
- RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast);
+ LHS = S.ImpCastExprToType(LHS.get(), ResultTy, CK_BitCast);
+ RHS = S.ImpCastExprToType(RHS.get(), ResultTy, CK_BitCast);
return ResultTy;
}
+/// \brief Returns true if QT is quelified-id and implements 'NSObject' and/or
+/// 'NSCopying' protocols (and nothing else); or QT is an NSObject and optionally
+/// implements 'NSObject' and/or NSCopying' protocols (and nothing else).
+static bool isObjCPtrBlockCompatible(Sema &S, ASTContext &C, QualType QT) {
+ if (QT->isObjCIdType())
+ return true;
+
+ const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+ if (!OPT)
+ return false;
+
+ if (ObjCInterfaceDecl *ID = OPT->getInterfaceDecl())
+ if (ID->getIdentifier() != &C.Idents.get("NSObject"))
+ return false;
+
+ ObjCProtocolDecl* PNSCopying =
+ S.LookupProtocol(&C.Idents.get("NSCopying"), SourceLocation());
+ ObjCProtocolDecl* PNSObject =
+ S.LookupProtocol(&C.Idents.get("NSObject"), SourceLocation());
+
+ for (auto *Proto : OPT->quals()) {
+ if ((PNSCopying && declaresSameEntity(Proto, PNSCopying)) ||
+ (PNSObject && declaresSameEntity(Proto, PNSObject)))
+ ;
+ else
+ return false;
+ }
+ return true;
+}
+
/// \brief Return the resulting type when the operands are both block pointers.
static QualType checkConditionalBlockPointerCompatibility(Sema &S,
ExprResult &LHS,
@@ -5505,8 +5612,8 @@
if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
QualType destType = S.Context.getPointerType(S.Context.VoidTy);
- LHS = S.ImpCastExprToType(LHS.take(), destType, CK_BitCast);
- RHS = S.ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+ LHS = S.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
+ RHS = S.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
return destType;
}
S.Diag(Loc, diag::err_typecheck_cond_incompatible_operands)
@@ -5539,9 +5646,9 @@
= S.Context.getQualifiedType(lhptee, rhptee.getQualifiers());
QualType destType = S.Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- LHS = S.ImpCastExprToType(LHS.take(), destType, CK_NoOp);
+ LHS = S.ImpCastExprToType(LHS.get(), destType, CK_NoOp);
// Promote to void*.
- RHS = S.ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+ RHS = S.ImpCastExprToType(RHS.get(), destType, CK_BitCast);
return destType;
}
if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -5549,9 +5656,9 @@
= S.Context.getQualifiedType(rhptee, lhptee.getQualifiers());
QualType destType = S.Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- RHS = S.ImpCastExprToType(RHS.take(), destType, CK_NoOp);
+ RHS = S.ImpCastExprToType(RHS.get(), destType, CK_NoOp);
// Promote to void*.
- LHS = S.ImpCastExprToType(LHS.take(), destType, CK_BitCast);
+ LHS = S.ImpCastExprToType(LHS.get(), destType, CK_BitCast);
return destType;
}
@@ -5573,7 +5680,7 @@
S.Diag(Loc, diag::warn_typecheck_cond_pointer_integer_mismatch)
<< Expr1->getType() << Expr2->getType()
<< Expr1->getSourceRange() << Expr2->getSourceRange();
- Int = S.ImpCastExprToType(Int.take(), PointerExpr->getType(),
+ Int = S.ImpCastExprToType(Int.get(), PointerExpr->getType(),
CK_IntegralToPointer);
return true;
}
@@ -5602,7 +5709,7 @@
OK = OK_Ordinary;
// First, check the condition.
- Cond = UsualUnaryConversions(Cond.take());
+ Cond = UsualUnaryConversions(Cond.get());
if (Cond.isInvalid())
return QualType();
if (checkCondition(*this, Cond.get()))
@@ -5708,34 +5815,34 @@
// redefinition type if an attempt is made to access its fields.
if (LHSTy->isObjCClassType() &&
(Context.hasSameType(RHSTy, Context.getObjCClassRedefinitionType()))) {
- RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast);
return LHSTy;
}
if (RHSTy->isObjCClassType() &&
(Context.hasSameType(LHSTy, Context.getObjCClassRedefinitionType()))) {
- LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
+ LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_CPointerToObjCPointerCast);
return RHSTy;
}
// And the same for struct objc_object* / id
if (LHSTy->isObjCIdType() &&
(Context.hasSameType(RHSTy, Context.getObjCIdRedefinitionType()))) {
- RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_CPointerToObjCPointerCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_CPointerToObjCPointerCast);
return LHSTy;
}
if (RHSTy->isObjCIdType() &&
(Context.hasSameType(LHSTy, Context.getObjCIdRedefinitionType()))) {
- LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_CPointerToObjCPointerCast);
+ LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_CPointerToObjCPointerCast);
return RHSTy;
}
// And the same for struct objc_selector* / SEL
if (Context.isObjCSelType(LHSTy) &&
(Context.hasSameType(RHSTy, Context.getObjCSelRedefinitionType()))) {
- RHS = ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSTy, CK_BitCast);
return LHSTy;
}
if (Context.isObjCSelType(RHSTy) &&
(Context.hasSameType(LHSTy, Context.getObjCSelRedefinitionType()))) {
- LHS = ImpCastExprToType(LHS.take(), RHSTy, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.get(), RHSTy, CK_BitCast);
return RHSTy;
}
// Check constraints for Objective-C object pointers types.
@@ -5784,13 +5891,13 @@
<< LHSTy << RHSTy
<< LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
QualType incompatTy = Context.getObjCIdType();
- LHS = ImpCastExprToType(LHS.take(), incompatTy, CK_BitCast);
- RHS = ImpCastExprToType(RHS.take(), incompatTy, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.get(), incompatTy, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), incompatTy, CK_BitCast);
return incompatTy;
}
// The object pointer types are compatible.
- LHS = ImpCastExprToType(LHS.take(), compositeType, CK_BitCast);
- RHS = ImpCastExprToType(RHS.take(), compositeType, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.get(), compositeType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), compositeType, CK_BitCast);
return compositeType;
}
// Check Objective-C object pointer types and 'void *'
@@ -5809,9 +5916,9 @@
= Context.getQualifiedType(lhptee, rhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- LHS = ImpCastExprToType(LHS.take(), destType, CK_NoOp);
+ LHS = ImpCastExprToType(LHS.get(), destType, CK_NoOp);
// Promote to void*.
- RHS = ImpCastExprToType(RHS.take(), destType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), destType, CK_BitCast);
return destType;
}
if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -5829,9 +5936,9 @@
= Context.getQualifiedType(rhptee, lhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- RHS = ImpCastExprToType(RHS.take(), destType, CK_NoOp);
+ RHS = ImpCastExprToType(RHS.get(), destType, CK_NoOp);
// Promote to void*.
- LHS = ImpCastExprToType(LHS.take(), destType, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.get(), destType, CK_BitCast);
return destType;
}
return QualType();
@@ -5973,7 +6080,7 @@
if (commonExpr->hasPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(commonExpr);
if (!result.isUsable()) return ExprError();
- commonExpr = result.take();
+ commonExpr = result.get();
}
// We usually want to apply unary conversions *before* saving, except
// in the special case of a C++ l-value conditional.
@@ -5987,7 +6094,7 @@
ExprResult commonRes = UsualUnaryConversions(commonExpr);
if (commonRes.isInvalid())
return ExprError();
- commonExpr = commonRes.take();
+ commonExpr = commonRes.get();
}
opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(),
@@ -6000,7 +6107,7 @@
ExprValueKind VK = VK_RValue;
ExprObjectKind OK = OK_Ordinary;
- ExprResult Cond = Owned(CondExpr), LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
+ ExprResult Cond = CondExpr, LHS = LHSExpr, RHS = RHSExpr;
QualType result = CheckConditionalOperands(Cond, LHS, RHS,
VK, OK, QuestionLoc);
if (result.isNull() || Cond.isInvalid() || LHS.isInvalid() ||
@@ -6011,14 +6118,13 @@
RHS.get());
if (!commonExpr)
- return Owned(new (Context) ConditionalOperator(Cond.take(), QuestionLoc,
- LHS.take(), ColonLoc,
- RHS.take(), result, VK, OK));
+ return new (Context)
+ ConditionalOperator(Cond.get(), QuestionLoc, LHS.get(), ColonLoc,
+ RHS.get(), result, VK, OK);
- return Owned(new (Context)
- BinaryConditionalOperator(commonExpr, opaqueValue, Cond.take(), LHS.take(),
- RHS.take(), QuestionLoc, ColonLoc, result, VK,
- OK));
+ return new (Context) BinaryConditionalOperator(
+ commonExpr, opaqueValue, Cond.get(), LHS.get(), RHS.get(), QuestionLoc,
+ ColonLoc, result, VK, OK);
}
// checkPointerTypesForAssignment - This is a very tricky routine (despite
@@ -6270,7 +6376,7 @@
if (result != Compatible)
return result;
if (Kind != CK_NoOp)
- RHS = ImpCastExprToType(RHS.take(), AtomicTy->getValueType(), Kind);
+ RHS = ImpCastExprToType(RHS.get(), AtomicTy->getValueType(), Kind);
Kind = CK_NonAtomicToAtomic;
return Compatible;
}
@@ -6301,7 +6407,7 @@
QualType elType = cast<ExtVectorType>(LHSType)->getElementType();
if (elType != RHSType) {
Kind = PrepareScalarCast(RHS, elType);
- RHS = ImpCastExprToType(RHS.take(), elType, Kind);
+ RHS = ImpCastExprToType(RHS.get(), elType, Kind);
}
Kind = CK_VectorSplat;
return Compatible;
@@ -6452,8 +6558,9 @@
return IncompatiblePointer;
}
- // T^ -> A*
- if (RHSType->isBlockPointerType()) {
+ // Only under strict condition T^ is compatible with an Objective-C pointer.
+ if (RHSType->isBlockPointerType() &&
+ isObjCPtrBlockCompatible(*this, Context, LHSType)) {
maybeExtendBlockObject(*this, RHS);
Kind = CK_BlockPointerToObjCPointerCast;
return Compatible;
@@ -6514,7 +6621,7 @@
FieldDecl *Field) {
// Build an initializer list that designates the appropriate member
// of the transparent union.
- Expr *E = EResult.take();
+ Expr *E = EResult.get();
InitListExpr *Initializer = new (C) InitListExpr(C, SourceLocation(),
E, SourceLocation());
Initializer->setType(UnionType);
@@ -6523,9 +6630,8 @@
// Build a compound literal constructing a value of the transparent
// union type from this initializer list.
TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType);
- EResult = S.Owned(
- new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
- VK_RValue, Initializer, false));
+ EResult = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType,
+ VK_RValue, Initializer, false);
}
Sema::AssignConvertType
@@ -6550,14 +6656,14 @@
// 2) null pointer constant
if (RHSType->isPointerType())
if (RHSType->castAs<PointerType>()->getPointeeType()->isVoidType()) {
- RHS = ImpCastExprToType(RHS.take(), it->getType(), CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), it->getType(), CK_BitCast);
InitField = it;
break;
}
if (RHS.get()->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- RHS = ImpCastExprToType(RHS.take(), it->getType(),
+ RHS = ImpCastExprToType(RHS.get(), it->getType(),
CK_NullToPointer);
InitField = it;
break;
@@ -6567,7 +6673,7 @@
CastKind Kind = CK_Invalid;
if (CheckAssignmentConstraints(it->getType(), RHS, Kind)
== Compatible) {
- RHS = ImpCastExprToType(RHS.take(), it->getType(), Kind);
+ RHS = ImpCastExprToType(RHS.get(), it->getType(), Kind);
InitField = it;
break;
}
@@ -6632,7 +6738,7 @@
CastKind Kind;
CXXCastPath Path;
CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false);
- RHS = ImpCastExprToType(RHS.take(), LHSType, Kind, VK_RValue, &Path);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, Kind, VK_RValue, &Path);
return Compatible;
}
@@ -6643,7 +6749,7 @@
//
// Suppress this for references: C++ 8.5.3p5.
if (!LHSType->isReferenceType()) {
- RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+ RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
if (RHS.isInvalid())
return Incompatible;
}
@@ -6660,7 +6766,7 @@
// does not have reference type.
if (result != Incompatible && RHS.get()->getType() != LHSType) {
QualType Ty = LHSType.getNonLValueExprType(Context);
- Expr *E = RHS.take();
+ Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
DiagnoseCFAudited);
@@ -6668,7 +6774,7 @@
(CheckObjCBridgeRelatedConversions(E->getLocStart(),
LHSType, E->getType(), E) ||
ConversionToObjCStringLiteralCheck(LHSType, E))) {
- RHS = Owned(E);
+ RHS = E;
return Compatible;
}
@@ -6726,8 +6832,8 @@
// Adjust scalar if desired.
if (scalar) {
if (scalarCast != CK_Invalid)
- *scalar = S.ImpCastExprToType(scalar->take(), vectorEltTy, scalarCast);
- *scalar = S.ImpCastExprToType(scalar->take(), vectorTy, CK_VectorSplat);
+ *scalar = S.ImpCastExprToType(scalar->get(), vectorEltTy, scalarCast);
+ *scalar = S.ImpCastExprToType(scalar->get(), vectorTy, CK_VectorSplat);
}
return false;
}
@@ -6735,11 +6841,11 @@
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign) {
if (!IsCompAssign) {
- LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
+ LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
if (LHS.isInvalid())
return QualType();
}
- RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+ RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
if (RHS.isInvalid())
return QualType();
@@ -6760,12 +6866,12 @@
if (LHSVecType && RHSVecType &&
Context.areCompatibleVectorTypes(LHSType, RHSType)) {
if (isa<ExtVectorType>(LHSVecType)) {
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
return LHSType;
}
if (!IsCompAssign)
- LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
return RHSType;
}
@@ -6789,7 +6895,7 @@
// FIXME: We really just pick the LHS type arbitrarily?
if (isLaxVectorConversion(RHSType, LHSType)) {
QualType resultType = LHSType;
- RHS = ImpCastExprToType(RHS.take(), resultType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), resultType, CK_BitCast);
return resultType;
}
@@ -7402,14 +7508,14 @@
// For the LHS, do usual unary conversions, but then reset them away
// if this is a compound assignment.
ExprResult OldLHS = LHS;
- LHS = UsualUnaryConversions(LHS.take());
+ LHS = UsualUnaryConversions(LHS.get());
if (LHS.isInvalid())
return QualType();
QualType LHSType = LHS.get()->getType();
if (IsCompAssign) LHS = OldLHS;
// The RHS is simpler.
- RHS = UsualUnaryConversions(RHS.take());
+ RHS = UsualUnaryConversions(RHS.get());
if (RHS.isInvalid())
return QualType();
QualType RHSType = RHS.get()->getType();
@@ -7521,8 +7627,8 @@
<< LHSType << RHSType << T << LHS.get()->getSourceRange()
<< RHS.get()->getSourceRange();
- LHS = S.ImpCastExprToType(LHS.take(), T, CK_BitCast);
- RHS = S.ImpCastExprToType(RHS.take(), T, CK_BitCast);
+ LHS = S.ImpCastExprToType(LHS.get(), T, CK_BitCast);
+ RHS = S.ImpCastExprToType(RHS.get(), T, CK_BitCast);
return false;
}
@@ -7588,7 +7694,7 @@
if (!Method)
return false;
- QualType T = Method->param_begin()[0]->getType();
+ QualType T = Method->parameters()[0]->getType();
if (!T->isObjCObjectPointerType())
return false;
@@ -7911,7 +8017,7 @@
if (isSFINAEContext())
return QualType();
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
return ResultTy;
}
}
@@ -7947,9 +8053,9 @@
CastKind Kind = AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion
: CK_BitCast;
if (LHSIsNull && !RHSIsNull)
- LHS = ImpCastExprToType(LHS.take(), RHSType, Kind);
+ LHS = ImpCastExprToType(LHS.get(), RHSType, Kind);
else
- RHS = ImpCastExprToType(RHS.take(), LHSType, Kind);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, Kind);
}
return ResultTy;
}
@@ -7965,7 +8071,7 @@
((LHSType->isAnyPointerType() || LHSType->isNullPtrType()) ||
(!IsRelational &&
(LHSType->isMemberPointerType() || LHSType->isBlockPointerType())))) {
- RHS = ImpCastExprToType(RHS.take(), LHSType,
+ RHS = ImpCastExprToType(RHS.get(), LHSType,
LHSType->isMemberPointerType()
? CK_NullToMemberPointer
: CK_NullToPointer);
@@ -7975,7 +8081,7 @@
((RHSType->isAnyPointerType() || RHSType->isNullPtrType()) ||
(!IsRelational &&
(RHSType->isMemberPointerType() || RHSType->isBlockPointerType())))) {
- LHS = ImpCastExprToType(LHS.take(), RHSType,
+ LHS = ImpCastExprToType(LHS.get(), RHSType,
RHSType->isMemberPointerType()
? CK_NullToMemberPointer
: CK_NullToPointer);
@@ -8011,7 +8117,7 @@
<< LHSType << RHSType << LHS.get()->getSourceRange()
<< RHS.get()->getSourceRange();
}
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
return ResultTy;
}
@@ -8029,11 +8135,11 @@
<< RHS.get()->getSourceRange();
}
if (LHSIsNull && !RHSIsNull)
- LHS = ImpCastExprToType(LHS.take(), RHSType,
+ LHS = ImpCastExprToType(LHS.get(), RHSType,
RHSType->isPointerType() ? CK_BitCast
: CK_AnyPointerToBlockPointerCast);
else
- RHS = ImpCastExprToType(RHS.take(), LHSType,
+ RHS = ImpCastExprToType(RHS.get(), LHSType,
LHSType->isPointerType() ? CK_BitCast
: CK_AnyPointerToBlockPointerCast);
return ResultTy;
@@ -8053,16 +8159,17 @@
/*isError*/false);
}
if (LHSIsNull && !RHSIsNull) {
- Expr *E = LHS.take();
+ Expr *E = LHS.get();
if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), RHSType, E, CCK_ImplicitConversion);
LHS = ImpCastExprToType(E, RHSType,
RPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
}
else {
- Expr *E = RHS.take();
+ Expr *E = RHS.get();
if (getLangOpts().ObjCAutoRefCount)
- CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion);
+ CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion, false,
+ Opc);
RHS = ImpCastExprToType(E, LHSType,
LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
}
@@ -8077,9 +8184,9 @@
diagnoseObjCLiteralComparison(*this, Loc, LHS, RHS, Opc);
if (LHSIsNull && !RHSIsNull)
- LHS = ImpCastExprToType(LHS.take(), RHSType, CK_BitCast);
+ LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast);
else
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_BitCast);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
return ResultTy;
}
}
@@ -8111,10 +8218,10 @@
}
if (LHSType->isIntegerType())
- LHS = ImpCastExprToType(LHS.take(), RHSType,
+ LHS = ImpCastExprToType(LHS.get(), RHSType,
LHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
else
- RHS = ImpCastExprToType(RHS.take(), LHSType,
+ RHS = ImpCastExprToType(RHS.get(), LHSType,
RHSIsNull ? CK_NullToPointer : CK_IntegralToPointer);
return ResultTy;
}
@@ -8122,12 +8229,12 @@
// Handle block pointers.
if (!IsRelational && RHSIsNull
&& LHSType->isBlockPointerType() && RHSType->isIntegerType()) {
- RHS = ImpCastExprToType(RHS.take(), LHSType, CK_NullToPointer);
+ RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
return ResultTy;
}
if (!IsRelational && LHSIsNull
&& LHSType->isIntegerType() && RHSType->isBlockPointerType()) {
- LHS = ImpCastExprToType(LHS.take(), RHSType, CK_NullToPointer);
+ LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
return ResultTy;
}
@@ -8228,13 +8335,13 @@
return InvalidOperands(Loc, LHS, RHS);
}
- ExprResult LHSResult = Owned(LHS), RHSResult = Owned(RHS);
+ ExprResult LHSResult = LHS, RHSResult = RHS;
QualType compType = UsualArithmeticConversions(LHSResult, RHSResult,
IsCompAssign);
if (LHSResult.isInvalid() || RHSResult.isInvalid())
return QualType();
- LHS = LHSResult.take();
- RHS = RHSResult.take();
+ LHS = LHSResult.get();
+ RHS = RHSResult.get();
if (!compType.isNull() && compType->isIntegralOrUnscopedEnumerationType())
return compType;
@@ -8297,11 +8404,11 @@
return InvalidOperands(Loc, LHS, RHS);
}
- LHS = UsualUnaryConversions(LHS.take());
+ LHS = UsualUnaryConversions(LHS.get());
if (LHS.isInvalid())
return QualType();
- RHS = UsualUnaryConversions(RHS.take());
+ RHS = UsualUnaryConversions(RHS.get());
if (RHS.isInvalid())
return QualType();
@@ -8581,10 +8688,8 @@
// we do not warn to warn spuriously when 'x' and 'y' are on separate
// paths through the function. This should be revisited if
// -Wrepeated-use-of-weak is made flow-sensitive.
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- RHS.get()->getLocStart());
- if (Level != DiagnosticsEngine::Ignored)
+ if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+ RHS.get()->getLocStart()))
getCurFunction()->markSafeWeakUse(RHS.get());
} else if (getLangOpts().ObjCAutoRefCount) {
@@ -8616,8 +8721,8 @@
// C99 6.5.17
static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc) {
- LHS = S.CheckPlaceholderExpr(LHS.take());
- RHS = S.CheckPlaceholderExpr(RHS.take());
+ LHS = S.CheckPlaceholderExpr(LHS.get());
+ RHS = S.CheckPlaceholderExpr(RHS.get());
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
@@ -8627,14 +8732,14 @@
// So we treat the LHS as a ignored value, and in C++ we allow the
// containing site to determine what should be done with the RHS.
- LHS = S.IgnoredValueConversions(LHS.take());
+ LHS = S.IgnoredValueConversions(LHS.get());
if (LHS.isInvalid())
return QualType();
S.DiagnoseUnusedExprResult(LHS.get());
if (!S.getLangOpts().CPlusPlus) {
- RHS = S.DefaultFunctionArrayLvalueConversion(RHS.take());
+ RHS = S.DefaultFunctionArrayLvalueConversion(RHS.get());
if (RHS.isInvalid())
return QualType();
if (!RHS.get()->getType()->isVoidType())
@@ -8694,7 +8799,7 @@
} else if (ResType->isPlaceholderType()) {
ExprResult PR = S.CheckPlaceholderExpr(Op);
if (PR.isInvalid()) return QualType();
- return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc,
+ return CheckIncrementDecrementOperand(S, PR.get(), VK, OpLoc,
IsInc, IsPrefix);
} else if (S.getLangOpts().AltiVec && ResType->isVectorType()) {
// OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 )
@@ -8835,7 +8940,7 @@
return QualType();
}
- OrigOp = CheckPlaceholderExpr(OrigOp.take());
+ OrigOp = CheckPlaceholderExpr(OrigOp.get());
if (OrigOp.isInvalid()) return QualType();
}
@@ -8877,7 +8982,7 @@
return QualType();
// Materialize the temporary as an lvalue so that we can take its address.
OrigOp = op = new (Context)
- MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true);
+ MaterializeTemporaryExpr(op->getType(), OrigOp.get(), true);
} else if (isa<ObjCSelectorExpr>(op)) {
return Context.getPointerType(op->getType());
} else if (lval == Expr::LV_MemberFunction) {
@@ -9008,7 +9113,7 @@
ExprResult ConvResult = S.UsualUnaryConversions(Op);
if (ConvResult.isInvalid())
return QualType();
- Op = ConvResult.take();
+ Op = ConvResult.get();
QualType OpTy = Op->getType();
QualType Result;
@@ -9026,8 +9131,8 @@
else {
ExprResult PR = S.CheckPlaceholderExpr(Op);
if (PR.isInvalid()) return QualType();
- if (PR.take() != Op)
- return CheckIndirectionOperand(S, PR.take(), VK, OpLoc);
+ if (PR.get() != Op)
+ return CheckIndirectionOperand(S, PR.get(), VK, OpLoc);
}
if (Result.isNull()) {
@@ -9218,10 +9323,10 @@
ExprResult Init = InitSeq.Perform(*this, Entity, Kind, RHSExpr);
if (Init.isInvalid())
return Init;
- RHSExpr = Init.take();
+ RHSExpr = Init.get();
}
- ExprResult LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
+ ExprResult LHS = LHSExpr, RHS = RHSExpr;
QualType ResultTy; // Result type of the binary operator.
// The following two variables are used for compound assignment operators
QualType CompLHSTy; // Type of LHS after promotions for computation
@@ -9315,8 +9420,9 @@
ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy);
break;
case BO_AndAssign:
+ case BO_OrAssign: // fallthrough
+ DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc);
case BO_XorAssign:
- case BO_OrAssign:
CompResultTy = CheckBitwiseOperands(LHS, RHS, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid())
@@ -9356,18 +9462,16 @@
DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get());
if (CompResultTy.isNull())
- return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc,
- ResultTy, VK, OK, OpLoc,
- FPFeatures.fp_contract));
+ return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
+ OK, OpLoc, FPFeatures.fp_contract);
if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
OK_ObjCProperty) {
VK = VK_LValue;
OK = LHS.get()->getObjectKind();
}
- return Owned(new (Context) CompoundAssignOperator(LHS.take(), RHS.take(), Opc,
- ResultTy, VK, OK, CompLHSTy,
- CompResultTy, OpLoc,
- FPFeatures.fp_contract));
+ return new (Context) CompoundAssignOperator(
+ LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
+ OpLoc, FPFeatures.fp_contract);
}
/// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
@@ -9639,7 +9743,7 @@
// instantiates to having an overloadable type.
ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
if (resolvedRHS.isInvalid()) return ExprError();
- RHSExpr = resolvedRHS.take();
+ RHSExpr = resolvedRHS.get();
if (RHSExpr->isTypeDependent() ||
RHSExpr->getType()->isOverloadableType())
@@ -9648,7 +9752,7 @@
ExprResult LHS = CheckPlaceholderExpr(LHSExpr);
if (LHS.isInvalid()) return ExprError();
- LHSExpr = LHS.take();
+ LHSExpr = LHS.get();
}
// Handle pseudo-objects in the RHS.
@@ -9672,7 +9776,7 @@
ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
if (!resolvedRHS.isUsable()) return ExprError();
- RHSExpr = resolvedRHS.take();
+ RHSExpr = resolvedRHS.get();
}
if (getLangOpts().CPlusPlus) {
@@ -9695,7 +9799,7 @@
ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
UnaryOperatorKind Opc,
Expr *InputExpr) {
- ExprResult Input = Owned(InputExpr);
+ ExprResult Input = InputExpr;
ExprValueKind VK = VK_RValue;
ExprObjectKind OK = OK_Ordinary;
QualType resultType;
@@ -9714,14 +9818,14 @@
resultType = CheckAddressOfOperand(Input, OpLoc);
break;
case UO_Deref: {
- Input = DefaultFunctionArrayLvalueConversion(Input.take());
+ Input = DefaultFunctionArrayLvalueConversion(Input.get());
if (Input.isInvalid()) return ExprError();
resultType = CheckIndirectionOperand(*this, Input.get(), VK, OpLoc);
break;
}
case UO_Plus:
case UO_Minus:
- Input = UsualUnaryConversions(Input.take());
+ Input = UsualUnaryConversions(Input.get());
if (Input.isInvalid()) return ExprError();
resultType = Input.get()->getType();
if (resultType->isDependentType())
@@ -9738,7 +9842,7 @@
<< resultType << Input.get()->getSourceRange());
case UO_Not: // bitwise complement
- Input = UsualUnaryConversions(Input.take());
+ Input = UsualUnaryConversions(Input.get());
if (Input.isInvalid())
return ExprError();
resultType = Input.get()->getType();
@@ -9769,13 +9873,13 @@
case UO_LNot: // logical negation
// Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
- Input = DefaultFunctionArrayLvalueConversion(Input.take());
+ Input = DefaultFunctionArrayLvalueConversion(Input.get());
if (Input.isInvalid()) return ExprError();
resultType = Input.get()->getType();
// Though we still have to promote half FP to float...
if (resultType->isHalfType() && !Context.getLangOpts().NativeHalfType) {
- Input = ImpCastExprToType(Input.take(), Context.FloatTy, CK_FloatingCast).take();
+ Input = ImpCastExprToType(Input.get(), Context.FloatTy, CK_FloatingCast).get();
resultType = Context.FloatTy;
}
@@ -9786,7 +9890,7 @@
if (Context.getLangOpts().CPlusPlus) {
// C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9:
// operand contextually converted to bool.
- Input = ImpCastExprToType(Input.take(), Context.BoolTy,
+ Input = ImpCastExprToType(Input.get(), Context.BoolTy,
ScalarTypeToBooleanCastKind(resultType));
} else if (Context.getLangOpts().OpenCL &&
Context.getLangOpts().OpenCLVersion < 120) {
@@ -9830,7 +9934,7 @@
VK = Input.get()->getValueKind();
} else if (!getLangOpts().CPlusPlus) {
// In C, a volatile scalar is read by __imag. In C++, it is not.
- Input = DefaultLvalueConversion(Input.take());
+ Input = DefaultLvalueConversion(Input.get());
}
break;
case UO_Extension:
@@ -9849,8 +9953,8 @@
if (Opc != UO_AddrOf && Opc != UO_Deref)
CheckArrayAccess(Input.get());
- return Owned(new (Context) UnaryOperator(Input.take(), Opc, resultType,
- VK, OK, OpLoc));
+ return new (Context)
+ UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc);
}
/// \brief Determine whether the given expression is a qualified member
@@ -9920,7 +10024,7 @@
// Anything else needs to be handled now.
ExprResult Result = CheckPlaceholderExpr(Input);
if (Result.isInvalid()) return ExprError();
- Input = Result.take();
+ Input = Result.get();
}
if (getLangOpts().CPlusPlus && Input->getType()->isOverloadableType() &&
@@ -9953,8 +10057,8 @@
LabelDecl *TheDecl) {
TheDecl->markUsed(Context);
// Create the AST node. The address of a label always has type 'void*'.
- return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
- Context.getPointerType(Context.VoidTy)));
+ return new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
+ Context.getPointerType(Context.VoidTy));
}
/// Given the last statement in a statement-expression, check whether
@@ -10056,9 +10160,9 @@
return ExprError();
if (LastExpr.get() != nullptr) {
if (!LastLabelStmt)
- Compound->setLastStmt(LastExpr.take());
+ Compound->setLastStmt(LastExpr.get());
else
- LastLabelStmt->setSubStmt(LastExpr.take());
+ LastLabelStmt->setSubStmt(LastExpr.get());
StmtExprMayBindToTemp = true;
}
}
@@ -10070,7 +10174,7 @@
Expr *ResStmtExpr = new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc);
if (StmtExprMayBindToTemp)
return MaybeBindToTemporary(ResStmtExpr);
- return Owned(ResStmtExpr);
+ return ResStmtExpr;
}
ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
@@ -10125,7 +10229,7 @@
ExprResult IdxRval = DefaultLvalueConversion(static_cast<Expr*>(OC.U.E));
if (IdxRval.isInvalid())
return ExprError();
- Expr *Idx = IdxRval.take();
+ Expr *Idx = IdxRval.get();
// The expression must be an integral expression.
// FIXME: An integral constant expression?
@@ -10243,8 +10347,8 @@
CurrentType = MemberDecl->getType().getNonReferenceType();
}
- return Owned(OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc,
- TInfo, Comps, Exprs, RParenLoc));
+ return OffsetOfExpr::Create(Context, Context.getSizeType(), BuiltinLoc, TInfo,
+ Comps, Exprs, RParenLoc);
}
ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
@@ -10290,7 +10394,7 @@
diag::err_typecheck_choose_expr_requires_constant, false);
if (CondICE.isInvalid())
return ExprError();
- CondExpr = CondICE.take();
+ CondExpr = CondICE.get();
CondIsTrue = condEval.getZExtValue();
// If the condition is > zero, then the AST type is the same as the LSHExpr.
@@ -10302,10 +10406,9 @@
OK = ActiveExpr->getObjectKind();
}
- return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
- resType, VK, OK, RPLoc, CondIsTrue,
- resType->isDependentType(),
- ValueDependent));
+ return new (Context)
+ ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, resType, VK, OK, RPLoc,
+ CondIsTrue, resType->isDependentType(), ValueDependent);
}
//===----------------------------------------------------------------------===//
@@ -10585,7 +10688,7 @@
}
}
- return Owned(Result);
+ return Result;
}
ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
@@ -10612,7 +10715,7 @@
ExprResult Result = UsualUnaryConversions(E);
if (Result.isInvalid())
return ExprError();
- E = Result.take();
+ E = Result.get();
} else if (VaListType->isRecordType() && getLangOpts().CPlusPlus) {
// If va_list is a record type and we are compiling in C++ mode,
// check the argument using reference binding.
@@ -10622,7 +10725,7 @@
ExprResult Init = PerformCopyInitialization(Entity, SourceLocation(), E);
if (Init.isInvalid())
return ExprError();
- E = Init.takeAs<Expr>();
+ E = Init.getAs<Expr>();
} else {
// Otherwise, the va_list argument must be an l-value because
// it is modified by va_arg.
@@ -10678,7 +10781,7 @@
}
QualType T = TInfo->getType().getNonLValueExprType(Context);
- return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
+ return new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T);
}
ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
@@ -10696,7 +10799,7 @@
llvm_unreachable("I don't know size of pointer!");
}
- return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
+ return new (Context) GNUNullExpr(Ty, TokenLoc);
}
bool
@@ -10728,7 +10831,7 @@
return false;
Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
<< FixItHint::CreateInsertion(SL->getLocStart(), "@");
- Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).take();
+ Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).get();
return true;
}
@@ -10748,6 +10851,8 @@
ConversionFixItGenerator ConvHints;
bool MayHaveConvFixit = false;
bool MayHaveFunctionDiff = false;
+ const ObjCInterfaceDecl *IFace = nullptr;
+ const ObjCProtocolDecl *PDecl = nullptr;
switch (ConvTy) {
case Compatible:
@@ -10829,11 +10934,32 @@
case IncompatibleBlockPointer:
DiagKind = diag::err_typecheck_convert_incompatible_block_pointer;
break;
- case IncompatibleObjCQualifiedId:
- // FIXME: Diagnose the problem in ObjCQualifiedIdTypesAreCompatible, since
- // it can give a more specific diagnostic.
+ case IncompatibleObjCQualifiedId: {
+ if (SrcType->isObjCQualifiedIdType()) {
+ const ObjCObjectPointerType *srcOPT =
+ SrcType->getAs<ObjCObjectPointerType>();
+ for (auto *srcProto : srcOPT->quals()) {
+ PDecl = srcProto;
+ break;
+ }
+ if (const ObjCInterfaceType *IFaceT =
+ DstType->getAs<ObjCObjectPointerType>()->getInterfaceType())
+ IFace = IFaceT->getDecl();
+ }
+ else if (DstType->isObjCQualifiedIdType()) {
+ const ObjCObjectPointerType *dstOPT =
+ DstType->getAs<ObjCObjectPointerType>();
+ for (auto *dstProto : dstOPT->quals()) {
+ PDecl = dstProto;
+ break;
+ }
+ if (const ObjCInterfaceType *IFaceT =
+ SrcType->getAs<ObjCObjectPointerType>()->getInterfaceType())
+ IFace = IFaceT->getDecl();
+ }
DiagKind = diag::warn_incompatible_qualified_id;
break;
+ }
case IncompatibleVectors:
DiagKind = diag::warn_incompatible_vectors;
break;
@@ -10891,7 +11017,11 @@
HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
Diag(Loc, FDiag);
-
+ if (DiagKind == diag::warn_incompatible_qualified_id &&
+ PDecl && IFace && !IFace->hasDefinition())
+ Diag(IFace->getLocation(), diag::not_incomplete_class_and_qualified_id)
+ << IFace->getName() << PDecl->getName();
+
if (SecondType == Context.OverloadTy)
NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression,
FirstType);
@@ -11004,7 +11134,7 @@
ConvertDiagnoser);
if (Converted.isInvalid())
return Converted;
- E = Converted.take();
+ E = Converted.get();
if (!E->getType()->isIntegralOrUnscopedEnumerationType())
return ExprError();
} else if (!E->getType()->isIntegralOrUnscopedEnumerationType()) {
@@ -11019,7 +11149,7 @@
if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) {
if (Result)
*Result = E->EvaluateKnownConstInt(Context);
- return Owned(E);
+ return E;
}
Expr::EvalResult EvalResult;
@@ -11037,7 +11167,7 @@
if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) {
if (Result)
*Result = EvalResult.Val.getInt();
- return Owned(E);
+ return E;
}
// If our only note is the usual "invalid subexpression" note, just point
@@ -11065,7 +11195,7 @@
if (Result)
*Result = EvalResult.Val.getInt();
- return Owned(E);
+ return E;
}
namespace {
@@ -11304,7 +11434,7 @@
Constructor = cast<CXXConstructorDecl>(Constructor->getFirstDecl());
if (Constructor->isDefaulted() && !Constructor->isDeleted()) {
if (Constructor->isDefaultConstructor()) {
- if (Constructor->isTrivial())
+ if (Constructor->isTrivial() && !Constructor->hasAttr<DLLExportAttr>())
return;
DefineImplicitDefaultConstructor(Loc, Constructor);
} else if (Constructor->isCopyConstructor()) {
@@ -11469,8 +11599,8 @@
<< var->getIdentifier();
}
- S.Diag(var->getLocation(), diag::note_local_variable_declared_here)
- << var->getIdentifier();
+ S.Diag(var->getLocation(), diag::note_entity_declared_at)
+ << var->getIdentifier();
// FIXME: Add additional diagnostic info about class etc. which prevents
// capture.
@@ -11538,7 +11668,7 @@
}
// Prohibit variably-modified types; they're difficult to deal with.
- if (Var->getType()->isVariablyModifiedType()) {
+ if (Var->getType()->isVariablyModifiedType() && (IsBlock || IsLambda)) {
if (Diagnose) {
if (IsBlock)
S.Diag(Loc, diag::err_ref_vm_type);
@@ -11647,7 +11777,7 @@
= S.PerformCopyInitialization(
InitializedEntity::InitializeBlock(Var->getLocation(),
CaptureType, false),
- Loc, S.Owned(DeclRef));
+ Loc, DeclRef);
// Build a full-expression copy expression if initialization
// succeeded and used a non-trivial constructor. Recover from
@@ -11656,7 +11786,7 @@
!cast<CXXConstructExpr>(Result.get())->getConstructor()
->isTrivial()) {
Result = S.MaybeCreateExprWithCleanups(Result);
- CopyExpr = Result.take();
+ CopyExpr = Result.get();
}
}
}
@@ -11788,20 +11918,20 @@
= S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc);
assert(!IterationVarRef.isInvalid() &&
"Reference to invented variable cannot fail!");
- IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take());
+ IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.get());
assert(!IterationVarRef.isInvalid() &&
"Conversion of invented variable cannot fail!");
// Subscript the array with this iteration variable.
ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr(
- Ref, Loc, IterationVarRef.take(), Loc);
+ Ref, Loc, IterationVarRef.get(), Loc);
if (Subscript.isInvalid()) {
S.CleanupVarDeclMarking();
S.DiscardCleanupsInEvaluationContext();
return ExprError();
}
- Ref = Subscript.take();
+ Ref = Subscript.get();
BaseType = Array->getElementType();
}
@@ -11922,7 +12052,7 @@
CaptureType, DeclRefType, Loc,
RefersToEnclosingLocal);
if (!Result.isInvalid())
- CopyExpr = Result.take();
+ CopyExpr = Result.get();
}
// Compute the type of a reference to this captured variable.
@@ -12025,8 +12155,107 @@
// certain types of variables (unnamed, variably modified types etc.)
// so check for eligibility.
if (!isVariableCapturable(CSI, Var, ExprLoc, BuildAndDiagnose, *this))
- return true;
-
+ return true;
+
+ // Try to capture variable-length arrays types.
+ if (Var->getType()->isVariablyModifiedType()) {
+ // We're going to walk down into the type and look for VLA
+ // expressions.
+ QualType QTy = Var->getType();
+ if (ParmVarDecl *PVD = dyn_cast_or_null<ParmVarDecl>(Var))
+ QTy = PVD->getOriginalType();
+ do {
+ const Type *Ty = QTy.getTypePtr();
+ switch (Ty->getTypeClass()) {
+#define TYPE(Class, Base)
+#define ABSTRACT_TYPE(Class, Base)
+#define NON_CANONICAL_TYPE(Class, Base)
+#define DEPENDENT_TYPE(Class, Base) case Type::Class:
+#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+ QTy = QualType();
+ break;
+ // These types are never variably-modified.
+ case Type::Builtin:
+ case Type::Complex:
+ case Type::Vector:
+ case Type::ExtVector:
+ case Type::Record:
+ case Type::Enum:
+ case Type::Elaborated:
+ case Type::TemplateSpecialization:
+ case Type::ObjCObject:
+ case Type::ObjCInterface:
+ case Type::ObjCObjectPointer:
+ llvm_unreachable("type class is never variably-modified!");
+ case Type::Adjusted:
+ QTy = cast<AdjustedType>(Ty)->getOriginalType();
+ break;
+ case Type::Decayed:
+ QTy = cast<DecayedType>(Ty)->getPointeeType();
+ break;
+ case Type::Pointer:
+ QTy = cast<PointerType>(Ty)->getPointeeType();
+ break;
+ case Type::BlockPointer:
+ QTy = cast<BlockPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::LValueReference:
+ case Type::RValueReference:
+ QTy = cast<ReferenceType>(Ty)->getPointeeType();
+ break;
+ case Type::MemberPointer:
+ QTy = cast<MemberPointerType>(Ty)->getPointeeType();
+ break;
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ // Losing element qualification here is fine.
+ QTy = cast<ArrayType>(Ty)->getElementType();
+ break;
+ case Type::VariableArray: {
+ // Losing element qualification here is fine.
+ const VariableArrayType *Vat = cast<VariableArrayType>(Ty);
+
+ // Unknown size indication requires no size computation.
+ // Otherwise, evaluate and record it.
+ if (Expr *Size = Vat->getSizeExpr()) {
+ MarkDeclarationsReferencedInExpr(Size);
+ }
+ QTy = Vat->getElementType();
+ break;
+ }
+ case Type::FunctionProto:
+ case Type::FunctionNoProto:
+ QTy = cast<FunctionType>(Ty)->getReturnType();
+ break;
+ case Type::Paren:
+ case Type::TypeOf:
+ case Type::UnaryTransform:
+ case Type::Attributed:
+ case Type::SubstTemplateTypeParm:
+ case Type::PackExpansion:
+ // Keep walking after single level desugaring.
+ QTy = QTy.getSingleStepDesugaredType(getASTContext());
+ break;
+ case Type::Typedef:
+ QTy = cast<TypedefType>(Ty)->desugar();
+ break;
+ case Type::Decltype:
+ QTy = cast<DecltypeType>(Ty)->desugar();
+ break;
+ case Type::Auto:
+ QTy = cast<AutoType>(Ty)->getDeducedType();
+ break;
+ case Type::TypeOfExpr:
+ QTy = cast<TypeOfExprType>(Ty)->getUnderlyingExpr()->getType();
+ break;
+ case Type::Atomic:
+ QTy = cast<AtomicType>(Ty)->getValueType();
+ break;
+ }
+ } while (!QTy.isNull() && QTy->isVariablyModifiedType());
+ }
+
if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) {
// No capture-default, and this is not an explicit capture
// so cannot capture this variable.
@@ -12586,9 +12815,8 @@
S.Diag(Loc, diag::err_call_function_incomplete_return)
<< CE->getSourceRange() << FD->getDeclName() << T;
- S.Diag(FD->getLocation(),
- diag::note_function_with_incomplete_return_type_declared_here)
- << FD->getDeclName();
+ S.Diag(FD->getLocation(), diag::note_entity_declared_at)
+ << FD->getDeclName();
}
} Diagnoser(FD, CE);
@@ -12692,7 +12920,7 @@
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
- E = result.take();
+ E = result.get();
if (!E->isTypeDependent()) {
if (getLangOpts().CPlusPlus)
@@ -12701,7 +12929,7 @@
ExprResult ERes = DefaultFunctionArrayLvalueConversion(E);
if (ERes.isInvalid())
return ExprError();
- E = ERes.take();
+ E = ERes.get();
QualType T = E->getType();
if (!T->isScalarType()) { // C99 6.8.4.1p1
@@ -12711,7 +12939,7 @@
}
}
- return Owned(E);
+ return E;
}
ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
@@ -12748,7 +12976,7 @@
ExprResult SubResult = Visit(E->getSubExpr());
if (SubResult.isInvalid()) return ExprError();
- Expr *SubExpr = SubResult.take();
+ Expr *SubExpr = SubResult.get();
E->setSubExpr(SubExpr);
E->setType(SubExpr->getType());
E->setValueKind(SubExpr->getValueKind());
@@ -12768,7 +12996,7 @@
ExprResult SubResult = Visit(E->getSubExpr());
if (SubResult.isInvalid()) return ExprError();
- Expr *SubExpr = SubResult.take();
+ Expr *SubExpr = SubResult.get();
E->setSubExpr(SubExpr);
E->setType(S.Context.getPointerType(SubExpr->getType()));
assert(E->getValueKind() == VK_RValue);
@@ -12805,7 +13033,7 @@
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *FunctionExpr) {
ExprResult Result = RebuildUnknownAnyFunction(S).Visit(FunctionExpr);
if (Result.isInvalid()) return ExprError();
- return S.DefaultFunctionArrayConversion(Result.take());
+ return S.DefaultFunctionArrayConversion(Result.get());
}
namespace {
@@ -12842,7 +13070,7 @@
template <class T> ExprResult rebuildSugarExpr(T *E) {
ExprResult SubResult = Visit(E->getSubExpr());
if (SubResult.isInvalid()) return ExprError();
- Expr *SubExpr = SubResult.take();
+ Expr *SubExpr = SubResult.get();
E->setSubExpr(SubExpr);
E->setType(SubExpr->getType());
E->setValueKind(SubExpr->getValueKind());
@@ -12873,7 +13101,7 @@
DestType = Ptr->getPointeeType();
ExprResult SubResult = Visit(E->getSubExpr());
if (SubResult.isInvalid()) return ExprError();
- E->setSubExpr(SubResult.take());
+ E->setSubExpr(SubResult.get());
return E;
}
@@ -12995,7 +13223,7 @@
// Finally, we can recurse.
ExprResult CalleeResult = Visit(CalleeExpr);
if (!CalleeResult.isUsable()) return ExprError();
- E->setCallee(CalleeResult.take());
+ E->setCallee(CalleeResult.get());
// Bind a temporary if necessary.
return S.MaybeBindToTemporary(E);
@@ -13036,8 +13264,8 @@
ExprResult Result = Visit(E->getSubExpr());
if (!Result.isUsable()) return ExprError();
- E->setSubExpr(Result.take());
- return S.Owned(E);
+ E->setSubExpr(Result.get());
+ return E;
} else if (E->getCastKind() == CK_LValueToRValue) {
assert(E->getValueKind() == VK_RValue);
assert(E->getObjectKind() == OK_Ordinary);
@@ -13052,8 +13280,8 @@
ExprResult Result = Visit(E->getSubExpr());
if (!Result.isUsable()) return ExprError();
- E->setSubExpr(Result.take());
- return S.Owned(E);
+ E->setSubExpr(Result.get());
+ return E;
} else {
llvm_unreachable("Unhandled cast type!");
}
@@ -13071,7 +13299,7 @@
DestType = Ptr->getPointeeType();
ExprResult Result = resolveDecl(E, VD);
if (Result.isInvalid()) return ExprError();
- return S.ImpCastExprToType(Result.take(), Type,
+ return S.ImpCastExprToType(Result.get(), Type,
CK_FunctionToPointerDecay, VK_RValue);
}
@@ -13113,7 +13341,7 @@
VD->setType(DestType);
E->setType(Type);
E->setValueKind(ValueKind);
- return S.Owned(E);
+ return E;
}
/// Check a cast of an unknown-any type. We intentionally only
@@ -13125,7 +13353,7 @@
ExprResult result = RebuildUnknownAnyExpr(*this, CastType).Visit(CastExpr);
if (!result.isUsable()) return ExprError();
- CastExpr = result.take();
+ CastExpr = result.get();
VK = CastExpr->getValueKind();
CastKind = CK_NoOp;
@@ -13156,7 +13384,7 @@
InitializedEntity entity =
InitializedEntity::InitializeParameter(Context, paramType,
/*consumed*/ false);
- return PerformCopyInitialization(entity, callLoc, Owned(arg));
+ return PerformCopyInitialization(entity, callLoc, arg);
}
static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) {
@@ -13206,7 +13434,7 @@
/// Returns true if there was an error and no recovery was possible.
ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType();
- if (!placeholderType) return Owned(E);
+ if (!placeholderType) return E;
switch (placeholderType->getKind()) {
@@ -13214,7 +13442,7 @@
case BuiltinType::Overload: {
// Try to resolve a single function template specialization.
// This is obligatory.
- ExprResult result = Owned(E);
+ ExprResult result = E;
if (ResolveAndFixSingleFunctionTemplateSpecialization(result, false)) {
return result;
@@ -13228,7 +13456,7 @@
// Bound member functions.
case BuiltinType::BoundMember: {
- ExprResult result = Owned(E);
+ ExprResult result = E;
tryToRecoverWithCall(result, PDiag(diag::err_bound_member_function),
/*complain*/ true);
return result;
@@ -13238,7 +13466,7 @@
case BuiltinType::ARCUnbridgedCast: {
Expr *realCast = stripARCUnbridgedCast(E);
diagnoseARCUnbridgedCast(realCast);
- return Owned(realCast);
+ return realCast;
}
// Expressions of unknown type.
@@ -13289,6 +13517,6 @@
}
if (Context.getBOOLDecl())
BoolT = Context.getBOOLType();
- return Owned(new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes,
- BoolT, OpLoc));
+ return new (Context)
+ ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, BoolT, OpLoc);
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e84f2f3..fc3ede0 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -15,6 +15,7 @@
#include "clang/Sema/SemaInternal.h"
#include "TypeLocBuilder.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclObjC.h"
@@ -379,9 +380,8 @@
RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
return ExprError();
- return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
- Operand,
- SourceRange(TypeidLoc, RParenLoc)));
+ return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
+ SourceRange(TypeidLoc, RParenLoc));
}
/// \brief Build a C++ typeid expression with an expression operand.
@@ -393,7 +393,7 @@
if (E->getType()->isPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return ExprError();
- E = result.take();
+ E = result.get();
}
QualType T = E->getType();
@@ -414,7 +414,7 @@
// and recheck the subexpression.
ExprResult Result = TransformToPotentiallyEvaluated(E);
if (Result.isInvalid()) return ExprError();
- E = Result.take();
+ E = Result.get();
// We require a vtable to query the type at run time.
MarkVTableUsed(TypeidLoc, RecordD);
@@ -430,13 +430,12 @@
QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
if (!Context.hasSameType(T, UnqualT)) {
T = UnqualT;
- E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).take();
+ E = ImpCastExprToType(E, UnqualT, CK_NoOp, E->getValueKind()).get();
}
}
- return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
- E,
- SourceRange(TypeidLoc, RParenLoc)));
+ return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
+ SourceRange(TypeidLoc, RParenLoc));
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
@@ -502,9 +501,8 @@
}
}
- return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
- Operand,
- SourceRange(TypeidLoc, RParenLoc)));
+ return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), Operand,
+ SourceRange(TypeidLoc, RParenLoc));
}
/// \brief Build a Microsoft __uuidof expression with an expression operand.
@@ -523,9 +521,8 @@
}
}
- return Owned(new (Context) CXXUuidofExpr(TypeInfoType.withConst(),
- E,
- SourceRange(TypeidLoc, RParenLoc)));
+ return new (Context) CXXUuidofExpr(TypeInfoType.withConst(), E,
+ SourceRange(TypeidLoc, RParenLoc));
}
/// ActOnCXXUuidof - Parse __uuidof( type-id ) or __uuidof (expression);
@@ -567,14 +564,14 @@
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
"Unknown C++ Boolean value!");
- return Owned(new (Context) CXXBoolLiteralExpr(Kind == tok::kw_true,
- Context.BoolTy, OpLoc));
+ return new (Context)
+ CXXBoolLiteralExpr(Kind == tok::kw_true, Context.BoolTy, OpLoc);
}
/// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
ExprResult
Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
- return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
+ return new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc);
}
/// ActOnCXXThrow - Parse throw expressions.
@@ -621,16 +618,19 @@
if (!getLangOpts().CXXExceptions &&
!getSourceManager().isInSystemHeader(OpLoc))
Diag(OpLoc, diag::err_exceptions_disabled) << "throw";
-
+
+ if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+ Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
+
if (Ex && !Ex->isTypeDependent()) {
ExprResult ExRes = CheckCXXThrowOperand(OpLoc, Ex, IsThrownVarInScope);
if (ExRes.isInvalid())
return ExprError();
- Ex = ExRes.take();
+ Ex = ExRes.get();
}
- return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc,
- IsThrownVarInScope));
+ return new (Context)
+ CXXThrowExpr(Ex, Context.VoidTy, OpLoc, IsThrownVarInScope);
}
/// CheckCXXThrowOperand - Validate the operand of a throw.
@@ -644,12 +644,12 @@
// or "pointer to function returning T", [...]
if (E->getType().hasQualifiers())
E = ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
- E->getValueKind()).take();
+ E->getValueKind()).get();
ExprResult Res = DefaultFunctionArrayConversion(E);
if (Res.isInvalid())
return ExprError();
- E = Res.take();
+ E = Res.get();
// If the type of the exception would be an incomplete type or a pointer
// to an incomplete type other than (cv) void the program is ill-formed.
@@ -697,12 +697,12 @@
IsThrownVarInScope);
if (Res.isInvalid())
return ExprError();
- E = Res.take();
+ E = Res.get();
// If the exception has class type, we need additional handling.
const RecordType *RecordTy = Ty->getAs<RecordType>();
if (!RecordTy)
- return Owned(E);
+ return E;
CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
// If we are throwing a polymorphic class type or pointer thereof,
@@ -711,22 +711,22 @@
// If a pointer is thrown, the referenced object will not be destroyed.
if (isPointer)
- return Owned(E);
+ return E;
// If the class has a destructor, we must be able to call it.
if (RD->hasIrrelevantDestructor())
- return Owned(E);
+ return E;
CXXDestructorDecl *Destructor = LookupDestructor(RD);
if (!Destructor)
- return Owned(E);
+ return E;
MarkFunctionReferenced(E->getExprLoc(), Destructor);
CheckDestructorAccess(E->getExprLoc(), Destructor,
PDiag(diag::err_access_dtor_exception) << Ty);
if (DiagnoseUseOfDecl(Destructor, E->getExprLoc()))
return ExprError();
- return Owned(E);
+ return E;
}
QualType Sema::getCurrentThisType() {
@@ -736,7 +736,20 @@
if (method && method->isInstance())
ThisTy = method->getThisType(Context);
}
-
+ if (ThisTy.isNull()) {
+ if (isGenericLambdaCallOperatorSpecialization(CurContext) &&
+ CurContext->getParent()->getParent()->isRecord()) {
+ // This is a generic lambda call operator that is being instantiated
+ // within a default initializer - so use the enclosing class as 'this'.
+ // There is no enclosing member function to retrieve the 'this' pointer
+ // from.
+ QualType ClassTy = Context.getTypeDeclType(
+ cast<CXXRecordDecl>(CurContext->getParent()->getParent()));
+ // There are no cv-qualifiers for 'this' within default initializers,
+ // per [expr.prim.general]p4.
+ return Context.getPointerType(ClassTy);
+ }
+ }
return ThisTy;
}
@@ -853,7 +866,7 @@
if (ThisTy.isNull()) return Diag(Loc, diag::err_invalid_this_use);
CheckCXXThisCapture(Loc);
- return Owned(new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false));
+ return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/false);
}
bool Sema::isThisOutsideMemberFunctionBody(QualType BaseType) {
@@ -897,10 +910,8 @@
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
- return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo,
- LParenLoc,
- Exprs,
- RParenLoc));
+ return CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, Exprs,
+ RParenLoc);
}
bool ListInitialization = LParenLoc.isInvalid();
@@ -956,9 +967,9 @@
// want, since it will be treated as an initializer list in further
// processing. Explicitly insert a cast here.
QualType ResultType = Result.get()->getType();
- Result = Owned(CXXFunctionalCastExpr::Create(
+ Result = CXXFunctionalCastExpr::Create(
Context, ResultType, Expr::getValueKindForType(TInfo->getType()), TInfo,
- CK_NoOp, Result.take(), /*Path=*/ nullptr, LParenLoc, RParenLoc));
+ CK_NoOp, Result.get(), /*Path=*/nullptr, LParenLoc, RParenLoc);
}
// FIXME: Improve AST representation?
@@ -1082,12 +1093,12 @@
Array.NumElts
= CheckConvertedConstantExpression(NumElts, Context.getSizeType(), Value,
CCEK_NewExpr)
- .take();
+ .get();
} else {
Array.NumElts
= VerifyIntegerConstantExpression(NumElts, nullptr,
diag::err_new_array_nonconst)
- .take();
+ .get();
}
if (!Array.NumElts)
return ExprError();
@@ -1243,7 +1254,7 @@
if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(ArraySize);
if (result.isInvalid()) return ExprError();
- ArraySize = result.take();
+ ArraySize = result.get();
}
// C++98 5.3.4p6: "The expression in a direct-new-declarator shall have
// integral or enumeration type with a non-negative value."
@@ -1325,7 +1336,7 @@
if (ConvertedSize.isInvalid())
return ExprError();
- ArraySize = ConvertedSize.take();
+ ArraySize = ConvertedSize.get();
QualType SizeType = ArraySize->getType();
if (!SizeType->isIntegralOrUnscopedEnumerationType())
@@ -1501,9 +1512,9 @@
// we don't want the initialized object to be destructed.
if (CXXBindTemporaryExpr *Binder =
dyn_cast_or_null<CXXBindTemporaryExpr>(FullInit.get()))
- FullInit = Owned(Binder->getSubExpr());
+ FullInit = Binder->getSubExpr();
- Initializer = FullInit.take();
+ Initializer = FullInit.get();
}
// Mark the new and delete operators as referenced.
@@ -1536,13 +1547,11 @@
}
}
- return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
- OperatorDelete,
- UsualArrayDeleteWantsSize,
- PlacementArgs, TypeIdParens,
- ArraySize, initStyle, Initializer,
- ResultType, AllocTypeInfo,
- Range, DirectInitRange));
+ return new (Context)
+ CXXNewExpr(Context, UseGlobal, OperatorNew, OperatorDelete,
+ UsualArrayDeleteWantsSize, PlacementArgs, TypeIdParens,
+ ArraySize, initStyle, Initializer, ResultType, AllocTypeInfo,
+ Range, DirectInitRange);
}
/// \brief Checks that a type is suitable as the allocated type
@@ -2241,14 +2250,14 @@
//
// DR599 amends "pointer type" to "pointer to object type" in both cases.
- ExprResult Ex = Owned(ExE);
+ ExprResult Ex = ExE;
FunctionDecl *OperatorDelete = nullptr;
bool ArrayFormAsWritten = ArrayForm;
bool UsualArrayDeleteWantsSize = false;
if (!Ex.get()->isTypeDependent()) {
// Perform lvalue-to-rvalue cast, if needed.
- Ex = DefaultLvalueConversion(Ex.take());
+ Ex = DefaultLvalueConversion(Ex.get());
if (Ex.isInvalid())
return ExprError();
@@ -2307,7 +2316,7 @@
}
} Converter;
- Ex = PerformContextualImplicitConversion(StartLoc, Ex.take(), Converter);
+ Ex = PerformContextualImplicitConversion(StartLoc, Ex.get(), Converter);
if (Ex.isInvalid())
return ExprError();
Type = Ex.get()->getType();
@@ -2432,10 +2441,9 @@
}
}
- return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
- ArrayFormAsWritten,
- UsualArrayDeleteWantsSize,
- OperatorDelete, Ex.take(), StartLoc));
+ return new (Context) CXXDeleteExpr(
+ Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
+ UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
}
/// \brief Check the use of the given variable as a C++ condition in an if,
@@ -2459,19 +2467,15 @@
diag::err_invalid_use_of_array_type)
<< ConditionVar->getSourceRange());
- ExprResult Condition =
- Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
- SourceLocation(),
- ConditionVar,
- /*enclosing*/ false,
- ConditionVar->getLocation(),
- ConditionVar->getType().getNonReferenceType(),
- VK_LValue));
+ ExprResult Condition = DeclRefExpr::Create(
+ Context, NestedNameSpecifierLoc(), SourceLocation(), ConditionVar,
+ /*enclosing*/ false, ConditionVar->getLocation(),
+ ConditionVar->getType().getNonReferenceType(), VK_LValue);
MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));
if (ConvertToBoolean) {
- Condition = CheckBooleanCondition(Condition.take(), StmtLoc);
+ Condition = CheckBooleanCondition(Condition.get(), StmtLoc);
if (Condition.isInvalid())
return ExprError();
}
@@ -2564,7 +2568,7 @@
if (Result.isInvalid())
return ExprError();
- return S.MaybeBindToTemporary(Result.takeAs<Expr>());
+ return S.MaybeBindToTemporary(Result.getAs<Expr>());
}
case CK_UserDefinedConversion: {
@@ -2577,11 +2581,9 @@
if (Result.isInvalid())
return ExprError();
// Record usage of conversion in an implicit cast.
- Result = S.Owned(ImplicitCastExpr::Create(S.Context,
- Result.get()->getType(),
- CK_UserDefinedConversion,
- Result.get(), nullptr,
- Result.get()->getValueKind()));
+ Result = ImplicitCastExpr::Create(S.Context, Result.get()->getType(),
+ CK_UserDefinedConversion, Result.get(),
+ nullptr, Result.get()->getValueKind());
S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ nullptr, FoundDecl);
@@ -2606,7 +2608,7 @@
Action, CCK);
if (Res.isInvalid())
return ExprError();
- From = Res.take();
+ From = Res.get();
break;
}
@@ -2642,7 +2644,7 @@
CCK);
if (Res.isInvalid())
return ExprError();
- From = Res.take();
+ From = Res.get();
}
ExprResult CastArg
@@ -2657,7 +2659,7 @@
if (CastArg.isInvalid())
return ExprError();
- From = CastArg.take();
+ From = CastArg.get();
return PerformImplicitConversion(From, ToType, ICS.UserDefined.After,
AA_Converting, CCK);
@@ -2677,7 +2679,7 @@
}
// Everything went well.
- return Owned(From);
+ return From;
}
/// PerformImplicitConversion - Perform an implicit conversion of the
@@ -2757,20 +2759,20 @@
FromType = FromType.getUnqualifiedType();
ExprResult FromRes = DefaultLvalueConversion(From);
assert(!FromRes.isInvalid() && "Can't perform deduced conversion?!");
- From = FromRes.take();
+ From = FromRes.get();
break;
}
case ICK_Array_To_Pointer:
FromType = Context.getArrayDecayedType(FromType);
From = ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Function_To_Pointer:
FromType = Context.getPointerType(FromType);
From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
default:
@@ -2794,7 +2796,7 @@
return ExprError();
From = ImpCastExprToType(From, ToType, CK_NoOp,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Integral_Promotion:
@@ -2804,17 +2806,17 @@
SCS.Second == ICK_Integral_Promotion &&
"only enums with fixed underlying type can promote to bool");
From = ImpCastExprToType(From, ToType, CK_IntegralToBoolean,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
} else {
From = ImpCastExprToType(From, ToType, CK_IntegralCast,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
}
break;
case ICK_Floating_Promotion:
case ICK_Floating_Conversion:
From = ImpCastExprToType(From, ToType, CK_FloatingCast,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Complex_Promotion:
@@ -2833,22 +2835,22 @@
CK = CK_IntegralComplexCast;
}
From = ImpCastExprToType(From, ToType, CK,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
}
case ICK_Floating_Integral:
if (ToType->isRealFloatingType())
From = ImpCastExprToType(From, ToType, CK_IntegralToFloating,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
else
From = ImpCastExprToType(From, ToType, CK_FloatingToIntegral,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Compatible_Conversion:
From = ImpCastExprToType(From, ToType, CK_NoOp,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Writeback_Conversion:
@@ -2893,12 +2895,12 @@
if (Kind == CK_BlockPointerToObjCPointerCast) {
ExprResult E = From;
(void) PrepareCastToObjCObjectPointer(E);
- From = E.take();
+ From = E.get();
}
if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), ToType, From, CCK);
From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
- .take();
+ .get();
break;
}
@@ -2910,20 +2912,20 @@
if (CheckExceptionSpecCompatibility(From, ToType))
return ExprError();
From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
- .take();
+ .get();
break;
}
case ICK_Boolean_Conversion:
// Perform half-to-boolean conversion via float.
if (From->getType()->isHalfType()) {
- From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).take();
+ From = ImpCastExprToType(From, Context.FloatTy, CK_FloatingCast).get();
FromType = Context.FloatTy;
}
From = ImpCastExprToType(From, Context.BoolTy,
ScalarTypeToBooleanCastKind(FromType),
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Derived_To_Base: {
@@ -2938,18 +2940,18 @@
From = ImpCastExprToType(From, ToType.getNonReferenceType(),
CK_DerivedToBase, From->getValueKind(),
- &BasePath, CCK).take();
+ &BasePath, CCK).get();
break;
}
case ICK_Vector_Conversion:
From = ImpCastExprToType(From, ToType, CK_BitCast,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Vector_Splat:
From = ImpCastExprToType(From, ToType, CK_VectorSplat,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
case ICK_Complex_Real:
@@ -2963,16 +2965,16 @@
// do nothing
} else if (From->getType()->isRealFloatingType()) {
From = ImpCastExprToType(From, ElType,
- isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).take();
+ isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get();
} else {
assert(From->getType()->isIntegerType());
From = ImpCastExprToType(From, ElType,
- isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).take();
+ isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get();
}
// y -> _Complex y
From = ImpCastExprToType(From, ToType,
isFloatingComplex ? CK_FloatingRealToComplex
- : CK_IntegralRealToComplex).take();
+ : CK_IntegralRealToComplex).get();
// Case 2. _Complex x -> y
} else {
@@ -2986,7 +2988,7 @@
From = ImpCastExprToType(From, ElType,
isFloatingComplex ? CK_FloatingComplexToReal
: CK_IntegralComplexToReal,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
// x -> y
if (Context.hasSameUnqualifiedType(ElType, ToType)) {
@@ -2994,29 +2996,29 @@
} else if (ToType->isRealFloatingType()) {
From = ImpCastExprToType(From, ToType,
isFloatingComplex ? CK_FloatingCast : CK_IntegralToFloating,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
} else {
assert(ToType->isIntegerType());
From = ImpCastExprToType(From, ToType,
isFloatingComplex ? CK_FloatingToIntegral : CK_IntegralCast,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
}
}
break;
case ICK_Block_Pointer_Conversion: {
From = ImpCastExprToType(From, ToType.getUnqualifiedType(), CK_BitCast,
- VK_RValue, /*BasePath=*/nullptr, CCK).take();
+ VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
}
case ICK_TransparentUnionConversion: {
- ExprResult FromRes = Owned(From);
+ ExprResult FromRes = From;
Sema::AssignConvertType ConvTy =
CheckTransparentUnionArgumentConstraints(ToType, FromRes);
if (FromRes.isInvalid())
return ExprError();
- From = FromRes.take();
+ From = FromRes.get();
assert ((ConvTy == Sema::Compatible) &&
"Improper transparent union conversion");
(void)ConvTy;
@@ -3026,7 +3028,7 @@
case ICK_Zero_Event_Conversion:
From = ImpCastExprToType(From, ToType,
CK_ZeroToOCLEvent,
- From->getValueKind()).take();
+ From->getValueKind()).get();
break;
case ICK_Lvalue_To_Rvalue:
@@ -3048,7 +3050,7 @@
ExprValueKind VK = ToType->isReferenceType() ?
From->getValueKind() : VK_RValue;
From = ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
- CK_NoOp, VK, /*BasePath=*/nullptr, CCK).take();
+ CK_NoOp, VK, /*BasePath=*/nullptr, CCK).get();
if (SCS.DeprecatedStringLiteralToCharPtr &&
!getLangOpts().WritableStrings) {
@@ -3071,10 +3073,10 @@
assert(Context.hasSameType(
ToAtomicType->castAs<AtomicType>()->getValueType(), From->getType()));
From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic,
- VK_RValue, nullptr, CCK).take();
+ VK_RValue, nullptr, CCK).get();
}
- return Owned(From);
+ return From;
}
/// \brief Check the completeness of a type in a unary type trait.
@@ -4002,9 +4004,8 @@
// returns 'size_t'. On Windows, the primary platform for the Embarcadero
// compiler, there is no difference. On several other platforms this is an
// important distinction.
- return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value,
- DimExpr, RParen,
- Context.getSizeType()));
+ return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
+ RParen, Context.getSizeType());
}
ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
@@ -4037,13 +4038,13 @@
} else if (Queried->getType()->isPlaceholderType()) {
ExprResult PE = CheckPlaceholderExpr(Queried);
if (PE.isInvalid()) return ExprError();
- return BuildExpressionTrait(ET, KWLoc, PE.take(), RParen);
+ return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
}
bool Value = EvaluateExpressionTrait(ET, Queried);
- return Owned(new (Context) ExpressionTraitExpr(KWLoc, ET, Queried, Value,
- RParen, Context.BoolTy));
+ return new (Context)
+ ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
}
QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
@@ -4056,12 +4057,12 @@
// The LHS undergoes lvalue conversions if this is ->*.
if (isIndirect) {
- LHS = DefaultLvalueConversion(LHS.take());
+ LHS = DefaultLvalueConversion(LHS.get());
if (LHS.isInvalid()) return QualType();
}
// The RHS always undergoes lvalue conversions.
- RHS = DefaultLvalueConversion(RHS.take());
+ RHS = DefaultLvalueConversion(RHS.get());
if (RHS.isInvalid()) return QualType();
const char *OpSpelling = isIndirect ? "->*" : ".*";
@@ -4124,7 +4125,7 @@
// Cast LHS to type of use.
QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
ExprValueKind VK = isIndirect ? VK_RValue : LHS.get()->getValueKind();
- LHS = ImpCastExprToType(LHS.take(), UseType, CK_DerivedToBase, VK,
+ LHS = ImpCastExprToType(LHS.get(), UseType, CK_DerivedToBase, VK,
&BasePath);
}
@@ -4347,7 +4348,7 @@
InitializedEntity Entity = InitializedEntity::InitializeTemporary(T);
InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(),
SourceLocation());
- Expr *Arg = E.take();
+ Expr *Arg = E.get();
InitializationSequence InitSeq(Self, Entity, Kind, Arg);
ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg);
if (Result.isInvalid())
@@ -4371,7 +4372,7 @@
// C++11 [expr.cond]p1
// The first expression is contextually converted to bool.
if (!Cond.get()->isTypeDependent()) {
- ExprResult CondRes = CheckCXXBooleanCondition(Cond.take());
+ ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());
if (CondRes.isInvalid())
return QualType();
Cond = CondRes;
@@ -4471,11 +4472,11 @@
Qualifiers LCVR = Qualifiers::fromCVRMask(LTy.getCVRQualifiers());
Qualifiers RCVR = Qualifiers::fromCVRMask(RTy.getCVRQualifiers());
if (RCVR.isStrictSupersetOf(LCVR)) {
- LHS = ImpCastExprToType(LHS.take(), RTy, CK_NoOp, LVK);
+ LHS = ImpCastExprToType(LHS.get(), RTy, CK_NoOp, LVK);
LTy = LHS.get()->getType();
}
else if (LCVR.isStrictSupersetOf(RCVR)) {
- RHS = ImpCastExprToType(RHS.take(), LTy, CK_NoOp, RVK);
+ RHS = ImpCastExprToType(RHS.get(), LTy, CK_NoOp, RVK);
RTy = RHS.get()->getType();
}
}
@@ -4512,8 +4513,8 @@
// C++11 [expr.cond]p6
// Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
// conversions are performed on the second and third operands.
- LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
- RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
+ LHS = DefaultFunctionArrayLvalueConversion(LHS.get());
+ RHS = DefaultFunctionArrayLvalueConversion(RHS.get());
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
LTy = LHS.get()->getType();
@@ -4640,12 +4641,12 @@
!T2->isAnyPointerType() && !T2->isMemberPointerType()) {
if (T1->isNullPtrType() &&
E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
- E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+ E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get();
return T1;
}
if (T2->isNullPtrType() &&
E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
- E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+ E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get();
return T2;
}
return QualType();
@@ -4653,16 +4654,16 @@
if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (T2->isMemberPointerType())
- E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).take();
+ E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).get();
else
- E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+ E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).get();
return T2;
}
if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
if (T1->isMemberPointerType())
- E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).take();
+ E2 = ImpCastExprToType(E2, T1, CK_NullToMemberPointer).get();
else
- E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+ E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).get();
return T1;
}
@@ -4800,14 +4801,14 @@
= E1ToC1.Perform(*this, Entity1, Kind, E1);
if (E1Result.isInvalid())
return QualType();
- E1 = E1Result.takeAs<Expr>();
+ E1 = E1Result.getAs<Expr>();
// Convert E2 to Composite1
ExprResult E2Result
= E2ToC1.Perform(*this, Entity1, Kind, E2);
if (E2Result.isInvalid())
return QualType();
- E2 = E2Result.takeAs<Expr>();
+ E2 = E2Result.getAs<Expr>();
return Composite1;
}
@@ -4825,14 +4826,14 @@
= E1ToC2.Perform(*this, Entity2, Kind, E1);
if (E1Result.isInvalid())
return QualType();
- E1 = E1Result.takeAs<Expr>();
+ E1 = E1Result.getAs<Expr>();
// Convert E2 to Composite2
ExprResult E2Result
= E2ToC2.Perform(*this, Entity2, Kind, E2);
if (E2Result.isInvalid())
return QualType();
- E2 = E2Result.takeAs<Expr>();
+ E2 = E2Result.getAs<Expr>();
return Composite2;
}
@@ -4845,7 +4846,7 @@
// If the result is a glvalue, we shouldn't bind it.
if (!E->isRValue())
- return Owned(E);
+ return E;
// In ARC, calls that return a retainable type can return retained,
// in which case we have to insert a consuming cast.
@@ -4888,7 +4889,7 @@
// we don't want any extra casts here.
} else if (isa<CastExpr>(E) &&
isa<BlockExpr>(cast<CastExpr>(E)->getSubExpr())) {
- return Owned(E);
+ return E;
// For message sends and property references, we try to find an
// actual method. FIXME: we should infer retention by selector in
@@ -4913,23 +4914,23 @@
// return an object.
if (!ReturnsRetained &&
D && D->getMethodFamily() == OMF_performSelector)
- return Owned(E);
+ return E;
}
// Don't reclaim an object of Class type.
if (!ReturnsRetained && E->getType()->isObjCARCImplicitlyUnretainedType())
- return Owned(E);
+ return E;
ExprNeedsCleanups = true;
CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
: CK_ARCReclaimReturnedObject);
- return Owned(ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
- VK_RValue));
+ return ImplicitCastExpr::Create(Context, E->getType(), ck, E, nullptr,
+ VK_RValue);
}
if (!getLangOpts().CPlusPlus)
- return Owned(E);
+ return E;
// Search for the base element type (cf. ASTContext::getBaseElementType) with
// a fast path for the common case that the type is directly a RecordType.
@@ -4947,7 +4948,7 @@
T = cast<ArrayType>(T)->getElementType().getTypePtr();
break;
default:
- return Owned(E);
+ return E;
}
}
@@ -4955,7 +4956,7 @@
// not processing a decltype expression.
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
if (RD->isInvalidDecl() || RD->isDependentContext())
- return Owned(E);
+ return E;
bool IsDecltype = ExprEvalContexts.back().IsDecltype;
CXXDestructorDecl *Destructor = IsDecltype ? nullptr : LookupDestructor(RD);
@@ -4970,7 +4971,7 @@
// If destructor is trivial, we can avoid the extra copy.
if (Destructor->isTrivial())
- return Owned(E);
+ return E;
// We need a cleanup, but we don't need to remember the temporary.
ExprNeedsCleanups = true;
@@ -4982,7 +4983,7 @@
if (IsDecltype)
ExprEvalContexts.back().DelayedDecltypeBinds.push_back(Bind);
- return Owned(Bind);
+ return Bind;
}
ExprResult
@@ -4990,7 +4991,7 @@
if (SubExpr.isInvalid())
return ExprError();
- return Owned(MaybeCreateExprWithCleanups(SubExpr.take()));
+ return MaybeCreateExprWithCleanups(SubExpr.get());
}
Expr *Sema::MaybeCreateExprWithCleanups(Expr *SubExpr) {
@@ -5056,8 +5057,8 @@
if (SubExpr.isInvalid())
return ExprError();
if (SubExpr.get() == PE->getSubExpr())
- return Owned(E);
- return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.take());
+ return E;
+ return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
}
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
if (BO->getOpcode() == BO_Comma) {
@@ -5065,13 +5066,10 @@
if (RHS.isInvalid())
return ExprError();
if (RHS.get() == BO->getRHS())
- return Owned(E);
- return Owned(new (Context) BinaryOperator(BO->getLHS(), RHS.take(),
- BO_Comma, BO->getType(),
- BO->getValueKind(),
- BO->getObjectKind(),
- BO->getOperatorLoc(),
- BO->isFPContractable()));
+ return E;
+ return new (Context) BinaryOperator(
+ BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
+ BO->getObjectKind(), BO->getOperatorLoc(), BO->isFPContractable());
}
}
@@ -5089,7 +5087,7 @@
// In MS mode, don't perform any extra checking of call return types within a
// decltype expression.
if (getLangOpts().MSVCCompat)
- return Owned(E);
+ return E;
// Perform the semantic checks we delayed until this point.
for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size();
@@ -5132,12 +5130,12 @@
}
// Possibly strip off the top CXXBindTemporaryExpr.
- return Owned(E);
+ return E;
}
/// Note a set of 'operator->' functions that were used for a member access.
static void noteOperatorArrows(Sema &S,
- llvm::ArrayRef<FunctionDecl *> OperatorArrows) {
+ ArrayRef<FunctionDecl *> OperatorArrows) {
unsigned SkipStart = OperatorArrows.size(), SkipCount = 0;
// FIXME: Make this configurable?
unsigned Limit = 9;
@@ -5172,7 +5170,7 @@
Result = CheckPlaceholderExpr(Base);
if (Result.isInvalid()) return ExprError();
- Base = Result.take();
+ Base = Result.get();
QualType BaseType = Base->getType();
MayBePseudoDestructor = false;
@@ -5186,7 +5184,7 @@
ObjectType = ParsedType::make(BaseType);
MayBePseudoDestructor = true;
- return Owned(Base);
+ return Base;
}
// C++ [over.match.oper]p8:
@@ -5276,7 +5274,7 @@
} else if (!BaseType->isRecordType()) {
ObjectType = ParsedType();
MayBePseudoDestructor = true;
- return Owned(Base);
+ return Base;
}
// The object type must be complete (or dependent), or
@@ -5317,7 +5315,7 @@
if (Base->hasPlaceholderType()) {
ExprResult result = S.CheckPlaceholderExpr(Base);
if (result.isInvalid()) return true;
- Base = result.take();
+ Base = result.get();
}
ObjectType = Base->getType();
@@ -5442,7 +5440,7 @@
Destructed);
if (HasTrailingLParen)
- return Owned(Result);
+ return Result;
return DiagnoseDtorReference(Destructed.getLocation(), Result);
}
@@ -5644,7 +5642,7 @@
return true;
MemberExpr *ME =
- new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method,
+ new (Context) MemberExpr(Exp.get(), /*IsArrow=*/false, Method,
SourceLocation(), Context.BoundMemberTy,
VK_RValue, OK_Ordinary);
if (HadMultipleCandidates)
@@ -5664,8 +5662,8 @@
ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,
SourceLocation RParen) {
CanThrowResult CanThrow = canThrow(Operand);
- return Owned(new (Context) CXXNoexceptExpr(Context.BoolTy, Operand,
- CanThrow, KeyLoc, RParen));
+ return new (Context)
+ CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen);
}
ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
@@ -5733,8 +5731,8 @@
ExprResult Sema::IgnoredValueConversions(Expr *E) {
if (E->hasPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(E);
- if (result.isInvalid()) return Owned(E);
- E = result.take();
+ if (result.isInvalid()) return E;
+ E = result.get();
}
// C99 6.3.2.1:
@@ -5749,7 +5747,7 @@
if (!getLangOpts().CPlusPlus && E->getType()->isFunctionType())
return DefaultFunctionArrayConversion(E);
- return Owned(E);
+ return E;
}
if (getLangOpts().CPlusPlus) {
@@ -5762,30 +5760,30 @@
IsSpecialDiscardedValue(E)) {
ExprResult Res = DefaultLvalueConversion(E);
if (Res.isInvalid())
- return Owned(E);
- E = Res.take();
+ return E;
+ E = Res.get();
}
- return Owned(E);
+ return E;
}
// GCC seems to also exclude expressions of incomplete enum type.
if (const EnumType *T = E->getType()->getAs<EnumType>()) {
if (!T->getDecl()->isComplete()) {
// FIXME: stupid workaround for a codegen bug!
- E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).take();
- return Owned(E);
+ E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get();
+ return E;
}
}
ExprResult Res = DefaultFunctionArrayLvalueConversion(E);
if (Res.isInvalid())
- return Owned(E);
- E = Res.take();
+ return E;
+ E = Res.get();
if (!E->getType()->isVoidType())
RequireCompleteType(E->getExprLoc(), E->getType(),
diag::err_incomplete_type);
- return Owned(E);
+ return E;
}
// If we can unambiguously determine whether Var can never be used
@@ -5924,7 +5922,7 @@
bool DiscardedValue,
bool IsConstexpr,
bool IsLambdaInitCaptureInitializer) {
- ExprResult FullExpr = Owned(FE);
+ ExprResult FullExpr = FE;
if (!FullExpr.get())
return ExprError();
@@ -5951,17 +5949,17 @@
// Top-level expressions default to 'id' when we're in a debugger.
if (DiscardedValue && getLangOpts().DebuggerCastResultToId &&
FullExpr.get()->getType() == Context.UnknownAnyTy) {
- FullExpr = forceUnknownAnyToType(FullExpr.take(), Context.getObjCIdType());
+ FullExpr = forceUnknownAnyToType(FullExpr.get(), Context.getObjCIdType());
if (FullExpr.isInvalid())
return ExprError();
}
if (DiscardedValue) {
- FullExpr = CheckPlaceholderExpr(FullExpr.take());
+ FullExpr = CheckPlaceholderExpr(FullExpr.get());
if (FullExpr.isInvalid())
return ExprError();
- FullExpr = IgnoredValueConversions(FullExpr.take());
+ FullExpr = IgnoredValueConversions(FullExpr.get());
if (FullExpr.isInvalid())
return ExprError();
}
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 5e9ccff..b73ebc4 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -472,12 +472,10 @@
// Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
// must have pointer type, and the accessed type is the pointee.
- return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
- IsArrow, OpLoc,
- SS.getWithLocInContext(Context),
- TemplateKWLoc,
- FirstQualifierInScope,
- NameInfo, TemplateArgs));
+ return CXXDependentScopeMemberExpr::Create(
+ Context, BaseExpr, BaseType, IsArrow, OpLoc,
+ SS.getWithLocInContext(Context), TemplateKWLoc, FirstQualifierInScope,
+ NameInfo, TemplateArgs);
}
/// We know that the given qualified member reference points only to
@@ -672,6 +670,11 @@
return false;
}
+static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
+ ExprResult &BaseExpr, bool &IsArrow,
+ SourceLocation OpLoc, CXXScopeSpec &SS,
+ Decl *ObjCImpDecl, bool HasTemplateArgs);
+
ExprResult
Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
SourceLocation OpLoc, bool IsArrow,
@@ -679,7 +682,8 @@
SourceLocation TemplateKWLoc,
NamedDecl *FirstQualifierInScope,
const DeclarationNameInfo &NameInfo,
- const TemplateArgumentListInfo *TemplateArgs) {
+ const TemplateArgumentListInfo *TemplateArgs,
+ ActOnMemberAccessExtraArgs *ExtraArgs) {
if (BaseType->isDependentType() ||
(SS.isSet() && isDependentScopeSpecifier(SS)))
return ActOnDependentMemberExpr(Base, BaseType,
@@ -700,19 +704,18 @@
// Explicit member accesses.
} else {
- ExprResult BaseResult = Owned(Base);
- ExprResult Result =
- LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
- SS, /*ObjCImpDecl*/ nullptr, TemplateArgs != nullptr);
+ ExprResult BaseResult = Base;
+ ExprResult Result = LookupMemberExpr(
+ *this, R, BaseResult, IsArrow, OpLoc, SS,
+ ExtraArgs ? ExtraArgs->ObjCImpDecl : nullptr,
+ TemplateArgs != nullptr);
if (BaseResult.isInvalid())
return ExprError();
- Base = BaseResult.take();
+ Base = BaseResult.get();
- if (Result.isInvalid()) {
- Owned(Base);
+ if (Result.isInvalid())
return ExprError();
- }
if (Result.get())
return Result;
@@ -723,7 +726,8 @@
return BuildMemberReferenceExpr(Base, BaseType,
OpLoc, IsArrow, SS, TemplateKWLoc,
- FirstQualifierInScope, R, TemplateArgs);
+ FirstQualifierInScope, R, TemplateArgs,
+ false, ExtraArgs);
}
static ExprResult
@@ -763,7 +767,7 @@
= BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
if (result.isInvalid()) return ExprError();
- baseObjectExpr = result.take();
+ baseObjectExpr = result.get();
baseObjectIsPointer = false;
baseQuals = baseObjectExpr->getType().getQualifiers();
@@ -819,7 +823,7 @@
result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer,
EmptySS, field, foundDecl,
- memberNameInfo).take();
+ memberNameInfo).get();
if (!result)
return ExprError();
@@ -839,10 +843,10 @@
result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false,
(FI == FEnd? SS : EmptySS), field,
- fakeFoundDecl, memberNameInfo).take();
+ fakeFoundDecl, memberNameInfo).get();
}
- return Owned(result);
+ return result;
}
static ExprResult
@@ -1013,7 +1017,7 @@
TemplateKWLoc, MemberNameInfo,
TemplateArgs, R.begin(), R.end());
- return Owned(MemExpr);
+ return MemExpr;
}
assert(R.isSingleResult());
@@ -1050,10 +1054,8 @@
}
// Check the use of this member.
- if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc)) {
- Owned(BaseExpr);
+ if (ShouldCheckUse && DiagnoseUseOfDecl(MemberDecl, MemberLoc))
return ExprError();
- }
if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow,
@@ -1071,10 +1073,10 @@
OpLoc);
if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
- return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
- TemplateKWLoc, Var, FoundDecl, MemberNameInfo,
- Var->getType().getNonReferenceType(),
- VK_LValue, OK_Ordinary));
+ return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+ Var, FoundDecl, MemberNameInfo,
+ Var->getType().getNonReferenceType(), VK_LValue,
+ OK_Ordinary);
}
if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) {
@@ -1088,21 +1090,18 @@
type = MemberFn->getType();
}
- return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
- TemplateKWLoc, MemberFn, FoundDecl,
- MemberNameInfo, type, valueKind,
- OK_Ordinary));
+ return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+ MemberFn, FoundDecl, MemberNameInfo, type, valueKind,
+ OK_Ordinary);
}
assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?");
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
- return Owned(BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS,
- TemplateKWLoc, Enum, FoundDecl, MemberNameInfo,
- Enum->getType(), VK_RValue, OK_Ordinary));
+ return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, SS, TemplateKWLoc,
+ Enum, FoundDecl, MemberNameInfo, Enum->getType(),
+ VK_RValue, OK_Ordinary);
}
- Owned(BaseExpr);
-
// We found something that we didn't expect. Complain.
if (isa<TypeDecl>(MemberDecl))
Diag(MemberLoc, diag::err_typecheck_member_reference_type)
@@ -1145,7 +1144,7 @@
if (opty && !opty->getObjectType()->getInterface())
return false;
- base = S.ImpCastExprToType(base.take(), redef, CK_BitCast);
+ base = S.ImpCastExprToType(base.get(), redef, CK_BitCast);
return true;
}
@@ -1177,15 +1176,14 @@
///
/// The ObjCImpDecl bit is a gross hack that will need to be properly
/// fixed for ObjC++.
-ExprResult
-Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
- bool &IsArrow, SourceLocation OpLoc,
- CXXScopeSpec &SS,
- Decl *ObjCImpDecl, bool HasTemplateArgs) {
+static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
+ ExprResult &BaseExpr, bool &IsArrow,
+ SourceLocation OpLoc, CXXScopeSpec &SS,
+ Decl *ObjCImpDecl, bool HasTemplateArgs) {
assert(BaseExpr.get() && "no base expression");
// Perform default conversions.
- BaseExpr = PerformMemberExprBaseConversion(BaseExpr.take(), IsArrow);
+ BaseExpr = S.PerformMemberExprBaseConversion(BaseExpr.get(), IsArrow);
if (BaseExpr.isInvalid())
return ExprError();
@@ -1213,8 +1211,8 @@
// overloaded operator->, but that should have been dealt with
// by now--or a diagnostic message already issued if a problem
// was encountered while looking for the overloaded operator->.
- if (!getLangOpts().CPlusPlus) {
- Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+ if (!S.getLangOpts().CPlusPlus) {
+ S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
<< BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
<< FixItHint::CreateReplacement(OpLoc, ".");
}
@@ -1222,7 +1220,7 @@
} else if (BaseType->isFunctionType()) {
goto fail;
} else {
- Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
+ S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow)
<< BaseType << BaseExpr.get()->getSourceRange();
return ExprError();
}
@@ -1230,24 +1228,24 @@
// Handle field access to simple records.
if (const RecordType *RTy = BaseType->getAs<RecordType>()) {
- if (LookupMemberExprInRecord(*this, R, BaseExpr.get()->getSourceRange(),
+ if (LookupMemberExprInRecord(S, R, BaseExpr.get()->getSourceRange(),
RTy, OpLoc, SS, HasTemplateArgs))
return ExprError();
// Returning valid-but-null is how we indicate to the caller that
// the lookup result was filled in.
- return Owned((Expr*) nullptr);
+ return ExprResult((Expr *)nullptr);
}
// Handle ivar access to Objective-C objects.
if (const ObjCObjectType *OTy = BaseType->getAs<ObjCObjectType>()) {
if (!SS.isEmpty() && !SS.isInvalid()) {
- Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
+ S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
<< 1 << SS.getScopeRep()
<< FixItHint::CreateRemoval(SS.getRange());
SS.clear();
}
-
+
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
// There are three cases for the base type:
@@ -1256,24 +1254,24 @@
// - an interface
ObjCInterfaceDecl *IDecl = OTy->getInterface();
if (!IDecl) {
- if (getLangOpts().ObjCAutoRefCount &&
+ if (S.getLangOpts().ObjCAutoRefCount &&
(OTy->isObjCId() || OTy->isObjCClass()))
goto fail;
// There's an implicit 'isa' ivar on all objects.
// But we only actually find it this way on objects of type 'id',
// apparently.
if (OTy->isObjCId() && Member->isStr("isa"))
- return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc,
- OpLoc,
- Context.getObjCClassType()));
- if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ return new (S.Context) ObjCIsaExpr(BaseExpr.get(), IsArrow, MemberLoc,
+ OpLoc, S.Context.getObjCClassType());
+ if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
goto fail;
}
-
- if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag,
- BaseExpr.get()))
+
+ if (S.RequireCompleteType(OpLoc, BaseType,
+ diag::err_typecheck_incomplete_tag,
+ BaseExpr.get()))
return ExprError();
ObjCInterfaceDecl *ClassDeclared = nullptr;
@@ -1283,14 +1281,14 @@
// Attempt to correct for typos in ivar names.
DeclFilterCCC<ObjCIvarDecl> Validator;
Validator.IsObjCIvarLookup = IsArrow;
- if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
- LookupMemberName, nullptr,
- nullptr, Validator,
- CTK_ErrorRecovery, IDecl)) {
+ if (TypoCorrection Corrected = S.CorrectTypo(
+ R.getLookupNameInfo(), Sema::LookupMemberName, nullptr, nullptr,
+ Validator, Sema::CTK_ErrorRecovery, IDecl)) {
IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>();
- diagnoseTypo(Corrected,
- PDiag(diag::err_typecheck_member_reference_ivar_suggest)
- << IDecl->getDeclName() << MemberName);
+ S.diagnoseTypo(
+ Corrected,
+ S.PDiag(diag::err_typecheck_member_reference_ivar_suggest)
+ << IDecl->getDeclName() << MemberName);
// Figure out the class that declares the ivar.
assert(!ClassDeclared);
@@ -1300,20 +1298,19 @@
ClassDeclared = cast<ObjCInterfaceDecl>(D);
} else {
if (IsArrow && IDecl->FindPropertyDeclaration(Member)) {
- Diag(MemberLoc,
- diag::err_property_found_suggest)
- << Member << BaseExpr.get()->getType()
- << FixItHint::CreateReplacement(OpLoc, ".");
+ S.Diag(MemberLoc, diag::err_property_found_suggest)
+ << Member << BaseExpr.get()->getType()
+ << FixItHint::CreateReplacement(OpLoc, ".");
return ExprError();
}
- Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
- << IDecl->getDeclName() << MemberName
- << BaseExpr.get()->getSourceRange();
+ S.Diag(MemberLoc, diag::err_typecheck_member_reference_ivar)
+ << IDecl->getDeclName() << MemberName
+ << BaseExpr.get()->getSourceRange();
return ExprError();
}
}
-
+
assert(ClassDeclared);
// If the decl being referenced had an error, return an error for this
@@ -1323,14 +1320,14 @@
return ExprError();
// Check whether we can reference this field.
- if (DiagnoseUseOfDecl(IV, MemberLoc))
+ if (S.DiagnoseUseOfDecl(IV, MemberLoc))
return ExprError();
if (IV->getAccessControl() != ObjCIvarDecl::Public &&
IV->getAccessControl() != ObjCIvarDecl::Package) {
ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
- if (ObjCMethodDecl *MD = getCurMethodDecl())
+ if (ObjCMethodDecl *MD = S.getCurMethodDecl())
ClassOfMethodDecl = MD->getClassInterface();
- else if (ObjCImpDecl && getCurFunctionDecl()) {
+ else if (ObjCImpDecl && S.getCurFunctionDecl()) {
// Case of a c-function declared inside an objc implementation.
// FIXME: For a c-style function nested inside an objc implementation
// class, there is no implementation context available, so we pass
@@ -1344,20 +1341,20 @@
dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
ClassOfMethodDecl = CatImplClass->getClassInterface();
}
- if (!getLangOpts().DebuggerSupport) {
+ if (!S.getLangOpts().DebuggerSupport) {
if (IV->getAccessControl() == ObjCIvarDecl::Private) {
if (!declaresSameEntity(ClassDeclared, IDecl) ||
!declaresSameEntity(ClassOfMethodDecl, ClassDeclared))
- Diag(MemberLoc, diag::error_private_ivar_access)
+ S.Diag(MemberLoc, diag::error_private_ivar_access)
<< IV->getDeclName();
} else if (!IDecl->isSuperClassOf(ClassOfMethodDecl))
// @protected
- Diag(MemberLoc, diag::error_protected_ivar_access)
- << IV->getDeclName();
+ S.Diag(MemberLoc, diag::error_protected_ivar_access)
+ << IV->getDeclName();
}
}
bool warn = true;
- if (getLangOpts().ObjCAutoRefCount) {
+ if (S.getLangOpts().ObjCAutoRefCount) {
Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
if (UO->getOpcode() == UO_Deref)
@@ -1365,55 +1362,50 @@
if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
- Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
+ S.Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
warn = false;
}
}
if (warn) {
- if (ObjCMethodDecl *MD = getCurMethodDecl()) {
+ if (ObjCMethodDecl *MD = S.getCurMethodDecl()) {
ObjCMethodFamily MF = MD->getMethodFamily();
warn = (MF != OMF_init && MF != OMF_dealloc &&
MF != OMF_finalize &&
- !IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
+ !S.IvarBacksCurrentMethodAccessor(IDecl, MD, IV));
}
if (warn)
- Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
+ S.Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
}
- ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(),
- MemberLoc, OpLoc,
- BaseExpr.take(),
- IsArrow);
+ ObjCIvarRefExpr *Result = new (S.Context) ObjCIvarRefExpr(
+ IV, IV->getType(), MemberLoc, OpLoc, BaseExpr.get(), IsArrow);
- if (getLangOpts().ObjCAutoRefCount) {
+ if (S.getLangOpts().ObjCAutoRefCount) {
if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- MemberLoc);
- if (Level != DiagnosticsEngine::Ignored)
- recordUseOfEvaluatedWeak(Result);
+ if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
+ S.recordUseOfEvaluatedWeak(Result);
}
}
- return Owned(Result);
+ return Result;
}
// Objective-C property access.
const ObjCObjectPointerType *OPT;
if (!IsArrow && (OPT = BaseType->getAs<ObjCObjectPointerType>())) {
if (!SS.isEmpty() && !SS.isInvalid()) {
- Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
- << 0 << SS.getScopeRep()
- << FixItHint::CreateRemoval(SS.getRange());
+ S.Diag(SS.getRange().getBegin(), diag::err_qualified_objc_access)
+ << 0 << SS.getScopeRep() << FixItHint::CreateRemoval(SS.getRange());
SS.clear();
}
// This actually uses the base as an r-value.
- BaseExpr = DefaultLvalueConversion(BaseExpr.take());
+ BaseExpr = S.DefaultLvalueConversion(BaseExpr.get());
if (BaseExpr.isInvalid())
return ExprError();
- assert(Context.hasSameUnqualifiedType(BaseType, BaseExpr.get()->getType()));
+ assert(S.Context.hasSameUnqualifiedType(BaseType,
+ BaseExpr.get()->getType()));
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
@@ -1422,78 +1414,75 @@
// id, with and without qualifiers.
if (OT->isObjCId()) {
// Check protocols on qualified interfaces.
- Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
- if (Decl *PMDecl = FindGetterSetterNameDecl(OPT, Member, Sel, Context)) {
+ Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
+ if (Decl *PMDecl =
+ FindGetterSetterNameDecl(OPT, Member, Sel, S.Context)) {
if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
// Check the use of this declaration
- if (DiagnoseUseOfDecl(PD, MemberLoc))
+ if (S.DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
- return Owned(new (Context) ObjCPropertyRefExpr(PD,
- Context.PseudoObjectTy,
- VK_LValue,
- OK_ObjCProperty,
- MemberLoc,
- BaseExpr.take()));
+ return new (S.Context)
+ ObjCPropertyRefExpr(PD, S.Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, BaseExpr.get());
}
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
// Check the use of this method.
- if (DiagnoseUseOfDecl(OMD, MemberLoc))
+ if (S.DiagnoseUseOfDecl(OMD, MemberLoc))
return ExprError();
Selector SetterSel =
- SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
- PP.getSelectorTable(),
+ SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
+ S.PP.getSelectorTable(),
Member);
ObjCMethodDecl *SMD = nullptr;
if (Decl *SDecl = FindGetterSetterNameDecl(OPT,
- /*Property id*/nullptr,
- SetterSel, Context))
+ /*Property id*/ nullptr,
+ SetterSel, S.Context))
SMD = dyn_cast<ObjCMethodDecl>(SDecl);
-
- return Owned(new (Context) ObjCPropertyRefExpr(OMD, SMD,
- Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- MemberLoc, BaseExpr.take()));
+
+ return new (S.Context)
+ ObjCPropertyRefExpr(OMD, SMD, S.Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, BaseExpr.get());
}
}
// Use of id.member can only be for a property reference. Do not
// use the 'id' redefinition in this case.
- if (IsArrow && ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ if (IsArrow && ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
- return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+ return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
<< MemberName << BaseType);
}
// 'Class', unqualified only.
if (OT->isObjCClass()) {
// Only works in a method declaration (??!).
- ObjCMethodDecl *MD = getCurMethodDecl();
+ ObjCMethodDecl *MD = S.getCurMethodDecl();
if (!MD) {
- if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
goto fail;
}
// Also must look for a getter name which uses property syntax.
- Selector Sel = PP.getSelectorTable().getNullarySelector(Member);
+ Selector Sel = S.PP.getSelectorTable().getNullarySelector(Member);
ObjCInterfaceDecl *IFace = MD->getClassInterface();
ObjCMethodDecl *Getter;
if ((Getter = IFace->lookupClassMethod(Sel))) {
// Check the use of this method.
- if (DiagnoseUseOfDecl(Getter, MemberLoc))
+ if (S.DiagnoseUseOfDecl(Getter, MemberLoc))
return ExprError();
} else
Getter = IFace->lookupPrivateMethod(Sel, false);
// If we found a getter then this may be a valid dot-reference, we
// will look for the matching setter, in case it is needed.
Selector SetterSel =
- SelectorTable::constructSetterSelector(PP.getIdentifierTable(),
- PP.getSelectorTable(),
+ SelectorTable::constructSetterSelector(S.PP.getIdentifierTable(),
+ S.PP.getSelectorTable(),
Member);
ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
if (!Setter) {
@@ -1502,28 +1491,27 @@
Setter = IFace->lookupPrivateMethod(SetterSel, false);
}
- if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
+ if (Setter && S.DiagnoseUseOfDecl(Setter, MemberLoc))
return ExprError();
if (Getter || Setter) {
- return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
- Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- MemberLoc, BaseExpr.take()));
+ return new (S.Context) ObjCPropertyRefExpr(
+ Getter, Setter, S.Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, BaseExpr.get());
}
- if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr))
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ if (ShouldTryAgainWithRedefinitionType(S, BaseExpr))
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
- return ExprError(Diag(MemberLoc, diag::err_property_not_found)
+ return ExprError(S.Diag(MemberLoc, diag::err_property_not_found)
<< MemberName << BaseType);
}
// Normal property access.
- return HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc,
- MemberName, MemberLoc,
- SourceLocation(), QualType(), false);
+ return S.HandleExprPropertyRefExpr(OPT, BaseExpr.get(), OpLoc, MemberName,
+ MemberLoc, SourceLocation(), QualType(),
+ false);
}
// Handle 'field access' to vectors, such as 'V.xx'.
@@ -1531,24 +1519,22 @@
// FIXME: this expr should store IsArrow.
IdentifierInfo *Member = MemberName.getAsIdentifierInfo();
ExprValueKind VK = (IsArrow ? VK_LValue : BaseExpr.get()->getValueKind());
- QualType ret = CheckExtVectorComponent(*this, BaseType, VK, OpLoc,
+ QualType ret = CheckExtVectorComponent(S, BaseType, VK, OpLoc,
Member, MemberLoc);
if (ret.isNull())
return ExprError();
- return Owned(new (Context) ExtVectorElementExpr(ret, VK, BaseExpr.take(),
- *Member, MemberLoc));
+ return new (S.Context)
+ ExtVectorElementExpr(ret, VK, BaseExpr.get(), *Member, MemberLoc);
}
// Adjust builtin-sel to the appropriate redefinition type if that's
// not just a pointer to builtin-sel again.
- if (IsArrow &&
- BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
- !Context.getObjCSelRedefinitionType()->isObjCSelType()) {
- BaseExpr = ImpCastExprToType(BaseExpr.take(),
- Context.getObjCSelRedefinitionType(),
- CK_BitCast);
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ if (IsArrow && BaseType->isSpecificBuiltinType(BuiltinType::ObjCSel) &&
+ !S.Context.getObjCSelRedefinitionType()->isObjCSelType()) {
+ BaseExpr = S.ImpCastExprToType(
+ BaseExpr.get(), S.Context.getObjCSelRedefinitionType(), CK_BitCast);
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
}
@@ -1565,31 +1551,31 @@
if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
if (!IsArrow && Ptr->getPointeeType()->isRecordType() &&
MemberName.getNameKind() != DeclarationName::CXXDestructorName) {
- Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
- << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
+ S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+ << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange()
<< FixItHint::CreateReplacement(OpLoc, "->");
// Recurse as an -> access.
IsArrow = true;
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
}
}
// If the user is trying to apply -> or . to a function name, it's probably
// because they forgot parentheses to call that function.
- if (tryToRecoverWithCall(BaseExpr,
- PDiag(diag::err_member_reference_needs_call),
- /*complain*/ false,
- IsArrow ? &isPointerToRecordType : &isRecordType)) {
+ if (S.tryToRecoverWithCall(
+ BaseExpr, S.PDiag(diag::err_member_reference_needs_call),
+ /*complain*/ false,
+ IsArrow ? &isPointerToRecordType : &isRecordType)) {
if (BaseExpr.isInvalid())
return ExprError();
- BaseExpr = DefaultFunctionArrayConversion(BaseExpr.take());
- return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS,
+ BaseExpr = S.DefaultFunctionArrayConversion(BaseExpr.get());
+ return LookupMemberExpr(S, R, BaseExpr, IsArrow, OpLoc, SS,
ObjCImpDecl, HasTemplateArgs);
}
- Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
+ S.Diag(OpLoc, diag::err_typecheck_member_reference_struct_union)
<< BaseType << BaseExpr.get()->getSourceRange() << MemberLoc;
return ExprError();
@@ -1619,6 +1605,19 @@
if (SS.isSet() && SS.isInvalid())
return ExprError();
+ // The only way a reference to a destructor can be used is to
+ // immediately call it. If the next token is not a '(', produce
+ // a diagnostic and build the call now.
+ if (!HasTrailingLParen &&
+ Id.getKind() == UnqualifiedId::IK_DestructorName) {
+ ExprResult DtorAccess =
+ ActOnMemberAccessExpr(S, Base, OpLoc, OpKind, SS, TemplateKWLoc, Id,
+ ObjCImpDecl, /*HasTrailingLParen*/true);
+ if (DtorAccess.isInvalid())
+ return DtorAccess;
+ return DiagnoseDtorReference(Id.getLocStart(), DtorAccess.get());
+ }
+
// Warn about the explicit constructor calls Microsoft extension.
if (getLangOpts().MicrosoftExt &&
Id.getKind() == UnqualifiedId::IK_ConstructorName)
@@ -1642,48 +1641,20 @@
// This is a postfix expression, so get rid of ParenListExprs.
ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
if (Result.isInvalid()) return ExprError();
- Base = Result.take();
+ Base = Result.get();
if (Base->getType()->isDependentType() || Name.isDependentName() ||
isDependentScopeSpecifier(SS)) {
- Result = ActOnDependentMemberExpr(Base, Base->getType(),
- IsArrow, OpLoc,
- SS, TemplateKWLoc, FirstQualifierInScope,
- NameInfo, TemplateArgs);
- } else {
- LookupResult R(*this, NameInfo, LookupMemberName);
- ExprResult BaseResult = Owned(Base);
- Result = LookupMemberExpr(R, BaseResult, IsArrow, OpLoc,
- SS, ObjCImpDecl, TemplateArgs != nullptr);
- if (BaseResult.isInvalid())
- return ExprError();
- Base = BaseResult.take();
-
- if (Result.isInvalid()) {
- Owned(Base);
- return ExprError();
- }
-
- if (Result.get()) {
- // The only way a reference to a destructor can be used is to
- // immediately call it, which falls into this case. If the
- // next token is not a '(', produce a diagnostic and build the
- // call now.
- if (!HasTrailingLParen &&
- Id.getKind() == UnqualifiedId::IK_DestructorName)
- return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
-
- return Result;
- }
-
- ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl, HasTrailingLParen};
- Result = BuildMemberReferenceExpr(Base, Base->getType(),
- OpLoc, IsArrow, SS, TemplateKWLoc,
- FirstQualifierInScope, R, TemplateArgs,
- false, &ExtraArgs);
+ return ActOnDependentMemberExpr(Base, Base->getType(), IsArrow, OpLoc, SS,
+ TemplateKWLoc, FirstQualifierInScope,
+ NameInfo, TemplateArgs);
}
- return Result;
+ ActOnMemberAccessExtraArgs ExtraArgs = {S, Id, ObjCImpDecl,
+ HasTrailingLParen};
+ return BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, IsArrow, SS,
+ TemplateKWLoc, FirstQualifierInScope,
+ NameInfo, TemplateArgs, &ExtraArgs);
}
static ExprResult
@@ -1742,10 +1713,9 @@
FoundDecl, Field);
if (Base.isInvalid())
return ExprError();
- return S.Owned(BuildMemberExpr(S, S.Context, Base.take(), IsArrow, SS,
- /*TemplateKWLoc=*/SourceLocation(),
- Field, FoundDecl, MemberNameInfo,
- MemberType, VK, OK));
+ return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, SS,
+ /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl,
+ MemberNameInfo, MemberType, VK, OK);
}
/// Builds an implicit member access expression. The current context
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index d9e2828..5002332 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -291,12 +291,12 @@
return ExprError();
// Convert the number to the type that the parameter expects.
- ParmVarDecl *ParamDecl = Method->param_begin()[0];
+ ParmVarDecl *ParamDecl = Method->parameters()[0];
InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
ParamDecl);
ExprResult ConvertedNumber = PerformCopyInitialization(Entity,
SourceLocation(),
- Owned(Number));
+ Number);
if (ConvertedNumber.isInvalid())
return ExprError();
Number = ConvertedNumber.get();
@@ -445,7 +445,7 @@
if (ValueExpr->isTypeDependent()) {
ObjCBoxedExpr *BoxedExpr =
new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, nullptr, SR);
- return Owned(BoxedExpr);
+ return BoxedExpr;
}
ObjCMethodDecl *BoxingMethod = nullptr;
QualType BoxedType;
@@ -555,7 +555,7 @@
break;
}
}
-
+ CheckForIntOverflow(ValueExpr);
// FIXME: Do I need to do anything special with BoolTy expressions?
// Look for the appropriate method within NSNumber.
@@ -581,12 +581,12 @@
}
// Convert the expression to the type that the parameter requires.
- ParmVarDecl *ParamDecl = BoxingMethod->param_begin()[0];
+ ParmVarDecl *ParamDecl = BoxingMethod->parameters()[0];
InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
ParamDecl);
ExprResult ConvertedValueExpr = PerformCopyInitialization(Entity,
SourceLocation(),
- Owned(ValueExpr));
+ ValueExpr);
if (ConvertedValueExpr.isInvalid())
return ExprError();
ValueExpr = ConvertedValueExpr.get();
@@ -624,13 +624,9 @@
BaseExpr = Result.get();
// Build the pseudo-object expression.
- return Owned(ObjCSubscriptRefExpr::Create(Context,
- BaseExpr,
- IndexExpr,
- Context.PseudoObjectTy,
- getterMethod,
- setterMethod, RB));
-
+ return ObjCSubscriptRefExpr::Create(Context, BaseExpr, IndexExpr,
+ Context.PseudoObjectTy, getterMethod,
+ setterMethod, RB);
}
ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
@@ -693,13 +689,13 @@
return ExprError();
// Dig out the type that all elements should be converted to.
- QualType T = Method->param_begin()[0]->getType();
+ QualType T = Method->parameters()[0]->getType();
const PointerType *PtrT = T->getAs<PointerType>();
if (!PtrT ||
!Context.hasSameUnqualifiedType(PtrT->getPointeeType(), IdT)) {
Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
<< Sel;
- Diag(Method->param_begin()[0]->getLocation(),
+ Diag(Method->parameters()[0]->getLocation(),
diag::note_objc_literal_method_param)
<< 0 << T
<< Context.getPointerType(IdT.withConst());
@@ -707,13 +703,13 @@
}
// Check that the 'count' parameter is integral.
- if (!Method->param_begin()[1]->getType()->isIntegerType()) {
+ if (!Method->parameters()[1]->getType()->isIntegerType()) {
Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
<< Sel;
- Diag(Method->param_begin()[1]->getLocation(),
+ Diag(Method->parameters()[1]->getLocation(),
diag::note_objc_literal_method_param)
<< 1
- << Method->param_begin()[1]->getType()
+ << Method->parameters()[1]->getType()
<< "integral";
return ExprError();
}
@@ -722,7 +718,7 @@
ArrayWithObjectsMethod = Method;
}
- QualType ObjectsType = ArrayWithObjectsMethod->param_begin()[0]->getType();
+ QualType ObjectsType = ArrayWithObjectsMethod->parameters()[0]->getType();
QualType RequiredType = ObjectsType->castAs<PointerType>()->getPointeeType();
// Check that each of the elements provided is valid in a collection literal,
@@ -820,13 +816,13 @@
return ExprError();
// Dig out the type that all values should be converted to.
- QualType ValueT = Method->param_begin()[0]->getType();
+ QualType ValueT = Method->parameters()[0]->getType();
const PointerType *PtrValue = ValueT->getAs<PointerType>();
if (!PtrValue ||
!Context.hasSameUnqualifiedType(PtrValue->getPointeeType(), IdT)) {
Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
<< Sel;
- Diag(Method->param_begin()[0]->getLocation(),
+ Diag(Method->parameters()[0]->getLocation(),
diag::note_objc_literal_method_param)
<< 0 << ValueT
<< Context.getPointerType(IdT.withConst());
@@ -834,7 +830,7 @@
}
// Dig out the type that all keys should be converted to.
- QualType KeyT = Method->param_begin()[1]->getType();
+ QualType KeyT = Method->parameters()[1]->getType();
const PointerType *PtrKey = KeyT->getAs<PointerType>();
if (!PtrKey ||
!Context.hasSameUnqualifiedType(PtrKey->getPointeeType(),
@@ -860,7 +856,7 @@
if (err) {
Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
<< Sel;
- Diag(Method->param_begin()[1]->getLocation(),
+ Diag(Method->parameters()[1]->getLocation(),
diag::note_objc_literal_method_param)
<< 1 << KeyT
<< Context.getPointerType(IdT.withConst());
@@ -869,11 +865,11 @@
}
// Check that the 'count' parameter is integral.
- QualType CountType = Method->param_begin()[2]->getType();
+ QualType CountType = Method->parameters()[2]->getType();
if (!CountType->isIntegerType()) {
Diag(SR.getBegin(), diag::err_objc_literal_method_sig)
<< Sel;
- Diag(Method->param_begin()[2]->getLocation(),
+ Diag(Method->parameters()[2]->getLocation(),
diag::note_objc_literal_method_param)
<< 2 << CountType
<< "integral";
@@ -884,9 +880,9 @@
DictionaryWithObjectsMethod = Method;
}
- QualType ValuesT = DictionaryWithObjectsMethod->param_begin()[0]->getType();
+ QualType ValuesT = DictionaryWithObjectsMethod->parameters()[0]->getType();
QualType ValueT = ValuesT->castAs<PointerType>()->getPointeeType();
- QualType KeysT = DictionaryWithObjectsMethod->param_begin()[1]->getType();
+ QualType KeysT = DictionaryWithObjectsMethod->parameters()[1]->getType();
QualType KeyT = KeysT->castAs<PointerType>()->getPointeeType();
// Check that each of the keys and values provided is valid in a collection
@@ -980,6 +976,8 @@
static bool HelperToDiagnoseMismatchedMethodsInGlobalPool(Sema &S,
SourceLocation AtLoc,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc,
ObjCMethodDecl *Method,
ObjCMethodList &MethList) {
ObjCMethodList *M = &MethList;
@@ -995,7 +993,8 @@
if (!Warned) {
Warned = true;
S.Diag(AtLoc, diag::warning_multiple_selectors)
- << Method->getSelector();
+ << Method->getSelector() << FixItHint::CreateInsertion(LParenLoc, "(")
+ << FixItHint::CreateInsertion(RParenLoc, ")");
S.Diag(Method->getLocation(), diag::note_method_declared_at)
<< Method->getDeclName();
}
@@ -1007,25 +1006,26 @@
}
static void DiagnoseMismatchedSelectors(Sema &S, SourceLocation AtLoc,
- ObjCMethodDecl *Method) {
- if (S.Diags.getDiagnosticLevel(diag::warning_multiple_selectors,
- SourceLocation())
- == DiagnosticsEngine::Ignored)
+ ObjCMethodDecl *Method,
+ SourceLocation LParenLoc,
+ SourceLocation RParenLoc,
+ bool WarnMultipleSelectors) {
+ if (!WarnMultipleSelectors ||
+ S.Diags.isIgnored(diag::warning_multiple_selectors, SourceLocation()))
return;
bool Warned = false;
for (Sema::GlobalMethodPool::iterator b = S.MethodPool.begin(),
e = S.MethodPool.end(); b != e; b++) {
// first, instance methods
ObjCMethodList &InstMethList = b->second.first;
- if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
+ if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
Method, InstMethList))
Warned = true;
// second, class methods
ObjCMethodList &ClsMethList = b->second.second;
- if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc,
- Method, ClsMethList) ||
- Warned)
+ if (HelperToDiagnoseMismatchedMethodsInGlobalPool(S, AtLoc, LParenLoc, RParenLoc,
+ Method, ClsMethList) || Warned)
return;
}
}
@@ -1034,7 +1034,8 @@
SourceLocation AtLoc,
SourceLocation SelLoc,
SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
+ SourceLocation RParenLoc,
+ bool WarnMultipleSelectors) {
ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
SourceRange(LParenLoc, RParenLoc), false, false);
if (!Method)
@@ -1052,7 +1053,8 @@
} else
Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
} else
- DiagnoseMismatchedSelectors(*this, AtLoc, Method);
+ DiagnoseMismatchedSelectors(*this, AtLoc, Method, LParenLoc, RParenLoc,
+ WarnMultipleSelectors);
if (Method &&
Method->getImplementationControl() != ObjCMethodDecl::Optional &&
@@ -1296,7 +1298,7 @@
}
if (result.isInvalid())
return true;
- Args[i] = result.take();
+ Args[i] = result.get();
}
unsigned DiagID;
@@ -1366,7 +1368,7 @@
Expr *argExpr = Args[i];
- ParmVarDecl *param = Method->param_begin()[i];
+ ParmVarDecl *param = Method->parameters()[i];
assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
// Strip the unbridged-cast placeholder expression off unless it's
@@ -1383,7 +1385,7 @@
if (argE.isInvalid()) {
IsError = true;
} else {
- Args[i] = argE.take();
+ Args[i] = argE.get();
// Update the parameter type in-place.
param->setType(paramType);
@@ -1398,11 +1400,11 @@
InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
param);
- ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, Owned(argExpr));
+ ExprResult ArgE = PerformCopyInitialization(Entity, SelLoc, argExpr);
if (ArgE.isInvalid())
IsError = true;
else
- Args[i] = ArgE.takeAs<Expr>();
+ Args[i] = ArgE.getAs<Expr>();
}
// Promote additional arguments to variadic methods.
@@ -1414,7 +1416,7 @@
ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
nullptr);
IsError |= Arg.isInvalid();
- Args[i] = Arg.take();
+ Args[i] = Arg.get();
}
} else {
// Check for extra arguments to non-variadic methods.
@@ -1583,14 +1585,13 @@
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
if (Super)
- return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- MemberLoc,
- SuperLoc, SuperType));
+ return new (Context)
+ ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
else
- return Owned(new (Context) ObjCPropertyRefExpr(PD, Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- MemberLoc, BaseExpr));
+ return new (Context)
+ ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, BaseExpr);
}
// Check protocols on qualified interfaces.
for (const auto *I : OPT->quals())
@@ -1600,19 +1601,13 @@
return ExprError();
if (Super)
- return Owned(new (Context) ObjCPropertyRefExpr(PD,
- Context.PseudoObjectTy,
- VK_LValue,
- OK_ObjCProperty,
- MemberLoc,
- SuperLoc, SuperType));
+ return new (Context) ObjCPropertyRefExpr(
+ PD, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty, MemberLoc,
+ SuperLoc, SuperType);
else
- return Owned(new (Context) ObjCPropertyRefExpr(PD,
- Context.PseudoObjectTy,
- VK_LValue,
- OK_ObjCProperty,
- MemberLoc,
- BaseExpr));
+ return new (Context)
+ ObjCPropertyRefExpr(PD, Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, BaseExpr);
}
// If that failed, look for an "implicit" property by seeing if the nullary
// selector is implemented.
@@ -1658,16 +1653,13 @@
if (Getter || Setter) {
if (Super)
- return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
- Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- MemberLoc,
- SuperLoc, SuperType));
+ return new (Context)
+ ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, SuperLoc, SuperType);
else
- return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
- Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- MemberLoc, BaseExpr));
+ return new (Context)
+ ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, MemberLoc, BaseExpr);
}
@@ -1798,18 +1790,14 @@
if (Getter || Setter) {
if (IsSuper)
- return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
- Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- propertyNameLoc,
- receiverNameLoc,
- Context.getObjCInterfaceType(IFace)));
+ return new (Context)
+ ObjCPropertyRefExpr(Getter, Setter, Context.PseudoObjectTy, VK_LValue,
+ OK_ObjCProperty, propertyNameLoc, receiverNameLoc,
+ Context.getObjCInterfaceType(IFace));
- return Owned(new (Context) ObjCPropertyRefExpr(Getter, Setter,
- Context.PseudoObjectTy,
- VK_LValue, OK_ObjCProperty,
- propertyNameLoc,
- receiverNameLoc, IFace));
+ return new (Context) ObjCPropertyRefExpr(
+ Getter, Setter, Context.PseudoObjectTy, VK_LValue, OK_ObjCProperty,
+ propertyNameLoc, receiverNameLoc, IFace);
}
return ExprError(Diag(propertyNameLoc, diag::err_property_not_found)
<< &propertyName << Context.getObjCInterfaceType(IFace));
@@ -2007,7 +1995,7 @@
bool (*refactor)(const ObjCMessageExpr *,
const NSAPI &, edit::Commit &)) {
SourceLocation MsgLoc = Msg->getExprLoc();
- if (S.Diags.getDiagnosticLevel(DiagID, MsgLoc) == DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(DiagID, MsgLoc))
return;
SourceManager &SM = S.SourceMgr;
@@ -2103,11 +2091,10 @@
unsigned NumArgs = ArgsIn.size();
Expr **Args = ArgsIn.data();
assert(SuperLoc.isInvalid() && "Message to super with dependent type");
- return Owned(ObjCMessageExpr::Create(Context, ReceiverType,
- VK_RValue, LBracLoc, ReceiverTypeInfo,
- Sel, SelectorLocs, /*Method=*/nullptr,
- makeArrayRef(Args, NumArgs),RBracLoc,
- isImplicit));
+ return ObjCMessageExpr::Create(
+ Context, ReceiverType, VK_RValue, LBracLoc, ReceiverTypeInfo, Sel,
+ SelectorLocs, /*Method=*/nullptr, makeArrayRef(Args, NumArgs), RBracLoc,
+ isImplicit);
}
// Find the class to which we are sending this message.
@@ -2288,7 +2275,7 @@
else
Result = CheckPlaceholderExpr(Receiver);
if (Result.isInvalid()) return ExprError();
- Receiver = Result.take();
+ Receiver = Result.get();
}
if (Receiver->isTypeDependent()) {
@@ -2297,11 +2284,10 @@
unsigned NumArgs = ArgsIn.size();
Expr **Args = ArgsIn.data();
assert(SuperLoc.isInvalid() && "Message to super with dependent type");
- return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy,
- VK_RValue, LBracLoc, Receiver, Sel,
- SelectorLocs, /*Method=*/nullptr,
- makeArrayRef(Args, NumArgs),
- RBracLoc, isImplicit));
+ return ObjCMessageExpr::Create(
+ Context, Context.DependentTy, VK_RValue, LBracLoc, Receiver, Sel,
+ SelectorLocs, /*Method=*/nullptr, makeArrayRef(Args, NumArgs),
+ RBracLoc, isImplicit);
}
// If necessary, apply function/array conversion to the receiver.
@@ -2309,7 +2295,7 @@
ExprResult Result = DefaultFunctionArrayLvalueConversion(Receiver);
if (Result.isInvalid())
return ExprError();
- Receiver = Result.take();
+ Receiver = Result.get();
ReceiverType = Receiver->getType();
// If the receiver is an ObjC pointer, a block pointer, or an
@@ -2328,14 +2314,14 @@
<< Receiver->getSourceRange();
if (ReceiverType->isPointerType()) {
Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
- CK_CPointerToObjCPointerCast).take();
+ CK_CPointerToObjCPointerCast).get();
} else {
// TODO: specialized warning on null receivers?
bool IsNull = Receiver->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull);
CastKind Kind = IsNull ? CK_NullToPointer : CK_IntegralToPointer;
Receiver = ImpCastExprToType(Receiver, Context.getObjCIdType(),
- Kind).take();
+ Kind).get();
}
ReceiverType = Receiver->getType();
} else if (getLangOpts().CPlusPlus) {
@@ -2346,7 +2332,7 @@
ExprResult result = PerformContextuallyConvertToObjCPointer(Receiver);
if (result.isUsable()) {
- Receiver = result.take();
+ Receiver = result.get();
ReceiverType = Receiver->getType();
}
}
@@ -2662,7 +2648,14 @@
}
if (getLangOpts().ObjCAutoRefCount) {
- DiagnoseARCUseOfWeakReceiver(*this, Receiver);
+ // Do not warn about IBOutlet weak property receivers being set to null
+ // as this cannot asynchronously happen.
+ bool WarnWeakReceiver = true;
+ if (isImplicit && Method)
+ if (const ObjCPropertyDecl *PropertyDecl = Method->findPropertyDecl())
+ WarnWeakReceiver = !PropertyDecl->hasAttr<IBOutletAttr>();
+ if (WarnWeakReceiver)
+ DiagnoseARCUseOfWeakReceiver(*this, Receiver);
// In ARC, annotate delegate init calls.
if (Result->getMethodFamily() == OMF_init &&
@@ -2674,7 +2667,7 @@
// The implicit assignment to self means we also don't want to
// consume the result.
Result->setDelegateInitCall(true);
- return Owned(Result);
+ return Result;
}
}
@@ -2688,15 +2681,9 @@
Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak;
if (!IsWeak && Sel.isUnarySelector())
IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak;
-
- if (IsWeak) {
- DiagnosticsEngine::Level Level =
- Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- LBracLoc);
- if (Level != DiagnosticsEngine::Ignored)
- getCurFunction()->recordUseOfWeak(Result, Prop);
-
- }
+ if (IsWeak &&
+ !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc))
+ getCurFunction()->recordUseOfWeak(Result, Prop);
}
}
}
@@ -2733,7 +2720,7 @@
if (isa<ParenListExpr>(Receiver)) {
ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Receiver);
if (Result.isInvalid()) return ExprError();
- Receiver = Result.take();
+ Receiver = Result.get();
}
if (RespondsToSelectorSel.isNull()) {
@@ -3153,7 +3140,7 @@
if (QT->isPointerType()) {
QT = QT->getPointeeType();
if (const RecordType *RT = QT->getAs<RecordType>())
- if (RecordDecl *RD = RT->getDecl())
+ if (RecordDecl *RD = RT->getDecl()->getMostRecentDecl())
return RD->getAttr<T>();
}
return nullptr;
@@ -3300,12 +3287,15 @@
}
template <typename TB>
-static void CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
+ bool &HadTheAttribute, bool warn) {
QualType T = castExpr->getType();
+ HadTheAttribute = false;
while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
TypedefNameDecl *TDNDecl = TD->getDecl();
if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
+ HadTheAttribute = true;
NamedDecl *Target = nullptr;
// Check for an existing type with this name.
LookupResult R(S, DeclarationName(Parm), SourceLocation(),
@@ -3320,23 +3310,26 @@
= InterfacePointerType->getObjectType()->getInterface();
if ((CastClass == ExprClass) ||
(CastClass && ExprClass->isSuperClassOf(CastClass)))
- return;
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
- << T << Target->getName() << castType->getPointeeType();
- return;
+ return true;
+ if (warn)
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+ << T << Target->getName() << castType->getPointeeType();
+ return false;
} else if (castType->isObjCIdType() ||
(S.Context.ObjCObjectAdoptsQTypeProtocols(
castType, ExprClass)))
// ok to cast to 'id'.
// casting to id<p-list> is ok if bridge type adopts all of
// p-list protocols.
- return;
+ return true;
else {
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
- << T << Target->getName() << castType;
- S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- S.Diag(Target->getLocStart(), diag::note_declared_at);
- return;
+ if (warn) {
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge)
+ << T << Target->getName() << castType;
+ S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ S.Diag(Target->getLocStart(), diag::note_declared_at);
+ }
+ return false;
}
}
}
@@ -3345,20 +3338,25 @@
S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
if (Target)
S.Diag(Target->getLocStart(), diag::note_declared_at);
+ return true;
}
- return;
+ return false;
}
T = TDNDecl->getUnderlyingType();
}
+ return true;
}
template <typename TB>
-static void CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr) {
+static bool CheckObjCBridgeCFCast(Sema &S, QualType castType, Expr *castExpr,
+ bool &HadTheAttribute, bool warn) {
QualType T = castType;
+ HadTheAttribute = false;
while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
TypedefNameDecl *TDNDecl = TD->getDecl();
if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
+ HadTheAttribute = true;
NamedDecl *Target = nullptr;
// Check for an existing type with this name.
LookupResult R(S, DeclarationName(Parm), SourceLocation(),
@@ -3373,24 +3371,28 @@
= InterfacePointerType->getObjectType()->getInterface();
if ((CastClass == ExprClass) ||
(ExprClass && CastClass->isSuperClassOf(ExprClass)))
- return;
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
- << castExpr->getType()->getPointeeType() << T;
- S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- return;
+ return true;
+ if (warn) {
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+ << castExpr->getType()->getPointeeType() << T;
+ S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
+ return false;
} else if (castExpr->getType()->isObjCIdType() ||
(S.Context.QIdProtocolsAdoptObjCObjectProtocols(
castExpr->getType(), CastClass)))
// ok to cast an 'id' expression to a CFtype.
// ok to cast an 'id<plist>' expression to CFtype provided plist
// adopts all of CFtype's ObjetiveC's class plist.
- return;
+ return true;
else {
- S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
- << castExpr->getType() << castType;
- S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
- S.Diag(Target->getLocStart(), diag::note_declared_at);
- return;
+ if (warn) {
+ S.Diag(castExpr->getLocStart(), diag::warn_objc_invalid_bridge_to_cf)
+ << castExpr->getType() << castType;
+ S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ S.Diag(Target->getLocStart(), diag::note_declared_at);
+ }
+ return false;
}
}
}
@@ -3399,11 +3401,13 @@
S.Diag(TDNDecl->getLocStart(), diag::note_declared_at);
if (Target)
S.Diag(Target->getLocStart(), diag::note_declared_at);
+ return true;
}
- return;
+ return false;
}
T = TDNDecl->getUnderlyingType();
}
+ return true;
}
void Sema::CheckTollFreeBridgeCast(QualType castType, Expr *castExpr) {
@@ -3413,15 +3417,72 @@
ARCConversionTypeClass exprACTC = classifyTypeForARCConversion(castExpr->getType());
ARCConversionTypeClass castACTC = classifyTypeForARCConversion(castType);
if (castACTC == ACTC_retainable && exprACTC == ACTC_coreFoundation) {
- CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr);
- CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+ bool HasObjCBridgeAttr;
+ bool ObjCBridgeAttrWillNotWarn =
+ CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ false);
+ if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+ return;
+ bool HasObjCBridgeMutableAttr;
+ bool ObjCBridgeMutableAttrWillNotWarn =
+ CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, false);
+ if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+ return;
+
+ if (HasObjCBridgeAttr)
+ CheckObjCBridgeNSCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ true);
+ else if (HasObjCBridgeMutableAttr)
+ CheckObjCBridgeNSCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, true);
}
else if (castACTC == ACTC_coreFoundation && exprACTC == ACTC_retainable) {
- CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr);
- CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr);
+ bool HasObjCBridgeAttr;
+ bool ObjCBridgeAttrWillNotWarn =
+ CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ false);
+ if (ObjCBridgeAttrWillNotWarn && HasObjCBridgeAttr)
+ return;
+ bool HasObjCBridgeMutableAttr;
+ bool ObjCBridgeMutableAttrWillNotWarn =
+ CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, false);
+ if (ObjCBridgeMutableAttrWillNotWarn && HasObjCBridgeMutableAttr)
+ return;
+
+ if (HasObjCBridgeAttr)
+ CheckObjCBridgeCFCast<ObjCBridgeAttr>(*this, castType, castExpr, HasObjCBridgeAttr,
+ true);
+ else if (HasObjCBridgeMutableAttr)
+ CheckObjCBridgeCFCast<ObjCBridgeMutableAttr>(*this, castType, castExpr,
+ HasObjCBridgeMutableAttr, true);
}
}
+void Sema::CheckObjCBridgeRelatedCast(QualType castType, Expr *castExpr) {
+ QualType SrcType = castExpr->getType();
+ if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(castExpr)) {
+ if (PRE->isExplicitProperty()) {
+ if (ObjCPropertyDecl *PDecl = PRE->getExplicitProperty())
+ SrcType = PDecl->getType();
+ }
+ else if (PRE->isImplicitProperty()) {
+ if (ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter())
+ SrcType = Getter->getReturnType();
+
+ }
+ }
+
+ ARCConversionTypeClass srcExprACTC = classifyTypeForARCConversion(SrcType);
+ ARCConversionTypeClass castExprACTC = classifyTypeForARCConversion(castType);
+ if (srcExprACTC != ACTC_retainable || castExprACTC != ACTC_coreFoundation)
+ return;
+ CheckObjCBridgeRelatedConversions(castExpr->getLocStart(),
+ castType, SrcType, castExpr);
+ return;
+}
+
bool Sema::CheckTollFreeBridgeStaticCast(QualType castType, Expr *castExpr,
CastKind &Kind) {
if (!getLangOpts().ObjC1)
@@ -3547,7 +3608,7 @@
ClassMethod->getLocation(),
ClassMethod->getSelector(), ClassMethod,
MultiExprArg(args, 1));
- SrcExpr = msg.take();
+ SrcExpr = msg.get();
return true;
}
}
@@ -3584,7 +3645,7 @@
InstanceMethod->getLocation(),
InstanceMethod->getSelector(),
InstanceMethod, None);
- SrcExpr = msg.take();
+ SrcExpr = msg.get();
return true;
}
}
@@ -3594,7 +3655,8 @@
Sema::ARCConversionResult
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
Expr *&castExpr, CheckedConversionKind CCK,
- bool DiagnoseCFAudited) {
+ bool DiagnoseCFAudited,
+ BinaryOperatorKind Opc) {
QualType castExprType = castExpr->getType();
// For the purposes of the classification, we assume reference types
@@ -3688,8 +3750,10 @@
// instead.
if (!DiagnoseCFAudited || exprACTC != ACTC_retainable ||
castACTC != ACTC_coreFoundation)
- diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
- castExpr, castExpr, exprACTC, CCK);
+ if (!(exprACTC == ACTC_voidPtr && castACTC == ACTC_retainable &&
+ (Opc == BO_NE || Opc == BO_EQ)))
+ diagnoseObjCARCConversion(*this, castRange, castType, castACTC,
+ castExpr, castExpr, exprACTC, CCK);
return ACR_okay;
}
@@ -3806,7 +3870,7 @@
Expr *SubExpr) {
ExprResult SubResult = UsualUnaryConversions(SubExpr);
if (SubResult.isInvalid()) return ExprError();
- SubExpr = SubResult.take();
+ SubExpr = SubResult.get();
QualType T = TSInfo->getType();
QualType FromType = SubExpr->getType();
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index a169602..a33724a 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Designator.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/SemaInternal.h"
@@ -312,15 +313,20 @@
int numArrayElements(QualType DeclType);
int numStructUnionElements(QualType DeclType);
- void FillInValueInitForField(unsigned Init, FieldDecl *Field,
+ static ExprResult PerformEmptyInit(Sema &SemaRef,
+ SourceLocation Loc,
+ const InitializedEntity &Entity,
+ bool VerifyOnly);
+ void FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
const InitializedEntity &ParentEntity,
InitListExpr *ILE, bool &RequiresSecondPass);
- void FillInValueInitializations(const InitializedEntity &Entity,
+ void FillInEmptyInitializations(const InitializedEntity &Entity,
InitListExpr *ILE, bool &RequiresSecondPass);
bool CheckFlexibleArrayInit(const InitializedEntity &Entity,
Expr *InitExpr, FieldDecl *Field,
bool TopLevelObject);
- void CheckValueInitializable(const InitializedEntity &Entity);
+ void CheckEmptyInitializable(const InitializedEntity &Entity,
+ SourceLocation Loc);
public:
InitListChecker(Sema &S, const InitializedEntity &Entity,
@@ -333,33 +339,134 @@
};
} // end anonymous namespace
-void InitListChecker::CheckValueInitializable(const InitializedEntity &Entity) {
- assert(VerifyOnly &&
- "CheckValueInitializable is only inteded for verification mode.");
-
- SourceLocation Loc;
+ExprResult InitListChecker::PerformEmptyInit(Sema &SemaRef,
+ SourceLocation Loc,
+ const InitializedEntity &Entity,
+ bool VerifyOnly) {
InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
true);
- InitializationSequence InitSeq(SemaRef, Entity, Kind, None);
- if (InitSeq.Failed())
+ MultiExprArg SubInit;
+ Expr *InitExpr;
+ InitListExpr DummyInitList(SemaRef.Context, Loc, None, Loc);
+
+ // C++ [dcl.init.aggr]p7:
+ // If there are fewer initializer-clauses in the list than there are
+ // members in the aggregate, then each member not explicitly initialized
+ // ...
+ bool EmptyInitList = SemaRef.getLangOpts().CPlusPlus11 &&
+ Entity.getType()->getBaseElementTypeUnsafe()->isRecordType();
+ if (EmptyInitList) {
+ // C++1y / DR1070:
+ // shall be initialized [...] from an empty initializer list.
+ //
+ // We apply the resolution of this DR to C++11 but not C++98, since C++98
+ // does not have useful semantics for initialization from an init list.
+ // We treat this as copy-initialization, because aggregate initialization
+ // always performs copy-initialization on its elements.
+ //
+ // Only do this if we're initializing a class type, to avoid filling in
+ // the initializer list where possible.
+ InitExpr = VerifyOnly ? &DummyInitList : new (SemaRef.Context)
+ InitListExpr(SemaRef.Context, Loc, None, Loc);
+ InitExpr->setType(SemaRef.Context.VoidTy);
+ SubInit = InitExpr;
+ Kind = InitializationKind::CreateCopy(Loc, Loc);
+ } else {
+ // C++03:
+ // shall be value-initialized.
+ }
+
+ InitializationSequence InitSeq(SemaRef, Entity, Kind, SubInit);
+ // libstdc++4.6 marks the vector default constructor as explicit in
+ // _GLIBCXX_DEBUG mode, so recover using the C++03 logic in that case.
+ // stlport does so too. Look for std::__debug for libstdc++, and for
+ // std:: for stlport. This is effectively a compiler-side implementation of
+ // LWG2193.
+ if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() ==
+ InitializationSequence::FK_ExplicitConstructor) {
+ OverloadCandidateSet::iterator Best;
+ OverloadingResult O =
+ InitSeq.getFailedCandidateSet()
+ .BestViableFunction(SemaRef, Kind.getLocation(), Best);
+ (void)O;
+ assert(O == OR_Success && "Inconsistent overload resolution");
+ CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
+ CXXRecordDecl *R = CtorDecl->getParent();
+
+ if (CtorDecl->getMinRequiredArguments() == 0 &&
+ CtorDecl->isExplicit() && R->getDeclName() &&
+ SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) {
+
+
+ bool IsInStd = false;
+ for (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(R->getDeclContext());
+ ND && !IsInStd; ND = dyn_cast<NamespaceDecl>(ND->getParent())) {
+ if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND))
+ IsInStd = true;
+ }
+
+ if (IsInStd && llvm::StringSwitch<bool>(R->getName())
+ .Cases("basic_string", "deque", "forward_list", true)
+ .Cases("list", "map", "multimap", "multiset", true)
+ .Cases("priority_queue", "queue", "set", "stack", true)
+ .Cases("unordered_map", "unordered_set", "vector", true)
+ .Default(false)) {
+ InitSeq.InitializeFrom(
+ SemaRef, Entity,
+ InitializationKind::CreateValue(Loc, Loc, Loc, true),
+ MultiExprArg(), /*TopLevelOfInitList=*/false);
+ // Emit a warning for this. System header warnings aren't shown
+ // by default, but people working on system headers should see it.
+ if (!VerifyOnly) {
+ SemaRef.Diag(CtorDecl->getLocation(),
+ diag::warn_invalid_initializer_from_system_header);
+ SemaRef.Diag(Entity.getDecl()->getLocation(),
+ diag::note_used_in_initialization_here);
+ }
+ }
+ }
+ }
+ if (!InitSeq) {
+ if (!VerifyOnly) {
+ InitSeq.Diagnose(SemaRef, Entity, Kind, SubInit);
+ if (Entity.getKind() == InitializedEntity::EK_Member)
+ SemaRef.Diag(Entity.getDecl()->getLocation(),
+ diag::note_in_omitted_aggregate_initializer)
+ << /*field*/1 << Entity.getDecl();
+ else if (Entity.getKind() == InitializedEntity::EK_ArrayElement)
+ SemaRef.Diag(Loc, diag::note_in_omitted_aggregate_initializer)
+ << /*array element*/0 << Entity.getElementIndex();
+ }
+ return ExprError();
+ }
+
+ return VerifyOnly ? ExprResult(static_cast<Expr *>(nullptr))
+ : InitSeq.Perform(SemaRef, Entity, Kind, SubInit);
+}
+
+void InitListChecker::CheckEmptyInitializable(const InitializedEntity &Entity,
+ SourceLocation Loc) {
+ assert(VerifyOnly &&
+ "CheckEmptyInitializable is only inteded for verification mode.");
+ if (PerformEmptyInit(SemaRef, Loc, Entity, /*VerifyOnly*/true).isInvalid())
hadError = true;
}
-void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
+void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
const InitializedEntity &ParentEntity,
InitListExpr *ILE,
bool &RequiresSecondPass) {
- SourceLocation Loc = ILE->getLocStart();
+ SourceLocation Loc = ILE->getLocEnd();
unsigned NumInits = ILE->getNumInits();
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.
+ // C++1y [dcl.init.aggr]p7:
+ // If there are fewer initializer-clauses in the list than there are
+ // members in the aggregate, then each member not explicitly initialized
+ // shall be initialized from its brace-or-equal-initializer [...]
if (Field->hasInClassInitializer()) {
- Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context,
- ILE->getRBraceLoc(), Field);
+ Expr *DIE = CXXDefaultInitExpr::Create(SemaRef.Context, Loc, Field);
if (Init < NumInits)
ILE->setInit(Init, DIE);
else {
@@ -369,9 +476,6 @@
return;
}
- // FIXME: We probably don't need to handle references
- // specially here, since value-initialization of references is
- // handled in InitializationSequence.
if (Field->getType()->isReferenceType()) {
// C++ [dcl.init.aggr]p9:
// If an incomplete or empty initializer-list leaves a
@@ -386,17 +490,8 @@
return;
}
- InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
- true);
- InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, None);
- if (!InitSeq) {
- InitSeq.Diagnose(SemaRef, MemberEntity, Kind, None);
- hadError = true;
- return;
- }
-
- ExprResult MemberInit
- = InitSeq.Perform(SemaRef, MemberEntity, Kind, None);
+ ExprResult MemberInit = PerformEmptyInit(SemaRef, Loc, MemberEntity,
+ /*VerifyOnly*/false);
if (MemberInit.isInvalid()) {
hadError = true;
return;
@@ -405,18 +500,18 @@
if (hadError) {
// Do nothing
} else if (Init < NumInits) {
- ILE->setInit(Init, MemberInit.takeAs<Expr>());
- } else if (InitSeq.isConstructorInitialization()) {
- // Value-initialization requires a constructor call, so
+ ILE->setInit(Init, MemberInit.getAs<Expr>());
+ } else if (!isa<ImplicitValueInitExpr>(MemberInit.get())) {
+ // Empty initialization requires a constructor call, so
// extend the initializer list to include the constructor
// call and make a note that we'll need to take another pass
// through the initializer list.
- ILE->updateInit(SemaRef.Context, Init, MemberInit.takeAs<Expr>());
+ ILE->updateInit(SemaRef.Context, Init, MemberInit.getAs<Expr>());
RequiresSecondPass = true;
}
} else if (InitListExpr *InnerILE
= dyn_cast<InitListExpr>(ILE->getInit(Init)))
- FillInValueInitializations(MemberEntity, InnerILE,
+ FillInEmptyInitializations(MemberEntity, InnerILE,
RequiresSecondPass);
}
@@ -424,25 +519,22 @@
/// with expressions that perform value-initialization of the
/// appropriate type.
void
-InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
+InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
InitListExpr *ILE,
bool &RequiresSecondPass) {
assert((ILE->getType() != SemaRef.Context.VoidTy) &&
"Should not have void type");
- SourceLocation Loc = ILE->getLocStart();
- if (ILE->getSyntacticForm())
- Loc = ILE->getSyntacticForm()->getLocStart();
if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
const RecordDecl *RDecl = RType->getDecl();
if (RDecl->isUnion() && ILE->getInitializedFieldInUnion())
- FillInValueInitForField(0, ILE->getInitializedFieldInUnion(),
+ FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(),
Entity, ILE, RequiresSecondPass);
else if (RDecl->isUnion() && isa<CXXRecordDecl>(RDecl) &&
cast<CXXRecordDecl>(RDecl)->hasInClassInitializer()) {
for (auto *Field : RDecl->fields()) {
if (Field->hasInClassInitializer()) {
- FillInValueInitForField(0, Field, Entity, ILE, RequiresSecondPass);
+ FillInEmptyInitForField(0, Field, Entity, ILE, RequiresSecondPass);
break;
}
}
@@ -455,7 +547,7 @@
if (hadError)
return;
- FillInValueInitForField(Init, Field, Entity, ILE, RequiresSecondPass);
+ FillInEmptyInitForField(Init, Field, Entity, ILE, RequiresSecondPass);
if (hadError)
return;
@@ -489,7 +581,6 @@
} else
ElementType = ILE->getType();
-
for (unsigned Init = 0; Init != NumElements; ++Init) {
if (hadError)
return;
@@ -500,17 +591,9 @@
Expr *InitExpr = (Init < NumInits ? ILE->getInit(Init) : nullptr);
if (!InitExpr && !ILE->hasArrayFiller()) {
- InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc,
- true);
- InitializationSequence InitSeq(SemaRef, ElementEntity, Kind, None);
- if (!InitSeq) {
- InitSeq.Diagnose(SemaRef, ElementEntity, Kind, None);
- hadError = true;
- return;
- }
-
- ExprResult ElementInit
- = InitSeq.Perform(SemaRef, ElementEntity, Kind, None);
+ ExprResult ElementInit = PerformEmptyInit(SemaRef, ILE->getLocEnd(),
+ ElementEntity,
+ /*VerifyOnly*/false);
if (ElementInit.isInvalid()) {
hadError = true;
return;
@@ -522,29 +605,29 @@
// For arrays, just set the expression used for value-initialization
// of the "holes" in the array.
if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement)
- ILE->setArrayFiller(ElementInit.takeAs<Expr>());
+ ILE->setArrayFiller(ElementInit.getAs<Expr>());
else
- ILE->setInit(Init, ElementInit.takeAs<Expr>());
+ ILE->setInit(Init, ElementInit.getAs<Expr>());
} else {
// For arrays, just set the expression used for value-initialization
// of the rest of elements and exit.
if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement) {
- ILE->setArrayFiller(ElementInit.takeAs<Expr>());
+ ILE->setArrayFiller(ElementInit.getAs<Expr>());
return;
}
- if (InitSeq.isConstructorInitialization()) {
- // Value-initialization requires a constructor call, so
+ if (!isa<ImplicitValueInitExpr>(ElementInit.get())) {
+ // Empty initialization requires a constructor call, so
// extend the initializer list to include the constructor
// call and make a note that we'll need to take another pass
// through the initializer list.
- ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>());
+ ILE->updateInit(SemaRef.Context, Init, ElementInit.getAs<Expr>());
RequiresSecondPass = true;
}
}
} else if (InitListExpr *InnerILE
= dyn_cast_or_null<InitListExpr>(InitExpr))
- FillInValueInitializations(ElementEntity, InnerILE, RequiresSecondPass);
+ FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass);
}
}
@@ -562,9 +645,9 @@
if (!hadError && !VerifyOnly) {
bool RequiresSecondPass = false;
- FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass);
+ FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass);
if (RequiresSecondPass && !hadError)
- FillInValueInitializations(Entity, FullyStructuredList,
+ FillInEmptyInitializations(Entity, FullyStructuredList,
RequiresSecondPass);
}
}
@@ -673,7 +756,6 @@
InitListExpr *IList, QualType &T,
InitListExpr *StructuredList,
bool TopLevelObject) {
- assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
if (!VerifyOnly) {
SyntacticToSemantic[IList] = StructuredList;
StructuredList->setSyntacticForm(IList);
@@ -878,7 +960,7 @@
hadError = true;
UpdateStructuredListElement(StructuredList, StructuredIndex,
- Result.takeAs<Expr>());
+ Result.getAs<Expr>());
}
++Index;
return;
@@ -894,7 +976,7 @@
// compatible structure or union type. In the latter case, the
// initial value of the object, including unnamed members, is
// that of the expression.
- ExprResult ExprRes = SemaRef.Owned(expr);
+ ExprResult ExprRes = expr;
if ((ElemType->isRecordType() || ElemType->isVectorType()) &&
SemaRef.CheckSingleAssignmentConstraints(ElemType, ExprRes,
!VerifyOnly)
@@ -902,16 +984,16 @@
if (ExprRes.isInvalid())
hadError = true;
else {
- ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.take());
+ ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.get());
if (ExprRes.isInvalid())
hadError = true;
}
UpdateStructuredListElement(StructuredList, StructuredIndex,
- ExprRes.takeAs<Expr>());
+ ExprRes.getAs<Expr>());
++Index;
return;
}
- ExprRes.release();
+ ExprRes.get();
// Fall through for subaggregate initialization
}
@@ -930,8 +1012,7 @@
if (!VerifyOnly) {
// We cannot initialize this element, so let
// PerformCopyInitialization produce the appropriate diagnostic.
- SemaRef.PerformCopyInitialization(Entity, SourceLocation(),
- SemaRef.Owned(expr),
+ SemaRef.PerformCopyInitialization(Entity, SourceLocation(), expr,
/*TopLevelOfInitList=*/true);
}
hadError = true;
@@ -1019,15 +1100,14 @@
}
if (VerifyOnly) {
- if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(expr)))
+ if (!SemaRef.CanPerformCopyInitialization(Entity,expr))
hadError = true;
++Index;
return;
}
ExprResult Result =
- SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
- SemaRef.Owned(expr),
+ SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), expr,
/*TopLevelOfInitList=*/true);
Expr *ResultExpr = nullptr;
@@ -1035,7 +1115,7 @@
if (Result.isInvalid())
hadError = true; // types weren't compatible.
else {
- ResultExpr = Result.takeAs<Expr>();
+ ResultExpr = Result.getAs<Expr>();
if (ResultExpr != expr) {
// The type was promoted, update initializer list.
@@ -1082,21 +1162,20 @@
}
if (VerifyOnly) {
- if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(expr)))
+ if (!SemaRef.CanPerformCopyInitialization(Entity,expr))
hadError = true;
++Index;
return;
}
ExprResult Result =
- SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
- SemaRef.Owned(expr),
- /*TopLevelOfInitList=*/true);
+ SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), expr,
+ /*TopLevelOfInitList=*/true);
if (Result.isInvalid())
hadError = true;
- expr = Result.takeAs<Expr>();
+ expr = Result.getAs<Expr>();
IList->setInit(Index, expr);
if (hadError)
@@ -1119,8 +1198,9 @@
if (Index >= IList->getNumInits()) {
// Make sure the element type can be value-initialized.
if (VerifyOnly)
- CheckValueInitializable(
- InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity));
+ CheckEmptyInitializable(
+ InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity),
+ IList->getLocEnd());
return;
}
@@ -1130,22 +1210,21 @@
Expr *Init = IList->getInit(Index);
if (!isa<InitListExpr>(Init) && Init->getType()->isVectorType()) {
if (VerifyOnly) {
- if (!SemaRef.CanPerformCopyInitialization(Entity, SemaRef.Owned(Init)))
+ if (!SemaRef.CanPerformCopyInitialization(Entity, Init))
hadError = true;
++Index;
return;
}
- ExprResult Result =
- SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(),
- SemaRef.Owned(Init),
- /*TopLevelOfInitList=*/true);
+ ExprResult Result =
+ SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(), Init,
+ /*TopLevelOfInitList=*/true);
Expr *ResultExpr = nullptr;
if (Result.isInvalid())
hadError = true; // types weren't compatible.
else {
- ResultExpr = Result.takeAs<Expr>();
+ ResultExpr = Result.getAs<Expr>();
if (ResultExpr != Init) {
// The type was promoted, update initializer list.
@@ -1168,7 +1247,7 @@
// Don't attempt to go past the end of the init list
if (Index >= IList->getNumInits()) {
if (VerifyOnly)
- CheckValueInitializable(ElementEntity);
+ CheckEmptyInitializable(ElementEntity, IList->getLocEnd());
break;
}
@@ -1176,6 +1255,46 @@
CheckSubElementType(ElementEntity, IList, elementType, Index,
StructuredList, StructuredIndex);
}
+
+ if (VerifyOnly)
+ return;
+
+ bool isBigEndian = SemaRef.Context.getTargetInfo().isBigEndian();
+ const VectorType *T = Entity.getType()->getAs<VectorType>();
+ if (isBigEndian && (T->getVectorKind() == VectorType::NeonVector ||
+ T->getVectorKind() == VectorType::NeonPolyVector)) {
+ // The ability to use vector initializer lists is a GNU vector extension
+ // and is unrelated to the NEON intrinsics in arm_neon.h. On little
+ // endian machines it works fine, however on big endian machines it
+ // exhibits surprising behaviour:
+ //
+ // uint32x2_t x = {42, 64};
+ // return vget_lane_u32(x, 0); // Will return 64.
+ //
+ // Because of this, explicitly call out that it is non-portable.
+ //
+ SemaRef.Diag(IList->getLocStart(),
+ diag::warn_neon_vector_initializer_non_portable);
+
+ const char *typeCode;
+ unsigned typeSize = SemaRef.Context.getTypeSize(elementType);
+
+ if (elementType->isFloatingType())
+ typeCode = "f";
+ else if (elementType->isSignedIntegerType())
+ typeCode = "s";
+ else if (elementType->isUnsignedIntegerType())
+ typeCode = "u";
+ else
+ llvm_unreachable("Invalid element type!");
+
+ SemaRef.Diag(IList->getLocStart(),
+ SemaRef.Context.getTypeSize(VT) > 64 ?
+ diag::note_neon_vector_initializer_non_portable_q :
+ diag::note_neon_vector_initializer_non_portable)
+ << typeCode << typeSize;
+ }
+
return;
}
@@ -1345,8 +1464,9 @@
// If so, check if doing that is possible.
// FIXME: This needs to detect holes left by designated initializers too.
if (maxElementsKnown && elementIndex < maxElements)
- CheckValueInitializable(InitializedEntity::InitializeElement(
- SemaRef.Context, 0, Entity));
+ CheckEmptyInitializable(InitializedEntity::InitializeElement(
+ SemaRef.Context, 0, Entity),
+ IList->getLocEnd());
}
}
@@ -1431,8 +1551,9 @@
Field != FieldEnd; ++Field) {
if (Field->getDeclName()) {
if (VerifyOnly)
- CheckValueInitializable(
- InitializedEntity::InitializeMember(*Field, &Entity));
+ CheckEmptyInitializable(
+ InitializedEntity::InitializeMember(*Field, &Entity),
+ IList->getLocEnd());
else
StructuredList->setInitializedFieldInUnion(*Field);
break;
@@ -1544,8 +1665,9 @@
// FIXME: Should check for holes left by designated initializers too.
for (; Field != FieldEnd && !hadError; ++Field) {
if (!Field->isUnnamedBitfield() && !Field->hasInClassInitializer())
- CheckValueInitializable(
- InitializedEntity::InitializeMember(*Field, &Entity));
+ CheckEmptyInitializable(
+ InitializedEntity::InitializeMember(*Field, &Entity),
+ IList->getLocEnd());
}
}
@@ -2373,7 +2495,7 @@
Expr *Index = static_cast<Expr *>(D.getArrayIndex());
llvm::APSInt IndexValue;
if (!Index->isTypeDependent() && !Index->isValueDependent())
- Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).take();
+ Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).get();
if (!Index)
Invalid = true;
else {
@@ -2396,9 +2518,9 @@
EndIndex->isValueDependent();
if (!StartDependent)
StartIndex =
- CheckArrayDesignatorExpr(*this, StartIndex, StartValue).take();
+ CheckArrayDesignatorExpr(*this, StartIndex, StartValue).get();
if (!EndDependent)
- EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).take();
+ EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).get();
if (!StartIndex || !EndIndex)
Invalid = true;
@@ -2440,13 +2562,13 @@
= DesignatedInitExpr::Create(Context,
Designators.data(), Designators.size(),
InitExpressions, Loc, GNUSyntax,
- Init.takeAs<Expr>());
+ Init.getAs<Expr>());
if (!getLangOpts().C99)
Diag(DIE->getLocStart(), diag::ext_designated_init)
<< DIE->getSourceRange();
- return Owned(DIE);
+ return DIE;
}
//===----------------------------------------------------------------------===//
@@ -4433,7 +4555,7 @@
SetFailed(FK_PlaceholderType);
return;
}
- Args[I] = result.take();
+ Args[I] = result.get();
}
// C++0x [dcl.init]p16:
@@ -4982,7 +5104,7 @@
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
SmallVector<Expr*, 8> ConstructorArgs;
- CurInit.release(); // Ownership transferred into MultiExprArg, below.
+ CurInit.get(); // Ownership transferred into MultiExprArg, below.
S.CheckConstructorAccess(Loc, Constructor, Entity,
Best->FoundDecl.getAccess(), IsExtraneousCopy);
@@ -5010,7 +5132,7 @@
S.BuildCXXDefaultArgExpr(Loc, Constructor, Parm);
}
- return S.Owned(CurInitExpr);
+ return CurInitExpr;
}
// Determine the arguments required to actually perform the
@@ -5030,7 +5152,7 @@
// If we're supposed to bind temporaries, do so.
if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+ CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
return CurInit;
}
@@ -5047,8 +5169,7 @@
return;
SourceLocation Loc = getInitializationLoc(Entity, CurInitExpr);
- if (S.Diags.getDiagnosticLevel(diag::warn_cxx98_compat_temp_copy, Loc)
- == DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_cxx98_compat_temp_copy, Loc))
return;
// Find constructors which would have been considered.
@@ -5169,7 +5290,7 @@
S.DefineImplicitDefaultConstructor(Loc, Constructor);
}
- ExprResult CurInit = S.Owned((Expr *)nullptr);
+ ExprResult CurInit((Expr *)nullptr);
// C++ [over.match.copy]p1:
// - When initializing a temporary to be bound to the first parameter
@@ -5204,13 +5325,10 @@
? SourceRange(LBraceLoc, RBraceLoc)
: Kind.getParenRange();
- CurInit = S.Owned(
- new (S.Context) CXXTemporaryObjectExpr(S.Context, Constructor,
- TSInfo, ConstructorArgs,
- ParenOrBraceRange,
- HadMultipleCandidates,
- IsListInitialization,
- ConstructorInitRequiresZeroInit));
+ CurInit = new (S.Context) CXXTemporaryObjectExpr(
+ S.Context, Constructor, TSInfo, ConstructorArgs, ParenOrBraceRange,
+ HadMultipleCandidates, IsListInitialization,
+ ConstructorInitRequiresZeroInit);
} else {
CXXConstructExpr::ConstructionKind ConstructKind =
CXXConstructExpr::CK_Complete;
@@ -5262,7 +5380,7 @@
return ExprError();
if (shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.take());
+ CurInit = S.MaybeBindToTemporary(CurInit.get());
return CurInit;
}
@@ -5589,7 +5707,7 @@
// No steps means no initialization.
if (Steps.empty())
- return S.Owned((Expr *)nullptr);
+ return ExprResult((Expr *)nullptr);
if (S.getLangOpts().CPlusPlus11 && Entity.getType()->isReferenceType() &&
Args.size() == 1 && isa<InitListExpr>(Args[0]) &&
@@ -5622,7 +5740,7 @@
*ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
Entity.getType();
- ExprResult CurInit = S.Owned((Expr *)nullptr);
+ ExprResult CurInit((Expr *)nullptr);
// For initialization steps that start with a single initializer,
// grab the only argument out the Args and place it into the "current"
@@ -5721,11 +5839,9 @@
(Step->Kind == SK_CastDerivedToBaseXValue ?
VK_XValue :
VK_RValue);
- CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
- Step->Type,
- CK_DerivedToBase,
- CurInit.get(),
- &BasePath, VK));
+ CurInit =
+ ImplicitCastExpr::Create(S.Context, Step->Type, CK_DerivedToBase,
+ CurInit.get(), &BasePath, VK);
break;
}
@@ -5803,7 +5919,7 @@
MTE->getType().isDestructedType()))
S.ExprNeedsCleanups = true;
- CurInit = S.Owned(MTE);
+ CurInit = MTE;
break;
}
@@ -5825,7 +5941,7 @@
// Build a call to the selected constructor.
SmallVector<Expr*, 8> ConstructorArgs;
SourceLocation Loc = CurInit.get()->getLocStart();
- CurInit.release(); // Ownership transferred into MultiExprArg, below.
+ CurInit.get(); // Ownership transferred into MultiExprArg, below.
// Determine the arguments required to actually perform the constructor
// call.
@@ -5870,7 +5986,7 @@
// derived-to-base conversion? I believe the answer is "no", because
// we don't want to turn off access control here for c-style casts.
ExprResult CurInitExprRes =
- S.PerformObjectArgumentInitialization(CurInit.take(),
+ S.PerformObjectArgumentInitialization(CurInit.get(),
/*Qualifier=*/nullptr,
FoundFn, Conversion);
if(CurInitExprRes.isInvalid())
@@ -5904,13 +6020,11 @@
}
}
- CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
- CurInit.get()->getType(),
- CastKind, CurInit.get(),
- nullptr,
- CurInit.get()->getValueKind()));
+ CurInit = ImplicitCastExpr::Create(S.Context, CurInit.get()->getType(),
+ CastKind, CurInit.get(), nullptr,
+ CurInit.get()->getValueKind());
if (MaybeBindToTemp)
- CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+ CurInit = S.MaybeBindToTemporary(CurInit.getAs<Expr>());
if (RequiresCopy)
CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
CurInit, /*IsExtraneousCopy=*/false);
@@ -5927,17 +6041,15 @@
(Step->Kind == SK_QualificationConversionXValue ?
VK_XValue :
VK_RValue);
- CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type, CK_NoOp, VK);
+ CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK);
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=*/nullptr,
- VK_RValue));
+ CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
+ CK_LValueToRValue, CurInit.get(),
+ /*BasePath=*/nullptr, VK_RValue);
break;
}
@@ -5990,10 +6102,10 @@
InitListExpr *StructuredInitList =
PerformInitList.getFullyStructuredList();
- CurInit.release();
+ CurInit.get();
CurInit = shouldBindAsTemporary(InitEntity)
? S.MaybeBindToTemporary(StructuredInitList)
- : S.Owned(StructuredInitList);
+ : StructuredInitList;
break;
}
@@ -6023,18 +6135,18 @@
}
case SK_UnwrapInitList:
- CurInit = S.Owned(cast<InitListExpr>(CurInit.take())->getInit(0));
+ CurInit = cast<InitListExpr>(CurInit.get())->getInit(0);
break;
case SK_RewrapInitList: {
- Expr *E = CurInit.take();
+ Expr *E = CurInit.get();
InitListExpr *Syntactic = Step->WrappingSyntacticList;
InitListExpr *ILE = new (S.Context) InitListExpr(S.Context,
Syntactic->getLBraceLoc(), E, Syntactic->getRBraceLoc());
ILE->setSyntacticForm(Syntactic);
ILE->setType(E->getType());
ILE->setValueKind(E->getValueKind());
- CurInit = S.Owned(ILE);
+ CurInit = ILE;
break;
}
@@ -6075,12 +6187,11 @@
TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type,
Kind.getRange().getBegin());
- CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(
- TSInfo->getType().getNonLValueExprType(S.Context),
- TSInfo,
- Kind.getRange().getEnd()));
+ CurInit = new (S.Context) CXXScalarValueInitExpr(
+ TSInfo->getType().getNonLValueExprType(S.Context), TSInfo,
+ Kind.getRange().getEnd());
} else {
- CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type));
+ CurInit = new (S.Context) ImplicitValueInitExpr(Step->Type);
}
break;
}
@@ -6127,7 +6238,7 @@
}
case SK_ObjCObjectConversion:
- CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+ CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
CK_ObjCObjectLValueCast,
CurInit.get()->getValueKind());
break;
@@ -6165,16 +6276,15 @@
case SK_PassByIndirectCopyRestore:
case SK_PassByIndirectRestore:
checkIndirectCopyRestoreSource(S, CurInit.get());
- CurInit = S.Owned(new (S.Context)
- ObjCIndirectCopyRestoreExpr(CurInit.take(), Step->Type,
- Step->Kind == SK_PassByIndirectCopyRestore));
+ CurInit = new (S.Context) ObjCIndirectCopyRestoreExpr(
+ CurInit.get(), Step->Type,
+ Step->Kind == SK_PassByIndirectCopyRestore);
break;
case SK_ProduceObjCObject:
- CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type,
- CK_ARCProduceObject,
- CurInit.take(), nullptr,
- VK_RValue));
+ CurInit =
+ ImplicitCastExpr::Create(S.Context, Step->Type, CK_ARCProduceObject,
+ CurInit.get(), nullptr, VK_RValue);
break;
case SK_StdInitializerList: {
@@ -6197,13 +6307,12 @@
ExtendingEntity->getDecl());
// Wrap it in a construction of a std::initializer_list<T>.
- CurInit = S.Owned(
- new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE));
+ CurInit = new (S.Context) CXXStdInitializerListExpr(Step->Type, MTE);
// Bind the result, in case the library has given initializer_list a
// non-trivial destructor.
if (shouldBindAsTemporary(Entity))
- CurInit = S.MaybeBindToTemporary(CurInit.take());
+ CurInit = S.MaybeBindToTemporary(CurInit.get());
break;
}
@@ -6227,7 +6336,7 @@
assert(Step->Type->isEventT() &&
"Event initialization on non-event type.");
- CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type,
+ CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
CK_ZeroToOCLEvent,
CurInit.get()->getValueKind());
break;
@@ -6543,7 +6652,8 @@
Args.back()->getLocEnd());
if (Failure == FK_ListConstructorOverloadFailed) {
- assert(Args.size() == 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 = MultiExprArg(InitList->getInits(), InitList->getNumInits());
}
@@ -6588,7 +6698,8 @@
<< S.Context.getTypeDeclType(Constructor->getParent())
<< /*member=*/1
<< Entity.getName();
- S.Diag(Entity.getDecl()->getLocation(), diag::note_field_decl);
+ S.Diag(Entity.getDecl()->getLocation(),
+ diag::note_member_declared_at);
if (const RecordType *Record
= Entity.getType()->getAs<RecordType>())
@@ -7101,7 +7212,7 @@
EqualLoc,
AllowExplicit);
InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
- Init.release();
+ Init.get();
ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index ef92e7c..0cf4ed7 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -782,7 +782,7 @@
if (Result.isInvalid())
return QualType();
- Init = Result.takeAs<Expr>();
+ Init = Result.getAs<Expr>();
// The init-capture initialization is a full-expression that must be
// processed as one before we enter the declcontext of the lambda's
@@ -793,7 +793,7 @@
if (Result.isInvalid())
return QualType();
- Init = Result.takeAs<Expr>();
+ Init = Result.getAs<Expr>();
return DeducedType;
}
@@ -1013,7 +1013,7 @@
if (C->InitCaptureType.get().isNull())
continue;
Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(),
- C->Id, C->Init.take());
+ C->Id, C->Init.get());
// C++1y [expr.prim.lambda]p11:
// An init-capture behaves as if it declares and explicitly
// captures a variable [...] whose declarative region is the
@@ -1572,7 +1572,7 @@
/*NRVO=*/false),
CurrentLocation, Src);
if (!Init.isInvalid())
- Init = ActOnFinishFullExpr(Init.take());
+ Init = ActOnFinishFullExpr(Init.get());
if (Init.isInvalid())
return ExprError();
@@ -1612,7 +1612,7 @@
Src->getType(), CapVarTSI,
SC_None);
BlockDecl::Capture Capture(/*Variable=*/CapVar, /*ByRef=*/false,
- /*Nested=*/false, /*Copy=*/Init.take());
+ /*Nested=*/false, /*Copy=*/Init.get());
Block->setCaptures(Context, &Capture, &Capture + 1,
/*CapturesCXXThis=*/false);
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index eb6366c..adb4cbf 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1723,7 +1723,7 @@
!= Context.getCanonicalType(PathElement.Base->getType())) {
// We found members of the given name in two subobjects of
// different types. If the declaration sets aren't the same, this
- // this lookup is ambiguous.
+ // lookup is ambiguous.
if (HasOnlyStaticMembers(Path->Decls.begin(), Path->Decls.end())) {
CXXBasePaths::paths_iterator FirstPath = Paths.begin();
DeclContext::lookup_iterator FirstD = FirstPath->Decls.begin();
@@ -3265,151 +3265,20 @@
// Typo correction
//===----------------------------------------------------------------------===//
-namespace {
-
-typedef SmallVector<TypoCorrection, 1> TypoResultList;
-typedef llvm::StringMap<TypoResultList, llvm::BumpPtrAllocator> TypoResultsMap;
-typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
-
-static const unsigned MaxTypoDistanceResultSets = 5;
-
-class TypoCorrectionConsumer : public VisibleDeclConsumer {
- /// \brief The name written that is a typo in the source.
- StringRef Typo;
-
- /// \brief The results found that have the smallest edit distance
- /// found (so far) with the typo name.
- ///
- /// The pointer value being set to the current DeclContext indicates
- /// whether there is a keyword with this name.
- TypoEditDistanceMap CorrectionResults;
-
- Sema &SemaRef;
-
-public:
- explicit TypoCorrectionConsumer(Sema &SemaRef, IdentifierInfo *Typo)
- : Typo(Typo->getName()),
- SemaRef(SemaRef) {}
-
- bool includeHiddenDecls() const override { return true; }
-
- void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
- bool InBaseClass) override;
- void FoundName(StringRef Name);
- void addKeywordResult(StringRef Keyword);
- void addName(StringRef Name, NamedDecl *ND,
- NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
- void addCorrection(TypoCorrection Correction);
-
- typedef TypoResultsMap::iterator result_iterator;
- typedef TypoEditDistanceMap::iterator distance_iterator;
- distance_iterator begin() { return CorrectionResults.begin(); }
- distance_iterator end() { return CorrectionResults.end(); }
- void erase(distance_iterator I) { CorrectionResults.erase(I); }
- unsigned size() const { return CorrectionResults.size(); }
- bool empty() const { return CorrectionResults.empty(); }
-
- TypoResultList &operator[](StringRef Name) {
- return CorrectionResults.begin()->second[Name];
- }
-
- unsigned getBestEditDistance(bool Normalized) {
- if (CorrectionResults.empty())
- return (std::numeric_limits<unsigned>::max)();
-
- unsigned BestED = CorrectionResults.begin()->first;
- return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
- }
-
- TypoResultsMap &getBestResults() {
- return CorrectionResults.begin()->second;
- }
-
-};
-
+static bool isCandidateViable(CorrectionCandidateCallback &CCC,
+ TypoCorrection &Candidate) {
+ Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
+ return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
}
-void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
- DeclContext *Ctx, bool InBaseClass) {
- // Don't consider hidden names for typo correction.
- if (Hiding)
- return;
-
- // Only consider entities with identifiers for names, ignoring
- // special names (constructors, overloaded operators, selectors,
- // etc.).
- IdentifierInfo *Name = ND->getIdentifier();
- if (!Name)
- return;
-
- // Only consider visible declarations and declarations from modules with
- // names that exactly match.
- if (!LookupResult::isVisible(SemaRef, ND) && Name->getName() != Typo &&
- !findAcceptableDecl(SemaRef, ND))
- return;
-
- FoundName(Name->getName());
-}
-
-void TypoCorrectionConsumer::FoundName(StringRef Name) {
- // Compute the edit distance between the typo and the name of this
- // entity, and add the identifier to the list of results.
- addName(Name, nullptr);
-}
-
-void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
- // Compute the edit distance between the typo and this keyword,
- // and add the keyword to the list of results.
- addName(Keyword, nullptr, nullptr, true);
-}
-
-void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
- NestedNameSpecifier *NNS, bool isKeyword) {
- // Use a simple length-based heuristic to determine the minimum possible
- // edit distance. If the minimum isn't good enough, bail out early.
- unsigned MinED = abs((int)Name.size() - (int)Typo.size());
- if (MinED && Typo.size() / MinED < 3)
- return;
-
- // Compute an upper bound on the allowable edit distance, so that the
- // edit-distance algorithm can short-circuit.
- unsigned UpperBound = (Typo.size() + 2) / 3 + 1;
- unsigned ED = Typo.edit_distance(Name, true, UpperBound);
- if (ED >= UpperBound) return;
-
- TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);
- if (isKeyword) TC.makeKeyword();
- addCorrection(TC);
-}
-
-void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
- StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
- TypoResultList &CList =
- CorrectionResults[Correction.getEditDistance(false)][Name];
-
- if (!CList.empty() && !CList.back().isResolved())
- CList.pop_back();
- if (NamedDecl *NewND = Correction.getCorrectionDecl()) {
- std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts());
- for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end();
- RI != RIEnd; ++RI) {
- // If the Correction refers to a decl already in the result list,
- // replace the existing result if the string representation of Correction
- // comes before the current result alphabetically, then stop as there is
- // nothing more to be done to add Correction to the candidate set.
- if (RI->getCorrectionDecl() == NewND) {
- if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts()))
- *RI = Correction;
- return;
- }
- }
- }
- if (CList.empty() || Correction.isResolved())
- CList.push_back(Correction);
-
- while (CorrectionResults.size() > MaxTypoDistanceResultSets)
- erase(std::prev(CorrectionResults.end()));
-}
+static void LookupPotentialTypoResult(Sema &SemaRef,
+ LookupResult &Res,
+ IdentifierInfo *Name,
+ Scope *S, CXXScopeSpec *SS,
+ DeclContext *MemberContext,
+ bool EnteringContext,
+ bool isObjCIvarLookup,
+ bool FindHidden);
// Fill the supplied vector with the IdentifierInfo pointers for each piece of
// the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",
@@ -3454,81 +3323,452 @@
namespace {
-class SpecifierInfo {
- public:
- DeclContext* DeclCtx;
- NestedNameSpecifier* NameSpecifier;
- unsigned EditDistance;
+static const unsigned MaxTypoDistanceResultSets = 5;
- SpecifierInfo(DeclContext *Ctx, NestedNameSpecifier *NNS, unsigned ED)
- : DeclCtx(Ctx), NameSpecifier(NNS), EditDistance(ED) {}
-};
+class TypoCorrectionConsumer : public VisibleDeclConsumer {
+ typedef SmallVector<TypoCorrection, 1> TypoResultList;
+ typedef llvm::StringMap<TypoResultList> TypoResultsMap;
+ typedef std::map<unsigned, TypoResultsMap> TypoEditDistanceMap;
-typedef SmallVector<DeclContext*, 4> DeclContextList;
-typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
-
-class NamespaceSpecifierSet {
- ASTContext &Context;
- DeclContextList CurContextChain;
- std::string CurNameSpecifier;
- SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
- SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
- bool isSorted;
-
- SpecifierInfoList Specifiers;
- llvm::SmallSetVector<unsigned, 4> Distances;
- llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
-
- /// \brief Helper for building the list of DeclContexts between the current
- /// context and the top of the translation unit
- static DeclContextList BuildContextChain(DeclContext *Start);
-
- void SortNamespaces();
-
- public:
- NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
- CXXScopeSpec *CurScopeSpec)
- : Context(Context), CurContextChain(BuildContextChain(CurContext)),
- isSorted(false) {
- if (NestedNameSpecifier *NNS =
- CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
- llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
- NNS->print(SpecifierOStream, Context.getPrintingPolicy());
-
- getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
- }
- // Build the list of identifiers that would be used for an absolute
- // (from the global context) NestedNameSpecifier referring to the current
- // context.
- for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
- CEnd = CurContextChain.rend();
- C != CEnd; ++C) {
- if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
- CurContextIdentifiers.push_back(ND->getIdentifier());
- }
-
- // Add the global context as a NestedNameSpecifier
- Distances.insert(1);
- DistanceMap[1].push_back(
- SpecifierInfo(cast<DeclContext>(Context.getTranslationUnitDecl()),
- NestedNameSpecifier::GlobalSpecifier(Context), 1));
+public:
+ explicit TypoCorrectionConsumer(Sema &SemaRef,
+ const DeclarationNameInfo &TypoName,
+ Sema::LookupNameKind LookupKind,
+ Scope *S, CXXScopeSpec *SS,
+ CorrectionCandidateCallback &CCC,
+ DeclContext *MemberContext,
+ bool EnteringContext)
+ : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S),
+ SS(SS), CorrectionValidator(CCC), MemberContext(MemberContext),
+ Result(SemaRef, TypoName, LookupKind),
+ Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
+ EnteringContext(EnteringContext), SearchNamespaces(false) {
+ Result.suppressDiagnostics();
}
- /// \brief Add the DeclContext (a namespace or record) to the set, computing
- /// the corresponding NestedNameSpecifier and its distance in the process.
- void AddNameSpecifier(DeclContext *Ctx);
+ bool includeHiddenDecls() const override { return true; }
- typedef SpecifierInfoList::iterator iterator;
- iterator begin() {
- if (!isSorted) SortNamespaces();
- return Specifiers.begin();
+ // Methods for adding potential corrections to the consumer.
+ void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
+ bool InBaseClass) override;
+ void FoundName(StringRef Name);
+ void addKeywordResult(StringRef Keyword);
+ void addCorrection(TypoCorrection Correction);
+
+ bool empty() const { return CorrectionResults.empty(); }
+
+ /// \brief Return the list of TypoCorrections for the given identifier from
+ /// the set of corrections that have the closest edit distance, if any.
+ TypoResultList &operator[](StringRef Name) {
+ return CorrectionResults.begin()->second[Name];
}
- iterator end() { return Specifiers.end(); }
+
+ /// \brief Return the edit distance of the corrections that have the
+ /// closest/best edit distance from the original typop.
+ unsigned getBestEditDistance(bool Normalized) {
+ if (CorrectionResults.empty())
+ return (std::numeric_limits<unsigned>::max)();
+
+ unsigned BestED = CorrectionResults.begin()->first;
+ return Normalized ? TypoCorrection::NormalizeEditDistance(BestED) : BestED;
+ }
+
+ /// \brief Set-up method to add to the consumer the set of namespaces to use
+ /// in performing corrections to nested name specifiers. This method also
+ /// implicitly adds all of the known classes in the current AST context to the
+ /// to the consumer for correcting nested name specifiers.
+ void
+ addNamespaces(const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces);
+
+ /// \brief Return the next typo correction that passes all internal filters
+ /// and is deemed valid by the consumer's CorrectionCandidateCallback,
+ /// starting with the corrections that have the closest edit distance. An
+ /// empty TypoCorrection is returned once no more viable corrections remain
+ /// in the consumer.
+ TypoCorrection getNextCorrection();
+
+private:
+ class NamespaceSpecifierSet {
+ struct SpecifierInfo {
+ DeclContext* DeclCtx;
+ NestedNameSpecifier* NameSpecifier;
+ unsigned EditDistance;
+ };
+
+ typedef SmallVector<DeclContext*, 4> DeclContextList;
+ typedef SmallVector<SpecifierInfo, 16> SpecifierInfoList;
+
+ ASTContext &Context;
+ DeclContextList CurContextChain;
+ std::string CurNameSpecifier;
+ SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
+ SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
+ bool isSorted;
+
+ SpecifierInfoList Specifiers;
+ llvm::SmallSetVector<unsigned, 4> Distances;
+ llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap;
+
+ /// \brief Helper for building the list of DeclContexts between the current
+ /// context and the top of the translation unit
+ static DeclContextList buildContextChain(DeclContext *Start);
+
+ void sortNamespaces();
+
+ unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
+ NestedNameSpecifier *&NNS);
+
+ public:
+ NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
+ CXXScopeSpec *CurScopeSpec);
+
+ /// \brief Add the DeclContext (a namespace or record) to the set, computing
+ /// the corresponding NestedNameSpecifier and its distance in the process.
+ void addNameSpecifier(DeclContext *Ctx);
+
+ typedef SpecifierInfoList::iterator iterator;
+ iterator begin() {
+ if (!isSorted) sortNamespaces();
+ return Specifiers.begin();
+ }
+ iterator end() { return Specifiers.end(); }
+ };
+
+ void addName(StringRef Name, NamedDecl *ND,
+ NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
+
+ /// \brief Find any visible decls for the given typo correction candidate.
+ /// If none are found, it to the set of candidates for which qualified lookups
+ /// will be performed to find possible nested name specifier changes.
+ bool resolveCorrection(TypoCorrection &Candidate);
+
+ /// \brief Perform qualified lookups on the queued set of typo correction
+ /// candidates and add the nested name specifier changes to each candidate if
+ /// a lookup succeeds (at which point the candidate will be returned to the
+ /// main pool of potential corrections).
+ void performQualifiedLookups();
+
+ /// \brief The name written that is a typo in the source.
+ IdentifierInfo *Typo;
+
+ /// \brief The results found that have the smallest edit distance
+ /// found (so far) with the typo name.
+ ///
+ /// The pointer value being set to the current DeclContext indicates
+ /// whether there is a keyword with this name.
+ TypoEditDistanceMap CorrectionResults;
+
+ Sema &SemaRef;
+ Scope *S;
+ CXXScopeSpec *SS;
+ CorrectionCandidateCallback &CorrectionValidator;
+ DeclContext *MemberContext;
+ LookupResult Result;
+ NamespaceSpecifierSet Namespaces;
+ SmallVector<TypoCorrection, 2> QualifiedResults;
+ bool EnteringContext;
+ bool SearchNamespaces;
};
}
-DeclContextList NamespaceSpecifierSet::BuildContextChain(DeclContext *Start) {
+void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
+ DeclContext *Ctx, bool InBaseClass) {
+ // Don't consider hidden names for typo correction.
+ if (Hiding)
+ return;
+
+ // Only consider entities with identifiers for names, ignoring
+ // special names (constructors, overloaded operators, selectors,
+ // etc.).
+ IdentifierInfo *Name = ND->getIdentifier();
+ if (!Name)
+ return;
+
+ // Only consider visible declarations and declarations from modules with
+ // names that exactly match.
+ if (!LookupResult::isVisible(SemaRef, ND) && Name != Typo &&
+ !findAcceptableDecl(SemaRef, ND))
+ return;
+
+ FoundName(Name->getName());
+}
+
+void TypoCorrectionConsumer::FoundName(StringRef Name) {
+ // Compute the edit distance between the typo and the name of this
+ // entity, and add the identifier to the list of results.
+ addName(Name, nullptr);
+}
+
+void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
+ // Compute the edit distance between the typo and this keyword,
+ // and add the keyword to the list of results.
+ addName(Keyword, nullptr, nullptr, true);
+}
+
+void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
+ NestedNameSpecifier *NNS, bool isKeyword) {
+ // Use a simple length-based heuristic to determine the minimum possible
+ // edit distance. If the minimum isn't good enough, bail out early.
+ StringRef TypoStr = Typo->getName();
+ unsigned MinED = abs((int)Name.size() - (int)TypoStr.size());
+ if (MinED && TypoStr.size() / MinED < 3)
+ return;
+
+ // Compute an upper bound on the allowable edit distance, so that the
+ // edit-distance algorithm can short-circuit.
+ unsigned UpperBound = (TypoStr.size() + 2) / 3 + 1;
+ unsigned ED = TypoStr.edit_distance(Name, true, UpperBound);
+ if (ED >= UpperBound) return;
+
+ TypoCorrection TC(&SemaRef.Context.Idents.get(Name), ND, NNS, ED);
+ if (isKeyword) TC.makeKeyword();
+ addCorrection(TC);
+}
+
+void TypoCorrectionConsumer::addCorrection(TypoCorrection Correction) {
+ StringRef TypoStr = Typo->getName();
+ StringRef Name = Correction.getCorrectionAsIdentifierInfo()->getName();
+
+ // For very short typos, ignore potential corrections that have a different
+ // base identifier from the typo or which have a normalized edit distance
+ // longer than the typo itself.
+ if (TypoStr.size() < 3 &&
+ (Name != TypoStr || Correction.getEditDistance(true) > TypoStr.size()))
+ return;
+
+ // If the correction is resolved but is not viable, ignore it.
+ if (Correction.isResolved() &&
+ !isCandidateViable(CorrectionValidator, Correction))
+ return;
+
+ TypoResultList &CList =
+ CorrectionResults[Correction.getEditDistance(false)][Name];
+
+ if (!CList.empty() && !CList.back().isResolved())
+ CList.pop_back();
+ if (NamedDecl *NewND = Correction.getCorrectionDecl()) {
+ std::string CorrectionStr = Correction.getAsString(SemaRef.getLangOpts());
+ for (TypoResultList::iterator RI = CList.begin(), RIEnd = CList.end();
+ RI != RIEnd; ++RI) {
+ // If the Correction refers to a decl already in the result list,
+ // replace the existing result if the string representation of Correction
+ // comes before the current result alphabetically, then stop as there is
+ // nothing more to be done to add Correction to the candidate set.
+ if (RI->getCorrectionDecl() == NewND) {
+ if (CorrectionStr < RI->getAsString(SemaRef.getLangOpts()))
+ *RI = Correction;
+ return;
+ }
+ }
+ }
+ if (CList.empty() || Correction.isResolved())
+ CList.push_back(Correction);
+
+ while (CorrectionResults.size() > MaxTypoDistanceResultSets)
+ CorrectionResults.erase(std::prev(CorrectionResults.end()));
+}
+
+void TypoCorrectionConsumer::addNamespaces(
+ const llvm::MapVector<NamespaceDecl *, bool> &KnownNamespaces) {
+ SearchNamespaces = true;
+
+ for (auto KNPair : KnownNamespaces)
+ Namespaces.addNameSpecifier(KNPair.first);
+
+ bool SSIsTemplate = false;
+ if (NestedNameSpecifier *NNS =
+ (SS && SS->isValid()) ? SS->getScopeRep() : nullptr) {
+ if (const Type *T = NNS->getAsType())
+ SSIsTemplate = T->getTypeClass() == Type::TemplateSpecialization;
+ }
+ for (const auto *TI : SemaRef.getASTContext().types()) {
+ if (CXXRecordDecl *CD = TI->getAsCXXRecordDecl()) {
+ CD = CD->getCanonicalDecl();
+ if (!CD->isDependentType() && !CD->isAnonymousStructOrUnion() &&
+ !CD->isUnion() && CD->getIdentifier() &&
+ (SSIsTemplate || !isa<ClassTemplateSpecializationDecl>(CD)) &&
+ (CD->isBeingDefined() || CD->isCompleteDefinition()))
+ Namespaces.addNameSpecifier(CD);
+ }
+ }
+}
+
+TypoCorrection TypoCorrectionConsumer::getNextCorrection() {
+ while (!CorrectionResults.empty()) {
+ auto DI = CorrectionResults.begin();
+ if (DI->second.empty()) {
+ CorrectionResults.erase(DI);
+ continue;
+ }
+
+ auto RI = DI->second.begin();
+ if (RI->second.empty()) {
+ DI->second.erase(RI);
+ performQualifiedLookups();
+ continue;
+ }
+
+ TypoCorrection TC = RI->second.pop_back_val();
+ if (TC.isResolved() || resolveCorrection(TC))
+ return TC;
+ }
+ return TypoCorrection();
+}
+
+bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
+ IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
+ DeclContext *TempMemberContext = MemberContext;
+ CXXScopeSpec *TempSS = SS;
+retry_lookup:
+ LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext,
+ EnteringContext,
+ CorrectionValidator.IsObjCIvarLookup,
+ Name == Typo && !Candidate.WillReplaceSpecifier());
+ switch (Result.getResultKind()) {
+ case LookupResult::NotFound:
+ case LookupResult::NotFoundInCurrentInstantiation:
+ case LookupResult::FoundUnresolvedValue:
+ if (TempSS) {
+ // Immediately retry the lookup without the given CXXScopeSpec
+ TempSS = nullptr;
+ Candidate.WillReplaceSpecifier(true);
+ goto retry_lookup;
+ }
+ if (TempMemberContext) {
+ if (SS && !TempSS)
+ TempSS = SS;
+ TempMemberContext = nullptr;
+ goto retry_lookup;
+ }
+ if (SearchNamespaces)
+ QualifiedResults.push_back(Candidate);
+ break;
+
+ case LookupResult::Ambiguous:
+ // We don't deal with ambiguities.
+ break;
+
+ case LookupResult::Found:
+ case LookupResult::FoundOverloaded:
+ // Store all of the Decls for overloaded symbols
+ for (auto *TRD : Result)
+ Candidate.addCorrectionDecl(TRD);
+ if (!isCandidateViable(CorrectionValidator, Candidate)) {
+ if (SearchNamespaces)
+ QualifiedResults.push_back(Candidate);
+ break;
+ }
+ return true;
+ }
+ return false;
+}
+
+void TypoCorrectionConsumer::performQualifiedLookups() {
+ unsigned TypoLen = Typo->getName().size();
+ for (auto QR : QualifiedResults) {
+ for (auto NSI : Namespaces) {
+ DeclContext *Ctx = NSI.DeclCtx;
+ const Type *NSType = NSI.NameSpecifier->getAsType();
+
+ // If the current NestedNameSpecifier refers to a class and the
+ // current correction candidate is the name of that class, then skip
+ // it as it is unlikely a qualified version of the class' constructor
+ // is an appropriate correction.
+ if (CXXRecordDecl *NSDecl = NSType ? NSType->getAsCXXRecordDecl() : 0) {
+ if (NSDecl->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
+ continue;
+ }
+
+ TypoCorrection TC(QR);
+ TC.ClearCorrectionDecls();
+ TC.setCorrectionSpecifier(NSI.NameSpecifier);
+ TC.setQualifierDistance(NSI.EditDistance);
+ TC.setCallbackDistance(0); // Reset the callback distance
+
+ // If the current correction candidate and namespace combination are
+ // too far away from the original typo based on the normalized edit
+ // distance, then skip performing a qualified name lookup.
+ unsigned TmpED = TC.getEditDistance(true);
+ if (QR.getCorrectionAsIdentifierInfo() != Typo && TmpED &&
+ TypoLen / TmpED < 3)
+ continue;
+
+ Result.clear();
+ Result.setLookupName(QR.getCorrectionAsIdentifierInfo());
+ if (!SemaRef.LookupQualifiedName(Result, Ctx))
+ continue;
+
+ // Any corrections added below will be validated in subsequent
+ // iterations of the main while() loop over the Consumer's contents.
+ switch (Result.getResultKind()) {
+ case LookupResult::Found:
+ case LookupResult::FoundOverloaded: {
+ if (SS && SS->isValid()) {
+ std::string NewQualified = TC.getAsString(SemaRef.getLangOpts());
+ std::string OldQualified;
+ llvm::raw_string_ostream OldOStream(OldQualified);
+ SS->getScopeRep()->print(OldOStream, SemaRef.getPrintingPolicy());
+ OldOStream << Typo->getName();
+ // If correction candidate would be an identical written qualified
+ // identifer, then the existing CXXScopeSpec probably included a
+ // typedef that didn't get accounted for properly.
+ if (OldOStream.str() == NewQualified)
+ break;
+ }
+ for (LookupResult::iterator TRD = Result.begin(), TRDEnd = Result.end();
+ TRD != TRDEnd; ++TRD) {
+ if (SemaRef.CheckMemberAccess(TC.getCorrectionRange().getBegin(),
+ NSType ? NSType->getAsCXXRecordDecl()
+ : nullptr,
+ TRD.getPair()) == Sema::AR_accessible)
+ TC.addCorrectionDecl(*TRD);
+ }
+ if (TC.isResolved())
+ addCorrection(TC);
+ break;
+ }
+ case LookupResult::NotFound:
+ case LookupResult::NotFoundInCurrentInstantiation:
+ case LookupResult::Ambiguous:
+ case LookupResult::FoundUnresolvedValue:
+ break;
+ }
+ }
+ }
+ QualifiedResults.clear();
+}
+
+TypoCorrectionConsumer::NamespaceSpecifierSet::NamespaceSpecifierSet(
+ ASTContext &Context, DeclContext *CurContext, CXXScopeSpec *CurScopeSpec)
+ : Context(Context), CurContextChain(buildContextChain(CurContext)),
+ isSorted(false) {
+ if (NestedNameSpecifier *NNS =
+ CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
+ llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
+ NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+
+ getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
+ }
+ // Build the list of identifiers that would be used for an absolute
+ // (from the global context) NestedNameSpecifier referring to the current
+ // context.
+ for (DeclContextList::reverse_iterator C = CurContextChain.rbegin(),
+ CEnd = CurContextChain.rend();
+ C != CEnd; ++C) {
+ if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C))
+ CurContextIdentifiers.push_back(ND->getIdentifier());
+ }
+
+ // Add the global context as a NestedNameSpecifier
+ Distances.insert(1);
+ SpecifierInfo SI = {cast<DeclContext>(Context.getTranslationUnitDecl()),
+ NestedNameSpecifier::GlobalSpecifier(Context), 1};
+ DistanceMap[1].push_back(SI);
+}
+
+auto TypoCorrectionConsumer::NamespaceSpecifierSet::buildContextChain(
+ DeclContext *Start) -> DeclContextList {
assert(Start && "Building a context chain from a null context");
DeclContextList Chain;
for (DeclContext *DC = Start->getPrimaryContext(); DC != nullptr;
@@ -3541,7 +3781,7 @@
return Chain;
}
-void NamespaceSpecifierSet::SortNamespaces() {
+void TypoCorrectionConsumer::NamespaceSpecifierSet::sortNamespaces() {
SmallVector<unsigned, 4> sortedDistances;
sortedDistances.append(Distances.begin(), Distances.end());
@@ -3559,9 +3799,9 @@
isSorted = true;
}
-static unsigned BuildNestedNameSpecifier(ASTContext &Context,
- DeclContextList &DeclChain,
- NestedNameSpecifier *&NNS) {
+unsigned
+TypoCorrectionConsumer::NamespaceSpecifierSet::buildNestedNameSpecifier(
+ DeclContextList &DeclChain, NestedNameSpecifier *&NNS) {
unsigned NumSpecifiers = 0;
for (DeclContextList::reverse_iterator C = DeclChain.rbegin(),
CEnd = DeclChain.rend();
@@ -3578,10 +3818,11 @@
return NumSpecifiers;
}
-void NamespaceSpecifierSet::AddNameSpecifier(DeclContext *Ctx) {
+void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
+ DeclContext *Ctx) {
NestedNameSpecifier *NNS = nullptr;
unsigned NumSpecifiers = 0;
- DeclContextList NamespaceDeclChain(BuildContextChain(Ctx));
+ DeclContextList NamespaceDeclChain(buildContextChain(Ctx));
DeclContextList FullNamespaceDeclChain(NamespaceDeclChain);
// Eliminate common elements from the two DeclContext chains.
@@ -3593,14 +3834,14 @@
}
// Build the NestedNameSpecifier from what is left of the NamespaceDeclChain
- NumSpecifiers = BuildNestedNameSpecifier(Context, NamespaceDeclChain, NNS);
+ NumSpecifiers = buildNestedNameSpecifier(NamespaceDeclChain, NNS);
// Add an explicit leading '::' specifier if needed.
if (NamespaceDeclChain.empty()) {
// Rebuild the NestedNameSpecifier as a globally-qualified specifier.
NNS = NestedNameSpecifier::GlobalSpecifier(Context);
NumSpecifiers =
- BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
+ buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
} else if (NamedDecl *ND =
dyn_cast_or_null<NamedDecl>(NamespaceDeclChain.back())) {
IdentifierInfo *Name = ND->getIdentifier();
@@ -3622,7 +3863,7 @@
// Rebuild the NestedNameSpecifier as a globally-qualified specifier.
NNS = NestedNameSpecifier::GlobalSpecifier(Context);
NumSpecifiers =
- BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
+ buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
}
}
@@ -3640,7 +3881,8 @@
isSorted = false;
Distances.insert(NumSpecifiers);
- DistanceMap[NumSpecifiers].push_back(SpecifierInfo(Ctx, NNS, NumSpecifiers));
+ SpecifierInfo SI = {Ctx, NNS, NumSpecifiers};
+ DistanceMap[NumSpecifiers].push_back(SI);
}
/// \brief Perform name lookup for a possible result for typo correction.
@@ -3840,17 +4082,10 @@
}
}
-static bool isCandidateViable(CorrectionCandidateCallback &CCC,
- TypoCorrection &Candidate) {
- Candidate.setCallbackDistance(CCC.RankCandidate(Candidate));
- return Candidate.getEditDistance(false) != TypoCorrection::InvalidDistance;
-}
-
/// \brief Check whether the declarations found for a typo correction are
/// visible, and if none of them are, convert the correction to an 'import
/// a module' correction.
-static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC,
- DeclarationName TypoName) {
+static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) {
if (TC.begin() == TC.end())
return;
@@ -3980,8 +4215,6 @@
if (getLangOpts().AltiVec && Typo->isStr("vector"))
return TypoCorrection();
- TypoCorrectionConsumer Consumer(*this, Typo);
-
// If we're handling a missing symbol error, using modules, and the
// special search all modules option is used, look for a missing import.
if ((Mode == CTK_ErrorRecovery) && getLangOpts().Modules &&
@@ -3991,7 +4224,8 @@
TypoName.getLocStart());
}
- NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
+ TypoCorrectionConsumer Consumer(*this, TypoName, LookupKind, S, SS, CCC,
+ MemberContext, EnteringContext);
// If a callback object considers an empty typo correction candidate to be
// viable, assume it does not do any actual validation of the candidates.
@@ -4116,236 +4350,15 @@
KnownNamespaces[ExternalKnownNamespaces[I]] = true;
}
- for (auto KNPair : KnownNamespaces)
- Namespaces.AddNameSpecifier(KNPair.first);
-
- bool SSIsTemplate = false;
- if (NestedNameSpecifier *NNS =
- (SS && SS->isValid()) ? SS->getScopeRep() : nullptr) {
- if (const Type *T = NNS->getAsType())
- SSIsTemplate = T->getTypeClass() == Type::TemplateSpecialization;
- }
- for (const auto *TI : Context.types()) {
- if (CXXRecordDecl *CD = TI->getAsCXXRecordDecl()) {
- CD = CD->getCanonicalDecl();
- if (!CD->isDependentType() && !CD->isAnonymousStructOrUnion() &&
- !CD->isUnion() && CD->getIdentifier() &&
- (SSIsTemplate || !isa<ClassTemplateSpecializationDecl>(CD)) &&
- (CD->isBeingDefined() || CD->isCompleteDefinition()))
- Namespaces.AddNameSpecifier(CD);
- }
- }
+ Consumer.addNamespaces(KnownNamespaces);
}
- // Weed out any names that could not be found by name lookup or, if a
- // CorrectionCandidateCallback object was provided, failed validation.
- SmallVector<TypoCorrection, 16> QualifiedResults;
- LookupResult TmpRes(*this, TypoName, LookupKind);
- TmpRes.suppressDiagnostics();
- while (!Consumer.empty()) {
- TypoCorrectionConsumer::distance_iterator DI = Consumer.begin();
- for (TypoCorrectionConsumer::result_iterator I = DI->second.begin(),
- IEnd = DI->second.end();
- I != IEnd; /* Increment in loop. */) {
- // If we only want nested name specifier corrections, ignore potential
- // corrections that have a different base identifier from the typo or
- // which have a normalized edit distance longer than the typo itself.
- if (AllowOnlyNNSChanges) {
- TypoCorrection &TC = I->second.front();
- if (TC.getCorrectionAsIdentifierInfo() != Typo ||
- TC.getEditDistance(true) > TypoLen) {
- TypoCorrectionConsumer::result_iterator Prev = I;
- ++I;
- DI->second.erase(Prev);
- continue;
- }
- }
-
- // If the item already has been looked up or is a keyword, keep it.
- // If a validator callback object was given, drop the correction
- // unless it passes validation.
- bool Viable = false;
- for (TypoResultList::iterator RI = I->second.begin();
- RI != I->second.end(); /* Increment in loop. */) {
- TypoResultList::iterator Prev = RI;
- ++RI;
- if (Prev->isResolved()) {
- if (!isCandidateViable(CCC, *Prev))
- RI = I->second.erase(Prev);
- else
- Viable = true;
- }
- }
- if (Viable || I->second.empty()) {
- TypoCorrectionConsumer::result_iterator Prev = I;
- ++I;
- if (!Viable)
- DI->second.erase(Prev);
- continue;
- }
- assert(I->second.size() == 1 && "Expected a single unresolved candidate");
-
- // Perform name lookup on this name.
- TypoCorrection &Candidate = I->second.front();
- IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
- DeclContext *TempMemberContext = MemberContext;
- CXXScopeSpec *TempSS = SS;
-retry_lookup:
- LookupPotentialTypoResult(*this, TmpRes, Name, S, TempSS,
- TempMemberContext, EnteringContext,
- CCC.IsObjCIvarLookup,
- Name == TypoName.getName() &&
- !Candidate.WillReplaceSpecifier());
-
- switch (TmpRes.getResultKind()) {
- case LookupResult::NotFound:
- case LookupResult::NotFoundInCurrentInstantiation:
- case LookupResult::FoundUnresolvedValue:
- if (TempSS) {
- // Immediately retry the lookup without the given CXXScopeSpec
- TempSS = nullptr;
- Candidate.WillReplaceSpecifier(true);
- goto retry_lookup;
- }
- if (TempMemberContext) {
- if (SS && !TempSS)
- TempSS = SS;
- TempMemberContext = nullptr;
- goto retry_lookup;
- }
- QualifiedResults.push_back(Candidate);
- // We didn't find this name in our scope, or didn't like what we found;
- // ignore it.
- {
- TypoCorrectionConsumer::result_iterator Next = I;
- ++Next;
- DI->second.erase(I);
- I = Next;
- }
- break;
-
- case LookupResult::Ambiguous:
- // We don't deal with ambiguities.
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
-
- case LookupResult::FoundOverloaded: {
- TypoCorrectionConsumer::result_iterator Prev = I;
- // Store all of the Decls for overloaded symbols
- for (auto *TRD : TmpRes)
- Candidate.addCorrectionDecl(TRD);
- ++I;
- if (!isCandidateViable(CCC, Candidate)) {
- QualifiedResults.push_back(Candidate);
- DI->second.erase(Prev);
- }
- break;
- }
-
- case LookupResult::Found: {
- TypoCorrectionConsumer::result_iterator Prev = I;
- Candidate.setCorrectionDecl(TmpRes.getAsSingle<NamedDecl>());
- ++I;
- if (!isCandidateViable(CCC, Candidate)) {
- QualifiedResults.push_back(Candidate);
- DI->second.erase(Prev);
- }
- break;
- }
-
- }
- }
-
- if (DI->second.empty())
- Consumer.erase(DI);
- else if (!getLangOpts().CPlusPlus || QualifiedResults.empty() || !DI->first)
- // If there are results in the closest possible bucket, stop
- break;
-
- // Only perform the qualified lookups for C++
- if (SearchNamespaces) {
- TmpRes.suppressDiagnostics();
- for (auto QR : QualifiedResults) {
- for (auto NSI : Namespaces) {
- DeclContext *Ctx = NSI.DeclCtx;
- const Type *NSType = NSI.NameSpecifier->getAsType();
-
- // If the current NestedNameSpecifier refers to a class and the
- // current correction candidate is the name of that class, then skip
- // it as it is unlikely a qualified version of the class' constructor
- // is an appropriate correction.
- if (CXXRecordDecl *NSDecl =
- NSType ? NSType->getAsCXXRecordDecl() : nullptr) {
- if (NSDecl->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
- continue;
- }
-
- TypoCorrection TC(QR);
- TC.ClearCorrectionDecls();
- TC.setCorrectionSpecifier(NSI.NameSpecifier);
- TC.setQualifierDistance(NSI.EditDistance);
- TC.setCallbackDistance(0); // Reset the callback distance
-
- // If the current correction candidate and namespace combination are
- // too far away from the original typo based on the normalized edit
- // distance, then skip performing a qualified name lookup.
- unsigned TmpED = TC.getEditDistance(true);
- if (QR.getCorrectionAsIdentifierInfo() != Typo &&
- TmpED && TypoLen / TmpED < 3)
- continue;
-
- TmpRes.clear();
- TmpRes.setLookupName(QR.getCorrectionAsIdentifierInfo());
- if (!LookupQualifiedName(TmpRes, Ctx)) continue;
-
- // Any corrections added below will be validated in subsequent
- // iterations of the main while() loop over the Consumer's contents.
- switch (TmpRes.getResultKind()) {
- case LookupResult::Found:
- case LookupResult::FoundOverloaded: {
- if (SS && SS->isValid()) {
- std::string NewQualified = TC.getAsString(getLangOpts());
- std::string OldQualified;
- llvm::raw_string_ostream OldOStream(OldQualified);
- SS->getScopeRep()->print(OldOStream, getPrintingPolicy());
- OldOStream << TypoName;
- // If correction candidate would be an identical written qualified
- // identifer, then the existing CXXScopeSpec probably included a
- // typedef that didn't get accounted for properly.
- if (OldOStream.str() == NewQualified)
- break;
- }
- for (LookupResult::iterator TRD = TmpRes.begin(),
- TRDEnd = TmpRes.end();
- TRD != TRDEnd; ++TRD) {
- if (CheckMemberAccess(TC.getCorrectionRange().getBegin(),
- NSType ? NSType->getAsCXXRecordDecl()
- : nullptr,
- TRD.getPair()) == AR_accessible)
- TC.addCorrectionDecl(*TRD);
- }
- if (TC.isResolved())
- Consumer.addCorrection(TC);
- break;
- }
- case LookupResult::NotFound:
- case LookupResult::NotFoundInCurrentInstantiation:
- case LookupResult::Ambiguous:
- case LookupResult::FoundUnresolvedValue:
- break;
- }
- }
- }
- }
-
- QualifiedResults.clear();
- }
-
- // No corrections remain...
- if (Consumer.empty())
+ TypoCorrection BestTC = Consumer.getNextCorrection();
+ TypoCorrection SecondBestTC = Consumer.getNextCorrection();
+ if (!BestTC)
return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
- TypoResultsMap &BestResults = Consumer.getBestResults();
- ED = Consumer.getBestEditDistance(true);
+ ED = BestTC.getEditDistance();
if (!AllowOnlyNNSChanges && ED > 0 && TypoLen / ED < 3) {
// If this was an unqualified lookup and we believe the callback
@@ -4356,11 +4369,9 @@
}
// If only a single name remains, return that result.
- if (BestResults.size() == 1) {
- const TypoResultList &CorrectionList = BestResults.begin()->second;
- const TypoCorrection &Result = CorrectionList.front();
- if (CorrectionList.size() != 1)
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
+ if (!SecondBestTC ||
+ SecondBestTC.getEditDistance(false) > BestTC.getEditDistance(false)) {
+ const TypoCorrection &Result = BestTC;
// Don't correct to a keyword that's the same as the typo; the keyword
// wasn't actually in scope.
@@ -4373,39 +4384,42 @@
TypoCorrection TC = Result;
TC.setCorrectionRange(SS, TypoName);
- checkCorrectionVisibility(*this, TC, TypoName.getName());
+ checkCorrectionVisibility(*this, TC);
return TC;
}
- else if (BestResults.size() > 1
- // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver;
- // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
- // some instances of CTC_Unknown, while WantRemainingKeywords is true
- // for CTC_Unknown but not for CTC_ObjCMessageReceiver.
- && CCC.WantObjCSuper && !CCC.WantRemainingKeywords
- && BestResults["super"].front().isKeyword()) {
+ // Ugly hack equivalent to CTC == CTC_ObjCMessageReceiver;
+ // WantObjCSuper is only true for CTC_ObjCMessageReceiver and for
+ // some instances of CTC_Unknown, while WantRemainingKeywords is true
+ // for CTC_Unknown but not for CTC_ObjCMessageReceiver.
+ else if (SecondBestTC && CCC.WantObjCSuper && !CCC.WantRemainingKeywords) {
// Prefer 'super' when we're completing in a message-receiver
// context.
+ if (BestTC.getCorrection().getAsString() != "super") {
+ if (SecondBestTC.getCorrection().getAsString() == "super")
+ BestTC = SecondBestTC;
+ else if (Consumer["super"].front().isKeyword())
+ BestTC = Consumer["super"].front();
+ }
// Don't correct to a keyword that's the same as the typo; the keyword
// wasn't actually in scope.
- if (ED == 0)
+ if (BestTC.getEditDistance() == 0 ||
+ BestTC.getCorrection().getAsString() != "super")
return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
// Record the correction for unqualified lookup.
if (IsUnqualifiedLookup)
- UnqualifiedTyposCorrected[Typo] = BestResults["super"].front();
+ UnqualifiedTyposCorrected[Typo] = BestTC;
- TypoCorrection TC = BestResults["super"].front();
- TC.setCorrectionRange(SS, TypoName);
- return TC;
+ BestTC.setCorrectionRange(SS, TypoName);
+ return BestTC;
}
- // If this was an unqualified lookup and we believe the callback object did
- // not filter out possible corrections, note that no correction was found.
- if (IsUnqualifiedLookup && !ValidatingCallback)
- (void)UnqualifiedTyposCorrected[Typo];
-
- return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure);
+ // Record the failure's location if needed and return an empty correction. If
+ // this was an unqualified lookup and we believe the callback object did not
+ // filter out possible corrections, also cache the failure for the typo.
+ return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure,
+ IsUnqualifiedLookup && !ValidatingCallback);
}
void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
@@ -4440,14 +4454,27 @@
return WantTypeSpecifiers || WantExpressionKeywords || WantCXXNamedCasts ||
WantRemainingKeywords || WantObjCSuper;
- for (TypoCorrection::const_decl_iterator CDecl = candidate.begin(),
- CDeclEnd = candidate.end();
- CDecl != CDeclEnd; ++CDecl) {
- if (!isa<TypeDecl>(*CDecl))
- return true;
+ bool HasNonType = false;
+ bool HasStaticMethod = false;
+ bool HasNonStaticMethod = false;
+ for (Decl *D : candidate) {
+ if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+ D = FTD->getTemplatedDecl();
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
+ if (Method->isStatic())
+ HasStaticMethod = true;
+ else
+ HasNonStaticMethod = true;
+ }
+ if (!isa<TypeDecl>(D))
+ HasNonType = true;
}
- return WantTypeSpecifiers;
+ if (IsAddressOfOperand && HasNonStaticMethod && !HasStaticMethod &&
+ !candidate.getCorrectionSpecifier())
+ return false;
+
+ return WantTypeSpecifiers || HasNonType;
}
FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index bc98299..8eb806b 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -1156,9 +1156,9 @@
InitializedEntity::InitializeResult(PropertyDiagLoc,
getterMethod->getReturnType(),
/*NRVO=*/false),
- PropertyDiagLoc, Owned(IvarRefExpr));
+ PropertyDiagLoc, IvarRefExpr);
if (!Res.isInvalid()) {
- Expr *ResExpr = Res.takeAs<Expr>();
+ Expr *ResExpr = Res.getAs<Expr>();
if (ResExpr)
ResExpr = MaybeCreateExprWithCleanups(ResExpr);
PIDecl->setGetterCXXConstructor(ResExpr);
@@ -1212,7 +1212,7 @@
BO_Assign, lhs, rhs);
if (property->getPropertyAttributes() &
ObjCPropertyDecl::OBJC_PR_atomic) {
- Expr *callExpr = Res.takeAs<Expr>();
+ Expr *callExpr = Res.getAs<Expr>();
if (const CXXOperatorCallExpr *CXXCE =
dyn_cast_or_null<CXXOperatorCallExpr>(callExpr))
if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
@@ -1225,7 +1225,7 @@
diag::note_callee_decl) << FuncDecl;
}
}
- PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
+ PIDecl->setSetterCXXAssignment(Res.getAs<Expr>());
}
}
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 603dd56..a7ad809 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -40,6 +40,26 @@
DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'.
};
+template <class T> struct MatchesAny {
+ explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {}
+ bool operator()(T Kind) {
+ for (auto KindEl : Arr)
+ if (KindEl == Kind)
+ return true;
+ return false;
+ }
+
+private:
+ ArrayRef<T> Arr;
+};
+struct MatchesAlways {
+ MatchesAlways() {}
+ template <class T> bool operator()(T) { return true; }
+};
+
+typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause;
+typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective;
+
/// \brief Stack for tracking declarations used in OpenMP directives and
/// clauses and their data-sharing attributes.
class DSAStackTy {
@@ -48,7 +68,10 @@
OpenMPDirectiveKind DKind;
OpenMPClauseKind CKind;
DeclRefExpr *RefExpr;
- DSAVarData() : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr) {}
+ SourceLocation ImplicitDSALoc;
+ DSAVarData()
+ : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr),
+ ImplicitDSALoc() {}
};
private:
@@ -57,27 +80,33 @@
DeclRefExpr *RefExpr;
};
typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
+ typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
struct SharingMapTy {
DeclSAMapTy SharingMap;
+ AlignedMapTy AlignedMap;
DefaultDataSharingAttributes DefaultAttr;
+ SourceLocation DefaultAttrLoc;
OpenMPDirectiveKind Directive;
DeclarationNameInfo DirectiveName;
Scope *CurScope;
+ SourceLocation ConstructLoc;
SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
- Scope *CurScope)
- : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
- DirectiveName(std::move(Name)), CurScope(CurScope) {}
+ Scope *CurScope, SourceLocation Loc)
+ : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+ Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope),
+ ConstructLoc(Loc) {}
SharingMapTy()
- : SharingMap(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown),
- DirectiveName(), CurScope(nullptr) {}
+ : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+ Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr),
+ ConstructLoc() {}
};
typedef SmallVector<SharingMapTy, 64> StackTy;
/// \brief Stack of used declaration and their data-sharing attributes.
StackTy Stack;
- Sema &Actions;
+ Sema &SemaRef;
typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
@@ -87,11 +116,12 @@
bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
public:
- explicit DSAStackTy(Sema &S) : Stack(1), Actions(S) {}
+ explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {}
void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
- Scope *CurScope) {
- Stack.push_back(SharingMapTy(DKind, DirName, CurScope));
+ Scope *CurScope, SourceLocation Loc) {
+ Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc));
+ Stack.back().DefaultAttrLoc = Loc;
}
void pop() {
@@ -99,6 +129,11 @@
Stack.pop_back();
}
+ /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
+ /// add it and return NULL; otherwise return previous occurrence's expression
+ /// for diagnostics.
+ DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
+
/// \brief Adds explicit data sharing attribute to the specified declaration.
void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
@@ -107,46 +142,69 @@
DSAVarData getTopDSA(VarDecl *D);
/// \brief Returns data-sharing attributes for the specified declaration.
DSAVarData getImplicitDSA(VarDecl *D);
- /// \brief Checks if the specified variables has \a CKind data-sharing
- /// attribute in \a DKind directive.
- DSAVarData hasDSA(VarDecl *D, OpenMPClauseKind CKind,
- OpenMPDirectiveKind DKind = OMPD_unknown);
+ /// \brief Checks if the specified variables has data-sharing attributes which
+ /// match specified \a CPred predicate in any directive which matches \a DPred
+ /// predicate.
+ template <class ClausesPredicate, class DirectivesPredicate>
+ DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred,
+ DirectivesPredicate DPred);
+ /// \brief Checks if the specified variables has data-sharing attributes which
+ /// match specified \a CPred predicate in any innermost directive which
+ /// matches \a DPred predicate.
+ template <class ClausesPredicate, class DirectivesPredicate>
+ DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred,
+ DirectivesPredicate DPred);
/// \brief Returns currently analyzed directive.
OpenMPDirectiveKind getCurrentDirective() const {
return Stack.back().Directive;
}
+ /// \brief Returns parent directive.
+ OpenMPDirectiveKind getParentDirective() const {
+ if (Stack.size() > 2)
+ return Stack[Stack.size() - 2].Directive;
+ return OMPD_unknown;
+ }
/// \brief Set default data sharing attribute to none.
- void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }
+ void setDefaultDSANone(SourceLocation Loc) {
+ Stack.back().DefaultAttr = DSA_none;
+ Stack.back().DefaultAttrLoc = Loc;
+ }
/// \brief Set default data sharing attribute to shared.
- void setDefaultDSAShared() { Stack.back().DefaultAttr = DSA_shared; }
+ void setDefaultDSAShared(SourceLocation Loc) {
+ Stack.back().DefaultAttr = DSA_shared;
+ Stack.back().DefaultAttrLoc = Loc;
+ }
DefaultDataSharingAttributes getDefaultDSA() const {
return Stack.back().DefaultAttr;
}
+ SourceLocation getDefaultDSALocation() const {
+ return Stack.back().DefaultAttrLoc;
+ }
- /// \brief Checks if the spewcified variable is threadprivate.
+ /// \brief Checks if the specified variable is a threadprivate.
bool isThreadPrivate(VarDecl *D) {
DSAVarData DVar = getTopDSA(D);
- return (DVar.CKind == OMPC_threadprivate || DVar.CKind == OMPC_copyin);
+ return isOpenMPThreadPrivate(DVar.CKind);
}
Scope *getCurScope() const { return Stack.back().CurScope; }
Scope *getCurScope() { return Stack.back().CurScope; }
+ SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; }
};
} // namespace
DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter,
VarDecl *D) {
DSAVarData DVar;
- if (Iter == Stack.rend() - 1) {
+ if (Iter == std::prev(Stack.rend())) {
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
// in a region but not in construct]
// File-scope or namespace-scope variables referenced in called routines
// in the region are shared unless they appear in a threadprivate
// directive.
- // TODO
if (!D->isFunctionOrMethodVarDecl())
DVar.CKind = OMPC_shared;
@@ -165,12 +223,10 @@
// in a Construct, C/C++, predetermined, p.1]
// Variables with automatic storage duration that are declared in a scope
// inside the construct are private.
- if (DVar.DKind != OMPD_parallel) {
- if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
- (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
- DVar.CKind = OMPC_private;
- return DVar;
- }
+ if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() &&
+ (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
+ DVar.CKind = OMPC_private;
+ return DVar;
}
// Explicitly specified attributes and local variables with predetermined
@@ -188,6 +244,7 @@
switch (Iter->DefaultAttr) {
case DSA_shared:
DVar.CKind = OMPC_shared;
+ DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
return DVar;
case DSA_none:
return DVar;
@@ -196,7 +253,8 @@
// in a Construct, implicitly determined, p.2]
// In a parallel construct, if no default clause is present, these
// variables are shared.
- if (DVar.DKind == OMPD_parallel) {
+ DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
+ if (isOpenMPParallelDirective(DVar.DKind)) {
DVar.CKind = OMPC_shared;
return DVar;
}
@@ -206,7 +264,6 @@
// In a task construct, if no default clause is present, a variable that in
// the enclosing context is determined to be shared by all implicit tasks
// bound to the current team is shared.
- // TODO
if (DVar.DKind == OMPD_task) {
DSAVarData DVarTemp;
for (StackTy::reverse_iterator I = std::next(Iter),
@@ -225,7 +282,7 @@
DVar.CKind = OMPC_firstprivate;
return DVar;
}
- if (I->Directive == OMPD_parallel)
+ if (isOpenMPParallelDirective(I->Directive))
break;
}
DVar.DKind = OMPD_task;
@@ -242,6 +299,20 @@
return getDSA(std::next(Iter), D);
}
+DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
+ assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
+ auto It = Stack.back().AlignedMap.find(D);
+ if (It == Stack.back().AlignedMap.end()) {
+ assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
+ Stack.back().AlignedMap[D] = NewDE;
+ return nullptr;
+ } else {
+ assert(It->second && "Unexpected nullptr expr in the aligned map");
+ return It->second;
+ }
+ return nullptr;
+}
+
void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
if (A == OMPC_threadprivate) {
Stack[0].SharingMap[D].Attributes = A;
@@ -255,9 +326,9 @@
bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
if (Stack.size() > 2) {
- reverse_iterator I = Iter, E = Stack.rend() - 1;
+ reverse_iterator I = Iter, E = std::prev(Stack.rend());
Scope *TopScope = nullptr;
- while (I != E && I->Directive != OMPD_parallel) {
+ while (I != E && !isOpenMPParallelDirective(I->Directive)) {
++I;
}
if (I == E)
@@ -293,7 +364,7 @@
// Variables with automatic storage duration that are declared in a scope
// inside the construct are private.
OpenMPDirectiveKind Kind = getCurrentDirective();
- if (Kind != OMPD_parallel) {
+ if (!isOpenMPParallelDirective(Kind)) {
if (isOpenMPLocal(D, std::next(Stack.rbegin())) && D->isLocalVarDecl() &&
(D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) {
DVar.CKind = OMPC_private;
@@ -303,12 +374,12 @@
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
// in a Construct, C/C++, predetermined, p.4]
- // Static data memebers are shared.
+ // Static data members are shared.
if (D->isStaticDataMember()) {
// Variables with const-qualified type having no mutable member may be
- // listed
- // in a firstprivate clause, even if they are static data members.
- DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
+ // listed in a firstprivate clause, even if they are static data members.
+ DSAVarData DVarTemp =
+ hasDSA(D, MatchesAnyClause(OMPC_firstprivate), MatchesAlways());
if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
return DVar;
@@ -317,7 +388,7 @@
}
QualType Type = D->getType().getNonReferenceType().getCanonicalType();
- bool IsConstant = Type.isConstant(Actions.getASTContext());
+ bool IsConstant = Type.isConstant(SemaRef.getASTContext());
while (Type->isArrayType()) {
QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType();
Type = ElemType.getNonReferenceType().getCanonicalType();
@@ -327,12 +398,13 @@
// Variables with const qualified type having no mutable member are
// shared.
CXXRecordDecl *RD =
- Actions.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+ SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
if (IsConstant &&
- !(Actions.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
+ !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) {
// Variables with const-qualified type having no mutable member may be
// listed in a firstprivate clause, even if they are static data members.
- DSAVarData DVarTemp = hasDSA(D, OMPC_firstprivate);
+ DSAVarData DVarTemp =
+ hasDSA(D, MatchesAnyClause(OMPC_firstprivate), MatchesAlways());
if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
return DVar;
@@ -363,20 +435,36 @@
return getDSA(std::next(Stack.rbegin()), D);
}
-DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, OpenMPClauseKind CKind,
- OpenMPDirectiveKind DKind) {
+template <class ClausesPredicate, class DirectivesPredicate>
+DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred,
+ DirectivesPredicate DPred) {
for (StackTy::reverse_iterator I = std::next(Stack.rbegin()),
E = std::prev(Stack.rend());
I != E; ++I) {
- if (DKind != OMPD_unknown && DKind != I->Directive)
+ if (!DPred(I->Directive))
continue;
DSAVarData DVar = getDSA(I, D);
- if (DVar.CKind == CKind)
+ if (CPred(DVar.CKind))
return DVar;
}
return DSAVarData();
}
+template <class ClausesPredicate, class DirectivesPredicate>
+DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(VarDecl *D,
+ ClausesPredicate CPred,
+ DirectivesPredicate DPred) {
+ for (auto I = Stack.rbegin(), EE = std::prev(Stack.rend()); I != EE; ++I) {
+ if (!DPred(I->Directive))
+ continue;
+ DSAVarData DVar = getDSA(I, D);
+ if (CPred(DVar.CKind))
+ return DVar;
+ return DSAVarData();
+ }
+ return DSAVarData();
+}
+
void Sema::InitDataSharingAttributesStack() {
VarDataSharingAttributesStack = new DSAStackTy(*this);
}
@@ -387,12 +475,62 @@
void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
const DeclarationNameInfo &DirName,
- Scope *CurScope) {
- DSAStack->push(DKind, DirName, CurScope);
+ Scope *CurScope, SourceLocation Loc) {
+ DSAStack->push(DKind, DirName, CurScope, Loc);
PushExpressionEvaluationContext(PotentiallyEvaluated);
}
void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
+ // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
+ // A variable of class type (or array thereof) that appears in a lastprivate
+ // clause requires an accessible, unambiguous default constructor for the
+ // class type, unless the list item is also specified in a firstprivate
+ // clause.
+ if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
+ for (auto C : D->clauses()) {
+ if (auto Clause = dyn_cast<OMPLastprivateClause>(C)) {
+ for (auto VarRef : Clause->varlists()) {
+ if (VarRef->isValueDependent() || VarRef->isTypeDependent())
+ continue;
+ auto VD = cast<VarDecl>(cast<DeclRefExpr>(VarRef)->getDecl());
+ auto DVar = DSAStack->getTopDSA(VD);
+ if (DVar.CKind == OMPC_lastprivate) {
+ SourceLocation ELoc = VarRef->getExprLoc();
+ auto Type = VarRef->getType();
+ if (Type->isArrayType())
+ Type = QualType(Type->getArrayElementTypeNoTypeQual(), 0);
+ CXXRecordDecl *RD =
+ getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+ // FIXME This code must be replaced by actual constructing of the
+ // lastprivate variable.
+ if (RD) {
+ CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
+ PartialDiagnostic PD =
+ PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+ if (!CD ||
+ CheckConstructorAccess(
+ ELoc, CD, InitializedEntity::InitializeTemporary(Type),
+ CD->getAccess(), PD) == AR_inaccessible ||
+ CD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_lastprivate) << 0;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(), IsDecl ? diag::note_previous_decl
+ : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, CD);
+ DiagnoseUseOfDecl(CD, ELoc);
+ }
+ }
+ }
+ }
+ }
+ }
+
DSAStack->pop();
DiscardCleanupsInEvaluationContext();
PopExpressionEvaluationContext();
@@ -402,16 +540,16 @@
class VarDeclFilterCCC : public CorrectionCandidateCallback {
private:
- Sema &Actions;
+ Sema &SemaRef;
public:
- VarDeclFilterCCC(Sema &S) : Actions(S) {}
+ explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
bool ValidateCandidate(const TypoCorrection &Candidate) override {
NamedDecl *ND = Candidate.getCorrectionDecl();
if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) {
return VD->hasGlobalStorage() &&
- Actions.isDeclInScope(ND, Actions.getCurLexicalContext(),
- Actions.getCurScope());
+ SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
+ SemaRef.getCurScope());
}
return false;
}
@@ -553,6 +691,35 @@
return DeclGroupPtrTy();
}
+namespace {
+class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
+ Sema &SemaRef;
+
+public:
+ bool VisitDeclRefExpr(const DeclRefExpr *E) {
+ if (auto VD = dyn_cast<VarDecl>(E->getDecl())) {
+ if (VD->hasLocalStorage()) {
+ SemaRef.Diag(E->getLocStart(),
+ diag::err_omp_local_var_in_threadprivate_init)
+ << E->getSourceRange();
+ SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
+ << VD << VD->getSourceRange();
+ return true;
+ }
+ }
+ return false;
+ }
+ bool VisitStmt(const Stmt *S) {
+ for (auto Child : S->children()) {
+ if (Child && Visit(Child))
+ return true;
+ }
+ return false;
+ }
+ explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
+};
+} // namespace
+
OMPThreadPrivateDecl *
Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
SmallVector<Expr *, 8> Vars;
@@ -592,6 +759,14 @@
continue;
}
+ // Check if initial value of threadprivate variable reference variable with
+ // local storage (it is not supported by runtime).
+ if (auto Init = VD->getAnyInitializer()) {
+ LocalVarRefChecker Checker(*this);
+ if (Checker.Visit(Init))
+ continue;
+ }
+
Vars.push_back(RefExpr);
DSAStack->addDSA(VD, DE, OMPC_threadprivate);
}
@@ -604,13 +779,63 @@
return D;
}
+static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
+ const VarDecl *VD, DSAStackTy::DSAVarData DVar,
+ bool IsLoopIterVar = false) {
+ if (DVar.RefExpr) {
+ SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
+ << getOpenMPClauseName(DVar.CKind);
+ return;
+ }
+ enum {
+ PDSA_StaticMemberShared,
+ PDSA_StaticLocalVarShared,
+ PDSA_LoopIterVarPrivate,
+ PDSA_LoopIterVarLinear,
+ PDSA_LoopIterVarLastprivate,
+ PDSA_ConstVarShared,
+ PDSA_GlobalVarShared,
+ PDSA_LocalVarPrivate,
+ PDSA_Implicit
+ } Reason = PDSA_Implicit;
+ bool ReportHint = false;
+ if (IsLoopIterVar) {
+ if (DVar.CKind == OMPC_private)
+ Reason = PDSA_LoopIterVarPrivate;
+ else if (DVar.CKind == OMPC_lastprivate)
+ Reason = PDSA_LoopIterVarLastprivate;
+ else
+ Reason = PDSA_LoopIterVarLinear;
+ } else if (VD->isStaticLocal())
+ Reason = PDSA_StaticLocalVarShared;
+ else if (VD->isStaticDataMember())
+ Reason = PDSA_StaticMemberShared;
+ else if (VD->isFileVarDecl())
+ Reason = PDSA_GlobalVarShared;
+ else if (VD->getType().isConstant(SemaRef.getASTContext()))
+ Reason = PDSA_ConstVarShared;
+ else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
+ ReportHint = true;
+ Reason = PDSA_LocalVarPrivate;
+ }
+ if (Reason != PDSA_Implicit) {
+ SemaRef.Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
+ << Reason << ReportHint
+ << getOpenMPDirectiveName(Stack->getCurrentDirective());
+ } else if (DVar.ImplicitDSALoc.isValid()) {
+ SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
+ << getOpenMPClauseName(DVar.CKind);
+ }
+}
+
namespace {
class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
DSAStackTy *Stack;
- Sema &Actions;
+ Sema &SemaRef;
bool ErrorFound;
CapturedStmt *CS;
llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
+ llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA;
public:
void VisitDeclRefExpr(DeclRefExpr *E) {
@@ -634,9 +859,9 @@
// attribute, must have its data-sharing attribute explicitly determined
// by being listed in a data-sharing attribute clause.
if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
- (DKind == OMPD_parallel || DKind == OMPD_task)) {
- ErrorFound = true;
- Actions.Diag(ELoc, diag::err_omp_no_dsa_for_variable) << VD;
+ (isOpenMPParallelDirective(DKind) || DKind == OMPD_task) &&
+ VarsWithInheritedDSA.count(VD) == 0) {
+ VarsWithInheritedDSA[VD] = E;
return;
}
@@ -644,7 +869,14 @@
// A list item that appears in a reduction clause of the innermost
// enclosing worksharing or parallel construct may not be accessed in an
// explicit task.
- // TODO:
+ DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction),
+ MatchesAlways());
+ if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) {
+ ErrorFound = true;
+ SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
+ ReportOriginalDSA(SemaRef, Stack, VD, DVar);
+ return;
+ }
// Define implicit data-sharing attributes for task.
DVar = Stack->getImplicitDSA(VD);
@@ -669,31 +901,87 @@
bool isErrorFound() { return ErrorFound; }
ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; }
+ llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() {
+ return VarsWithInheritedDSA;
+ }
- DSAAttrChecker(DSAStackTy *S, Sema &Actions, CapturedStmt *CS)
- : Stack(S), Actions(Actions), ErrorFound(false), CS(CS) {}
+ DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
+ : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
};
} // namespace
-void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, SourceLocation Loc,
- Scope *CurScope) {
+void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
switch (DKind) {
case OMPD_parallel: {
QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
- Sema::CapturedParamNameType Params[3] = {
- std::make_pair(".global_tid.", KmpInt32PtrTy),
- std::make_pair(".bound_tid.", KmpInt32PtrTy),
- std::make_pair(StringRef(), QualType()) // __context with shared vars
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(".global_tid.", KmpInt32PtrTy),
+ std::make_pair(".bound_tid.", KmpInt32PtrTy),
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
};
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
break;
}
case OMPD_simd: {
- Sema::CapturedParamNameType Params[1] = {
- std::make_pair(StringRef(), QualType()) // __context with shared vars
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
};
- ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP, Params);
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
+ case OMPD_for: {
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
+ case OMPD_sections: {
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
+ case OMPD_section: {
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
+ case OMPD_single: {
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
+ case OMPD_parallel_for: {
+ QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
+ QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty);
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(".global_tid.", KmpInt32PtrTy),
+ std::make_pair(".bound_tid.", KmpInt32PtrTy),
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
+ break;
+ }
+ case OMPD_parallel_sections: {
+ Sema::CapturedParamNameType Params[] = {
+ std::make_pair(StringRef(), QualType()) // __context with shared vars
+ };
+ ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
+ Params);
break;
}
case OMPD_threadprivate:
@@ -704,6 +992,131 @@
}
}
+bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+ OpenMPDirectiveKind CurrentRegion,
+ SourceLocation StartLoc) {
+ // Allowed nesting of constructs
+ // +------------------+-----------------+------------------------------------+
+ // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)|
+ // +------------------+-----------------+------------------------------------+
+ // | parallel | parallel | * |
+ // | parallel | for | * |
+ // | parallel | simd | * |
+ // | parallel | sections | * |
+ // | parallel | section | + |
+ // | parallel | single | * |
+ // | parallel | parallel for | * |
+ // | parallel |parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ // | for | parallel | * |
+ // | for | for | + |
+ // | for | simd | * |
+ // | for | sections | + |
+ // | for | section | + |
+ // | for | single | + |
+ // | for | parallel for | * |
+ // | for |parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ // | simd | parallel | |
+ // | simd | for | |
+ // | simd | simd | |
+ // | simd | sections | |
+ // | simd | section | |
+ // | simd | single | |
+ // | simd | parallel for | |
+ // | simd |parallel sections| |
+ // +------------------+-----------------+------------------------------------+
+ // | sections | parallel | * |
+ // | sections | for | + |
+ // | sections | simd | * |
+ // | sections | sections | + |
+ // | sections | section | * |
+ // | sections | single | + |
+ // | sections | parallel for | * |
+ // | sections |parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ // | section | parallel | * |
+ // | section | for | + |
+ // | section | simd | * |
+ // | section | sections | + |
+ // | section | section | + |
+ // | section | single | + |
+ // | section | parallel for | * |
+ // | section |parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ // | single | parallel | * |
+ // | single | for | + |
+ // | single | simd | * |
+ // | single | sections | + |
+ // | single | section | + |
+ // | single | single | + |
+ // | single | parallel for | * |
+ // | single |parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ // | parallel for | parallel | * |
+ // | parallel for | for | + |
+ // | parallel for | simd | * |
+ // | parallel for | sections | + |
+ // | parallel for | section | + |
+ // | parallel for | single | + |
+ // | parallel for | parallel for | * |
+ // | parallel for |parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ // | parallel sections| parallel | * |
+ // | parallel sections| for | + |
+ // | parallel sections| simd | * |
+ // | parallel sections| sections | + |
+ // | parallel sections| section | * |
+ // | parallel sections| single | + |
+ // | parallel sections| parallel for | * |
+ // | parallel sections|parallel sections| * |
+ // +------------------+-----------------+------------------------------------+
+ if (Stack->getCurScope()) {
+ auto ParentRegion = Stack->getParentDirective();
+ bool NestingProhibited = false;
+ bool CloseNesting = true;
+ bool ShouldBeInParallelRegion = false;
+ if (isOpenMPSimdDirective(ParentRegion)) {
+ // OpenMP [2.16, Nesting of Regions]
+ // OpenMP constructs may not be nested inside a simd region.
+ SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
+ return true;
+ }
+ if (CurrentRegion == OMPD_section) {
+ // OpenMP [2.7.2, sections Construct, Restrictions]
+ // Orphaned section directives are prohibited. That is, the section
+ // directives must appear within the sections construct and must not be
+ // encountered elsewhere in the sections region.
+ if (ParentRegion != OMPD_sections &&
+ ParentRegion != OMPD_parallel_sections) {
+ SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
+ << (ParentRegion != OMPD_unknown)
+ << getOpenMPDirectiveName(ParentRegion);
+ return true;
+ }
+ return false;
+ }
+ if (isOpenMPWorksharingDirective(CurrentRegion) &&
+ !isOpenMPParallelDirective(CurrentRegion) &&
+ !isOpenMPSimdDirective(CurrentRegion)) {
+ // OpenMP [2.16, Nesting of Regions]
+ // A worksharing region may not be closely nested inside a worksharing,
+ // explicit task, critical, ordered, atomic, or master region.
+ // TODO
+ NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) &&
+ !isOpenMPSimdDirective(ParentRegion);
+ ShouldBeInParallelRegion = true;
+ }
+ if (NestingProhibited) {
+ SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
+ << CloseNesting << getOpenMPDirectiveName(ParentRegion)
+ << ShouldBeInParallelRegion << getOpenMPDirectiveName(CurrentRegion);
+ return true;
+ }
+ }
+ return false;
+}
+
StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
@@ -712,6 +1125,8 @@
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
StmtResult Res = StmtError();
+ if (CheckNestingOfRegions(*this, DSAStack, Kind, StartLoc))
+ return StmtError();
// Check default data sharing attributes for referenced variables.
DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
@@ -719,6 +1134,7 @@
if (DSAChecker.isErrorFound())
return StmtError();
// Generate list of implicitly defined firstprivate variables.
+ auto &VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
@@ -740,8 +1156,33 @@
EndLoc);
break;
case OMPD_simd:
- Res =
- ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
+ Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+ VarsWithInheritedDSA);
+ break;
+ case OMPD_for:
+ Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
+ VarsWithInheritedDSA);
+ break;
+ case OMPD_sections:
+ Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc);
+ break;
+ case OMPD_section:
+ assert(ClausesWithImplicit.empty() &&
+ "No clauses is allowed for 'omp section' directive");
+ Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
+ break;
+ case OMPD_single:
+ Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc);
+ break;
+ case OMPD_parallel_for:
+ Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc, VarsWithInheritedDSA);
+ break;
+ case OMPD_parallel_sections:
+ Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
+ StartLoc, EndLoc);
break;
case OMPD_threadprivate:
case OMPD_task:
@@ -750,6 +1191,13 @@
llvm_unreachable("Unknown OpenMP directive");
}
+ for (auto P : VarsWithInheritedDSA) {
+ Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
+ << P.first << P.second->getSourceRange();
+ }
+ if (!VarsWithInheritedDSA.empty())
+ return StmtError();
+
if (ErrorFound)
return StmtError();
return Res;
@@ -770,30 +1218,684 @@
getCurFunction()->setHasBranchProtectedScope();
- return Owned(
- OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt));
+ return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
+ AStmt);
}
-StmtResult Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses,
- Stmt *AStmt, SourceLocation StartLoc,
- SourceLocation EndLoc) {
- Stmt *CStmt = AStmt;
- while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(CStmt))
- CStmt = CS->getCapturedStmt();
- while (AttributedStmt *AS = dyn_cast_or_null<AttributedStmt>(CStmt))
- CStmt = AS->getSubStmt();
- ForStmt *For = dyn_cast<ForStmt>(CStmt);
+namespace {
+/// \brief Helper class for checking canonical form of the OpenMP loops and
+/// extracting iteration space of each loop in the loop nest, that will be used
+/// for IR generation.
+class OpenMPIterationSpaceChecker {
+ /// \brief Reference to Sema.
+ Sema &SemaRef;
+ /// \brief A location for diagnostics (when there is no some better location).
+ SourceLocation DefaultLoc;
+ /// \brief A location for diagnostics (when increment is not compatible).
+ SourceLocation ConditionLoc;
+ /// \brief A source location for referring to condition later.
+ SourceRange ConditionSrcRange;
+ /// \brief Loop variable.
+ VarDecl *Var;
+ /// \brief Lower bound (initializer for the var).
+ Expr *LB;
+ /// \brief Upper bound.
+ Expr *UB;
+ /// \brief Loop step (increment).
+ Expr *Step;
+ /// \brief This flag is true when condition is one of:
+ /// Var < UB
+ /// Var <= UB
+ /// UB > Var
+ /// UB >= Var
+ bool TestIsLessOp;
+ /// \brief This flag is true when condition is strict ( < or > ).
+ bool TestIsStrictOp;
+ /// \brief This flag is true when step is subtracted on each iteration.
+ bool SubtractStep;
+
+public:
+ OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
+ : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
+ ConditionSrcRange(SourceRange()), Var(nullptr), LB(nullptr),
+ UB(nullptr), Step(nullptr), TestIsLessOp(false), TestIsStrictOp(false),
+ SubtractStep(false) {}
+ /// \brief Check init-expr for canonical loop form and save loop counter
+ /// variable - #Var and its initialization value - #LB.
+ bool CheckInit(Stmt *S);
+ /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
+ /// for less/greater and for strict/non-strict comparison.
+ bool CheckCond(Expr *S);
+ /// \brief Check incr-expr for canonical loop form and return true if it
+ /// does not conform, otherwise save loop step (#Step).
+ bool CheckInc(Expr *S);
+ /// \brief Return the loop counter variable.
+ VarDecl *GetLoopVar() const { return Var; }
+ /// \brief Return true if any expression is dependent.
+ bool Dependent() const;
+
+private:
+ /// \brief Check the right-hand side of an assignment in the increment
+ /// expression.
+ bool CheckIncRHS(Expr *RHS);
+ /// \brief Helper to set loop counter variable and its initializer.
+ bool SetVarAndLB(VarDecl *NewVar, Expr *NewLB);
+ /// \brief Helper to set upper bound.
+ bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR,
+ const SourceLocation &SL);
+ /// \brief Helper to set loop increment.
+ bool SetStep(Expr *NewStep, bool Subtract);
+};
+
+bool OpenMPIterationSpaceChecker::Dependent() const {
+ if (!Var) {
+ assert(!LB && !UB && !Step);
+ return false;
+ }
+ return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) ||
+ (UB && UB->isValueDependent()) || (Step && Step->isValueDependent());
+}
+
+bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, Expr *NewLB) {
+ // State consistency checking to ensure correct usage.
+ assert(Var == nullptr && LB == nullptr && UB == nullptr && Step == nullptr &&
+ !TestIsLessOp && !TestIsStrictOp);
+ if (!NewVar || !NewLB)
+ return true;
+ Var = NewVar;
+ LB = NewLB;
+ return false;
+}
+
+bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
+ const SourceRange &SR,
+ const SourceLocation &SL) {
+ // State consistency checking to ensure correct usage.
+ assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr &&
+ !TestIsLessOp && !TestIsStrictOp);
+ if (!NewUB)
+ return true;
+ UB = NewUB;
+ TestIsLessOp = LessOp;
+ TestIsStrictOp = StrictOp;
+ ConditionSrcRange = SR;
+ ConditionLoc = SL;
+ return false;
+}
+
+bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
+ // State consistency checking to ensure correct usage.
+ assert(Var != nullptr && LB != nullptr && Step == nullptr);
+ if (!NewStep)
+ return true;
+ if (!NewStep->isValueDependent()) {
+ // Check that the step is integer expression.
+ SourceLocation StepLoc = NewStep->getLocStart();
+ ExprResult Val =
+ SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep);
+ if (Val.isInvalid())
+ return true;
+ NewStep = Val.get();
+
+ // OpenMP [2.6, Canonical Loop Form, Restrictions]
+ // If test-expr is of form var relational-op b and relational-op is < or
+ // <= then incr-expr must cause var to increase on each iteration of the
+ // loop. If test-expr is of form var relational-op b and relational-op is
+ // > or >= then incr-expr must cause var to decrease on each iteration of
+ // the loop.
+ // If test-expr is of form b relational-op var and relational-op is < or
+ // <= then incr-expr must cause var to decrease on each iteration of the
+ // loop. If test-expr is of form b relational-op var and relational-op is
+ // > or >= then incr-expr must cause var to increase on each iteration of
+ // the loop.
+ llvm::APSInt Result;
+ bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
+ bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
+ bool IsConstNeg =
+ IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
+ bool IsConstZero = IsConstant && !Result.getBoolValue();
+ if (UB && (IsConstZero ||
+ (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
+ : (!IsConstNeg || (IsUnsigned && !Subtract))))) {
+ SemaRef.Diag(NewStep->getExprLoc(),
+ diag::err_omp_loop_incr_not_compatible)
+ << Var << TestIsLessOp << NewStep->getSourceRange();
+ SemaRef.Diag(ConditionLoc,
+ diag::note_omp_loop_cond_requres_compatible_incr)
+ << TestIsLessOp << ConditionSrcRange;
+ return true;
+ }
+ }
+
+ Step = NewStep;
+ SubtractStep = Subtract;
+ return false;
+}
+
+bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S) {
+ // Check init-expr for canonical loop form and save loop counter
+ // variable - #Var and its initialization value - #LB.
+ // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
+ // var = lb
+ // integer-type var = lb
+ // random-access-iterator-type var = lb
+ // pointer-type var = lb
+ //
+ if (!S) {
+ SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
+ return true;
+ }
+ if (Expr *E = dyn_cast<Expr>(S))
+ S = E->IgnoreParens();
+ if (auto BO = dyn_cast<BinaryOperator>(S)) {
+ if (BO->getOpcode() == BO_Assign)
+ if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens()))
+ return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), BO->getLHS());
+ } else if (auto DS = dyn_cast<DeclStmt>(S)) {
+ if (DS->isSingleDecl()) {
+ if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
+ if (Var->hasInit()) {
+ // Accept non-canonical init form here but emit ext. warning.
+ if (Var->getInitStyle() != VarDecl::CInit)
+ SemaRef.Diag(S->getLocStart(),
+ diag::ext_omp_loop_not_canonical_init)
+ << S->getSourceRange();
+ return SetVarAndLB(Var, Var->getInit());
+ }
+ }
+ }
+ } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S))
+ if (CE->getOperator() == OO_Equal)
+ if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0)))
+ return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), CE->getArg(1));
+
+ SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
+ << S->getSourceRange();
+ return true;
+}
+
+/// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
+/// variable (which may be the loop variable) if possible.
+static const VarDecl *GetInitVarDecl(const Expr *E) {
+ if (!E)
+ return nullptr;
+ E = E->IgnoreParenImpCasts();
+ if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
+ if (const CXXConstructorDecl *Ctor = CE->getConstructor())
+ if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 &&
+ CE->getArg(0) != nullptr)
+ E = CE->getArg(0)->IgnoreParenImpCasts();
+ auto DRE = dyn_cast_or_null<DeclRefExpr>(E);
+ if (!DRE)
+ return nullptr;
+ return dyn_cast<VarDecl>(DRE->getDecl());
+}
+
+bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
+ // Check test-expr for canonical form, save upper-bound UB, flags for
+ // less/greater and for strict/non-strict comparison.
+ // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
+ // var relational-op b
+ // b relational-op var
+ //
+ if (!S) {
+ SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var;
+ return true;
+ }
+ S = S->IgnoreParenImpCasts();
+ SourceLocation CondLoc = S->getLocStart();
+ if (auto BO = dyn_cast<BinaryOperator>(S)) {
+ if (BO->isRelationalOp()) {
+ if (GetInitVarDecl(BO->getLHS()) == Var)
+ return SetUB(BO->getRHS(),
+ (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
+ (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
+ BO->getSourceRange(), BO->getOperatorLoc());
+ if (GetInitVarDecl(BO->getRHS()) == Var)
+ return SetUB(BO->getLHS(),
+ (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
+ (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
+ BO->getSourceRange(), BO->getOperatorLoc());
+ }
+ } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
+ if (CE->getNumArgs() == 2) {
+ auto Op = CE->getOperator();
+ switch (Op) {
+ case OO_Greater:
+ case OO_GreaterEqual:
+ case OO_Less:
+ case OO_LessEqual:
+ if (GetInitVarDecl(CE->getArg(0)) == Var)
+ return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
+ Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
+ CE->getOperatorLoc());
+ if (GetInitVarDecl(CE->getArg(1)) == Var)
+ return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
+ Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
+ CE->getOperatorLoc());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
+ << S->getSourceRange() << Var;
+ return true;
+}
+
+bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
+ // RHS of canonical loop form increment can be:
+ // var + incr
+ // incr + var
+ // var - incr
+ //
+ RHS = RHS->IgnoreParenImpCasts();
+ if (auto BO = dyn_cast<BinaryOperator>(RHS)) {
+ if (BO->isAdditiveOp()) {
+ bool IsAdd = BO->getOpcode() == BO_Add;
+ if (GetInitVarDecl(BO->getLHS()) == Var)
+ return SetStep(BO->getRHS(), !IsAdd);
+ if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var)
+ return SetStep(BO->getLHS(), false);
+ }
+ } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
+ bool IsAdd = CE->getOperator() == OO_Plus;
+ if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
+ if (GetInitVarDecl(CE->getArg(0)) == Var)
+ return SetStep(CE->getArg(1), !IsAdd);
+ if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var)
+ return SetStep(CE->getArg(0), false);
+ }
+ }
+ SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
+ << RHS->getSourceRange() << Var;
+ return true;
+}
+
+bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
+ // Check incr-expr for canonical loop form and return true if it
+ // does not conform.
+ // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
+ // ++var
+ // var++
+ // --var
+ // var--
+ // var += incr
+ // var -= incr
+ // var = var + incr
+ // var = incr + var
+ // var = var - incr
+ //
+ if (!S) {
+ SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var;
+ return true;
+ }
+ S = S->IgnoreParens();
+ if (auto UO = dyn_cast<UnaryOperator>(S)) {
+ if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var)
+ return SetStep(
+ SemaRef.ActOnIntegerConstant(UO->getLocStart(),
+ (UO->isDecrementOp() ? -1 : 1)).get(),
+ false);
+ } else if (auto BO = dyn_cast<BinaryOperator>(S)) {
+ switch (BO->getOpcode()) {
+ case BO_AddAssign:
+ case BO_SubAssign:
+ if (GetInitVarDecl(BO->getLHS()) == Var)
+ return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
+ break;
+ case BO_Assign:
+ if (GetInitVarDecl(BO->getLHS()) == Var)
+ return CheckIncRHS(BO->getRHS());
+ break;
+ default:
+ break;
+ }
+ } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) {
+ switch (CE->getOperator()) {
+ case OO_PlusPlus:
+ case OO_MinusMinus:
+ if (GetInitVarDecl(CE->getArg(0)) == Var)
+ return SetStep(
+ SemaRef.ActOnIntegerConstant(
+ CE->getLocStart(),
+ ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(),
+ false);
+ break;
+ case OO_PlusEqual:
+ case OO_MinusEqual:
+ if (GetInitVarDecl(CE->getArg(0)) == Var)
+ return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
+ break;
+ case OO_Equal:
+ if (GetInitVarDecl(CE->getArg(0)) == Var)
+ return CheckIncRHS(CE->getArg(1));
+ break;
+ default:
+ break;
+ }
+ }
+ SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
+ << S->getSourceRange() << Var;
+ return true;
+}
+} // namespace
+
+/// \brief Called on a for stmt to check and extract its iteration space
+/// for further processing (such as collapsing).
+static bool CheckOpenMPIterationSpace(
+ OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
+ unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
+ Expr *NestedLoopCountExpr,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+ // OpenMP [2.6, Canonical Loop Form]
+ // for (init-expr; test-expr; incr-expr) structured-block
+ auto For = dyn_cast_or_null<ForStmt>(S);
if (!For) {
- Diag(CStmt->getLocStart(), diag::err_omp_not_for)
- << getOpenMPDirectiveName(OMPD_simd);
+ SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
+ << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind)
+ << NestedLoopCount << (CurrentNestedLoopCount > 0)
+ << CurrentNestedLoopCount;
+ if (NestedLoopCount > 1)
+ SemaRef.Diag(NestedLoopCountExpr->getExprLoc(),
+ diag::note_omp_collapse_expr)
+ << NestedLoopCountExpr->getSourceRange();
+ return true;
+ }
+ assert(For->getBody());
+
+ OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
+
+ // Check init.
+ auto Init = For->getInit();
+ if (ISC.CheckInit(Init)) {
+ return true;
+ }
+
+ bool HasErrors = false;
+
+ // Check loop variable's type.
+ auto Var = ISC.GetLoopVar();
+
+ // OpenMP [2.6, Canonical Loop Form]
+ // Var is one of the following:
+ // A variable of signed or unsigned integer type.
+ // For C++, a variable of a random access iterator type.
+ // For C, a variable of a pointer type.
+ auto VarType = Var->getType();
+ if (!VarType->isDependentType() && !VarType->isIntegerType() &&
+ !VarType->isPointerType() &&
+ !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
+ SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
+ << SemaRef.getLangOpts().CPlusPlus;
+ HasErrors = true;
+ }
+
+ // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a
+ // Construct
+ // The loop iteration variable(s) in the associated for-loop(s) of a for or
+ // parallel for construct is (are) private.
+ // The loop iteration variable in the associated for-loop of a simd construct
+ // with just one associated for-loop is linear with a constant-linear-step
+ // that is the increment of the associated for-loop.
+ // Exclude loop var from the list of variables with implicitly defined data
+ // sharing attributes.
+ while (VarsWithImplicitDSA.count(Var) > 0)
+ VarsWithImplicitDSA.erase(Var);
+
+ // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in
+ // a Construct, C/C++].
+ // The loop iteration variable in the associated for-loop of a simd construct
+ // with just one associated for-loop may be listed in a linear clause with a
+ // constant-linear-step that is the increment of the associated for-loop.
+ // The loop iteration variable(s) in the associated for-loop(s) of a for or
+ // parallel for construct may be listed in a private or lastprivate clause.
+ DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var);
+ auto PredeterminedCKind =
+ isOpenMPSimdDirective(DKind)
+ ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
+ : OMPC_private;
+ if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
+ DVar.CKind != PredeterminedCKind) ||
+ (isOpenMPWorksharingDirective(DKind) && DVar.CKind != OMPC_unknown &&
+ DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
+ (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
+ SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
+ << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
+ << getOpenMPClauseName(PredeterminedCKind);
+ ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true);
+ HasErrors = true;
+ } else {
+ // Make the loop iteration variable private (for worksharing constructs),
+ // linear (for simd directives with the only one associated loop) or
+ // lastprivate (for simd directives with several collapsed loops).
+ DSA.addDSA(Var, nullptr, PredeterminedCKind);
+ }
+
+ assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
+
+ // Check test-expr.
+ HasErrors |= ISC.CheckCond(For->getCond());
+
+ // Check incr-expr.
+ HasErrors |= ISC.CheckInc(For->getInc());
+
+ if (ISC.Dependent())
+ return HasErrors;
+
+ // FIXME: Build loop's iteration space representation.
+ return HasErrors;
+}
+
+/// \brief A helper routine to skip no-op (attributed, compound) stmts get the
+/// next nested for loop. If \a IgnoreCaptured is true, it skips captured stmt
+/// to get the first for loop.
+static Stmt *IgnoreContainerStmts(Stmt *S, bool IgnoreCaptured) {
+ if (IgnoreCaptured)
+ if (auto CapS = dyn_cast_or_null<CapturedStmt>(S))
+ S = CapS->getCapturedStmt();
+ // OpenMP [2.8.1, simd construct, Restrictions]
+ // All loops associated with the construct must be perfectly nested; that is,
+ // there must be no intervening code nor any OpenMP directive between any two
+ // loops.
+ while (true) {
+ if (auto AS = dyn_cast_or_null<AttributedStmt>(S))
+ S = AS->getSubStmt();
+ else if (auto CS = dyn_cast_or_null<CompoundStmt>(S)) {
+ if (CS->size() != 1)
+ break;
+ S = CS->body_back();
+ } else
+ break;
+ }
+ return S;
+}
+
+/// \brief Called on a for stmt to check itself and nested loops (if any).
+/// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
+/// number of collapsed loops otherwise.
+static unsigned
+CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr,
+ Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+ unsigned NestedLoopCount = 1;
+ if (NestedLoopCountExpr) {
+ // Found 'collapse' clause - calculate collapse number.
+ llvm::APSInt Result;
+ if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
+ NestedLoopCount = Result.getLimitedValue();
+ }
+ // This is helper routine for loop directives (e.g., 'for', 'simd',
+ // 'for simd', etc.).
+ Stmt *CurStmt = IgnoreContainerStmts(AStmt, true);
+ for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
+ if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
+ NestedLoopCount, NestedLoopCountExpr,
+ VarsWithImplicitDSA))
+ return 0;
+ // Move on to the next nested for loop, or to the loop body.
+ CurStmt = IgnoreContainerStmts(cast<ForStmt>(CurStmt)->getBody(), false);
+ }
+
+ // FIXME: Build resulting iteration space for IR generation (collapsing
+ // iteration spaces when loop count > 1 ('collapse' clause)).
+ return NestedLoopCount;
+}
+
+static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
+ auto CollapseFilter = [](const OMPClause *C) -> bool {
+ return C->getClauseKind() == OMPC_collapse;
+ };
+ OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I(
+ Clauses, CollapseFilter);
+ if (I)
+ return cast<OMPCollapseClause>(*I)->getNumForLoops();
+ return nullptr;
+}
+
+StmtResult Sema::ActOnOpenMPSimdDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+ // In presence of clause 'collapse', it will define the nested loops number.
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this,
+ *DSAStack, VarsWithImplicitDSA);
+ if (NestedLoopCount == 0)
+ return StmtError();
+
+ getCurFunction()->setHasBranchProtectedScope();
+ return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+ Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+ // In presence of clause 'collapse', it will define the nested loops number.
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this,
+ *DSAStack, VarsWithImplicitDSA);
+ if (NestedLoopCount == 0)
+ return StmtError();
+
+ getCurFunction()->setHasBranchProtectedScope();
+ return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
+ Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+ auto BaseStmt = AStmt;
+ while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
+ BaseStmt = CS->getCapturedStmt();
+ if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
+ auto S = C->children();
+ if (!S)
+ return StmtError();
+ // All associated statements must be '#pragma omp section' except for
+ // the first one.
+ for (++S; S; ++S) {
+ auto SectionStmt = *S;
+ if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
+ if (SectionStmt)
+ Diag(SectionStmt->getLocStart(),
+ diag::err_omp_sections_substmt_not_section);
+ return StmtError();
+ }
+ }
+ } else {
+ Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
return StmtError();
}
- // FIXME: Checking loop canonical form, collapsing etc.
+ getCurFunction()->setHasBranchProtectedScope();
+
+ return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses,
+ AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
getCurFunction()->setHasBranchProtectedScope();
- return Owned(
- OMPSimdDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt));
+
+ return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ getCurFunction()->setHasBranchProtectedScope();
+ return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
+}
+
+StmtResult Sema::ActOnOpenMPParallelForDirective(
+ ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc,
+ llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+ CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+ // 1.2.2 OpenMP Language Terminology
+ // Structured block - An executable statement with a single entry at the
+ // top and a single exit at the bottom.
+ // The point of exit cannot be a branch out of the structured block.
+ // longjmp() and throw() must not violate the entry/exit criteria.
+ CS->getCapturedDecl()->setNothrow();
+
+ // In presence of clause 'collapse', it will define the nested loops number.
+ unsigned NestedLoopCount =
+ CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt,
+ *this, *DSAStack, VarsWithImplicitDSA);
+ if (NestedLoopCount == 0)
+ return StmtError();
+
+ getCurFunction()->setHasBranchProtectedScope();
+ return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
+ NestedLoopCount, Clauses, AStmt);
+}
+
+StmtResult
+Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
+ auto BaseStmt = AStmt;
+ while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
+ BaseStmt = CS->getCapturedStmt();
+ if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
+ auto S = C->children();
+ if (!S)
+ return StmtError();
+ // All associated statements must be '#pragma omp section' except for
+ // the first one.
+ for (++S; S; ++S) {
+ auto SectionStmt = *S;
+ if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
+ if (SectionStmt)
+ Diag(SectionStmt->getLocStart(),
+ diag::err_omp_parallel_sections_substmt_not_section);
+ return StmtError();
+ }
+ }
+ } else {
+ Diag(AStmt->getLocStart(),
+ diag::err_omp_parallel_sections_not_compound_stmt);
+ return StmtError();
+ }
+
+ getCurFunction()->setHasBranchProtectedScope();
+
+ return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc,
+ Clauses, AStmt);
}
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
@@ -816,11 +1918,18 @@
break;
case OMPC_default:
case OMPC_proc_bind:
+ case OMPC_schedule:
case OMPC_private:
case OMPC_firstprivate:
+ case OMPC_lastprivate:
case OMPC_shared:
+ case OMPC_reduction:
case OMPC_linear:
+ case OMPC_aligned:
case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_ordered:
+ case OMPC_nowait:
case OMPC_threadprivate:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
@@ -840,14 +1949,14 @@
if (Val.isInvalid())
return nullptr;
- ValExpr = Val.take();
+ ValExpr = Val.get();
}
return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc);
}
-ExprResult Sema::PerformImplicitIntegerConversion(SourceLocation Loc,
- Expr *Op) {
+ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
+ Expr *Op) {
if (!Op)
return ExprError();
@@ -900,11 +2009,11 @@
!NumThreads->containsUnexpandedParameterPack()) {
SourceLocation NumThreadsLoc = NumThreads->getLocStart();
ExprResult Val =
- PerformImplicitIntegerConversion(NumThreadsLoc, NumThreads);
+ PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads);
if (Val.isInvalid())
return nullptr;
- ValExpr = Val.take();
+ ValExpr = Val.get();
// OpenMP [2.5, Restrictions]
// The num_threads expression must evaluate to a positive integer value.
@@ -927,7 +2036,7 @@
return ExprError();
if (E->isValueDependent() || E->isTypeDependent() ||
E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
- return Owned(E);
+ return E;
llvm::APSInt Result;
ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
if (ICE.isInvalid())
@@ -950,21 +2059,24 @@
if (Safelen.isInvalid())
return nullptr;
return new (Context)
- OMPSafelenClause(Safelen.take(), StartLoc, LParenLoc, EndLoc);
+ OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
}
-OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
+ SourceLocation StartLoc,
SourceLocation LParenLoc,
SourceLocation EndLoc) {
+ // OpenMP [2.7.1, loop construct, Description]
// OpenMP [2.8.1, simd construct, Description]
+ // OpenMP [2.9.6, distribute construct, Description]
// The parameter of the collapse clause must be a constant
// positive integer expression.
- ExprResult NumForLoops =
- VerifyPositiveIntegerConstantInClause(Num, OMPC_collapse);
- if (NumForLoops.isInvalid())
+ ExprResult NumForLoopsResult =
+ VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
+ if (NumForLoopsResult.isInvalid())
return nullptr;
return new (Context)
- OMPCollapseClause(NumForLoops.take(), StartLoc, LParenLoc, EndLoc);
+ OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
}
OMPClause *Sema::ActOnOpenMPSimpleClause(
@@ -986,11 +2098,18 @@
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_collapse:
+ case OMPC_schedule:
case OMPC_private:
case OMPC_firstprivate:
+ case OMPC_lastprivate:
case OMPC_shared:
+ case OMPC_reduction:
case OMPC_linear:
+ case OMPC_aligned:
case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_ordered:
+ case OMPC_nowait:
case OMPC_threadprivate:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
@@ -1029,10 +2148,10 @@
}
switch (Kind) {
case OMPC_DEFAULT_none:
- DSAStack->setDefaultDSANone();
+ DSAStack->setDefaultDSANone(KindKwLoc);
break;
case OMPC_DEFAULT_shared:
- DSAStack->setDefaultDSAShared();
+ DSAStack->setDefaultDSAShared(KindKwLoc);
break;
case OMPC_DEFAULT_unknown:
llvm_unreachable("Clause kind is not allowed.");
@@ -1073,11 +2192,147 @@
OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
}
-OMPClause *
-Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef<Expr *> VarList,
- Expr *TailExpr, SourceLocation StartLoc,
- SourceLocation LParenLoc,
- SourceLocation ColonLoc, SourceLocation EndLoc) {
+OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
+ OpenMPClauseKind Kind, unsigned Argument, Expr *Expr,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ArgumentLoc, SourceLocation CommaLoc,
+ SourceLocation EndLoc) {
+ OMPClause *Res = nullptr;
+ switch (Kind) {
+ case OMPC_schedule:
+ Res = ActOnOpenMPScheduleClause(
+ static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc,
+ LParenLoc, ArgumentLoc, CommaLoc, EndLoc);
+ break;
+ case OMPC_if:
+ case OMPC_num_threads:
+ case OMPC_safelen:
+ case OMPC_collapse:
+ case OMPC_default:
+ case OMPC_proc_bind:
+ case OMPC_private:
+ case OMPC_firstprivate:
+ case OMPC_lastprivate:
+ case OMPC_shared:
+ case OMPC_reduction:
+ case OMPC_linear:
+ case OMPC_aligned:
+ case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_ordered:
+ case OMPC_nowait:
+ case OMPC_threadprivate:
+ case OMPC_unknown:
+ llvm_unreachable("Clause is not allowed.");
+ }
+ return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPScheduleClause(
+ OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
+ SourceLocation EndLoc) {
+ if (Kind == OMPC_SCHEDULE_unknown) {
+ std::string Values;
+ std::string Sep(", ");
+ for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) {
+ Values += "'";
+ Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i);
+ Values += "'";
+ switch (i) {
+ case OMPC_SCHEDULE_unknown - 2:
+ Values += " or ";
+ break;
+ case OMPC_SCHEDULE_unknown - 1:
+ break;
+ default:
+ Values += Sep;
+ break;
+ }
+ }
+ Diag(KindLoc, diag::err_omp_unexpected_clause_value)
+ << Values << getOpenMPClauseName(OMPC_schedule);
+ return nullptr;
+ }
+ Expr *ValExpr = ChunkSize;
+ if (ChunkSize) {
+ if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
+ !ChunkSize->isInstantiationDependent() &&
+ !ChunkSize->containsUnexpandedParameterPack()) {
+ SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
+ ExprResult Val =
+ PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
+ if (Val.isInvalid())
+ return nullptr;
+
+ ValExpr = Val.get();
+
+ // OpenMP [2.7.1, Restrictions]
+ // chunk_size must be a loop invariant integer expression with a positive
+ // value.
+ llvm::APSInt Result;
+ if (ValExpr->isIntegerConstantExpr(Result, Context) &&
+ Result.isSigned() && !Result.isStrictlyPositive()) {
+ Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
+ << "schedule" << ChunkSize->getSourceRange();
+ return nullptr;
+ }
+ }
+ }
+
+ return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc,
+ EndLoc, Kind, ValExpr);
+}
+
+OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ OMPClause *Res = nullptr;
+ switch (Kind) {
+ case OMPC_ordered:
+ Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
+ break;
+ case OMPC_nowait:
+ Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
+ break;
+ case OMPC_if:
+ case OMPC_num_threads:
+ case OMPC_safelen:
+ case OMPC_collapse:
+ case OMPC_schedule:
+ case OMPC_private:
+ case OMPC_firstprivate:
+ case OMPC_lastprivate:
+ case OMPC_shared:
+ case OMPC_reduction:
+ case OMPC_linear:
+ case OMPC_aligned:
+ case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_default:
+ case OMPC_proc_bind:
+ case OMPC_threadprivate:
+ case OMPC_unknown:
+ llvm_unreachable("Clause is not allowed.");
+ }
+ return Res;
+}
+
+OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPOrderedClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
+ SourceLocation EndLoc) {
+ return new (Context) OMPNowaitClause(StartLoc, EndLoc);
+}
+
+OMPClause *Sema::ActOnOpenMPVarListClause(
+ OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
+ SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
+ SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
+ const DeclarationNameInfo &ReductionId) {
OMPClause *Res = nullptr;
switch (Kind) {
case OMPC_private:
@@ -1086,22 +2341,39 @@
case OMPC_firstprivate:
Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_lastprivate:
+ Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_shared:
Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_reduction:
+ Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
+ EndLoc, ReductionIdScopeSpec, ReductionId);
+ break;
case OMPC_linear:
Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
ColonLoc, EndLoc);
break;
+ case OMPC_aligned:
+ Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
+ ColonLoc, EndLoc);
+ break;
case OMPC_copyin:
Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
break;
+ case OMPC_copyprivate:
+ Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
+ break;
case OMPC_if:
case OMPC_num_threads:
case OMPC_safelen:
case OMPC_collapse:
case OMPC_default:
case OMPC_proc_bind:
+ case OMPC_schedule:
+ case OMPC_ordered:
+ case OMPC_nowait:
case OMPC_threadprivate:
case OMPC_unknown:
llvm_unreachable("Clause is not allowed.");
@@ -1163,7 +2435,7 @@
// OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
// A variable of class type (or array thereof) that appears in a private
- // clause requires an accesible, unambiguous default constructor for the
+ // clause requires an accessible, unambiguous default constructor for the
// class type.
while (Type.getNonReferenceType()->isArrayType()) {
Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
@@ -1172,13 +2444,16 @@
CXXRecordDecl *RD = getLangOpts().CPlusPlus
? Type.getNonReferenceType()->getAsCXXRecordDecl()
: nullptr;
+ // FIXME This code must be replaced by actual constructing/destructing of
+ // the private variable.
if (RD) {
CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
PartialDiagnostic PD =
PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
- if (!CD || CheckConstructorAccess(
- ELoc, CD, InitializedEntity::InitializeTemporary(Type),
- CD->getAccess(), PD) == AR_inaccessible ||
+ if (!CD ||
+ CheckConstructorAccess(ELoc, CD,
+ InitializedEntity::InitializeTemporary(Type),
+ CD->getAccess(), PD) == AR_inaccessible ||
CD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
<< getOpenMPClauseName(OMPC_private) << 0;
@@ -1223,13 +2498,7 @@
if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
<< getOpenMPClauseName(OMPC_private);
- if (DVar.RefExpr) {
- Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
- } else {
- Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
- << getOpenMPClauseName(DVar.CKind);
- }
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
continue;
}
@@ -1297,19 +2566,22 @@
// OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
// A variable of class type (or array thereof) that appears in a private
- // clause requires an accesible, unambiguous copy constructor for the
+ // clause requires an accessible, unambiguous copy constructor for the
// class type.
Type = Context.getBaseElementType(Type);
CXXRecordDecl *RD = getLangOpts().CPlusPlus
? Type.getNonReferenceType()->getAsCXXRecordDecl()
: nullptr;
+ // FIXME This code must be replaced by actual constructing/destructing of
+ // the firstprivate variable.
if (RD) {
CXXConstructorDecl *CD = LookupCopyingConstructor(RD, 0);
PartialDiagnostic PD =
PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
- if (!CD || CheckConstructorAccess(
- ELoc, CD, InitializedEntity::InitializeTemporary(Type),
- CD->getAccess(), PD) == AR_inaccessible ||
+ if (!CD ||
+ CheckConstructorAccess(ELoc, CD,
+ InitializedEntity::InitializeTemporary(Type),
+ CD->getAccess(), PD) == AR_inaccessible ||
CD->isDeleted()) {
Diag(ELoc, diag::err_omp_required_method)
<< getOpenMPClauseName(OMPC_firstprivate) << 1;
@@ -1354,14 +2626,12 @@
// A list item that specifies a given variable may not appear in more
// than one clause on the same directive, except that a variable may be
// specified in both firstprivate and lastprivate clauses.
- // TODO: add processing for lastprivate.
if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
- DVar.RefExpr) {
+ DVar.CKind != OMPC_lastprivate && DVar.RefExpr) {
Diag(ELoc, diag::err_omp_wrong_dsa)
<< getOpenMPClauseName(DVar.CKind)
<< getOpenMPClauseName(OMPC_firstprivate);
- Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
continue;
}
@@ -1381,28 +2651,40 @@
Diag(ELoc, diag::err_omp_wrong_dsa)
<< getOpenMPClauseName(DVar.CKind)
<< getOpenMPClauseName(OMPC_firstprivate);
- Diag(VD->getLocation(), diag::note_omp_predetermined_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
continue;
}
+ OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
// OpenMP [2.9.3.4, Restrictions, p.2]
// A list item that is private within a parallel region must not appear
// in a firstprivate clause on a worksharing construct if any of the
// worksharing regions arising from the worksharing construct ever bind
// to any of the parallel regions arising from the parallel construct.
+ if (isOpenMPWorksharingDirective(CurrDir) &&
+ !isOpenMPParallelDirective(CurrDir)) {
+ DVar = DSAStack->getImplicitDSA(VD);
+ if (DVar.CKind != OMPC_shared) {
+ Diag(ELoc, diag::err_omp_required_access)
+ << getOpenMPClauseName(OMPC_firstprivate)
+ << getOpenMPClauseName(OMPC_shared);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+ }
// OpenMP [2.9.3.4, Restrictions, p.3]
// A list item that appears in a reduction clause of a parallel construct
// must not appear in a firstprivate clause on a worksharing or task
// construct if any of the worksharing or task regions arising from the
// worksharing or task construct ever bind to any of the parallel regions
// arising from the parallel construct.
+ // TODO
// OpenMP [2.9.3.4, Restrictions, p.4]
// A list item that appears in a reduction clause in worksharing
// construct must not appear in a firstprivate clause in a task construct
// encountered during execution of any of the worksharing regions arising
// from the worksharing construct.
- // TODO:
+ // TODO
}
DSAStack->addDSA(VD, DE, OMPC_firstprivate);
@@ -1416,6 +2698,161 @@
Vars);
}
+OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ SmallVector<Expr *, 8> Vars;
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ SourceLocation ELoc = RefExpr->getExprLoc();
+ // OpenMP [2.1, C/C++]
+ // A list item is a variable name.
+ // OpenMP [2.14.3.5, Restrictions, p.1]
+ // A variable that is part of another variable (as an array or structure
+ // element) cannot appear in a lastprivate clause.
+ DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
+ if (!DE || !isa<VarDecl>(DE->getDecl())) {
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+ continue;
+ }
+ Decl *D = DE->getDecl();
+ VarDecl *VD = cast<VarDecl>(D);
+
+ QualType Type = VD->getType();
+ if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+ // It will be analyzed later.
+ Vars.push_back(DE);
+ continue;
+ }
+
+ // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
+ // A variable that appears in a lastprivate clause must not have an
+ // incomplete type or a reference type.
+ if (RequireCompleteType(ELoc, Type,
+ diag::err_omp_lastprivate_incomplete_type)) {
+ continue;
+ }
+ if (Type->isReferenceType()) {
+ Diag(ELoc, diag::err_omp_clause_ref_type_arg)
+ << getOpenMPClauseName(OMPC_lastprivate) << Type;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+
+ // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
+ // in a Construct]
+ // Variables with the predetermined data-sharing attributes may not be
+ // listed in data-sharing attributes clauses, except for the cases
+ // listed below.
+ DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+ if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
+ DVar.CKind != OMPC_firstprivate &&
+ (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
+ Diag(ELoc, diag::err_omp_wrong_dsa)
+ << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_lastprivate);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+
+ OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+ // OpenMP [2.14.3.5, Restrictions, p.2]
+ // A list item that is private within a parallel region, or that appears in
+ // the reduction clause of a parallel construct, must not appear in a
+ // lastprivate clause on a worksharing construct if any of the corresponding
+ // worksharing regions ever binds to any of the corresponding parallel
+ // regions.
+ if (isOpenMPWorksharingDirective(CurrDir) &&
+ !isOpenMPParallelDirective(CurrDir)) {
+ DVar = DSAStack->getImplicitDSA(VD);
+ if (DVar.CKind != OMPC_shared) {
+ Diag(ELoc, diag::err_omp_required_access)
+ << getOpenMPClauseName(OMPC_lastprivate)
+ << getOpenMPClauseName(OMPC_shared);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+ }
+ // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
+ // A variable of class type (or array thereof) that appears in a
+ // lastprivate clause requires an accessible, unambiguous default
+ // constructor for the class type, unless the list item is also specified
+ // in a firstprivate clause.
+ // A variable of class type (or array thereof) that appears in a
+ // lastprivate clause requires an accessible, unambiguous copy assignment
+ // operator for the class type.
+ while (Type.getNonReferenceType()->isArrayType())
+ Type = cast<ArrayType>(Type.getNonReferenceType().getTypePtr())
+ ->getElementType();
+ CXXRecordDecl *RD = getLangOpts().CPlusPlus
+ ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+ : nullptr;
+ // FIXME This code must be replaced by actual copying and destructing of the
+ // lastprivate variable.
+ if (RD) {
+ CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+ DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+ if (MD) {
+ if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+ MD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_lastprivate) << 2;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, MD);
+ DiagnoseUseOfDecl(MD, ELoc);
+ }
+
+ CXXDestructorDecl *DD = RD->getDestructor();
+ if (DD) {
+ PartialDiagnostic PD =
+ PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+ if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
+ DD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_lastprivate) << 4;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, DD);
+ DiagnoseUseOfDecl(DD, ELoc);
+ }
+ }
+
+ if (DVar.CKind != OMPC_firstprivate)
+ DSAStack->addDSA(VD, DE, OMPC_lastprivate);
+ Vars.push_back(DE);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
+ Vars);
+}
+
OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1463,8 +2900,7 @@
DVar.RefExpr) {
Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
<< getOpenMPClauseName(OMPC_shared);
- Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
continue;
}
@@ -1478,6 +2914,327 @@
return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
+namespace {
+class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
+ DSAStackTy *Stack;
+
+public:
+ bool VisitDeclRefExpr(DeclRefExpr *E) {
+ if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
+ DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD);
+ if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
+ return false;
+ if (DVar.CKind != OMPC_unknown)
+ return true;
+ DSAStackTy::DSAVarData DVarPrivate =
+ Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways());
+ if (DVarPrivate.CKind != OMPC_unknown)
+ return true;
+ return false;
+ }
+ return false;
+ }
+ bool VisitStmt(Stmt *S) {
+ for (auto Child : S->children()) {
+ if (Child && Visit(Child))
+ return true;
+ }
+ return false;
+ }
+ explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
+};
+} // namespace
+
+OMPClause *Sema::ActOnOpenMPReductionClause(
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec,
+ const DeclarationNameInfo &ReductionId) {
+ // TODO: Allow scope specification search when 'declare reduction' is
+ // supported.
+ assert(ReductionIdScopeSpec.isEmpty() &&
+ "No support for scoped reduction identifiers yet.");
+
+ auto DN = ReductionId.getName();
+ auto OOK = DN.getCXXOverloadedOperator();
+ BinaryOperatorKind BOK = BO_Comma;
+
+ // OpenMP [2.14.3.6, reduction clause]
+ // C
+ // reduction-identifier is either an identifier or one of the following
+ // operators: +, -, *, &, |, ^, && and ||
+ // C++
+ // reduction-identifier is either an id-expression or one of the following
+ // operators: +, -, *, &, |, ^, && and ||
+ // FIXME: Only 'min' and 'max' identifiers are supported for now.
+ switch (OOK) {
+ case OO_Plus:
+ case OO_Minus:
+ BOK = BO_AddAssign;
+ break;
+ case OO_Star:
+ BOK = BO_MulAssign;
+ break;
+ case OO_Amp:
+ BOK = BO_AndAssign;
+ break;
+ case OO_Pipe:
+ BOK = BO_OrAssign;
+ break;
+ case OO_Caret:
+ BOK = BO_XorAssign;
+ break;
+ case OO_AmpAmp:
+ BOK = BO_LAnd;
+ break;
+ case OO_PipePipe:
+ BOK = BO_LOr;
+ break;
+ default:
+ if (auto II = DN.getAsIdentifierInfo()) {
+ if (II->isStr("max"))
+ BOK = BO_GT;
+ else if (II->isStr("min"))
+ BOK = BO_LT;
+ }
+ break;
+ }
+ SourceRange ReductionIdRange;
+ if (ReductionIdScopeSpec.isValid()) {
+ ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
+ }
+ ReductionIdRange.setEnd(ReductionId.getEndLoc());
+ if (BOK == BO_Comma) {
+ // Not allowed reduction identifier is found.
+ Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier)
+ << ReductionIdRange;
+ return nullptr;
+ }
+
+ SmallVector<Expr *, 8> Vars;
+ for (auto RefExpr : VarList) {
+ assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
+ RefExpr->isInstantiationDependent() ||
+ RefExpr->containsUnexpandedParameterPack()) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ auto ELoc = RefExpr->getExprLoc();
+ auto ERange = RefExpr->getSourceRange();
+ // OpenMP [2.1, C/C++]
+ // A list item is a variable or array section, subject to the restrictions
+ // specified in Section 2.4 on page 42 and in each of the sections
+ // describing clauses and directives for which a list appears.
+ // OpenMP [2.14.3.3, Restrictions, p.1]
+ // A variable that is part of another variable (as an array or
+ // structure element) cannot appear in a private clause.
+ auto DE = dyn_cast<DeclRefExpr>(RefExpr);
+ if (!DE || !isa<VarDecl>(DE->getDecl())) {
+ Diag(ELoc, diag::err_omp_expected_var_name) << ERange;
+ continue;
+ }
+ auto D = DE->getDecl();
+ auto VD = cast<VarDecl>(D);
+ auto Type = VD->getType();
+ // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
+ // A variable that appears in a private clause must not have an incomplete
+ // type or a reference type.
+ if (RequireCompleteType(ELoc, Type,
+ diag::err_omp_reduction_incomplete_type))
+ continue;
+ // OpenMP [2.14.3.6, reduction clause, Restrictions]
+ // Arrays may not appear in a reduction clause.
+ if (Type.getNonReferenceType()->isArrayType()) {
+ Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+ // OpenMP [2.14.3.6, reduction clause, Restrictions]
+ // A list item that appears in a reduction clause must not be
+ // const-qualified.
+ if (Type.getNonReferenceType().isConstant(Context)) {
+ Diag(ELoc, diag::err_omp_const_variable)
+ << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+ // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
+ // If a list-item is a reference type then it must bind to the same object
+ // for all threads of the team.
+ VarDecl *VDDef = VD->getDefinition();
+ if (Type->isReferenceType() && VDDef) {
+ DSARefChecker Check(DSAStack);
+ if (Check.Visit(VDDef->getInit())) {
+ Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
+ Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
+ continue;
+ }
+ }
+ // OpenMP [2.14.3.6, reduction clause, Restrictions]
+ // The type of a list item that appears in a reduction clause must be valid
+ // for the reduction-identifier. For a max or min reduction in C, the type
+ // of the list item must be an allowed arithmetic data type: char, int,
+ // float, double, or _Bool, possibly modified with long, short, signed, or
+ // unsigned. For a max or min reduction in C++, the type of the list item
+ // must be an allowed arithmetic data type: char, wchar_t, int, float,
+ // double, or bool, possibly modified with long, short, signed, or unsigned.
+ if ((BOK == BO_GT || BOK == BO_LT) &&
+ !(Type->isScalarType() ||
+ (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
+ Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
+ << getLangOpts().CPlusPlus;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+ if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
+ !getLangOpts().CPlusPlus && Type->isFloatingType()) {
+ Diag(ELoc, diag::err_omp_clause_floating_type_arg);
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+ bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
+ getDiagnostics().setSuppressAllDiagnostics(true);
+ ExprResult ReductionOp =
+ BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK,
+ RefExpr, RefExpr);
+ getDiagnostics().setSuppressAllDiagnostics(Suppress);
+ if (ReductionOp.isInvalid()) {
+ Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
+ << ReductionIdRange;
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+
+ // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
+ // in a Construct]
+ // Variables with the predetermined data-sharing attributes may not be
+ // listed in data-sharing attributes clauses, except for the cases
+ // listed below. For these exceptions only, listing a predetermined
+ // variable in a data-sharing attribute clause is allowed and overrides
+ // the variable's predetermined data-sharing attributes.
+ // OpenMP [2.14.3.6, Restrictions, p.3]
+ // Any number of reduction clauses can be specified on the directive,
+ // but a list item can appear only once in the reduction clauses for that
+ // directive.
+ DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD);
+ if (DVar.CKind == OMPC_reduction) {
+ Diag(ELoc, diag::err_omp_once_referenced)
+ << getOpenMPClauseName(OMPC_reduction);
+ if (DVar.RefExpr) {
+ Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
+ }
+ } else if (DVar.CKind != OMPC_unknown) {
+ Diag(ELoc, diag::err_omp_wrong_dsa)
+ << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_reduction);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+
+ // OpenMP [2.14.3.6, Restrictions, p.1]
+ // A list item that appears in a reduction clause of a worksharing
+ // construct must be shared in the parallel regions to which any of the
+ // worksharing regions arising from the worksharing construct bind.
+ OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+ if (isOpenMPWorksharingDirective(CurrDir) &&
+ !isOpenMPParallelDirective(CurrDir)) {
+ DVar = DSAStack->getImplicitDSA(VD);
+ if (DVar.CKind != OMPC_shared) {
+ Diag(ELoc, diag::err_omp_required_access)
+ << getOpenMPClauseName(OMPC_reduction)
+ << getOpenMPClauseName(OMPC_shared);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+ }
+
+ CXXRecordDecl *RD = getLangOpts().CPlusPlus
+ ? Type.getNonReferenceType()->getAsCXXRecordDecl()
+ : nullptr;
+ // FIXME This code must be replaced by actual constructing/destructing of
+ // the reduction variable.
+ if (RD) {
+ CXXConstructorDecl *CD = LookupDefaultConstructor(RD);
+ PartialDiagnostic PD =
+ PartialDiagnostic(PartialDiagnostic::NullDiagnostic());
+ if (!CD ||
+ CheckConstructorAccess(ELoc, CD,
+ InitializedEntity::InitializeTemporary(Type),
+ CD->getAccess(), PD) == AR_inaccessible ||
+ CD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_reduction) << 0;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, CD);
+ DiagnoseUseOfDecl(CD, ELoc);
+
+ CXXDestructorDecl *DD = RD->getDestructor();
+ if (DD) {
+ if (CheckDestructorAccess(ELoc, DD, PD) == AR_inaccessible ||
+ DD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_reduction) << 4;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, DD);
+ DiagnoseUseOfDecl(DD, ELoc);
+ }
+ }
+
+ DSAStack->addDSA(VD, DE, OMPC_reduction);
+ Vars.push_back(DE);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPReductionClause::Create(
+ Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
+ ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId);
+}
+
OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1522,8 +3279,7 @@
if (DVar.RefExpr) {
Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
<< getOpenMPClauseName(OMPC_linear);
- Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
- << getOpenMPClauseName(DVar.CKind);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
continue;
}
@@ -1588,10 +3344,10 @@
!Step->isInstantiationDependent() &&
!Step->containsUnexpandedParameterPack()) {
SourceLocation StepLoc = Step->getLocStart();
- ExprResult Val = PerformImplicitIntegerConversion(StepLoc, Step);
+ ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
if (Val.isInvalid())
return nullptr;
- StepExpr = Val.take();
+ StepExpr = Val.get();
// Warn about zero linear step (it would be probably better specified as
// making corresponding variables 'const').
@@ -1606,6 +3362,81 @@
Vars, StepExpr);
}
+OMPClause *Sema::ActOnOpenMPAlignedClause(
+ ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
+
+ SmallVector<Expr *, 8> Vars;
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP aligned clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ SourceLocation ELoc = RefExpr->getExprLoc();
+ // OpenMP [2.1, C/C++]
+ // A list item is a variable name.
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+ if (!DE || !isa<VarDecl>(DE->getDecl())) {
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+ continue;
+ }
+
+ VarDecl *VD = cast<VarDecl>(DE->getDecl());
+
+ // OpenMP [2.8.1, simd construct, Restrictions]
+ // The type of list items appearing in the aligned clause must be
+ // array, pointer, reference to array, or reference to pointer.
+ QualType QType = DE->getType()
+ .getNonReferenceType()
+ .getUnqualifiedType()
+ .getCanonicalType();
+ const Type *Ty = QType.getTypePtrOrNull();
+ if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
+ !Ty->isPointerType())) {
+ Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
+ << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
+ bool IsDecl =
+ VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ continue;
+ }
+
+ // OpenMP [2.8.1, simd construct, Restrictions]
+ // A list-item cannot appear in more than one aligned clause.
+ if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
+ Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
+ Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
+ << getOpenMPClauseName(OMPC_aligned);
+ continue;
+ }
+
+ Vars.push_back(DE);
+ }
+
+ // OpenMP [2.8.1, simd construct, Description]
+ // The parameter of the aligned clause, alignment, must be a constant
+ // positive integer expression.
+ // If no optional parameter is specified, implementation-defined default
+ // alignments for SIMD instructions on the target platforms are assumed.
+ if (Alignment != nullptr) {
+ ExprResult AlignResult =
+ VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
+ if (AlignResult.isInvalid())
+ return nullptr;
+ Alignment = AlignResult.get();
+ }
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
+ EndLoc, Vars, Alignment);
+}
+
OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1651,28 +3482,32 @@
// OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
// A variable of class type (or array thereof) that appears in a
- // copyin clause requires an accesible, unambiguous copy assignment
+ // copyin clause requires an accessible, unambiguous copy assignment
// operator for the class type.
Type = Context.getBaseElementType(Type);
CXXRecordDecl *RD =
getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+ // FIXME This code must be replaced by actual assignment of the
+ // threadprivate variable.
if (RD) {
CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
- if (!MD || CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
- MD->isDeleted()) {
- Diag(ELoc, diag::err_omp_required_method)
- << getOpenMPClauseName(OMPC_copyin) << 2;
- bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(VD->getLocation(),
- IsDecl ? diag::note_previous_decl : diag::note_defined_here)
- << VD;
- Diag(RD->getLocation(), diag::note_previous_decl) << RD;
- continue;
+ if (MD) {
+ if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+ MD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_copyin) << 2;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, MD);
+ DiagnoseUseOfDecl(MD, ELoc);
}
- MarkFunctionReferenced(ELoc, MD);
- DiagnoseUseOfDecl(MD, ELoc);
}
DSAStack->addDSA(VD, DE, OMPC_copyin);
@@ -1685,4 +3520,108 @@
return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
}
+OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ SmallVector<Expr *, 8> Vars;
+ for (auto &RefExpr : VarList) {
+ assert(RefExpr && "NULL expr in OpenMP copyprivate clause.");
+ if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+ // It will be analyzed later.
+ Vars.push_back(RefExpr);
+ continue;
+ }
+
+ SourceLocation ELoc = RefExpr->getExprLoc();
+ // OpenMP [2.1, C/C++]
+ // A list item is a variable name.
+ // OpenMP [2.14.4.1, Restrictions, p.1]
+ // A list item that appears in a copyin clause must be threadprivate.
+ DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+ if (!DE || !isa<VarDecl>(DE->getDecl())) {
+ Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+ continue;
+ }
+
+ Decl *D = DE->getDecl();
+ VarDecl *VD = cast<VarDecl>(D);
+
+ QualType Type = VD->getType();
+ if (Type->isDependentType() || Type->isInstantiationDependentType()) {
+ // It will be analyzed later.
+ Vars.push_back(DE);
+ continue;
+ }
+
+ // OpenMP [2.14.4.2, Restrictions, p.2]
+ // A list item that appears in a copyprivate clause may not appear in a
+ // private or firstprivate clause on the single construct.
+ if (!DSAStack->isThreadPrivate(VD)) {
+ auto DVar = DSAStack->getTopDSA(VD);
+ if (DVar.CKind != OMPC_copyprivate && DVar.CKind != OMPC_unknown &&
+ !(DVar.CKind == OMPC_private && !DVar.RefExpr)) {
+ Diag(ELoc, diag::err_omp_wrong_dsa)
+ << getOpenMPClauseName(DVar.CKind)
+ << getOpenMPClauseName(OMPC_copyprivate);
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+
+ // OpenMP [2.11.4.2, Restrictions, p.1]
+ // All list items that appear in a copyprivate clause must be either
+ // threadprivate or private in the enclosing context.
+ if (DVar.CKind == OMPC_unknown) {
+ DVar = DSAStack->getImplicitDSA(VD);
+ if (DVar.CKind == OMPC_shared) {
+ Diag(ELoc, diag::err_omp_required_access)
+ << getOpenMPClauseName(OMPC_copyprivate)
+ << "threadprivate or private in the enclosing context";
+ ReportOriginalDSA(*this, DSAStack, VD, DVar);
+ continue;
+ }
+ }
+ }
+
+ // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
+ // A variable of class type (or array thereof) that appears in a
+ // copyin clause requires an accessible, unambiguous copy assignment
+ // operator for the class type.
+ Type = Context.getBaseElementType(Type);
+ CXXRecordDecl *RD =
+ getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
+ // FIXME This code must be replaced by actual assignment of the
+ // threadprivate variable.
+ if (RD) {
+ CXXMethodDecl *MD = LookupCopyingAssignment(RD, 0, false, 0);
+ DeclAccessPair FoundDecl = DeclAccessPair::make(MD, MD->getAccess());
+ if (MD) {
+ if (CheckMemberAccess(ELoc, RD, FoundDecl) == AR_inaccessible ||
+ MD->isDeleted()) {
+ Diag(ELoc, diag::err_omp_required_method)
+ << getOpenMPClauseName(OMPC_copyprivate) << 2;
+ bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ Diag(VD->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ << VD;
+ Diag(RD->getLocation(), diag::note_previous_decl) << RD;
+ continue;
+ }
+ MarkFunctionReferenced(ELoc, MD);
+ DiagnoseUseOfDecl(MD, ELoc);
+ }
+ }
+
+ // No need to mark vars as copyprivate, they are already threadprivate or
+ // implicitly private.
+ Vars.push_back(DE);
+ }
+
+ if (Vars.empty())
+ return nullptr;
+
+ return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
+}
+
#undef DSAStack
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 147325b..4eed8c1 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -61,8 +61,8 @@
S.MarkDeclRefReferenced(DRE);
- ExprResult E = S.Owned(DRE);
- E = S.DefaultFunctionArrayConversion(E.take());
+ ExprResult E = DRE;
+ E = S.DefaultFunctionArrayConversion(E.get());
if (E.isInvalid())
return ExprError();
return E;
@@ -851,7 +851,7 @@
if (result.isInvalid())
return true;
- E = result.take();
+ E = result.get();
return false;
}
@@ -4557,7 +4557,7 @@
InitializedEntity Entity =
InitializedEntity::InitializeParameter(S.Context, ToType,
/*Consumed=*/false);
- if (S.CanPerformCopyInitialization(Entity, S.Owned(From))) {
+ if (S.CanPerformCopyInitialization(Entity, From)) {
Result.setUserDefined();
Result.UserDefined.Before.setAsIdentityConversion();
// Initializer lists don't have a type.
@@ -4878,13 +4878,13 @@
PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
if (FromRes.isInvalid())
return ExprError();
- From = FromRes.take();
+ From = FromRes.get();
}
if (!Context.hasSameType(From->getType(), DestType))
From = ImpCastExprToType(From, DestType, CK_NoOp,
- From->getValueKind()).take();
- return Owned(From);
+ From->getValueKind()).get();
+ return From;
}
/// TryContextuallyConvertToBool - Attempt to contextually convert the
@@ -5166,7 +5166,7 @@
QualType ConvTy = Conv->getConversionType().getNonReferenceType();
Converter.noteAmbiguous(SemaRef, Conv, ConvTy);
}
- return SemaRef.Owned(From);
+ return From;
}
static bool
@@ -5299,14 +5299,14 @@
SourceLocation Loc, Expr *From, ContextualImplicitConverter &Converter) {
// We can't perform any more checking for type-dependent expressions.
if (From->isTypeDependent())
- return Owned(From);
+ return From;
// Process placeholders immediately.
if (From->hasPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(From);
if (result.isInvalid())
return result;
- From = result.take();
+ From = result.get();
}
// If the expression already has a matching type, we're golden.
@@ -5322,7 +5322,7 @@
if (!RecordTy || !getLangOpts().CPlusPlus) {
if (!Converter.Suppress)
Converter.diagnoseNoMatch(*this, Loc, T) << From->getSourceRange();
- return Owned(From);
+ return From;
}
// We must have a complete class type.
@@ -5339,7 +5339,7 @@
} IncompleteDiagnoser(Converter, From);
if (RequireCompleteType(Loc, T, IncompleteDiagnoser))
- return Owned(From);
+ return From;
// Look for a conversion to an integral or enumeration type.
UnresolvedSet<4>
@@ -5708,7 +5708,7 @@
InitializationFailed = true;
break;
}
- ConvertedArgs.push_back(R.take());
+ ConvertedArgs.push_back(R.get());
} else {
ExprResult R =
PerformCopyInitialization(InitializedEntity::InitializeParameter(
@@ -5720,7 +5720,7 @@
InitializationFailed = true;
break;
}
- ConvertedArgs.push_back(R.take());
+ ConvertedArgs.push_back(R.get());
}
}
@@ -5732,8 +5732,8 @@
EnableIfAttr *EIA = cast<EnableIfAttr>(*I);
if (!EIA->getCond()->EvaluateWithSubstitution(
Result, Context, Function,
- llvm::ArrayRef<const Expr*>(ConvertedArgs.data(),
- ConvertedArgs.size())) ||
+ ArrayRef<const Expr*>(ConvertedArgs.data(),
+ ConvertedArgs.size())) ||
!Result.isInt() || !Result.getInt().getBoolValue()) {
return EIA;
}
@@ -10153,12 +10153,12 @@
// Fix the expression to refer to 'fn'.
SingleFunctionExpression =
- Owned(FixOverloadedFunctionReference(SrcExpr.take(), found, fn));
+ FixOverloadedFunctionReference(SrcExpr.get(), found, fn);
// If desired, do function-to-pointer decay.
if (doFunctionPointerConverion) {
SingleFunctionExpression =
- DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.take());
+ DefaultFunctionArrayLvalueConversion(SingleFunctionExpression.get());
if (SingleFunctionExpression.isInvalid()) {
SrcExpr = ExprError();
return true;
@@ -10429,7 +10429,7 @@
BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
UnresolvedLookupExpr *ULE,
SourceLocation LParenLoc,
- llvm::MutableArrayRef<Expr *> Args,
+ MutableArrayRef<Expr *> Args,
SourceLocation RParenLoc,
bool EmptyLookup, bool AllowTypoCorrection) {
// Do not try to recover if it is already building a recovery call.
@@ -10490,7 +10490,7 @@
// This shouldn't cause an infinite loop because we're giving it
// an expression with viable lookup results, which should never
// end up here.
- return SemaRef.ActOnCallExpr(/*Scope*/ nullptr, NewFn.take(), LParenLoc,
+ return SemaRef.ActOnCallExpr(/*Scope*/ nullptr, NewFn.get(), LParenLoc,
MultiExprArg(Args.data(), Args.size()),
RParenLoc);
}
@@ -10546,7 +10546,7 @@
Context.DependentTy, VK_RValue,
RParenLoc);
CE->setTypeDependent(true);
- *Result = Owned(CE);
+ *Result = CE;
return true;
}
return false;
@@ -10713,11 +10713,8 @@
if (Input->isTypeDependent()) {
if (Fns.empty())
- return Owned(new (Context) UnaryOperator(Input,
- Opc,
- Context.DependentTy,
- VK_RValue, OK_Ordinary,
- OpLoc));
+ return new (Context) UnaryOperator(Input, Opc, Context.DependentTy,
+ VK_RValue, OK_Ordinary, OpLoc);
CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators
UnresolvedLookupExpr *Fn
@@ -10725,10 +10722,9 @@
NestedNameSpecifierLoc(), OpNameInfo,
/*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
- return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, ArgsArray,
- Context.DependentTy,
- VK_RValue,
- OpLoc, false));
+ return new (Context)
+ CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy,
+ VK_RValue, OpLoc, false);
}
// Build an empty overload set.
@@ -10770,7 +10766,7 @@
Best->FoundDecl, Method);
if (InputRes.isInvalid())
return ExprError();
- Input = InputRes.take();
+ Input = InputRes.get();
} else {
// Convert the arguments.
ExprResult InputInit
@@ -10781,7 +10777,7 @@
Input);
if (InputInit.isInvalid())
return ExprError();
- Input = InputInit.take();
+ Input = InputInit.get();
}
// Build the actual expression node.
@@ -10797,7 +10793,7 @@
Args[0] = Input;
CallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray,
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray,
ResultTy, VK, OpLoc, false);
if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
@@ -10813,7 +10809,7 @@
Best->Conversions[0], AA_Passing);
if (InputRes.isInvalid())
return ExprError();
- Input = InputRes.take();
+ Input = InputRes.get();
break;
}
}
@@ -10892,20 +10888,14 @@
// If there are no functions to store, just build a dependent
// BinaryOperator or CompoundAssignment.
if (Opc <= BO_Assign || Opc > BO_OrAssign)
- return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
- Context.DependentTy,
- VK_RValue, OK_Ordinary,
- OpLoc,
- FPFeatures.fp_contract));
+ return new (Context) BinaryOperator(
+ Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
+ OpLoc, FPFeatures.fp_contract);
- return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc,
- Context.DependentTy,
- VK_LValue,
- OK_Ordinary,
- Context.DependentTy,
- Context.DependentTy,
- OpLoc,
- FPFeatures.fp_contract));
+ return new (Context) CompoundAssignOperator(
+ Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
+ Context.DependentTy, Context.DependentTy, OpLoc,
+ FPFeatures.fp_contract);
}
// FIXME: save results of ADL from here?
@@ -10917,9 +10907,9 @@
NestedNameSpecifierLoc(), OpNameInfo,
/*ADL*/ true, IsOverloaded(Fns),
Fns.begin(), Fns.end());
- return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args,
- Context.DependentTy, VK_RValue,
- OpLoc, FPFeatures.fp_contract));
+ return new (Context)
+ CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy,
+ VK_RValue, OpLoc, FPFeatures.fp_contract);
}
// Always do placeholder-like conversions on the RHS.
@@ -10985,7 +10975,7 @@
PerformCopyInitialization(
InitializedEntity::InitializeParameter(Context,
FnDecl->getParamDecl(0)),
- SourceLocation(), Owned(Args[1]));
+ SourceLocation(), Args[1]);
if (Arg1.isInvalid())
return ExprError();
@@ -10994,14 +10984,14 @@
Best->FoundDecl, Method);
if (Arg0.isInvalid())
return ExprError();
- Args[0] = Arg0.takeAs<Expr>();
- Args[1] = RHS = Arg1.takeAs<Expr>();
+ Args[0] = Arg0.getAs<Expr>();
+ Args[1] = RHS = Arg1.getAs<Expr>();
} else {
// Convert the arguments.
ExprResult Arg0 = PerformCopyInitialization(
InitializedEntity::InitializeParameter(Context,
FnDecl->getParamDecl(0)),
- SourceLocation(), Owned(Args[0]));
+ SourceLocation(), Args[0]);
if (Arg0.isInvalid())
return ExprError();
@@ -11009,11 +10999,11 @@
PerformCopyInitialization(
InitializedEntity::InitializeParameter(Context,
FnDecl->getParamDecl(1)),
- SourceLocation(), Owned(Args[1]));
+ SourceLocation(), Args[1]);
if (Arg1.isInvalid())
return ExprError();
- Args[0] = LHS = Arg0.takeAs<Expr>();
- Args[1] = RHS = Arg1.takeAs<Expr>();
+ Args[0] = LHS = Arg0.getAs<Expr>();
+ Args[1] = RHS = Arg1.getAs<Expr>();
}
// Build the actual expression node.
@@ -11029,7 +11019,7 @@
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(),
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(),
Args, ResultTy, VK, OpLoc,
FPFeatures.fp_contract);
@@ -11054,14 +11044,14 @@
Best->Conversions[0], AA_Passing);
if (ArgsRes0.isInvalid())
return ExprError();
- Args[0] = ArgsRes0.take();
+ Args[0] = ArgsRes0.get();
ExprResult ArgsRes1 =
PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], AA_Passing);
if (ArgsRes1.isInvalid())
return ExprError();
- Args[1] = ArgsRes1.take();
+ Args[1] = ArgsRes1.get();
break;
}
}
@@ -11168,11 +11158,9 @@
UnresolvedSetIterator());
// Can't add any actual overloads yet
- return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
- Args,
- Context.DependentTy,
- VK_RValue,
- RLoc, false));
+ return new (Context)
+ CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args,
+ Context.DependentTy, VK_RValue, RLoc, false);
}
// Handle placeholders on both operands.
@@ -11214,7 +11202,7 @@
Best->FoundDecl, Method);
if (Arg0.isInvalid())
return ExprError();
- Args[0] = Arg0.take();
+ Args[0] = Arg0.get();
// Convert the arguments.
ExprResult InputInit
@@ -11222,11 +11210,11 @@
Context,
FnDecl->getParamDecl(0)),
SourceLocation(),
- Owned(Args[1]));
+ Args[1]);
if (InputInit.isInvalid())
return ExprError();
- Args[1] = InputInit.takeAs<Expr>();
+ Args[1] = InputInit.getAs<Expr>();
// Build the actual expression node.
DeclarationNameInfo OpLocInfo(OpName, LLoc);
@@ -11246,7 +11234,7 @@
CXXOperatorCallExpr *TheCall =
new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
- FnExpr.take(), Args,
+ FnExpr.get(), Args,
ResultTy, VK, RLoc,
false);
@@ -11263,14 +11251,14 @@
Best->Conversions[0], AA_Passing);
if (ArgsRes0.isInvalid())
return ExprError();
- Args[0] = ArgsRes0.take();
+ Args[0] = ArgsRes0.get();
ExprResult ArgsRes1 =
PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], AA_Passing);
if (ArgsRes1.isInvalid())
return ExprError();
- Args[1] = ArgsRes1.take();
+ Args[1] = ArgsRes1.get();
break;
}
@@ -11531,7 +11519,7 @@
FoundDecl, Method);
if (ObjectArg.isInvalid())
return ExprError();
- MemExpr->setBase(ObjectArg.take());
+ MemExpr->setBase(ObjectArg.get());
}
// Convert the rest of the arguments
@@ -11574,7 +11562,7 @@
SourceLocation RParenLoc) {
if (checkPlaceholderForOverload(*this, Obj))
return ExprError();
- ExprResult Object = Owned(Obj);
+ ExprResult Object = Obj;
UnbridgedCastsSet UnbridgedCasts;
if (checkArgPlaceholdersForOverload(*this, Args, UnbridgedCasts))
@@ -11728,9 +11716,9 @@
if (Call.isInvalid())
return ExprError();
// Record usage of conversion in an implicit cast.
- Call = Owned(ImplicitCastExpr::Create(Context, Call.get()->getType(),
- CK_UserDefinedConversion,
- Call.get(), nullptr, VK_RValue));
+ Call = ImplicitCastExpr::Create(Context, Call.get()->getType(),
+ CK_UserDefinedConversion, Call.get(),
+ nullptr, VK_RValue);
return ActOnCallExpr(S, Call.get(), LParenLoc, Args, RParenLoc);
}
@@ -11774,7 +11762,7 @@
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall = new (Context)
- CXXOperatorCallExpr(Context, OO_Call, NewFn.take(),
+ CXXOperatorCallExpr(Context, OO_Call, NewFn.get(),
llvm::makeArrayRef(MethodArgs.get(), Args.size() + 1),
ResultTy, VK, RParenLoc, false);
MethodArgs.reset();
@@ -11797,7 +11785,7 @@
IsError = true;
else
Object = ObjRes;
- TheCall->setArg(0, Object.take());
+ TheCall->setArg(0, Object.get());
// Check the argument types.
for (unsigned i = 0; i != NumParams; i++) {
@@ -11814,7 +11802,7 @@
SourceLocation(), Arg);
IsError |= InputInit.isInvalid();
- Arg = InputInit.takeAs<Expr>();
+ Arg = InputInit.getAs<Expr>();
} else {
ExprResult DefArg
= BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
@@ -11823,7 +11811,7 @@
break;
}
- Arg = DefArg.takeAs<Expr>();
+ Arg = DefArg.getAs<Expr>();
}
TheCall->setArg(i + 1, Arg);
@@ -11836,7 +11824,7 @@
ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], VariadicMethod,
nullptr);
IsError |= Arg.isInvalid();
- TheCall->setArg(i + 1, Arg.take());
+ TheCall->setArg(i + 1, Arg.get());
}
}
@@ -11944,7 +11932,7 @@
Best->FoundDecl, Method);
if (BaseResult.isInvalid())
return ExprError();
- Base = BaseResult.take();
+ Base = BaseResult.get();
// Build the operator call.
ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, Best->FoundDecl,
@@ -11956,7 +11944,7 @@
ExprValueKind VK = Expr::getValueKindForType(ResultTy);
ResultTy = ResultTy.getNonLValueExprType(Context);
CXXOperatorCallExpr *TheCall =
- new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.take(),
+ new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(),
Base, ResultTy, VK, OpLoc, false);
if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
@@ -12018,7 +12006,7 @@
SourceLocation(), Args[ArgIdx]);
if (InputInit.isInvalid())
return true;
- ConvArgs[ArgIdx] = InputInit.take();
+ ConvArgs[ArgIdx] = InputInit.get();
}
QualType ResultTy = FD->getReturnType();
@@ -12026,7 +12014,7 @@
ResultTy = ResultTy.getNonLValueExprType(Context);
UserDefinedLiteral *UDL =
- new (Context) UserDefinedLiteral(Context, Fn.take(),
+ new (Context) UserDefinedLiteral(Context, Fn.get(),
llvm::makeArrayRef(ConvArgs, Args.size()),
ResultTy, VK, LitEndLoc, UDSuffixLoc);
@@ -12282,7 +12270,7 @@
ExprResult Sema::FixOverloadedFunctionReference(ExprResult E,
DeclAccessPair Found,
FunctionDecl *Fn) {
- return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
+ return FixOverloadedFunctionReference(E.get(), Found, Fn);
}
} // end namespace clang
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index 94b1943..c8d34f8 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -284,6 +284,7 @@
bool tryBuildGetOfReference(Expr *op, ExprResult &result);
bool findSetter(bool warn=true);
bool findGetter();
+ bool DiagnoseUnsupportedPropertyUse();
Expr *rebuildAndCaptureObject(Expr *syntacticBase) override;
ExprResult buildGet() override;
@@ -393,7 +394,7 @@
ExprResult getExpr = buildGet();
if (getExpr.isInvalid()) return ExprError();
- addResultSemanticExpr(getExpr.take());
+ addResultSemanticExpr(getExpr.get());
return complete(syntacticBase);
}
@@ -426,7 +427,7 @@
BinaryOperatorKind nonCompound =
BinaryOperator::getOpForCompoundAssignment(opcode);
result = S.BuildBinOp(Sc, opcLoc, nonCompound,
- opLHS.take(), capturedRHS);
+ opLHS.get(), capturedRHS);
if (result.isInvalid()) return ExprError();
syntactic =
@@ -441,9 +442,9 @@
// The result of the assignment, if not void, is the value set into
// the l-value.
- result = buildSet(result.take(), opcLoc, /*captureSetValueAsResult*/ true);
+ result = buildSet(result.get(), opcLoc, /*captureSetValueAsResult*/ true);
if (result.isInvalid()) return ExprError();
- addSemanticExpr(result.take());
+ addSemanticExpr(result.get());
return complete(syntactic);
}
@@ -467,7 +468,7 @@
// That's the postfix result.
if (UnaryOperator::isPostfix(opcode) &&
(result.get()->isTypeDependent() || CanCaptureValue(result.get()))) {
- result = capture(result.take());
+ result = capture(result.get());
setResultToLastSemantic();
}
@@ -477,17 +478,17 @@
GenericLoc);
if (UnaryOperator::isIncrementOp(opcode)) {
- result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.take(), one);
+ result = S.BuildBinOp(Sc, opcLoc, BO_Add, result.get(), one);
} else {
- result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.take(), one);
+ result = S.BuildBinOp(Sc, opcLoc, BO_Sub, result.get(), one);
}
if (result.isInvalid()) return ExprError();
// Store that back into the result. The value stored is the result
// of a prefix operation.
- result = buildSet(result.take(), opcLoc, UnaryOperator::isPrefix(opcode));
+ result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode));
if (result.isInvalid()) return ExprError();
- addSemanticExpr(result.take());
+ addSemanticExpr(result.get());
UnaryOperator *syntactic =
new (S.Context) UnaryOperator(syntacticOp, opcode, resultType,
@@ -541,7 +542,7 @@
if (RefExpr->isExplicitProperty()) {
const ObjCPropertyDecl *Prop = RefExpr->getExplicitProperty();
if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
- return true;
+ return !Prop->hasAttr<IBOutletAttr>();
T = Prop->getType();
} else if (Getter) {
@@ -568,13 +569,11 @@
assert(setter && "both setter and getter are null - cannot happen");
IdentifierInfo *setterName =
setter->getSelector().getIdentifierInfoForSlot(0);
- const char *compStr = setterName->getNameStart();
- compStr += 3;
- IdentifierInfo *getterName = &S.Context.Idents.get(compStr);
+ IdentifierInfo *getterName =
+ &S.Context.Idents.get(setterName->getName().substr(3));
GetterSelector =
S.PP.getSelectorTable().getNullarySelector(getterName);
return false;
-
}
}
@@ -643,6 +642,20 @@
return false;
}
+bool ObjCPropertyOpBuilder::DiagnoseUnsupportedPropertyUse() {
+ if (S.getCurLexicalContext()->isObjCContainer() &&
+ S.getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl &&
+ S.getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) {
+ if (ObjCPropertyDecl *prop = RefExpr->getExplicitProperty()) {
+ S.Diag(RefExpr->getLocation(),
+ diag::err_property_function_in_objc_container);
+ S.Diag(prop->getLocation(), diag::note_property_declare);
+ return true;
+ }
+ }
+ return false;
+}
+
/// Capture the base object of an Objective-C property expression.
Expr *ObjCPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
assert(InstanceReceiver == nullptr);
@@ -666,6 +679,9 @@
/// Load from an Objective-C property reference.
ExprResult ObjCPropertyOpBuilder::buildGet() {
findGetter();
+ if (!Getter && DiagnoseUnsupportedPropertyUse())
+ return ExprError();
+
assert(Getter);
if (SyntacticRefExpr)
@@ -680,7 +696,8 @@
assert(InstanceReceiver);
receiverType = InstanceReceiver->getType();
}
-
+ if (!Getter->isImplicit())
+ S.DiagnoseUseOfDecl(Getter, GenericLoc, nullptr, true);
// Build a message-send.
ExprResult msg;
if ((Getter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
@@ -704,6 +721,8 @@
ExprResult ObjCPropertyOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
bool captureSetValueAsResult) {
bool hasSetter = findSetter(false);
+ if (!hasSetter && DiagnoseUnsupportedPropertyUse())
+ return ExprError();
assert(hasSetter); (void) hasSetter;
if (SyntacticRefExpr)
@@ -733,7 +752,7 @@
Sema::AA_Assigning))
return ExprError();
- op = opResult.take();
+ op = opResult.get();
assert(op && "successful assignment left argument invalid?");
}
else if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(op)) {
@@ -753,6 +772,8 @@
// Build a message-send.
ExprResult msg;
+ if (!Setter->isImplicit())
+ S.DiagnoseUseOfDecl(Setter, GenericLoc, nullptr, true);
if ((Setter->isInstanceMethod() && !RefExpr->isClassReceiver()) ||
RefExpr->isObjectReceiver()) {
msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
@@ -795,13 +816,20 @@
// As a special case, if the method returns 'id', try to get
// a better type from the property.
- if (RefExpr->isExplicitProperty() && result.get()->isRValue() &&
- result.get()->getType()->isObjCIdType()) {
+ if (RefExpr->isExplicitProperty() && result.get()->isRValue()) {
QualType propType = RefExpr->getExplicitProperty()->getType();
- if (const ObjCObjectPointerType *ptr
- = propType->getAs<ObjCObjectPointerType>()) {
- if (!ptr->isObjCIdType())
- result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+ if (result.get()->getType()->isObjCIdType()) {
+ if (const ObjCObjectPointerType *ptr
+ = propType->getAs<ObjCObjectPointerType>()) {
+ if (!ptr->isObjCIdType())
+ result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
+ }
+ }
+ if (S.getLangOpts().ObjCAutoRefCount) {
+ Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
+ if (LT == Qualifiers::OCL_Weak)
+ if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
+ S.getCurFunction()->markSafeWeakUse(RefExpr);
}
}
@@ -841,7 +869,7 @@
ExprResult result;
if (tryBuildGetOfReference(LHS, result)) {
if (result.isInvalid()) return ExprError();
- return S.BuildBinOp(Sc, opcLoc, opcode, result.take(), RHS);
+ return S.BuildBinOp(Sc, opcLoc, opcode, result.get(), RHS);
}
// Otherwise, it's an error.
@@ -885,7 +913,7 @@
ExprResult result;
if (tryBuildGetOfReference(op, result)) {
if (result.isInvalid()) return ExprError();
- return S.BuildUnaryOp(Sc, opcLoc, opcode, result.take());
+ return S.BuildUnaryOp(Sc, opcLoc, opcode, result.get());
}
// Otherwise, it's an error.
@@ -913,14 +941,11 @@
}
ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
- if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty()) {
- DiagnosticsEngine::Level Level =
- S.Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak,
- SyntacticForm->getLocStart());
- if (Level != DiagnosticsEngine::Ignored)
+ if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
+ !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+ SyntacticForm->getLocStart()))
S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
SyntacticRefExpr->isMessagingGetter());
- }
return PseudoOpBuilder::complete(SyntacticForm);
}
@@ -1074,7 +1099,7 @@
true /*instance*/);
if (!Getter)
return;
- QualType T = Getter->param_begin()[0]->getType();
+ QualType T = Getter->parameters()[0]->getType();
S.CheckObjCARCConversion(Key->getSourceRange(),
T, Key, Sema::CCK_ImplicitConversion);
}
@@ -1167,13 +1192,13 @@
}
if (AtIndexGetter) {
- QualType T = AtIndexGetter->param_begin()[0]->getType();
+ QualType T = AtIndexGetter->parameters()[0]->getType();
if ((arrayRef && !T->isIntegralOrEnumerationType()) ||
(!arrayRef && !T->isObjCObjectPointerType())) {
S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
arrayRef ? diag::err_objc_subscript_index_type
: diag::err_objc_subscript_key_type) << T;
- S.Diag(AtIndexGetter->param_begin()[0]->getLocation(),
+ S.Diag(AtIndexGetter->parameters()[0]->getLocation(),
diag::note_parameter_type) << T;
return false;
}
@@ -1290,26 +1315,26 @@
bool err = false;
if (AtIndexSetter && arrayRef) {
- QualType T = AtIndexSetter->param_begin()[1]->getType();
+ QualType T = AtIndexSetter->parameters()[1]->getType();
if (!T->isIntegralOrEnumerationType()) {
S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
diag::err_objc_subscript_index_type) << T;
- S.Diag(AtIndexSetter->param_begin()[1]->getLocation(),
+ S.Diag(AtIndexSetter->parameters()[1]->getLocation(),
diag::note_parameter_type) << T;
err = true;
}
- T = AtIndexSetter->param_begin()[0]->getType();
+ T = AtIndexSetter->parameters()[0]->getType();
if (!T->isObjCObjectPointerType()) {
S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
diag::err_objc_subscript_object_type) << T << arrayRef;
- S.Diag(AtIndexSetter->param_begin()[0]->getLocation(),
+ S.Diag(AtIndexSetter->parameters()[0]->getLocation(),
diag::note_parameter_type) << T;
err = true;
}
}
else if (AtIndexSetter && !arrayRef)
for (unsigned i=0; i <2; i++) {
- QualType T = AtIndexSetter->param_begin()[i]->getType();
+ QualType T = AtIndexSetter->parameters()[i]->getType();
if (!T->isObjCObjectPointerType()) {
if (i == 1)
S.Diag(RefExpr->getKeyExpr()->getExprLoc(),
@@ -1317,7 +1342,7 @@
else
S.Diag(RefExpr->getBaseExpr()->getExprLoc(),
diag::err_objc_subscript_dic_object_type) << T;
- S.Diag(AtIndexSetter->param_begin()[i]->getLocation(),
+ S.Diag(AtIndexSetter->parameters()[i]->getLocation(),
diag::note_parameter_type) << T;
err = true;
}
@@ -1341,6 +1366,8 @@
// Arguments.
Expr *args[] = { Index };
assert(InstanceBase);
+ if (AtIndexGetter)
+ S.DiagnoseUseOfDecl(AtIndexGetter, GenericLoc);
msg = S.BuildInstanceMessageImplicit(InstanceBase, receiverType,
GenericLoc,
AtIndexGetterSelector, AtIndexGetter,
@@ -1357,7 +1384,8 @@
bool captureSetValueAsResult) {
if (!findAtIndexSetter())
return ExprError();
-
+ if (AtIndexSetter)
+ S.DiagnoseUseOfDecl(AtIndexSetter, GenericLoc);
QualType receiverType = InstanceBase->getType();
Expr *Index = InstanceKey;
@@ -1419,7 +1447,7 @@
}
MultiExprArg ArgExprs;
- return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
+ return S.ActOnCallExpr(S.getCurScope(), GetterExpr.get(),
RefExpr->getSourceRange().getBegin(), ArgExprs,
RefExpr->getSourceRange().getEnd());
}
@@ -1450,7 +1478,7 @@
SmallVector<Expr*, 1> ArgExprs;
ArgExprs.push_back(op);
- return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
+ return S.ActOnCallExpr(S.getCurScope(), SetterExpr.get(),
RefExpr->getSourceRange().getBegin(), ArgExprs,
op->getSourceRange().getEnd());
}
@@ -1517,7 +1545,7 @@
if (RHS->getType()->isNonOverloadPlaceholderType()) {
ExprResult result = CheckPlaceholderExpr(RHS);
if (result.isInvalid()) return ExprError();
- RHS = result.take();
+ RHS = result.get();
}
Expr *opaqueRef = LHS->IgnoreParens();
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 7d568ee..dc5619d 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -49,7 +49,7 @@
// operand, even incomplete types.
// Same thing in for stmt first clause (when expr) and third clause.
- return Owned(static_cast<Stmt*>(FE.take()));
+ return StmtResult(FE.getAs<Stmt>());
}
@@ -60,7 +60,7 @@
StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
bool HasLeadingEmptyMacro) {
- return Owned(new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro));
+ return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);
}
StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
@@ -70,7 +70,7 @@
// If we have an invalid decl, just return an error.
if (DG.isNull()) return StmtError();
- return Owned(new (Context) DeclStmt(DG, StartLoc, EndLoc));
+ return new (Context) DeclStmt(DG, StartLoc, EndLoc);
}
void Sema::ActOnForEachDeclStmt(DeclGroupPtrTy dg) {
@@ -344,7 +344,7 @@
DiagnoseEmptyLoopBody(Elts[i], Elts[i + 1]);
}
- return Owned(new (Context) CompoundStmt(Context, Elts, L, R));
+ return new (Context) CompoundStmt(Context, Elts, L, R);
}
StmtResult
@@ -362,7 +362,7 @@
// C99 6.8.4.2p3: The expression shall be an integer constant.
// However, GCC allows any evaluatable integer expression.
if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent()) {
- LHSVal = VerifyIntegerConstantExpression(LHSVal).take();
+ LHSVal = VerifyIntegerConstantExpression(LHSVal).get();
if (!LHSVal)
return StmtError();
}
@@ -370,21 +370,21 @@
// GCC extension: The expression shall be an integer constant.
if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent()) {
- RHSVal = VerifyIntegerConstantExpression(RHSVal).take();
+ RHSVal = VerifyIntegerConstantExpression(RHSVal).get();
// Recover from an error by just forgetting about it.
}
}
LHSVal = ActOnFinishFullExpr(LHSVal, LHSVal->getExprLoc(), false,
- getLangOpts().CPlusPlus11).take();
+ getLangOpts().CPlusPlus11).get();
if (RHSVal)
RHSVal = ActOnFinishFullExpr(RHSVal, RHSVal->getExprLoc(), false,
- getLangOpts().CPlusPlus11).take();
+ getLangOpts().CPlusPlus11).get();
CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
ColonLoc);
getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
- return Owned(CS);
+ return CS;
}
/// ActOnCaseStmtBody - This installs a statement as the body of a case.
@@ -402,12 +402,12 @@
if (getCurFunction()->SwitchStack.empty()) {
Diag(DefaultLoc, diag::err_default_not_in_switch);
- return Owned(SubStmt);
+ return SubStmt;
}
DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
- return Owned(DS);
+ return DS;
}
StmtResult
@@ -417,7 +417,7 @@
if (TheDecl->getStmt()) {
Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
Diag(TheDecl->getLocation(), diag::note_previous_definition);
- return Owned(SubStmt);
+ return SubStmt;
}
// Otherwise, things are good. Fill in the declaration and return it.
@@ -427,7 +427,7 @@
TheDecl->setLocStart(IdentLoc);
TheDecl->setLocation(IdentLoc);
}
- return Owned(LS);
+ return LS;
}
StmtResult Sema::ActOnAttributedStmt(SourceLocation AttrLoc,
@@ -435,7 +435,7 @@
Stmt *SubStmt) {
// Fill in the declaration and return it.
AttributedStmt *LS = AttributedStmt::Create(Context, AttrLoc, Attrs, SubStmt);
- return Owned(LS);
+ return LS;
}
StmtResult
@@ -458,7 +458,7 @@
if (CondResult.isInvalid())
return StmtError();
}
- Expr *ConditionExpr = CondResult.takeAs<Expr>();
+ Expr *ConditionExpr = CondResult.getAs<Expr>();
if (!ConditionExpr)
return StmtError();
@@ -471,8 +471,8 @@
DiagnoseUnusedExprResult(elseStmt);
- return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
- thenStmt, ElseLoc, elseStmt));
+ return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
+ thenStmt, ElseLoc, elseStmt);
}
/// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
@@ -587,7 +587,7 @@
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.release();
+ Cond = CondResult.get();
}
if (!Cond)
@@ -643,25 +643,25 @@
CondResult =
PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
if (CondResult.isInvalid()) return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
// C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
CondResult = UsualUnaryConversions(Cond);
if (CondResult.isInvalid()) return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
if (!CondVar) {
CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
}
getCurFunction()->setHasBranchIntoScope();
SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
getCurFunction()->SwitchStack.push_back(SS);
- return Owned(SS);
+ return SS;
}
static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
@@ -798,7 +798,7 @@
CaseListIsErroneous = true;
continue;
}
- Lo = ConvLo.take();
+ Lo = ConvLo.get();
} else {
// We already verified that the expression has a i-c-e value (C99
// 6.8.4.2p3) - get that value now.
@@ -806,8 +806,8 @@
// If the LHS is not the same type as the condition, insert an implicit
// cast.
- Lo = DefaultLvalueConversion(Lo).take();
- Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take();
+ Lo = DefaultLvalueConversion(Lo).get();
+ Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).get();
}
// Convert the value to the same width/sign as the condition had prior to
@@ -919,14 +919,14 @@
CaseListIsErroneous = true;
continue;
}
- Hi = ConvHi.take();
+ Hi = ConvHi.get();
} else {
HiVal = Hi->EvaluateKnownConstInt(Context);
// If the RHS is not the same type as the condition, insert an
// implicit cast.
- Hi = DefaultLvalueConversion(Hi).take();
- Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take();
+ Hi = DefaultLvalueConversion(Hi).get();
+ Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).get();
}
// Convert the value to the same width/sign as the condition.
@@ -1151,15 +1151,13 @@
if (CaseListIsErroneous)
return StmtError();
- return Owned(SS);
+ return SS;
}
void
Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
Expr *SrcExpr) {
- if (Diags.getDiagnosticLevel(diag::warn_not_in_enum_assignment,
- SrcExpr->getExprLoc()) ==
- DiagnosticsEngine::Ignored)
+ if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))
return;
if (const EnumType *ET = DstType->getAs<EnumType>())
@@ -1215,7 +1213,7 @@
if (CondResult.isInvalid())
return StmtError();
}
- Expr *ConditionExpr = CondResult.take();
+ Expr *ConditionExpr = CondResult.get();
if (!ConditionExpr)
return StmtError();
CheckBreakContinueBinding(ConditionExpr);
@@ -1225,8 +1223,8 @@
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
- return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
- Body, WhileLoc));
+ return new (Context)
+ WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
}
StmtResult
@@ -1239,16 +1237,16 @@
ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
CondResult = ActOnFinishFullExpr(Cond, DoLoc);
if (CondResult.isInvalid())
return StmtError();
- Cond = CondResult.take();
+ Cond = CondResult.get();
DiagnoseUnusedExprResult(Body);
- return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
+ return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
}
namespace {
@@ -1406,9 +1404,8 @@
// Condition is empty
if (!Second) return;
- if (S.Diags.getDiagnosticLevel(diag::warn_variables_not_in_loop_body,
- Second->getLocStart())
- == DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,
+ Second->getLocStart()))
return;
PartialDiagnostic PDiag = S.PDiag(diag::warn_variables_not_in_loop_body);
@@ -1535,9 +1532,8 @@
// Return when there is nothing to check.
if (!Body || !Third) return;
- if (S.Diags.getDiagnosticLevel(diag::warn_redundant_loop_iteration,
- Third->getLocStart())
- == DiagnosticsEngine::Ignored)
+ if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,
+ Third->getLocStart()))
return;
// Get the last statement from the loop body.
@@ -1623,7 +1619,7 @@
return StmtError();
}
- Expr *Third = third.release().takeAs<Expr>();
+ Expr *Third = third.release().getAs<Expr>();
DiagnoseUnusedExprResult(First);
DiagnoseUnusedExprResult(Third);
@@ -1632,10 +1628,8 @@
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
- return Owned(new (Context) ForStmt(Context, First,
- SecondResult.take(), ConditionVar,
- Third, Body, ForLoc, LParenLoc,
- RParenLoc));
+ return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
+ Third, Body, ForLoc, LParenLoc, RParenLoc);
}
/// In an Objective C collection iteration statement:
@@ -1647,12 +1641,12 @@
// use of pseudo-object l-values in this position.
ExprResult result = CheckPlaceholderExpr(E);
if (result.isInvalid()) return StmtError();
- E = result.take();
+ E = result.get();
ExprResult FullExpr = ActOnFinishFullExpr(E);
if (FullExpr.isInvalid())
return StmtError();
- return StmtResult(static_cast<Stmt*>(FullExpr.take()));
+ return StmtResult(static_cast<Stmt*>(FullExpr.get()));
}
ExprResult
@@ -1661,13 +1655,13 @@
return ExprError();
// Bail out early if we've got a type-dependent expression.
- if (collection->isTypeDependent()) return Owned(collection);
+ if (collection->isTypeDependent()) return collection;
// Perform normal l-value conversion.
ExprResult result = DefaultFunctionArrayLvalueConversion(collection);
if (result.isInvalid())
return ExprError();
- collection = result.take();
+ collection = result.get();
// The operand needs to have object-pointer type.
// TODO: should we do a contextual conversion?
@@ -1723,7 +1717,7 @@
}
// Wrap up any cleanups in the expression.
- return Owned(collection);
+ return collection;
}
StmtResult
@@ -1798,13 +1792,12 @@
if (CollectionExprResult.isInvalid())
return StmtError();
- CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.take());
+ CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
if (CollectionExprResult.isInvalid())
return StmtError();
- return Owned(new (Context) ObjCForCollectionStmt(First,
- CollectionExprResult.take(),
- nullptr, ForLoc, RParenLoc));
+ return new (Context) ObjCForCollectionStmt(First, CollectionExprResult.get(),
+ nullptr, ForLoc, RParenLoc);
}
/// Finish building a variable declaration for a for-range statement.
@@ -1941,7 +1934,7 @@
// Claim the type doesn't contain auto: we've already done the checking.
DeclGroupPtrTy RangeGroup =
- BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
+ BuildDeclaratorGroup(MutableArrayRef<Decl *>((Decl **)&RangeVar, 1),
/*TypeMayContainAuto=*/ false);
StmtResult RangeDecl = ActOnDeclStmt(RangeGroup, RangeLoc, RangeLoc);
if (RangeDecl.isInvalid()) {
@@ -2173,9 +2166,8 @@
// Find the array bound.
ExprResult BoundExpr;
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(UnqAT))
- BoundExpr = Owned(IntegerLiteral::Create(Context, CAT->getSize(),
- Context.getPointerDiffType(),
- RangeLoc));
+ BoundExpr = IntegerLiteral::Create(
+ Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
else if (const VariableArrayType *VAT =
dyn_cast<VariableArrayType>(UnqAT))
BoundExpr = VAT->getSizeExpr();
@@ -2259,7 +2251,7 @@
Decl *BeginEndDecls[] = { BeginVar, EndVar };
// Claim the type doesn't contain auto: we've already done the checking.
DeclGroupPtrTy BeginEndGroup =
- BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *>(BeginEndDecls, 2),
+ BuildDeclaratorGroup(MutableArrayRef<Decl *>(BeginEndDecls, 2),
/*TypeMayContainAuto=*/ false);
BeginEndDecl = ActOnDeclStmt(BeginEndGroup, ColonLoc, ColonLoc);
@@ -2332,11 +2324,9 @@
if (Kind == BFRK_Check)
return StmtResult();
- return Owned(new (Context) CXXForRangeStmt(RangeDS,
- cast_or_null<DeclStmt>(BeginEndDecl.get()),
- NotEqExpr.take(), IncrExpr.take(),
- LoopVarDS, /*Body=*/nullptr,
- ForLoc, ColonLoc, RParenLoc));
+ return new (Context) CXXForRangeStmt(
+ RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(),
+ IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc);
}
/// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach
@@ -2375,7 +2365,7 @@
LabelDecl *TheDecl) {
getCurFunction()->setHasBranchIntoScope();
TheDecl->markUsed(Context);
- return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));
+ return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
}
StmtResult
@@ -2385,12 +2375,12 @@
if (!E->isTypeDependent()) {
QualType ETy = E->getType();
QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
- ExprResult ExprRes = Owned(E);
+ ExprResult ExprRes = E;
AssignConvertType ConvTy =
CheckSingleAssignmentConstraints(DestTy, ExprRes);
if (ExprRes.isInvalid())
return StmtError();
- E = ExprRes.take();
+ E = ExprRes.get();
if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
return StmtError();
}
@@ -2398,11 +2388,11 @@
ExprResult ExprRes = ActOnFinishFullExpr(E);
if (ExprRes.isInvalid())
return StmtError();
- E = ExprRes.take();
+ E = ExprRes.get();
getCurFunction()->setHasIndirectGoto();
- return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
+ return new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E);
}
StmtResult
@@ -2413,7 +2403,7 @@
return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
}
- return Owned(new (Context) ContinueStmt(ContinueLoc));
+ return new (Context) ContinueStmt(ContinueLoc);
}
StmtResult
@@ -2423,8 +2413,11 @@
// C99 6.8.6.3p1: A break shall appear only in or as a switch/loop body.
return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
}
+ if (S->isOpenMPLoopScope())
+ return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
+ << "break");
- return Owned(new (Context) BreakStmt(BreakLoc));
+ return new (Context) BreakStmt(BreakLoc);
}
/// \brief Determine whether the given expression is a candidate for
@@ -2620,7 +2613,7 @@
ExprResult Result = DefaultFunctionArrayLvalueConversion(RetValExp);
if (Result.isInvalid())
return StmtError();
- RetValExp = Result.take();
+ RetValExp = Result.get();
if (!CurContext->isDependentContext())
FnRetType = RetValExp->getType();
@@ -2704,7 +2697,7 @@
// FIXME: Cleanup temporaries here, anyway?
return StmtError();
}
- RetValExp = Res.take();
+ RetValExp = Res.get();
CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
} else {
NRVOCandidate = getCopyElisionCandidate(FnRetType, RetValExp, false);
@@ -2714,7 +2707,7 @@
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
- RetValExp = ER.take();
+ RetValExp = ER.get();
}
ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
NRVOCandidate);
@@ -2725,7 +2718,7 @@
if (CurCap->HasImplicitReturnType || NRVOCandidate)
FunctionScopes.back()->Returns.push_back(Result);
- return Owned(Result);
+ return Result;
}
/// Deduce the return type for a function from a returned expression, per
@@ -2921,13 +2914,13 @@
D = diag::ext_return_has_void_expr;
}
else {
- ExprResult Result = Owned(RetValExp);
- Result = IgnoredValueConversions(Result.take());
+ ExprResult Result = RetValExp;
+ Result = IgnoredValueConversions(Result.get());
if (Result.isInvalid())
return StmtError();
- RetValExp = Result.take();
+ RetValExp = Result.get();
RetValExp = ImpCastExprToType(RetValExp,
- Context.VoidTy, CK_ToVoid).take();
+ Context.VoidTy, CK_ToVoid).get();
}
// return of void in constructor/destructor is illegal in C++.
if (D == diag::err_ctor_dtor_returns_void) {
@@ -2959,7 +2952,7 @@
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
- RetValExp = ER.take();
+ RetValExp = ER.get();
}
}
@@ -2999,7 +2992,7 @@
// FIXME: Clean up temporaries here anyway?
return StmtError();
}
- RetValExp = Res.takeAs<Expr>();
+ RetValExp = Res.getAs<Expr>();
// If we have a related result type, we need to implicitly
// convert back to the formal result type. We can't pretend to
@@ -3013,7 +3006,7 @@
// FIXME: Clean up temporaries here anyway?
return StmtError();
}
- RetValExp = Res.takeAs<Expr>();
+ RetValExp = Res.getAs<Expr>();
}
CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
@@ -3024,7 +3017,7 @@
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
- RetValExp = ER.take();
+ RetValExp = ER.get();
}
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
}
@@ -3034,7 +3027,7 @@
if (Result->getNRVOCandidate())
FunctionScopes.back()->Returns.push_back(Result);
- return Owned(Result);
+ return Result;
}
StmtResult
@@ -3045,12 +3038,12 @@
if (Var && Var->isInvalidDecl())
return StmtError();
- return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
+ return new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body);
}
StmtResult
Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
- return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
+ return new (Context) ObjCAtFinallyStmt(AtLoc, Body);
}
StmtResult
@@ -3061,10 +3054,8 @@
getCurFunction()->setHasBranchProtectedScope();
unsigned NumCatchStmts = CatchStmts.size();
- return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
- CatchStmts.data(),
- NumCatchStmts,
- Finally));
+ return ObjCAtTryStmt::Create(Context, AtLoc, Try, CatchStmts.data(),
+ NumCatchStmts, Finally);
}
StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
@@ -3073,10 +3064,10 @@
if (Result.isInvalid())
return StmtError();
- Result = ActOnFinishFullExpr(Result.take());
+ Result = ActOnFinishFullExpr(Result.get());
if (Result.isInvalid())
return StmtError();
- Throw = Result.take();
+ Throw = Result.get();
QualType ThrowType = Throw->getType();
// Make sure the expression type is an ObjC pointer or "void *".
@@ -3089,7 +3080,7 @@
}
}
- return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
+ return new (Context) ObjCAtThrowStmt(AtLoc, Throw);
}
StmtResult
@@ -3115,7 +3106,7 @@
ExprResult result = DefaultLvalueConversion(operand);
if (result.isInvalid())
return ExprError();
- operand = result.take();
+ operand = result.get();
// Make sure the expression type is an ObjC pointer or "void *".
QualType type = operand->getType();
@@ -3136,7 +3127,7 @@
Stmt *SyncBody) {
// We can't jump into or indirect-jump out of a @synchronized block.
getCurFunction()->setHasBranchProtectedScope();
- return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
+ return new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody);
}
/// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
@@ -3145,15 +3136,14 @@
Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
Stmt *HandlerBlock) {
// There's nothing to test that ActOnExceptionDecl didn't already test.
- return Owned(new (Context) CXXCatchStmt(CatchLoc,
- cast_or_null<VarDecl>(ExDecl),
- HandlerBlock));
+ return new (Context)
+ CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
}
StmtResult
Sema::ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body) {
getCurFunction()->setHasBranchProtectedScope();
- return Owned(new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body));
+ return new (Context) ObjCAutoreleasePoolStmt(AtLoc, Body);
}
namespace {
@@ -3197,6 +3187,9 @@
!getSourceManager().isInSystemHeader(TryLoc))
Diag(TryLoc, diag::err_exceptions_disabled) << "try";
+ if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
+ Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
+
const unsigned NumHandlers = Handlers.size();
assert(NumHandlers > 0 &&
"The parser shouldn't call this if there are no handlers.");
@@ -3247,7 +3240,7 @@
// Neither of these are explicitly forbidden, but every compiler detects them
// and warns.
- return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers));
+ return CXXTryStmt::Create(Context, TryLoc, TryBlock, Handlers);
}
StmtResult
@@ -3259,7 +3252,7 @@
getCurFunction()->setHasBranchProtectedScope();
- return Owned(SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler));
+ return SEHTryStmt::Create(Context,IsCXXTry,TryLoc,TryBlock,Handler);
}
StmtResult
@@ -3274,14 +3267,25 @@
<< FilterExpr->getType());
}
- return Owned(SEHExceptStmt::Create(Context,Loc,FilterExpr,Block));
+ return SEHExceptStmt::Create(Context,Loc,FilterExpr,Block);
}
StmtResult
Sema::ActOnSEHFinallyBlock(SourceLocation Loc,
Stmt *Block) {
assert(Block);
- return Owned(SEHFinallyStmt::Create(Context,Loc,Block));
+ return SEHFinallyStmt::Create(Context,Loc,Block);
+}
+
+StmtResult
+Sema::ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope) {
+ Scope *SEHTryParent = CurScope;
+ while (SEHTryParent && !SEHTryParent->isSEHTryScope())
+ SEHTryParent = SEHTryParent->getParent();
+ if (!SEHTryParent)
+ return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
+
+ return new (Context) SEHLeaveStmt(Loc);
}
StmtResult Sema::BuildMSDependentExistsStmt(SourceLocation KeywordLoc,
@@ -3474,5 +3478,5 @@
PopDeclContext();
PopFunctionScopeInfo();
- return Owned(Res);
+ return Res;
}
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 6502548..fdab947 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -21,6 +21,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
using namespace clang;
using namespace sema;
@@ -166,7 +167,7 @@
if (Result.isInvalid())
return StmtError();
- Exprs[i] = Result.take();
+ Exprs[i] = Result.get();
InputConstraintInfos.push_back(Info);
const Type *Ty = Exprs[i]->getType().getTypePtr();
@@ -351,7 +352,7 @@
InputExpr->isEvaluatable(Context)) {
CastKind castKind =
(OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
- InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take();
+ InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).get();
Exprs[InputOpNo] = InputExpr;
NS->setInputExpr(i, InputExpr);
continue;
@@ -364,13 +365,13 @@
return StmtError();
}
- return Owned(NS);
+ return NS;
}
ExprResult Sema::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
UnqualifiedId &Id,
- InlineAsmIdentifierInfo &Info,
+ llvm::InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedContext) {
Info.clear();
@@ -389,7 +390,7 @@
if (!Result.isUsable()) return Result;
- Result = CheckPlaceholderExpr(Result.take());
+ Result = CheckPlaceholderExpr(Result.get());
if (!Result.isUsable()) return Result;
QualType T = Result.get()->getType();
@@ -484,5 +485,5 @@
/*IsVolatile*/ true, AsmToks, NumOutputs, NumInputs,
Constraints, Exprs, AsmString,
Clobbers, EndLoc);
- return Owned(NS);
+ return NS;
}
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index 3bc620b..44169c2 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -16,6 +16,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Sema/DelayedDiagnostic.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/LoopHint.h"
#include "clang/Sema/ScopeInfo.h"
#include "llvm/ADT/StringExtras.h"
@@ -42,6 +43,156 @@
A.getAttributeSpellingListIndex());
}
+static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
+ SourceRange) {
+ if (St->getStmtClass() != Stmt::DoStmtClass &&
+ St->getStmtClass() != Stmt::ForStmtClass &&
+ St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
+ St->getStmtClass() != Stmt::WhileStmtClass) {
+ S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop);
+ return nullptr;
+ }
+
+ IdentifierLoc *OptionLoc = A.getArgAsIdent(0);
+ IdentifierInfo *OptionInfo = OptionLoc->Ident;
+ IdentifierLoc *ValueLoc = A.getArgAsIdent(1);
+ IdentifierInfo *ValueInfo = ValueLoc->Ident;
+ Expr *ValueExpr = A.getArgAsExpr(2);
+
+ assert(OptionInfo && "Attribute must have valid option info.");
+
+ LoopHintAttr::OptionType Option =
+ llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())
+ .Case("vectorize", LoopHintAttr::Vectorize)
+ .Case("vectorize_width", LoopHintAttr::VectorizeWidth)
+ .Case("interleave", LoopHintAttr::Interleave)
+ .Case("interleave_count", LoopHintAttr::InterleaveCount)
+ .Case("unroll", LoopHintAttr::Unroll)
+ .Case("unroll_count", LoopHintAttr::UnrollCount)
+ .Default(LoopHintAttr::Vectorize);
+
+ int ValueInt;
+ if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave ||
+ Option == LoopHintAttr::Unroll) {
+ if (!ValueInfo) {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+ return nullptr;
+ }
+ if (ValueInfo->isStr("disable"))
+ ValueInt = 0;
+ else if (ValueInfo->isStr("enable"))
+ ValueInt = 1;
+ else {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+ return nullptr;
+ }
+ } else if (Option == LoopHintAttr::VectorizeWidth ||
+ Option == LoopHintAttr::InterleaveCount ||
+ Option == LoopHintAttr::UnrollCount) {
+ // FIXME: We should support template parameters for the loop hint value.
+ // See bug report #19610.
+ llvm::APSInt ValueAPS;
+ if (!ValueExpr || !ValueExpr->isIntegerConstantExpr(ValueAPS, S.Context) ||
+ (ValueInt = ValueAPS.getSExtValue()) < 1) {
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_value);
+ return nullptr;
+ }
+ } else
+ llvm_unreachable("Unknown loop hint option");
+
+ return LoopHintAttr::CreateImplicit(S.Context, Option, ValueInt,
+ A.getRange());
+}
+
+static void
+CheckForIncompatibleAttributes(Sema &S, SmallVectorImpl<const Attr *> &Attrs) {
+ // There are 3 categories of loop hints: vectorize, interleave, and
+ // unroll. Each comes in two variants: an enable/disable form and a
+ // form which takes a numeric argument. For example:
+ // unroll(enable|disable) and unroll_count(N). The following array
+ // accumulate the hints encountered while iterating through the
+ // attributes to check for compatibility.
+ struct {
+ int EnableOptionId;
+ int NumericOptionId;
+ bool EnabledIsSet;
+ bool ValueIsSet;
+ bool Enabled;
+ int Value;
+ } Options[] = {{LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth, false,
+ false, false, 0},
+ {LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount,
+ false, false, false, 0},
+ {LoopHintAttr::Unroll, LoopHintAttr::UnrollCount, false, false,
+ false, 0}};
+
+ for (const auto *I : Attrs) {
+ const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
+
+ // Skip non loop hint attributes
+ if (!LH)
+ continue;
+
+ int Option = LH->getOption();
+ int ValueInt = LH->getValue();
+
+ int Category;
+ switch (Option) {
+ case LoopHintAttr::Vectorize:
+ case LoopHintAttr::VectorizeWidth:
+ Category = 0;
+ break;
+ case LoopHintAttr::Interleave:
+ case LoopHintAttr::InterleaveCount:
+ Category = 1;
+ break;
+ case LoopHintAttr::Unroll:
+ case LoopHintAttr::UnrollCount:
+ Category = 2;
+ break;
+ };
+
+ auto &CategoryState = Options[Category];
+ SourceLocation ValueLoc = LH->getRange().getEnd();
+ if (Option == LoopHintAttr::Vectorize ||
+ Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {
+ // Enable|disable hint. For example, vectorize(enable).
+ if (CategoryState.EnabledIsSet) {
+ // Cannot specify enable/disable state twice.
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
+ << LoopHintAttr::getValueName(CategoryState.Enabled)
+ << LoopHintAttr::getOptionName(Option)
+ << LoopHintAttr::getValueName(ValueInt);
+ }
+ CategoryState.EnabledIsSet = true;
+ CategoryState.Enabled = ValueInt;
+ } else {
+ // Numeric hint. For example, unroll_count(8).
+ if (CategoryState.ValueIsSet) {
+ // Cannot specify numeric hint twice.
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)
+ << CategoryState.Value << LoopHintAttr::getOptionName(Option)
+ << ValueInt;
+ }
+ CategoryState.ValueIsSet = true;
+ CategoryState.Value = ValueInt;
+ }
+
+ if (CategoryState.EnabledIsSet && !CategoryState.Enabled &&
+ CategoryState.ValueIsSet) {
+ // Disable hints are not compatible with numeric hints of the
+ // same category.
+ S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)
+ << /*Duplicate=*/false
+ << LoopHintAttr::getOptionName(CategoryState.EnableOptionId)
+ << LoopHintAttr::getValueName(CategoryState.Enabled)
+ << LoopHintAttr::getOptionName(CategoryState.NumericOptionId)
+ << CategoryState.Value;
+ }
+ }
+}
static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const AttributeList &A,
SourceRange Range) {
@@ -53,6 +204,8 @@
return nullptr;
case AttributeList::AT_FallThrough:
return handleFallThroughAttr(S, St, A, Range);
+ case AttributeList::AT_LoopHint:
+ return handleLoopHintAttr(S, St, A, Range);
default:
// if we're here, then we parsed a known attribute, but didn't recognize
// it as a statement attribute => it is declaration attribute
@@ -70,6 +223,8 @@
Attrs.push_back(a);
}
+ CheckForIncompatibleAttributes(*this, Attrs);
+
if (Attrs.empty())
return S;
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 272c811..5a18845 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -421,15 +421,10 @@
// perform the double-lookup check.
NamedDecl *FirstQualifierInScope = nullptr;
- return Owned(CXXDependentScopeMemberExpr::Create(Context,
- /*This*/ nullptr, ThisType,
- /*IsArrow*/ true,
- /*Op*/ SourceLocation(),
- SS.getWithLocInContext(Context),
- TemplateKWLoc,
- FirstQualifierInScope,
- NameInfo,
- TemplateArgs));
+ return CXXDependentScopeMemberExpr::Create(
+ Context, /*This*/ nullptr, ThisType, /*IsArrow*/ true,
+ /*Op*/ SourceLocation(), SS.getWithLocInContext(Context), TemplateKWLoc,
+ FirstQualifierInScope, NameInfo, TemplateArgs);
}
return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
@@ -440,11 +435,9 @@
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
- return Owned(DependentScopeDeclRefExpr::Create(Context,
- SS.getWithLocInContext(Context),
- TemplateKWLoc,
- NameInfo,
- TemplateArgs));
+ return DependentScopeDeclRefExpr::Create(
+ Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+ TemplateArgs);
}
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
@@ -551,7 +544,7 @@
/// ParamNameLoc is the location of the parameter name (if any).
/// If the type parameter has a default argument, it will be added
/// later via ActOnTypeParameterDefault.
-Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename,
SourceLocation EllipsisLoc,
SourceLocation KeyLoc,
IdentifierInfo *ParamName,
@@ -567,10 +560,11 @@
if (!ParamName)
Loc = KeyLoc;
+ bool IsParameterPack = EllipsisLoc.isValid();
TemplateTypeParmDecl *Param
= TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
KeyLoc, Loc, Depth, Position, ParamName,
- Typename, Ellipsis);
+ Typename, IsParameterPack);
Param->setAccess(AS_public);
if (Invalid)
Param->setInvalidDecl();
@@ -586,7 +580,7 @@
// C++0x [temp.param]p9:
// A default template-argument may be specified for any kind of
// template-parameter that is not a template parameter pack.
- if (DefaultArg && Ellipsis) {
+ if (DefaultArg && IsParameterPack) {
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
DefaultArg = ParsedType();
}
@@ -731,7 +725,7 @@
Param->setInvalidDecl();
return Param;
}
- Default = DefaultRes.take();
+ Default = DefaultRes.get();
Param->setDefaultArgument(Default, false);
}
@@ -2125,8 +2119,7 @@
// corresponds to these arguments.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *Decl
- = ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
- InsertPos);
+ = ClassTemplate->findSpecialization(Converted, InsertPos);
if (!Decl) {
// This is the first time we have referenced this class template
// specialization. Create the canonical declaration and add it to
@@ -2506,11 +2499,9 @@
if (IsPartialSpecialization)
// FIXME: Template parameter list matters too
- PrevDecl = VarTemplate->findPartialSpecialization(
- Converted.data(), Converted.size(), InsertPos);
+ PrevDecl = VarTemplate->findPartialSpecialization(Converted, InsertPos);
else
- PrevDecl = VarTemplate->findSpecialization(Converted.data(),
- Converted.size(), InsertPos);
+ PrevDecl = VarTemplate->findSpecialization(Converted, InsertPos);
VarTemplateSpecializationDecl *Specialization = nullptr;
@@ -2675,7 +2666,7 @@
// corresponds to these arguments.
void *InsertPos = nullptr;
if (VarTemplateSpecializationDecl *Spec = Template->findSpecialization(
- Converted.data(), Converted.size(), InsertPos))
+ Converted, InsertPos))
// If we already have a variable template specialization, return it.
return Spec;
@@ -2869,7 +2860,7 @@
RequiresADL, TemplateArgs,
R.begin(), R.end());
- return Owned(ULE);
+ return ULE;
}
// We actually only call this from template instantiation.
@@ -2903,7 +2894,7 @@
if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
<< SS.getScopeRep()
- << NameInfo.getName() << SS.getRange();
+ << NameInfo.getName().getAsString() << SS.getRange();
Diag(Temp->getLocation(), diag::note_referenced_class_template);
return ExprError();
}
@@ -3005,9 +2996,11 @@
}
bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
- const TemplateArgumentLoc &AL,
+ TemplateArgumentLoc &AL,
SmallVectorImpl<TemplateArgument> &Converted) {
const TemplateArgument &Arg = AL.getArgument();
+ QualType ArgType;
+ TypeSourceInfo *TSI = nullptr;
// Check template type parameter.
switch(Arg.getKind()) {
@@ -3015,6 +3008,8 @@
// C++ [temp.arg.type]p1:
// A template-argument for a template-parameter which is a
// type shall be a type-id.
+ ArgType = Arg.getAsType();
+ TSI = AL.getTypeSourceInfo();
break;
case TemplateArgument::Template: {
// We have a template type parameter but the template argument
@@ -3049,18 +3044,38 @@
}
}
- if (NameInfo.getName().isIdentifier()) {
+ if (auto *II = NameInfo.getName().getAsIdentifierInfo()) {
LookupResult Result(*this, NameInfo, LookupOrdinaryName);
LookupParsedName(Result, CurScope, &SS);
if (Result.getAsSingle<TypeDecl>() ||
Result.getResultKind() ==
- LookupResult::NotFoundInCurrentInstantiation) {
- // FIXME: Add a FixIt and fix up the template argument for recovery.
+ LookupResult::NotFoundInCurrentInstantiation) {
+ // Suggest that the user add 'typename' before the NNS.
SourceLocation Loc = AL.getSourceRange().getBegin();
- Diag(Loc, diag::err_template_arg_must_be_type_suggest);
+ Diag(Loc, getLangOpts().MSVCCompat
+ ? diag::ext_ms_template_type_arg_missing_typename
+ : diag::err_template_arg_must_be_type_suggest)
+ << FixItHint::CreateInsertion(Loc, "typename ");
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
+
+ // Recover by synthesizing a type using the location information that we
+ // already have.
+ ArgType =
+ Context.getDependentNameType(ETK_Typename, SS.getScopeRep(), II);
+ TypeLocBuilder TLB;
+ DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(ArgType);
+ TL.setElaboratedKeywordLoc(SourceLocation(/*synthesized*/));
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
+ TL.setNameLoc(NameInfo.getLoc());
+ TSI = TLB.getTypeSourceInfo(Context, ArgType);
+
+ // Overwrite our input TemplateArgumentLoc so that we can recover
+ // properly.
+ AL = TemplateArgumentLoc(TemplateArgument(ArgType),
+ TemplateArgumentLocInfo(TSI));
+
+ break;
}
}
// fallthrough
@@ -3076,11 +3091,11 @@
}
}
- if (CheckTemplateArgument(Param, AL.getTypeSourceInfo()))
+ if (CheckTemplateArgument(Param, TSI))
return true;
// Add the converted template type argument.
- QualType ArgType = Context.getCanonicalType(Arg.getAsType());
+ ArgType = Context.getCanonicalType(ArgType);
// Objective-C ARC:
// If an explicitly-specified template argument type is a lifetime type
@@ -3310,7 +3325,7 @@
if (Arg.isInvalid())
return TemplateArgumentLoc();
- Expr *ArgE = Arg.takeAs<Expr>();
+ Expr *ArgE = Arg.getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE);
}
@@ -3362,7 +3377,7 @@
///
/// \returns true on error, false otherwise.
bool Sema::CheckTemplateArgument(NamedDecl *Param,
- const TemplateArgumentLoc &Arg,
+ TemplateArgumentLoc &Arg,
NamedDecl *Template,
SourceLocation TemplateLoc,
SourceLocation RAngleLoc,
@@ -3452,22 +3467,20 @@
// so it was provided with a template keyword. However, its source
// location is not stored in the template argument structure.
SourceLocation TemplateKWLoc;
- ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context,
- SS.getWithLocInContext(Context),
- TemplateKWLoc,
- NameInfo,
- nullptr));
+ ExprResult E = DependentScopeDeclRefExpr::Create(
+ Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
+ nullptr);
// If we parsed the template argument as a pack expansion, create a
// pack expansion expression.
if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
- E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc());
+ E = ActOnPackExpansion(E.get(), Arg.getTemplateEllipsisLoc());
if (E.isInvalid())
return true;
}
TemplateArgument Result;
- E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result);
+ E = CheckTemplateArgument(NTTP, NTTPType, E.get(), Result);
if (E.isInvalid())
return true;
@@ -3817,7 +3830,7 @@
if (E.isInvalid())
return true;
- Expr *Ex = E.takeAs<Expr>();
+ Expr *Ex = E.getAs<Expr>();
Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
} else {
TemplateTemplateParmDecl *TempParm
@@ -3864,6 +3877,17 @@
++ArgIdx;
}
+ // If we're performing a partial argument substitution, allow any trailing
+ // pack expansions; they might be empty. This can happen even if
+ // PartialTemplateArgs is false (the list of arguments is complete but
+ // still dependent).
+ if (ArgIdx < NumArgs && CurrentInstantiationScope &&
+ CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+ while (ArgIdx < NumArgs &&
+ TemplateArgs[ArgIdx].getArgument().isPackExpansion())
+ Converted.push_back(TemplateArgs[ArgIdx++].getArgument());
+ }
+
// If we have any leftover arguments, then there were too many arguments.
// Complain and fail.
if (ArgIdx < NumArgs)
@@ -4134,12 +4158,17 @@
//
// C++11 allows these, and even in C++03 we allow them as an extension with
// a warning.
- if (LangOpts.CPlusPlus11 ?
- Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type,
- SR.getBegin()) != DiagnosticsEngine::Ignored ||
- Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type,
- SR.getBegin()) != DiagnosticsEngine::Ignored :
- Arg->hasUnnamedOrLocalType()) {
+ bool NeedsCheck;
+ if (LangOpts.CPlusPlus11)
+ NeedsCheck =
+ !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_unnamed_type,
+ SR.getBegin()) ||
+ !Diags.isIgnored(diag::warn_cxx98_compat_template_arg_local_type,
+ SR.getBegin());
+ else
+ NeedsCheck = Arg->hasUnnamedOrLocalType();
+
+ if (NeedsCheck) {
UnnamedLocalNoLinkageFinder Finder(*this, SR);
(void)Finder.Visit(Context.getCanonicalType(Arg));
}
@@ -4161,14 +4190,14 @@
if (Arg->isValueDependent() || Arg->isTypeDependent())
return NPV_NotNullPointer;
- if (!S.getLangOpts().CPlusPlus11)
+ if (!S.getLangOpts().CPlusPlus11 || S.getLangOpts().MSVCCompat)
return NPV_NotNullPointer;
// Determine whether we have a constant expression.
ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg);
if (ArgRV.isInvalid())
return NPV_Error;
- Arg = ArgRV.take();
+ Arg = ArgRV.get();
Expr::EvalResult EvalResult;
SmallVector<PartialDiagnosticAt, 8> Notes;
@@ -4308,22 +4337,6 @@
Expr *Arg = ArgIn;
QualType ArgType = Arg->getType();
- // If our parameter has pointer type, check for a null template value.
- if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
- switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) {
- case NPV_NullPointer:
- S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
- Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
- return false;
-
- case NPV_Error:
- return true;
-
- case NPV_NotNullPointer:
- break;
- }
- }
-
bool AddressTaken = false;
SourceLocation AddrOpLoc;
if (S.getLangOpts().MicrosoftExt) {
@@ -4411,6 +4424,32 @@
Arg = subst->getReplacement()->IgnoreImpCasts();
}
+ DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
+ ValueDecl *Entity = DRE ? DRE->getDecl() : nullptr;
+
+ // If our parameter has pointer type, check for a null template value.
+ if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
+ NullPointerValueKind NPV;
+ // dllimport'd entities aren't constant but are available inside of template
+ // arguments.
+ if (Entity && Entity->hasAttr<DLLImportAttr>())
+ NPV = NPV_NotNullPointer;
+ else
+ NPV = isNullPointerValueTemplateArgument(S, Param, ParamType, ArgIn);
+ switch (NPV) {
+ case NPV_NullPointer:
+ S.Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
+ Converted = TemplateArgument(ParamType, /*isNullPtr=*/true);
+ return false;
+
+ case NPV_Error:
+ return true;
+
+ case NPV_NotNullPointer:
+ break;
+ }
+ }
+
// Stop checking the precise nature of the argument if it is value dependent,
// it should be checked when instantiated.
if (Arg->isValueDependent()) {
@@ -4427,7 +4466,6 @@
return false;
}
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
if (!DRE) {
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref)
<< Arg->getSourceRange();
@@ -4435,8 +4473,6 @@
return true;
}
- ValueDecl *Entity = DRE->getDecl();
-
// Cannot refer to non-static data members
if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) {
S.Diag(Arg->getLocStart(), diag::err_template_arg_field)
@@ -4611,7 +4647,7 @@
ParamType.getNonReferenceType(),
false, ObjCLifetimeConversion)) {
Arg = S.ImpCastExprToType(Arg, ParamType, CK_NoOp,
- Arg->getValueKind()).take();
+ Arg->getValueKind()).get();
ResultArg = Arg;
} else if (!S.Context.hasSameUnqualifiedType(Arg->getType(),
ParamType.getNonReferenceType())) {
@@ -4732,7 +4768,7 @@
if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
// FIXME: Produce a cloned, canonical expression?
Converted = TemplateArgument(Arg);
- return Owned(Arg);
+ return Arg;
}
// C++ [temp.arg.nontype]p5:
@@ -4776,7 +4812,7 @@
// we should be able to diagnose that prior to instantiation.
if (Arg->isValueDependent()) {
Converted = TemplateArgument(Arg);
- return Owned(Arg);
+ return Arg;
}
// C++ [temp.arg.nontype]p1:
@@ -4809,7 +4845,7 @@
ExprResult ArgResult = DefaultLvalueConversion(Arg);
if (ArgResult.isInvalid())
return ExprError();
- Arg = ArgResult.take();
+ Arg = ArgResult.get();
QualType ArgType = Arg->getType();
@@ -4842,7 +4878,7 @@
} Diagnoser(ArgType);
Arg = VerifyIntegerConstantExpression(Arg, &Value, Diagnoser,
- false).take();
+ false).get();
if (!Arg)
return ExprError();
}
@@ -4857,11 +4893,11 @@
// Okay: no conversion necessary
} else if (ParamType->isBooleanType()) {
// This is an integral-to-boolean conversion.
- Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take();
+ Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).get();
} else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
!ParamType->isEnumeralType()) {
// This is an integral promotion or conversion.
- Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take();
+ Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).get();
} else {
// We can't perform this conversion.
Diag(Arg->getLocStart(),
@@ -4878,7 +4914,7 @@
// The argument is value-dependent. Create a new
// TemplateArgument with the converted expression.
Converted = TemplateArgument(Arg);
- return Owned(Arg);
+ return Arg;
}
QualType IntegerType = Context.getCanonicalType(ParamType);
@@ -4932,7 +4968,7 @@
ParamType->isEnumeralType()
? Context.getCanonicalType(ParamType)
: IntegerType);
- return Owned(Arg);
+ return Arg;
}
QualType ArgType = Arg->getType();
@@ -4980,13 +5016,13 @@
ParamType,
Arg, Converted))
return ExprError();
- return Owned(Arg);
+ return Arg;
}
if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
Converted))
return ExprError();
- return Owned(Arg);
+ return Arg;
}
if (ParamType->isPointerType()) {
@@ -5001,7 +5037,7 @@
ParamType,
Arg, Converted))
return ExprError();
- return Owned(Arg);
+ return Arg;
}
if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
@@ -5032,14 +5068,14 @@
ParamType,
Arg, Converted))
return ExprError();
- return Owned(Arg);
+ return Arg;
}
// Deal with parameters of type std::nullptr_t.
if (ParamType->isNullPtrType()) {
if (Arg->isTypeDependent() || Arg->isValueDependent()) {
Converted = TemplateArgument(Arg);
- return Owned(Arg);
+ return Arg;
}
switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) {
@@ -5055,7 +5091,7 @@
case NPV_NullPointer:
Diag(Arg->getExprLoc(), diag::warn_cxx98_compat_template_arg_null);
Converted = TemplateArgument(ParamType, /*isNullPtr*/true);
- return Owned(Arg);
+ return Arg;
}
}
@@ -5066,7 +5102,7 @@
if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
Converted))
return ExprError();
- return Owned(Arg);
+ return Arg;
}
/// \brief Check a template argument against its corresponding
@@ -5075,7 +5111,7 @@
/// This routine implements the semantics of C++ [temp.arg.template].
/// It returns true if an error occurred, and false otherwise.
bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
- const TemplateArgumentLoc &Arg,
+ TemplateArgumentLoc &Arg,
unsigned ArgumentPackIndex) {
TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern();
TemplateDecl *Template = Name.getAsTemplateDecl();
@@ -5192,7 +5228,7 @@
if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
ParamType.getUnqualifiedType(), false,
ObjCLifetimeConversion))
- RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp);
+ RefExpr = ImpCastExprToType(RefExpr.get(), ParamType.getUnqualifiedType(), CK_NoOp);
assert(!RefExpr.isInvalid() &&
Context.hasSameType(((Expr*) RefExpr.get())->getType(),
@@ -5212,7 +5248,7 @@
if (T->isFunctionType() || T->isArrayType()) {
// Decay functions and arrays.
- RefExpr = DefaultFunctionArrayConversion(RefExpr.take());
+ RefExpr = DefaultFunctionArrayConversion(RefExpr.get());
if (RefExpr.isInvalid())
return ExprError();
@@ -5295,7 +5331,7 @@
Loc, Loc);
}
- return Owned(E);
+ return E;
}
/// \brief Match two template parameters within template parameter lists.
@@ -6048,14 +6084,9 @@
if (isPartialSpecialization)
// FIXME: Template parameter list matters, too
- PrevDecl
- = ClassTemplate->findPartialSpecialization(Converted.data(),
- Converted.size(),
- InsertPos);
+ PrevDecl = ClassTemplate->findPartialSpecialization(Converted, InsertPos);
else
- PrevDecl
- = ClassTemplate->findSpecialization(Converted.data(),
- Converted.size(), InsertPos);
+ PrevDecl = ClassTemplate->findSpecialization(Converted, InsertPos);
ClassTemplateSpecializationDecl *Specialization = nullptr;
@@ -7065,8 +7096,7 @@
// corresponds to these arguments.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->findSpecialization(Converted.data(),
- Converted.size(), InsertPos);
+ = ClassTemplate->findSpecialization(Converted, InsertPos);
TemplateSpecializationKind PrevDecl_TSK
= PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 246107e..f941a09 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -297,6 +297,7 @@
XAEnd = X.pack_end(),
YA = Y.pack_begin();
XA != XAEnd; ++XA, ++YA) {
+ // FIXME: Do we need to merge the results together here?
if (checkDeducedTemplateArguments(Context,
DeducedTemplateArgument(*XA, X.wasDeducedFromArrayBound()),
DeducedTemplateArgument(*YA, Y.wasDeducedFromArrayBound()))
@@ -581,96 +582,181 @@
return TemplateParameter(cast<TemplateTemplateParmDecl>(D));
}
-typedef SmallVector<SmallVector<DeducedTemplateArgument, 4>, 2>
- NewlyDeducedPacksType;
+/// A pack that we're currently deducing.
+struct clang::DeducedPack {
+ DeducedPack(unsigned Index) : Index(Index), Outer(nullptr) {}
-/// \brief Prepare to perform template argument deduction for all of the
-/// arguments in a set of argument packs.
-static void
-PrepareArgumentPackDeduction(Sema &S,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- ArrayRef<unsigned> PackIndices,
- SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
- NewlyDeducedPacksType &NewlyDeducedPacks) {
- // Save the deduced template arguments for each parameter pack expanded
- // by this pack expansion, then clear out the deduction.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- // Save the previously-deduced argument pack, then clear it out so that we
- // can deduce a new argument pack.
- SavedPacks[I] = Deduced[PackIndices[I]];
- Deduced[PackIndices[I]] = TemplateArgument();
+ // The index of the pack.
+ unsigned Index;
- if (!S.CurrentInstantiationScope)
- continue;
+ // The old value of the pack before we started deducing it.
+ DeducedTemplateArgument Saved;
- // If the template argument pack was explicitly specified, add that to
- // the set of deduced arguments.
- const TemplateArgument *ExplicitArgs;
- unsigned NumExplicitArgs;
- if (NamedDecl *PartiallySubstitutedPack
- = S.CurrentInstantiationScope->getPartiallySubstitutedPack(
- &ExplicitArgs,
- &NumExplicitArgs)) {
- if (getDepthAndIndex(PartiallySubstitutedPack).second == PackIndices[I])
- NewlyDeducedPacks[I].append(ExplicitArgs,
- ExplicitArgs + NumExplicitArgs);
+ // A deferred value of this pack from an inner deduction, that couldn't be
+ // deduced because this deduction hadn't happened yet.
+ DeducedTemplateArgument DeferredDeduction;
+
+ // The new value of the pack.
+ SmallVector<DeducedTemplateArgument, 4> New;
+
+ // The outer deduction for this pack, if any.
+ DeducedPack *Outer;
+};
+
+/// A scope in which we're performing pack deduction.
+class PackDeductionScope {
+public:
+ PackDeductionScope(Sema &S, TemplateParameterList *TemplateParams,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ TemplateDeductionInfo &Info, TemplateArgument Pattern)
+ : S(S), TemplateParams(TemplateParams), Deduced(Deduced), Info(Info) {
+ // Compute the set of template parameter indices that correspond to
+ // parameter packs expanded by the pack expansion.
+ {
+ llvm::SmallBitVector SawIndices(TemplateParams->size());
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
+ for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
+ unsigned Depth, Index;
+ std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
+ if (Depth == 0 && !SawIndices[Index]) {
+ SawIndices[Index] = true;
+
+ // Save the deduced template argument for the parameter pack expanded
+ // by this pack expansion, then clear out the deduction.
+ DeducedPack Pack(Index);
+ Pack.Saved = Deduced[Index];
+ Deduced[Index] = TemplateArgument();
+
+ Packs.push_back(Pack);
+ }
+ }
+ }
+ assert(!Packs.empty() && "Pack expansion without unexpanded packs?");
+
+ for (auto &Pack : Packs) {
+ if (Info.PendingDeducedPacks.size() > Pack.Index)
+ Pack.Outer = Info.PendingDeducedPacks[Pack.Index];
+ else
+ Info.PendingDeducedPacks.resize(Pack.Index + 1);
+ Info.PendingDeducedPacks[Pack.Index] = &Pack;
+
+ if (S.CurrentInstantiationScope) {
+ // If the template argument pack was explicitly specified, add that to
+ // the set of deduced arguments.
+ const TemplateArgument *ExplicitArgs;
+ unsigned NumExplicitArgs;
+ NamedDecl *PartiallySubstitutedPack =
+ S.CurrentInstantiationScope->getPartiallySubstitutedPack(
+ &ExplicitArgs, &NumExplicitArgs);
+ if (PartiallySubstitutedPack &&
+ getDepthAndIndex(PartiallySubstitutedPack).second == Pack.Index)
+ Pack.New.append(ExplicitArgs, ExplicitArgs + NumExplicitArgs);
+ }
}
}
-}
-/// \brief Finish template argument deduction for a set of argument packs,
-/// producing the argument packs and checking for consistency with prior
-/// deductions.
-static Sema::TemplateDeductionResult
-FinishArgumentPackDeduction(Sema &S,
- TemplateParameterList *TemplateParams,
- bool HasAnyArguments,
- SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- ArrayRef<unsigned> PackIndices,
- SmallVectorImpl<DeducedTemplateArgument> &SavedPacks,
- NewlyDeducedPacksType &NewlyDeducedPacks,
- TemplateDeductionInfo &Info) {
- // Build argument packs for each of the parameter packs expanded by this
- // pack expansion.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- if (HasAnyArguments && NewlyDeducedPacks[I].empty()) {
- // We were not able to deduce anything for this parameter pack,
- // so just restore the saved argument pack.
- Deduced[PackIndices[I]] = SavedPacks[I];
- continue;
- }
-
- DeducedTemplateArgument NewPack;
-
- if (NewlyDeducedPacks[I].empty()) {
- // If we deduced an empty argument pack, create it now.
- NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
- } else {
- TemplateArgument *ArgumentPack
- = new (S.Context) TemplateArgument [NewlyDeducedPacks[I].size()];
- std::copy(NewlyDeducedPacks[I].begin(), NewlyDeducedPacks[I].end(),
- ArgumentPack);
- NewPack
- = DeducedTemplateArgument(TemplateArgument(ArgumentPack,
- NewlyDeducedPacks[I].size()),
- NewlyDeducedPacks[I][0].wasDeducedFromArrayBound());
- }
-
- DeducedTemplateArgument Result
- = checkDeducedTemplateArguments(S.Context, SavedPacks[I], NewPack);
- if (Result.isNull()) {
- Info.Param
- = makeTemplateParameter(TemplateParams->getParam(PackIndices[I]));
- Info.FirstArg = SavedPacks[I];
- Info.SecondArg = NewPack;
- return Sema::TDK_Inconsistent;
- }
-
- Deduced[PackIndices[I]] = Result;
+ ~PackDeductionScope() {
+ for (auto &Pack : Packs)
+ Info.PendingDeducedPacks[Pack.Index] = Pack.Outer;
}
- return Sema::TDK_Success;
-}
+ /// Move to deducing the next element in each pack that is being deduced.
+ void nextPackElement() {
+ // Capture the deduced template arguments for each parameter pack expanded
+ // by this pack expansion, add them to the list of arguments we've deduced
+ // for that pack, then clear out the deduced argument.
+ for (auto &Pack : Packs) {
+ DeducedTemplateArgument &DeducedArg = Deduced[Pack.Index];
+ if (!DeducedArg.isNull()) {
+ Pack.New.push_back(DeducedArg);
+ DeducedArg = DeducedTemplateArgument();
+ }
+ }
+ }
+
+ /// \brief Finish template argument deduction for a set of argument packs,
+ /// producing the argument packs and checking for consistency with prior
+ /// deductions.
+ Sema::TemplateDeductionResult finish(bool HasAnyArguments) {
+ // Build argument packs for each of the parameter packs expanded by this
+ // pack expansion.
+ for (auto &Pack : Packs) {
+ // Put back the old value for this pack.
+ Deduced[Pack.Index] = Pack.Saved;
+
+ // Build or find a new value for this pack.
+ DeducedTemplateArgument NewPack;
+ if (HasAnyArguments && Pack.New.empty()) {
+ if (Pack.DeferredDeduction.isNull()) {
+ // We were not able to deduce anything for this parameter pack
+ // (because it only appeared in non-deduced contexts), so just
+ // restore the saved argument pack.
+ continue;
+ }
+
+ NewPack = Pack.DeferredDeduction;
+ Pack.DeferredDeduction = TemplateArgument();
+ } else if (Pack.New.empty()) {
+ // If we deduced an empty argument pack, create it now.
+ NewPack = DeducedTemplateArgument(TemplateArgument::getEmptyPack());
+ } else {
+ TemplateArgument *ArgumentPack =
+ new (S.Context) TemplateArgument[Pack.New.size()];
+ std::copy(Pack.New.begin(), Pack.New.end(), ArgumentPack);
+ NewPack = DeducedTemplateArgument(
+ TemplateArgument(ArgumentPack, Pack.New.size()),
+ Pack.New[0].wasDeducedFromArrayBound());
+ }
+
+ // Pick where we're going to put the merged pack.
+ DeducedTemplateArgument *Loc;
+ if (Pack.Outer) {
+ if (Pack.Outer->DeferredDeduction.isNull()) {
+ // Defer checking this pack until we have a complete pack to compare
+ // it against.
+ Pack.Outer->DeferredDeduction = NewPack;
+ continue;
+ }
+ Loc = &Pack.Outer->DeferredDeduction;
+ } else {
+ Loc = &Deduced[Pack.Index];
+ }
+
+ // Check the new pack matches any previous value.
+ DeducedTemplateArgument OldPack = *Loc;
+ DeducedTemplateArgument Result =
+ checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
+
+ // If we deferred a deduction of this pack, check that one now too.
+ if (!Result.isNull() && !Pack.DeferredDeduction.isNull()) {
+ OldPack = Result;
+ NewPack = Pack.DeferredDeduction;
+ Result = checkDeducedTemplateArguments(S.Context, OldPack, NewPack);
+ }
+
+ if (Result.isNull()) {
+ Info.Param =
+ makeTemplateParameter(TemplateParams->getParam(Pack.Index));
+ Info.FirstArg = OldPack;
+ Info.SecondArg = NewPack;
+ return Sema::TDK_Inconsistent;
+ }
+
+ *Loc = Result;
+ }
+
+ return Sema::TDK_Success;
+ }
+
+private:
+ Sema &S;
+ TemplateParameterList *TemplateParams;
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced;
+ TemplateDeductionInfo &Info;
+
+ SmallVector<DeducedPack, 2> Packs;
+};
/// \brief Deduce the template arguments by comparing the list of parameter
/// types to the list of argument types, as in the parameter-type-lists of
@@ -773,33 +859,8 @@
// comparison deduces template arguments for subsequent positions in the
// template parameter packs expanded by the function parameter pack.
- // Compute the set of template parameter indices that correspond to
- // parameter packs expanded by the pack expansion.
- SmallVector<unsigned, 2> PackIndices;
QualType Pattern = Expansion->getPattern();
- {
- llvm::SmallBitVector SawIndices(TemplateParams->size());
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
- for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
- if (Depth == 0 && !SawIndices[Index]) {
- SawIndices[Index] = true;
- PackIndices.push_back(Index);
- }
- }
- }
- assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
- // Keep track of the deduced template arguments for each parameter pack
- // expanded by this pack expansion (the outer index) and for each
- // template argument (the inner SmallVectors).
- NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
- SmallVector<DeducedTemplateArgument, 2>
- SavedPacks(PackIndices.size());
- PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks);
+ PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
bool HasAnyArguments = false;
for (; ArgIdx < NumArgs; ++ArgIdx) {
@@ -813,24 +874,12 @@
RefParamComparisons))
return Result;
- // Capture the deduced template arguments for each parameter pack expanded
- // by this pack expansion, add them to the list of arguments we've deduced
- // for that pack, then clear out the deduced argument.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
- if (!DeducedArg.isNull()) {
- NewlyDeducedPacks[I].push_back(DeducedArg);
- DeducedArg = DeducedTemplateArgument();
- }
- }
+ PackScope.nextPackElement();
}
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- if (Sema::TemplateDeductionResult Result
- = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
- Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks, Info))
+ if (auto Result = PackScope.finish(HasAnyArguments))
return Result;
}
@@ -1852,41 +1901,18 @@
// template parameter packs expanded by Pi.
TemplateArgument Pattern = Params[ParamIdx].getPackExpansionPattern();
- // Compute the set of template parameter indices that correspond to
- // parameter packs expanded by the pack expansion.
- SmallVector<unsigned, 2> PackIndices;
- {
- llvm::SmallBitVector SawIndices(TemplateParams->size());
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- S.collectUnexpandedParameterPacks(Pattern, Unexpanded);
- for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
- if (Depth == 0 && !SawIndices[Index]) {
- SawIndices[Index] = true;
- PackIndices.push_back(Index);
- }
- }
- }
- assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
-
// FIXME: If there are no remaining arguments, we can bail out early
// and set any deduced parameter packs to an empty argument pack.
// The latter part of this is a (minor) correctness issue.
- // Save the deduced template arguments for each parameter pack expanded
- // by this pack expansion, then clear out the deduction.
- SmallVector<DeducedTemplateArgument, 2>
- SavedPacks(PackIndices.size());
- NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
- PrepareArgumentPackDeduction(S, Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks);
+ // Prepare to deduce the packs within the pattern.
+ PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern);
// Keep track of the deduced template arguments for each parameter pack
// expanded by this pack expansion (the outer index) and for each
// template argument (the inner SmallVectors).
bool HasAnyArguments = false;
- while (hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs)) {
+ for (; hasTemplateArgumentForDeduction(Args, ArgIdx, NumArgs); ++ArgIdx) {
HasAnyArguments = true;
// Deduce template arguments from the pattern.
@@ -1895,26 +1921,12 @@
Info, Deduced))
return Result;
- // Capture the deduced template arguments for each parameter pack expanded
- // by this pack expansion, add them to the list of arguments we've deduced
- // for that pack, then clear out the deduced argument.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
- if (!DeducedArg.isNull()) {
- NewlyDeducedPacks[I].push_back(DeducedArg);
- DeducedArg = DeducedTemplateArgument();
- }
- }
-
- ++ArgIdx;
+ PackScope.nextPackElement();
}
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- if (Sema::TemplateDeductionResult Result
- = FinishArgumentPackDeduction(S, TemplateParams, HasAnyArguments,
- Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks, Info))
+ if (auto Result = PackScope.finish(HasAnyArguments))
return Result;
}
@@ -2020,21 +2032,21 @@
case TemplateArgument::Declaration: {
Expr *E
= S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
- .takeAs<Expr>();
+ .getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
case TemplateArgument::NullPtr: {
Expr *E
= S.BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc)
- .takeAs<Expr>();
+ .getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true),
E);
}
case TemplateArgument::Integral: {
Expr *E
- = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).takeAs<Expr>();
+ = S.BuildExpressionFromIntegralTemplateArgument(Arg, Loc).getAs<Expr>();
return TemplateArgumentLoc(TemplateArgument(E), E);
}
@@ -2804,9 +2816,19 @@
// argument, because it was explicitly-specified. Just record the
// presence of this argument.
Builder.push_back(Deduced[I]);
+ // We may have had explicitly-specified template arguments for a
+ // template parameter pack (that may or may not have been extended
+ // via additional deduced arguments).
+ if (Param->isParameterPack() && CurrentInstantiationScope) {
+ if (CurrentInstantiationScope->getPartiallySubstitutedPack() ==
+ Param) {
+ // Forget the partially-substituted pack; its substitution is now
+ // complete.
+ CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+ }
+ }
continue;
}
-
// We have deduced this argument, so it still needs to be
// checked and converted.
@@ -3403,30 +3425,9 @@
break;
QualType ParamPattern = ParamExpansion->getPattern();
- SmallVector<unsigned, 2> PackIndices;
- {
- llvm::SmallBitVector SawIndices(TemplateParams->size());
- SmallVector<UnexpandedParameterPack, 2> Unexpanded;
- collectUnexpandedParameterPacks(ParamPattern, Unexpanded);
- for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(Unexpanded[I]);
- if (Depth == 0 && !SawIndices[Index]) {
- SawIndices[Index] = true;
- PackIndices.push_back(Index);
- }
- }
- }
- assert(!PackIndices.empty() && "Pack expansion without unexpanded packs?");
+ PackDeductionScope PackScope(*this, TemplateParams, Deduced, Info,
+ ParamPattern);
- // Keep track of the deduced template arguments for each parameter pack
- // expanded by this pack expansion (the outer index) and for each
- // template argument (the inner SmallVectors).
- NewlyDeducedPacksType NewlyDeducedPacks(PackIndices.size());
- SmallVector<DeducedTemplateArgument, 2>
- SavedPacks(PackIndices.size());
- PrepareArgumentPackDeduction(*this, Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks);
bool HasAnyArguments = false;
for (; ArgIdx < Args.size(); ++ArgIdx) {
HasAnyArguments = true;
@@ -3435,7 +3436,7 @@
ParamType = OrigParamType;
Expr *Arg = Args[ArgIdx];
QualType ArgType = Arg->getType();
-
+
unsigned TDF = 0;
if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
ParamType, ArgType, Arg,
@@ -3476,24 +3477,12 @@
return Result;
}
- // Capture the deduced template arguments for each parameter pack expanded
- // by this pack expansion, add them to the list of arguments we've deduced
- // for that pack, then clear out the deduced argument.
- for (unsigned I = 0, N = PackIndices.size(); I != N; ++I) {
- DeducedTemplateArgument &DeducedArg = Deduced[PackIndices[I]];
- if (!DeducedArg.isNull()) {
- NewlyDeducedPacks[I].push_back(DeducedArg);
- DeducedArg = DeducedTemplateArgument();
- }
- }
+ PackScope.nextPackElement();
}
// Build argument packs for each of the parameter packs expanded by this
// pack expansion.
- if (Sema::TemplateDeductionResult Result
- = FinishArgumentPackDeduction(*this, TemplateParams, HasAnyArguments,
- Deduced, PackIndices, SavedPacks,
- NewlyDeducedPacks, Info))
+ if (auto Result = PackScope.finish(HasAnyArguments))
return Result;
// After we've matching against a parameter pack, we're done.
@@ -3982,7 +3971,7 @@
ExprResult NonPlaceholder = CheckPlaceholderExpr(Init);
if (NonPlaceholder.isInvalid())
return DAR_FailedAlreadyDiagnosed;
- Init = NonPlaceholder.take();
+ Init = NonPlaceholder.get();
}
if (Init->isTypeDependent() || Type.getType()->isDependentType()) {
@@ -4199,34 +4188,24 @@
// otherwise, the ordering rules for static functions against non-static
// functions don't make any sense.
//
- // C++98/03 doesn't have this provision, so instead we drop the
- // first argument of the free function, which seems to match
- // existing practice.
+ // C++98/03 doesn't have this provision but we've extended DR532 to cover
+ // it as wording was broken prior to it.
SmallVector<QualType, 4> Args1;
- unsigned Skip1 = 0, Skip2 = 0;
unsigned NumComparedArguments = NumCallArguments1;
if (!Method2 && Method1 && !Method1->isStatic()) {
- if (S.getLangOpts().CPlusPlus11) {
- // Compare 'this' from Method1 against first parameter from Method2.
- AddImplicitObjectParameterType(S.Context, Method1, Args1);
- ++NumComparedArguments;
- } else
- // Ignore first parameter from Method2.
- ++Skip2;
+ // Compare 'this' from Method1 against first parameter from Method2.
+ AddImplicitObjectParameterType(S.Context, Method1, Args1);
+ ++NumComparedArguments;
} else if (!Method1 && Method2 && !Method2->isStatic()) {
- if (S.getLangOpts().CPlusPlus11)
- // Compare 'this' from Method2 against first parameter from Method1.
- AddImplicitObjectParameterType(S.Context, Method2, Args2);
- else
- // Ignore first parameter from Method1.
- ++Skip1;
+ // Compare 'this' from Method2 against first parameter from Method1.
+ AddImplicitObjectParameterType(S.Context, Method2, Args2);
}
- Args1.insert(Args1.end(), Proto1->param_type_begin() + Skip1,
+ Args1.insert(Args1.end(), Proto1->param_type_begin(),
Proto1->param_type_end());
- Args2.insert(Args2.end(), Proto2->param_type_begin() + Skip2,
+ Args2.insert(Args2.end(), Proto2->param_type_begin(),
Proto2->param_type_end());
// C++ [temp.func.order]p5:
@@ -4240,7 +4219,7 @@
Args1.data(), Args1.size(), Info, Deduced,
TDF_None, /*PartialOrdering=*/true,
RefParamComparisons))
- return false;
+ return false;
break;
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index fae1222..14c6405 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1084,7 +1084,7 @@
ExprResult
TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
if (!E->isTypeDependent())
- return SemaRef.Owned(E);
+ return E;
return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
}
@@ -1098,7 +1098,7 @@
// arguments left unspecified.
if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(),
NTTP->getPosition()))
- return SemaRef.Owned(E);
+ return E;
TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
if (NTTP->isParameterPack()) {
@@ -1138,7 +1138,7 @@
// case we just return that expression.
if (arg.getKind() == TemplateArgument::Expression) {
Expr *argExpr = arg.getAsExpr();
- result = SemaRef.Owned(argExpr);
+ result = argExpr;
type = argExpr->getType();
} else if (arg.getKind() == TemplateArgument::Declaration ||
@@ -1185,11 +1185,9 @@
}
if (result.isInvalid()) return ExprError();
- Expr *resultExpr = result.take();
- return SemaRef.Owned(new (SemaRef.Context)
- SubstNonTypeTemplateParmExpr(type,
- resultExpr->getValueKind(),
- loc, parm, resultExpr));
+ Expr *resultExpr = result.get();
+ return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
+ type, resultExpr->getValueKind(), loc, parm, resultExpr);
}
ExprResult
@@ -1197,7 +1195,7 @@
SubstNonTypeTemplateParmPackExpr *E) {
if (getSema().ArgumentPackSubstitutionIndex == -1) {
// We aren't expanding the parameter pack, so just return ourselves.
- return getSema().Owned(E);
+ return E;
}
TemplateArgument Arg = E->getArgumentPack();
@@ -1850,7 +1848,7 @@
S.Diag(PointOfInstantiation,
diag::err_implicit_instantiate_member_undefined)
<< S.Context.getTypeDeclType(Instantiation);
- S.Diag(Pattern->getLocation(), diag::note_member_of_template_here);
+ S.Diag(Pattern->getLocation(), diag::note_member_declared_at);
} else {
S.Diag(PointOfInstantiation, diag::err_template_instantiate_undefined)
<< (TSK != TSK_ImplicitInstantiation)
@@ -2035,11 +2033,11 @@
ActOnStartCXXInClassMemberInitializer();
ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
/*CXXDirectInit=*/false);
- Expr *Init = NewInit.take();
+ Expr *Init = NewInit.get();
assert((!Init || !isa<ParenListExpr>(Init)) &&
"call-style init in class");
- ActOnFinishCXXInClassMemberInitializer(NewField, Init->getLocStart(),
- Init);
+ ActOnFinishCXXInClassMemberInitializer(NewField,
+ Init ? Init->getLocStart() : SourceLocation(), Init);
}
}
// Instantiate late parsed attributes, and attach them to their decls.
@@ -2571,7 +2569,7 @@
StmtResult
Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
if (!S)
- return Owned(S);
+ return S;
TemplateInstantiator Instantiator(*this, TemplateArgs,
SourceLocation(),
@@ -2582,7 +2580,7 @@
ExprResult
Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
if (!E)
- return Owned(E);
+ return E;
TemplateInstantiator Instantiator(*this, TemplateArgs,
SourceLocation(),
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index be2db41..c655d3f 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -79,7 +79,7 @@
EnterExpressionEvaluationContext Unevaluated(S, Sema::ConstantEvaluated);
ExprResult Result = S.SubstExpr(Aligned->getAlignmentExpr(), TemplateArgs);
if (!Result.isInvalid())
- S.AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(),
+ S.AddAlignedAttr(Aligned->getLocation(), New, Result.getAs<Expr>(),
Aligned->getSpellingListIndex(), IsPackExpansion);
} else {
TypeSourceInfo *Result = S.SubstType(Aligned->getAlignmentType(),
@@ -138,13 +138,13 @@
ExprResult Result = S.SubstExpr(A->getCond(), TemplateArgs);
if (Result.isInvalid())
return;
- Cond = Result.takeAs<Expr>();
+ Cond = Result.getAs<Expr>();
}
if (A->getCond()->isTypeDependent() && !Cond->isTypeDependent()) {
ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
if (Converted.isInvalid())
return;
- Cond = Converted.take();
+ Cond = Converted.get();
}
SmallVector<PartialDiagnosticAt, 8> Diags;
@@ -475,7 +475,7 @@
Invalid = true;
BitWidth = nullptr;
} else
- BitWidth = InstantiatedBitWidth.takeAs<Expr>();
+ BitWidth = InstantiatedBitWidth.getAs<Expr>();
}
FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(),
@@ -741,7 +741,7 @@
EnumConstantDecl *LastEnumConst = nullptr;
for (auto *EC : Pattern->enumerators()) {
// The specified value for the enumerator.
- ExprResult Value = SemaRef.Owned((Expr *)nullptr);
+ ExprResult Value((Expr *)nullptr);
if (Expr *UninstValue = EC->getInitExpr()) {
// The enumerator's value expression is a constant expression.
EnterExpressionEvaluationContext Unevaluated(SemaRef,
@@ -753,7 +753,7 @@
// Drop the initial value and continue.
bool isInvalid = false;
if (Value.isInvalid()) {
- Value = SemaRef.Owned((Expr *)nullptr);
+ Value = nullptr;
isInvalid = true;
}
@@ -1230,8 +1230,7 @@
void *InsertPos = nullptr;
FunctionDecl *SpecFunc
- = FunctionTemplate->findSpecialization(Innermost.begin(), Innermost.size(),
- InsertPos);
+ = FunctionTemplate->findSpecialization(Innermost, InsertPos);
// If we already have a function template specialization, return it.
if (SpecFunc)
@@ -1508,9 +1507,7 @@
void *InsertPos = nullptr;
FunctionDecl *SpecFunc
- = FunctionTemplate->findSpecialization(Innermost.begin(),
- Innermost.size(),
- InsertPos);
+ = FunctionTemplate->findSpecialization(Innermost, InsertPos);
// If we already have a function template specialization, return it.
if (SpecFunc)
@@ -2311,7 +2308,7 @@
OMPThreadPrivateDecl *D) {
SmallVector<Expr *, 5> Vars;
for (auto *I : D->varlists()) {
- Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).take();
+ Expr *Var = SemaRef.SubstExpr(I, TemplateArgs).get();
assert(isa<DeclRefExpr>(Var) && "threadprivate arg is not a DeclRefExpr");
Vars.push_back(Var);
}
@@ -2386,8 +2383,7 @@
// in the member template's set of class template explicit specializations.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *PrevDecl =
- InstClassTemplate->findSpecialization(Converted.data(), Converted.size(),
- InsertPos);
+ InstClassTemplate->findSpecialization(Converted, InsertPos);
// Check whether we've already seen a conflicting instantiation of this
// declaration (for instance, if there was a prior implicit instantiation).
@@ -2509,7 +2505,7 @@
// corresponds to these arguments.
void *InsertPos = nullptr;
if (VarTemplateSpecializationDecl *VarSpec = VarTemplate->findSpecialization(
- Converted.data(), Converted.size(), InsertPos))
+ Converted, InsertPos))
// If we already have a variable template specialization, return it.
return VarSpec;
@@ -2520,7 +2516,7 @@
Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
VarTemplateDecl *VarTemplate, VarDecl *D, void *InsertPos,
const TemplateArgumentListInfo &TemplateArgsInfo,
- llvm::ArrayRef<TemplateArgument> Converted) {
+ ArrayRef<TemplateArgument> Converted) {
// If this is the variable for an anonymous struct or union,
// instantiate the anonymous struct/union type first.
@@ -2674,8 +2670,7 @@
// in the member template's set of class template partial specializations.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->findPartialSpecialization(Converted.data(),
- Converted.size(), InsertPos);
+ = ClassTemplate->findPartialSpecialization(Converted, InsertPos);
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
@@ -2799,8 +2794,7 @@
// in the member template's set of variable template partial specializations.
void *InsertPos = nullptr;
VarTemplateSpecializationDecl *PrevDecl =
- VarTemplate->findPartialSpecialization(Converted.data(), Converted.size(),
- InsertPos);
+ VarTemplate->findPartialSpecialization(Converted, InsertPos);
// Build the canonical type that describes the converted template
// arguments of the variable template partial specialization.
@@ -3127,13 +3121,13 @@
E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart());
if (E.isUsable()) {
- NoexceptExpr = E.take();
+ NoexceptExpr = E.get();
if (!NoexceptExpr->isTypeDependent() &&
!NoexceptExpr->isValueDependent())
NoexceptExpr
= SemaRef.VerifyIntegerConstantExpression(NoexceptExpr,
nullptr, diag::err_noexcept_needs_constant_expression,
- /*AllowFold*/ false).take();
+ /*AllowFold*/ false).get();
}
}
@@ -3377,8 +3371,16 @@
!PatternDecl->getReturnType()->getContainedAutoType())
return;
- if (PatternDecl->isInlined())
- Function->setImplicitlyInline();
+ if (PatternDecl->isInlined()) {
+ // Function, and all later redeclarations of it (from imported modules,
+ // for instance), are now implicitly inline.
+ for (auto *D = Function->getMostRecentDecl(); /**/;
+ D = D->getPreviousDecl()) {
+ D->setImplicitlyInline();
+ if (D == Function)
+ break;
+ }
+ }
InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
if (Inst.isInvalid())
@@ -3675,9 +3677,14 @@
OldVar->getInitStyle() == VarDecl::CallInit);
if (!Init.isInvalid()) {
bool TypeMayContainAuto = true;
- if (Init.get()) {
+ Expr *InitExpr = Init.get();
+
+ if (Var->hasAttr<DLLImportAttr>() && InitExpr &&
+ !InitExpr->isConstantInitializer(getASTContext(), false)) {
+ // Do not dynamically initialize dllimport variables.
+ } else if (InitExpr) {
bool DirectInit = OldVar->isDirectInit();
- AddInitializerToDecl(Var, Init.take(), DirectInit, TypeMayContainAuto);
+ AddInitializerToDecl(Var, InitExpr, DirectInit, TypeMayContainAuto);
} else
ActOnUninitializedDecl(Var, TypeMayContainAuto);
} else {
@@ -4056,7 +4063,7 @@
// Build the initializer.
MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),
- BaseTInfo, TempInit.take(),
+ BaseTInfo, TempInit.get(),
New->getParent(),
SourceLocation());
if (NewInit.isInvalid()) {
@@ -4091,10 +4098,10 @@
}
if (Init->isBaseInitializer())
- NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.take(),
+ NewInit = BuildBaseInitializer(TInfo->getType(), TInfo, TempInit.get(),
New->getParent(), EllipsisLoc);
else
- NewInit = BuildDelegatingInitializer(TInfo, TempInit.take(),
+ NewInit = BuildDelegatingInitializer(TInfo, TempInit.get(),
cast<CXXRecordDecl>(CurContext->getParent()));
} else if (Init->isMemberInitializer()) {
FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl(
@@ -4107,7 +4114,7 @@
continue;
}
- NewInit = BuildMemberInitializer(Member, TempInit.take(),
+ NewInit = BuildMemberInitializer(Member, TempInit.get(),
Init->getSourceLocation());
} else if (Init->isIndirectMemberInitializer()) {
IndirectFieldDecl *IndirectMember =
@@ -4121,7 +4128,7 @@
continue;
}
- NewInit = BuildMemberInitializer(IndirectMember, TempInit.take(),
+ NewInit = BuildMemberInitializer(IndirectMember, TempInit.get(),
Init->getSourceLocation());
}
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 9480c11..8e4ce0d 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -509,8 +509,8 @@
}
// Create the pack expansion expression and source-location information.
- return Owned(new (Context) PackExpansionExpr(Context.DependentTy, Pattern,
- EllipsisLoc, NumExpansions));
+ return new (Context)
+ PackExpansionExpr(Context.DependentTy, Pattern, EllipsisLoc, NumExpansions);
}
/// \brief Retrieve the depth and index of a parameter pack.
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index dec2b17..be1191c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1566,7 +1566,7 @@
if (ArraySize && ArraySize->hasPlaceholderType()) {
ExprResult Result = CheckPlaceholderExpr(ArraySize);
if (Result.isInvalid()) return QualType();
- ArraySize = Result.take();
+ ArraySize = Result.get();
}
// Do lvalue-to-rvalue conversions on the array size expression.
@@ -1575,7 +1575,7 @@
if (Result.isInvalid())
return QualType();
- ArraySize = Result.take();
+ ArraySize = Result.get();
}
// C99 6.7.5.2p1: The size expression shall have integer type.
@@ -1763,7 +1763,7 @@
}
QualType Sema::BuildFunctionType(QualType T,
- llvm::MutableArrayRef<QualType> ParamTypes,
+ MutableArrayRef<QualType> ParamTypes,
SourceLocation Loc, DeclarationName Entity,
const FunctionProtoType::ExtProtoInfo &EPI) {
bool Invalid = false;
@@ -1989,18 +1989,15 @@
// TODO: mark whether we did this inference?
}
-static void diagnoseIgnoredQualifiers(
- Sema &S, unsigned Quals,
- SourceLocation FallbackLoc,
- SourceLocation ConstQualLoc = SourceLocation(),
- SourceLocation VolatileQualLoc = SourceLocation(),
- SourceLocation RestrictQualLoc = SourceLocation(),
- SourceLocation AtomicQualLoc = SourceLocation()) {
+void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
+ SourceLocation FallbackLoc,
+ SourceLocation ConstQualLoc,
+ SourceLocation VolatileQualLoc,
+ SourceLocation RestrictQualLoc,
+ SourceLocation AtomicQualLoc) {
if (!Quals)
return;
- const SourceManager &SM = S.getSourceManager();
-
struct Qual {
unsigned Mask;
const char *Name;
@@ -2027,7 +2024,8 @@
SourceLocation QualLoc = QualKinds[I].Loc;
if (!QualLoc.isInvalid()) {
FixIts[NumQuals] = FixItHint::CreateRemoval(QualLoc);
- if (Loc.isInvalid() || SM.isBeforeInTranslationUnit(QualLoc, Loc))
+ if (Loc.isInvalid() ||
+ getSourceManager().isBeforeInTranslationUnit(QualLoc, Loc))
Loc = QualLoc;
}
@@ -2035,19 +2033,20 @@
}
}
- S.Diag(Loc.isInvalid() ? FallbackLoc : Loc, diag::warn_qual_return_type)
+ Diag(Loc.isInvalid() ? FallbackLoc : Loc, DiagID)
<< QualStr << NumQuals << FixIts[0] << FixIts[1] << FixIts[2] << FixIts[3];
}
// Diagnose pointless type qualifiers on the return type of a function.
-static void diagnoseIgnoredFunctionQualifiers(Sema &S, QualType RetTy,
- Declarator &D,
- unsigned FunctionChunkIndex) {
+static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
+ Declarator &D,
+ unsigned FunctionChunkIndex) {
if (D.getTypeObject(FunctionChunkIndex).Fun.hasTrailingReturnType()) {
// FIXME: TypeSourceInfo doesn't preserve location information for
// qualifiers.
- diagnoseIgnoredQualifiers(S, RetTy.getLocalCVRQualifiers(),
- D.getIdentifierLoc());
+ S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+ RetTy.getLocalCVRQualifiers(),
+ D.getIdentifierLoc());
return;
}
@@ -2061,8 +2060,9 @@
case DeclaratorChunk::Pointer: {
DeclaratorChunk::PointerTypeInfo &PTI = OuterChunk.Ptr;
- diagnoseIgnoredQualifiers(
- S, PTI.TypeQuals,
+ S.diagnoseIgnoredQualifiers(
+ diag::warn_qual_return_type,
+ PTI.TypeQuals,
SourceLocation(),
SourceLocation::getFromRawEncoding(PTI.ConstQualLoc),
SourceLocation::getFromRawEncoding(PTI.VolatileQualLoc),
@@ -2079,8 +2079,9 @@
// FIXME: We can't currently provide an accurate source location and a
// fix-it hint for these.
unsigned AtomicQual = RetTy->isAtomicType() ? DeclSpec::TQ_atomic : 0;
- diagnoseIgnoredQualifiers(S, RetTy.getCVRQualifiers() | AtomicQual,
- D.getIdentifierLoc());
+ S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+ RetTy.getCVRQualifiers() | AtomicQual,
+ D.getIdentifierLoc());
return;
}
@@ -2095,12 +2096,13 @@
// Just parens all the way out to the decl specifiers. Diagnose any qualifiers
// which are present there.
- diagnoseIgnoredQualifiers(S, D.getDeclSpec().getTypeQualifiers(),
- D.getIdentifierLoc(),
- D.getDeclSpec().getConstSpecLoc(),
- D.getDeclSpec().getVolatileSpecLoc(),
- D.getDeclSpec().getRestrictSpecLoc(),
- D.getDeclSpec().getAtomicSpecLoc());
+ S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
+ D.getDeclSpec().getTypeQualifiers(),
+ D.getIdentifierLoc(),
+ D.getDeclSpec().getConstSpecLoc(),
+ D.getDeclSpec().getVolatileSpecLoc(),
+ D.getDeclSpec().getRestrictSpecLoc(),
+ D.getDeclSpec().getAtomicSpecLoc());
}
static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
@@ -2393,9 +2395,9 @@
}
if (FTI.NumParams > 0) {
- // For a declaration with parameters, eg. "T var(T());", suggest adding parens
- // around the first parameter to turn the declaration into a variable
- // declaration.
+ // For a declaration with parameters, eg. "T var(T());", suggest adding
+ // parens around the first parameter to turn the declaration into a
+ // variable declaration.
SourceRange Range = FTI.Params[0].Param->getSourceRange();
SourceLocation B = Range.getBegin();
SourceLocation E = S.getLocForEndOfToken(Range.getEnd());
@@ -2405,8 +2407,8 @@
<< FixItHint::CreateInsertion(B, "(")
<< FixItHint::CreateInsertion(E, ")");
} else {
- // For a declaration without parameters, eg. "T var();", suggest replacing the
- // parens with an initializer to turn the declaration into a variable
+ // For a declaration without parameters, eg. "T var();", suggest replacing
+ // the parens with an initializer to turn the declaration into a variable
// declaration.
const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
@@ -2788,7 +2790,7 @@
if ((T.getCVRQualifiers() || T->isAtomicType()) &&
!(S.getLangOpts().CPlusPlus &&
(T->isDependentType() || T->isRecordType())))
- diagnoseIgnoredFunctionQualifiers(S, T, D, chunkIndex);
+ diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex);
// Objective-C ARC ownership qualifiers are ignored on the function
// return type (by type canonicalization). Complain if this attribute
@@ -5127,7 +5129,7 @@
ED = NewED;
if (ED->isFixed()) {
// If the enum has a fixed underlying type, any declaration of it will do.
- *Suggested = 0;
+ *Suggested = nullptr;
for (auto *Redecl : ED->redecls()) {
if (LookupResult::isVisible(S, Redecl))
return true;
@@ -5147,6 +5149,45 @@
return LookupResult::isVisible(S, D);
}
+/// Locks in the inheritance model for the given class and all of its bases.
+static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
+ RD = RD->getMostRecentDecl();
+ if (!RD->hasAttr<MSInheritanceAttr>()) {
+ MSInheritanceAttr::Spelling IM;
+
+ switch (S.MSPointerToMemberRepresentationMethod) {
+ case LangOptions::PPTMK_BestCase:
+ IM = RD->calculateInheritanceModel();
+ break;
+ case LangOptions::PPTMK_FullGeneralitySingleInheritance:
+ IM = MSInheritanceAttr::Keyword_single_inheritance;
+ break;
+ case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
+ IM = MSInheritanceAttr::Keyword_multiple_inheritance;
+ break;
+ case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
+ IM = MSInheritanceAttr::Keyword_unspecified_inheritance;
+ break;
+ }
+
+ RD->addAttr(MSInheritanceAttr::CreateImplicit(
+ S.getASTContext(), IM,
+ /*BestCase=*/S.MSPointerToMemberRepresentationMethod ==
+ LangOptions::PPTMK_BestCase,
+ S.ImplicitMSInheritanceAttrLoc.isValid()
+ ? S.ImplicitMSInheritanceAttrLoc
+ : RD->getSourceRange()));
+ }
+
+ if (RD->hasDefinition()) {
+ // Assign inheritance models to all of the base classes, because now we can
+ // form pointers to members of base classes without calling
+ // RequireCompleteType on the pointer to member of the base class type.
+ for (const CXXBaseSpecifier &BS : RD->bases())
+ assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl());
+ }
+}
+
/// \brief The implementation of RequireCompleteType
bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
TypeDiagnoser &Diagnoser) {
@@ -5162,7 +5203,7 @@
NamedDecl *Def = nullptr;
if (!T->isIncompleteType(&Def)) {
// If we know about the definition but it is not visible, complain.
- NamedDecl *SuggestedDef = 0;
+ NamedDecl *SuggestedDef = nullptr;
if (!Diagnoser.Suppressed && Def &&
!hasVisibleDefinition(*this, Def, &SuggestedDef)) {
// Suppress this error outside of a SFINAE context if we've already
@@ -5185,36 +5226,7 @@
if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
if (!MPTy->getClass()->isDependentType()) {
RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);
-
- CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl();
- if (!RD->hasAttr<MSInheritanceAttr>()) {
- MSInheritanceAttr::Spelling InheritanceModel;
-
- switch (MSPointerToMemberRepresentationMethod) {
- case LangOptions::PPTMK_BestCase:
- InheritanceModel = RD->calculateInheritanceModel();
- break;
- case LangOptions::PPTMK_FullGeneralitySingleInheritance:
- InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance;
- break;
- case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
- InheritanceModel =
- MSInheritanceAttr::Keyword_multiple_inheritance;
- break;
- case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
- InheritanceModel =
- MSInheritanceAttr::Keyword_unspecified_inheritance;
- break;
- }
-
- RD->addAttr(MSInheritanceAttr::CreateImplicit(
- getASTContext(), InheritanceModel,
- /*BestCase=*/MSPointerToMemberRepresentationMethod ==
- LangOptions::PPTMK_BestCase,
- ImplicitMSInheritanceAttrLoc.isValid()
- ? ImplicitMSInheritanceAttrLoc
- : RD->getSourceRange()));
- }
+ assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());
}
}
}
@@ -5461,7 +5473,7 @@
QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) {
ExprResult ER = CheckPlaceholderExpr(E);
if (ER.isInvalid()) return QualType();
- E = ER.take();
+ E = ER.get();
if (!E->isTypeDependent()) {
QualType T = E->getType();
@@ -5541,7 +5553,7 @@
QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) {
ExprResult ER = CheckPlaceholderExpr(E);
if (ER.isInvalid()) return QualType();
- E = ER.take();
+ E = ER.get();
return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
}
@@ -5557,12 +5569,23 @@
} else {
QualType Underlying = BaseType;
if (!BaseType->isDependentType()) {
+ // The enum could be incomplete if we're parsing its definition or
+ // recovering from an error.
+ NamedDecl *FwdDecl = nullptr;
+ if (BaseType->isIncompleteType(&FwdDecl)) {
+ Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
+ Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
+ return QualType();
+ }
+
EnumDecl *ED = BaseType->getAs<EnumType>()->getDecl();
assert(ED && "EnumType has no EnumDecl");
+
DiagnoseUseOfDecl(ED, Loc);
+
Underlying = ED->getIntegerType();
+ assert(!Underlying.isNull());
}
- assert(!Underlying.isNull());
return Context.getUnaryTransformType(BaseType, Underlying,
UnaryTransformType::EnumUnderlyingType);
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 3386b5b..5626ad5 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -604,8 +604,15 @@
}
ExprResult TransformAddressOfOperand(Expr *E);
+
ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
- bool IsAddressOfOperand);
+ bool IsAddressOfOperand,
+ TypeSourceInfo **RecoveryTSI);
+
+ ExprResult TransformParenDependentScopeDeclRefExpr(
+ ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
+ TypeSourceInfo **RecoveryTSI);
+
StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
@@ -743,7 +750,7 @@
/// By default, performs semantic analysis when building the function type.
/// Subclasses may override this routine to provide different behavior.
QualType RebuildFunctionProtoType(QualType T,
- llvm::MutableArrayRef<QualType> ParamTypes,
+ MutableArrayRef<QualType> ParamTypes,
const FunctionProtoType::ExtProtoInfo &EPI);
/// \brief Build a new unprototyped function type.
@@ -1194,7 +1201,7 @@
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- StmtResult RebuildDeclStmt(llvm::MutableArrayRef<Decl *> Decls,
+ StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
SourceLocation StartLoc, SourceLocation EndLoc) {
Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
@@ -1301,7 +1308,7 @@
/// \brief Build a new OpenMP 'if' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPIfClause(Expr *Condition,
SourceLocation StartLoc,
@@ -1313,7 +1320,7 @@
/// \brief Build a new OpenMP 'num_threads' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
SourceLocation StartLoc,
@@ -1325,7 +1332,7 @@
/// \brief Build a new OpenMP 'safelen' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1335,7 +1342,7 @@
/// \brief Build a new OpenMP 'collapse' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1346,7 +1353,7 @@
/// \brief Build a new OpenMP 'default' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind,
SourceLocation KindKwLoc,
@@ -1359,7 +1366,7 @@
/// \brief Build a new OpenMP 'proc_bind' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPProcBindClause(OpenMPProcBindClauseKind Kind,
SourceLocation KindKwLoc,
@@ -1370,9 +1377,24 @@
StartLoc, LParenLoc, EndLoc);
}
+ /// \brief Build a new OpenMP 'schedule' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPScheduleClause(OpenMPScheduleClauseKind Kind,
+ Expr *ChunkSize,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation KindLoc,
+ SourceLocation CommaLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPScheduleClause(
+ Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
+ }
+
/// \brief Build a new OpenMP 'private' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -1384,7 +1406,7 @@
/// \brief Build a new OpenMP 'firstprivate' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -1394,9 +1416,21 @@
EndLoc);
}
+ /// \brief Build a new OpenMP 'lastprivate' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc,
+ EndLoc);
+ }
+
/// \brief Build a new OpenMP 'shared' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -1406,10 +1440,26 @@
EndLoc);
}
- /// \brief Build a new OpenMP 'linear' clause.
+ /// \brief Build a new OpenMP 'reduction' clause.
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPReductionClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec,
+ const DeclarationNameInfo &ReductionId) {
+ return getSema().ActOnOpenMPReductionClause(
+ VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
+ ReductionId);
+ }
+
+ /// \brief Build a new OpenMP 'linear' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -1419,9 +1469,22 @@
ColonLoc, EndLoc);
}
+ /// \brief Build a new OpenMP 'aligned' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
+ LParenLoc, ColonLoc, EndLoc);
+ }
+
/// \brief Build a new OpenMP 'copyin' clause.
///
- /// By default, performs semantic analysis to build the new statement.
+ /// By default, performs semantic analysis to build the new OpenMP clause.
/// Subclasses may override this routine to provide different behavior.
OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
SourceLocation StartLoc,
@@ -1431,6 +1494,18 @@
EndLoc);
}
+ /// \brief Build a new OpenMP 'copyprivate' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
+ SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
+ EndLoc);
+ }
+
/// \brief Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -1474,7 +1549,7 @@
if (ForEachStmt.isInvalid())
return StmtError();
- return getSema().FinishObjCForCollectionStmt(ForEachStmt.take(), Body);
+ return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
}
/// \brief Build a new C++ exception declaration.
@@ -1729,25 +1804,25 @@
"unnamed member not of record type?");
BaseResult =
- getSema().PerformObjectMemberConversion(BaseResult.take(),
+ getSema().PerformObjectMemberConversion(BaseResult.get(),
QualifierLoc.getNestedNameSpecifier(),
FoundDecl, Member);
if (BaseResult.isInvalid())
return ExprError();
- Base = BaseResult.take();
+ Base = BaseResult.get();
ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
MemberExpr *ME =
new (getSema().Context) MemberExpr(Base, isArrow,
Member, MemberNameInfo,
cast<FieldDecl>(Member)->getType(),
VK, OK_Ordinary);
- return getSema().Owned(ME);
+ return ME;
}
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
- Base = BaseResult.take();
+ Base = BaseResult.get();
QualType BaseType = Base->getType();
// FIXME: this involves duplicating earlier analysis in a lot of
@@ -1872,7 +1947,7 @@
/// any semantic analysis. Subclasses may override this routine to provide
/// different behavior.
ExprResult RebuildImplicitValueInitExpr(QualType T) {
- return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
+ return new (SemaRef.Context) ImplicitValueInitExpr(T);
}
/// \brief Build a new \c va_arg expression.
@@ -2137,9 +2212,7 @@
QualType ThisType,
bool isImplicit) {
getSema().CheckCXXThisCapture(ThisLoc);
- return getSema().Owned(
- new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
- isImplicit));
+ return new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, isImplicit);
}
/// \brief Build a new C++ throw expression.
@@ -2158,8 +2231,7 @@
/// provide different behavior.
ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
ParmVarDecl *Param) {
- return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
- Param));
+ return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param);
}
/// \brief Build a new C++11 default-initialization expression.
@@ -2169,8 +2241,7 @@
/// routine to provide different behavior.
ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
FieldDecl *Field) {
- return getSema().Owned(CXXDefaultInitExpr::Create(getSema().Context, Loc,
- Field));
+ return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field);
}
/// \brief Build a new C++ zero-initialization expression.
@@ -2267,16 +2338,17 @@
SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs,
- bool IsAddressOfOperand) {
+ bool IsAddressOfOperand,
+ TypeSourceInfo **RecoveryTSI) {
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
if (TemplateArgs || TemplateKWLoc.isValid())
- return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc,
- NameInfo, TemplateArgs);
+ return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
+ TemplateArgs);
- return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo,
- IsAddressOfOperand);
+ return getSema().BuildQualifiedDeclarationNameExpr(
+ SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
}
/// \brief Build a new template-id expression.
@@ -2459,8 +2531,7 @@
ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
TypeSourceInfo *EncodeTypeInfo,
SourceLocation RParenLoc) {
- return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
- RParenLoc));
+ return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
}
/// \brief Build a new Objective-C class message.
@@ -2502,24 +2573,12 @@
bool IsArrow, bool IsFreeIvar) {
// FIXME: We lose track of the IsFreeIvar bit.
CXXScopeSpec SS;
- ExprResult Base = getSema().Owned(BaseArg);
- LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
- Sema::LookupMemberName);
- ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
- /*FIME:*/IvarLoc,
- SS, nullptr,
- false);
- if (Result.isInvalid() || Base.isInvalid())
- return ExprError();
-
- if (Result.get())
- return Result;
-
- return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
+ DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
+ return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
/*FIXME:*/IvarLoc, IsArrow,
SS, SourceLocation(),
/*FirstQualifierInScope=*/nullptr,
- R,
+ NameInfo,
/*TemplateArgs=*/nullptr);
}
@@ -2531,24 +2590,14 @@
ObjCPropertyDecl *Property,
SourceLocation PropertyLoc) {
CXXScopeSpec SS;
- ExprResult Base = getSema().Owned(BaseArg);
- LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
- Sema::LookupMemberName);
- bool IsArrow = false;
- ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
- /*FIME:*/PropertyLoc,
- SS, nullptr, false);
- if (Result.isInvalid() || Base.isInvalid())
- return ExprError();
-
- if (Result.get())
- return Result;
-
- return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
- /*FIXME:*/PropertyLoc, IsArrow,
+ DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
+ return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
+ /*FIXME:*/PropertyLoc,
+ /*IsArrow=*/false,
SS, SourceLocation(),
/*FirstQualifierInScope=*/nullptr,
- R, /*TemplateArgs=*/nullptr);
+ NameInfo,
+ /*TemplateArgs=*/nullptr);
}
/// \brief Build a new Objective-C property reference expression.
@@ -2572,26 +2621,14 @@
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
- SourceLocation OpLoc,
- bool IsArrow) {
+ SourceLocation OpLoc, bool IsArrow) {
CXXScopeSpec SS;
- ExprResult Base = getSema().Owned(BaseArg);
- LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
- Sema::LookupMemberName);
- ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
- OpLoc,
- SS, nullptr, false);
- if (Result.isInvalid() || Base.isInvalid())
- return ExprError();
-
- if (Result.get())
- return Result;
-
- return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
+ DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
+ return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
OpLoc, IsArrow,
SS, SourceLocation(),
/*FirstQualifierInScope=*/nullptr,
- R,
+ NameInfo,
/*TemplateArgs=*/nullptr);
}
@@ -2616,15 +2653,15 @@
VK_RValue, BuiltinLoc);
QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
- CK_BuiltinFnToFnPtr).take();
+ CK_BuiltinFnToFnPtr).get();
// Build the CallExpr
- ExprResult TheCall = SemaRef.Owned(new (SemaRef.Context) CallExpr(
+ ExprResult TheCall = new (SemaRef.Context) CallExpr(
SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
- Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc));
+ Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc);
// Type-check the __builtin_shufflevector expression.
- return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take()));
+ return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
}
/// \brief Build a new convert vector expression.
@@ -2728,7 +2765,7 @@
template<typename Derived>
StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
if (!S)
- return SemaRef.Owned(S);
+ return S;
switch (S->getStmtClass()) {
case Stmt::NoStmtClass: break;
@@ -2754,7 +2791,7 @@
}
}
- return SemaRef.Owned(S);
+ return S;
}
template<typename Derived>
@@ -2778,7 +2815,7 @@
template<typename Derived>
ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
if (!E)
- return SemaRef.Owned(E);
+ return E;
switch (E->getStmtClass()) {
case Stmt::NoStmtClass: break;
@@ -2789,7 +2826,7 @@
#include "clang/AST/StmtNodes.inc"
}
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -2798,7 +2835,7 @@
// Initializers are instantiated like expressions, except that various outer
// layers are stripped.
if (!Init)
- return SemaRef.Owned(Init);
+ return Init;
if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
Init = ExprTemp->getSubExpr();
@@ -2926,9 +2963,11 @@
if (Out.isInvalid())
return true;
+ // FIXME: Can this happen? We should not try to expand the pack
+ // in this case.
if (Out.get()->containsUnexpandedParameterPack()) {
- Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(),
- OrigNumExpansions);
+ Out = getDerived().RebuildPackExpansion(
+ Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
if (Out.isInvalid())
return true;
}
@@ -2936,6 +2975,23 @@
Outputs.push_back(Out.get());
}
+ // If we're supposed to retain a pack expansion, do so by temporarily
+ // forgetting the partially-substituted parameter pack.
+ if (RetainExpansion) {
+ ForgetPartiallySubstitutedPackRAII Forget(getDerived());
+
+ ExprResult Out = getDerived().TransformExpr(Pattern);
+ if (Out.isInvalid())
+ return true;
+
+ Out = getDerived().RebuildPackExpansion(
+ Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
+ if (Out.isInvalid())
+ return true;
+
+ Outputs.push_back(Out.get());
+ }
+
continue;
}
@@ -3304,7 +3360,7 @@
ExprResult E = getDerived().TransformExpr(InputExpr);
E = SemaRef.ActOnConstantExpression(E);
if (E.isInvalid()) return true;
- Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
+ Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
return false;
}
}
@@ -3951,8 +4007,8 @@
if (Size) {
EnterExpressionEvaluationContext Unevaluated(SemaRef,
Sema::ConstantEvaluated);
- Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
- Size = SemaRef.ActOnConstantExpression(Size).take();
+ Size = getDerived().TransformExpr(Size).template getAs<Expr>();
+ Size = SemaRef.ActOnConstantExpression(Size).get();
}
NewTL.setSizeExpr(Size);
@@ -4001,7 +4057,7 @@
if (SizeResult.isInvalid())
return QualType();
- Expr *Size = SizeResult.take();
+ Expr *Size = SizeResult.get();
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() ||
@@ -4099,7 +4155,7 @@
ElementType != T->getElementType() ||
Size.get() != T->getSizeExpr()) {
Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
- Size.take(),
+ Size.get(),
T->getAttributeLoc());
if (Result.isNull())
return QualType();
@@ -4588,7 +4644,7 @@
if (Result.isNull())
return QualType();
}
- else E.take();
+ else E.get();
TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
NewTL.setTypeofLoc(TL.getTypeofLoc());
@@ -4635,7 +4691,7 @@
if (E.isInvalid())
return QualType();
- E = getSema().ActOnDecltypeExpression(E.take());
+ E = getSema().ActOnDecltypeExpression(E.get());
if (E.isInvalid())
return QualType();
@@ -4646,7 +4702,7 @@
if (Result.isNull())
return QualType();
}
- else E.take();
+ else E.get();
DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
@@ -5313,7 +5369,7 @@
template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
- return SemaRef.Owned(S);
+ return S;
}
template<typename Derived>
@@ -5345,7 +5401,7 @@
}
SubStmtChanged = SubStmtChanged || Result.get() != B;
- Statements.push_back(Result.takeAs<Stmt>());
+ Statements.push_back(Result.getAs<Stmt>());
}
if (SubStmtInvalid)
@@ -5353,7 +5409,7 @@
if (!getDerived().AlwaysRebuild() &&
!SubStmtChanged)
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
Statements,
@@ -5481,7 +5537,7 @@
}
}
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
return StmtError();
@@ -5500,7 +5556,7 @@
ConditionVar == S->getConditionVariable() &&
Then.get() == S->getThen() &&
Else.get() == S->getElse())
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
Then.get(),
@@ -5576,7 +5632,7 @@
}
}
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
return StmtError();
@@ -5611,7 +5667,7 @@
if (!getDerived().AlwaysRebuild() &&
Cond.get() == S->getCond() &&
Body.get() == S->getBody())
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
/*FIXME:*/S->getWhileLoc(), Cond.get(),
@@ -5655,7 +5711,7 @@
}
}
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+ Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get()));
if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
return StmtError();
@@ -5678,7 +5734,7 @@
FullCond.get() == S->getCond() &&
Inc.get() == S->getInc() &&
Body.get() == S->getBody())
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
Init.get(), FullCond, ConditionVar,
@@ -5704,11 +5760,11 @@
ExprResult Target = getDerived().TransformExpr(S->getTarget());
if (Target.isInvalid())
return StmtError();
- Target = SemaRef.MaybeCreateExprWithCleanups(Target.take());
+ Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
if (!getDerived().AlwaysRebuild() &&
Target.get() == S->getTarget())
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
Target.get());
@@ -5717,13 +5773,13 @@
template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
- return SemaRef.Owned(S);
+ return S;
}
template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
- return SemaRef.Owned(S);
+ return S;
}
template<typename Derived>
@@ -5755,7 +5811,7 @@
}
if (!getDerived().AlwaysRebuild() && !DeclChanged)
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildDeclStmt(Decls, S->getStartLoc(), S->getEndLoc());
}
@@ -5810,14 +5866,14 @@
}
if (!getDerived().AlwaysRebuild() && !ExprsChanged)
- return SemaRef.Owned(S);
+ return S;
// Go through the clobbers.
for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
Clobbers.push_back(S->getClobberStringLiteral(I));
// No need to transform the asm string literal.
- AsmString = SemaRef.Owned(S->getAsmString());
+ AsmString = S->getAsmString();
return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
S->isVolatile(), S->getNumOutputs(),
S->getNumInputs(), Names.data(),
@@ -5842,7 +5898,7 @@
HadError = true;
} else {
HadChange |= (Result.get() != SrcExprs[i]);
- TransformedExprs.push_back(Result.take());
+ TransformedExprs.push_back(Result.get());
}
}
@@ -5874,7 +5930,7 @@
return StmtError();
if (Catch.get() != S->getCatchStmt(I))
AnyCatchChanged = true;
- CatchStmts.push_back(Catch.release());
+ CatchStmts.push_back(Catch.get());
}
// Transform the @finally statement (if present).
@@ -5890,7 +5946,7 @@
TryBody.get() == S->getTryBody() &&
!AnyCatchChanged &&
Finally.get() == S->getFinallyStmt())
- return SemaRef.Owned(S);
+ return S;
// Build a new statement.
return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
@@ -5944,7 +6000,7 @@
// If nothing changed, just retain this statement.
if (!getDerived().AlwaysRebuild() &&
Body.get() == S->getFinallyBody())
- return SemaRef.Owned(S);
+ return S;
// Build a new statement.
return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
@@ -5963,7 +6019,7 @@
if (!getDerived().AlwaysRebuild() &&
Operand.get() == S->getThrowExpr())
- return getSema().Owned(S);
+ return S;
return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
}
@@ -5991,7 +6047,7 @@
if (!getDerived().AlwaysRebuild() &&
Object.get() == S->getSynchExpr() &&
Body.get() == S->getSynchBody())
- return SemaRef.Owned(S);
+ return S;
// Build a new statement.
return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
@@ -6010,7 +6066,7 @@
// If nothing changed, just retain this statement.
if (!getDerived().AlwaysRebuild() &&
Body.get() == S->getSubStmt())
- return SemaRef.Owned(S);
+ return S;
// Build a new statement.
return getDerived().RebuildObjCAutoreleasePoolStmt(
@@ -6041,7 +6097,7 @@
Element.get() == S->getElement() &&
Collection.get() == S->getCollection() &&
Body.get() == S->getBody())
- return SemaRef.Owned(S);
+ return S;
// Build a new statement.
return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
@@ -6075,7 +6131,7 @@
if (!getDerived().AlwaysRebuild() && !Var &&
Handler.get() == S->getHandlerBlock())
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
}
@@ -6096,12 +6152,12 @@
return StmtError();
HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
- Handlers.push_back(Handler.takeAs<Stmt>());
+ Handlers.push_back(Handler.getAs<Stmt>());
}
if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
!HandlerChanged)
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
Handlers);
@@ -6122,17 +6178,17 @@
if (Cond.isInvalid())
return StmtError();
if (Cond.get())
- Cond = SemaRef.CheckBooleanCondition(Cond.take(), S->getColonLoc());
+ Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());
if (Cond.isInvalid())
return StmtError();
if (Cond.get())
- Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.take());
+ Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
ExprResult Inc = getDerived().TransformExpr(S->getInc());
if (Inc.isInvalid())
return StmtError();
if (Inc.get())
- Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.take());
+ Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
if (LoopVar.isInvalid())
@@ -6171,7 +6227,7 @@
}
if (NewStmt.get() == S)
- return SemaRef.Owned(S);
+ return S;
return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
}
@@ -6283,10 +6339,10 @@
if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
Handler.get() == S->getHandler())
- return SemaRef.Owned(S);
+ return S;
return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
- TryBlock.take(), Handler.take());
+ TryBlock.get(), Handler.get());
}
template <typename Derived>
@@ -6295,7 +6351,7 @@
if (Block.isInvalid())
return StmtError();
- return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.take());
+ return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
}
template <typename Derived>
@@ -6308,8 +6364,8 @@
if (Block.isInvalid())
return StmtError();
- return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.take(),
- Block.take());
+ return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
+ Block.get());
}
template <typename Derived>
@@ -6322,8 +6378,16 @@
template<typename Derived>
StmtResult
-TreeTransform<Derived>::TransformOMPExecutableDirective(
- OMPExecutableDirective *D) {
+TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
+ return S;
+}
+
+//===----------------------------------------------------------------------===//
+// OpenMP directive transformation
+//===----------------------------------------------------------------------===//
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
+ OMPExecutableDirective *D) {
// Transform the clauses
llvm::SmallVector<OMPClause *, 16> TClauses;
@@ -6333,12 +6397,9 @@
I != E; ++I) {
if (*I) {
OMPClause *Clause = getDerived().TransformOMPClause(*I);
- if (!Clause) {
- return StmtError();
- }
- TClauses.push_back(Clause);
- }
- else {
+ if (Clause)
+ TClauses.push_back(Clause);
+ } else {
TClauses.push_back(nullptr);
}
}
@@ -6346,58 +6407,124 @@
return StmtError();
}
StmtResult AssociatedStmt =
- getDerived().TransformStmt(D->getAssociatedStmt());
- if (AssociatedStmt.isInvalid()) {
+ getDerived().TransformStmt(D->getAssociatedStmt());
+ if (AssociatedStmt.isInvalid() || TClauses.size() != Clauses.size()) {
return StmtError();
}
- return getDerived().RebuildOMPExecutableDirective(D->getDirectiveKind(),
- TClauses,
- AssociatedStmt.take(),
- D->getLocStart(),
- D->getLocEnd());
+ return getDerived().RebuildOMPExecutableDirective(
+ D->getDirectiveKind(), TClauses, AssociatedStmt.get(), D->getLocStart(),
+ D->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
DeclarationNameInfo DirName;
- getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr);
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
+ D->getLocStart());
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
getDerived().getSema().EndOpenMPDSABlock(Res.get());
return Res;
}
-template<typename Derived>
+template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
DeclarationNameInfo DirName;
- getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr);
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
+ D->getLocStart());
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
getDerived().getSema().EndOpenMPDSABlock(Res.get());
return Res;
}
-template<typename Derived>
-OMPClause *
-TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
+ D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
+ D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
+ D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
+ D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
+ OMPParallelForDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
+ nullptr, D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+template <typename Derived>
+StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
+ OMPParallelSectionsDirective *D) {
+ DeclarationNameInfo DirName;
+ getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
+ nullptr, D->getLocStart());
+ StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
+ getDerived().getSema().EndOpenMPDSABlock(Res.get());
+ return Res;
+}
+
+//===----------------------------------------------------------------------===//
+// OpenMP clause transformation
+//===----------------------------------------------------------------------===//
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
ExprResult Cond = getDerived().TransformExpr(C->getCondition());
if (Cond.isInvalid())
return nullptr;
- return getDerived().RebuildOMPIfClause(Cond.take(), C->getLocStart(),
+ return getDerived().RebuildOMPIfClause(Cond.get(), C->getLocStart(),
C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
if (NumThreads.isInvalid())
return nullptr;
- return getDerived().RebuildOMPNumThreadsClause(NumThreads.take(),
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPNumThreadsClause(
+ NumThreads.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
template <typename Derived>
@@ -6407,7 +6534,7 @@
if (E.isInvalid())
return nullptr;
return getDerived().RebuildOMPSafelenClause(
- E.take(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+ E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
template <typename Derived>
@@ -6417,30 +6544,51 @@
if (E.isInvalid())
return 0;
return getDerived().RebuildOMPCollapseClause(
- E.take(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+ E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
- return getDerived().RebuildOMPDefaultClause(C->getDefaultKind(),
- C->getDefaultKindKwLoc(),
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPDefaultClause(
+ C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getLocStart(),
+ C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
- return getDerived().RebuildOMPProcBindClause(C->getProcBindKind(),
- C->getProcBindKindKwLoc(),
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPProcBindClause(
+ C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getLocStart(),
+ C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
+ ExprResult E = getDerived().TransformExpr(C->getChunkSize());
+ if (E.isInvalid())
+ return nullptr;
+ return getDerived().RebuildOMPScheduleClause(
+ C->getScheduleKind(), E.get(), C->getLocStart(), C->getLParenLoc(),
+ C->getScheduleKindLoc(), C->getCommaLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
+ // No need to rebuild this clause, no template-dependent parameters.
+ return C;
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
+ // No need to rebuild this clause, no template-dependent parameters.
+ return C;
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
@@ -6449,33 +6597,43 @@
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
if (EVar.isInvalid())
return nullptr;
- Vars.push_back(EVar.take());
+ Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPPrivateClause(Vars,
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPPrivateClause(
+ Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
-OMPClause *
-TreeTransform<Derived>::TransformOMPFirstprivateClause(
- OMPFirstprivateClause *C) {
+template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
+ OMPFirstprivateClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
Vars.reserve(C->varlist_size());
for (auto *VE : C->varlists()) {
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
if (EVar.isInvalid())
return nullptr;
- Vars.push_back(EVar.take());
+ Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPFirstprivateClause(Vars,
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPFirstprivateClause(
+ Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ return getDerived().RebuildOMPLastprivateClause(
+ Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
@@ -6484,15 +6642,38 @@
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
if (EVar.isInvalid())
return nullptr;
- Vars.push_back(EVar.take());
+ Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPSharedClause(Vars,
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPSharedClause(Vars, C->getLocStart(),
+ C->getLParenLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ CXXScopeSpec ReductionIdScopeSpec;
+ ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
+
+ DeclarationNameInfo NameInfo = C->getNameInfo();
+ if (NameInfo.getName()) {
+ NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+ if (!NameInfo.getName())
+ return nullptr;
+ }
+ return getDerived().RebuildOMPReductionClause(
+ Vars, C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
+ C->getLocEnd(), ReductionIdScopeSpec, NameInfo);
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
@@ -6501,17 +6682,36 @@
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
if (EVar.isInvalid())
return nullptr;
- Vars.push_back(EVar.take());
+ Vars.push_back(EVar.get());
}
ExprResult Step = getDerived().TransformExpr(C->getStep());
if (Step.isInvalid())
return nullptr;
- return getDerived().RebuildOMPLinearClause(
- Vars, Step.take(), C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPLinearClause(Vars, Step.get(), C->getLocStart(),
+ C->getLParenLoc(),
+ C->getColonLoc(), C->getLocEnd());
}
-template<typename Derived>
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
+ if (Alignment.isInvalid())
+ return nullptr;
+ return getDerived().RebuildOMPAlignedClause(
+ Vars, Alignment.get(), C->getLocStart(), C->getLParenLoc(),
+ C->getColonLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
@@ -6520,12 +6720,25 @@
ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
if (EVar.isInvalid())
return nullptr;
- Vars.push_back(EVar.take());
+ Vars.push_back(EVar.get());
}
- return getDerived().RebuildOMPCopyinClause(Vars,
- C->getLocStart(),
- C->getLParenLoc(),
- C->getLocEnd());
+ return getDerived().RebuildOMPCopyinClause(Vars, C->getLocStart(),
+ C->getLParenLoc(), C->getLocEnd());
+}
+
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ return getDerived().RebuildOMPCopyprivateClause(
+ Vars, C->getLocStart(), C->getLParenLoc(), C->getLocEnd());
}
//===----------------------------------------------------------------------===//
@@ -6534,7 +6747,7 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -6571,7 +6784,7 @@
// FIXME: this is a bit instantiation-specific.
SemaRef.MarkDeclRefReferenced(E);
- return SemaRef.Owned(E);
+ return E;
}
TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
@@ -6592,31 +6805,31 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -6651,13 +6864,13 @@
ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
if (AssocExpr.isInvalid())
return ExprError();
- AssocExprs.push_back(AssocExpr.release());
+ AssocExprs.push_back(AssocExpr.get());
}
return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
E->getDefaultLoc(),
E->getRParenLoc(),
- ControllingExpr.release(),
+ ControllingExpr.get(),
AssocTypes,
AssocExprs);
}
@@ -6670,7 +6883,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
E->getRParen());
@@ -6683,7 +6896,7 @@
ExprResult
TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
- return getDerived().TransformDependentScopeDeclRefExpr(DRE, true);
+ return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
else
return getDerived().TransformExpr(E);
}
@@ -6700,7 +6913,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
E->getOpcode(),
@@ -6765,7 +6978,7 @@
if (!getDerived().AlwaysRebuild() &&
Type == E->getTypeSourceInfo() &&
!ExprChanged)
- return SemaRef.Owned(E);
+ return E;
// Build a new offsetof expression.
return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
@@ -6778,7 +6991,7 @@
TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
assert(getDerived().AlreadyTransformed(E->getType()) &&
"opaque value expression requires transformation");
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -6798,7 +7011,7 @@
// expression must have been an lvalue-to-rvalue conversion which we
// should reapply.
if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
- result = SemaRef.checkPseudoObjectRValue(result.take());
+ result = SemaRef.checkPseudoObjectRValue(result.get());
return result;
}
@@ -6815,7 +7028,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && OldT == NewT)
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
E->getKind(),
@@ -6828,12 +7041,26 @@
EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
Sema::ReuseLambdaContextDecl);
- ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
- if (SubExpr.isInvalid())
+ // Try to recover if we have something like sizeof(T::X) where X is a type.
+ // Notably, there must be *exactly* one set of parens if X is a type.
+ TypeSourceInfo *RecoveryTSI = nullptr;
+ ExprResult SubExpr;
+ auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
+ if (auto *DRE =
+ PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
+ SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
+ PE, DRE, false, &RecoveryTSI);
+ else
+ SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
+
+ if (RecoveryTSI) {
+ return getDerived().RebuildUnaryExprOrTypeTrait(
+ RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
+ } else if (SubExpr.isInvalid())
return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
E->getOperatorLoc(),
@@ -6856,7 +7083,7 @@
if (!getDerived().AlwaysRebuild() &&
LHS.get() == E->getLHS() &&
RHS.get() == E->getRHS())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildArraySubscriptExpr(LHS.get(),
/*FIXME:*/E->getLHS()->getLocStart(),
@@ -6936,7 +7163,7 @@
// FIXME: this is a bit instantiation-specific.
SemaRef.MarkMemberReferenced(E);
- return SemaRef.Owned(E);
+ return E;
}
TemplateArgumentListInfo TransArgs;
@@ -6985,7 +7212,7 @@
if (!getDerived().AlwaysRebuild() &&
LHS.get() == E->getLHS() &&
RHS.get() == E->getRHS())
- return SemaRef.Owned(E);
+ return E;
Sema::FPContractStateRAII FPContractState(getSema());
getSema().FPFeatures.fp_contract = E->isFPContractable();
@@ -7018,9 +7245,9 @@
if (!getDerived().AlwaysRebuild() &&
commonExpr.get() == e->getCommon() &&
rhs.get() == e->getFalseExpr())
- return SemaRef.Owned(e);
+ return e;
- return getDerived().RebuildConditionalOperator(commonExpr.take(),
+ return getDerived().RebuildConditionalOperator(commonExpr.get(),
e->getQuestionLoc(),
nullptr,
e->getColonLoc(),
@@ -7046,7 +7273,7 @@
Cond.get() == E->getCond() &&
LHS.get() == E->getLHS() &&
RHS.get() == E->getRHS())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildConditionalOperator(Cond.get(),
E->getQuestionLoc(),
@@ -7078,7 +7305,7 @@
if (!getDerived().AlwaysRebuild() &&
Type == E->getTypeInfoAsWritten() &&
SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
Type,
@@ -7121,7 +7348,7 @@
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
- return SemaRef.Owned(E);
+ return E;
// FIXME: Bad source location
SourceLocation FakeOperatorLoc =
@@ -7142,7 +7369,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && !InitChanged)
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
E->getRBraceLoc(), E->getType());
@@ -7180,7 +7407,7 @@
D->getLBracketLoc()));
ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
- ArrayExprs.push_back(Index.release());
+ ArrayExprs.push_back(Index.get());
continue;
}
@@ -7202,14 +7429,14 @@
ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
End.get() != E->getArrayRangeEnd(*D);
- ArrayExprs.push_back(Start.release());
- ArrayExprs.push_back(End.release());
+ ArrayExprs.push_back(Start.get());
+ ArrayExprs.push_back(End.get());
}
if (!getDerived().AlwaysRebuild() &&
Init.get() == E->getInit() &&
!ExprChanged)
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
E->getEqualOrColonLoc(),
@@ -7230,7 +7457,7 @@
if (!getDerived().AlwaysRebuild() &&
T == E->getType())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildImplicitValueInitExpr(T);
}
@@ -7249,7 +7476,7 @@
if (!getDerived().AlwaysRebuild() &&
TInfo == E->getWrittenTypeInfo() &&
SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
TInfo, E->getRParenLoc());
@@ -7328,7 +7555,7 @@
Cond.get() == E->getCond() &&
LHS.get() == E->getLHS() &&
RHS.get() == E->getRHS())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
Cond.get(), LHS.get(), RHS.get(),
@@ -7338,7 +7565,7 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -7480,7 +7707,7 @@
if (!getDerived().AlwaysRebuild() &&
Type == E->getTypeInfoAsWritten() &&
SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
E->getStmtClass(),
E->getAngleBrackets().getBegin(),
@@ -7533,7 +7760,7 @@
if (!getDerived().AlwaysRebuild() &&
Type == E->getTypeInfoAsWritten() &&
SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXFunctionalCastExpr(Type,
E->getLParenLoc(),
@@ -7552,7 +7779,7 @@
if (!getDerived().AlwaysRebuild() &&
TInfo == E->getTypeOperandSourceInfo())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXTypeidExpr(E->getType(),
E->getLocStart(),
@@ -7573,7 +7800,7 @@
if (!getDerived().AlwaysRebuild() &&
SubExpr.get() == E->getExprOperand())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXTypeidExpr(E->getType(),
E->getLocStart(),
@@ -7592,7 +7819,7 @@
if (!getDerived().AlwaysRebuild() &&
TInfo == E->getTypeOperandSourceInfo())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXUuidofExpr(E->getType(),
E->getLocStart(),
@@ -7608,7 +7835,7 @@
if (!getDerived().AlwaysRebuild() &&
SubExpr.get() == E->getExprOperand())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXUuidofExpr(E->getType(),
E->getLocStart(),
@@ -7619,14 +7846,14 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
CXXNullPtrLiteralExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -7637,7 +7864,7 @@
if (!getDerived().AlwaysRebuild() && T == E->getType()) {
// Make sure that we capture 'this'.
getSema().CheckCXXThisCapture(E->getLocStart());
- return SemaRef.Owned(E);
+ return E;
}
return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
@@ -7652,7 +7879,7 @@
if (!getDerived().AlwaysRebuild() &&
SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
E->isThrownVariableInScope());
@@ -7669,7 +7896,7 @@
if (!getDerived().AlwaysRebuild() &&
Param == E->getParam())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
}
@@ -7684,7 +7911,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && Field == E->getField())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
}
@@ -7699,7 +7926,7 @@
if (!getDerived().AlwaysRebuild() &&
T == E->getTypeSourceInfo())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXScalarValueInitExpr(T,
/*FIXME:*/T->getTypeLoc().getEndLoc(),
@@ -7780,7 +8007,7 @@
}
}
- return SemaRef.Owned(E);
+ return E;
}
QualType AllocType = AllocTypeInfo->getType();
@@ -7795,16 +8022,14 @@
// Do nothing
} else if (const ConstantArrayType *ConsArrayT
= dyn_cast<ConstantArrayType>(ArrayT)) {
- ArraySize
- = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
- ConsArrayT->getSize(),
- SemaRef.Context.getSizeType(),
- /*FIXME:*/E->getLocStart()));
+ ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
+ SemaRef.Context.getSizeType(),
+ /*FIXME:*/ E->getLocStart());
AllocType = ConsArrayT->getElementType();
} else if (const DependentSizedArrayType *DepArrayT
= dyn_cast<DependentSizedArrayType>(ArrayT)) {
if (DepArrayT->getSizeExpr()) {
- ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr());
+ ArraySize = DepArrayT->getSizeExpr();
AllocType = DepArrayT->getElementType();
}
}
@@ -7820,7 +8045,7 @@
AllocTypeInfo,
ArraySize.get(),
E->getDirectInitRange(),
- NewInit.take());
+ NewInit.get());
}
template<typename Derived>
@@ -7858,7 +8083,7 @@
}
}
- return SemaRef.Owned(E);
+ return E;
}
return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
@@ -8156,7 +8381,7 @@
}
if (!getDerived().AlwaysRebuild() && !ArgChanged)
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildTypeTrait(E->getTrait(),
E->getLocStart(),
@@ -8173,7 +8398,7 @@
if (!getDerived().AlwaysRebuild() &&
T == E->getQueriedTypeSourceInfo())
- return SemaRef.Owned(E);
+ return E;
ExprResult SubExpr;
{
@@ -8183,7 +8408,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
- return SemaRef.Owned(E);
+ return E;
}
return getDerived().RebuildArrayTypeTrait(E->getTrait(),
@@ -8204,25 +8429,44 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
- return SemaRef.Owned(E);
+ return E;
}
return getDerived().RebuildExpressionTrait(
E->getTrait(), E->getLocStart(), SubExpr.get(), E->getLocEnd());
}
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
- DependentScopeDeclRefExpr *E) {
- return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand*/false);
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
+ ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
+ TypeSourceInfo **RecoveryTSI) {
+ ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
+ DRE, AddrTaken, RecoveryTSI);
+
+ // Propagate both errors and recovered types, which return ExprEmpty.
+ if (!NewDRE.isUsable())
+ return NewDRE;
+
+ // We got an expr, wrap it up in parens.
+ if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
+ return PE;
+ return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
+ PE->getRParen());
+}
+
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
+ DependentScopeDeclRefExpr *E) {
+ return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
+ nullptr);
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
DependentScopeDeclRefExpr *E,
- bool IsAddressOfOperand) {
+ bool IsAddressOfOperand,
+ TypeSourceInfo **RecoveryTSI) {
assert(E->getQualifierLoc());
NestedNameSpecifierLoc QualifierLoc
= getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
@@ -8245,13 +8489,11 @@
// Note: it is sufficient to compare the Name component of NameInfo:
// if name has not changed, DNLoc has not changed either.
NameInfo.getName() == E->getDeclName())
- return SemaRef.Owned(E);
+ return E;
- return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
- TemplateKWLoc,
- NameInfo,
- /*TemplateArgs*/nullptr,
- IsAddressOfOperand);
+ return getDerived().RebuildDependentScopeDeclRefExpr(
+ QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
+ IsAddressOfOperand, RecoveryTSI);
}
TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
@@ -8260,11 +8502,9 @@
TransArgs))
return ExprError();
- return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
- TemplateKWLoc,
- NameInfo,
- &TransArgs,
- IsAddressOfOperand);
+ return getDerived().RebuildDependentScopeDeclRefExpr(
+ QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
+ RecoveryTSI);
}
template<typename Derived>
@@ -8305,7 +8545,7 @@
// Mark the constructor as referenced.
// FIXME: Instantiation-specific
SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
- return SemaRef.Owned(E);
+ return E;
}
return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
@@ -8614,6 +8854,9 @@
// Capture the transformed variable.
getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
}
+
+ // FIXME: Retain a pack expansion if RetainExpansion is true.
+
continue;
}
@@ -8654,7 +8897,7 @@
return ExprError();
}
- return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
+ return getSema().ActOnLambdaExpr(E->getLocStart(), Body.get(),
/*CurScope=*/nullptr,
/*IsInstantiation=*/true);
}
@@ -8677,7 +8920,7 @@
if (!getDerived().AlwaysRebuild() &&
T == E->getTypeSourceInfo() &&
!ArgumentChanged)
- return SemaRef.Owned(E);
+ return E;
// FIXME: we're faking the locations of the commas
return getDerived().RebuildCXXUnresolvedConstructExpr(T,
@@ -8757,7 +9000,7 @@
QualifierLoc == E->getQualifierLoc() &&
NameInfo.getName() == E->getMember() &&
FirstQualifierInScope == E->getFirstQualifierFoundInScope())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
BaseType,
@@ -8797,7 +9040,7 @@
Base = getDerived().TransformExpr(Old->getBase());
if (Base.isInvalid())
return ExprError();
- Base = getSema().PerformMemberExprBaseConversion(Base.take(),
+ Base = getSema().PerformMemberExprBaseConversion(Base.get(),
Old->isArrow());
if (Base.isInvalid())
return ExprError();
@@ -8898,7 +9141,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
}
@@ -8911,7 +9154,7 @@
return ExprError();
if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
E->getNumExpansions());
@@ -8923,7 +9166,7 @@
// If E is not value-dependent, then nothing will change when we transform it.
// Note: This is an instantiation-centric view.
if (!E->isValueDependent())
- return SemaRef.Owned(E);
+ return E;
// Note: None of the implementations of TryExpandParameterPacks can ever
// produce a diagnostic when given only a single unexpanded parameter pack,
@@ -8939,7 +9182,7 @@
return ExprError();
if (RetainExpansion)
- return SemaRef.Owned(E);
+ return E;
NamedDecl *Pack = E->getPack();
if (!ShouldExpand) {
@@ -8962,7 +9205,7 @@
TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
SubstNonTypeTemplateParmPackExpr *E) {
// Default behavior is to do nothing with this transformation.
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -8970,14 +9213,14 @@
TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
// Default behavior is to do nothing with this transformation.
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
// Default behavior is to do nothing with this transformation.
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -9003,7 +9246,7 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -9015,7 +9258,7 @@
if (!getDerived().AlwaysRebuild() &&
SubExpr.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
}
@@ -9118,6 +9361,7 @@
// If any unexpanded parameter packs remain, we still have a
// pack expansion.
+ // FIXME: Can this really happen?
if (Key.get()->containsUnexpandedParameterPack() ||
Value.get()->containsUnexpandedParameterPack())
Element.EllipsisLoc = OrigElement.EllipsisLoc;
@@ -9125,6 +9369,8 @@
Elements.push_back(Element);
}
+ // FIXME: Retain a pack expansion if RetainExpansion is true.
+
// We've finished with this pack expansion.
continue;
}
@@ -9170,7 +9416,7 @@
if (!getDerived().AlwaysRebuild() &&
EncodedTypeInfo == E->getEncodedTypeSourceInfo())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
EncodedTypeInfo,
@@ -9202,7 +9448,7 @@
if (!getDerived().AlwaysRebuild() &&
TSInfo == E->getTypeInfoAsWritten() &&
Result.get() == E->getSubExpr())
- return SemaRef.Owned(E);
+ return E;
return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
E->getBridgeKeywordLoc(), TSInfo,
@@ -9272,13 +9518,13 @@
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
- return SemaRef.Owned(E);
+ return E;
}
template<typename Derived>
@@ -9294,7 +9540,7 @@
// If nothing changed, just retain the existing expression.
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
E->getLocation(),
@@ -9307,7 +9553,7 @@
// 'super' and types never change. Property never changes. Just
// retain the existing expression.
if (!E->isObjectReceiver())
- return SemaRef.Owned(E);
+ return E;
// Transform the base expression.
ExprResult Base = getDerived().TransformExpr(E->getBase());
@@ -9319,7 +9565,7 @@
// If nothing changed, just retain the existing expression.
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
- return SemaRef.Owned(E);
+ return E;
if (E->isExplicitProperty())
return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
@@ -9349,7 +9595,7 @@
// If nothing changed, just retain the existing expression.
if (!getDerived().AlwaysRebuild() &&
Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
Base.get(), Key.get(),
@@ -9368,7 +9614,7 @@
// If nothing changed, just retain the existing expression.
if (!getDerived().AlwaysRebuild() &&
Base.get() == E->getBase())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
E->getOpLoc(),
@@ -9387,7 +9633,7 @@
if (!getDerived().AlwaysRebuild() &&
!ArgumentChanged)
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
SubExprs,
@@ -9408,7 +9654,7 @@
if (!getDerived().AlwaysRebuild() &&
Type == E->getTypeSourceInfo() &&
SrcExpr.get() == E->getSrcExpr())
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
SrcExpr.get(), Type,
@@ -9508,7 +9754,7 @@
if (!getDerived().AlwaysRebuild() &&
!ArgumentChanged)
- return SemaRef.Owned(E);
+ return E;
return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
RetTy, E->getOp(), E->getRParenLoc());
@@ -9662,7 +9908,7 @@
template<typename Derived>
QualType TreeTransform<Derived>::RebuildFunctionProtoType(
QualType T,
- llvm::MutableArrayRef<QualType> ParamTypes,
+ MutableArrayRef<QualType> ParamTypes,
const FunctionProtoType::ExtProtoInfo &EPI) {
return SemaRef.BuildFunctionType(T, ParamTypes,
getDerived().getBaseLocation(),
@@ -9796,6 +10042,24 @@
Expr *Callee = OrigCallee->IgnoreParenCasts();
bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
+ if (First->getObjectKind() == OK_ObjCProperty) {
+ BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+ if (BinaryOperator::isAssignmentOp(Opc))
+ return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
+ First, Second);
+ ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
+ if (Result.isInvalid())
+ return ExprError();
+ First = Result.get();
+ }
+
+ if (Second && Second->getObjectKind() == OK_ObjCProperty) {
+ ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
+ if (Result.isInvalid())
+ return ExprError();
+ Second = Result.get();
+ }
+
// Determine whether this should be a builtin operation.
if (Op == OO_Subscript) {
if (!First->getType()->isOverloadableType() &&
@@ -9951,14 +10215,18 @@
}
getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
S->getCapturedRegionKind(), Params);
- StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
+ StmtResult Body;
+ {
+ Sema::CompoundScopeRAII CompoundScope(getSema());
+ Body = getDerived().TransformStmt(S->getCapturedStmt());
+ }
if (Body.isInvalid()) {
getSema().ActOnCapturedRegionError();
return StmtError();
}
- return getSema().ActOnCapturedRegionEnd(Body.take());
+ return getSema().ActOnCapturedRegionEnd(Body.get());
}
} // end namespace clang