mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
Vendor import of clang release_39 branch r287912:
https://llvm.org/svn/llvm-project/cfe/branches/release_39@287912
This commit is contained in:
parent
c477790a57
commit
17c7957f02
68 changed files with 848 additions and 185 deletions
|
|
@ -44,6 +44,8 @@ class VarTemplatePartialSpecializationDecl;
|
|||
typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
|
||||
TemplateTemplateParmDecl*> TemplateParameter;
|
||||
|
||||
NamedDecl *getAsNamedDecl(TemplateParameter P);
|
||||
|
||||
/// \brief Stores a list of template parameters for a TemplateDecl and its
|
||||
/// derived classes.
|
||||
class TemplateParameterList final
|
||||
|
|
@ -2912,6 +2914,14 @@ public:
|
|||
friend class ASTDeclWriter;
|
||||
};
|
||||
|
||||
inline NamedDecl *getAsNamedDecl(TemplateParameter P) {
|
||||
if (auto *PD = P.dyn_cast<TemplateTypeParmDecl*>())
|
||||
return PD;
|
||||
if (auto *PD = P.dyn_cast<NonTypeTemplateParmDecl*>())
|
||||
return PD;
|
||||
return P.get<TemplateTemplateParmDecl*>();
|
||||
}
|
||||
|
||||
} /* end of namespace clang */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -159,8 +159,6 @@ def err_drv_bitcode_unsupported_on_toolchain : Error<
|
|||
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
|
||||
|
||||
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
|
||||
def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">,
|
||||
InGroup<LibLTO>;
|
||||
def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
|
||||
InGroup<InvalidCommandLineArgument>;
|
||||
def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">,
|
||||
|
|
|
|||
|
|
@ -4291,7 +4291,7 @@ def err_definition_of_implicitly_declared_member : Error<
|
|||
def err_definition_of_explicitly_defaulted_member : Error<
|
||||
"definition of explicitly defaulted %select{default constructor|copy "
|
||||
"constructor|move constructor|copy assignment operator|move assignment "
|
||||
"operator|destructor}0">;
|
||||
"operator|destructor|function}0">;
|
||||
def err_redefinition_extern_inline : Error<
|
||||
"redefinition of a 'extern inline' function %0 is not supported in "
|
||||
"%select{C99 mode|C++}1">;
|
||||
|
|
@ -6917,6 +6917,10 @@ def err_in_class_initializer_not_yet_parsed
|
|||
def err_in_class_initializer_not_yet_parsed_outer_class
|
||||
: Error<"cannot use defaulted default constructor of %0 within "
|
||||
"%1 outside of member functions because %2 has an initializer">;
|
||||
def err_in_class_initializer_cycle
|
||||
: Error<"default member initializer for %0 uses itself">;
|
||||
def err_exception_spec_cycle
|
||||
: Error<"exception specification of %0 uses itself">;
|
||||
|
||||
def ext_in_class_initializer_non_constant : Extension<
|
||||
"in-class initializer for static data member is not a constant expression; "
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "clang/AST/Attr.h"
|
||||
#include "clang/AST/Availability.h"
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprObjC.h"
|
||||
#include "clang/AST/ExternalASTSource.h"
|
||||
|
|
@ -1217,8 +1218,10 @@ public:
|
|||
/// \brief Retrieve the current block, if any.
|
||||
sema::BlockScopeInfo *getCurBlock();
|
||||
|
||||
/// \brief Retrieve the current lambda scope info, if any.
|
||||
sema::LambdaScopeInfo *getCurLambda();
|
||||
/// Retrieve the current lambda scope info, if any.
|
||||
/// \param IgnoreCapturedRegions true if should find the top-most lambda scope
|
||||
/// info ignoring all inner captured regions scope infos.
|
||||
sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false);
|
||||
|
||||
/// \brief Retrieve the current generic lambda info, if any.
|
||||
sema::LambdaScopeInfo *getCurGenericLambda();
|
||||
|
|
@ -6613,10 +6616,10 @@ public:
|
|||
TemplateInstantiation,
|
||||
|
||||
/// We are instantiating a default argument for a template
|
||||
/// parameter. The Entity is the template, and
|
||||
/// TemplateArgs/NumTemplateArguments provides the template
|
||||
/// arguments as specified.
|
||||
/// FIXME: Use a TemplateArgumentList
|
||||
/// parameter. The Entity is the template parameter whose argument is
|
||||
/// being instantiated, the Template is the template, and the
|
||||
/// TemplateArgs/NumTemplateArguments provide the template arguments as
|
||||
/// specified.
|
||||
DefaultTemplateArgumentInstantiation,
|
||||
|
||||
/// We are instantiating a default argument for a function.
|
||||
|
|
@ -6731,6 +6734,9 @@ public:
|
|||
SmallVector<ActiveTemplateInstantiation, 16>
|
||||
ActiveTemplateInstantiations;
|
||||
|
||||
/// Specializations whose definitions are currently being instantiated.
|
||||
llvm::DenseSet<std::pair<Decl *, unsigned>> InstantiatingSpecializations;
|
||||
|
||||
/// \brief Extra modules inspected when performing a lookup during a template
|
||||
/// instantiation. Computed lazily.
|
||||
SmallVector<Module*, 16> ActiveTemplateInstantiationLookupModules;
|
||||
|
|
@ -6837,12 +6843,12 @@ public:
|
|||
/// \brief Note that we are instantiating a default argument in a
|
||||
/// template-id.
|
||||
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
||||
TemplateDecl *Template,
|
||||
TemplateParameter Param, TemplateDecl *Template,
|
||||
ArrayRef<TemplateArgument> TemplateArgs,
|
||||
SourceRange InstantiationRange = SourceRange());
|
||||
|
||||
/// \brief Note that we are instantiating a default argument in a
|
||||
/// template-id.
|
||||
/// \brief Note that we are substituting either explicitly-specified or
|
||||
/// deduced template arguments during function template argument deduction.
|
||||
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
|
||||
FunctionTemplateDecl *FunctionTemplate,
|
||||
ArrayRef<TemplateArgument> TemplateArgs,
|
||||
|
|
@ -6909,9 +6915,14 @@ public:
|
|||
/// recursive template instantiations.
|
||||
bool isInvalid() const { return Invalid; }
|
||||
|
||||
/// \brief Determine whether we are already instantiating this
|
||||
/// specialization in some surrounding active instantiation.
|
||||
bool isAlreadyInstantiating() const { return AlreadyInstantiating; }
|
||||
|
||||
private:
|
||||
Sema &SemaRef;
|
||||
bool Invalid;
|
||||
bool AlreadyInstantiating;
|
||||
bool SavedInNonInstantiationSFINAEContext;
|
||||
bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
|
||||
SourceRange InstantiationRange);
|
||||
|
|
|
|||
|
|
@ -158,14 +158,25 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
|
|||
|
||||
// Set the appropriate OS version define.
|
||||
if (Triple.isiOS()) {
|
||||
assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
|
||||
char Str[6];
|
||||
Str[0] = '0' + Maj;
|
||||
Str[1] = '0' + (Min / 10);
|
||||
Str[2] = '0' + (Min % 10);
|
||||
Str[3] = '0' + (Rev / 10);
|
||||
Str[4] = '0' + (Rev % 10);
|
||||
Str[5] = '\0';
|
||||
assert(Maj < 100 && Min < 100 && Rev < 100 && "Invalid version!");
|
||||
char Str[7];
|
||||
if (Maj < 10) {
|
||||
Str[0] = '0' + Maj;
|
||||
Str[1] = '0' + (Min / 10);
|
||||
Str[2] = '0' + (Min % 10);
|
||||
Str[3] = '0' + (Rev / 10);
|
||||
Str[4] = '0' + (Rev % 10);
|
||||
Str[5] = '\0';
|
||||
} else {
|
||||
// Handle versions >= 10.
|
||||
Str[0] = '0' + (Maj / 10);
|
||||
Str[1] = '0' + (Maj % 10);
|
||||
Str[2] = '0' + (Min / 10);
|
||||
Str[3] = '0' + (Min % 10);
|
||||
Str[4] = '0' + (Rev / 10);
|
||||
Str[5] = '0' + (Rev % 10);
|
||||
Str[6] = '\0';
|
||||
}
|
||||
if (Triple.isTvOS())
|
||||
Builder.defineMacro("__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__", Str);
|
||||
else
|
||||
|
|
@ -8170,6 +8181,8 @@ static TargetInfo *AllocateTarget(const llvm::Triple &Triple,
|
|||
return new DarwinARMTargetInfo(Triple, Opts);
|
||||
|
||||
switch (os) {
|
||||
case llvm::Triple::CloudABI:
|
||||
return new CloudABITargetInfo<ARMleTargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::Linux:
|
||||
return new LinuxTargetInfo<ARMleTargetInfo>(Triple, Opts);
|
||||
case llvm::Triple::FreeBSD:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ std::string getClangRepositoryPath() {
|
|||
|
||||
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
|
||||
// pick up a tag in an SVN export, for example.
|
||||
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_390/final/lib/Basic/Version.cpp $");
|
||||
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_39/lib/Basic/Version.cpp $");
|
||||
if (URL.empty()) {
|
||||
URL = SVNRepository.slice(SVNRepository.find(':'),
|
||||
SVNRepository.find("/lib/Basic"));
|
||||
|
|
|
|||
|
|
@ -2105,12 +2105,11 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|||
if (auto *FD = LambdaCaptureFields.lookup(VD))
|
||||
return EmitCapturedFieldLValue(*this, FD, CXXABIThisValue);
|
||||
else if (CapturedStmtInfo) {
|
||||
auto it = LocalDeclMap.find(VD);
|
||||
if (it != LocalDeclMap.end()) {
|
||||
if (auto RefTy = VD->getType()->getAs<ReferenceType>()) {
|
||||
return EmitLoadOfReferenceLValue(it->second, RefTy);
|
||||
}
|
||||
return MakeAddrLValue(it->second, T);
|
||||
auto I = LocalDeclMap.find(VD);
|
||||
if (I != LocalDeclMap.end()) {
|
||||
if (auto RefTy = VD->getType()->getAs<ReferenceType>())
|
||||
return EmitLoadOfReferenceLValue(I->second, RefTy);
|
||||
return MakeAddrLValue(I->second, T);
|
||||
}
|
||||
LValue CapLVal =
|
||||
EmitCapturedFieldLValue(*this, CapturedStmtInfo->lookup(VD),
|
||||
|
|
@ -2249,13 +2248,15 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
|
|||
return LV;
|
||||
}
|
||||
|
||||
assert(E->getSubExpr()->getType()->isAnyComplexType());
|
||||
QualType T = ExprTy->castAs<ComplexType>()->getElementType();
|
||||
|
||||
Address Component =
|
||||
(E->getOpcode() == UO_Real
|
||||
? emitAddrOfRealComponent(LV.getAddress(), LV.getType())
|
||||
: emitAddrOfImagComponent(LV.getAddress(), LV.getType()));
|
||||
return MakeAddrLValue(Component, ExprTy, LV.getAlignmentSource());
|
||||
LValue ElemLV = MakeAddrLValue(Component, T, LV.getAlignmentSource());
|
||||
ElemLV.getQuals().addQualifiers(LV.getQuals());
|
||||
return ElemLV;
|
||||
}
|
||||
case UO_PreInc:
|
||||
case UO_PreDec: {
|
||||
|
|
|
|||
|
|
@ -1323,6 +1323,10 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
|||
// Handle this as two cases: we might be looking for the SwitchCase (if so
|
||||
// the skipped statements must be skippable) or we might already have it.
|
||||
CompoundStmt::const_body_iterator I = CS->body_begin(), E = CS->body_end();
|
||||
bool StartedInLiveCode = FoundCase;
|
||||
unsigned StartSize = ResultStmts.size();
|
||||
|
||||
// If we've not found the case yet, scan through looking for it.
|
||||
if (Case) {
|
||||
// Keep track of whether we see a skipped declaration. The code could be
|
||||
// using the declaration even if it is skipped, so we can't optimize out
|
||||
|
|
@ -1332,7 +1336,7 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
|||
// If we're looking for the case, just see if we can skip each of the
|
||||
// substatements.
|
||||
for (; Case && I != E; ++I) {
|
||||
HadSkippedDecl |= isa<DeclStmt>(*I);
|
||||
HadSkippedDecl |= CodeGenFunction::mightAddDeclToScope(*I);
|
||||
|
||||
switch (CollectStatementsForCase(*I, Case, FoundCase, ResultStmts)) {
|
||||
case CSFC_Failure: return CSFC_Failure;
|
||||
|
|
@ -1368,11 +1372,19 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!FoundCase)
|
||||
return CSFC_Success;
|
||||
|
||||
assert(!HadSkippedDecl && "fallthrough after skipping decl");
|
||||
}
|
||||
|
||||
// If we have statements in our range, then we know that the statements are
|
||||
// live and need to be added to the set of statements we're tracking.
|
||||
bool AnyDecls = false;
|
||||
for (; I != E; ++I) {
|
||||
AnyDecls |= CodeGenFunction::mightAddDeclToScope(*I);
|
||||
|
||||
switch (CollectStatementsForCase(*I, nullptr, FoundCase, ResultStmts)) {
|
||||
case CSFC_Failure: return CSFC_Failure;
|
||||
case CSFC_FallThrough:
|
||||
|
|
@ -1390,7 +1402,24 @@ static CSFC_Result CollectStatementsForCase(const Stmt *S,
|
|||
}
|
||||
}
|
||||
|
||||
return Case ? CSFC_Success : CSFC_FallThrough;
|
||||
// If we're about to fall out of a scope without hitting a 'break;', we
|
||||
// can't perform the optimization if there were any decls in that scope
|
||||
// (we'd lose their end-of-lifetime).
|
||||
if (AnyDecls) {
|
||||
// If the entire compound statement was live, there's one more thing we
|
||||
// can try before giving up: emit the whole thing as a single statement.
|
||||
// We can do that unless the statement contains a 'break;'.
|
||||
// FIXME: Such a break must be at the end of a construct within this one.
|
||||
// We could emit this by just ignoring the BreakStmts entirely.
|
||||
if (StartedInLiveCode && !CodeGenFunction::containsBreak(S)) {
|
||||
ResultStmts.resize(StartSize);
|
||||
ResultStmts.push_back(S);
|
||||
} else {
|
||||
return CSFC_Failure;
|
||||
}
|
||||
}
|
||||
|
||||
return CSFC_FallThrough;
|
||||
}
|
||||
|
||||
// Okay, this is some other statement that we don't handle explicitly, like a
|
||||
|
|
|
|||
|
|
@ -232,8 +232,15 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
|
|||
assert(I->capturesVariableArrayType());
|
||||
II = &getContext().Idents.get("vla");
|
||||
}
|
||||
if (ArgType->isVariablyModifiedType())
|
||||
ArgType = getContext().getVariableArrayDecayedType(ArgType);
|
||||
if (ArgType->isVariablyModifiedType()) {
|
||||
bool IsReference = ArgType->isLValueReferenceType();
|
||||
ArgType =
|
||||
getContext().getCanonicalParamType(ArgType.getNonReferenceType());
|
||||
if (IsReference && !ArgType->isPointerType()) {
|
||||
ArgType = getContext().getLValueReferenceType(
|
||||
ArgType, /*SpelledAsLValue=*/false);
|
||||
}
|
||||
}
|
||||
Args.push_back(ImplicitParamDecl::Create(getContext(), nullptr,
|
||||
FD->getLocation(), II, ArgType));
|
||||
++I;
|
||||
|
|
@ -287,8 +294,14 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
|
|||
QualType VarTy = Var->getType();
|
||||
Address ArgAddr = ArgLVal.getAddress();
|
||||
if (!VarTy->isReferenceType()) {
|
||||
ArgAddr = EmitLoadOfReference(
|
||||
ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
|
||||
if (ArgLVal.getType()->isLValueReferenceType()) {
|
||||
ArgAddr = EmitLoadOfReference(
|
||||
ArgAddr, ArgLVal.getType()->castAs<ReferenceType>());
|
||||
} else if (!VarTy->isVariablyModifiedType() || !VarTy->isPointerType()) {
|
||||
assert(ArgLVal.getType()->isPointerType());
|
||||
ArgAddr = EmitLoadOfPointer(
|
||||
ArgAddr, ArgLVal.getType()->castAs<PointerType>());
|
||||
}
|
||||
}
|
||||
setAddrOfLocalVar(
|
||||
Var, Address(ArgAddr.getPointer(), getContext().getDeclAlign(Var)));
|
||||
|
|
@ -1754,9 +1767,17 @@ void CodeGenFunction::EmitOMPOuterLoop(bool DynamicOrOrdered, bool IsMonotonic,
|
|||
EmitBlock(LoopExit.getBlock());
|
||||
|
||||
// Tell the runtime we are done.
|
||||
if (!DynamicOrOrdered)
|
||||
RT.emitForStaticFinish(*this, S.getLocEnd());
|
||||
SourceLocation ELoc = S.getLocEnd();
|
||||
auto &&CodeGen = [DynamicOrOrdered, ELoc](CodeGenFunction &CGF) {
|
||||
if (!DynamicOrOrdered)
|
||||
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
|
||||
};
|
||||
CodeGen(*this);
|
||||
|
||||
OpenMPDirectiveKind DKind = S.getDirectiveKind();
|
||||
if (DKind == OMPD_for || DKind == OMPD_parallel_for ||
|
||||
DKind == OMPD_distribute_parallel_for)
|
||||
OMPCancelStack.back().CodeGen = CodeGen;
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPForOuterLoop(
|
||||
|
|
@ -1868,6 +1889,7 @@ void CodeGenFunction::EmitOMPDistributeOuterLoop(
|
|||
void CodeGenFunction::EmitOMPDistributeParallelForDirective(
|
||||
const OMPDistributeParallelForDirective &S) {
|
||||
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
|
||||
OMPCancelStackRAII CancelRegion(*this);
|
||||
CGM.getOpenMPRuntime().emitInlinedDirective(
|
||||
*this, OMPD_distribute_parallel_for,
|
||||
[&S](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||
|
|
@ -2060,7 +2082,15 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
|
|||
[](CodeGenFunction &) {});
|
||||
EmitBlock(LoopExit.getBlock());
|
||||
// Tell the runtime we are done.
|
||||
RT.emitForStaticFinish(*this, S.getLocStart());
|
||||
SourceLocation ELoc = S.getLocEnd();
|
||||
auto &&CodeGen = [ELoc](CodeGenFunction &CGF) {
|
||||
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
|
||||
};
|
||||
CodeGen(*this);
|
||||
OpenMPDirectiveKind DKind = S.getDirectiveKind();
|
||||
if (DKind == OMPD_for || DKind == OMPD_parallel_for ||
|
||||
DKind == OMPD_distribute_parallel_for)
|
||||
OMPCancelStack.back().CodeGen = CodeGen;
|
||||
} else {
|
||||
const bool IsMonotonic =
|
||||
Ordered || ScheduleKind.Schedule == OMPC_SCHEDULE_static ||
|
||||
|
|
@ -2114,6 +2144,7 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) {
|
|||
};
|
||||
{
|
||||
OMPLexicalScope Scope(*this, S, /*AsInlined=*/true);
|
||||
OMPCancelStackRAII CancelRegion(*this);
|
||||
CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen,
|
||||
S.hasCancel());
|
||||
}
|
||||
|
|
@ -2156,6 +2187,7 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
|
|||
bool HasLastprivates = false;
|
||||
auto &&CodeGen = [&S, Stmt, CS, &HasLastprivates](CodeGenFunction &CGF,
|
||||
PrePostActionTy &) {
|
||||
OMPCancelStackRAII CancelRegion(CGF);
|
||||
auto &C = CGF.CGM.getContext();
|
||||
auto KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
|
||||
// Emit helper vars inits.
|
||||
|
|
@ -2250,7 +2282,12 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
|
|||
CGF.EmitOMPInnerLoop(S, /*RequiresCleanup=*/false, &Cond, &Inc, BodyGen,
|
||||
[](CodeGenFunction &) {});
|
||||
// Tell the runtime we are done.
|
||||
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
|
||||
SourceLocation ELoc = S.getLocEnd();
|
||||
auto &&FinalCodeGen = [ELoc](CodeGenFunction &CGF) {
|
||||
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, ELoc);
|
||||
};
|
||||
FinalCodeGen(CGF);
|
||||
CGF.OMPCancelStack.back().CodeGen = FinalCodeGen;
|
||||
CGF.EmitOMPReductionClauseFinal(S);
|
||||
// Emit post-update of the reduction variables if IsLastIter != 0.
|
||||
emitPostUpdateForReductionClause(
|
||||
|
|
@ -2375,6 +2412,7 @@ void CodeGenFunction::EmitOMPParallelForDirective(
|
|||
// Emit directive as a combined directive that consists of two implicit
|
||||
// directives: 'parallel' with 'for' directive.
|
||||
auto &&CodeGen = [&S](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||
OMPCancelStackRAII CancelRegion(CGF);
|
||||
CGF.EmitOMPWorksharingLoop(S);
|
||||
};
|
||||
emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen);
|
||||
|
|
@ -3377,8 +3415,11 @@ CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) {
|
|||
if (Kind == OMPD_parallel || Kind == OMPD_task)
|
||||
return ReturnBlock;
|
||||
assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections ||
|
||||
Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for);
|
||||
return BreakContinueStack.back().BreakBlock;
|
||||
Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for ||
|
||||
Kind == OMPD_distribute_parallel_for);
|
||||
if (!OMPCancelStack.back().ExitBlock.isValid())
|
||||
OMPCancelStack.back().ExitBlock = getJumpDestInCurrentScope("cancel.exit");
|
||||
return OMPCancelStack.back().ExitBlock;
|
||||
}
|
||||
|
||||
// Generate the instructions for '#pragma omp target data' directive.
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "clang/AST/StmtObjC.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/CodeGen/CGFunctionInfo.h"
|
||||
|
|
@ -436,6 +437,23 @@ void CodeGenFunction::EmitMCountInstrumentation() {
|
|||
EmitNounwindRuntimeCall(MCountFn);
|
||||
}
|
||||
|
||||
// Returns the address space id that should be produced to the
|
||||
// kernel_arg_addr_space metadata. This is always fixed to the ids
|
||||
// as specified in the SPIR 2.0 specification in order to differentiate
|
||||
// for example in clGetKernelArgInfo() implementation between the address
|
||||
// spaces with targets without unique mapping to the OpenCL address spaces
|
||||
// (basically all single AS CPUs).
|
||||
static unsigned ArgInfoAddressSpace(unsigned LangAS) {
|
||||
switch (LangAS) {
|
||||
case LangAS::opencl_global: return 1;
|
||||
case LangAS::opencl_constant: return 2;
|
||||
case LangAS::opencl_local: return 3;
|
||||
case LangAS::opencl_generic: return 4; // Not in SPIR 2.0 specs.
|
||||
default:
|
||||
return 0; // Assume private.
|
||||
}
|
||||
}
|
||||
|
||||
// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument
|
||||
// information in the program executable. The argument information stored
|
||||
// includes the argument name, its type, the address and access qualifiers used.
|
||||
|
|
@ -476,7 +494,7 @@ static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn,
|
|||
|
||||
// Get address qualifier.
|
||||
addressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32(
|
||||
ASTCtx.getTargetAddressSpace(pointeeTy.getAddressSpace()))));
|
||||
ArgInfoAddressSpace(pointeeTy.getAddressSpace()))));
|
||||
|
||||
// Get argument type name.
|
||||
std::string typeName =
|
||||
|
|
@ -513,8 +531,7 @@ static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn,
|
|||
uint32_t AddrSpc = 0;
|
||||
bool isPipe = ty->isPipeType();
|
||||
if (ty->isImageType() || isPipe)
|
||||
AddrSpc =
|
||||
CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);
|
||||
AddrSpc = ArgInfoAddressSpace(LangAS::opencl_global);
|
||||
|
||||
addressQuals.push_back(
|
||||
llvm::ConstantAsMetadata::get(Builder.getInt32(AddrSpc)));
|
||||
|
|
@ -1143,6 +1160,28 @@ bool CodeGenFunction::containsBreak(const Stmt *S) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CodeGenFunction::mightAddDeclToScope(const Stmt *S) {
|
||||
if (!S) return false;
|
||||
|
||||
// Some statement kinds add a scope and thus never add a decl to the current
|
||||
// scope. Note, this list is longer than the list of statements that might
|
||||
// have an unscoped decl nested within them, but this way is conservatively
|
||||
// correct even if more statement kinds are added.
|
||||
if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
|
||||
isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
|
||||
isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
|
||||
isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
|
||||
return false;
|
||||
|
||||
if (isa<DeclStmt>(S))
|
||||
return true;
|
||||
|
||||
for (const Stmt *SubStmt : S->children())
|
||||
if (mightAddDeclToScope(SubStmt))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ConstantFoldsToSimpleInteger - If the specified expression does not fold
|
||||
/// to a constant, or if it does but contains a label, return false. If it
|
||||
|
|
|
|||
|
|
@ -965,6 +965,35 @@ private:
|
|||
};
|
||||
SmallVector<BreakContinue, 8> BreakContinueStack;
|
||||
|
||||
/// Data for exit block for proper support of OpenMP cancellation constructs.
|
||||
struct OMPCancel {
|
||||
JumpDest ExitBlock;
|
||||
llvm::function_ref<void(CodeGenFunction &CGF)> CodeGen;
|
||||
OMPCancel() : CodeGen([](CodeGenFunction &CGF) {}) {}
|
||||
};
|
||||
SmallVector<OMPCancel, 8> OMPCancelStack;
|
||||
|
||||
/// Controls insertion of cancellation exit blocks in worksharing constructs.
|
||||
class OMPCancelStackRAII {
|
||||
CodeGenFunction &CGF;
|
||||
|
||||
public:
|
||||
OMPCancelStackRAII(CodeGenFunction &CGF) : CGF(CGF) {
|
||||
CGF.OMPCancelStack.push_back({});
|
||||
}
|
||||
~OMPCancelStackRAII() {
|
||||
if (CGF.HaveInsertPoint() &&
|
||||
CGF.OMPCancelStack.back().ExitBlock.isValid()) {
|
||||
auto CJD = CGF.getJumpDestInCurrentScope("cancel.cont");
|
||||
CGF.EmitBranchThroughCleanup(CJD);
|
||||
CGF.EmitBlock(CGF.OMPCancelStack.back().ExitBlock.getBlock());
|
||||
CGF.OMPCancelStack.back().CodeGen(CGF);
|
||||
CGF.EmitBranchThroughCleanup(CJD);
|
||||
CGF.EmitBlock(CJD.getBlock());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CodeGenPGO PGO;
|
||||
|
||||
/// Calculate branch weights appropriate for PGO data
|
||||
|
|
@ -3163,6 +3192,10 @@ public:
|
|||
/// If the statement (recursively) contains a switch or loop with a break
|
||||
/// inside of it, this is fine.
|
||||
static bool containsBreak(const Stmt *S);
|
||||
|
||||
/// Determine if the given statement might introduce a declaration into the
|
||||
/// current scope, by being a (possibly-labelled) DeclStmt.
|
||||
static bool mightAddDeclToScope(const Stmt *S);
|
||||
|
||||
/// ConstantFoldsToSimpleInteger - If the specified expression does not fold
|
||||
/// to a constant, or if it does but contains a label, return false. If it
|
||||
|
|
|
|||
|
|
@ -688,13 +688,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
|
|||
assert(iOSVersion && "Unknown target platform!");
|
||||
if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
|
||||
HadExtra) ||
|
||||
HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100)
|
||||
HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
|
||||
getDriver().Diag(diag::err_drv_invalid_version_number)
|
||||
<< iOSVersion->getAsString(Args);
|
||||
} else if (Platform == TvOS) {
|
||||
if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
|
||||
Micro, HadExtra) || HadExtra ||
|
||||
Major >= 10 || Minor >= 100 || Micro >= 100)
|
||||
Major >= 100 || Minor >= 100 || Micro >= 100)
|
||||
getDriver().Diag(diag::err_drv_invalid_version_number)
|
||||
<< TvOSVersion->getAsString(Args);
|
||||
} else if (Platform == WatchOS) {
|
||||
|
|
|
|||
|
|
@ -7637,23 +7637,23 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
|
|||
CmdArgs.push_back("-object_path_lto");
|
||||
CmdArgs.push_back(TmpPath);
|
||||
}
|
||||
}
|
||||
|
||||
// Use -lto_library option to specify the libLTO.dylib path. Try to find
|
||||
// it in clang installed libraries. If not found, the option is not used
|
||||
// and 'ld' will use its default mechanism to search for libLTO.dylib.
|
||||
if (Version[0] >= 133) {
|
||||
// Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
|
||||
StringRef P = llvm::sys::path::parent_path(D.getInstalledDir());
|
||||
SmallString<128> LibLTOPath(P);
|
||||
llvm::sys::path::append(LibLTOPath, "lib");
|
||||
llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
|
||||
if (llvm::sys::fs::exists(LibLTOPath)) {
|
||||
CmdArgs.push_back("-lto_library");
|
||||
CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
|
||||
} else {
|
||||
D.Diag(diag::warn_drv_lto_libpath);
|
||||
}
|
||||
}
|
||||
// Use -lto_library option to specify the libLTO.dylib path. Try to find
|
||||
// it in clang installed libraries. ld64 will only look at this argument
|
||||
// when it actually uses LTO, so libLTO.dylib only needs to exist at link
|
||||
// time if ld64 decides that it needs to use LTO.
|
||||
// Since this is passed unconditionally, ld64 will never look for libLTO.dylib
|
||||
// next to it. That's ok since ld64 using a libLTO.dylib not matching the
|
||||
// clang version won't work anyways.
|
||||
if (Version[0] >= 133) {
|
||||
// Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
|
||||
StringRef P = llvm::sys::path::parent_path(D.Dir);
|
||||
SmallString<128> LibLTOPath(P);
|
||||
llvm::sys::path::append(LibLTOPath, "lib");
|
||||
llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
|
||||
CmdArgs.push_back("-lto_library");
|
||||
CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
|
||||
}
|
||||
|
||||
// Derived from the "link" spec.
|
||||
|
|
|
|||
|
|
@ -1197,11 +1197,19 @@ BlockScopeInfo *Sema::getCurBlock() {
|
|||
return CurBSI;
|
||||
}
|
||||
|
||||
LambdaScopeInfo *Sema::getCurLambda() {
|
||||
LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) {
|
||||
if (FunctionScopes.empty())
|
||||
return nullptr;
|
||||
|
||||
auto CurLSI = dyn_cast<LambdaScopeInfo>(FunctionScopes.back());
|
||||
auto I = FunctionScopes.rbegin();
|
||||
if (IgnoreCapturedRegions) {
|
||||
auto E = FunctionScopes.rend();
|
||||
while (I != E && isa<CapturedRegionScopeInfo>(*I))
|
||||
++I;
|
||||
if (I == E)
|
||||
return nullptr;
|
||||
}
|
||||
auto *CurLSI = dyn_cast<LambdaScopeInfo>(*I);
|
||||
if (CurLSI && CurLSI->Lambda &&
|
||||
!CurLSI->Lambda->Encloses(CurContext)) {
|
||||
// We have switched contexts due to template instantiation.
|
||||
|
|
|
|||
|
|
@ -806,7 +806,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
|
|||
if (!Found.empty()) {
|
||||
if (TypeDecl *TD = Found.getAsSingle<TypeDecl>())
|
||||
Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
|
||||
<< QualType(TD->getTypeForDecl(), 0) << getLangOpts().CPlusPlus;
|
||||
<< Context.getTypeDeclType(TD) << getLangOpts().CPlusPlus;
|
||||
else {
|
||||
Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
|
||||
<< &Identifier << getLangOpts().CPlusPlus;
|
||||
|
|
|
|||
|
|
@ -9615,7 +9615,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
|
|||
}
|
||||
|
||||
VarDecl *Def;
|
||||
if ((Def = VDecl->getDefinition()) && Def != VDecl) {
|
||||
if ((Def = VDecl->getDefinition()) && Def != VDecl &&
|
||||
(!VDecl->isStaticDataMember() || VDecl->isOutOfLine())) {
|
||||
NamedDecl *Hidden = nullptr;
|
||||
if (!hasVisibleDefinition(Def, &Hidden) &&
|
||||
(VDecl->getFormalLinkage() == InternalLinkage ||
|
||||
|
|
|
|||
|
|
@ -4522,6 +4522,11 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
|
|||
MutiLevelArgList.getInnermost());
|
||||
if (Inst.isInvalid())
|
||||
return ExprError();
|
||||
if (Inst.isAlreadyInstantiating()) {
|
||||
Diag(Param->getLocStart(), diag::err_recursive_default_argument) << FD;
|
||||
Param->setInvalidDecl();
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
ExprResult Result;
|
||||
{
|
||||
|
|
@ -13880,7 +13885,8 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
|
|||
(SemaRef.CurContext != Var->getDeclContext() &&
|
||||
Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
|
||||
if (RefersToEnclosingScope) {
|
||||
if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) {
|
||||
if (LambdaScopeInfo *const LSI =
|
||||
SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) {
|
||||
// If a variable could potentially be odr-used, defer marking it so
|
||||
// until we finish analyzing the full expression for any
|
||||
// lvalue-to-rvalue
|
||||
|
|
|
|||
|
|
@ -6582,10 +6582,16 @@ static inline bool VariableCanNeverBeAConstantExpression(VarDecl *Var,
|
|||
static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(
|
||||
Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S) {
|
||||
|
||||
assert(!S.isUnevaluatedContext());
|
||||
assert(S.CurContext->isDependentContext());
|
||||
assert(CurrentLSI->CallOperator == S.CurContext &&
|
||||
assert(!S.isUnevaluatedContext());
|
||||
assert(S.CurContext->isDependentContext());
|
||||
#ifndef NDEBUG
|
||||
DeclContext *DC = S.CurContext;
|
||||
while (DC && isa<CapturedDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
assert(
|
||||
CurrentLSI->CallOperator == DC &&
|
||||
"The current call operator must be synchronized with Sema's CurContext");
|
||||
#endif // NDEBUG
|
||||
|
||||
const bool IsFullExprInstantiationDependent = FE->isInstantiationDependent();
|
||||
|
||||
|
|
@ -7051,7 +7057,8 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
|
|||
// and then the full-expression +n + ({ 0; }); ends, but it's too late
|
||||
// for us to see that we need to capture n after all.
|
||||
|
||||
LambdaScopeInfo *const CurrentLSI = getCurLambda();
|
||||
LambdaScopeInfo *const CurrentLSI =
|
||||
getCurLambda(/*IgnoreCapturedRegions=*/true);
|
||||
// FIXME: PR 17877 showed that getCurLambda() can return a valid pointer
|
||||
// even if CurContext is not a lambda call operator. Refer to that Bug Report
|
||||
// for an example of the code that might cause this asynchrony.
|
||||
|
|
@ -7066,7 +7073,10 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
|
|||
// constructor/destructor.
|
||||
// - Teach the handful of places that iterate over FunctionScopes to
|
||||
// stop at the outermost enclosing lexical scope."
|
||||
const bool IsInLambdaDeclContext = isLambdaCallOperator(CurContext);
|
||||
DeclContext *DC = CurContext;
|
||||
while (DC && isa<CapturedDecl>(DC))
|
||||
DC = DC->getParent();
|
||||
const bool IsInLambdaDeclContext = isLambdaCallOperator(DC);
|
||||
if (IsInLambdaDeclContext && CurrentLSI &&
|
||||
CurrentLSI->hasPotentialCaptures() && !FullExpr.isInvalid())
|
||||
CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(FE, CurrentLSI,
|
||||
|
|
|
|||
|
|
@ -66,17 +66,20 @@ getStackIndexOfNearestEnclosingCaptureReadyLambda(
|
|||
// Label failure to capture.
|
||||
const Optional<unsigned> NoLambdaIsCaptureReady;
|
||||
|
||||
// Ignore all inner captured regions.
|
||||
unsigned CurScopeIndex = FunctionScopes.size() - 1;
|
||||
while (CurScopeIndex > 0 && isa<clang::sema::CapturedRegionScopeInfo>(
|
||||
FunctionScopes[CurScopeIndex]))
|
||||
--CurScopeIndex;
|
||||
assert(
|
||||
isa<clang::sema::LambdaScopeInfo>(
|
||||
FunctionScopes[FunctionScopes.size() - 1]) &&
|
||||
isa<clang::sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex]) &&
|
||||
"The function on the top of sema's function-info stack must be a lambda");
|
||||
|
||||
|
||||
// If VarToCapture is null, we are attempting to capture 'this'.
|
||||
const bool IsCapturingThis = !VarToCapture;
|
||||
const bool IsCapturingVariable = !IsCapturingThis;
|
||||
|
||||
// Start with the current lambda at the top of the stack (highest index).
|
||||
unsigned CurScopeIndex = FunctionScopes.size() - 1;
|
||||
DeclContext *EnclosingDC =
|
||||
cast<sema::LambdaScopeInfo>(FunctionScopes[CurScopeIndex])->CallOperator;
|
||||
|
||||
|
|
@ -311,18 +314,21 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
|
|||
bool IsInNonspecializedTemplate =
|
||||
!ActiveTemplateInstantiations.empty() || CurContext->isDependentContext();
|
||||
switch (Kind) {
|
||||
case Normal:
|
||||
case Normal: {
|
||||
// -- the bodies of non-exported nonspecialized template functions
|
||||
// -- the bodies of inline functions
|
||||
if ((IsInNonspecializedTemplate &&
|
||||
!(ManglingContextDecl && isa<ParmVarDecl>(ManglingContextDecl))) ||
|
||||
isInInlineFunction(CurContext)) {
|
||||
ManglingContextDecl = nullptr;
|
||||
while (auto *CD = dyn_cast<CapturedDecl>(DC))
|
||||
DC = CD->getParent();
|
||||
return &Context.getManglingNumberContext(DC);
|
||||
}
|
||||
|
||||
ManglingContextDecl = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
case StaticDataMember:
|
||||
// -- the initializers of nonspecialized static members of template classes
|
||||
|
|
|
|||
|
|
@ -9133,7 +9133,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
|
|||
// for all threads of the team.
|
||||
if (!ASE && !OASE && VD) {
|
||||
VarDecl *VDDef = VD->getDefinition();
|
||||
if (VD->getType()->isReferenceType() && VDDef) {
|
||||
if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
|
||||
DSARefChecker Check(DSAStack);
|
||||
if (Check.Visit(VDDef->getInit())) {
|
||||
Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
|
||||
|
|
@ -10680,6 +10680,25 @@ static bool CheckMapConflicts(
|
|||
if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
|
||||
break;
|
||||
}
|
||||
// Check if the extra components of the expressions in the enclosing
|
||||
// data environment are redundant for the current base declaration.
|
||||
// If they are, the maps completely overlap, which is legal.
|
||||
for (; SI != SE; ++SI) {
|
||||
QualType Type;
|
||||
if (auto *ASE =
|
||||
dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
|
||||
Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
|
||||
} else if (auto *OASE =
|
||||
dyn_cast<OMPArraySectionExpr>(SI->getAssociatedExpression())) {
|
||||
auto *E = OASE->getBase()->IgnoreParenImpCasts();
|
||||
Type =
|
||||
OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
|
||||
}
|
||||
if (Type.isNull() || Type->isAnyPointerType() ||
|
||||
CheckArrayExpressionDoesNotReferToWholeSize(
|
||||
SemaRef, SI->getAssociatedExpression(), Type))
|
||||
break;
|
||||
}
|
||||
|
||||
// OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
|
||||
// List items of map clauses in the same construct must not share
|
||||
|
|
|
|||
|
|
@ -3256,7 +3256,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
|||
// on the previously-computed template arguments.
|
||||
if (ArgType->getType()->isDependentType()) {
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
||||
Template, Converted,
|
||||
Param, Template, Converted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return nullptr;
|
||||
|
|
@ -3308,7 +3308,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
|||
NonTypeTemplateParmDecl *Param,
|
||||
SmallVectorImpl<TemplateArgument> &Converted) {
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
||||
Template, Converted,
|
||||
Param, Template, Converted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return ExprError();
|
||||
|
|
@ -3359,8 +3359,9 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
|
|||
TemplateTemplateParmDecl *Param,
|
||||
SmallVectorImpl<TemplateArgument> &Converted,
|
||||
NestedNameSpecifierLoc &QualifierLoc) {
|
||||
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, Template, Converted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
Sema::InstantiatingTemplate Inst(
|
||||
SemaRef, TemplateLoc, TemplateParameter(Param), Template, Converted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
return TemplateName();
|
||||
|
||||
|
|
@ -3981,7 +3982,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
}
|
||||
|
||||
// Introduce an instantiation record that describes where we are using
|
||||
// the default template argument.
|
||||
// the default template argument. We're not actually instantiating a
|
||||
// template here, we just create this object to put a note into the
|
||||
// context stack.
|
||||
InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param, Converted,
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
if (Inst.isInvalid())
|
||||
|
|
|
|||
|
|
@ -225,6 +225,10 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|||
Inst.NumTemplateArgs = TemplateArgs.size();
|
||||
Inst.DeductionInfo = DeductionInfo;
|
||||
Inst.InstantiationRange = InstantiationRange;
|
||||
AlreadyInstantiating =
|
||||
!SemaRef.InstantiatingSpecializations
|
||||
.insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
|
||||
.second;
|
||||
SemaRef.InNonInstantiationSFINAEContext = false;
|
||||
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
|
||||
if (!Inst.isInstantiationRecord())
|
||||
|
|
@ -247,13 +251,14 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|||
PointOfInstantiation, InstantiationRange, Entity) {}
|
||||
|
||||
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
||||
Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateDecl *Template,
|
||||
ArrayRef<TemplateArgument> TemplateArgs, SourceRange InstantiationRange)
|
||||
Sema &SemaRef, SourceLocation PointOfInstantiation, TemplateParameter Param,
|
||||
TemplateDecl *Template, ArrayRef<TemplateArgument> TemplateArgs,
|
||||
SourceRange InstantiationRange)
|
||||
: InstantiatingTemplate(
|
||||
SemaRef,
|
||||
ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation,
|
||||
PointOfInstantiation, InstantiationRange, Template, nullptr,
|
||||
TemplateArgs) {}
|
||||
PointOfInstantiation, InstantiationRange, getAsNamedDecl(Param),
|
||||
Template, TemplateArgs) {}
|
||||
|
||||
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
||||
Sema &SemaRef, SourceLocation PointOfInstantiation,
|
||||
|
|
@ -263,7 +268,11 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|||
sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
|
||||
: InstantiatingTemplate(SemaRef, Kind, PointOfInstantiation,
|
||||
InstantiationRange, FunctionTemplate, nullptr,
|
||||
TemplateArgs, &DeductionInfo) {}
|
||||
TemplateArgs, &DeductionInfo) {
|
||||
assert(
|
||||
Kind == ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution ||
|
||||
Kind == ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
|
||||
}
|
||||
|
||||
Sema::InstantiatingTemplate::InstantiatingTemplate(
|
||||
Sema &SemaRef, SourceLocation PointOfInstantiation,
|
||||
|
|
@ -327,7 +336,8 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
|
|||
|
||||
void Sema::InstantiatingTemplate::Clear() {
|
||||
if (!Invalid) {
|
||||
if (!SemaRef.ActiveTemplateInstantiations.back().isInstantiationRecord()) {
|
||||
auto &Active = SemaRef.ActiveTemplateInstantiations.back();
|
||||
if (!Active.isInstantiationRecord()) {
|
||||
assert(SemaRef.NonInstantiationEntries > 0);
|
||||
--SemaRef.NonInstantiationEntries;
|
||||
}
|
||||
|
|
@ -345,6 +355,10 @@ void Sema::InstantiatingTemplate::Clear() {
|
|||
SemaRef.ActiveTemplateInstantiationLookupModules.pop_back();
|
||||
}
|
||||
|
||||
if (!AlreadyInstantiating)
|
||||
SemaRef.InstantiatingSpecializations.erase(
|
||||
std::make_pair(Active.Entity, Active.Kind));
|
||||
|
||||
SemaRef.ActiveTemplateInstantiations.pop_back();
|
||||
Invalid = true;
|
||||
}
|
||||
|
|
@ -443,7 +457,7 @@ void Sema::PrintInstantiationStack() {
|
|||
}
|
||||
|
||||
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
|
||||
TemplateDecl *Template = cast<TemplateDecl>(Active->Entity);
|
||||
TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
|
||||
SmallVector<char, 128> TemplateArgsStr;
|
||||
llvm::raw_svector_ostream OS(TemplateArgsStr);
|
||||
Template->printName(OS);
|
||||
|
|
@ -1950,6 +1964,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
|
|||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
||||
if (Inst.isInvalid())
|
||||
return true;
|
||||
assert(!Inst.isAlreadyInstantiating() && "should have been caught by caller");
|
||||
PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(),
|
||||
"instantiating class definition");
|
||||
|
||||
|
|
@ -2175,6 +2190,8 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
|
|||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
||||
if (Inst.isInvalid())
|
||||
return true;
|
||||
if (Inst.isAlreadyInstantiating())
|
||||
return false;
|
||||
PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(),
|
||||
"instantiating enum definition");
|
||||
|
||||
|
|
@ -2249,6 +2266,12 @@ bool Sema::InstantiateInClassInitializer(
|
|||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
|
||||
if (Inst.isInvalid())
|
||||
return true;
|
||||
if (Inst.isAlreadyInstantiating()) {
|
||||
// Error out if we hit an instantiation cycle for this initializer.
|
||||
Diag(PointOfInstantiation, diag::err_in_class_initializer_cycle)
|
||||
<< Instantiation;
|
||||
return true;
|
||||
}
|
||||
PrettyDeclStackTraceEntry CrashInfo(*this, Instantiation, SourceLocation(),
|
||||
"instantiating default member init");
|
||||
|
||||
|
|
|
|||
|
|
@ -3360,6 +3360,13 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
|
|||
UpdateExceptionSpec(Decl, EST_None);
|
||||
return;
|
||||
}
|
||||
if (Inst.isAlreadyInstantiating()) {
|
||||
// This exception specification indirectly depends on itself. Reject.
|
||||
// FIXME: Corresponding rule in the standard?
|
||||
Diag(PointOfInstantiation, diag::err_exception_spec_cycle) << Decl;
|
||||
UpdateExceptionSpec(Decl, EST_None);
|
||||
return;
|
||||
}
|
||||
|
||||
// Enter the scope of this instantiation. We don't use
|
||||
// PushDeclContext because we don't have a scope.
|
||||
|
|
@ -3619,7 +3626,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
|
|||
}
|
||||
|
||||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
|
||||
if (Inst.isInvalid())
|
||||
if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
|
||||
return;
|
||||
PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(),
|
||||
"instantiating function definition");
|
||||
|
|
@ -3882,10 +3889,6 @@ void Sema::InstantiateVariableInitializer(
|
|||
else if (OldVar->isInline())
|
||||
Var->setImplicitlyInline();
|
||||
|
||||
if (Var->getAnyInitializer())
|
||||
// We already have an initializer in the class.
|
||||
return;
|
||||
|
||||
if (OldVar->getInit()) {
|
||||
if (Var->isStaticDataMember() && !OldVar->isOutOfLine())
|
||||
PushExpressionEvaluationContext(Sema::ConstantEvaluated, OldVar);
|
||||
|
|
@ -3921,9 +3924,23 @@ void Sema::InstantiateVariableInitializer(
|
|||
}
|
||||
|
||||
PopExpressionEvaluationContext();
|
||||
} else if ((!Var->isStaticDataMember() || Var->isOutOfLine()) &&
|
||||
!Var->isCXXForRangeDecl())
|
||||
} else {
|
||||
if (Var->isStaticDataMember()) {
|
||||
if (!Var->isOutOfLine())
|
||||
return;
|
||||
|
||||
// If the declaration inside the class had an initializer, don't add
|
||||
// another one to the out-of-line definition.
|
||||
if (OldVar->getFirstDecl()->hasInit())
|
||||
return;
|
||||
}
|
||||
|
||||
// We'll add an initializer to a for-range declaration later.
|
||||
if (Var->isCXXForRangeDecl())
|
||||
return;
|
||||
|
||||
ActOnUninitializedDecl(Var, false);
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Instantiate the definition of the given variable from its
|
||||
|
|
@ -4013,7 +4030,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
|
|||
// FIXME: Factor out the duplicated instantiation context setup/tear down
|
||||
// code here.
|
||||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
|
||||
if (Inst.isInvalid())
|
||||
if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
|
||||
return;
|
||||
PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(),
|
||||
"instantiating variable initializer");
|
||||
|
|
@ -4142,7 +4159,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
|
|||
}
|
||||
|
||||
InstantiatingTemplate Inst(*this, PointOfInstantiation, Var);
|
||||
if (Inst.isInvalid())
|
||||
if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
|
||||
return;
|
||||
PrettyDeclStackTraceEntry CrashInfo(*this, Var, SourceLocation(),
|
||||
"instantiating variable definition");
|
||||
|
|
|
|||
|
|
@ -2220,7 +2220,7 @@ void ASTDeclReader::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
|||
VisitDecl(D);
|
||||
D->AssertExprAndFailed.setPointer(Reader.ReadExpr(F));
|
||||
D->AssertExprAndFailed.setInt(Record[Idx++]);
|
||||
D->Message = cast<StringLiteral>(Reader.ReadExpr(F));
|
||||
D->Message = cast_or_null<StringLiteral>(Reader.ReadExpr(F));
|
||||
D->RParenLoc = ReadSourceLocation(Record, Idx);
|
||||
}
|
||||
|
||||
|
|
|
|||
19
test/CodeGenCXX/PR28523.cpp
Normal file
19
test/CodeGenCXX/PR28523.cpp
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// RUN: %clang_cc1 -std=c++14 -verify -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
template <class F> void parallel_loop(F &&f) { f(0); }
|
||||
|
||||
//CHECK-LABEL: @main
|
||||
int main() {
|
||||
// CHECK: [[X_ADDR:%.+]] = alloca i32,
|
||||
int x;
|
||||
// CHECK: getelementptr inbounds
|
||||
// CHECK: store i32* [[X_ADDR]], i32** %
|
||||
// CHECK: call
|
||||
parallel_loop([&](auto y) {
|
||||
#pragma clang __debug captured
|
||||
{
|
||||
x = y;
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
@ -78,6 +78,7 @@ void test3(int x) {
|
|||
{
|
||||
x = [=]() { return x + 1; } ();
|
||||
}
|
||||
x = [=]() { return x + 1; }();
|
||||
|
||||
// CHECK-3: %[[Capture:struct\.anon[\.0-9]*]] = type { i32* }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
|
||||
// CHECK that we don't crash.
|
||||
|
||||
extern int printf(const char*, ...);
|
||||
|
||||
// CHECK-LABEL: @_Z4testi(
|
||||
int test(int val){
|
||||
switch (val) {
|
||||
case 4:
|
||||
do {
|
||||
switch (6) {
|
||||
// CHECK: call i32 (i8*, ...) @_Z6printfPKcz
|
||||
case 6: do { case 5: printf("bad\n"); } while (0);
|
||||
};
|
||||
} while (0);
|
||||
|
|
@ -18,6 +20,7 @@ int main(void) {
|
|||
return test(5);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @_Z10other_testv(
|
||||
void other_test() {
|
||||
switch(0) {
|
||||
case 0:
|
||||
|
|
@ -27,4 +30,79 @@ void other_test() {
|
|||
}
|
||||
}
|
||||
|
||||
// CHECK: call i32 (i8*, ...) @_Z6printfPKcz
|
||||
struct X { X(); ~X(); };
|
||||
|
||||
void dont_call();
|
||||
void foo();
|
||||
|
||||
// CHECK-LABEL: @_Z13nested_scopesv(
|
||||
void nested_scopes() {
|
||||
switch (1) {
|
||||
case 0:
|
||||
// CHECK-NOT: @_Z9dont_callv(
|
||||
dont_call();
|
||||
break;
|
||||
|
||||
default:
|
||||
// CHECK: call {{.*}} @_ZN1XC1Ev(
|
||||
// CHECK: call {{.*}} @_Z3foov(
|
||||
// CHECK-NOT: call {{.*}} @_Z3foov(
|
||||
// CHECK: call {{.*}} @_ZN1XD1Ev(
|
||||
{ X x; foo(); }
|
||||
|
||||
// CHECK: call {{.*}} @_ZN1XC1Ev(
|
||||
// CHECK: call {{.*}} @_Z3foov(
|
||||
// CHECK: call {{.*}} @_ZN1XD1Ev(
|
||||
{ X x; foo(); }
|
||||
|
||||
// CHECK: call {{.*}} @_ZN1XC1Ev(
|
||||
// CHECK: call {{.*}} @_Z3foov(
|
||||
// CHECK: call {{.*}} @_ZN1XD1Ev(
|
||||
{ X x; foo(); }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @_Z17scope_fallthroughv(
|
||||
void scope_fallthrough() {
|
||||
switch (1) {
|
||||
// CHECK: call {{.*}} @_ZN1XC1Ev(
|
||||
// CHECK-NOT: call {{.*}} @_Z3foov(
|
||||
// CHECK: call {{.*}} @_ZN1XD1Ev(
|
||||
{ default: X x; }
|
||||
// CHECK: call {{.*}} @_Z3foov(
|
||||
foo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @_Z12hidden_breakb(
|
||||
void hidden_break(bool b) {
|
||||
switch (1) {
|
||||
default:
|
||||
// CHECK: br
|
||||
if (b)
|
||||
break;
|
||||
// CHECK: call {{.*}} @_Z3foov(
|
||||
foo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @_Z10hidden_varv(
|
||||
int hidden_var() {
|
||||
switch (1) {
|
||||
// CHECK: %[[N:.*]] = alloca i32
|
||||
case 0: int n;
|
||||
// CHECK: store i32 0, i32* %[[N]]
|
||||
// CHECK: load i32, i32* %[[N]]
|
||||
// CHECK: ret
|
||||
default: n = 0; return n;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @_Z13case_in_labelv(
|
||||
void case_in_label() {
|
||||
// CHECK: br label %
|
||||
switch (1) case 1: foo: case 0: goto foo;
|
||||
}
|
||||
|
|
|
|||
9
test/CodeGenOpenCL/kernel-arg-info-single-as.cl
Normal file
9
test/CodeGenOpenCL/kernel-arg-info-single-as.cl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// Test that the kernel argument info always refers to SPIR address spaces,
|
||||
// even if the target has only one address space like x86_64 does.
|
||||
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown -cl-kernel-arg-info | FileCheck %s
|
||||
|
||||
kernel void foo(__global int * G, __constant int *C, __local int *L) {
|
||||
*G = *C + *L;
|
||||
}
|
||||
// CHECK: !kernel_arg_addr_space ![[MD123:[0-9]+]]
|
||||
// CHECK: ![[MD123]] = !{i32 1, i32 2, i32 3}
|
||||
|
|
@ -1,25 +1,16 @@
|
|||
// REQUIRES: system-darwin
|
||||
|
||||
// Check that ld gets "-lto_library" and warnings about libLTO.dylib path.
|
||||
// Check that ld gets "-lto_library".
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -### %s \
|
||||
// RUN: -mlinker-version=133 -flto 2> %t.log
|
||||
// RUN: cat %t.log
|
||||
// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s < %t.log
|
||||
// RUN: -ccc-install-dir %T/bin -mlinker-version=133 2> %t.log
|
||||
// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s -input-file %t.log
|
||||
//
|
||||
// LINK_LTOLIB_PATH: {{ld(.exe)?"}}
|
||||
// LINK_LTOLIB_PATH: "-lto_library"
|
||||
|
||||
// Also pass -lto_library even if the file doesn't exist; if it's needed at
|
||||
// link time, ld will complain instead.
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -### %s \
|
||||
// RUN: -ccc-install-dir %S/dummytestdir -mlinker-version=133 -flto 2> %t.log
|
||||
// RUN: cat %t.log
|
||||
// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH_WRN %s < %t.log
|
||||
//
|
||||
// LINK_LTOLIB_PATH_WRN: warning: libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead
|
||||
|
||||
// RUN: %clang -target x86_64-apple-darwin10 -### %s \
|
||||
// RUN: -ccc-install-dir %S/dummytestdir -mlinker-version=133 -Wno-liblto -flto 2> %t.log
|
||||
// RUN: cat %t.log
|
||||
// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH_NOWRN %s < %t.log
|
||||
//
|
||||
// LINK_LTOLIB_PATH_NOWRN-NOT: warning: libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead
|
||||
// RUN: -ccc-install-dir %S/dummytestdir -mlinker-version=133 2> %t.log
|
||||
// RUN: FileCheck -check-prefix=LINK_LTOLIB_PATH %s -input-file %t.log
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
// RUN: %clang_cc1 -triple armv6-apple-ios2.3.1 -dM -E -o %t %s
|
||||
// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '20301' | count 1
|
||||
// RUN: not grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t
|
||||
// RUN: %clang_cc1 -triple armv7-apple-ios10.1.2 -dM -E -o %t %s
|
||||
// RUN: grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t | grep '100102' | count 1
|
||||
// RUN: %clang_cc1 -triple i386-apple-macosx10.4.0 -dM -E -o %t %s
|
||||
// RUN: grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t | grep '1040' | count 1
|
||||
// RUN: not grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t
|
||||
|
|
@ -32,6 +34,8 @@
|
|||
// RUN: grep '__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__' %t | grep '80300' | count 1
|
||||
// RUN: not grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t
|
||||
// RUN: not grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t
|
||||
// RUN: %clang_cc1 -triple arm64-apple-tvos10.2.3 -dM -E -o %t %s
|
||||
// RUN: grep '__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__' %t | grep '100203' | count 1
|
||||
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-tvos8.3 -dM -E -o %t %s
|
||||
// RUN: grep '__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__' %t | grep '80300' | count 1
|
||||
|
|
|
|||
3
test/Modules/Inputs/static_assert/a.h
Normal file
3
test/Modules/Inputs/static_assert/a.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
class S {
|
||||
static_assert(4 == 4);
|
||||
};
|
||||
1
test/Modules/Inputs/static_assert/module.modulemap
Normal file
1
test/Modules/Inputs/static_assert/module.modulemap
Normal file
|
|
@ -0,0 +1 @@
|
|||
module a { header "a.h" }
|
||||
8
test/Modules/static_assert.cpp
Normal file
8
test/Modules/static_assert.cpp
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fimplicit-module-maps \
|
||||
// RUN: -I%S/Inputs/static_assert -std=c++1z -verify %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#include "a.h"
|
||||
|
||||
S s;
|
||||
|
|
@ -78,6 +78,9 @@ float2 float2x;
|
|||
register int rix __asm__("esp");
|
||||
|
||||
int main() {
|
||||
// CHECK: store atomic i32 1, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @civ, i32 0, i32 1) monotonic,
|
||||
#pragma omp atomic write
|
||||
__imag(civ) = 1;
|
||||
// CHECK: load i8, i8*
|
||||
// CHECK: store atomic i8
|
||||
#pragma omp atomic write
|
||||
|
|
|
|||
|
|
@ -91,9 +91,11 @@ for (int i = 0; i < argc; ++i) {
|
|||
}
|
||||
}
|
||||
// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
|
||||
#pragma omp parallel for
|
||||
int r = 0;
|
||||
#pragma omp parallel for reduction(+:r)
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
#pragma omp cancel for
|
||||
r += i;
|
||||
}
|
||||
// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
|
||||
return argc;
|
||||
|
|
@ -164,6 +166,9 @@ for (int i = 0; i < argc; ++i) {
|
|||
// CHECK: [[CONTINUE]]
|
||||
// CHECK: br label
|
||||
// CHECK: call void @__kmpc_for_static_fini(
|
||||
// CHECK: call i32 @__kmpc_reduce_nowait(
|
||||
// CHECK: call void @__kmpc_end_reduce_nowait(
|
||||
// CHECK: call void @__kmpc_for_static_fini(
|
||||
// CHECK: ret void
|
||||
|
||||
#endif
|
||||
|
|
|
|||
13
test/OpenMP/debug-info-openmp-array.cpp
Normal file
13
test/OpenMP/debug-info-openmp-array.cpp
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
void f(int m) {
|
||||
int i;
|
||||
int cen[m];
|
||||
#pragma omp parallel for
|
||||
for (i = 0; i < m; ++i) {
|
||||
cen[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: !DILocalVariable(name: "cen", arg: 6
|
||||
|
|
@ -9,6 +9,14 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute parallel for reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute parallel for simd reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target
|
||||
#pragma omp teams
|
||||
#pragma omp distribute simd reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ struct SS {
|
|||
for (a = 0; a < 2; ++a)
|
||||
#ifdef LAMBDA
|
||||
[&]() {
|
||||
++this->a, --b, (this)->c /= 1;
|
||||
--this->a, ++b, (this)->c *= 2;
|
||||
#pragma omp parallel
|
||||
#pragma omp for lastprivate(b)
|
||||
for (b = 0; b < 2; ++b)
|
||||
|
|
@ -190,7 +190,7 @@ int main() {
|
|||
// LAMBDA: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[SS_TY]]*)* [[SS_MICROTASK:@.+]] to void
|
||||
// LAMBDA: call void @__kmpc_for_static_init_4(
|
||||
// LAMBDA-NOT: getelementptr inbounds [[SS_TY]], [[SS_TY]]* %{{.+}}, i32 0, i32 0
|
||||
// LAMBDA: call void {{.+}} [[SS_LAMBDA:@[^ ]+]]
|
||||
// LAMBDA: call{{.*}} void [[SS_LAMBDA1:@[^ ]+]]
|
||||
// LAMBDA: call void @__kmpc_for_static_fini(%
|
||||
// LAMBDA: ret
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ int main() {
|
|||
// LAMBDA: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 2
|
||||
// LAMBDA: call void @__kmpc_for_static_init_4(
|
||||
// LAMBDA-NOT: getelementptr {{.*}}[[SS_TY]], [[SS_TY]]*
|
||||
// LAMBDA: call{{.*}} void
|
||||
// LAMBDA: call{{.*}} void [[SS_LAMBDA:@[^ ]+]]
|
||||
// LAMBDA: call void @__kmpc_for_static_fini(
|
||||
// LAMBDA: br i1
|
||||
// LAMBDA: [[B_REF:%.+]] = getelementptr {{.*}}[[SS_TY]], [[SS_TY]]* %{{.*}}, i32 0, i32 1
|
||||
|
|
@ -236,6 +236,9 @@ int main() {
|
|||
// LAMBDA: br label
|
||||
// LAMBDA: ret void
|
||||
|
||||
// LAMBDA: define internal void @{{.+}}(i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[SS_TY]]* %{{.+}})
|
||||
// LAMBDA: ret void
|
||||
|
||||
// LAMBDA: define{{.*}} internal{{.*}} void [[OMP_REGION]](i32* noalias %{{.+}}, i32* noalias %{{.+}}, i32* dereferenceable(4) [[SIVAR:%.+]])
|
||||
// LAMBDA: alloca i{{[0-9]+}},
|
||||
// LAMBDA: alloca i{{[0-9]+}},
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ int main() {
|
|||
// CHECK: store float [[UP]], float* [[T_VAR1_LHS]],
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
|
||||
// Reduction list for runtime.
|
||||
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
|
||||
|
|
@ -696,7 +696,7 @@ int main() {
|
|||
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}})
|
||||
|
||||
// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
|
||||
|
||||
|
|
|
|||
|
|
@ -301,7 +301,7 @@ int main() {
|
|||
// CHECK: fadd float 5.550000e+02, %
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK1]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [2 x i32]* dereferenceable(8) %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
|
||||
// Reduction list for runtime.
|
||||
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
|
||||
|
|
@ -500,7 +500,7 @@ int main() {
|
|||
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(480) %{{.+}})
|
||||
|
||||
// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]],
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel
|
||||
#pragma omp for reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel
|
||||
#pragma omp for simd reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
// CHECK-DEBUG-DAG: %ident_t = type { i32, i32, i32, i32, i8* }
|
||||
// CHECK-DEBUG-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00"
|
||||
// CHECK-DEBUG-DAG: [[DEF_LOC_2:@.+]] = private unnamed_addr constant %ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* [[STR]], i32 0, i32 0) }
|
||||
// CHECK-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;main;[[@LINE+14]];9;;\00"
|
||||
// CHECK-DEBUG-DAG: [[LOC1:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;main;[[@LINE+15]];9;;\00"
|
||||
// CHECK-DEBUG-DAG: [[LOC2:@.+]] = private unnamed_addr constant [{{.+}} x i8] c";{{.*}}parallel_codegen.cpp;tmain;[[@LINE+7]];9;;\00"
|
||||
|
||||
template <class T>
|
||||
|
|
@ -25,17 +25,19 @@ int tmain(T argc) {
|
|||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int a[argc];
|
||||
#pragma omp parallel
|
||||
foo(argc);
|
||||
foo(a[1]);
|
||||
return tmain(argv);
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define {{[a-z\_\b]*[ ]?i32}} @main({{i32[ ]?[a-z]*}} %argc, i8** %argv)
|
||||
// CHECK: store i32 %argc, i32* [[ARGC_ADDR:%.+]],
|
||||
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC_ADDR]])
|
||||
// CHECK: [[VLA:%.+]] = alloca i32, i{{[0-9]+}} [[VLA_SIZE:%[^,]+]],
|
||||
// CHECK: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[DEF_LOC_2]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i{{[0-9]+}}, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i{{[0-9]+}} [[VLA_SIZE]], i32* [[VLA]])
|
||||
// CHECK-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}}
|
||||
// CHECK-NEXT: [[RET:%.+]] = call {{[a-z\_\b]*[ ]?i32}} [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
|
||||
// CHECK-NEXT: ret i32 [[RET]]
|
||||
// CHECK: ret i32
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-DEBUG-LABEL: define i32 @main(i32 %argc, i8** %argv)
|
||||
// CHECK-DEBUG: [[LOC_2_ADDR:%.+]] = alloca %ident_t
|
||||
|
|
@ -43,30 +45,33 @@ int main (int argc, char **argv) {
|
|||
// CHECK-DEBUG-NEXT: [[KMPC_DEFAULT_LOC_VOIDPTR:%.+]] = bitcast %ident_t* [[DEF_LOC_2]] to i8*
|
||||
// CHECK-DEBUG-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[KMPC_LOC_VOIDPTR]], i8* [[KMPC_DEFAULT_LOC_VOIDPTR]], i64 24, i32 8, i1 false)
|
||||
// CHECK-DEBUG: store i32 %argc, i32* [[ARGC_ADDR:%.+]],
|
||||
// CHECK-DEBUG: [[VLA:%.+]] = alloca i32, i64 [[VLA_SIZE:%[^,]+]],
|
||||
// CHECK-DEBUG: [[KMPC_LOC_PSOURCE_REF:%.+]] = getelementptr inbounds %ident_t, %ident_t* [[LOC_2_ADDR]], i32 0, i32 4
|
||||
// CHECK-DEBUG-NEXT: store i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* [[LOC1]], i32 0, i32 0), i8** [[KMPC_LOC_PSOURCE_REF]]
|
||||
// CHECK-DEBUG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i32* [[ARGC_ADDR]])
|
||||
// CHECK-DEBUG: call {{.*}}void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* [[LOC_2_ADDR]], i32 2, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64, i32*)* [[OMP_OUTLINED:@.+]] to void (i32*, i32*, ...)*), i64 [[VLA_SIZE]], i32* [[VLA]])
|
||||
// CHECK-DEBUG-NEXT: [[ARGV:%.+]] = load i8**, i8*** {{%[a-z0-9.]+}}
|
||||
// CHECK-DEBUG-NEXT: [[RET:%.+]] = call i32 [[TMAIN:@.+tmain.+]](i8** [[ARGV]])
|
||||
// CHECK-DEBUG-NEXT: ret i32 [[RET]]
|
||||
// CHECK-DEBUG: ret i32
|
||||
// CHECK-DEBUG-NEXT: }
|
||||
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) [[ARGC_ADDR:%[^)]+]])
|
||||
// CHECK: define internal {{.*}}void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i{{[0-9]+}}{{.*}} [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-SAME: #[[FN_ATTRS:[0-9]+]]
|
||||
// CHECK: store i32* [[ARGC_ADDR]], i32** [[ARGC_PTR_ADDR:%.+]],
|
||||
// CHECK: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]]
|
||||
// CHECK-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]]
|
||||
// CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[ARGC]])
|
||||
// CHECK: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]],
|
||||
// CHECK: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]]
|
||||
// CHECK: [[VLA_ELEM_REF:%.+]] = getelementptr inbounds i32, i32* [[VLA_REF]], i{{[0-9]+}} 1
|
||||
// CHECK-NEXT: [[VLA_ELEM:%.+]] = load i32, i32* [[VLA_ELEM_REF]]
|
||||
// CHECK-NEXT: invoke {{.*}}void [[FOO:@.+foo.+]](i32{{[ ]?[a-z]*}} [[VLA_ELEM]])
|
||||
// CHECK: ret void
|
||||
// CHECK: call {{.*}}void @{{.+terminate.*|abort}}(
|
||||
// CHECK-NEXT: unreachable
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i32* dereferenceable(4) [[ARGC_ADDR:%[^)]+]])
|
||||
// CHECK-DEBUG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i64 [[VLA_SIZE:%.+]], i32* [[VLA_ADDR:%[^)]+]])
|
||||
// CHECK-DEBUG-SAME: #[[FN_ATTRS:[0-9]+]]
|
||||
// CHECK-DEBUG: store i32* [[ARGC_ADDR]], i32** [[ARGC_PTR_ADDR:%.+]],
|
||||
// CHECK-DEBUG: [[ARGC_REF:%.+]] = load i32*, i32** [[ARGC_PTR_ADDR]]
|
||||
// CHECK-DEBUG-NEXT: [[ARGC:%.+]] = load i32, i32* [[ARGC_REF]]
|
||||
// CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[ARGC]])
|
||||
// CHECK-DEBUG: store i32* [[VLA_ADDR]], i32** [[VLA_PTR_ADDR:%.+]],
|
||||
// CHECK-DEBUG: [[VLA_REF:%.+]] = load i32*, i32** [[VLA_PTR_ADDR]]
|
||||
// CHECK-DEBUG: [[VLA_ELEM_REF:%.+]] = getelementptr inbounds i32, i32* [[VLA_REF]], i64 1
|
||||
// CHECK-DEBUG-NEXT: [[VLA_ELEM:%.+]] = load i32, i32* [[VLA_ELEM_REF]]
|
||||
// CHECK-DEBUG-NEXT: invoke void [[FOO:@.+foo.+]](i32 [[VLA_ELEM]])
|
||||
// CHECK-DEBUG: ret void
|
||||
// CHECK-DEBUG: call void @{{.+terminate.*|abort}}(
|
||||
// CHECK-DEBUG-NEXT: unreachable
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel for reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel for simd reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel reduction(+:ref)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel sections reduction(+:ref)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp parallel
|
||||
#pragma omp sections reduction(+:ref)
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp simd reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ int foo(int n, double *ptr) {
|
|||
|
||||
// make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
|
||||
// target region
|
||||
// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* {{.+}} [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* {{.+}} [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
|
||||
// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], i{{[0-9]+}} [[BN_SZ:%.+]], float* [[BN_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], i{{[0-9]+}} [[CN_SZ1:%.+]], i{{[0-9]+}} [[CN_SZ2:%.+]], double* [[CN_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
|
||||
// TCHECK: [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
|
||||
// TCHECK: [[B_ADDR:%.+]] = alloca [10 x float]*,
|
||||
// TCHECK: [[VLA_ADDR:%.+]] = alloca i{{[0-9]+}},
|
||||
|
|
|
|||
|
|
@ -645,7 +645,7 @@ void implicit_maps_variable_length_array (int a){
|
|||
}
|
||||
}
|
||||
|
||||
// CK13: define internal void [[KERNEL]](i[[sz]] [[VLA0:%.+]], i[[sz]] [[VLA1:%.+]], double* {{.+}}[[ARG:%.+]])
|
||||
// CK13: define internal void [[KERNEL]](i[[sz]] [[VLA0:%.+]], i[[sz]] [[VLA1:%.+]], double* {{.*}}[[ARG:%.+]])
|
||||
// CK13: [[ADDR0:%.+]] = alloca i[[sz]],
|
||||
// CK13: [[ADDR1:%.+]] = alloca i[[sz]],
|
||||
// CK13: [[ADDR2:%.+]] = alloca double*,
|
||||
|
|
@ -4074,7 +4074,9 @@ int explicit_maps_with_inner_lambda(int a){
|
|||
// CK25: [[VAL1:%.+]] = load i32*, i32** [[VALADDR]],
|
||||
// CK25: [[VALADDR1:%.+]] = getelementptr inbounds [[CA01]], [[CA01]]* [[CA:%[^,]+]], i32 0, i32 0
|
||||
// CK25: store i32* [[VAL1]], i32** [[VALADDR1]],
|
||||
// CK25: call void {{.*}}[[LAMBDA]]{{.*}}([[CA01]]* [[CA]])
|
||||
// CK25: call void {{.*}}[[LAMBDA2:@.+]]{{.*}}([[CA01]]* [[CA]])
|
||||
|
||||
// CK25: define {{.+}}[[LAMBDA2]]
|
||||
#endif
|
||||
///==========================================================================///
|
||||
// RUN: %clang_cc1 -DCK26 -std=c++11 -verify -fopenmp -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple powerpc64le-unknown-unknown -emit-llvm %s -o - | FileCheck %s --check-prefix CK26 --check-prefix CK26-64
|
||||
|
|
|
|||
|
|
@ -284,6 +284,11 @@ void SAclient(int arg) {
|
|||
{}
|
||||
}
|
||||
}
|
||||
#pragma omp target data map(marr[:][:][:])
|
||||
{
|
||||
#pragma omp target data map(marr)
|
||||
{}
|
||||
}
|
||||
|
||||
#pragma omp target data map(to: t)
|
||||
{
|
||||
|
|
@ -419,10 +424,10 @@ T tmain(T argc) {
|
|||
#pragma omp target data map(j)
|
||||
#pragma omp target map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
#pragma omp target data map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
|
||||
#pragma omp target data map(j)
|
||||
#pragma omp target map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target map(l)
|
||||
foo();
|
||||
|
||||
#pragma omp target data map(always, tofrom: x)
|
||||
|
|
@ -488,10 +493,10 @@ int main(int argc, char **argv) {
|
|||
#pragma omp target data map(j)
|
||||
#pragma omp target map(l) map(l[:5]) // expected-error {{variable already marked as mapped in current construct}} expected-note {{used here}}
|
||||
foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
|
||||
#pragma omp target data map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
|
||||
#pragma omp target data map(j)
|
||||
#pragma omp target map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target map(l)
|
||||
foo();
|
||||
|
||||
#pragma omp target data map(always, tofrom: x)
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ T tmain(T argc) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
{
|
||||
#pragma omp target parallel for map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(j)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target parallel for map(l)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
}
|
||||
|
||||
|
|
@ -247,13 +247,13 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
|
||||
{
|
||||
#pragma omp target parallel for map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(j)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target parallel for map(l)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target parallel for reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ T tmain(T argc) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
{
|
||||
#pragma omp target parallel for simd map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for simd map(j)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for simd map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target parallel for simd map(l)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
}
|
||||
|
||||
|
|
@ -247,13 +247,13 @@ int main(int argc, char **argv) {
|
|||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for simd map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note {{used here}}
|
||||
{
|
||||
#pragma omp target parallel for simd map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for simd map(j)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp target parallel for simd map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target parallel for simd map(l)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target parallel for simd reduction(+:ref)
|
||||
for (int i = 0; i < 10; ++i)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ T tmain(T argc) {
|
|||
foo();
|
||||
#pragma omp target parallel map(l) map(l[:5]) // expected-error 2 {{variable already marked as mapped in current construct}} expected-note 2 {{used here}}
|
||||
foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 4 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
{
|
||||
#pragma omp target parallel map(k) // expected-error 2 {{pointer cannot be mapped along with a section derived from itself}}
|
||||
foo();
|
||||
#pragma omp target parallel map(j)
|
||||
foo();
|
||||
#pragma omp target parallel map(l) // expected-error 2 {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target parallel map(l)
|
||||
foo();
|
||||
}
|
||||
|
||||
|
|
@ -246,13 +246,13 @@ int main(int argc, char **argv) {
|
|||
foo();
|
||||
#pragma omp target parallel map(l) map(l[:5]) // expected-error 1 {{variable already marked as mapped in current construct}} expected-note 1 {{used here}}
|
||||
foo();
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 2 {{used here}}
|
||||
#pragma omp target data map(k[:4], j, l[:5]) // expected-note 1 {{used here}}
|
||||
{
|
||||
#pragma omp target parallel map(k) // expected-error {{pointer cannot be mapped along with a section derived from itself}}
|
||||
foo();
|
||||
#pragma omp target parallel map(j)
|
||||
foo();
|
||||
#pragma omp target parallel map(l) // expected-error {{original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage}}
|
||||
#pragma omp target parallel map(l)
|
||||
foo();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target parallel reduction(+:ref)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ bool foobool(int argc) {
|
|||
return argc;
|
||||
}
|
||||
|
||||
void foobar(int &ref) {
|
||||
#pragma omp target
|
||||
#pragma omp teams reduction(+:ref)
|
||||
foo();
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
|
||||
extern S1 a;
|
||||
class S2 {
|
||||
|
|
|
|||
|
|
@ -1975,6 +1975,11 @@
|
|||
// ARMEABIHARDFP:#define __arm 1
|
||||
// ARMEABIHARDFP:#define __arm__ 1
|
||||
|
||||
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=armv6-unknown-cloudabi-eabihf < /dev/null | FileCheck -match-full-lines -check-prefix ARMV6-CLOUDABI %s
|
||||
//
|
||||
// ARMV6-CLOUDABI:#define __CloudABI__ 1
|
||||
// ARMV6-CLOUDABI:#define __arm__ 1
|
||||
|
||||
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-netbsd-eabi < /dev/null | FileCheck -match-full-lines -check-prefix ARM-NETBSD %s
|
||||
//
|
||||
// ARM-NETBSD-NOT:#define _LP64
|
||||
|
|
|
|||
|
|
@ -208,3 +208,38 @@ int fn() {
|
|||
t = true;
|
||||
}
|
||||
}
|
||||
|
||||
namespace dependent_classes {
|
||||
template <bool B, typename X, typename Y>
|
||||
struct conditional;
|
||||
|
||||
template <typename X, typename Y>
|
||||
struct conditional<true, X, Y> { typedef X type; };
|
||||
|
||||
template <typename X, typename Y>
|
||||
struct conditional<false, X, Y> { typedef Y type; };
|
||||
|
||||
template<bool B> struct X {
|
||||
X();
|
||||
|
||||
// B == false triggers error for = default.
|
||||
using T = typename conditional<B, const X &, int>::type;
|
||||
X(T) = default; // expected-error {{only special member functions}}
|
||||
|
||||
// Either value of B creates a constructor that can be default
|
||||
using U = typename conditional<B, X&&, const X&>::type;
|
||||
X(U) = default;
|
||||
};
|
||||
|
||||
X<true> x1;
|
||||
X<false> x2; // expected-note {{in instantiation}}
|
||||
|
||||
template <typename Type>
|
||||
class E {
|
||||
explicit E(const int &) = default;
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
E<Type>::E(const int&) {} // expected-error {{definition of explicitly defaulted function}}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,3 +435,21 @@ namespace PR16951 {
|
|||
// expected-error{{no member named 'X2' in 'PR16951::enumerator_2'}}
|
||||
|
||||
}
|
||||
|
||||
namespace PR30619 {
|
||||
c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d;
|
||||
// expected-error@-1 16{{unknown type name 'c'}}
|
||||
c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d;
|
||||
// expected-error@-1 16{{unknown type name 'c'}}
|
||||
c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d;
|
||||
// expected-error@-1 16{{unknown type name 'c'}}
|
||||
c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d; c d;
|
||||
// expected-error@-1 16{{unknown type name 'c'}}
|
||||
namespace A {
|
||||
class B {
|
||||
typedef C D; // expected-error{{unknown type name 'C'}}
|
||||
A::D::F;
|
||||
// expected-error@-1{{'D' (aka 'int') is not a class, namespace, or enumeration}}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang_cc1 -std=c++11 -verify %s
|
||||
// RUN: %clang_cc1 -std=c++1z -verify -pedantic-errors %s
|
||||
|
||||
// Check that we deal with cases where the instantiation of a class template
|
||||
// recursively requires the instantiation of the same template.
|
||||
|
|
@ -47,9 +47,8 @@ namespace test4 {
|
|||
A<int> a; // expected-note {{in instantiation of}}
|
||||
}
|
||||
|
||||
// FIXME: PR12298: Recursive constexpr function template instantiation leads to
|
||||
// PR12298: Recursive constexpr function template instantiation leads to
|
||||
// stack overflow.
|
||||
#if 0
|
||||
namespace test5 {
|
||||
template<typename T> struct A {
|
||||
constexpr T f(T k) { return g(k); }
|
||||
|
|
@ -57,22 +56,20 @@ namespace test5 {
|
|||
return k ? f(k-1)+1 : 0;
|
||||
}
|
||||
};
|
||||
// This should be accepted.
|
||||
constexpr int x = A<int>().f(5);
|
||||
constexpr int x = A<int>().f(5); // ok
|
||||
}
|
||||
|
||||
namespace test6 {
|
||||
template<typename T> constexpr T f(T);
|
||||
template<typename T> constexpr T g(T t) {
|
||||
typedef int arr[f(T())];
|
||||
typedef int arr[f(T())]; // expected-error {{variable length array}}
|
||||
return t;
|
||||
}
|
||||
template<typename T> constexpr T f(T t) {
|
||||
typedef int arr[g(T())];
|
||||
typedef int arr[g(T())]; // expected-error {{zero size array}} expected-note {{instantiation of}}
|
||||
return t;
|
||||
}
|
||||
// This should be ill-formed.
|
||||
int n = f(0);
|
||||
int n = f(0); // expected-note 2{{instantiation of}}
|
||||
}
|
||||
|
||||
namespace test7 {
|
||||
|
|
@ -80,10 +77,94 @@ namespace test7 {
|
|||
return t;
|
||||
}
|
||||
template<typename T> constexpr T f(T t) {
|
||||
typedef int arr[g(T())];
|
||||
typedef int arr[g(T() + 1)];
|
||||
return t;
|
||||
}
|
||||
// This should be accepted.
|
||||
int n = f(0);
|
||||
}
|
||||
|
||||
namespace test8 {
|
||||
template<typename T> struct A {
|
||||
int n = A{}.n; // expected-error {{default member initializer for 'n' uses itself}} expected-note {{instantiation of default member init}}
|
||||
};
|
||||
A<int> ai = {}; // expected-note {{instantiation of default member init}}
|
||||
}
|
||||
|
||||
namespace test9 {
|
||||
template<typename T> struct A { enum class B; };
|
||||
// FIXME: It'd be nice to give the "it has not yet been instantiated" diagnostic here.
|
||||
template<typename T> enum class A<T>::B { k = A<T>::B::k2, k2 = k }; // expected-error {{no member named 'k2'}}
|
||||
auto k = A<int>::B::k; // expected-note {{in instantiation of}}
|
||||
}
|
||||
|
||||
namespace test10 {
|
||||
template<typename T> struct A {
|
||||
void f() noexcept(noexcept(f())); // expected-error {{exception specification of 'f' uses itself}} expected-note {{instantiation of}}
|
||||
};
|
||||
bool b = noexcept(A<int>().f()); // expected-note {{instantiation of}}
|
||||
}
|
||||
|
||||
namespace test11 {
|
||||
template<typename T> const int var = var<T>;
|
||||
int k = var<int>;
|
||||
|
||||
template<typename T> struct X {
|
||||
static const int k = X<T>::k;
|
||||
};
|
||||
template<typename T> const int X<T>::k;
|
||||
int q = X<int>::k;
|
||||
|
||||
template<typename T> struct Y {
|
||||
static const int k;
|
||||
};
|
||||
template<typename T> const int Y<T>::k = Y<T>::k;
|
||||
int r = Y<int>::k;
|
||||
}
|
||||
|
||||
namespace test12 {
|
||||
template<typename T> int f(T t, int = f(T())) {} // expected-error {{recursive evaluation of default argument}} expected-note {{instantiation of}}
|
||||
struct X {};
|
||||
int q = f(X()); // expected-note {{instantiation of}}
|
||||
}
|
||||
|
||||
namespace test13 {
|
||||
struct A {
|
||||
// Cycle via type of non-type template parameter.
|
||||
template<typename T, typename T::template W<T>::type U = 0> struct W { using type = int; };
|
||||
// Cycle via default template argument.
|
||||
template<typename T, typename U = typename T::template X<T>> struct X {};
|
||||
template<typename T, int U = T::template Y<T>::value> struct Y { static const int value = 0; };
|
||||
template<typename T, template<typename> typename U = T::template Z<T>::template nested> struct Z { template<typename> struct nested; };
|
||||
};
|
||||
template<typename T> struct Wrap {
|
||||
template<typename U> struct W : A::W<T> {};
|
||||
template<typename U> struct X : A::X<T> {};
|
||||
template<typename U> struct Y : A::Y<T> {};
|
||||
template<typename U> struct Z : A::Z<T> {};
|
||||
};
|
||||
struct B {
|
||||
template<typename U> struct W { using type = int; };
|
||||
template<typename U> struct X {};
|
||||
template<typename U> struct Y { static const int value = 0; };
|
||||
template<typename U> struct Z { template<typename> struct nested; };
|
||||
};
|
||||
|
||||
A::W<B> awb;
|
||||
A::X<B> axb;
|
||||
A::Y<B> ayb;
|
||||
A::Z<B> azb;
|
||||
|
||||
A::W<Wrap<Wrap<B>>> awwwb;
|
||||
A::X<Wrap<Wrap<B>>> axwwb;
|
||||
A::Y<Wrap<Wrap<B>>> aywwb;
|
||||
A::Z<Wrap<Wrap<B>>> azwwb;
|
||||
|
||||
// FIXME: These tests cause us to use too much stack and crash on a self-hosted debug build.
|
||||
// FIXME: Check for recursion here and give a better diagnostic.
|
||||
#if 0
|
||||
A::W<A> awa;
|
||||
A::X<A> axa;
|
||||
A::Y<A> aya;
|
||||
A::Z<A> aza;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s
|
||||
|
||||
template<typename T> T go(T a) noexcept(noexcept(go(a))); // \
|
||||
// expected-error 16{{call to function 'go' that is neither visible}} \
|
||||
// expected-note 16{{'go' should be declared prior to the call site}} \
|
||||
// expected-error {{recursive template instantiation exceeded maximum depth of 16}}
|
||||
template<int N> struct X {
|
||||
static int go(int a) noexcept(noexcept(X<N+1>::go(a))); // \
|
||||
// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \
|
||||
// expected-note 9{{in instantiation of exception specification}} \
|
||||
// expected-note {{skipping 7 context}} \
|
||||
// expected-note {{use -ftemplate-depth}}
|
||||
};
|
||||
|
||||
void f() {
|
||||
int k = go(0); // \
|
||||
// expected-note {{in instantiation of exception specification for 'go<int>' requested here}}
|
||||
int k = X<0>::go(0); // \
|
||||
// expected-note {{in instantiation of exception specification for 'go' requested here}}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,13 +19,12 @@ void test() {
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s
|
||||
|
||||
template<typename T> struct S {
|
||||
S() noexcept(noexcept(T()));
|
||||
};
|
||||
struct T : S<T> {}; \
|
||||
S() noexcept(noexcept(S<S>())); \
|
||||
// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
|
||||
// expected-note 4 {{in instantiation of exception spec}} \
|
||||
// expected-note 3 {{in instantiation of exception spec}} \
|
||||
// expected-note {{skipping 2 contexts in backtrace}} \
|
||||
// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
|
||||
T t; // expected-note {{implicit default constructor for 'T' first required here}}
|
||||
};
|
||||
S<void> t; // expected-note {{in instantiation of exception spec}}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1243,8 +1243,9 @@ bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
|
|||
bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
|
||||
if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
|
||||
return true;
|
||||
if (Visit(MakeCXCursor(D->getMessage(), StmtParent, TU, RegionOfInterest)))
|
||||
return true;
|
||||
if (StringLiteral *Message = D->getMessage())
|
||||
if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue