Vendor import of clang release_60 branch r325330:

https://llvm.org/svn/llvm-project/cfe/branches/release_60@325330
This commit is contained in:
Dimitry Andric 2018-02-16 19:10:26 +00:00
parent 660d91aa9e
commit 6eea8b8c1a
32 changed files with 412 additions and 124 deletions

View File

@ -132,6 +132,11 @@ New Compiler Flags
difference between the ``-std=c17`` and ``-std=c11`` language modes is the
value of the ``__STDC_VERSION__`` macro, as C17 is a bug fix release.
- Added the ``-fexperimental-isel`` and ``-fno-experimental-isel`` flags to
enable/disable the new GlobalISel instruction selection framework. This
feature is enabled by default for AArch64 at the ``-O0`` optimization level.
Support for other targets or optimization levels is currently incomplete.
Deprecated Compiler Flags
-------------------------

View File

@ -836,6 +836,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
void setLexicalDeclContext(DeclContext *DC);
/// Determine whether this declaration is a templated entity (whether it is
// within the scope of a template parameter).
bool isTemplated() const;
/// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
/// scoped decl is defined outside the current function or method. This is
/// roughly global variables and functions, but also handles enums (which

View File

@ -2145,7 +2145,7 @@ static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,
if (FieldSize != UnionSize)
return false;
}
return true;
return !RD->field_empty();
}
static bool isStructEmpty(QualType Ty) {

View File

@ -236,10 +236,23 @@ TemplateDecl *Decl::getDescribedTemplate() const {
return RD->getDescribedClassTemplate();
else if (auto *VD = dyn_cast<VarDecl>(this))
return VD->getDescribedVarTemplate();
else if (auto *AD = dyn_cast<TypeAliasDecl>(this))
return AD->getDescribedAliasTemplate();
return nullptr;
}
bool Decl::isTemplated() const {
// A declaration is dependent if it is a template or a template pattern, or
// is within (lexcially for a friend, semantically otherwise) a dependent
// context.
// FIXME: Should local extern declarations be treated like friends?
if (auto *AsDC = dyn_cast<DeclContext>(this))
return AsDC->isDependentContext();
auto *DC = getFriendObjectKind() ? getLexicalDeclContext() : getDeclContext();
return DC->isDependentContext() || isTemplateDecl() || getDescribedTemplate();
}
const DeclContext *Decl::getParentFunctionOrMethod() const {
for (const DeclContext *DC = getDeclContext();
DC && !DC->isTranslationUnit() && !DC->isNamespace();

View File

@ -950,11 +950,10 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
}
// <postfix> ::= <unqualified-name> [<postfix>]
// ::= <substitution> [<postfix>]
void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
// <postfix> ::= <unqualified-name> [<postfix>]
// ::= <substitution> [<postfix>]
const DeclContext *DC = getEffectiveDeclContext(ND);
while (!DC->isTranslationUnit()) {
if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
unsigned Disc;
@ -2140,6 +2139,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
case CC_X86StdCall: Out << 'G'; break;
case CC_X86FastCall: Out << 'I'; break;
case CC_X86VectorCall: Out << 'Q'; break;
case CC_Swift: Out << 'S'; break;
case CC_X86RegCall: Out << 'w'; break;
}
}

View File

@ -4000,18 +4000,13 @@ void CodeGenModule::EmitDeclContext(const DeclContext *DC) {
/// EmitTopLevelDecl - Emit code for a single top level declaration.
void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// Ignore dependent declarations.
if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
if (D->isTemplated())
return;
switch (D->getKind()) {
case Decl::CXXConversion:
case Decl::CXXMethod:
case Decl::Function:
// Skip function templates
if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() ||
cast<FunctionDecl>(D)->isLateTemplateParsed())
return;
EmitGlobal(cast<FunctionDecl>(D));
// Always provide some coverage mapping
// even for the functions that aren't emitted.
@ -4024,10 +4019,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::Var:
case Decl::Decomposition:
// Skip variable templates
if (cast<VarDecl>(D)->getDescribedVarTemplate())
return;
LLVM_FALLTHROUGH;
case Decl::VarTemplateSpecialization:
EmitGlobal(cast<VarDecl>(D));
if (auto *DD = dyn_cast<DecompositionDecl>(D))
@ -4086,16 +4077,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
DI->EmitUsingDirective(cast<UsingDirectiveDecl>(*D));
return;
case Decl::CXXConstructor:
// Skip function templates
if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate() ||
cast<FunctionDecl>(D)->isLateTemplateParsed())
return;
getCXXABI().EmitCXXConstructors(cast<CXXConstructorDecl>(D));
break;
case Decl::CXXDestructor:
if (cast<FunctionDecl>(D)->isLateTemplateParsed())
return;
getCXXABI().EmitCXXDestructors(cast<CXXDestructorDecl>(D));
break;

View File

@ -2761,6 +2761,11 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
// N.B. We must always emit the RTTI data ourselves if there exists a key
// function.
bool IsDLLImport = RD->hasAttr<DLLImportAttr>();
// Don't import the RTTI but emit it locally.
if (CGM.getTriple().isWindowsGNUEnvironment() && IsDLLImport)
return false;
if (CGM.getVTables().isVTableExternal(RD))
return IsDLLImport && !CGM.getTriple().isWindowsItaniumEnvironment()
? false

View File

@ -3543,7 +3543,17 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructType(QualType Ty,
void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
const unsigned CallingConv = FI.getCallingConvention();
// It is possible to force Win64 calling convention on any x86_64 target by
// using __attribute__((ms_abi)). In such case to correctly emit Win64
// compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
if (CallingConv == llvm::CallingConv::Win64) {
WinX86_64ABIInfo Win64ABIInfo(CGT);
Win64ABIInfo.computeInfo(FI);
return;
}
bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
// Keep track of the number of assigned registers.
unsigned FreeIntRegs = IsRegCall ? 11 : 6;

View File

@ -1723,15 +1723,18 @@ void TokenAnnotator::setCommentLineLevels(
}
}
if (NextNonCommentLine && CommentLine) {
// If the comment is currently aligned with the line immediately following
// it, that's probably intentional and we should keep it.
bool AlignedWithNextLine =
NextNonCommentLine->First->NewlinesBefore <= 1 &&
NextNonCommentLine->First->OriginalColumn ==
(*I)->First->OriginalColumn;
if (AlignedWithNextLine)
(*I)->Level = NextNonCommentLine->Level;
// If the comment is currently aligned with the line immediately following
// it, that's probably intentional and we should keep it.
if (NextNonCommentLine && CommentLine &&
NextNonCommentLine->First->NewlinesBefore <= 1 &&
NextNonCommentLine->First->OriginalColumn ==
(*I)->First->OriginalColumn) {
// Align comments for preprocessor lines with the # in column 0.
// Otherwise, align with the next line.
(*I)->Level = (NextNonCommentLine->Type == LT_PreprocessorDirective ||
NextNonCommentLine->Type == LT_ImportStatement)
? 0
: NextNonCommentLine->Level;
} else {
NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
}

View File

@ -234,14 +234,17 @@ UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
CurrentLines(&Lines), Style(Style), Keywords(Keywords),
CommentPragmasRegex(Style.CommentPragmas), Tokens(nullptr),
Callback(Callback), AllTokens(Tokens), PPBranchLevel(-1),
IfNdefCondition(nullptr), FoundIncludeGuardStart(false),
IncludeGuardRejected(false), FirstStartColumn(FirstStartColumn) {}
IncludeGuard(Style.IndentPPDirectives == FormatStyle::PPDIS_None
? IG_Rejected
: IG_Inited),
IncludeGuardToken(nullptr), FirstStartColumn(FirstStartColumn) {}
void UnwrappedLineParser::reset() {
PPBranchLevel = -1;
IfNdefCondition = nullptr;
FoundIncludeGuardStart = false;
IncludeGuardRejected = false;
IncludeGuard = Style.IndentPPDirectives == FormatStyle::PPDIS_None
? IG_Rejected
: IG_Inited;
IncludeGuardToken = nullptr;
Line.reset(new UnwrappedLine);
CommentsBeforeNextToken.clear();
FormatTok = nullptr;
@ -264,6 +267,14 @@ void UnwrappedLineParser::parse() {
readToken();
parseFile();
// If we found an include guard then all preprocessor directives (other than
// the guard) are over-indented by one.
if (IncludeGuard == IG_Found)
for (auto &Line : Lines)
if (Line.InPPDirective && Line.Level > 0)
--Line.Level;
// Create line with eof token.
pushToken(FormatTok);
addUnwrappedLine();
@ -712,26 +723,27 @@ void UnwrappedLineParser::parsePPIf(bool IfDef) {
// If there's a #ifndef on the first line, and the only lines before it are
// comments, it could be an include guard.
bool MaybeIncludeGuard = IfNDef;
if (!IncludeGuardRejected && !FoundIncludeGuardStart && MaybeIncludeGuard) {
if (IncludeGuard == IG_Inited && MaybeIncludeGuard)
for (auto &Line : Lines) {
if (!Line.Tokens.front().Tok->is(tok::comment)) {
MaybeIncludeGuard = false;
IncludeGuardRejected = true;
IncludeGuard = IG_Rejected;
break;
}
}
}
--PPBranchLevel;
parsePPUnknown();
++PPBranchLevel;
if (!IncludeGuardRejected && !FoundIncludeGuardStart && MaybeIncludeGuard)
IfNdefCondition = IfCondition;
if (IncludeGuard == IG_Inited && MaybeIncludeGuard) {
IncludeGuard = IG_IfNdefed;
IncludeGuardToken = IfCondition;
}
}
void UnwrappedLineParser::parsePPElse() {
// If a potential include guard has an #else, it's not an include guard.
if (FoundIncludeGuardStart && PPBranchLevel == 0)
FoundIncludeGuardStart = false;
if (IncludeGuard == IG_Defined && PPBranchLevel == 0)
IncludeGuard = IG_Rejected;
conditionalCompilationAlternative();
if (PPBranchLevel > -1)
--PPBranchLevel;
@ -745,34 +757,37 @@ void UnwrappedLineParser::parsePPEndIf() {
conditionalCompilationEnd();
parsePPUnknown();
// If the #endif of a potential include guard is the last thing in the file,
// then we count it as a real include guard and subtract one from every
// preprocessor indent.
// then we found an include guard.
unsigned TokenPosition = Tokens->getPosition();
FormatToken *PeekNext = AllTokens[TokenPosition];
if (FoundIncludeGuardStart && PPBranchLevel == -1 && PeekNext->is(tok::eof) &&
if (IncludeGuard == IG_Defined && PPBranchLevel == -1 &&
PeekNext->is(tok::eof) &&
Style.IndentPPDirectives != FormatStyle::PPDIS_None)
for (auto &Line : Lines)
if (Line.InPPDirective && Line.Level > 0)
--Line.Level;
IncludeGuard = IG_Found;
}
void UnwrappedLineParser::parsePPDefine() {
nextToken();
if (FormatTok->Tok.getKind() != tok::identifier) {
IncludeGuard = IG_Rejected;
IncludeGuardToken = nullptr;
parsePPUnknown();
return;
}
if (IfNdefCondition && IfNdefCondition->TokenText == FormatTok->TokenText) {
FoundIncludeGuardStart = true;
if (IncludeGuard == IG_IfNdefed &&
IncludeGuardToken->TokenText == FormatTok->TokenText) {
IncludeGuard = IG_Defined;
IncludeGuardToken = nullptr;
for (auto &Line : Lines) {
if (!Line.Tokens.front().Tok->isOneOf(tok::comment, tok::hash)) {
FoundIncludeGuardStart = false;
IncludeGuard = IG_Rejected;
break;
}
}
}
IfNdefCondition = nullptr;
nextToken();
if (FormatTok->Tok.getKind() == tok::l_paren &&
FormatTok->WhitespaceRange.getBegin() ==
@ -799,7 +814,6 @@ void UnwrappedLineParser::parsePPUnknown() {
if (Style.IndentPPDirectives == FormatStyle::PPDIS_AfterHash)
Line->Level += PPBranchLevel + 1;
addUnwrappedLine();
IfNdefCondition = nullptr;
}
// Here we blacklist certain tokens that are not usually the first token in an

View File

@ -248,10 +248,23 @@ class UnwrappedLineParser {
// sequence.
std::stack<int> PPChainBranchIndex;
// Contains the #ifndef condition for a potential include guard.
FormatToken *IfNdefCondition;
bool FoundIncludeGuardStart;
bool IncludeGuardRejected;
// Include guard search state. Used to fixup preprocessor indent levels
// so that include guards do not participate in indentation.
enum IncludeGuardState {
IG_Inited, // Search started, looking for #ifndef.
IG_IfNdefed, // #ifndef found, IncludeGuardToken points to condition.
IG_Defined, // Matching #define found, checking other requirements.
IG_Found, // All requirements met, need to fix indents.
IG_Rejected, // Search failed or never started.
};
// Current state of include guard search.
IncludeGuardState IncludeGuard;
// Points to the #ifndef condition for a potential include guard. Null unless
// IncludeGuardState == IG_IfNdefed.
FormatToken *IncludeGuardToken;
// Contains the first start column where the source begins. This is zero for
// normal source code and may be nonzero when formatting a code fragment that
// does not start at the beginning of the file.

View File

@ -1854,13 +1854,15 @@ _mm512_maskz_set1_epi8 (__mmask64 __M, char __A)
static __inline__ __mmask64 __DEFAULT_FN_ATTRS
_mm512_kunpackd (__mmask64 __A, __mmask64 __B)
{
return (__mmask64) (( __A & 0xFFFFFFFF) | ( __B << 32));
return (__mmask64) __builtin_ia32_kunpckdi ((__mmask64) __A,
(__mmask64) __B);
}
static __inline__ __mmask32 __DEFAULT_FN_ATTRS
_mm512_kunpackw (__mmask32 __A, __mmask32 __B)
{
return (__mmask32) (( __A & 0xFFFF) | ( __B << 16));
return (__mmask32) __builtin_ia32_kunpcksi ((__mmask32) __A,
(__mmask32) __B);
}
static __inline__ __m512i __DEFAULT_FN_ATTRS

View File

@ -8787,7 +8787,7 @@ _mm512_kortestz (__mmask16 __A, __mmask16 __B)
static __inline__ __mmask16 __DEFAULT_FN_ATTRS
_mm512_kunpackb (__mmask16 __A, __mmask16 __B)
{
return (__mmask16) (( __A & 0xFF) | ( __B << 8));
return (__mmask16) __builtin_ia32_kunpckhi ((__mmask16) __A, (__mmask16) __B);
}
static __inline__ __mmask16 __DEFAULT_FN_ATTRS

View File

@ -738,15 +738,17 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){
s++;
radix = 10;
saw_exponent = true;
if (*s == '+' || *s == '-') s++; // sign
if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign
const char *first_non_digit = SkipDigits(s);
if (containsDigits(s, first_non_digit)) {
checkSeparator(TokLoc, s, CSK_BeforeDigits);
s = first_non_digit;
} else {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
diag::err_exponent_has_no_digits);
hadError = true;
if (!hadError) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
diag::err_exponent_has_no_digits);
hadError = true;
}
return;
}
}
@ -787,10 +789,12 @@ void NumericLiteralParser::checkSeparator(SourceLocation TokLoc,
} else if (Pos == ThisTokEnd)
return;
if (isDigitSeparator(*Pos))
if (isDigitSeparator(*Pos)) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin),
diag::err_digit_separator_not_between_digits)
<< IsAfterDigits;
hadError = true;
}
}
/// ParseNumberStartingWithZero - This method is called when the first character
@ -840,12 +844,14 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
const char *Exponent = s;
s++;
saw_exponent = true;
if (*s == '+' || *s == '-') s++; // sign
if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign
const char *first_non_digit = SkipDigits(s);
if (!containsDigits(s, first_non_digit)) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
diag::err_exponent_has_no_digits);
hadError = true;
if (!hadError) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
diag::err_exponent_has_no_digits);
hadError = true;
}
return;
}
checkSeparator(TokLoc, s, CSK_BeforeDigits);

