aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/HeuristicResolver.cpp5
-rw-r--r--clang/lib/Sema/Sema.cpp17
-rw-r--r--clang/lib/Sema/SemaConcept.cpp32
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp24
-rw-r--r--clang/lib/Sema/SemaOpenACC.cpp25
-rw-r--r--clang/lib/Sema/SemaType.cpp18
6 files changed, 77 insertions, 44 deletions
diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp
index cbdefaa..056e133 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -450,7 +450,12 @@ QualType HeuristicResolverImpl::resolveExprToType(const Expr *E) {
if (const auto *CE = dyn_cast<CallExpr>(E)) {
if (QualType Resolved = resolveTypeOfCallExpr(CE); !Resolved.isNull())
return Resolved;
+
+ // Don't proceed to try resolveExprToDecls(), it would just call
+ // resolveTypeOfCallExpr() again.
+ return E->getType();
}
+
// Similarly, unwrapping a unary dereference operation does not work via
// resolveExprToDecls.
if (const auto *UO = dyn_cast<UnaryOperator>(E->IgnoreParenCasts())) {
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 215ac18..23bf7f2 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -276,10 +276,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()),
SourceMgr(PP.getSourceManager()), APINotes(SourceMgr, LangOpts),
AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr),
- LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr),
- OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr),
- StackHandler(Diags), CurScope(nullptr), Ident_super(nullptr),
- AMDGPUPtr(std::make_unique<SemaAMDGPU>(*this)),
+ LateTemplateParser(nullptr), OpaqueParser(nullptr), CurContext(nullptr),
+ ExternalSource(nullptr), StackHandler(Diags), CurScope(nullptr),
+ Ident_super(nullptr), AMDGPUPtr(std::make_unique<SemaAMDGPU>(*this)),
ARMPtr(std::make_unique<SemaARM>(*this)),
AVRPtr(std::make_unique<SemaAVR>(*this)),
BPFPtr(std::make_unique<SemaBPF>(*this)),
@@ -1248,9 +1247,6 @@ void Sema::ActOnEndOfTranslationUnit() {
? TUFragmentKind::Private
: TUFragmentKind::Normal);
- if (LateTemplateParserCleanup)
- LateTemplateParserCleanup(OpaqueParser);
-
CheckDelayedMemberExceptionSpecs();
} else {
// If we are building a TU prefix for serialization, it is safe to transfer
@@ -1484,6 +1480,13 @@ void Sema::ActOnEndOfTranslationUnit() {
Consumer.CompleteTentativeDefinition(VD);
}
+ // In incremental mode, tentative definitions belong to the current
+ // partial translation unit (PTU). Once they have been completed and
+ // emitted to codegen, drop them to prevent re-emission in future PTUs.
+ if (PP.isIncrementalProcessingEnabled())
+ TentativeDefinitions.erase(TentativeDefinitions.begin(ExternalSource.get()),
+ TentativeDefinitions.end());
+
for (auto *D : ExternalDeclarations) {
if (!D || D->isInvalidDecl() || D->getPreviousDecl() || !D->isUsed())
continue;
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 54cbfe4..a1163e9 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -417,8 +417,8 @@ class ConstraintSatisfactionChecker {
const NamedDecl *Template;
SourceLocation TemplateNameLoc;
UnsignedOrNone PackSubstitutionIndex;
-
ConstraintSatisfaction &Satisfaction;
+ bool BuildExpression;
private:
ExprResult
@@ -461,10 +461,11 @@ public:
ConstraintSatisfactionChecker(Sema &SemaRef, const NamedDecl *Template,
SourceLocation TemplateNameLoc,
UnsignedOrNone PackSubstitutionIndex,
- ConstraintSatisfaction &Satisfaction)
+ ConstraintSatisfaction &Satisfaction,
+ bool BuildExpression)
: S(SemaRef), Template(Template), TemplateNameLoc(TemplateNameLoc),
PackSubstitutionIndex(PackSubstitutionIndex),
- Satisfaction(Satisfaction) {}
+ Satisfaction(Satisfaction), BuildExpression(BuildExpression) {}
ExprResult Evaluate(const NormalizedConstraint &Constraint,
const MultiLevelTemplateArgumentList &MLTAL);
@@ -821,9 +822,10 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
Satisfaction.ContainsErrors = false;
ExprResult Expr =
ConstraintSatisfactionChecker(S, Template, TemplateNameLoc,
- UnsignedOrNone(I), Satisfaction)
+ UnsignedOrNone(I), Satisfaction,
+ /*BuildExpression=*/false)
.Evaluate(Constraint.getNormalizedPattern(), *SubstitutedArgs);
- if (Expr.isUsable()) {
+ if (BuildExpression && Expr.isUsable()) {
if (Out.isUnset())
Out = Expr;
else
@@ -834,7 +836,7 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
Constraint.getBeginLoc(),
FPOptionsOverride{});
} else {
- assert(!Satisfaction.IsSatisfied);
+ assert(!BuildExpression || !Satisfaction.IsSatisfied);
}
if (!Conjunction && Satisfaction.IsSatisfied) {
Satisfaction.Details.erase(Satisfaction.Details.begin() +
@@ -985,7 +987,7 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
ExprResult E = Evaluate(Constraint.getNormalizedConstraint(), MLTAL);
- if (!E.isUsable()) {
+ if (E.isInvalid()) {
Satisfaction.Details.insert(Satisfaction.Details.begin() + Size, ConceptId);
return E;
}
@@ -1041,7 +1043,7 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
if (Conjunction && (!Satisfaction.IsSatisfied || Satisfaction.ContainsErrors))
return LHS;
- if (!Conjunction && LHS.isUsable() && Satisfaction.IsSatisfied &&
+ if (!Conjunction && !LHS.isInvalid() && Satisfaction.IsSatisfied &&
!Satisfaction.ContainsErrors)
return LHS;
@@ -1050,12 +1052,15 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
ExprResult RHS = Evaluate(Constraint.getRHS(), MLTAL);
- if (RHS.isUsable() && Satisfaction.IsSatisfied &&
+ if (!Conjunction && !RHS.isInvalid() && Satisfaction.IsSatisfied &&
!Satisfaction.ContainsErrors)
Satisfaction.Details.erase(Satisfaction.Details.begin() +
EffectiveDetailEndIndex,
Satisfaction.Details.end());
+ if (!BuildExpression)
+ return Satisfaction.ContainsErrors ? ExprError() : ExprEmpty();
+
if (!LHS.isUsable())
return RHS;
@@ -1136,10 +1141,11 @@ static bool CheckConstraintSatisfaction(
Template, /*CSE=*/nullptr,
S.ArgPackSubstIndex);
- ExprResult Res =
- ConstraintSatisfactionChecker(S, Template, TemplateIDRange.getBegin(),
- S.ArgPackSubstIndex, Satisfaction)
- .Evaluate(*C, TemplateArgsLists);
+ ExprResult Res = ConstraintSatisfactionChecker(
+ S, Template, TemplateIDRange.getBegin(),
+ S.ArgPackSubstIndex, Satisfaction,
+ /*BuildExpression=*/ConvertedExpr != nullptr)
+ .Evaluate(*C, TemplateArgsLists);
if (Res.isInvalid())
return true;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 9475b8a..964a2a7 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5206,16 +5206,36 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
- if (S.getASTContext().getTargetInfo().getTriple().isNVPTX()) {
+ llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple();
+ const LangOptions &LangOpts = S.getLangOpts();
+ // OpenCL has its own error messages.
+ if (!LangOpts.OpenCL && FD && !FD->isExternallyVisible()) {
+ S.Diag(AL.getLoc(), diag::err_hidden_device_kernel) << FD;
+ AL.setInvalid();
+ return;
+ }
+ if (Triple.isNVPTX()) {
handleGlobalAttr(S, D, AL);
} else {
// OpenCL C++ will throw a more specific error.
- if (!S.getLangOpts().OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
+ if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type_str)
<< AL << AL.isRegularKeywordAttribute() << "functions";
+ AL.setInvalid();
+ return;
}
handleSimpleAttribute<DeviceKernelAttr>(S, D, AL);
}
+ // TODO: isGPU() should probably return true for SPIR.
+ bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() ||
+ LangOpts.isTargetDevice() || LangOpts.OpenCL;
+ if (!TargetDeviceEnvironment) {
+ S.Diag(AL.getLoc(), diag::warn_cconv_unsupported)
+ << AL << (int)Sema::CallingConventionIgnoredReason::ForThisTarget;
+ AL.setInvalid();
+ return;
+ }
+
// Make sure we validate the CC with the target
// and warn/error if necessary.
handleCallConvAttr(S, D, AL);
diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp
index 3bb8080..ee9b2b3 100644
--- a/clang/lib/Sema/SemaOpenACC.cpp
+++ b/clang/lib/Sema/SemaOpenACC.cpp
@@ -2999,11 +2999,11 @@ bool SemaOpenACC::CreateReductionCombinerRecipe(
BinOp = BinaryOperatorKind::BO_LT;
break;
case OpenACCReductionOperator::And:
+ BinOp = BinaryOperatorKind::BO_LAnd;
+ break;
case OpenACCReductionOperator::Or:
- // We just want a 'NYI' error in the backend, so leave an empty combiner
- // recipe, and claim success.
- CombinerRecipes.push_back({nullptr, nullptr, nullptr});
- return false;
+ BinOp = BinaryOperatorKind::BO_LOr;
+ break;
}
// If VarTy is an array type, at the top level only, we want to do our
@@ -3068,8 +3068,21 @@ bool SemaOpenACC::CreateReductionCombinerRecipe(
: CombinerFailureKind::Assignment};
}
case OpenACCReductionOperator::And:
- case OpenACCReductionOperator::Or:
- llvm_unreachable("And/Or not implemented, but should fail earlier");
+ case OpenACCReductionOperator::Or: {
+ // These are done as LHS = LHS && RHS (or LHS = LHS || RHS). So after the
+ // binop, all we have to do is the assignment.
+ if (!BinOpRes.isUsable())
+ return {BinOpRes, CombinerFailureKind::BinOp};
+
+ // Build assignment.
+ ExprResult Assignment = SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc,
+ BinaryOperatorKind::BO_Assign,
+ LHSDRE, BinOpRes.get(),
+ /*ForFoldExpr=*/false);
+ return {Assignment, Assignment.isUsable()
+ ? CombinerFailureKind::None
+ : CombinerFailureKind::Assignment};
+ }
case OpenACCReductionOperator::Invalid:
llvm_unreachable("Invalid should have been caught above");
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 7c1fb12..280b3c9 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -134,7 +134,6 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
case ParsedAttr::AT_VectorCall: \
case ParsedAttr::AT_AArch64VectorPcs: \
case ParsedAttr::AT_AArch64SVEPcs: \
- case ParsedAttr::AT_DeviceKernel: \
case ParsedAttr::AT_MSABI: \
case ParsedAttr::AT_SysVABI: \
case ParsedAttr::AT_Pcs: \
@@ -3786,7 +3785,8 @@ static CallingConv getCCForDeclaratorChunk(
}
}
}
- for (const ParsedAttr &AL : D.getDeclSpec().getAttributes()) {
+ for (const ParsedAttr &AL : llvm::concat<ParsedAttr>(
+ D.getDeclSpec().getAttributes(), D.getAttributes())) {
if (AL.getKind() == ParsedAttr::AT_DeviceKernel) {
CC = CC_DeviceKernel;
break;
@@ -7569,8 +7569,6 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
return createSimpleAttr<AArch64SVEPcsAttr>(Ctx, Attr);
case ParsedAttr::AT_ArmStreaming:
return createSimpleAttr<ArmStreamingAttr>(Ctx, Attr);
- case ParsedAttr::AT_DeviceKernel:
- return createSimpleAttr<DeviceKernelAttr>(Ctx, Attr);
case ParsedAttr::AT_Pcs: {
// The attribute may have had a fixit applied where we treated an
// identifier as a string literal. The contents of the string are valid,
@@ -8809,16 +8807,6 @@ static void HandleHLSLParamModifierAttr(TypeProcessingState &State,
}
}
-static bool isMultiSubjectAttrAllowedOnType(const ParsedAttr &Attr) {
- // The DeviceKernel attribute is shared for many targets, and
- // it is only allowed to be a type attribute with the AMDGPU
- // spelling, so skip processing the attr as a type attr
- // unless it has that spelling.
- if (Attr.getKind() != ParsedAttr::AT_DeviceKernel)
- return true;
- return DeviceKernelAttr::isAMDGPUSpelling(Attr);
-}
-
static void processTypeAttrs(TypeProcessingState &state, QualType &type,
TypeAttrLocation TAL,
const ParsedAttributesView &attrs,
@@ -9072,8 +9060,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
break;
[[fallthrough]];
FUNCTION_TYPE_ATTRS_CASELIST:
- if (!isMultiSubjectAttrAllowedOnType(attr))
- break;
attr.setUsedAsTypeAttr();