Date: Fri, 16 Feb 2018 19:10:27 +0000 (UTC) From: Dimitry Andric <dim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r329396 - in vendor/clang/dist-release_60: docs include/clang/AST lib/AST lib/CodeGen lib/Format lib/Headers lib/Lex lib/Sema test/CodeGen test/CodeGenCXX test/Lexer test/Sema test/Sema... Message-ID: <201802161910.w1GJARPf069006@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dim Date: Fri Feb 16 19:10:26 2018 New Revision: 329396 URL: https://svnweb.freebsd.org/changeset/base/329396 Log: Vendor import of clang release_60 branch r325330: https://llvm.org/svn/llvm-project/cfe/branches/release_60@325330 Added: vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-missing-key.cpp (contents, props changed) vendor/clang/dist-release_60/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp (contents, props changed) vendor/clang/dist-release_60/test/CodeGenCXX/msabi-swiftcall-cc.cpp (contents, props changed) vendor/clang/dist-release_60/test/Sema/cxx-as-c.c (contents, props changed) Modified: vendor/clang/dist-release_60/docs/ReleaseNotes.rst vendor/clang/dist-release_60/include/clang/AST/DeclBase.h vendor/clang/dist-release_60/lib/AST/ASTContext.cpp vendor/clang/dist-release_60/lib/AST/DeclBase.cpp vendor/clang/dist-release_60/lib/AST/MicrosoftMangle.cpp vendor/clang/dist-release_60/lib/CodeGen/CodeGenModule.cpp vendor/clang/dist-release_60/lib/CodeGen/ItaniumCXXABI.cpp vendor/clang/dist-release_60/lib/CodeGen/TargetInfo.cpp vendor/clang/dist-release_60/lib/Format/TokenAnnotator.cpp vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.cpp vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.h vendor/clang/dist-release_60/lib/Headers/avx512bwintrin.h vendor/clang/dist-release_60/lib/Headers/avx512fintrin.h vendor/clang/dist-release_60/lib/Lex/LiteralSupport.cpp vendor/clang/dist-release_60/lib/Sema/SemaChecking.cpp vendor/clang/dist-release_60/lib/Sema/SemaDecl.cpp vendor/clang/dist-release_60/lib/Sema/SemaInit.cpp vendor/clang/dist-release_60/test/CodeGen/avx512bw-builtins.c vendor/clang/dist-release_60/test/CodeGen/avx512f-builtins.c vendor/clang/dist-release_60/test/CodeGen/ms_abi.c vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-rtti.cpp vendor/clang/dist-release_60/test/Lexer/cxx1y_digit_separators.cpp vendor/clang/dist-release_60/test/Sema/bitfield.c vendor/clang/dist-release_60/test/Sema/compare.c vendor/clang/dist-release_60/test/SemaCXX/init-expr-crash.cpp vendor/clang/dist-release_60/test/SemaCXX/type-traits.cpp vendor/clang/dist-release_60/test/SemaTemplate/instantiate-init.cpp vendor/clang/dist-release_60/unittests/Format/FormatTest.cpp Modified: vendor/clang/dist-release_60/docs/ReleaseNotes.rst ============================================================================== --- vendor/clang/dist-release_60/docs/ReleaseNotes.rst Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/docs/ReleaseNotes.rst Fri Feb 16 19:10:26 2018 (r329396) @@ -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 ------------------------- Modified: vendor/clang/dist-release_60/include/clang/AST/DeclBase.h ============================================================================== --- vendor/clang/dist-release_60/include/clang/AST/DeclBase.h Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/include/clang/AST/DeclBase.h Fri Feb 16 19:10:26 2018 (r329396) @@ -836,6 +836,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl { (pu 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 Modified: vendor/clang/dist-release_60/lib/AST/ASTContext.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/AST/ASTContext.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/AST/ASTContext.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -2145,7 +2145,7 @@ static bool unionHasUniqueObjectRepresentations(const if (FieldSize != UnionSize) return false; } - return true; + return !RD->field_empty(); } static bool isStructEmpty(QualType Ty) { Modified: vendor/clang/dist-release_60/lib/AST/DeclBase.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/AST/DeclBase.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/AST/DeclBase.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -236,8 +236,21 @@ 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 { Modified: vendor/clang/dist-release_60/lib/AST/MicrosoftMangle.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/AST/MicrosoftMangle.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/AST/MicrosoftMangle.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -950,11 +950,10 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(co } } +// <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( 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; } } Modified: vendor/clang/dist-release_60/lib/CodeGen/CodeGenModule.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/CodeGen/CodeGenModule.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/CodeGen/CodeGenModule.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -4000,18 +4000,13 @@ void CodeGenModule::EmitDeclContext(const DeclContext /// 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; Modified: vendor/clang/dist-release_60/lib/CodeGen/ItaniumCXXABI.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/CodeGen/ItaniumCXXABI.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/CodeGen/ItaniumCXXABI.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -2761,6 +2761,11 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenMod // 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 Modified: vendor/clang/dist-release_60/lib/CodeGen/TargetInfo.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/CodeGen/TargetInfo.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/CodeGen/TargetInfo.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -3543,7 +3543,17 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructType(Qu 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; Modified: vendor/clang/dist-release_60/lib/Format/TokenAnnotator.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/Format/TokenAnnotator.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Format/TokenAnnotator.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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; } Modified: vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -234,14 +234,17 @@ UnwrappedLineParser::UnwrappedLineParser(const FormatS 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 Modified: vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.h ============================================================================== --- vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.h Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Format/UnwrappedLineParser.h Fri Feb 16 19:10:26 2018 (r329396) @@ -248,10 +248,23 @@ class UnwrappedLineParser { (private) // 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. Modified: vendor/clang/dist-release_60/lib/Headers/avx512bwintrin.h ============================================================================== --- vendor/clang/dist-release_60/lib/Headers/avx512bwintrin.h Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Headers/avx512bwintrin.h Fri Feb 16 19:10:26 2018 (r329396) @@ -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 Modified: vendor/clang/dist-release_60/lib/Headers/avx512fintrin.h ============================================================================== --- vendor/clang/dist-release_60/lib/Headers/avx512fintrin.h Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Headers/avx512fintrin.h Fri Feb 16 19:10:26 2018 (r329396) @@ -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 Modified: vendor/clang/dist-release_60/lib/Lex/LiteralSupport.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/Lex/LiteralSupport.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Lex/LiteralSupport.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -738,15 +738,17 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(S 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(SourceLocati } 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 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); Modified: vendor/clang/dist-release_60/lib/Sema/SemaChecking.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/Sema/SemaChecking.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Sema/SemaChecking.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -8972,6 +8972,16 @@ static void AnalyzeComparison(Sema &S, BinaryOperator 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; Modified: vendor/clang/dist-release_60/lib/Sema/SemaDecl.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/Sema/SemaDecl.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Sema/SemaDecl.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -12507,9 +12507,19 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl /// 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 Modified: vendor/clang/dist-release_60/lib/Sema/SemaInit.cpp ============================================================================== --- vendor/clang/dist-release_60/lib/Sema/SemaInit.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/lib/Sema/SemaInit.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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 } 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 Init } 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 Initia 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 Initia 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; Modified: vendor/clang/dist-release_60/test/CodeGen/avx512bw-builtins.c ============================================================================== --- vendor/clang/dist-release_60/test/CodeGen/avx512bw-builtins.c Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/CodeGen/avx512bw-builtins.c Fri Feb 16 19:10:26 2018 (r329396) @@ -1626,26 +1626,16 @@ __m512i test_mm512_maskz_set1_epi8(__mmask64 __M, char 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) { Modified: vendor/clang/dist-release_60/test/CodeGen/avx512f-builtins.c ============================================================================== --- vendor/clang/dist-release_60/test/CodeGen/avx512f-builtins.c Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/CodeGen/avx512f-builtins.c Fri Feb 16 19:10:26 2018 (r329396) @@ -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) { Modified: vendor/clang/dist-release_60/test/CodeGen/ms_abi.c ============================================================================== --- vendor/clang/dist-release_60/test/CodeGen/ms_abi.c Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/CodeGen/ms_abi.c Fri Feb 16 19:10:26 2018 (r329396) @@ -146,3 +146,16 @@ void __attribute__((sysv_abi)) f6(__builtin_ms_va_list // 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; +} Added: vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-missing-key.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-missing-key.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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 Modified: vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-rtti.cpp ============================================================================== --- vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-rtti.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/CodeGenCXX/dllimport-rtti.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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; Added: vendor/clang/dist-release_60/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist-release_60/test/CodeGenCXX/microsoft-abi-emit-dependent.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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>()); } Added: vendor/clang/dist-release_60/test/CodeGenCXX/msabi-swiftcall-cc.cpp ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist-release_60/test/CodeGenCXX/msabi-swiftcall-cc.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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" + Modified: vendor/clang/dist-release_60/test/Lexer/cxx1y_digit_separators.cpp ============================================================================== --- vendor/clang/dist-release_60/test/Lexer/cxx1y_digit_separators.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/Lexer/cxx1y_digit_separators.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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 Modified: vendor/clang/dist-release_60/test/Sema/bitfield.c ============================================================================== --- vendor/clang/dist-release_60/test/Sema/bitfield.c Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/Sema/bitfield.c Fri Feb 16 19:10:26 2018 (r329396) @@ -82,3 +82,7 @@ typedef __typeof__(+(t5.n--)) Unsigned; // also act li 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}} +}; Modified: vendor/clang/dist-release_60/test/Sema/compare.c ============================================================================== --- vendor/clang/dist-release_60/test/Sema/compare.c Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/Sema/compare.c Fri Feb 16 19:10:26 2018 (r329396) @@ -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 +} Added: vendor/clang/dist-release_60/test/Sema/cxx-as-c.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ vendor/clang/dist-release_60/test/Sema/cxx-as-c.c Fri Feb 16 19:10:26 2018 (r329396) @@ -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+{{}} Modified: vendor/clang/dist-release_60/test/SemaCXX/init-expr-crash.cpp ============================================================================== --- vendor/clang/dist-release_60/test/SemaCXX/init-expr-crash.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/SemaCXX/init-expr-crash.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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}; +}; + Modified: vendor/clang/dist-release_60/test/SemaCXX/type-traits.cpp ============================================================================== --- vendor/clang/dist-release_60/test/SemaCXX/type-traits.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/SemaCXX/type-traits.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -2524,6 +2524,7 @@ static_assert(!has_unique_object_representations<const 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; Modified: vendor/clang/dist-release_60/test/SemaTemplate/instantiate-init.cpp ============================================================================== --- vendor/clang/dist-release_60/test/SemaTemplate/instantiate-init.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/test/SemaTemplate/instantiate-init.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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}} +} Modified: vendor/clang/dist-release_60/unittests/Format/FormatTest.cpp ============================================================================== --- vendor/clang/dist-release_60/unittests/Format/FormatTest.cpp Fri Feb 16 19:10:22 2018 (r329395) +++ vendor/clang/dist-release_60/unittests/Format/FormatTest.cpp Fri Feb 16 19:10:26 2018 (r329396) @@ -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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802161910.w1GJARPf069006>