View File

@ -8972,6 +8972,16 @@ static void AnalyzeComparison(Sema &S, BinaryOperator *E) {
LHS = LHS->IgnoreParenImpCasts();
RHS = RHS->IgnoreParenImpCasts();
if (!S.getLangOpts().CPlusPlus) {
// Avoid warning about comparison of integers with different signs when
// RHS/LHS has a `typeof(E)` type whose sign is different from the sign of
// the type of `E`.
if (const auto *TET = dyn_cast<TypeOfExprType>(LHS->getType()))
LHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts();
if (const auto *TET = dyn_cast<TypeOfExprType>(RHS->getType()))
RHS = TET->getUnderlyingExpr()->IgnoreParenImpCasts();
}
// Check to see if one of the (unmodified) operands is of different
// signedness.
Expr *signedOperand, *unsignedOperand;

View File

@ -12507,10 +12507,20 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D,
/// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
IdentifierInfo &II, Scope *S) {
// Find the scope in which the identifier is injected and the corresponding
// DeclContext.
// FIXME: C89 does not say what happens if there is no enclosing block scope.
// In that case, we inject the declaration into the translation unit scope
// instead.
Scope *BlockScope = S;
while (!BlockScope->isCompoundStmtScope() && BlockScope->getParent())
BlockScope = BlockScope->getParent();
Scope *ContextScope = BlockScope;
while (!ContextScope->getEntity())
ContextScope = ContextScope->getParent();
ContextRAII SavedContext(*this, ContextScope->getEntity());
// Before we produce a declaration for an implicitly defined
// function, see whether there was a locally-scoped declaration of
// this name as a function or variable. If so, use that

View File

@ -352,6 +352,7 @@ class InitListChecker {
bool FillWithNoInit = false);
void FillInEmptyInitializations(const InitializedEntity &Entity,
InitListExpr *ILE, bool &RequiresSecondPass,
InitListExpr *OuterILE, unsigned OuterIndex,
bool FillWithNoInit = false);
bool CheckFlexibleArrayInit(const InitializedEntity &Entity,
Expr *InitExpr, FieldDecl *Field,
@ -517,12 +518,13 @@ void InitListChecker::FillInEmptyInitForBase(
ILE->setInit(Init, BaseInit.getAs<Expr>());
} else if (InitListExpr *InnerILE =
dyn_cast<InitListExpr>(ILE->getInit(Init))) {
FillInEmptyInitializations(BaseEntity, InnerILE,
RequiresSecondPass, FillWithNoInit);
FillInEmptyInitializations(BaseEntity, InnerILE, RequiresSecondPass,
ILE, Init, FillWithNoInit);
} else if (DesignatedInitUpdateExpr *InnerDIUE =
dyn_cast<DesignatedInitUpdateExpr>(ILE->getInit(Init))) {
FillInEmptyInitializations(BaseEntity, InnerDIUE->getUpdater(),
RequiresSecondPass, /*FillWithNoInit =*/true);
RequiresSecondPass, ILE, Init,
/*FillWithNoInit =*/true);
}
}
@ -605,24 +607,43 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
} else if (InitListExpr *InnerILE
= dyn_cast<InitListExpr>(ILE->getInit(Init)))
FillInEmptyInitializations(MemberEntity, InnerILE,
RequiresSecondPass, FillWithNoInit);
RequiresSecondPass, ILE, Init, FillWithNoInit);
else if (DesignatedInitUpdateExpr *InnerDIUE
= dyn_cast<DesignatedInitUpdateExpr>(ILE->getInit(Init)))
FillInEmptyInitializations(MemberEntity, InnerDIUE->getUpdater(),
RequiresSecondPass, /*FillWithNoInit =*/ true);
RequiresSecondPass, ILE, Init,
/*FillWithNoInit =*/true);
}
/// Recursively replaces NULL values within the given initializer list
/// with expressions that perform value-initialization of the
/// appropriate type.
/// appropriate type, and finish off the InitListExpr formation.
void
InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
InitListExpr *ILE,
bool &RequiresSecondPass,
InitListExpr *OuterILE,
unsigned OuterIndex,
bool FillWithNoInit) {
assert((ILE->getType() != SemaRef.Context.VoidTy) &&
"Should not have void type");
// If this is a nested initializer list, we might have changed its contents
// (and therefore some of its properties, such as instantiation-dependence)
// while filling it in. Inform the outer initializer list so that its state
// can be updated to match.
// FIXME: We should fully build the inner initializers before constructing
// the outer InitListExpr instead of mutating AST nodes after they have
// been used as subexpressions of other nodes.
struct UpdateOuterILEWithUpdatedInit {
InitListExpr *Outer;
unsigned OuterIndex;
~UpdateOuterILEWithUpdatedInit() {
if (Outer)
Outer->setInit(OuterIndex, Outer->getInit(OuterIndex));
}
} UpdateOuterRAII = {OuterILE, OuterIndex};
// A transparent ILE is not performing aggregate initialization and should
// not be filled in.
if (ILE->isTransparent())
@ -769,11 +790,12 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
} else if (InitListExpr *InnerILE
= dyn_cast_or_null<InitListExpr>(InitExpr))
FillInEmptyInitializations(ElementEntity, InnerILE, RequiresSecondPass,
FillWithNoInit);
ILE, Init, FillWithNoInit);
else if (DesignatedInitUpdateExpr *InnerDIUE
= dyn_cast_or_null<DesignatedInitUpdateExpr>(InitExpr))
FillInEmptyInitializations(ElementEntity, InnerDIUE->getUpdater(),
RequiresSecondPass, /*FillWithNoInit =*/ true);
RequiresSecondPass, ILE, Init,
/*FillWithNoInit =*/true);
}
}
@ -795,10 +817,11 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
if (!hadError && !VerifyOnly) {
bool RequiresSecondPass = false;
FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass);
FillInEmptyInitializations(Entity, FullyStructuredList, RequiresSecondPass,
/*OuterILE=*/nullptr, /*OuterIndex=*/0);
if (RequiresSecondPass && !hadError)
FillInEmptyInitializations(Entity, FullyStructuredList,
RequiresSecondPass);
RequiresSecondPass, nullptr, 0);
}
}
@ -1162,10 +1185,12 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
if (!hadError && !VerifyOnly) {
bool RequiresSecondPass = false;
FillInEmptyInitializations(Entity, InnerStructuredList,
RequiresSecondPass);
RequiresSecondPass, StructuredList,
StructuredIndex);
if (RequiresSecondPass && !hadError)
FillInEmptyInitializations(Entity, InnerStructuredList,
RequiresSecondPass);
RequiresSecondPass, StructuredList,
StructuredIndex);
}
++StructuredIndex;
++Index;

View File

@ -1626,26 +1626,16 @@ __m512i test_mm512_maskz_set1_epi8(__mmask64 __M, char __A) {
return _mm512_maskz_set1_epi8(__M, __A);
}
__mmask64 test_mm512_kunpackd(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
__mmask64 test_mm512_kunpackd(__mmask64 __A, __mmask64 __B) {
// CHECK-LABEL: @test_mm512_kunpackd
// CHECK: bitcast <64 x i1> %{{.*}} to i64
// CHECK: bitcast <64 x i1> %{{.*}} to i64
// CHECK: and i64 %{{.*}}, 4294967295
// CHECK: shl i64 %{{.*}}, 32
// CHECK: or i64 %{{.*}}, %{{.*}}
// CHECK: bitcast i64 %{{.*}} to <64 x i1>
return _mm512_mask_cmpneq_epu8_mask(_mm512_kunpackd(_mm512_cmpneq_epu8_mask(__B, __A),_mm512_cmpneq_epu8_mask(__C, __D)), __E, __F);
// CHECK: @llvm.x86.avx512.kunpck.dq
return _mm512_kunpackd(__A, __B);
}
__mmask32 test_mm512_kunpackw(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
__mmask32 test_mm512_kunpackw(__mmask32 __A, __mmask32 __B) {
// CHECK-LABEL: @test_mm512_kunpackw
// CHECK: bitcast <32 x i1> %{{.*}} to i32
// CHECK: bitcast <32 x i1> %{{.*}} to i32
// CHECK: and i32 %{{.*}}, 65535
// CHECK: shl i32 %{{.*}}, 16
// CHECK: or i32 %{{.*}}, %{{.*}}
// CHECK: bitcast i32 %{{.*}} to <32 x i1>
return _mm512_mask_cmpneq_epu16_mask(_mm512_kunpackw(_mm512_cmpneq_epu16_mask(__B, __A),_mm512_cmpneq_epu16_mask(__C, __D)), __E, __F);
// CHECK: @llvm.x86.avx512.kunpck.wd
return _mm512_kunpackw(__A, __B);
}
__m512i test_mm512_mask_loadu_epi16(__m512i __W, __mmask32 __U, void const *__P) {

View File

@ -6259,17 +6259,10 @@ int test_mm512_kortestz(__mmask16 __A, __mmask16 __B) {
return _mm512_kortestz(__A, __B);
}
__mmask16 test_mm512_kunpackb(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {
__mmask16 test_mm512_kunpackb(__mmask16 __A, __mmask16 __B) {
// CHECK-LABEL: @test_mm512_kunpackb
// CHECK: bitcast <16 x i1> %{{.*}} to i16
// CHECK: bitcast <16 x i1> %{{.*}} to i16
// CHECK: and i32 %{{.*}}, 255
// CHECK: shl i32 %{{.*}}, 8
// CHECK: or i32 %{{.*}}, %{{.*}}
// CHECK: bitcast i16 %{{.*}} to <16 x i1>
return _mm512_mask_cmpneq_epu32_mask(_mm512_kunpackb(_mm512_cmpneq_epu32_mask(__A, __B),
_mm512_cmpneq_epu32_mask(__C, __D)),
__E, __F);
// CHECK: @llvm.x86.avx512.kunpck.bw
return _mm512_kunpackb(__A, __B);
}
__mmask16 test_mm512_kxnor(__m512i __A, __m512i __B, __m512i __C, __m512i __D, __m512i __E, __m512i __F) {

View File

@ -146,3 +146,16 @@ void __attribute__((sysv_abi)) f6(__builtin_ms_va_list ap) {
// WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
// WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
}
// This test checks if structs are passed according to Win64 calling convention
// when it's enforced by __attribute((ms_abi)).
struct i128 {
unsigned long long a;
unsigned long long b;
};
__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
// WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
// FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
return a;
}

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU %s
class __declspec(dllimport) QObjectData {
public:
virtual ~QObjectData() = 0;
void *ptr;
int method() const;
};
class LocalClass : public QObjectData {
};
void call() {
(new LocalClass())->method();
}
// GNU-DAG: @_ZTV11QObjectData = available_externally dllimport
// GNU-DAG: @_ZTS11QObjectData = linkonce_odr
// GNU-DAG: @_ZTI11QObjectData = linkonce_odr

View File

@ -12,7 +12,7 @@ struct __declspec(dllimport) S {
// MSVC-DAG: @"\01??_R3S@@8" = linkonce_odr
// GNU-DAG: @_ZTV1S = available_externally dllimport
// GNU-DAG: @_ZTI1S = external dllimport
// GNU-DAG: @_ZTI1S = linkonce_odr
struct U : S {
} u;

View File

@ -0,0 +1,11 @@
// RUN: %clang_cc1 -emit-llvm-only -fmodules -triple x86_64-windows %s
// PR36181
#pragma clang module build foo
module foo {}
#pragma clang module contents
template <typename T> struct A {
friend void f(A<T>) {}
};
#pragma clang module endbuild
#pragma clang module import foo
void g() { f(A<int>()); }

View File

@ -0,0 +1,28 @@
// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fdeclspec -emit-llvm %s -o - | FileCheck %s
void __attribute__((__swiftcall__)) f() {}
// CHECK-DAG: @"\01?f@@YSXXZ"
void (__attribute__((__swiftcall__)) *p)();
// CHECK-DAG: @"\01?p@@3P6SXXZA"
namespace {
void __attribute__((__swiftcall__)) __attribute__((__used__)) f() { }
// CHECK-DAG: "\01?f@?A@@YSXXZ"
}
namespace n {
void __attribute__((__swiftcall__)) f() {}
// CHECK-DAG: "\01?f@n@@YSXXZ"
}
struct __declspec(dllexport) S {
S(const S &) = delete;
S & operator=(const S &) = delete;
void __attribute__((__swiftcall__)) m() { }
// CHECK-DAG: "\01?m@S@@QASXXZ"
};
void f(void (__attribute__((__swiftcall__))())) {}
// CHECK-DAG: "\01?f@@YAXP6SXXZ@Z"

View File

@ -51,6 +51,8 @@ namespace floating {
float u = 0x.'p1f; // expected-error {{hexadecimal floating literal requires a significand}}
float v = 0e'f; // expected-error {{exponent has no digits}}
float w = 0x0p'f; // expected-error {{exponent has no digits}}
float x = 0'e+1; // expected-error {{digit separator cannot appear at end of digit sequence}}
float y = 0x0'p+1; // expected-error {{digit separator cannot appear at end of digit sequence}}
}
#line 123'456

View File

@ -82,3 +82,7 @@ typedef __typeof__(+(t5.n--)) Unsigned; // also act like compound-assignment.
struct Test6 {
: 0.0; // expected-error{{type name requires a specifier or qualifier}}
};
struct PR36157 {
int n : 1 ? 1 : implicitly_declare_function(); // expected-warning {{invalid in C99}}
};

View File

@ -391,3 +391,16 @@ typedef char two_chars[2];
void test12(unsigned a) {
if (0 && -1 > a) { }
}
// PR36008
enum PR36008EnumTest {
kPR36008Value = 0,
};
void pr36008(enum PR36008EnumTest lhs) {
__typeof__(lhs) x = lhs;
__typeof__(kPR36008Value) y = (kPR36008Value);
if (x == y) x = y; // no warning
if (y == x) y = x; // no warning
}

9
test/Sema/cxx-as-c.c Normal file
View File

@ -0,0 +1,9 @@
// RUN: %clang_cc1 %s -verify
// PR36157
struct Foo {
Foo(int n) : n_(n) {} // expected-error 1+{{}} expected-warning 1+{{}}
private:
int n;
};
int main() { Foo f; } // expected-error 1+{{}}

View File

@ -29,3 +29,11 @@ template <class T> struct B {
return 0;
}
};
// This test checks for a crash that resulted from us miscomputing the
// dependence of a nested initializer list.
template<int> struct X {
static constexpr int n = 4;
static constexpr int a[1][1] = {n};
};

View File

@ -2524,6 +2524,7 @@ static_assert(!has_unique_object_representations<const int &>::value, "No refere
static_assert(!has_unique_object_representations<volatile int &>::value, "No references!");
static_assert(!has_unique_object_representations<const volatile int &>::value, "No references!");
static_assert(!has_unique_object_representations<Empty>::value, "No empty types!");
static_assert(!has_unique_object_representations<EmptyUnion>::value, "No empty types!");
class Compressed : Empty {
int x;

View File

@ -142,3 +142,17 @@ namespace ReturnStmtIsInitialization {
template<typename T> X f() { return {}; }
auto &&x = f<void>();
}
namespace InitListUpdate {
struct A { int n; };
using AA = A[1];
// Check that an init list update doesn't "lose" the pack-ness of an expression.
template <int... N> void f() {
g(AA{0, [0].n = N} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}}
g(AA{N, [0].n = 0} ...); // expected-warning 3{{overrides prior init}} expected-note 3{{previous init}}
};
void g(AA, AA);
void h() { f<1, 2>(); } // expected-note {{instantiation of}}
}

View File

@ -2532,6 +2532,20 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) {
"#elif FOO\n"
"#endif",
Style);
// Non-identifier #define after potential include guard.
verifyFormat("#ifndef FOO\n"
"# define 1\n"
"#endif\n",
Style);
// #if closes past last non-preprocessor line.
verifyFormat("#ifndef FOO\n"
"#define FOO\n"
"#if 1\n"
"int i;\n"
"# define A 0\n"
"#endif\n"
"#endif\n",
Style);
// FIXME: This doesn't handle the case where there's code between the
// #ifndef and #define but all other conditions hold. This is because when
// the #define line is parsed, UnwrappedLineParser::Lines doesn't hold the
@ -2580,21 +2594,85 @@ TEST_F(FormatTest, IndentPreprocessorDirectives) {
"code();\n"
"#endif",
Style));
// FIXME: The comment indent corrector in TokenAnnotator gets thrown off by
// preprocessor indentation.
EXPECT_EQ("#if 1\n"
" // comment\n"
"# define A 0\n"
"// comment\n"
"# define B 0\n"
"#endif",
format("#if 1\n"
"// comment\n"
"# define A 0\n"
" // comment\n"
"# define B 0\n"
"#endif",
Style));
// Keep comments aligned with #, otherwise indent comments normally. These
// tests cannot use verifyFormat because messUp manipulates leading
// whitespace.
{
const char *Expected = ""
"void f() {\n"
"#if 1\n"
"// Preprocessor aligned.\n"
"# define A 0\n"
" // Code. Separated by blank line.\n"
"\n"
"# define B 0\n"
" // Code. Not aligned with #\n"
"# define C 0\n"
"#endif";
const char *ToFormat = ""
"void f() {\n"
"#if 1\n"
"// Preprocessor aligned.\n"
"# define A 0\n"
"// Code. Separated by blank line.\n"
"\n"
"# define B 0\n"
" // Code. Not aligned with #\n"
"# define C 0\n"
"#endif";
EXPECT_EQ(Expected, format(ToFormat, Style));
EXPECT_EQ(Expected, format(Expected, Style));
}
// Keep block quotes aligned.
{
const char *Expected = ""
"void f() {\n"
"#if 1\n"
"/* Preprocessor aligned. */\n"
"# define A 0\n"
" /* Code. Separated by blank line. */\n"
"\n"
"# define B 0\n"
" /* Code. Not aligned with # */\n"
"# define C 0\n"
"#endif";
const char *ToFormat = ""
"void f() {\n"
"#if 1\n"
"/* Preprocessor aligned. */\n"
"# define A 0\n"
"/* Code. Separated by blank line. */\n"
"\n"
"# define B 0\n"
" /* Code. Not aligned with # */\n"
"# define C 0\n"
"#endif";
EXPECT_EQ(Expected, format(ToFormat, Style));
EXPECT_EQ(Expected, format(Expected, Style));
}
// Keep comments aligned with un-indented directives.
{
const char *Expected = ""
"void f() {\n"
"// Preprocessor aligned.\n"
"#define A 0\n"
" // Code. Separated by blank line.\n"
"\n"
"#define B 0\n"
" // Code. Not aligned with #\n"
"#define C 0\n";
const char *ToFormat = ""
"void f() {\n"
"// Preprocessor aligned.\n"
"#define A 0\n"
"// Code. Separated by blank line.\n"
"\n"
"#define B 0\n"
" // Code. Not aligned with #\n"
"#define C 0\n";
EXPECT_EQ(Expected, format(ToFormat, Style));
EXPECT_EQ(Expected, format(Expected, Style));
}
// Test with tabs.
Style.UseTab = FormatStyle::UT_Always;
Style.IndentWidth = 8;