Index: docs/ClangFormatStyleOptions.rst =================================================================== --- docs/ClangFormatStyleOptions.rst +++ docs/ClangFormatStyleOptions.rst @@ -252,6 +252,27 @@ If ``false``, a function declaration's or function definition's parameters will either all be on the same line or will have one line each. +**BraceWrapping** (``BraceWrappingFlags``) + Control of individual brace wrapping cases. + + If ``BreakBeforeBraces`` is set to ``custom``, use this to specify how each + individual brace case should be handled. Otherwise, this is ignored. + + Nested configuration flags: + + * ``bool AfterClass`` Wrap class definitions. + * ``bool AfterControlStatement`` Wrap control statements (if/for/while/switch/..). + * ``bool AfterEnum`` Wrap enum definitions. + * ``bool AfterFunction`` Wrap function definitions. + * ``bool AfterNamespace`` Wrap namespace definitions. + * ``bool AfterObjCDeclaration`` Wrap ObjC definitions (@autoreleasepool, interfaces, ..). + * ``bool AfterStruct`` Wrap struct definitions. + * ``bool AfterUnion`` Wrap union definitions. + * ``bool BeforeCatch`` Wrap before ``catch``. + * ``bool BeforeElse`` Wrap before ``else``. + * ``bool IndentBraces`` Indent the wrapped braces themselves. + + **BreakBeforeBinaryOperators** (``BinaryOperatorStyle``) The way to wrap binary operators. @@ -288,6 +309,8 @@ or other definitions. * ``BS_WebKit`` (in configuration: ``WebKit``) Like ``Attach``, but break before functions. + * ``BS_Custom`` (in configuration: ``Custom``) + Configure each individual brace in ``BraceWrapping``. **BreakBeforeTernaryOperators** (``bool``) @@ -365,6 +388,21 @@ For example: BOOST_FOREACH. +**IncludeCategories** (``std::vector>``) + Regular expressions denoting the different #include categories used + for ordering #includes. + + These regular expressions are matched against the filename of an include + (including the <> or "") in order. The value belonging to the first + matching regular expression is assigned and #includes are sorted first + according to increasing category number and then alphabetically within + each category. + + If none of the regular expressions match, UINT_MAX is assigned as + category. The main header for a source file automatically gets category 0, + so that it is kept at the beginning of the #includes + (http://llvm.org/docs/CodingStandards.html#include-style). + **IndentCaseLabels** (``bool``) Indent case labels one level from the switch statement. Index: docs/tools/dump_format_style.py =================================================================== --- docs/tools/dump_format_style.py +++ docs/tools/dump_format_style.py @@ -36,14 +36,35 @@ self.type = type self.comment = comment.strip() self.enum = None + self.nested_struct = None def __str__(self): s = '**%s** (``%s``)\n%s' % (self.name, self.type, doxygen2rst(indent(self.comment, 2))) if self.enum: s += indent('\n\nPossible values:\n\n%s\n' % self.enum, 2) + if self.nested_struct: + s += indent('\n\nNested configuration flags:\n\n%s\n' %self.nested_struct, + 2) return s +class NestedStruct: + def __init__(self, name, comment): + self.name = name + self.comment = comment.strip() + self.values = [] + + def __str__(self): + return '\n'.join(map(str, self.values)) + +class NestedField: + def __init__(self, name, comment): + self.name = name + self.comment = comment.strip() + + def __str__(self): + return '* ``%s`` %s' % (self.name, doxygen2rst(self.comment)) + class Enum: def __init__(self, name, comment): self.name = name @@ -69,14 +90,16 @@ def read_options(header): class State: - BeforeStruct, Finished, InStruct, InFieldComment, InEnum, \ - InEnumMemberComment = range(6) + BeforeStruct, Finished, InStruct, InNestedStruct, InNestedFieldComent, \ + InFieldComment, InEnum, InEnumMemberComment = range(8) state = State.BeforeStruct options = [] enums = {} + nested_structs = {} comment = '' enum = None + nested_struct = None for line in header: line = line.strip() @@ -97,13 +120,33 @@ state = State.InEnum name = re.sub(r'enum\s+(\w+)\s*\{', '\\1', line) enum = Enum(name, comment) + elif line.startswith('struct'): + state = State.InNestedStruct + name = re.sub(r'struct\s+(\w+)\s*\{', '\\1', line) + nested_struct = NestedStruct(name, comment) elif line.endswith(';'): state = State.InStruct - field_type, field_name = re.match(r'([<>:\w]+)\s+(\w+);', line).groups() + field_type, field_name = re.match(r'([<>:\w(,\s)]+)\s+(\w+);', + line).groups() option = Option(str(field_name), str(field_type), comment) options.append(option) else: raise Exception('Invalid format, expected comment, field or enum') + elif state == State.InNestedStruct: + if line.startswith('///'): + state = State.InNestedFieldComent + comment = clean_comment_line(line) + elif line == '};': + state = State.InStruct + nested_structs[nested_struct.name] = nested_struct + else: + raise Exception('Invalid format, expected struct field comment or };') + elif state == State.InNestedFieldComent: + if line.startswith('///'): + comment += clean_comment_line(line) + else: + state = State.InNestedStruct + nested_struct.values.append(NestedField(line.replace(';', ''), comment)) elif state == State.InEnum: if line.startswith('///'): state = State.InEnumMemberComment @@ -124,9 +167,12 @@ for option in options: if not option.type in ['bool', 'unsigned', 'int', 'std::string', - 'std::vector']: + 'std::vector', + 'std::vector>']: if enums.has_key(option.type): option.enum = enums[option.type] + elif nested_structs.has_key(option.type): + option.nested_struct = nested_structs[option.type]; else: raise Exception('Unknown type: %s' % option.type) return options Index: include/clang/AST/DataRecursiveASTVisitor.h =================================================================== --- include/clang/AST/DataRecursiveASTVisitor.h +++ include/clang/AST/DataRecursiveASTVisitor.h @@ -2540,6 +2540,11 @@ } template +bool RecursiveASTVisitor::VisitOMPSIMDClause(OMPSIMDClause *) { + return true; +} + +template template bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -62,7 +62,6 @@ MemberPointerAdjustment } Kind; - struct DTB { const CastExpr *BasePath; const CXXRecordDecl *DerivedClass; @@ -807,7 +806,6 @@ } }; - //===----------------------------------------------------------------------===// // Primary Expressions. //===----------------------------------------------------------------------===// @@ -1675,7 +1673,6 @@ child_range children() { return child_range(&Val, &Val+1); } }; - /// UnaryOperator - This represents the unary-expression's (except sizeof and /// alignof), the postinc/postdec operators from postfix-expression, and various /// extensions. @@ -2159,7 +2156,6 @@ } }; - /// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]). /// CallExpr itself represents a normal function call, e.g., "f(x, 2)", /// while its subclasses may represent alternative syntax that (semantically) @@ -3456,7 +3452,6 @@ child_range children() { return child_range(&SubStmt, &SubStmt+1); } }; - /// ShuffleVectorExpr - clang-specific builtin-in function /// __builtin_shufflevector. /// This AST node represents a operator that does a constant @@ -3712,7 +3707,7 @@ /// Create an empty __builtin_va_arg expression. explicit VAArgExpr(EmptyShell Empty) - : Expr(VAArgExprClass, Empty), Val(0), TInfo(0, false) {} + : Expr(VAArgExprClass, Empty), Val(nullptr), TInfo(nullptr, false) {} const Expr *getSubExpr() const { return cast(Val); } Expr *getSubExpr() { return cast(Val); } @@ -4406,7 +4401,6 @@ } }; - class ParenListExpr : public Expr { Stmt **Exprs; unsigned NumExprs; @@ -4452,7 +4446,6 @@ friend class ASTStmtWriter; }; - /// \brief Represents a C11 generic selection. /// /// A generic selection (C11 6.5.1.1) contains an unevaluated controlling @@ -4568,7 +4561,6 @@ // Clang Extensions //===----------------------------------------------------------------------===// - /// ExtVectorElementExpr - This represents access to specific elements of a /// vector, and may occur on the left hand side or right hand side. For example /// the following is legal: "V.xy = V.zw" if V is a 4 element extended vector. @@ -4632,7 +4624,6 @@ child_range children() { return child_range(&Base, &Base+1); } }; - /// BlockExpr - Adaptor class for mixing a BlockDecl with expressions. /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockExpr : public Expr { @@ -4984,6 +4975,6 @@ } }; -} // end namespace clang +} // end namespace clang -#endif +#endif // LLVM_CLANG_AST_EXPR_H Index: include/clang/AST/ExprOpenMP.h =================================================================== --- include/clang/AST/ExprOpenMP.h +++ include/clang/AST/ExprOpenMP.h @@ -84,6 +84,9 @@ /// \brief Set base of the array section. void setBase(Expr *E) { SubExprs[BASE] = E; } + /// \brief Return original type of the base expression for array section. + static QualType getBaseOriginalType(Expr *Base); + /// \brief Get lower bound of array section. Expr *getLowerBound() { return cast_or_null(SubExprs[LOWER_BOUND]); } const Expr *getLowerBound() const { Index: include/clang/AST/OpenMPClause.h =================================================================== --- include/clang/AST/OpenMPClause.h +++ include/clang/AST/OpenMPClause.h @@ -2513,7 +2513,7 @@ /// OMPDeviceClause() : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Device(0) {} + LParenLoc(SourceLocation()), Device(nullptr) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } /// \brief Returns the location of '('. @@ -2561,7 +2561,36 @@ } }; -} // end namespace clang +/// \brief This represents 'simd' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp ordered simd +/// \endcode +/// In this example directive '#pragma omp ordered' has simple 'simd' clause. +/// +class OMPSIMDClause : public OMPClause { +public: + /// \brief Build 'simd' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + + /// \brief Build an empty clause. + /// + OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_simd; + } -#endif + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + +} // end namespace clang +#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H Index: include/clang/AST/RecursiveASTVisitor.h =================================================================== --- include/clang/AST/RecursiveASTVisitor.h +++ include/clang/AST/RecursiveASTVisitor.h @@ -2572,6 +2572,11 @@ } template +bool RecursiveASTVisitor::VisitOMPSIMDClause(OMPSIMDClause *) { + return true; +} + +template template bool RecursiveASTVisitor::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -4635,7 +4635,7 @@ /// Retrieve the type arguments of this object type as they were /// written. ArrayRef getTypeArgsAsWritten() const { - return ArrayRef(getTypeArgStorage(), + return llvm::makeArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs); } Index: include/clang/Analysis/Analyses/ThreadSafetyCommon.h =================================================================== --- include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -291,6 +291,8 @@ return nullptr; if (auto *P = dyn_cast(CapExpr)) return P->clangDecl(); + if (auto *P = dyn_cast(CapExpr)) + return P->clangDecl(); return nullptr; } Index: include/clang/Analysis/Analyses/ThreadSafetyTIL.h =================================================================== --- include/clang/Analysis/Analyses/ThreadSafetyTIL.h +++ include/clang/Analysis/Analyses/ThreadSafetyTIL.h @@ -1395,7 +1395,7 @@ /// Return the list of basic blocks that this terminator can branch to. ArrayRef successors() { - return ArrayRef(&TargetBlock, 1); + return TargetBlock; } template @@ -1445,7 +1445,7 @@ /// Return the list of basic blocks that this terminator can branch to. ArrayRef successors() { - return ArrayRef(Branches, 2); + return llvm::makeArrayRef(Branches); } template @@ -1479,7 +1479,7 @@ /// Return an empty list. ArrayRef successors() { - return ArrayRef(); + return None; } SExpr *returnValue() { return Retval; } @@ -1507,7 +1507,7 @@ case COP_Branch: return cast(this)->successors(); case COP_Return: return cast(this)->successors(); default: - return ArrayRef(); + return None; } } Index: include/clang/Analysis/CFG.h =================================================================== --- include/clang/Analysis/CFG.h +++ include/clang/Analysis/CFG.h @@ -229,7 +229,6 @@ return static_cast(Data2.getPointer()); } - private: friend class CFGElement; CFGDeleteDtor() {} @@ -693,7 +692,7 @@ iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C) { return iterator(Elements.insert(I.base(), Cnt, - CFGAutomaticObjDtor(nullptr, 0), C)); + CFGAutomaticObjDtor(nullptr, nullptr), C)); } iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { *I = CFGAutomaticObjDtor(VD, S); @@ -1110,4 +1109,5 @@ } }; } // end llvm namespace -#endif + +#endif // LLVM_CLANG_ANALYSIS_CFG_H Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -113,7 +113,7 @@ // the case of a SubsetSubject, there's no way to express it without this hack. def DeclBase : AttrSubject; def FunctionLike : SubsetSubjectgetFunctionType(false) != NULL}]>; + [{S->getFunctionType(false) != nullptr}]>; def OpenCLKernelFunction : SubsetSubjecthasAttr() @@ -123,7 +123,7 @@ // never be specified in a Subjects list along with FunctionLike (due to the // inclusive nature of subject testing). def HasFunctionProto : SubsetSubjectgetFunctionType(true) != NULL && + [{(S->getFunctionType(true) != nullptr && isa(S->getFunctionType())) || isa(S) || isa(S)}]>; @@ -1543,8 +1543,8 @@ let Spellings = [GNU<"capability">, CXX11<"clang", "capability">, GNU<"shared_capability">, CXX11<"clang", "shared_capability">]; - let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag, - "ExpectedStructOrTypedef">; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, + "ExpectedStructOrUnionOrTypedef">; let Args = [StringArgument<"Name">]; let Accessors = [Accessor<"isShared", [GNU<"shared_capability">, Index: include/clang/Basic/BuiltinsNVPTX.def =================================================================== --- include/clang/Basic/BuiltinsNVPTX.def +++ include/clang/Basic/BuiltinsNVPTX.def @@ -50,7 +50,7 @@ BUILTIN(__builtin_ptx_read_lanemask_gt, "i", "nc") BUILTIN(__builtin_ptx_read_clock, "i", "n") -BUILTIN(__builtin_ptx_read_clock64, "Li", "n") +BUILTIN(__builtin_ptx_read_clock64, "LLi", "n") BUILTIN(__builtin_ptx_read_pm0, "i", "n") BUILTIN(__builtin_ptx_read_pm1, "i", "n") Index: include/clang/Basic/BuiltinsPPC.def =================================================================== --- include/clang/Basic/BuiltinsPPC.def +++ include/clang/Basic/BuiltinsPPC.def @@ -280,12 +280,21 @@ BUILTIN(__builtin_vsx_xvcmpeqdp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpeqsp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvcmpeqdp_p, "iiV2dV2d", "") +BUILTIN(__builtin_vsx_xvcmpeqsp_p, "iiV4fV4f", "") + BUILTIN(__builtin_vsx_xvcmpgedp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpgesp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvcmpgedp_p, "iiV2dV2d", "") +BUILTIN(__builtin_vsx_xvcmpgesp_p, "iiV4fV4f", "") + BUILTIN(__builtin_vsx_xvcmpgtdp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpgtsp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvcmpgtdp_p, "iiV2dV2d", "") +BUILTIN(__builtin_vsx_xvcmpgtsp_p, "iiV4fV4f", "") + BUILTIN(__builtin_vsx_xvrdpim, "V2dV2d", "") BUILTIN(__builtin_vsx_xvrspim, "V4fV4f", "") Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1153,7 +1153,10 @@ "target exception specification is not superset of source">; def err_deep_exception_specs_differ : Error< "exception specifications of %select{return|argument}0 types differ">; -def warn_missing_exception_specification : Warning< +def ext_missing_exception_specification : ExtWarn< + "%0 is missing exception specification '%1'">, + InGroup>; +def err_missing_exception_specification : Error< "%0 is missing exception specification '%1'">; def err_noexcept_needs_constant_expression : Error< "argument to noexcept specifier must be a constant expression">; @@ -7477,6 +7480,9 @@ "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; +def err_atomic_init_constant : Error< + "atomic variable can only be assigned to a compile time constant" + " in the declaration statement in the program scope">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; } // end of sema category @@ -7505,7 +7511,7 @@ def err_omp_lastprivate_incomplete_type : Error< "a lastprivate variable with incomplete type %0">; def err_omp_reduction_incomplete_type : Error< - "a reduction variable with incomplete type %0">; + "a reduction list item with incomplete type %0">; def err_omp_unexpected_clause_value : Error< "expected %0 in OpenMP clause '%1'">; def err_omp_expected_var_name : Error< @@ -7562,6 +7568,8 @@ "%0 variable must be %1">; def err_omp_const_variable : Error< "const-qualified variable cannot be %0">; +def err_omp_const_reduction_list_item : Error< + "const-qualified list item cannot be reduction">; def err_omp_linear_incomplete_type : Error< "a linear variable with incomplete type %0">; def err_omp_linear_expected_int_or_ptr : Error< @@ -7613,7 +7621,7 @@ def err_omp_unknown_reduction_identifier : Error< "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">; def err_omp_reduction_type_array : Error< - "a reduction variable with array type %0">; + "a reduction list item with array type %0">; def err_omp_reduction_ref_type_arg : Error< "argument of OpenMP clause 'reduction' must reference the same object in all threads">; def err_omp_clause_not_arithmetic_type_arg : Error< @@ -7627,7 +7635,7 @@ def err_omp_reduction_in_task : Error< "reduction variables may not be accessed in an explicit task">; def err_omp_reduction_id_not_compatible : Error< - "variable of type %0 is not valid for specified reduction operation: unable to provide default initialization value">; + "list item of type %0 is not valid for specified reduction operation: unable to provide default initialization value">; def err_omp_prohibited_region : Error< "region cannot be%select{| closely}0 nested inside '%1' region" "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|" @@ -7735,6 +7743,8 @@ "'ordered' directive %select{without any clauses|with 'threads' clause}0 cannot be closely nested inside ordered region with specified parameter">; def note_omp_ordered_param : Note< "'ordered' clause with specified parameter">; +def err_omp_expected_array_sect_reduction_lb_not_zero : Error< + "lower bound expected to be evaluated to zero">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { Index: include/clang/Basic/OpenMPKinds.def =================================================================== --- include/clang/Basic/OpenMPKinds.def +++ include/clang/Basic/OpenMPKinds.def @@ -145,6 +145,7 @@ OPENMP_CLAUSE(depend, OMPDependClause) OPENMP_CLAUSE(device, OMPDeviceClause) OPENMP_CLAUSE(threads, OMPThreadsClause) +OPENMP_CLAUSE(simd, OMPSIMDClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -318,6 +319,7 @@ // Clauses allowed for OpenMP directive 'ordered'. // TODO More clauses for 'ordered' directive. OPENMP_ORDERED_CLAUSE(threads) +OPENMP_ORDERED_CLAUSE(simd) #undef OPENMP_LINEAR_KIND #undef OPENMP_DEPEND_KIND Index: include/clang/CodeGen/CodeGenABITypes.h =================================================================== --- include/clang/CodeGen/CodeGenABITypes.h +++ include/clang/CodeGen/CodeGenABITypes.h @@ -52,7 +52,6 @@ public: CodeGenABITypes(ASTContext &C, llvm::Module &M, CoverageSourceInfo *CoverageInfo = nullptr); - ~CodeGenABITypes(); /// These methods all forward to methods in the private implementation class /// CodeGenTypes. @@ -75,12 +74,12 @@ /// Default CodeGenOptions object used to initialize the /// CodeGenModule and otherwise not used. More specifically, it is /// not used in ABI type generation, so none of the options matter. - CodeGenOptions *CGO; - HeaderSearchOptions *HSO; - PreprocessorOptions *PPO; + std::unique_ptr CGO; + std::unique_ptr HSO; + std::unique_ptr PPO; /// The CodeGenModule we use get to the CodeGenTypes object. - CodeGen::CodeGenModule *CGM; + std::unique_ptr CGM; }; } // end namespace CodeGen Index: include/clang/Driver/Job.h =================================================================== --- include/clang/Driver/Job.h +++ include/clang/Driver/Job.h @@ -85,6 +85,9 @@ Command(const Action &Source, const Tool &Creator, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef Inputs); + // FIXME: This really shouldn't be copyable, but is currently copied in some + // error handling in Driver::generateCompilationDiagnostics. + Command(const Command &) = default; virtual ~Command() {} virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -151,6 +151,20 @@ // Returns the RTTIMode for the toolchain with the current arguments. RTTIMode getRTTIMode() const { return CachedRTTIMode; } + /// \brief Return any implicit target and/or mode flag for an invocation of + /// the compiler driver as `ProgName`. + /// + /// For example, when called with i686-linux-android-g++, the first element + /// of the return value will be set to `"i686-linux-android"` and the second + /// will be set to "--driver-mode=g++"`. + /// + /// \pre `llvm::InitializeAllTargets()` has been called. + /// \param ProgName The name the Clang driver was invoked with (from, + /// e.g., argv[0]) + /// \return A pair of (`target`, `mode-flag`), where one or both may be empty. + static std::pair + getTargetAndModeFromProgramName(StringRef ProgName); + // Tool access. /// TranslateArgs - Create a new derived argument list for any argument Index: include/clang/Format/Format.h =================================================================== --- include/clang/Format/Format.h +++ include/clang/Format/Format.h @@ -64,6 +64,17 @@ /// \endcode bool AlignConsecutiveAssignments; + /// \brief If \c true, aligns consecutive declarations. + /// + /// This will align the declaration names of consecutive lines. This + /// will result in formattings like + /// \code + /// int aaaa = 12; + /// float b = 23; + /// std::string ccc = 23; + /// \endcode + bool AlignConsecutiveDeclarations; + /// \brief If \c true, aligns escaped newlines as far left as possible. /// Otherwise puts them into the right-most column. bool AlignEscapedNewlinesLeft; @@ -178,12 +189,46 @@ /// or other definitions. BS_GNU, /// Like ``Attach``, but break before functions. - BS_WebKit + BS_WebKit, + /// Configure each individual brace in \c BraceWrapping. + BS_Custom }; /// \brief The brace breaking style to use. BraceBreakingStyle BreakBeforeBraces; + /// \brief Precise control over the wrapping of braces. + struct BraceWrappingFlags { + /// \brief Wrap class definitions. + bool AfterClass; + /// \brief Wrap control statements (if/for/while/switch/..). + bool AfterControlStatement; + /// \brief Wrap enum definitions. + bool AfterEnum; + /// \brief Wrap function definitions. + bool AfterFunction; + /// \brief Wrap namespace definitions. + bool AfterNamespace; + /// \brief Wrap ObjC definitions (@autoreleasepool, interfaces, ..). + bool AfterObjCDeclaration; + /// \brief Wrap struct definitions. + bool AfterStruct; + /// \brief Wrap union definitions. + bool AfterUnion; + /// \brief Wrap before \c catch. + bool BeforeCatch; + /// \brief Wrap before \c else. + bool BeforeElse; + /// \brief Indent the wrapped braces themselves. + bool IndentBraces; + }; + + /// \brief Control of individual brace wrapping cases. + /// + /// If \c BreakBeforeBraces is set to \c custom, use this to specify how each + /// individual brace case should be handled. Otherwise, this is ignored. + BraceWrappingFlags BraceWrapping; + /// \brief If \c true, ternary operators will be placed after line breaks. bool BreakBeforeTernaryOperators; @@ -259,6 +304,21 @@ /// For example: BOOST_FOREACH. std::vector ForEachMacros; + /// \brief Regular expressions denoting the different #include categories used + /// for ordering #includes. + /// + /// These regular expressions are matched against the filename of an include + /// (including the <> or "") in order. The value belonging to the first + /// matching regular expression is assigned and #includes are sorted first + /// according to increasing category number and then alphabetically within + /// each category. + /// + /// If none of the regular expressions match, UINT_MAX is assigned as + /// category. The main header for a source file automatically gets category 0, + /// so that it is kept at the beginning of the #includes + /// (http://llvm.org/docs/CodingStandards.html#include-style). + std::vector> IncludeCategories; + /// \brief Indent case labels one level from the switch statement. /// /// When \c false, use the same indentation level as for the switch statement. @@ -446,6 +506,7 @@ return AccessModifierOffset == R.AccessModifierOffset && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && + AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft && AlignOperands == R.AlignOperands && AlignTrailingComments == R.AlignTrailingComments && Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -6737,7 +6737,7 @@ Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind, SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template = nullptr, - ArrayRef TemplateArgs = ArrayRef(), + ArrayRef TemplateArgs = None, sema::TemplateDeductionInfo *DeductionInfo = nullptr); InstantiatingTemplate(const InstantiatingTemplate&) = delete; @@ -7997,7 +7997,10 @@ SourceLocation EndLoc); /// \brief Called on well-formed 'threads' clause. OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, - SourceLocation EndLoc); + SourceLocation EndLoc); + /// \brief Called on well-formed 'simd' clause. + OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc, + SourceLocation EndLoc); OMPClause *ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef Vars, Expr *TailExpr, Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -5329,7 +5329,7 @@ return new (Importer.getToContext()) CallExpr(Importer.getToContext(), ToCallee, - ArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(), + llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(), Importer.Import(E->getRParenLoc())); } Index: lib/AST/CMakeLists.txt =================================================================== --- lib/AST/CMakeLists.txt +++ lib/AST/CMakeLists.txt @@ -30,6 +30,7 @@ ExprClassification.cpp ExprConstant.cpp ExprCXX.cpp + ExprObjC.cpp ExternalASTSource.cpp InheritViz.cpp ItaniumCXXABI.cpp Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -3510,285 +3510,6 @@ } } -ObjCMessageExpr::ObjCMessageExpr(QualType T, - ExprValueKind VK, - SourceLocation LBracLoc, - SourceLocation SuperLoc, - bool IsInstanceSuper, - QualType SuperType, - Selector Sel, - ArrayRef SelLocs, - SelectorLocationsKind SelLocsK, - ObjCMethodDecl *Method, - ArrayRef Args, - SourceLocation RBracLoc, - bool isImplicit) - : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/false, - /*InstantiationDependent=*/false, - /*ContainsUnexpandedParameterPack=*/false), - SelectorOrMethod(reinterpret_cast(Method? Method - : Sel.getAsOpaquePtr())), - Kind(IsInstanceSuper? SuperInstance : SuperClass), - HasMethod(Method != nullptr), IsDelegateInitCall(false), - IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc), - RBracLoc(RBracLoc) -{ - initArgsAndSelLocs(Args, SelLocs, SelLocsK); - setReceiverPointer(SuperType.getAsOpaquePtr()); -} - -ObjCMessageExpr::ObjCMessageExpr(QualType T, - ExprValueKind VK, - SourceLocation LBracLoc, - TypeSourceInfo *Receiver, - Selector Sel, - ArrayRef SelLocs, - SelectorLocationsKind SelLocsK, - ObjCMethodDecl *Method, - ArrayRef Args, - SourceLocation RBracLoc, - bool isImplicit) - : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), - T->isDependentType(), T->isInstantiationDependentType(), - T->containsUnexpandedParameterPack()), - SelectorOrMethod(reinterpret_cast(Method? Method - : Sel.getAsOpaquePtr())), - Kind(Class), - HasMethod(Method != nullptr), IsDelegateInitCall(false), - IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) -{ - initArgsAndSelLocs(Args, SelLocs, SelLocsK); - setReceiverPointer(Receiver); -} - -ObjCMessageExpr::ObjCMessageExpr(QualType T, - ExprValueKind VK, - SourceLocation LBracLoc, - Expr *Receiver, - Selector Sel, - ArrayRef SelLocs, - SelectorLocationsKind SelLocsK, - ObjCMethodDecl *Method, - ArrayRef Args, - SourceLocation RBracLoc, - bool isImplicit) - : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), - Receiver->isTypeDependent(), - Receiver->isInstantiationDependent(), - Receiver->containsUnexpandedParameterPack()), - SelectorOrMethod(reinterpret_cast(Method? Method - : Sel.getAsOpaquePtr())), - Kind(Instance), - HasMethod(Method != nullptr), IsDelegateInitCall(false), - IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) -{ - initArgsAndSelLocs(Args, SelLocs, SelLocsK); - setReceiverPointer(Receiver); -} - -void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef Args, - ArrayRef SelLocs, - SelectorLocationsKind SelLocsK) { - setNumArgs(Args.size()); - Expr **MyArgs = getArgs(); - for (unsigned I = 0; I != Args.size(); ++I) { - if (Args[I]->isTypeDependent()) - ExprBits.TypeDependent = true; - if (Args[I]->isValueDependent()) - ExprBits.ValueDependent = true; - if (Args[I]->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (Args[I]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; - - MyArgs[I] = Args[I]; - } - - SelLocsKind = SelLocsK; - if (!isImplicit()) { - if (SelLocsK == SelLoc_NonStandard) - std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); - } -} - -ObjCMessageExpr *ObjCMessageExpr::Create(const ASTContext &Context, QualType T, - ExprValueKind VK, - SourceLocation LBracLoc, - SourceLocation SuperLoc, - bool IsInstanceSuper, - QualType SuperType, - Selector Sel, - ArrayRef SelLocs, - ObjCMethodDecl *Method, - ArrayRef Args, - SourceLocation RBracLoc, - bool isImplicit) { - assert((!SelLocs.empty() || isImplicit) && - "No selector locs for non-implicit message"); - ObjCMessageExpr *Mem; - SelectorLocationsKind SelLocsK = SelectorLocationsKind(); - if (isImplicit) - Mem = alloc(Context, Args.size(), 0); - else - Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); - return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, - SuperType, Sel, SelLocs, SelLocsK, - Method, Args, RBracLoc, isImplicit); -} - -ObjCMessageExpr *ObjCMessageExpr::Create(const ASTContext &Context, QualType T, - ExprValueKind VK, - SourceLocation LBracLoc, - TypeSourceInfo *Receiver, - Selector Sel, - ArrayRef SelLocs, - ObjCMethodDecl *Method, - ArrayRef Args, - SourceLocation RBracLoc, - bool isImplicit) { - assert((!SelLocs.empty() || isImplicit) && - "No selector locs for non-implicit message"); - ObjCMessageExpr *Mem; - SelectorLocationsKind SelLocsK = SelectorLocationsKind(); - if (isImplicit) - Mem = alloc(Context, Args.size(), 0); - else - Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); - return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, - SelLocs, SelLocsK, Method, Args, RBracLoc, - isImplicit); -} - -ObjCMessageExpr *ObjCMessageExpr::Create(const ASTContext &Context, QualType T, - ExprValueKind VK, - SourceLocation LBracLoc, - Expr *Receiver, - Selector Sel, - ArrayRef SelLocs, - ObjCMethodDecl *Method, - ArrayRef Args, - SourceLocation RBracLoc, - bool isImplicit) { - assert((!SelLocs.empty() || isImplicit) && - "No selector locs for non-implicit message"); - ObjCMessageExpr *Mem; - SelectorLocationsKind SelLocsK = SelectorLocationsKind(); - if (isImplicit) - Mem = alloc(Context, Args.size(), 0); - else - Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); - return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, - SelLocs, SelLocsK, Method, Args, RBracLoc, - isImplicit); -} - -ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context, - unsigned NumArgs, - unsigned NumStoredSelLocs) { - ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); - return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); -} - -ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, - ArrayRef Args, - SourceLocation RBraceLoc, - ArrayRef SelLocs, - Selector Sel, - SelectorLocationsKind &SelLocsK) { - SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); - unsigned NumStoredSelLocs = (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() - : 0; - return alloc(C, Args.size(), NumStoredSelLocs); -} - -ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, - unsigned NumArgs, - unsigned NumStoredSelLocs) { - unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + - NumArgs * sizeof(Expr *) + NumStoredSelLocs * sizeof(SourceLocation); - return (ObjCMessageExpr *)C.Allocate(Size, - llvm::AlignOf::Alignment); -} - -void ObjCMessageExpr::getSelectorLocs( - SmallVectorImpl &SelLocs) const { - for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) - SelLocs.push_back(getSelectorLoc(i)); -} - -SourceRange ObjCMessageExpr::getReceiverRange() const { - switch (getReceiverKind()) { - case Instance: - return getInstanceReceiver()->getSourceRange(); - - case Class: - return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange(); - - case SuperInstance: - case SuperClass: - return getSuperLoc(); - } - - llvm_unreachable("Invalid ReceiverKind!"); -} - -Selector ObjCMessageExpr::getSelector() const { - if (HasMethod) - return reinterpret_cast(SelectorOrMethod) - ->getSelector(); - return Selector(SelectorOrMethod); -} - -QualType ObjCMessageExpr::getReceiverType() const { - switch (getReceiverKind()) { - case Instance: - return getInstanceReceiver()->getType(); - case Class: - return getClassReceiver(); - case SuperInstance: - case SuperClass: - return getSuperType(); - } - - llvm_unreachable("unexpected receiver kind"); -} - -ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { - QualType T = getReceiverType(); - - if (const ObjCObjectPointerType *Ptr = T->getAs()) - return Ptr->getInterfaceDecl(); - - if (const ObjCObjectType *Ty = T->getAs()) - return Ty->getInterface(); - - return nullptr; -} - -QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const { - if (isClassReceiver()) - return ctx.getObjCInterfaceType(getClassReceiver()); - - if (isSuperReceiver()) - return getSuperReceiverType(); - - return getBase()->getType(); -} - -StringRef ObjCBridgedCastExpr::getBridgeKindName() const { - switch (getBridgeKind()) { - case OBC_Bridge: - return "__bridge"; - case OBC_BridgeTransfer: - return "__bridge_transfer"; - case OBC_BridgeRetained: - return "__bridge_retained"; - } - - llvm_unreachable("Invalid BridgeKind!"); -} - ShuffleVectorExpr::ShuffleVectorExpr(const ASTContext &C, ArrayRef args, QualType Type, SourceLocation BLoc, SourceLocation RP) @@ -4190,129 +3911,6 @@ return child_range(&Argument.Ex, &Argument.Ex + 1); } -// ObjCMessageExpr -Stmt::child_range ObjCMessageExpr::children() { - Stmt **begin; - if (getReceiverKind() == Instance) - begin = reinterpret_cast(this + 1); - else - begin = reinterpret_cast(getArgs()); - return child_range(begin, - reinterpret_cast(getArgs() + getNumArgs())); -} - -ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef Elements, - QualType T, ObjCMethodDecl *Method, - SourceRange SR) - : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, - false, false, false, false), - NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) -{ - Expr **SaveElements = getElements(); - for (unsigned I = 0, N = Elements.size(); I != N; ++I) { - if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent()) - ExprBits.ValueDependent = true; - if (Elements[I]->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (Elements[I]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; - - SaveElements[I] = Elements[I]; - } -} - -ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C, - ArrayRef Elements, - QualType T, ObjCMethodDecl * Method, - SourceRange SR) { - void *Mem = C.Allocate(sizeof(ObjCArrayLiteral) - + Elements.size() * sizeof(Expr *)); - return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR); -} - -ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C, - unsigned NumElements) { - - void *Mem = C.Allocate(sizeof(ObjCArrayLiteral) - + NumElements * sizeof(Expr *)); - return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements); -} - -ObjCDictionaryLiteral::ObjCDictionaryLiteral( - ArrayRef VK, - bool HasPackExpansions, - QualType T, ObjCMethodDecl *method, - SourceRange SR) - : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR), - DictWithObjectsMethod(method) -{ - KeyValuePair *KeyValues = getKeyValues(); - ExpansionData *Expansions = getExpansionData(); - for (unsigned I = 0; I < NumElements; I++) { - if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() || - VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent()) - ExprBits.ValueDependent = true; - if (VK[I].Key->isInstantiationDependent() || - VK[I].Value->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (VK[I].EllipsisLoc.isInvalid() && - (VK[I].Key->containsUnexpandedParameterPack() || - VK[I].Value->containsUnexpandedParameterPack())) - ExprBits.ContainsUnexpandedParameterPack = true; - - KeyValues[I].Key = VK[I].Key; - KeyValues[I].Value = VK[I].Value; - if (Expansions) { - Expansions[I].EllipsisLoc = VK[I].EllipsisLoc; - if (VK[I].NumExpansions) - Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1; - else - Expansions[I].NumExpansionsPlusOne = 0; - } - } -} - -ObjCDictionaryLiteral * -ObjCDictionaryLiteral::Create(const ASTContext &C, - ArrayRef VK, - bool HasPackExpansions, - QualType T, ObjCMethodDecl *method, - SourceRange SR) { - unsigned ExpansionsSize = 0; - if (HasPackExpansions) - ExpansionsSize = sizeof(ExpansionData) * VK.size(); - - void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + - sizeof(KeyValuePair) * VK.size() + ExpansionsSize); - return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR); -} - -ObjCDictionaryLiteral * -ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements, - bool HasPackExpansions) { - unsigned ExpansionsSize = 0; - if (HasPackExpansions) - ExpansionsSize = sizeof(ExpansionData) * NumElements; - void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + - sizeof(KeyValuePair) * NumElements + ExpansionsSize); - return new (Mem) ObjCDictionaryLiteral(EmptyShell(), NumElements, - HasPackExpansions); -} - -ObjCSubscriptRefExpr *ObjCSubscriptRefExpr::Create(const ASTContext &C, - Expr *base, - Expr *key, QualType T, - ObjCMethodDecl *getMethod, - ObjCMethodDecl *setMethod, - SourceLocation RB) { - void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr)); - return new (Mem) ObjCSubscriptRefExpr(base, key, T, VK_LValue, - OK_ObjCSubscript, - getMethod, setMethod, RB); -} - AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef args, QualType t, AtomicOp op, SourceLocation RP) : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary, @@ -4379,3 +3977,26 @@ } llvm_unreachable("unknown atomic op"); } + +QualType OMPArraySectionExpr::getBaseOriginalType(Expr *Base) { + unsigned ArraySectionCount = 0; + while (auto *OASE = dyn_cast(Base->IgnoreParens())) { + Base = OASE->getBase(); + ++ArraySectionCount; + } + auto OriginalTy = Base->getType(); + if (auto *DRE = dyn_cast(Base)) + if (auto *PVD = dyn_cast(DRE->getDecl())) + OriginalTy = PVD->getOriginalType().getNonReferenceType(); + + for (unsigned Cnt = 0; Cnt < ArraySectionCount; ++Cnt) { + if (OriginalTy->isAnyPointerType()) + OriginalTy = OriginalTy->getPointeeType(); + else { + assert (OriginalTy->isArrayType()); + OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType(); + } + } + return OriginalTy; +} + Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -5568,7 +5568,7 @@ VectorExprEvaluator(EvalInfo &info, APValue &Result) : ExprEvaluatorBaseTy(info), Result(Result) {} - bool Success(const ArrayRef &V, const Expr *E) { + bool Success(ArrayRef V, const Expr *E) { assert(V.size() == E->getType()->castAs()->getNumElements()); // FIXME: remove this APValue copy. Result = APValue(V.data(), V.size()); Index: lib/AST/ExprObjC.cpp =================================================================== --- /dev/null +++ lib/AST/ExprObjC.cpp @@ -0,0 +1,379 @@ +//===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the subclesses of Expr class declared in ExprObjC.h +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ExprObjC.h" + +#include "clang/AST/ASTContext.h" + +using namespace clang; + +ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef Elements, QualType T, + ObjCMethodDecl *Method, SourceRange SR) + : Expr(ObjCArrayLiteralClass, T, VK_RValue, OK_Ordinary, false, false, + false, false), + NumElements(Elements.size()), Range(SR), ArrayWithObjectsMethod(Method) { + Expr **SaveElements = getElements(); + for (unsigned I = 0, N = Elements.size(); I != N; ++I) { + if (Elements[I]->isTypeDependent() || Elements[I]->isValueDependent()) + ExprBits.ValueDependent = true; + if (Elements[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (Elements[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + SaveElements[I] = Elements[I]; + } +} + +ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C, + ArrayRef Elements, + QualType T, ObjCMethodDecl *Method, + SourceRange SR) { + void *Mem = + C.Allocate(sizeof(ObjCArrayLiteral) + Elements.size() * sizeof(Expr *)); + return new (Mem) ObjCArrayLiteral(Elements, T, Method, SR); +} + +ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C, + unsigned NumElements) { + + void *Mem = + C.Allocate(sizeof(ObjCArrayLiteral) + NumElements * sizeof(Expr *)); + return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements); +} + +ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef VK, + bool HasPackExpansions, QualType T, + ObjCMethodDecl *method, + SourceRange SR) + : Expr(ObjCDictionaryLiteralClass, T, VK_RValue, OK_Ordinary, false, false, + false, false), + NumElements(VK.size()), HasPackExpansions(HasPackExpansions), Range(SR), + DictWithObjectsMethod(method) { + KeyValuePair *KeyValues = getKeyValues(); + ExpansionData *Expansions = getExpansionData(); + for (unsigned I = 0; I < NumElements; I++) { + if (VK[I].Key->isTypeDependent() || VK[I].Key->isValueDependent() || + VK[I].Value->isTypeDependent() || VK[I].Value->isValueDependent()) + ExprBits.ValueDependent = true; + if (VK[I].Key->isInstantiationDependent() || + VK[I].Value->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (VK[I].EllipsisLoc.isInvalid() && + (VK[I].Key->containsUnexpandedParameterPack() || + VK[I].Value->containsUnexpandedParameterPack())) + ExprBits.ContainsUnexpandedParameterPack = true; + + KeyValues[I].Key = VK[I].Key; + KeyValues[I].Value = VK[I].Value; + if (Expansions) { + Expansions[I].EllipsisLoc = VK[I].EllipsisLoc; + if (VK[I].NumExpansions) + Expansions[I].NumExpansionsPlusOne = *VK[I].NumExpansions + 1; + else + Expansions[I].NumExpansionsPlusOne = 0; + } + } +} + +ObjCDictionaryLiteral * +ObjCDictionaryLiteral::Create(const ASTContext &C, + ArrayRef VK, + bool HasPackExpansions, QualType T, + ObjCMethodDecl *method, SourceRange SR) { + unsigned ExpansionsSize = 0; + if (HasPackExpansions) + ExpansionsSize = sizeof(ExpansionData) * VK.size(); + + void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + + sizeof(KeyValuePair) * VK.size() + ExpansionsSize); + return new (Mem) ObjCDictionaryLiteral(VK, HasPackExpansions, T, method, SR); +} + +ObjCDictionaryLiteral * +ObjCDictionaryLiteral::CreateEmpty(const ASTContext &C, unsigned NumElements, + bool HasPackExpansions) { + unsigned ExpansionsSize = 0; + if (HasPackExpansions) + ExpansionsSize = sizeof(ExpansionData) * NumElements; + void *Mem = C.Allocate(sizeof(ObjCDictionaryLiteral) + + sizeof(KeyValuePair) * NumElements + ExpansionsSize); + return new (Mem) + ObjCDictionaryLiteral(EmptyShell(), NumElements, HasPackExpansions); +} + +QualType ObjCPropertyRefExpr::getReceiverType(const ASTContext &ctx) const { + if (isClassReceiver()) + return ctx.getObjCInterfaceType(getClassReceiver()); + + if (isSuperReceiver()) + return getSuperReceiverType(); + + return getBase()->getType(); +} + +ObjCSubscriptRefExpr * +ObjCSubscriptRefExpr::Create(const ASTContext &C, Expr *base, Expr *key, + QualType T, ObjCMethodDecl *getMethod, + ObjCMethodDecl *setMethod, SourceLocation RB) { + void *Mem = C.Allocate(sizeof(ObjCSubscriptRefExpr)); + return new (Mem) ObjCSubscriptRefExpr( + base, key, T, VK_LValue, OK_ObjCSubscript, getMethod, setMethod, RB); +} + +ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, + SourceLocation LBracLoc, + SourceLocation SuperLoc, bool IsInstanceSuper, + QualType SuperType, Selector Sel, + ArrayRef SelLocs, + SelectorLocationsKind SelLocsK, + ObjCMethodDecl *Method, ArrayRef Args, + SourceLocation RBracLoc, bool isImplicit) + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/false, + /*InstantiationDependent=*/false, + /*ContainsUnexpandedParameterPack=*/false), + SelectorOrMethod( + reinterpret_cast(Method ? Method : Sel.getAsOpaquePtr())), + Kind(IsInstanceSuper ? SuperInstance : SuperClass), + HasMethod(Method != nullptr), IsDelegateInitCall(false), + IsImplicit(isImplicit), SuperLoc(SuperLoc), LBracLoc(LBracLoc), + RBracLoc(RBracLoc) { + initArgsAndSelLocs(Args, SelLocs, SelLocsK); + setReceiverPointer(SuperType.getAsOpaquePtr()); +} + +ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, + SourceLocation LBracLoc, + TypeSourceInfo *Receiver, Selector Sel, + ArrayRef SelLocs, + SelectorLocationsKind SelLocsK, + ObjCMethodDecl *Method, ArrayRef Args, + SourceLocation RBracLoc, bool isImplicit) + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), + T->isDependentType(), T->isInstantiationDependentType(), + T->containsUnexpandedParameterPack()), + SelectorOrMethod( + reinterpret_cast(Method ? Method : Sel.getAsOpaquePtr())), + Kind(Class), HasMethod(Method != nullptr), IsDelegateInitCall(false), + IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { + initArgsAndSelLocs(Args, SelLocs, SelLocsK); + setReceiverPointer(Receiver); +} + +ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprValueKind VK, + SourceLocation LBracLoc, Expr *Receiver, + Selector Sel, ArrayRef SelLocs, + SelectorLocationsKind SelLocsK, + ObjCMethodDecl *Method, ArrayRef Args, + SourceLocation RBracLoc, bool isImplicit) + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, + Receiver->isTypeDependent(), Receiver->isTypeDependent(), + Receiver->isInstantiationDependent(), + Receiver->containsUnexpandedParameterPack()), + SelectorOrMethod( + reinterpret_cast(Method ? Method : Sel.getAsOpaquePtr())), + Kind(Instance), HasMethod(Method != nullptr), IsDelegateInitCall(false), + IsImplicit(isImplicit), LBracLoc(LBracLoc), RBracLoc(RBracLoc) { + initArgsAndSelLocs(Args, SelLocs, SelLocsK); + setReceiverPointer(Receiver); +} + +void ObjCMessageExpr::initArgsAndSelLocs(ArrayRef Args, + ArrayRef SelLocs, + SelectorLocationsKind SelLocsK) { + setNumArgs(Args.size()); + Expr **MyArgs = getArgs(); + for (unsigned I = 0; I != Args.size(); ++I) { + if (Args[I]->isTypeDependent()) + ExprBits.TypeDependent = true; + if (Args[I]->isValueDependent()) + ExprBits.ValueDependent = true; + if (Args[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (Args[I]->containsUnexpandedParameterPack()) + ExprBits.ContainsUnexpandedParameterPack = true; + + MyArgs[I] = Args[I]; + } + + SelLocsKind = SelLocsK; + if (!isImplicit()) { + if (SelLocsK == SelLoc_NonStandard) + std::copy(SelLocs.begin(), SelLocs.end(), getStoredSelLocs()); + } +} + +ObjCMessageExpr * +ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, + SourceLocation LBracLoc, SourceLocation SuperLoc, + bool IsInstanceSuper, QualType SuperType, Selector Sel, + ArrayRef SelLocs, + ObjCMethodDecl *Method, ArrayRef Args, + SourceLocation RBracLoc, bool isImplicit) { + assert((!SelLocs.empty() || isImplicit) && + "No selector locs for non-implicit message"); + ObjCMessageExpr *Mem; + SelectorLocationsKind SelLocsK = SelectorLocationsKind(); + if (isImplicit) + Mem = alloc(Context, Args.size(), 0); + else + Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, + SuperType, Sel, SelLocs, SelLocsK, Method, + Args, RBracLoc, isImplicit); +} + +ObjCMessageExpr * +ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, + SourceLocation LBracLoc, TypeSourceInfo *Receiver, + Selector Sel, ArrayRef SelLocs, + ObjCMethodDecl *Method, ArrayRef Args, + SourceLocation RBracLoc, bool isImplicit) { + assert((!SelLocs.empty() || isImplicit) && + "No selector locs for non-implicit message"); + ObjCMessageExpr *Mem; + SelectorLocationsKind SelLocsK = SelectorLocationsKind(); + if (isImplicit) + Mem = alloc(Context, Args.size(), 0); + else + Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); + return new (Mem) + ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, + Args, RBracLoc, isImplicit); +} + +ObjCMessageExpr * +ObjCMessageExpr::Create(const ASTContext &Context, QualType T, ExprValueKind VK, + SourceLocation LBracLoc, Expr *Receiver, Selector Sel, + ArrayRef SelLocs, + ObjCMethodDecl *Method, ArrayRef Args, + SourceLocation RBracLoc, bool isImplicit) { + assert((!SelLocs.empty() || isImplicit) && + "No selector locs for non-implicit message"); + ObjCMessageExpr *Mem; + SelectorLocationsKind SelLocsK = SelectorLocationsKind(); + if (isImplicit) + Mem = alloc(Context, Args.size(), 0); + else + Mem = alloc(Context, Args, RBracLoc, SelLocs, Sel, SelLocsK); + return new (Mem) + ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, SelLocs, SelLocsK, Method, + Args, RBracLoc, isImplicit); +} + +ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(const ASTContext &Context, + unsigned NumArgs, + unsigned NumStoredSelLocs) { + ObjCMessageExpr *Mem = alloc(Context, NumArgs, NumStoredSelLocs); + return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs); +} + +ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, + ArrayRef Args, + SourceLocation RBraceLoc, + ArrayRef SelLocs, + Selector Sel, + SelectorLocationsKind &SelLocsK) { + SelLocsK = hasStandardSelectorLocs(Sel, SelLocs, Args, RBraceLoc); + unsigned NumStoredSelLocs = + (SelLocsK == SelLoc_NonStandard) ? SelLocs.size() : 0; + return alloc(C, Args.size(), NumStoredSelLocs); +} + +ObjCMessageExpr *ObjCMessageExpr::alloc(const ASTContext &C, unsigned NumArgs, + unsigned NumStoredSelLocs) { + unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + + NumArgs * sizeof(Expr *) + + NumStoredSelLocs * sizeof(SourceLocation); + return (ObjCMessageExpr *)C.Allocate( + Size, llvm::AlignOf::Alignment); +} + +void ObjCMessageExpr::getSelectorLocs( + SmallVectorImpl &SelLocs) const { + for (unsigned i = 0, e = getNumSelectorLocs(); i != e; ++i) + SelLocs.push_back(getSelectorLoc(i)); +} + +SourceRange ObjCMessageExpr::getReceiverRange() const { + switch (getReceiverKind()) { + case Instance: + return getInstanceReceiver()->getSourceRange(); + + case Class: + return getClassReceiverTypeInfo()->getTypeLoc().getSourceRange(); + + case SuperInstance: + case SuperClass: + return getSuperLoc(); + } + + llvm_unreachable("Invalid ReceiverKind!"); +} + +Selector ObjCMessageExpr::getSelector() const { + if (HasMethod) + return reinterpret_cast(SelectorOrMethod) + ->getSelector(); + return Selector(SelectorOrMethod); +} + +QualType ObjCMessageExpr::getReceiverType() const { + switch (getReceiverKind()) { + case Instance: + return getInstanceReceiver()->getType(); + case Class: + return getClassReceiver(); + case SuperInstance: + case SuperClass: + return getSuperType(); + } + + llvm_unreachable("unexpected receiver kind"); +} + +ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const { + QualType T = getReceiverType(); + + if (const ObjCObjectPointerType *Ptr = T->getAs()) + return Ptr->getInterfaceDecl(); + + if (const ObjCObjectType *Ty = T->getAs()) + return Ty->getInterface(); + + return nullptr; +} + +Stmt::child_range ObjCMessageExpr::children() { + Stmt **begin; + if (getReceiverKind() == Instance) + begin = reinterpret_cast(this + 1); + else + begin = reinterpret_cast(getArgs()); + return child_range(begin, + reinterpret_cast(getArgs() + getNumArgs())); +} + +StringRef ObjCBridgedCastExpr::getBridgeKindName() const { + switch (getBridgeKind()) { + case OBC_Bridge: + return "__bridge"; + case OBC_BridgeTransfer: + return "__bridge_transfer"; + case OBC_BridgeRetained: + return "__bridge_retained"; + } + + llvm_unreachable("Invalid BridgeKind!"); +} Index: lib/AST/StmtPrinter.cpp =================================================================== --- lib/AST/StmtPrinter.cpp +++ lib/AST/StmtPrinter.cpp @@ -701,6 +701,8 @@ OS << "threads"; } +void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; } + void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) { OS << "device("; Node->getDevice()->printPretty(OS, nullptr, Policy, 0); Index: lib/AST/StmtProfile.cpp =================================================================== --- lib/AST/StmtProfile.cpp +++ lib/AST/StmtProfile.cpp @@ -335,6 +335,8 @@ void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {} +void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {} + template void OMPClauseProfiler::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { Index: lib/Analysis/ThreadSafetyCommon.cpp =================================================================== --- lib/Analysis/ThreadSafetyCommon.cpp +++ lib/Analysis/ThreadSafetyCommon.cpp @@ -290,7 +290,7 @@ VD = FD->getParamDecl(I); } - // For non-local variables, treat it as a referenced to a named object. + // For non-local variables, treat it as a reference to a named object. return new (Arena) til::LiteralPtr(VD); } Index: lib/Basic/OpenMPKinds.cpp =================================================================== --- lib/Basic/OpenMPKinds.cpp +++ lib/Basic/OpenMPKinds.cpp @@ -129,6 +129,7 @@ case OMPC_seq_cst: case OMPC_device: case OMPC_threads: + case OMPC_simd: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); @@ -214,6 +215,7 @@ case OMPC_seq_cst: case OMPC_device: case OMPC_threads: + case OMPC_simd: break; } llvm_unreachable("Invalid OpenMP simple clause kind"); Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -1716,6 +1716,7 @@ class NVPTX32TargetInfo : public NVPTXTargetInfo { public: NVPTX32TargetInfo(const llvm::Triple &Triple) : NVPTXTargetInfo(Triple) { + LongWidth = LongAlign = 32; PointerWidth = PointerAlign = 32; SizeType = TargetInfo::UnsignedInt; PtrDiffType = TargetInfo::SignedInt; Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -14,6 +14,7 @@ #include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/Utils.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -455,13 +456,8 @@ llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, BackendArgs.data()); - std::string FeaturesStr; - if (!TargetOpts.Features.empty()) { - SubtargetFeatures Features; - for (const std::string &Feature : TargetOpts.Features) - Features.AddFeature(Feature); - FeaturesStr = Features.getString(); - } + std::string FeaturesStr = + llvm::join(TargetOpts.Features.begin(), TargetOpts.Features.end(), ","); // Keep this synced with the equivalent code in tools/driver/cc1as_main.cpp. llvm::Reloc::Model RM = llvm::Reloc::Default; Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -2895,16 +2895,19 @@ return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); } case NEON::BI__builtin_neon_vld1_v: - case NEON::BI__builtin_neon_vld1q_v: + case NEON::BI__builtin_neon_vld1q_v: { + llvm::Type *Tys[] = {Ty, Int8PtrTy}; Ops.push_back(getAlignmentValue32(PtrOp0)); - return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vld1"); + return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1"); + } case NEON::BI__builtin_neon_vld2_v: case NEON::BI__builtin_neon_vld2q_v: case NEON::BI__builtin_neon_vld3_v: case NEON::BI__builtin_neon_vld3q_v: case NEON::BI__builtin_neon_vld4_v: case NEON::BI__builtin_neon_vld4q_v: { - Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty); + llvm::Type *Tys[] = {Ty, Int8PtrTy}; + Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); Value *Align = getAlignmentValue32(PtrOp1); Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint); Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); @@ -2927,7 +2930,8 @@ case NEON::BI__builtin_neon_vld3q_lane_v: case NEON::BI__builtin_neon_vld4_lane_v: case NEON::BI__builtin_neon_vld4q_lane_v: { - Function *F = CGM.getIntrinsic(LLVMIntrinsic, Ty); + llvm::Type *Tys[] = {Ty, Int8PtrTy}; + Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); for (unsigned I = 2; I < Ops.size() - 1; ++I) Ops[I] = Builder.CreateBitCast(Ops[I], Ty); Ops.push_back(getAlignmentValue32(PtrOp1)); @@ -3046,9 +3050,11 @@ case NEON::BI__builtin_neon_vst3_lane_v: case NEON::BI__builtin_neon_vst3q_lane_v: case NEON::BI__builtin_neon_vst4_lane_v: - case NEON::BI__builtin_neon_vst4q_lane_v: + case NEON::BI__builtin_neon_vst4q_lane_v: { + llvm::Type *Tys[] = {Int8PtrTy, Ty}; Ops.push_back(getAlignmentValue32(PtrOp0)); - return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, ""); + return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); + } case NEON::BI__builtin_neon_vsubhn_v: { llvm::VectorType *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); @@ -3776,7 +3782,8 @@ Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); // Load the value as a one-element vector. Ty = llvm::VectorType::get(VTy->getElementType(), 1); - Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); + llvm::Type *Tys[] = {Ty, Int8PtrTy}; + Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys); Value *Align = getAlignmentValue32(PtrOp0); Value *Ld = Builder.CreateCall(F, {Ops[0], Align}); // Combine them. @@ -3808,7 +3815,8 @@ break; default: llvm_unreachable("unknown vld_dup intrinsic?"); } - Function *F = CGM.getIntrinsic(Int, Ty); + llvm::Type *Tys[] = {Ty, Int8PtrTy}; + Function *F = CGM.getIntrinsic(Int, Tys); llvm::Value *Align = getAlignmentValue32(PtrOp1); Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup"); Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); @@ -3827,7 +3835,8 @@ break; default: llvm_unreachable("unknown vld_dup intrinsic?"); } - Function *F = CGM.getIntrinsic(Int, Ty); + llvm::Type *Tys[] = {Ty, Int8PtrTy}; + Function *F = CGM.getIntrinsic(Int, Tys); llvm::StructType *STy = cast(F->getReturnType()); SmallVector Args; @@ -3902,8 +3911,9 @@ Value *SV = llvm::ConstantVector::get(cast(Ops[2])); Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); Ops[2] = getAlignmentValue32(PtrOp0); + llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()}; return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, - Ops[1]->getType()), Ops); + Tys), Ops); } // fall through case NEON::BI__builtin_neon_vst1_lane_v: { Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -2107,9 +2107,12 @@ // FIXME: If vtable is used by ctor/dtor, or if vtable is external and we are // sure that definition of vtable is not hidden, // then we are always safe to refer to it. + // FIXME: It looks like InstCombine is very inefficient on dealing with + // assumes. Make assumption loads require -fstrict-vtable-pointers temporarily. if (CGM.getCodeGenOpts().OptimizationLevel > 0 && ClassDecl->isDynamicClass() && Type != Ctor_Base && - CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl)) + CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) && + CGM.getCodeGenOpts().StrictVTablePointers) EmitVTableAssumptionLoads(ClassDecl, This); } Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -326,7 +326,7 @@ llvm::Value *storage, CGBuilderTy &Builder, const CGBlockInfo &blockInfo, - llvm::Instruction *InsertPoint = 0); + llvm::Instruction *InsertPoint = nullptr); /// Emit call to \c llvm.dbg.declare for an argument variable /// declaration. @@ -593,4 +593,4 @@ } // namespace CodeGen } // namespace clang -#endif +#endif // LLVM_CLANG_LIB_CODEGEN_CGDEBUGINFO_H Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -1680,9 +1680,9 @@ // nullptr if the "Module" is a PCH, which is safe because we don't // support chained PCH debug info, so there can only be a single PCH. const Module *M = Mod.getModuleOrNull(); - auto &ModRef = ModuleCache[M]; - if (ModRef) - return cast(ModRef); + auto ModRef = ModuleCache.find(M); + if (ModRef != ModuleCache.end()) + return cast(ModRef->second); // Macro definitions that were defined with "-D" on the command line. SmallString<128> ConfigMacros; @@ -1724,7 +1724,7 @@ llvm::DIModule *DIMod = DBuilder.createModule(Parent, Mod.getModuleName(), ConfigMacros, Mod.getPath(), CGM.getHeaderSearchOpts().Sysroot); - ModRef.reset(DIMod); + ModuleCache[M].reset(DIMod); return DIMod; } Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -814,7 +814,6 @@ // If this is an explicit bitcast, and the source l-value is // opaque, honor the alignment of the casted-to type. if (isa(CE) && - CE->getCastKind() == CK_BitCast && InnerSource != AlignmentSource::Decl) { Addr = Address(Addr.getPointer(), getNaturalPointeeTypeAlignment(E->getType(), Source)); Index: lib/CodeGen/CGExprCXX.cpp =================================================================== --- lib/CodeGen/CGExprCXX.cpp +++ lib/CodeGen/CGExprCXX.cpp @@ -1289,9 +1289,11 @@ Address allocation = Address::invalid(); CallArgList allocatorArgs; if (allocator->isReservedGlobalPlacementOperator()) { + assert(E->getNumPlacementArgs() == 1); + const Expr *arg = *E->placement_arguments().begin(); + AlignmentSource alignSource; - allocation = EmitPointerWithAlignment(*E->placement_arguments().begin(), - &alignSource); + allocation = EmitPointerWithAlignment(arg, &alignSource); // The pointer expression will, in many cases, be an opaque void*. // In these cases, discard the computed alignment and use the @@ -1301,6 +1303,14 @@ getContext().getTypeAlignInChars(allocType)); } + // Set up allocatorArgs for the call to operator delete if it's not + // the reserved global operator. + if (E->getOperatorDelete() && + !E->getOperatorDelete()->isReservedGlobalPlacementOperator()) { + allocatorArgs.add(RValue::get(allocSize), getContext().getSizeType()); + allocatorArgs.add(RValue::get(allocation.getPointer()), arg->getType()); + } + } else { const FunctionProtoType *allocatorType = allocator->getType()->castAs(); Index: lib/CodeGen/CGOpenMPRuntime.h =================================================================== --- lib/CodeGen/CGOpenMPRuntime.h +++ lib/CodeGen/CGOpenMPRuntime.h @@ -449,7 +449,7 @@ /// ordered region. virtual void emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, - SourceLocation Loc); + SourceLocation Loc, bool IsThreads); /// \brief Emit an implicit/explicit barrier for OpenMP threads. /// \param Kind Directive for which this implicit barrier call must be Index: lib/CodeGen/CGOpenMPRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenMPRuntime.cpp +++ lib/CodeGen/CGOpenMPRuntime.cpp @@ -1548,21 +1548,21 @@ void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF, const RegionCodeGenTy &OrderedOpGen, - SourceLocation Loc) { + SourceLocation Loc, bool IsThreads) { // __kmpc_ordered(ident_t *, gtid); // OrderedOpGen(); // __kmpc_end_ordered(ident_t *, gtid); // Prepare arguments and build a call to __kmpc_ordered - { - CodeGenFunction::RunCleanupsScope Scope(CGF); + CodeGenFunction::RunCleanupsScope Scope(CGF); + if (IsThreads) { llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)}; CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_ordered), Args); // Build a call to __kmpc_end_ordered CGF.EHStack.pushCleanup::value>>( NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_ordered), llvm::makeArrayRef(Args)); - emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen); } + emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen); } void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc, @@ -1894,8 +1894,7 @@ } // anonymous namespace static RecordDecl * -createPrivatesRecordDecl(CodeGenModule &CGM, - const ArrayRef Privates) { +createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef Privates) { if (!Privates.empty()) { auto &C = CGM.getContext(); // Build struct .kmp_privates_t. { @@ -1943,7 +1942,7 @@ static RecordDecl * createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy, - const ArrayRef Privates) { + ArrayRef Privates) { auto &C = CGM.getContext(); // Build struct kmp_task_t_with_privates { // kmp_task_t task_data; @@ -2092,10 +2091,10 @@ /// \endcode static llvm::Value * emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc, - const ArrayRef PrivateVars, - const ArrayRef FirstprivateVars, + ArrayRef PrivateVars, + ArrayRef FirstprivateVars, QualType PrivatesQTy, - const ArrayRef Privates) { + ArrayRef Privates) { auto &C = CGM.getContext(); FunctionArgList Args; ImplicitParamDecl TaskPrivatesArg( Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -1799,13 +1799,33 @@ }(), S.getLocStart()); } +static llvm::Function *emitOutlinedOrderedFunction(CodeGenModule &CGM, + const CapturedStmt *S) { + CodeGenFunction CGF(CGM, /*suppressNewContext=*/true); + CodeGenFunction::CGCapturedStmtInfo CapStmtInfo; + CGF.CapturedStmtInfo = &CapStmtInfo; + auto *Fn = CGF.GenerateOpenMPCapturedStmtFunction(*S); + Fn->addFnAttr(llvm::Attribute::NoInline); + return Fn; +} + void CodeGenFunction::EmitOMPOrderedDirective(const OMPOrderedDirective &S) { LexicalScope Scope(*this, S.getSourceRange()); - auto &&CodeGen = [&S](CodeGenFunction &CGF) { - CGF.EmitStmt(cast(S.getAssociatedStmt())->getCapturedStmt()); + auto *C = S.getSingleClause(); + auto &&CodeGen = [&S, C, this](CodeGenFunction &CGF) { + if (C) { + auto CS = cast(S.getAssociatedStmt()); + llvm::SmallVector CapturedVars; + CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars); + auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS); + CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars); + } else { + CGF.EmitStmt( + cast(S.getAssociatedStmt())->getCapturedStmt()); + } CGF.EnsureInsertPoint(); }; - CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart()); + CGM.getOpenMPRuntime().emitOrderedRegion(*this, CodeGen, S.getLocStart(), !C); } static llvm::Value *convertToScalarValue(CodeGenFunction &CGF, RValue Val, @@ -2210,6 +2230,7 @@ case OMPC_mergeable: case OMPC_device: case OMPC_threads: + case OMPC_simd: llvm_unreachable("Clause is not allowed in 'omp atomic'."); } } Index: lib/CodeGen/CodeGenABITypes.cpp =================================================================== --- lib/CodeGen/CodeGenABITypes.cpp +++ lib/CodeGen/CodeGenABITypes.cpp @@ -33,12 +33,6 @@ CGM(new CodeGen::CodeGenModule(C, *HSO, *PPO, *CGO, M, C.getDiagnostics(), CoverageInfo)) {} -CodeGenABITypes::~CodeGenABITypes() -{ - delete CGO; - delete CGM; -} - const CGFunctionInfo & CodeGenABITypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, QualType receiverType) { Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -715,7 +715,7 @@ /// Return the address of the given function. If Ty is non-null, then this /// function will use the specified type if it has to create it. - llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = 0, + llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr, bool ForVTable = false, bool DontDefer = false, bool IsForDefinition = false); @@ -1184,7 +1184,7 @@ // FIXME: Hardcoding priority here is gross. void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, - llvm::Constant *AssociatedData = 0); + llvm::Constant *AssociatedData = nullptr); void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535); /// Generates a global array of functions and priorities using the given list @@ -1251,4 +1251,4 @@ } // end namespace CodeGen } // end namespace clang -#endif +#endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2825,7 +2825,7 @@ // String pointer. llvm::Constant *C = nullptr; if (isUTF16) { - ArrayRef Arr = llvm::makeArrayRef( + auto Arr = llvm::makeArrayRef( reinterpret_cast(const_cast(Entry.first().data())), Entry.first().size() / 2); C = llvm::ConstantDataArray::get(VMContext, Arr); Index: lib/CodeGen/CoverageMappingGen.cpp =================================================================== --- lib/CodeGen/CoverageMappingGen.cpp +++ lib/CodeGen/CoverageMappingGen.cpp @@ -47,17 +47,6 @@ Optional LocEnd) : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {} - SourceMappingRegion(SourceMappingRegion &&Region) - : Count(std::move(Region.Count)), LocStart(std::move(Region.LocStart)), - LocEnd(std::move(Region.LocEnd)) {} - - SourceMappingRegion &operator=(SourceMappingRegion &&RHS) { - Count = std::move(RHS.Count); - LocStart = std::move(RHS.LocStart); - LocEnd = std::move(RHS.LocEnd); - return *this; - } - const Counter &getCounter() const { return Count; } void setCounter(Counter C) { Count = C; } @@ -66,7 +55,7 @@ void setStartLoc(SourceLocation Loc) { LocStart = Loc; } - const SourceLocation &getStartLoc() const { + SourceLocation getStartLoc() const { assert(LocStart && "Region has no start location"); return *LocStart; } @@ -75,7 +64,7 @@ void setEndLoc(SourceLocation Loc) { LocEnd = Loc; } - const SourceLocation &getEndLoc() const { + SourceLocation getEndLoc() const { assert(LocEnd && "Region has no end location"); return *LocEnd; } @@ -426,7 +415,7 @@ MostRecentLocation = getIncludeOrExpansionLoc(EndLoc); assert(SM.isWrittenInSameFile(Region.getStartLoc(), EndLoc)); - SourceRegions.push_back(std::move(Region)); + SourceRegions.push_back(Region); } RegionStack.pop_back(); } Index: lib/CodeGen/TargetInfo.h =================================================================== --- lib/CodeGen/TargetInfo.h +++ lib/CodeGen/TargetInfo.h @@ -47,7 +47,7 @@ public: // WARNING: Acquires the ownership of ABIInfo. - TargetCodeGenInfo(ABIInfo *info = 0) : Info(info) {} + TargetCodeGenInfo(ABIInfo *info = nullptr) : Info(info) {} virtual ~TargetCodeGenInfo(); /// getABIInfo() - Returns ABI info helper for the target. @@ -219,6 +219,6 @@ llvm::StringRef Value, llvm::SmallString<32> &Opt) const {} }; -} +} // namespace clang -#endif +#endif // LLVM_CLANG_LIB_CODEGEN_TARGETINFO_H Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -609,12 +609,13 @@ if (TC.getTriple().isOSWindows() && needsUbsanRt()) { // Instruct the code generator to embed linker directives in the object file // that cause the required runtime libraries to be linked. - CmdArgs.push_back(Args.MakeArgString( - "--dependent-lib=" + tools::getCompilerRT(TC, "ubsan_standalone"))); + CmdArgs.push_back( + Args.MakeArgString("--dependent-lib=" + + tools::getCompilerRT(TC, Args, "ubsan_standalone"))); if (types::isCXX(InputType)) - CmdArgs.push_back( - Args.MakeArgString("--dependent-lib=" + - tools::getCompilerRT(TC, "ubsan_standalone_cxx"))); + CmdArgs.push_back(Args.MakeArgString( + "--dependent-lib=" + + tools::getCompilerRT(TC, Args, "ubsan_standalone_cxx"))); } } Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -22,6 +22,7 @@ #include "llvm/Option/Option.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/TargetRegistry.h" using namespace clang::driver; using namespace clang; using namespace llvm::opt; @@ -88,6 +89,99 @@ return *SanitizerArguments.get(); } +namespace { +struct DriverSuffix { + const char *Suffix; + const char *ModeFlag; +}; + +const DriverSuffix *FindDriverSuffix(StringRef ProgName) { + // A list of known driver suffixes. Suffixes are compared against the + // program name in order. If there is a match, the frontend type is updated as + // necessary by applying the ModeFlag. + static const DriverSuffix DriverSuffixes[] = { + {"clang", nullptr}, + {"clang++", "--driver-mode=g++"}, + {"clang-c++", "--driver-mode=g++"}, + {"clang-cc", nullptr}, + {"clang-cpp", "--driver-mode=cpp"}, + {"clang-g++", "--driver-mode=g++"}, + {"clang-gcc", nullptr}, + {"clang-cl", "--driver-mode=cl"}, + {"cc", nullptr}, + {"cpp", "--driver-mode=cpp"}, + {"cl", "--driver-mode=cl"}, + {"++", "--driver-mode=g++"}, + }; + + for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) + if (ProgName.endswith(DriverSuffixes[i].Suffix)) + return &DriverSuffixes[i]; + return nullptr; +} + +/// Normalize the program name from argv[0] by stripping the file extension if +/// present and lower-casing the string on Windows. +std::string normalizeProgramName(llvm::StringRef Argv0) { + std::string ProgName = llvm::sys::path::stem(Argv0); +#ifdef LLVM_ON_WIN32 + // Transform to lowercase for case insensitive file systems. + std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower); +#endif + return ProgName; +} + +const DriverSuffix *parseDriverSuffix(StringRef ProgName) { + // Try to infer frontend type and default target from the program name by + // comparing it against DriverSuffixes in order. + + // If there is a match, the function tries to identify a target as prefix. + // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target + // prefix "x86_64-linux". If such a target prefix is found, it may be + // added via -target as implicit first argument. + const DriverSuffix *DS = FindDriverSuffix(ProgName); + + if (!DS) { + // Try again after stripping any trailing version number: + // clang++3.5 -> clang++ + ProgName = ProgName.rtrim("0123456789."); + DS = FindDriverSuffix(ProgName); + } + + if (!DS) { + // Try again after stripping trailing -component. + // clang++-tot -> clang++ + ProgName = ProgName.slice(0, ProgName.rfind('-')); + DS = FindDriverSuffix(ProgName); + } + return DS; +} +} // anonymous namespace + +std::pair +ToolChain::getTargetAndModeFromProgramName(StringRef PN) { + std::string ProgName = normalizeProgramName(PN); + const DriverSuffix *DS = parseDriverSuffix(ProgName); + if (!DS) + return std::make_pair("", ""); + std::string ModeFlag = DS->ModeFlag == nullptr ? "" : DS->ModeFlag; + + std::string::size_type LastComponent = + ProgName.rfind('-', ProgName.size() - strlen(DS->Suffix)); + if (LastComponent == std::string::npos) + return std::make_pair("", ModeFlag); + + // Infer target from the prefix. + StringRef Prefix(ProgName); + Prefix = Prefix.slice(0, LastComponent); + std::string IgnoredError; + std::string Target; + if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { + Target = Prefix; + } + return std::make_pair(Target, ModeFlag); +} + StringRef ToolChain::getDefaultUniversalArchName() const { // In universal driver terms, the arch name accepted by -arch isn't exactly // the same as the ones that appear in the triple. Roughly speaking, this is Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -37,8 +37,9 @@ using llvm::opt::ArgStringList; -SmallString<128> getCompilerRT(const ToolChain &TC, StringRef Component, - bool Shared = false); +SmallString<128> getCompilerRT(const ToolChain &TC, + const llvm::opt::ArgList &Args, + StringRef Component, bool Shared = false); /// \brief Clang compiler tool. class LLVM_LIBRARY_VISIBILITY Clang : public Tool { Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -2403,12 +2403,19 @@ } // Until ARM libraries are build separately, we have them all in one library -static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) { - if (TC.getTriple().isWindowsMSVCEnvironment() && - TC.getArch() == llvm::Triple::x86) +static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, + const ArgList &Args) { + const llvm::Triple &Triple = TC.getTriple(); + bool IsWindows = Triple.isOSWindows(); + + if (Triple.isWindowsMSVCEnvironment() && TC.getArch() == llvm::Triple::x86) return "i386"; + if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) - return "arm"; + return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows) + ? "armhf" + : "arm"; + return TC.getArchName(); } @@ -2423,8 +2430,8 @@ return Res; } -SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component, - bool Shared) { +SmallString<128> tools::getCompilerRT(const ToolChain &TC, const ArgList &Args, + StringRef Component, bool Shared) { const char *Env = TC.getTriple().getEnvironment() == llvm::Triple::Android ? "-android" : ""; @@ -2432,7 +2439,7 @@ bool IsOSWindows = TC.getTriple().isOSWindows(); bool IsITANMSVCWindows = TC.getTriple().isWindowsMSVCEnvironment() || TC.getTriple().isWindowsItaniumEnvironment(); - StringRef Arch = getArchNameForCompilerRTLib(TC); + StringRef Arch = getArchNameForCompilerRTLib(TC, Args); const char *Prefix = IsITANMSVCWindows ? "" : "lib"; const char *Suffix = Shared ? (IsOSWindows ? ".dll" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a"); @@ -2444,12 +2451,19 @@ return Path; } +static const char *getCompilerRTArgString(const ToolChain &TC, + const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared = false) { + return Args.MakeArgString(getCompilerRT(TC, Args, Component, Shared)); +} + // This adds the static libclang_rt.builtins-arch.a directly to the command line // FIXME: Make sure we can also emit shared objects if they're requested // and available, check for possible errors, etc. static void addClangRT(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "builtins"))); + CmdArgs.push_back(getCompilerRTArgString(TC, Args, "builtins")); } static void addProfileRT(const ToolChain &TC, const ArgList &Args, @@ -2464,7 +2478,7 @@ Args.hasArg(options::OPT_coverage))) return; - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, "profile"))); + CmdArgs.push_back(getCompilerRTArgString(TC, Args, "profile")); } namespace { @@ -2545,7 +2559,7 @@ // whole-archive. if (!IsShared) CmdArgs.push_back("-whole-archive"); - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Sanitizer, IsShared))); + CmdArgs.push_back(getCompilerRTArgString(TC, Args, Sanitizer, IsShared)); if (!IsShared) CmdArgs.push_back("-no-whole-archive"); } @@ -2555,7 +2569,7 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer) { - SmallString<128> SanRT = getCompilerRT(TC, Sanitizer); + SmallString<128> SanRT = getCompilerRT(TC, Args, Sanitizer); if (llvm::sys::fs::exists(SanRT + ".syms")) { CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms")); return true; @@ -9016,19 +9030,18 @@ "asan_dynamic", "asan_dynamic_runtime_thunk", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component))); + CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component)); // Make sure the dynamic runtime thunk is not optimized out at link time // to ensure proper SEH handling. CmdArgs.push_back(Args.MakeArgString("-include:___asan_seh_interceptor")); } else if (DLL) { - CmdArgs.push_back( - Args.MakeArgString(getCompilerRT(TC, "asan_dll_thunk"))); + CmdArgs.push_back(getCompilerRTArgString(TC, Args, "asan_dll_thunk")); } else { static const char *CompilerRTComponents[] = { "asan", "asan_cxx", }; for (const auto &Component : CompilerRTComponents) - CmdArgs.push_back(Args.MakeArgString(getCompilerRT(TC, Component))); + CmdArgs.push_back(getCompilerRTArgString(TC, Args, Component)); } } Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -13,6 +13,7 @@ /// //===----------------------------------------------------------------------===// +#include "clang/Format/Format.h" #include "ContinuationIndenter.h" #include "TokenAnnotator.h" #include "UnwrappedLineFormatter.h" @@ -21,7 +22,6 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/SourceManager.h" -#include "clang/Format/Format.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Allocator.h" @@ -99,11 +99,14 @@ IO.enumCase(Value, "Allman", FormatStyle::BS_Allman); IO.enumCase(Value, "GNU", FormatStyle::BS_GNU); IO.enumCase(Value, "WebKit", FormatStyle::BS_WebKit); + IO.enumCase(Value, "Custom", FormatStyle::BS_Custom); } }; -template <> struct ScalarEnumerationTraits { - static void enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) { +template <> +struct ScalarEnumerationTraits { + static void + enumeration(IO &IO, FormatStyle::DefinitionReturnTypeBreakingStyle &Value) { IO.enumCase(Value, "None", FormatStyle::DRTBS_None); IO.enumCase(Value, "All", FormatStyle::DRTBS_All); IO.enumCase(Value, "TopLevel", FormatStyle::DRTBS_TopLevel); @@ -198,6 +201,8 @@ IO.mapOptional("AlignAfterOpenBracket", Style.AlignAfterOpenBracket); IO.mapOptional("AlignConsecutiveAssignments", Style.AlignConsecutiveAssignments); + IO.mapOptional("AlignConsecutiveDeclarations", + Style.AlignConsecutiveDeclarations); IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft); IO.mapOptional("AlignOperands", Style.AlignOperands); IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments); @@ -221,6 +226,7 @@ Style.AlwaysBreakTemplateDeclarations); IO.mapOptional("BinPackArguments", Style.BinPackArguments); IO.mapOptional("BinPackParameters", Style.BinPackParameters); + IO.mapOptional("BraceWrapping", Style.BraceWrapping); IO.mapOptional("BreakBeforeBinaryOperators", Style.BreakBeforeBinaryOperators); IO.mapOptional("BreakBeforeBraces", Style.BreakBeforeBraces); @@ -285,6 +291,22 @@ } }; +template <> struct MappingTraits { + static void mapping(IO &IO, FormatStyle::BraceWrappingFlags &Wrapping) { + IO.mapOptional("AfterClass", Wrapping.AfterClass); + IO.mapOptional("AfterControlStatement", Wrapping.AfterControlStatement); + IO.mapOptional("AfterEnum", Wrapping.AfterEnum); + IO.mapOptional("AfterFunction", Wrapping.AfterFunction); + IO.mapOptional("AfterNamespace", Wrapping.AfterNamespace); + IO.mapOptional("AfterObjCDeclaration", Wrapping.AfterObjCDeclaration); + IO.mapOptional("AfterStruct", Wrapping.AfterStruct); + IO.mapOptional("AfterUnion", Wrapping.AfterUnion); + IO.mapOptional("BeforeCatch", Wrapping.BeforeCatch); + IO.mapOptional("BeforeElse", Wrapping.BeforeElse); + IO.mapOptional("IndentBraces", Wrapping.IndentBraces); + } +}; + // Allows to read vector while keeping default values. // IO.getContext() should contain a pointer to the FormatStyle structure, that // will be used to get default values for missing keys. @@ -340,6 +362,53 @@ llvm_unreachable("unexpected parse error"); } +static FormatStyle expandPresets(const FormatStyle &Style) { + FormatStyle Expanded = Style; + Expanded.BraceWrapping = {false, false, false, false, false, false, + false, false, false, false, false}; + switch (Style.BreakBeforeBraces) { + case FormatStyle::BS_Linux: + Expanded.BraceWrapping.AfterClass = true; + Expanded.BraceWrapping.AfterFunction = true; + Expanded.BraceWrapping.AfterNamespace = true; + Expanded.BraceWrapping.BeforeElse = true; + break; + case FormatStyle::BS_Mozilla: + Expanded.BraceWrapping.AfterClass = true; + Expanded.BraceWrapping.AfterEnum = true; + Expanded.BraceWrapping.AfterFunction = true; + Expanded.BraceWrapping.AfterStruct = true; + Expanded.BraceWrapping.AfterUnion = true; + break; + case FormatStyle::BS_Stroustrup: + Expanded.BraceWrapping.AfterFunction = true; + Expanded.BraceWrapping.BeforeCatch = true; + Expanded.BraceWrapping.BeforeElse = true; + break; + case FormatStyle::BS_Allman: + Expanded.BraceWrapping.AfterClass = true; + Expanded.BraceWrapping.AfterControlStatement = true; + Expanded.BraceWrapping.AfterEnum = true; + Expanded.BraceWrapping.AfterFunction = true; + Expanded.BraceWrapping.AfterNamespace = true; + Expanded.BraceWrapping.AfterObjCDeclaration = true; + Expanded.BraceWrapping.AfterStruct = true; + Expanded.BraceWrapping.BeforeCatch = true; + Expanded.BraceWrapping.BeforeElse = true; + break; + case FormatStyle::BS_GNU: + Expanded.BraceWrapping = {true, true, true, true, true, true, + true, true, true, true, true}; + break; + case FormatStyle::BS_WebKit: + Expanded.BraceWrapping.AfterFunction = true; + break; + default: + break; + } + return Expanded; +} + FormatStyle getLLVMStyle() { FormatStyle LLVMStyle; LLVMStyle.Language = FormatStyle::LK_Cpp; @@ -349,6 +418,7 @@ LLVMStyle.AlignOperands = true; LLVMStyle.AlignTrailingComments = true; LLVMStyle.AlignConsecutiveAssignments = false; + LLVMStyle.AlignConsecutiveDeclarations = false; LLVMStyle.AllowAllParametersOfDeclarationOnNextLine = true; LLVMStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; LLVMStyle.AllowShortBlocksOnASingleLine = false; @@ -375,6 +445,9 @@ LLVMStyle.ForEachMacros.push_back("foreach"); LLVMStyle.ForEachMacros.push_back("Q_FOREACH"); LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH"); + LLVMStyle.IncludeCategories = {{"^\"(llvm|llvm-c|clang|clang-c)/", 2}, + {"^(<|\"(gtest|isl|json)/)", 3}, + {".*", 1}}; LLVMStyle.IndentCaseLabels = false; LLVMStyle.IndentWrappedFunctionNames = false; LLVMStyle.IndentWidth = 2; @@ -423,6 +496,7 @@ GoogleStyle.AlwaysBreakTemplateDeclarations = true; GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true; GoogleStyle.DerivePointerAlignment = true; + GoogleStyle.IncludeCategories = {{"^<.*\\.h>", 1}, {"^<.*", 2}, {".*", 3}}; GoogleStyle.IndentCaseLabels = true; GoogleStyle.KeepEmptyLinesAtTheStartOfBlocks = false; GoogleStyle.ObjCSpaceAfterProperty = false; @@ -611,7 +685,7 @@ llvm::yaml::Output Output(Stream); // We use the same mapping method for input and output, so we need a non-const // reference here. - FormatStyle NonConstStyle = Style; + FormatStyle NonConstStyle = expandPresets(Style); Output << NonConstStyle; return Stream.str(); } @@ -1575,7 +1649,7 @@ StringRef Filename; StringRef Text; unsigned Offset; - bool IsAngled; + unsigned Category; }; } // end anonymous namespace @@ -1605,7 +1679,8 @@ for (unsigned i = 0, e = Includes.size(); i != e; ++i) Indices.push_back(i); std::sort(Indices.begin(), Indices.end(), [&](unsigned LHSI, unsigned RHSI) { - return Includes[LHSI].Filename < Includes[RHSI].Filename; + return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) < + std::tie(Includes[RHSI].Category, Includes[RHSI].Filename); }); // If the #includes are out of order, we generate a single replacement fixing @@ -1642,22 +1717,49 @@ tooling::Replacements Replaces; unsigned Prev = 0; unsigned SearchFrom = 0; - llvm::Regex IncludeRegex(R"(^[\t\ ]*#[\t\ ]*include[^"<]*["<]([^">]*)([">]))"); + llvm::Regex IncludeRegex( + R"(^[\t\ ]*#[\t\ ]*include[^"<]*(["<][^">]*[">]))"); SmallVector Matches; SmallVector IncludesInBlock; + + // In compiled files, consider the first #include to be the main #include of + // the file if it is not a system #include. This ensures that the header + // doesn't have hidden dependencies + // (http://llvm.org/docs/CodingStandards.html#include-style). + // + // FIXME: Do some sanity checking, e.g. edit distance of the base name, to fix + // cases where the first #include is unlikely to be the main header. + bool LookForMainHeader = FileName.endswith(".c") || + FileName.endswith(".cc") || + FileName.endswith(".cpp")|| + FileName.endswith(".c++")|| + FileName.endswith(".cxx"); + + // Create pre-compiled regular expressions for the #include categories. + SmallVector CategoryRegexs; + for (const auto &IncludeBlock : Style.IncludeCategories) + CategoryRegexs.emplace_back(IncludeBlock.first); + for (;;) { auto Pos = Code.find('\n', SearchFrom); StringRef Line = Code.substr(Prev, (Pos != StringRef::npos ? Pos : Code.size()) - Prev); if (!Line.endswith("\\")) { if (IncludeRegex.match(Line, &Matches)) { - bool IsAngled = Matches[2] == ">"; - if (!IncludesInBlock.empty() && - IsAngled != IncludesInBlock.back().IsAngled) { - sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces); - IncludesInBlock.clear(); + unsigned Category; + if (LookForMainHeader && !Matches[1].startswith("<")) { + Category = 0; + } else { + Category = UINT_MAX; + for (unsigned i = 0, e = CategoryRegexs.size(); i != e; ++i) { + if (CategoryRegexs[i].match(Matches[1])) { + Category = Style.IncludeCategories[i].second; + break; + } + } } - IncludesInBlock.push_back({Matches[1], Line, Prev, Matches[2] == ">"}); + LookForMainHeader = false; + IncludesInBlock.push_back({Matches[1], Line, Prev, Category}); } else if (!IncludesInBlock.empty()) { sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces); IncludesInBlock.clear(); @@ -1677,9 +1779,10 @@ SourceManager &SourceMgr, FileID ID, ArrayRef Ranges, bool *IncompleteFormat) { - if (Style.DisableFormat) + FormatStyle Expanded = expandPresets(Style); + if (Expanded.DisableFormat) return tooling::Replacements(); - Formatter formatter(Style, SourceMgr, ID, Ranges); + Formatter formatter(Expanded, SourceMgr, ID, Ranges); return formatter.format(IncompleteFormat); } Index: lib/Format/FormatToken.h =================================================================== --- lib/Format/FormatToken.h +++ lib/Format/FormatToken.h @@ -536,6 +536,7 @@ kw_finally = &IdentTable.get("finally"); kw_function = &IdentTable.get("function"); kw_import = &IdentTable.get("import"); + kw_let = &IdentTable.get("let"); kw_var = &IdentTable.get("var"); kw_abstract = &IdentTable.get("abstract"); @@ -577,6 +578,7 @@ IdentifierInfo *kw_finally; IdentifierInfo *kw_function; IdentifierInfo *kw_import; + IdentifierInfo *kw_let; IdentifierInfo *kw_var; // Java keywords. Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -374,7 +374,7 @@ FormatToken *Previous = CurrentToken->getPreviousNonComment(); if ((CurrentToken->is(tok::colon) || Style.Language == FormatStyle::LK_Proto) && - Previous->is(tok::identifier)) + Previous->Tok.getIdentifierInfo()) Previous->Type = TT_SelectorName; if (CurrentToken->is(tok::colon) || Style.Language == FormatStyle::LK_JavaScript) @@ -1951,7 +1951,7 @@ Left.isOneOf(Keywords.kw_returns, Keywords.kw_option)) return true; } else if (Style.Language == FormatStyle::LK_JavaScript) { - if (Left.isOneOf(Keywords.kw_var, TT_JsFatArrow)) + if (Left.isOneOf(Keywords.kw_let, Keywords.kw_var, TT_JsFatArrow)) return true; if (Right.isOneOf(TT_JsTypeColon, TT_JsTypeOptionalQuestion)) return false; @@ -2082,8 +2082,9 @@ Left.Previous && Left.Previous->is(tok::equal) && Line.First->isOneOf(tok::identifier, Keywords.kw_import, tok::kw_export, tok::kw_const) && - // kw_var is a pseudo-token that's a tok::identifier, so matches above. - !Line.startsWith(Keywords.kw_var)) + // kw_var/kw_let are pseudo-tokens that are tok::identifier, so match + // above. + !Line.First->isOneOf(Keywords.kw_var, Keywords.kw_let)) // Object literals on the top level of a file are treated as "enum-style". // Each key/value pair is put on a separate line, instead of bin-packing. return true; @@ -2157,10 +2158,9 @@ if (Right.is(TT_InlineASMBrace)) return Right.HasUnescapedNewline; if (isAllmanBrace(Left) || isAllmanBrace(Right)) - return Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU || - (Style.BreakBeforeBraces == FormatStyle::BS_Mozilla && - Line.startsWith(tok::kw_enum)); + return (Line.startsWith(tok::kw_enum) && Style.BraceWrapping.AfterEnum) || + (Line.startsWith(tok::kw_class) && Style.BraceWrapping.AfterClass) || + (Line.startsWith(tok::kw_struct) && Style.BraceWrapping.AfterStruct); if (Style.Language == FormatStyle::LK_Proto && Left.isNot(tok::l_brace) && Right.is(TT_SelectorName)) return true; Index: lib/Format/UnwrappedLineFormatter.cpp =================================================================== --- lib/Format/UnwrappedLineFormatter.cpp +++ lib/Format/UnwrappedLineFormatter.cpp @@ -199,12 +199,12 @@ return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; } if (TheLine->Last->is(tok::l_brace)) { - return Style.BreakBeforeBraces == FormatStyle::BS_Attach + return !Style.BraceWrapping.AfterFunction ? tryMergeSimpleBlock(I, E, Limit) : 0; } if (I[1]->First->is(TT_FunctionLBrace) && - Style.BreakBeforeBraces != FormatStyle::BS_Attach) { + Style.BraceWrapping.AfterFunction) { if (I[1]->Last->is(TT_LineComment)) return 0; @@ -263,8 +263,7 @@ SmallVectorImpl::const_iterator E, unsigned Limit) { if (Limit == 0) return 0; - if ((Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU) && + if (Style.BraceWrapping.AfterControlStatement && (I[1]->First->is(tok::l_brace) && !Style.AllowShortBlocksOnASingleLine)) return 0; if (I[1]->InPPDirective != (*I)->InPPDirective || Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -154,12 +154,10 @@ CompoundStatementIndenter(UnwrappedLineParser *Parser, const FormatStyle &Style, unsigned &LineLevel) : LineLevel(LineLevel), OldLineLevel(LineLevel) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman) { - Parser->addUnwrappedLine(); - } else if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) { + if (Style.BraceWrapping.AfterControlStatement) Parser->addUnwrappedLine(); + if (Style.BraceWrapping.IndentBraces) ++LineLevel; - } } ~CompoundStatementIndenter() { LineLevel = OldLineLevel; } @@ -456,17 +454,15 @@ static bool ShouldBreakBeforeBrace(const FormatStyle &Style, const FormatToken &InitialToken) { - switch (Style.BreakBeforeBraces) { - case FormatStyle::BS_Linux: - return InitialToken.isOneOf(tok::kw_namespace, tok::kw_class); - case FormatStyle::BS_Mozilla: - return InitialToken.isOneOf(tok::kw_class, tok::kw_struct, tok::kw_union); - case FormatStyle::BS_Allman: - case FormatStyle::BS_GNU: - return true; - default: - return false; - } + if (InitialToken.is(tok::kw_namespace)) + return Style.BraceWrapping.AfterNamespace; + if (InitialToken.is(tok::kw_class)) + return Style.BraceWrapping.AfterClass; + if (InitialToken.is(tok::kw_union)) + return Style.BraceWrapping.AfterUnion; + if (InitialToken.is(tok::kw_struct)) + return Style.BraceWrapping.AfterStruct; + return false; } void UnwrappedLineParser::parseChildBlock() { @@ -681,8 +677,7 @@ case tok::objc_autoreleasepool: nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU) + if (Style.BraceWrapping.AfterObjCDeclaration) addUnwrappedLine(); parseBlock(/*MustBeDeclaration=*/false); } @@ -844,6 +839,11 @@ if (Style.Language == FormatStyle::LK_Java && FormatTok && FormatTok->is(tok::kw_class)) nextToken(); + if (Style.Language == FormatStyle::LK_JavaScript && FormatTok && + FormatTok->Tok.getIdentifierInfo()) + // JavaScript only has pseudo keywords, all keywords are allowed to + // appear in "IdentifierName" positions. See http://es5.github.io/#x7.6 + nextToken(); break; case tok::semi: nextToken(); @@ -871,7 +871,7 @@ // structural element. // FIXME: Figure out cases where this is not true, and add projections // for them (the one we know is missing are lambdas). - if (Style.BreakBeforeBraces != FormatStyle::BS_Attach) + if (Style.BraceWrapping.AfterFunction) addUnwrappedLine(); FormatTok->Type = TT_FunctionLBrace; parseBlock(/*MustBeDeclaration=*/false); @@ -1259,12 +1259,10 @@ if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU) { + if (Style.BraceWrapping.BeforeElse) addUnwrappedLine(); - } else { + else NeedsUnwrappedLine = true; - } } else { addUnwrappedLine(); ++Line->Level; @@ -1272,8 +1270,6 @@ --Line->Level; } if (FormatTok->Tok.is(tok::kw_else)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) - addUnwrappedLine(); nextToken(); if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); @@ -1314,9 +1310,7 @@ if (FormatTok->is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU || - Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) { + if (Style.BraceWrapping.BeforeCatch) { addUnwrappedLine(); } else { NeedsUnwrappedLine = true; @@ -1354,17 +1348,13 @@ NeedsUnwrappedLine = false; CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU || - Style.BreakBeforeBraces == FormatStyle::BS_Stroustrup) { + if (Style.BraceWrapping.BeforeCatch) addUnwrappedLine(); - } else { + else NeedsUnwrappedLine = true; - } } - if (NeedsUnwrappedLine) { + if (NeedsUnwrappedLine) addUnwrappedLine(); - } } void UnwrappedLineParser::parseNamespace() { @@ -1440,7 +1430,7 @@ if (FormatTok->Tok.is(tok::l_brace)) { CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); - if (Style.BreakBeforeBraces == FormatStyle::BS_GNU) + if (Style.BraceWrapping.IndentBraces) addUnwrappedLine(); } else { addUnwrappedLine(); @@ -1468,11 +1458,8 @@ CompoundStatementIndenter Indenter(this, Style, Line->Level); parseBlock(/*MustBeDeclaration=*/false); if (FormatTok->Tok.is(tok::kw_break)) { - // "break;" after "}" on its own line only for BS_Allman and BS_GNU - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU) { + if (Style.BraceWrapping.AfterControlStatement) addUnwrappedLine(); - } parseStructuralElement(); } addUnwrappedLine(); @@ -1736,8 +1723,7 @@ parseObjCProtocolList(); if (FormatTok->Tok.is(tok::l_brace)) { - if (Style.BreakBeforeBraces == FormatStyle::BS_Allman || - Style.BreakBeforeBraces == FormatStyle::BS_GNU) + if (Style.BraceWrapping.AfterObjCDeclaration) addUnwrappedLine(); parseBlock(/*MustBeDeclaration=*/true); } @@ -1782,7 +1768,7 @@ } if (FormatTok->isOneOf(tok::kw_const, tok::kw_class, tok::kw_enum, - Keywords.kw_var)) + Keywords.kw_let, Keywords.kw_var)) return; // Fall through to parsing the corresponding structure. if (FormatTok->is(tok::l_brace)) { Index: lib/Format/WhitespaceManager.h =================================================================== --- lib/Format/WhitespaceManager.h +++ lib/Format/WhitespaceManager.h @@ -110,7 +110,7 @@ unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn, unsigned NewlinesBefore, StringRef PreviousLinePostfix, StringRef CurrentLinePrefix, tok::TokenKind Kind, - bool ContinuesPPDirective); + bool ContinuesPPDirective, bool IsStartOfDeclName); bool CreateReplacement; // Changes might be in the middle of a token, so we cannot just keep the @@ -126,6 +126,7 @@ // the \c BreakableToken is still doing its own alignment. tok::TokenKind Kind; bool ContinuesPPDirective; + bool IsStartOfDeclName; // The number of nested blocks the token is in. This is used to add tabs // only for the indentation, and not for alignment, when @@ -173,6 +174,14 @@ void alignConsecutiveAssignments(unsigned Start, unsigned End, unsigned Column); + /// \brief Align consecutive declarations over all \c Changes. + void alignConsecutiveDeclarations(); + + /// \brief Align consecutive declarations from change \p Start to change \p + /// End at the specified \p Column. + void alignConsecutiveDeclarations(unsigned Start, unsigned End, + unsigned Column); + /// \brief Align trailing comments over all \c Changes. void alignTrailingComments(); Index: lib/Format/WhitespaceManager.cpp =================================================================== --- lib/Format/WhitespaceManager.cpp +++ lib/Format/WhitespaceManager.cpp @@ -29,13 +29,15 @@ bool CreateReplacement, const SourceRange &OriginalWhitespaceRange, unsigned IndentLevel, int Spaces, unsigned StartOfTokenColumn, unsigned NewlinesBefore, StringRef PreviousLinePostfix, - StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective) + StringRef CurrentLinePrefix, tok::TokenKind Kind, bool ContinuesPPDirective, + bool IsStartOfDeclName) : CreateReplacement(CreateReplacement), OriginalWhitespaceRange(OriginalWhitespaceRange), StartOfTokenColumn(StartOfTokenColumn), NewlinesBefore(NewlinesBefore), PreviousLinePostfix(PreviousLinePostfix), CurrentLinePrefix(CurrentLinePrefix), Kind(Kind), - ContinuesPPDirective(ContinuesPPDirective), IndentLevel(IndentLevel), + ContinuesPPDirective(ContinuesPPDirective), + IsStartOfDeclName(IsStartOfDeclName), IndentLevel(IndentLevel), Spaces(Spaces), IsTrailingComment(false), TokenLength(0), PreviousEndOfTokenColumn(0), EscapedNewlineColumn(0), StartOfBlockComment(nullptr), IndentationOffset(0) {} @@ -52,19 +54,21 @@ if (Tok.Finalized) return; Tok.Decision = (Newlines > 0) ? FD_Break : FD_Continue; - Changes.push_back(Change(true, Tok.WhitespaceRange, IndentLevel, Spaces, - StartOfTokenColumn, Newlines, "", "", - Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst)); + Changes.push_back( + Change(true, Tok.WhitespaceRange, IndentLevel, Spaces, StartOfTokenColumn, + Newlines, "", "", Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst, + Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName))); } void WhitespaceManager::addUntouchableToken(const FormatToken &Tok, bool InPPDirective) { if (Tok.Finalized) return; - Changes.push_back(Change(false, Tok.WhitespaceRange, /*IndentLevel=*/0, - /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore, - "", "", Tok.Tok.getKind(), - InPPDirective && !Tok.IsFirst)); + Changes.push_back( + Change(false, Tok.WhitespaceRange, /*IndentLevel=*/0, + /*Spaces=*/0, Tok.OriginalColumn, Tok.NewlinesBefore, "", "", + Tok.Tok.getKind(), InPPDirective && !Tok.IsFirst, + Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName))); } void WhitespaceManager::replaceWhitespaceInToken( @@ -84,7 +88,8 @@ // calculate the new length of the comment and to calculate the changes // for which to do the alignment when aligning comments. Tok.is(TT_LineComment) && Newlines > 0 ? tok::comment : tok::unknown, - InPPDirective && !Tok.IsFirst)); + InPPDirective && !Tok.IsFirst, + Tok.is(TT_StartOfName) || Tok.is(TT_FunctionDeclarationName))); } const tooling::Replacements &WhitespaceManager::generateReplacements() { @@ -93,6 +98,7 @@ std::sort(Changes.begin(), Changes.end(), Change::IsBeforeInFile(SourceMgr)); calculateLineBreakInformation(); + alignConsecutiveDeclarations(); alignConsecutiveAssignments(); alignTrailingComments(); alignEscapedNewlines(); @@ -152,6 +158,7 @@ return; unsigned MinColumn = 0; + unsigned MaxColumn = UINT_MAX; unsigned StartOfSequence = 0; unsigned EndOfSequence = 0; bool FoundAssignmentOnLine = false; @@ -168,6 +175,7 @@ if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) alignConsecutiveAssignments(StartOfSequence, EndOfSequence, MinColumn); MinColumn = 0; + MaxColumn = UINT_MAX; StartOfSequence = 0; EndOfSequence = 0; }; @@ -207,7 +215,18 @@ StartOfSequence = i; unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn; + int LineLengthAfter = -Changes[i].Spaces; + for (unsigned j = i; j != e && Changes[j].NewlinesBefore == 0; ++j) + LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength; + unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter; + + if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) { + AlignSequence(); + StartOfSequence = i; + } + MinColumn = std::max(MinColumn, ChangeMinColumn); + MaxColumn = std::min(MaxColumn, ChangeMaxColumn); } } @@ -242,6 +261,110 @@ } } +// Walk through all of the changes and find sequences of declaration names to +// align. To do so, keep track of the lines and whether or not a name was found +// on align. If a name is found on a line, extend the current sequence. If the +// current line cannot be part of a sequence, e.g. because there is an empty +// line before it or it contains non-declarations, finalize the previous +// sequence. +void WhitespaceManager::alignConsecutiveDeclarations() { + if (!Style.AlignConsecutiveDeclarations) + return; + + unsigned MinColumn = 0; + unsigned MaxColumn = UINT_MAX; + unsigned StartOfSequence = 0; + unsigned EndOfSequence = 0; + bool FoundDeclarationOnLine = false; + bool FoundLeftBraceOnLine = false; + bool FoundLeftParenOnLine = false; + + auto AlignSequence = [&] { + if (StartOfSequence > 0 && StartOfSequence < EndOfSequence) + alignConsecutiveDeclarations(StartOfSequence, EndOfSequence, MinColumn); + MinColumn = 0; + MaxColumn = UINT_MAX; + StartOfSequence = 0; + EndOfSequence = 0; + }; + + for (unsigned i = 0, e = Changes.size(); i != e; ++i) { + if (Changes[i].NewlinesBefore != 0) { + EndOfSequence = i; + if (Changes[i].NewlinesBefore > 1 || !FoundDeclarationOnLine || + FoundLeftBraceOnLine || FoundLeftParenOnLine) + AlignSequence(); + FoundDeclarationOnLine = false; + FoundLeftBraceOnLine = false; + FoundLeftParenOnLine = false; + } + + if (Changes[i].Kind == tok::r_brace) { + if (!FoundLeftBraceOnLine) + AlignSequence(); + FoundLeftBraceOnLine = false; + } else if (Changes[i].Kind == tok::l_brace) { + FoundLeftBraceOnLine = true; + if (!FoundDeclarationOnLine) + AlignSequence(); + } else if (Changes[i].Kind == tok::r_paren) { + if (!FoundLeftParenOnLine) + AlignSequence(); + FoundLeftParenOnLine = false; + } else if (Changes[i].Kind == tok::l_paren) { + FoundLeftParenOnLine = true; + if (!FoundDeclarationOnLine) + AlignSequence(); + } else if (!FoundDeclarationOnLine && !FoundLeftBraceOnLine && + !FoundLeftParenOnLine && Changes[i].IsStartOfDeclName) { + FoundDeclarationOnLine = true; + if (StartOfSequence == 0) + StartOfSequence = i; + + unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn; + int LineLengthAfter = -Changes[i].Spaces; + for (unsigned j = i; j != e && Changes[j].NewlinesBefore == 0; ++j) + LineLengthAfter += Changes[j].Spaces + Changes[j].TokenLength; + unsigned ChangeMaxColumn = Style.ColumnLimit - LineLengthAfter; + + if (ChangeMinColumn > MaxColumn || ChangeMaxColumn < MinColumn) { + AlignSequence(); + StartOfSequence = i; + } + + MinColumn = std::max(MinColumn, ChangeMinColumn); + MaxColumn = std::min(MaxColumn, ChangeMaxColumn); + } + } + + EndOfSequence = Changes.size(); + AlignSequence(); +} + +void WhitespaceManager::alignConsecutiveDeclarations(unsigned Start, + unsigned End, + unsigned Column) { + bool FoundDeclarationOnLine = false; + int Shift = 0; + for (unsigned i = Start; i != End; ++i) { + if (Changes[i].NewlinesBefore != 0) { + FoundDeclarationOnLine = false; + Shift = 0; + } + + if (!FoundDeclarationOnLine && Changes[i].IsStartOfDeclName) { + FoundDeclarationOnLine = true; + Shift = Column - Changes[i].StartOfTokenColumn; + Changes[i].Spaces += Shift; + } + + assert(Shift >= 0); + Changes[i].StartOfTokenColumn += Shift; + if (i + 1 != Changes.size()) + Changes[i + 1].PreviousEndOfTokenColumn += Shift; + } +} + void WhitespaceManager::alignTrailingComments() { unsigned MinColumn = 0; unsigned MaxColumn = UINT_MAX; Index: lib/Headers/altivec.h =================================================================== --- lib/Headers/altivec.h +++ lib/Headers/altivec.h @@ -278,6 +278,38 @@ } #endif // __VSX__ +/* vec_adde */ + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_adde(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_adde(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddeuqm(__a, __b, __c); +} +#endif + +/* vec_addec */ + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai +vec_addec(vector signed __int128 __a, vector signed __int128 __b, + vector signed __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_addec(vector unsigned __int128 __a, vector unsigned __int128 __b, + vector unsigned __int128 __c) { + return __builtin_altivec_vaddecuq(__a, __b, __c); +} +#endif + /* vec_vaddubm */ #define __builtin_altivec_vaddubm vec_vaddubm @@ -390,6 +422,12 @@ /* vec_addc */ +static vector signed int __ATTRS_o_ai vec_addc(vector signed int __a, + vector signed int __b) { + return (vector signed int)__builtin_altivec_vaddcuw((vector unsigned int)__a, + (vector unsigned int)__b); +} + static vector unsigned int __ATTRS_o_ai vec_addc(vector unsigned int __a, vector unsigned int __b) { return __builtin_altivec_vaddcuw(__a, __b); @@ -398,7 +436,9 @@ #if defined(__POWER8_VECTOR__) && defined(__powerpc64__) static vector signed __int128 __ATTRS_o_ai vec_addc(vector signed __int128 __a, vector signed __int128 __b) { - return __builtin_altivec_vaddcuq(__a, __b); + return (vector signed __int128)__builtin_altivec_vaddcuq( + (vector unsigned __int128)__a, + (vector unsigned __int128)__b); } static vector unsigned __int128 __ATTRS_o_ai @@ -1512,48 +1552,6 @@ } #endif -/* vec_cmpge */ - -static vector bool int __ATTRS_o_ai -vec_cmpge(vector float __a, vector float __b) { -#ifdef __VSX__ - return (vector bool int)__builtin_vsx_xvcmpgesp(__a, __b); -#else - return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b); -#endif -} - -#ifdef __VSX__ -static vector bool long long __ATTRS_o_ai -vec_cmpge(vector double __a, vector double __b) { - return (vector bool long long)__builtin_vsx_xvcmpgedp(__a, __b); -} -#endif - -#ifdef __POWER8_VECTOR__ -/* Forwrad declarations as the functions are used here */ -static vector bool long long __ATTRS_o_ai -vec_cmpgt(vector unsigned long long __a, vector unsigned long long __b); -static vector bool long long __ATTRS_o_ai -vec_cmpgt(vector signed long long __a, vector signed long long __b); - -static vector bool long long __ATTRS_o_ai -vec_cmpge(vector signed long long __a, vector signed long long __b) { - return ~(vec_cmpgt(__b, __a)); -} - -static vector bool long long __ATTRS_o_ai -vec_cmpge(vector unsigned long long __a, vector unsigned long long __b) { - return ~(vec_cmpgt(__b, __a)); -} -#endif - -/* vec_vcmpgefp */ - -static vector bool int __attribute__((__always_inline__)) -vec_vcmpgefp(vector float __a, vector float __b) { - return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b); -} /* vec_cmpgt */ @@ -1613,6 +1611,74 @@ return (vector bool long long)__builtin_vsx_xvcmpgtdp(__a, __b); } #endif + +/* vec_cmpge */ + +static vector bool char __ATTRS_o_ai +vec_cmpge (vector signed char __a, vector signed char __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool char __ATTRS_o_ai +vec_cmpge (vector unsigned char __a, vector unsigned char __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool short __ATTRS_o_ai +vec_cmpge (vector signed short __a, vector signed short __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool short __ATTRS_o_ai +vec_cmpge (vector unsigned short __a, vector unsigned short __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool int __ATTRS_o_ai +vec_cmpge (vector signed int __a, vector signed int __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool int __ATTRS_o_ai +vec_cmpge (vector unsigned int __a, vector unsigned int __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool int __ATTRS_o_ai +vec_cmpge(vector float __a, vector float __b) { +#ifdef __VSX__ + return (vector bool int)__builtin_vsx_xvcmpgesp(__a, __b); +#else + return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b); +#endif +} + +#ifdef __VSX__ +static vector bool long long __ATTRS_o_ai +vec_cmpge(vector double __a, vector double __b) { + return (vector bool long long)__builtin_vsx_xvcmpgedp(__a, __b); +} +#endif + +#ifdef __POWER8_VECTOR__ +static vector bool long long __ATTRS_o_ai +vec_cmpge(vector signed long long __a, vector signed long long __b) { + return ~(vec_cmpgt(__b, __a)); +} + +static vector bool long long __ATTRS_o_ai +vec_cmpge(vector unsigned long long __a, vector unsigned long long __b) { + return ~(vec_cmpgt(__b, __a)); +} +#endif + +/* vec_vcmpgefp */ + +static vector bool int __attribute__((__always_inline__)) +vec_vcmpgefp(vector float __a, vector float __b) { + return (vector bool int)__builtin_altivec_vcmpgefp(__a, __b); +} + /* vec_vcmpgtsb */ static vector bool char __attribute__((__always_inline__)) @@ -1664,6 +1730,36 @@ /* vec_cmple */ +static vector bool char __ATTRS_o_ai +vec_cmple (vector signed char __a, vector signed char __b) { + return vec_cmpge(__b, __a); +} + +static vector bool char __ATTRS_o_ai +vec_cmple (vector unsigned char __a, vector unsigned char __b) { + return vec_cmpge(__b, __a); +} + +static vector bool short __ATTRS_o_ai +vec_cmple (vector signed short __a, vector signed short __b) { + return vec_cmpge(__b, __a); +} + +static vector bool short __ATTRS_o_ai +vec_cmple (vector unsigned short __a, vector unsigned short __b) { + return vec_cmpge(__b, __a); +} + +static vector bool int __ATTRS_o_ai +vec_cmple (vector signed int __a, vector signed int __b) { + return vec_cmpge(__b, __a); +} + +static vector bool int __ATTRS_o_ai +vec_cmple (vector unsigned int __a, vector unsigned int __b) { + return vec_cmpge(__b, __a); +} + static vector bool int __ATTRS_o_ai vec_cmple(vector float __a, vector float __b) { return vec_cmpge(__b, __a); @@ -1837,6 +1933,20 @@ return __builtin_altivec_vctuxs(__a, __b); } +/* vec_double */ + +#ifdef __VSX__ +static vector double __ATTRS_o_ai vec_double (vector signed long long __a) { + vector double __ret = { __a[0], __a[1] }; + return __ret; +} + +static vector double __ATTRS_o_ai vec_double (vector unsigned long long __a) { + vector double __ret = { __a[0], __a[1] }; + return __ret; +} +#endif + /* vec_div */ /* Integer vector divides (vectors are scalarized, elements divided @@ -1942,34 +2052,16 @@ (vector unsigned int)__b); } -static vector signed char __ATTRS_o_ai vec_eqv(vector bool char __a, - vector signed char __b) { - return (vector signed char)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector signed char __ATTRS_o_ai vec_eqv(vector signed char __a, - vector bool char __b) { - return (vector signed char)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - static vector unsigned char __ATTRS_o_ai vec_eqv(vector unsigned char __a, vector unsigned char __b) { return (vector unsigned char)__builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } -static vector unsigned char __ATTRS_o_ai vec_eqv(vector bool char __a, - vector unsigned char __b) { - return (vector unsigned char)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector unsigned char __ATTRS_o_ai vec_eqv(vector unsigned char __a, - vector bool char __b) { - return (vector unsigned char)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); +static vector bool char __ATTRS_o_ai vec_eqv(vector bool char __a, + vector bool char __b) { + return (vector bool char)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); } static vector signed short __ATTRS_o_ai vec_eqv(vector signed short __a, @@ -1978,70 +2070,33 @@ (vector unsigned int)__b); } -static vector signed short __ATTRS_o_ai vec_eqv(vector bool short __a, - vector signed short __b) { - return (vector signed short)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector signed short __ATTRS_o_ai vec_eqv(vector signed short __a, - vector bool short __b) { - return (vector signed short)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - static vector unsigned short __ATTRS_o_ai vec_eqv(vector unsigned short __a, vector unsigned short __b) { return (vector unsigned short)__builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } -static vector unsigned short __ATTRS_o_ai vec_eqv(vector bool short __a, - vector unsigned short __b) { - return (vector unsigned short)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector unsigned short __ATTRS_o_ai vec_eqv(vector unsigned short __a, - vector bool short __b) { - return (vector unsigned short)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector signed int __ATTRS_o_ai vec_eqv(vector signed int __a, - vector signed int __b) { - return (vector signed int)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector signed int __ATTRS_o_ai vec_eqv(vector bool int __a, - vector signed int __b) { - return (vector signed int)__builtin_vsx_xxleqv((vector unsigned int)__a, +static vector bool short __ATTRS_o_ai vec_eqv(vector bool short __a, + vector bool short __b) { + return (vector bool short)__builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } static vector signed int __ATTRS_o_ai vec_eqv(vector signed int __a, - vector bool int __b) { + vector signed int __b) { return (vector signed int)__builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } static vector unsigned int __ATTRS_o_ai vec_eqv(vector unsigned int __a, vector unsigned int __b) { - return __builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector unsigned int __ATTRS_o_ai vec_eqv(vector bool int __a, - vector unsigned int __b) { - return __builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); + return __builtin_vsx_xxleqv(__a, __b); } -static vector unsigned int __ATTRS_o_ai vec_eqv(vector unsigned int __a, - vector bool int __b) { - return __builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); +static vector bool int __ATTRS_o_ai vec_eqv(vector bool int __a, + vector bool int __b) { + return (vector bool int)__builtin_vsx_xxleqv((vector unsigned int)__a, + (vector unsigned int)__b); } static vector signed long long __ATTRS_o_ai @@ -2050,33 +2105,15 @@ __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } -static vector signed long long __ATTRS_o_ai -vec_eqv(vector bool long long __a, vector signed long long __b) { - return (vector signed long long) - __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); -} - -static vector signed long long __ATTRS_o_ai -vec_eqv(vector signed long long __a, vector bool long long __b) { - return (vector signed long long) - __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); -} - static vector unsigned long long __ATTRS_o_ai vec_eqv(vector unsigned long long __a, vector unsigned long long __b) { return (vector unsigned long long) __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } -static vector unsigned long long __ATTRS_o_ai -vec_eqv(vector bool long long __a, vector unsigned long long __b) { - return (vector unsigned long long) - __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); -} - -static vector unsigned long long __ATTRS_o_ai -vec_eqv(vector unsigned long long __a, vector bool long long __b) { - return (vector unsigned long long) +static vector bool long long __ATTRS_o_ai +vec_eqv(vector bool long long __a, vector bool long long __b) { + return (vector bool long long) __builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } @@ -2085,35 +2122,11 @@ (vector unsigned int)__b); } -static vector float __ATTRS_o_ai vec_eqv(vector bool int __a, - vector float __b) { - return (vector float)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector float __ATTRS_o_ai vec_eqv(vector float __a, - vector bool int __b) { - return (vector float)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - static vector double __ATTRS_o_ai vec_eqv(vector double __a, vector double __b) { return (vector double)__builtin_vsx_xxleqv((vector unsigned int)__a, (vector unsigned int)__b); } - -static vector double __ATTRS_o_ai vec_eqv(vector bool long long __a, - vector double __b) { - return (vector double)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} - -static vector double __ATTRS_o_ai vec_eqv(vector double __a, - vector bool long long __b) { - return (vector double)__builtin_vsx_xxleqv((vector unsigned int)__a, - (vector unsigned int)__b); -} #endif /* vec_expte */ @@ -2815,6 +2828,38 @@ #endif /* vec_madd */ +static vector signed short __ATTRS_o_ai +vec_mladd(vector signed short, vector signed short, vector signed short); +static vector signed short __ATTRS_o_ai +vec_mladd(vector signed short, vector unsigned short, vector unsigned short); +static vector signed short __ATTRS_o_ai +vec_mladd(vector unsigned short, vector signed short, vector signed short); +static vector unsigned short __ATTRS_o_ai +vec_mladd(vector unsigned short, vector unsigned short, vector unsigned short); + +static vector signed short __ATTRS_o_ai +vec_madd(vector signed short __a, vector signed short __b, + vector signed short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector signed short __ATTRS_o_ai +vec_madd(vector signed short __a, vector unsigned short __b, + vector unsigned short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector signed short __ATTRS_o_ai +vec_madd(vector unsigned short __a, vector signed short __b, + vector signed short __c) { + return vec_mladd(__a, __b, __c); +} + +static vector unsigned short __ATTRS_o_ai +vec_madd(vector unsigned short __a, vector unsigned short __b, + vector unsigned short __c) { + return vec_mladd(__a, __b, __c); +} static vector float __ATTRS_o_ai vec_madd(vector float __a, vector float __b, vector float __c) { @@ -3256,6 +3301,16 @@ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17)); } + +static vector bool long long __ATTRS_o_ai +vec_mergeh(vector bool long long __a, vector bool long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, + 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17)); +} + static vector double __ATTRS_o_ai vec_mergeh(vector double __a, vector double __b) { return vec_perm(__a, __b, @@ -3519,6 +3574,14 @@ 0x18, 0X19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F)); } +static vector bool long long __ATTRS_o_ai +vec_mergel(vector bool long long __a, vector bool long long __b) { + return vec_perm(__a, __b, + (vector unsigned char)(0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, + 0x18, 0X19, 0x1A, 0x1B, + 0x1C, 0x1D, 0x1E, 0x1F)); +} static vector double __ATTRS_o_ai vec_mergel(vector double __a, vector double __b) { return vec_perm(__a, __b, @@ -4439,6 +4502,11 @@ return ~(__a & __b); } +static vector bool char __ATTRS_o_ai vec_nand(vector bool char __a, + vector bool char __b) { + return ~(__a & __b); +} + static vector signed short __ATTRS_o_ai vec_nand(vector signed short __a, vector signed short __b) { return ~(__a & __b); @@ -4465,8 +4533,8 @@ } -static vector unsigned short __ATTRS_o_ai vec_nand(vector bool short __a, - vector unsigned short __b) { +static vector bool short __ATTRS_o_ai vec_nand(vector bool short __a, + vector bool short __b) { return ~(__a & __b); } @@ -4501,6 +4569,11 @@ return ~(__a & __b); } +static vector bool int __ATTRS_o_ai vec_nand(vector bool int __a, + vector bool int __b) { + return ~(__a & __b); +} + static vector signed long long __ATTRS_o_ai vec_nand(vector signed long long __a, vector signed long long __b) { return ~(__a & __b); @@ -4531,6 +4604,11 @@ return ~(__a & __b); } +static vector bool long long __ATTRS_o_ai +vec_nand(vector bool long long __a, vector bool long long __b) { + return ~(__a & __b); +} + #endif /* vec_nmadd */ @@ -4909,6 +4987,11 @@ return __a | ~__b; } +static vector bool char __ATTRS_o_ai vec_orc(vector bool char __a, + vector bool char __b) { + return __a | ~__b; +} + static vector signed short __ATTRS_o_ai vec_orc(vector signed short __a, vector signed short __b) { return __a | ~__b; @@ -4939,6 +5022,11 @@ return __a | ~__b; } +static vector bool short __ATTRS_o_ai vec_orc(vector bool short __a, + vector bool short __b) { + return __a | ~__b; +} + static vector signed int __ATTRS_o_ai vec_orc(vector signed int __a, vector signed int __b) { return __a | ~__b; @@ -4969,6 +5057,11 @@ return __a | ~__b; } +static vector bool int __ATTRS_o_ai vec_orc(vector bool int __a, + vector bool int __b) { + return __a | ~__b; +} + static vector signed long long __ATTRS_o_ai vec_orc(vector signed long long __a, vector signed long long __b) { return __a | ~__b; @@ -4998,6 +5091,11 @@ vec_orc(vector bool long long __a, vector unsigned long long __b) { return __a | ~__b; } + +static vector bool long long __ATTRS_o_ai +vec_orc(vector bool long long __a, vector bool long long __b) { + return __a | ~__b; +} #endif /* vec_vor */ @@ -9191,17 +9289,27 @@ } #endif // defined(__POWER8_VECTOR__) && defined(__powerpc64__) -static vector float __ATTRS_o_ai vec_sub(vector float __a, vector float __b) { +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_sub(vector signed long long __a, vector signed long long __b) { + return __a - __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_sub(vector unsigned long long __a, vector unsigned long long __b) { return __a - __b; } -#ifdef __VSX__ static vector double __ATTRS_o_ai vec_sub(vector double __a, vector double __b) { return __a - __b; } #endif +static vector float __ATTRS_o_ai vec_sub(vector float __a, vector float __b) { + return __a - __b; +} + /* vec_vsububm */ #define __builtin_altivec_vsububm vec_vsububm @@ -10390,7 +10498,12 @@ return __a[__b]; } -static short __ATTRS_o_ai vec_extract(vector short __a, int __b) { +static unsigned char __ATTRS_o_ai vec_extract(vector bool char __a, + int __b) { + return __a[__b]; +} + +static signed short __ATTRS_o_ai vec_extract(vector signed short __a, int __b) { return __a[__b]; } @@ -10399,7 +10512,12 @@ return __a[__b]; } -static int __ATTRS_o_ai vec_extract(vector int __a, int __b) { +static unsigned short __ATTRS_o_ai vec_extract(vector bool short __a, + int __b) { + return __a[__b]; +} + +static signed int __ATTRS_o_ai vec_extract(vector signed int __a, int __b) { return __a[__b]; } @@ -10407,6 +10525,31 @@ return __a[__b]; } +static unsigned int __ATTRS_o_ai vec_extract(vector bool int __a, int __b) { + return __a[__b]; +} + +#ifdef __VSX__ +static signed long long __ATTRS_o_ai vec_extract(vector signed long long __a, + int __b) { + return __a[__b]; +} + +static unsigned long long __ATTRS_o_ai +vec_extract(vector unsigned long long __a, int __b) { + return __a[__b]; +} + +static unsigned long long __ATTRS_o_ai vec_extract(vector bool long long __a, + int __b) { + return __a[__b]; +} + +static double __ATTRS_o_ai vec_extract(vector double __a, int __b) { + return __a[__b]; +} +#endif + static float __ATTRS_o_ai vec_extract(vector float __a, int __b) { return __a[__b]; } @@ -10427,8 +10570,16 @@ return __b; } -static vector short __ATTRS_o_ai vec_insert(short __a, vector short __b, - int __c) { +static vector bool char __ATTRS_o_ai vec_insert(unsigned char __a, + vector bool char __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector signed short __ATTRS_o_ai vec_insert(signed short __a, + vector signed short __b, + int __c) { __b[__c] = __a; return __b; } @@ -10440,7 +10591,16 @@ return __b; } -static vector int __ATTRS_o_ai vec_insert(int __a, vector int __b, int __c) { +static vector bool short __ATTRS_o_ai vec_insert(unsigned short __a, + vector bool short __b, + int __c) { + __b[__c] = __a; + return __b; +} + +static vector signed int __ATTRS_o_ai vec_insert(signed int __a, + vector signed int __b, + int __c) { __b[__c] = __a; return __b; } @@ -10452,6 +10612,38 @@ return __b; } +static vector bool int __ATTRS_o_ai vec_insert(unsigned int __a, + vector bool int __b, + int __c) { + __b[__c] = __a; + return __b; +} + +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai +vec_insert(signed long long __a, vector signed long long __b, int __c) { + __b[__c] = __a; + return __b; +} + +static vector unsigned long long __ATTRS_o_ai +vec_insert(unsigned long long __a, vector unsigned long long __b, int __c) { + __b[__c] = __a; + return __b; +} + +static vector bool long long __ATTRS_o_ai +vec_insert(unsigned long long __a, vector bool long long __b, int __c) { + __b[__c] = __a; + return __b; +} +static vector double __ATTRS_o_ai vec_insert(double __a, vector double __b, + int __c) { + __b[__c] = __a; + return __b; +} +#endif + static vector float __ATTRS_o_ai vec_insert(float __a, vector float __b, int __c) { __b[__c] = __a; @@ -11376,6 +11568,33 @@ return (vector unsigned int)(__a); } +#ifdef __VSX__ +static vector signed long long __ATTRS_o_ai vec_splats(signed long long __a) { + return (vector signed long long)(__a); +} + +static vector unsigned long long __ATTRS_o_ai +vec_splats(unsigned long long __a) { + return (vector unsigned long long)(__a); +} + +#if defined(__POWER8_VECTOR__) && defined(__powerpc64__) +static vector signed __int128 __ATTRS_o_ai vec_splats(signed __int128 __a) { + return (vector signed __int128)(__a); +} + +static vector unsigned __int128 __ATTRS_o_ai +vec_splats(unsigned __int128 __a) { + return (vector unsigned __int128)(__a); +} + +#endif + +static vector double __ATTRS_o_ai vec_splats(double __a) { + return (vector double)(__a); +} +#endif + static vector float __ATTRS_o_ai vec_splats(float __a) { return (vector float)(__a); } @@ -11546,8 +11765,18 @@ #endif static int __ATTRS_o_ai vec_all_eq(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_LT, __a, __b); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_LT, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_eq(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_LT, __a, __b); } +#endif /* vec_all_ge */ @@ -11698,8 +11927,18 @@ #endif static int __ATTRS_o_ai vec_all_ge(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_LT, __a, __b); +#else return __builtin_altivec_vcmpgefp_p(__CR6_LT, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_ge(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_LT, __a, __b); } +#endif /* vec_all_gt */ @@ -11850,8 +12089,18 @@ #endif static int __ATTRS_o_ai vec_all_gt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_LT, __a, __b); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_LT, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_gt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_LT, __a, __b); } +#endif /* vec_all_in */ @@ -12010,9 +12259,19 @@ #endif static int __ATTRS_o_ai vec_all_le(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_LT, __b, __a); +#else return __builtin_altivec_vcmpgefp_p(__CR6_LT, __b, __a); +#endif } +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_le(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_LT, __b, __a); +} +#endif + /* vec_all_lt */ static int __ATTRS_o_ai vec_all_lt(vector signed char __a, @@ -12163,15 +12422,35 @@ #endif static int __ATTRS_o_ai vec_all_lt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_LT, __b, __a); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_LT, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_lt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_LT, __b, __a); } +#endif /* vec_all_nan */ -static int __attribute__((__always_inline__)) vec_all_nan(vector float __a) { +static int __ATTRS_o_ai vec_all_nan(vector float __a) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_EQ, __a, __a); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, __a, __a); +#endif } +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_nan(vector double __a) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ, __a, __a); +} +#endif + /* vec_all_ne */ static int __ATTRS_o_ai vec_all_ne(vector signed char __a, @@ -12337,22 +12616,54 @@ #endif static int __ATTRS_o_ai vec_all_ne(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ, __a, __b); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_EQ, __a, __b); +#endif } +#ifdef __VSX__ +static int __ATTRS_o_ai vec_all_ne(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ, __a, __b); +} +#endif + /* vec_all_nge */ -static int __attribute__((__always_inline__)) +static int __ATTRS_o_ai vec_all_nge(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_EQ, __a, __b); +#else return __builtin_altivec_vcmpgefp_p(__CR6_EQ, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai +vec_all_nge(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_EQ, __a, __b); } +#endif /* vec_all_ngt */ -static int __attribute__((__always_inline__)) +static int __ATTRS_o_ai vec_all_ngt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_EQ, __a, __b); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_EQ, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai +vec_all_ngt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_EQ, __a, __b); } +#endif /* vec_all_nle */ @@ -12540,8 +12851,18 @@ #endif static int __ATTRS_o_ai vec_any_eq(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_EQ_REV, __a, __b); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_EQ_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_eq(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_EQ_REV, __a, __b); } +#endif /* vec_any_ge */ @@ -12700,9 +13021,19 @@ #endif static int __ATTRS_o_ai vec_any_ge(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_EQ_REV, __a, __b); +#else return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, __a, __b); +#endif } +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_ge(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_EQ_REV, __a, __b); +} +#endif + /* vec_any_gt */ static int __ATTRS_o_ai vec_any_gt(vector signed char __a, @@ -12860,8 +13191,18 @@ #endif static int __ATTRS_o_ai vec_any_gt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_EQ_REV, __a, __b); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, __a, __b); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_gt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_EQ_REV, __a, __b); } +#endif /* vec_any_le */ @@ -13020,8 +13361,18 @@ #endif static int __ATTRS_o_ai vec_any_le(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgesp_p(__CR6_EQ_REV, __b, __a); +#else return __builtin_altivec_vcmpgefp_p(__CR6_EQ_REV, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_le(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgedp_p(__CR6_EQ_REV, __b, __a); } +#endif /* vec_any_lt */ @@ -13180,8 +13531,18 @@ #endif static int __ATTRS_o_ai vec_any_lt(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpgtsp_p(__CR6_EQ_REV, __b, __a); +#else return __builtin_altivec_vcmpgtfp_p(__CR6_EQ_REV, __b, __a); +#endif +} + +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_lt(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpgtdp_p(__CR6_EQ_REV, __b, __a); } +#endif /* vec_any_nan */ @@ -13354,9 +13715,19 @@ #endif static int __ATTRS_o_ai vec_any_ne(vector float __a, vector float __b) { +#ifdef __VSX__ + return __builtin_vsx_xvcmpeqsp_p(__CR6_LT_REV, __a, __b); +#else return __builtin_altivec_vcmpeqfp_p(__CR6_LT_REV, __a, __b); +#endif } +#ifdef __VSX__ +static int __ATTRS_o_ai vec_any_ne(vector double __a, vector double __b) { + return __builtin_vsx_xvcmpeqdp_p(__CR6_LT_REV, __a, __b); +} +#endif + /* vec_any_nge */ static int __attribute__((__always_inline__)) @@ -13411,11 +13782,14 @@ The remaining ones (currently controlled by -mcrypto for GCC) still need to be provided on compliant hardware even if Vector.Crypto is not provided. -FIXME: the naming convention for the builtins will be adjusted due -to the inconsistency (__builtin_crypto_ prefix on builtins that cannot be -removed with -mno-crypto). This is under development. */ #ifdef __CRYPTO__ +#define vec_sbox_be __builtin_altivec_crypto_vsbox +#define vec_cipher_be __builtin_altivec_crypto_vcipher +#define vec_cipherlast_be __builtin_altivec_crypto_vcipherlast +#define vec_ncipher_be __builtin_altivec_crypto_vncipher +#define vec_ncipherlast_be __builtin_altivec_crypto_vncipherlast + static vector unsigned long long __attribute__((__always_inline__)) __builtin_crypto_vsbox(vector unsigned long long __a) { return __builtin_altivec_crypto_vsbox(__a); @@ -13447,6 +13821,11 @@ #define __builtin_crypto_vshasigmad __builtin_altivec_crypto_vshasigmad #define __builtin_crypto_vshasigmaw __builtin_altivec_crypto_vshasigmaw + +#define vec_shasigma_be(X, Y, Z) \ + _Generic((X), vector unsigned int: __builtin_crypto_vshasigmaw, \ + vector unsigned long long: __builtin_crypto_vshasigmad) \ +((X), (Y), (Z)) #endif #ifdef __POWER8_VECTOR__ @@ -13494,8 +13873,9 @@ return __builtin_altivec_crypto_vpmsumw(__a, __b); } -static vector unsigned long long __ATTRS_o_ai __builtin_crypto_vpmsumb( - vector unsigned long long __a, vector unsigned long long __b) { +static vector unsigned long long __ATTRS_o_ai +__builtin_crypto_vpmsumb(vector unsigned long long __a, + vector unsigned long long __b) { return __builtin_altivec_crypto_vpmsumd(__a, __b); } @@ -13504,6 +13884,9 @@ return __builtin_altivec_vgbbd((vector unsigned char) __a); } +#define vec_pmsum_be __builtin_crypto_vpmsumb +#define vec_gb __builtin_altivec_vgbbd + static vector unsigned char __ATTRS_o_ai vec_vgbbd (vector unsigned char __a) { return __builtin_altivec_vgbbd(__a); @@ -13521,6 +13904,14 @@ { return __builtin_altivec_vbpermq(__a, __b); } + +#ifdef __powerpc64__ +static vector unsigned long long __attribute__((__always_inline__)) +vec_bperm (vector unsigned __int128 __a, vector unsigned char __b) { + return __builtin_altivec_vbpermq((vector unsigned char) __a, + (vector unsigned char) __b); +} +#endif #endif #undef __ATTRS_o_ai Index: lib/Lex/Preprocessor.cpp =================================================================== --- lib/Lex/Preprocessor.cpp +++ lib/Lex/Preprocessor.cpp @@ -716,7 +716,7 @@ } void Preprocessor::Lex(Token &Result) { - // We loop here until a lex function retuns a token; this avoids recursion. + // We loop here until a lex function returns a token; this avoids recursion. bool ReturnedToken; do { switch (CurLexerKind) { Index: lib/Parse/ParseOpenMP.cpp =================================================================== --- lib/Parse/ParseOpenMP.cpp +++ lib/Parse/ParseOpenMP.cpp @@ -394,7 +394,7 @@ /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | /// mergeable-clause | flush-clause | read-clause | write-clause | /// update-clause | capture-clause | seq_cst-clause | device-clause | -/// simdlen-clause | threads-clause +/// simdlen-clause | threads-clause | simd-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -473,6 +473,7 @@ case OMPC_capture: case OMPC_seq_cst: case OMPC_threads: + case OMPC_simd: // OpenMP [2.7.1, Restrictions, p. 9] // Only one ordered clause can appear on a loop directive. // OpenMP [2.7.1, Restrictions, C/C++, p. 4] @@ -605,6 +606,9 @@ /// threads-clause: /// 'threads' /// +/// simd-clause: +/// 'simd' +/// OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) { SourceLocation Loc = Tok.getLocation(); ConsumeAnyToken(); Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -628,13 +628,10 @@ // Check that this attribute only applies to lockable types. QualType QT = cast(D)->getType(); - if (!QT->isDependentType()) { - const RecordType *RT = getRecordType(QT); - if (!RT || !RT->getDecl()->hasAttr()) { - S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) - << Attr.getName(); - return false; - } + if (!QT->isDependentType() && !typeHasCapability(S, QT)) { + S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) + << Attr.getName(); + return false; } // Check that all arguments are lockable objects. Index: lib/Sema/SemaExceptionSpec.cpp =================================================================== --- lib/Sema/SemaExceptionSpec.cpp +++ lib/Sema/SemaExceptionSpec.cpp @@ -270,16 +270,31 @@ FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType(); if (ESI.Type == EST_Dynamic) { ESI.Exceptions = OldProto->exceptions(); - } else if (ESI.Type == EST_ComputedNoexcept) { - // FIXME: We can't just take the expression from the old prototype. It - // likely contains references to the old prototype's parameters. } - // Update the type of the function with the appropriate exception - // specification. - New->setType(Context.getFunctionType( - NewProto->getReturnType(), NewProto->getParamTypes(), - NewProto->getExtProtoInfo().withExceptionSpec(ESI))); + if (ESI.Type == EST_ComputedNoexcept) { + // For computed noexcept, we can't just take the expression from the old + // prototype. It likely contains references to the old prototype's + // parameters. + New->setInvalidDecl(); + } else { + // Update the type of the function with the appropriate exception + // specification. + New->setType(Context.getFunctionType( + NewProto->getReturnType(), NewProto->getParamTypes(), + NewProto->getExtProtoInfo().withExceptionSpec(ESI))); + } + + // Allow missing exception specifications in redeclarations as an extension, + // when declaring a replaceable global allocation function. + if (New->isReplaceableGlobalAllocationFunction() && + ESI.Type != EST_ComputedNoexcept) { + DiagID = diag::ext_missing_exception_specification; + ReturnValueOnError = false; + } else { + DiagID = diag::err_missing_exception_specification; + ReturnValueOnError = true; + } // Warn about the lack of exception specification. SmallString<128> ExceptionSpecString; @@ -322,17 +337,18 @@ SourceLocation FixItLoc; if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); - if (FunctionTypeLoc FTLoc = TL.getAs()) - FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd()); + // FIXME: Preserve enough information so that we can produce a correct fixit + // location when there is a trailing return type. + if (auto FTLoc = TL.getAs()) + if (!FTLoc.getTypePtr()->hasTrailingReturn()) + FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd()); } if (FixItLoc.isInvalid()) - Diag(New->getLocation(), diag::warn_missing_exception_specification) + Diag(New->getLocation(), DiagID) << New << OS.str(); else { - // FIXME: This will get more complicated with C++0x - // late-specified return types. - Diag(New->getLocation(), diag::warn_missing_exception_specification) + Diag(New->getLocation(), DiagID) << New << OS.str() << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); } @@ -340,7 +356,7 @@ if (!Old->getLocation().isInvalid()) Diag(Old->getLocation(), diag::note_previous_declaration); - return false; + return ReturnValueOnError; } /// CheckEquivalentExceptionSpec - Check if the two types have equivalent Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -3987,28 +3987,6 @@ return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); } -static QualType getNonOMPArraySectionType(Expr *Base) { - unsigned ArraySectionCount = 0; - while (auto *OASE = dyn_cast(Base->IgnoreParens())) { - Base = OASE->getBase(); - ++ArraySectionCount; - } - auto OriginalTy = Base->getType(); - if (auto *DRE = dyn_cast(Base)) - if (auto *PVD = dyn_cast(DRE->getDecl())) - OriginalTy = PVD->getOriginalType().getNonReferenceType(); - - for (unsigned Cnt = 0; Cnt < ArraySectionCount; ++Cnt) { - if (OriginalTy->isAnyPointerType()) - OriginalTy = OriginalTy->getPointeeType(); - else { - assert (OriginalTy->isArrayType()); - OriginalTy = OriginalTy->castAsArrayTypeUnsafe()->getElementType(); - } - } - return OriginalTy; -} - ExprResult Sema::ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLoc, Expr *Length, @@ -4045,7 +4023,7 @@ } // Perform default conversions. - QualType OriginalTy = getNonOMPArraySectionType(Base); + QualType OriginalTy = OMPArraySectionExpr::getBaseOriginalType(Base); QualType ResultTy; if (OriginalTy->isAnyPointerType()) { ResultTy = OriginalTy->getPointeeType(); @@ -10298,6 +10276,20 @@ return ExprError(); } + if (getLangOpts().OpenCL) { + // OpenCLC v2.0 s6.13.11.1 allows atomic variables to be initialized by + // the ATOMIC_VAR_INIT macro. + if (LHSExpr->getType()->isAtomicType() || + RHSExpr->getType()->isAtomicType()) { + SourceRange SR(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + if (BO_Assign == Opc) + Diag(OpLoc, diag::err_atomic_init_constant) << SR; + else + ResultTy = InvalidOperands(OpLoc, LHS, RHS); + return ExprError(); + } + } + switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType()); @@ -10770,6 +10762,14 @@ ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; QualType resultType; + if (getLangOpts().OpenCL) { + // The only legal unary operation for atomics is '&'. + if (Opc != UO_AddrOf && InputExpr->getType()->isAtomicType()) { + return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) + << InputExpr->getType() + << Input.get()->getSourceRange()); + } + } switch (Opc) { case UO_PreInc: case UO_PreDec: Index: lib/Sema/SemaExprMember.cpp =================================================================== --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -632,6 +632,16 @@ DeclarationName Typo = R.getLookupName(); SourceLocation TypoLoc = R.getNameLoc(); + + struct QueryState { + Sema &SemaRef; + DeclarationNameInfo NameInfo; + Sema::LookupNameKind LookupKind; + Sema::RedeclarationKind Redecl; + }; + QueryState Q = {R.getSema(), R.getLookupNameInfo(), R.getLookupKind(), + R.isForRedeclaration() ? Sema::ForRedeclaration + : Sema::NotForRedeclaration}; TE = SemaRef.CorrectTypoDelayed( R.getLookupNameInfo(), R.getLookupKind(), nullptr, &SS, llvm::make_unique(RTy), @@ -650,6 +660,7 @@ } }, [=](Sema &SemaRef, TypoExpr *TE, TypoCorrection TC) mutable { + LookupResult R(Q.SemaRef, Q.NameInfo, Q.LookupKind, Q.Redecl); R.clear(); // Ensure there's no decls lingering in the shared state. R.suppressDiagnostics(); R.setLookupName(TC.getCorrection()); Index: lib/Sema/SemaOpenMP.cpp =================================================================== --- lib/Sema/SemaOpenMP.cpp +++ lib/Sema/SemaOpenMP.cpp @@ -1547,7 +1547,7 @@ // | simd | taskwait | | // | simd | taskgroup | | // | simd | flush | | - // | simd | ordered | | + // | simd | ordered | + (with simd clause) | // | simd | atomic | | // | simd | target | | // | simd | teams | | @@ -1573,7 +1573,7 @@ // | for simd | taskwait | | // | for simd | taskgroup | | // | for simd | flush | | - // | for simd | ordered | | + // | for simd | ordered | + (with simd clause) | // | for simd | atomic | | // | for simd | target | | // | for simd | teams | | @@ -1599,7 +1599,7 @@ // | parallel for simd| taskwait | | // | parallel for simd| taskgroup | | // | parallel for simd| flush | | - // | parallel for simd| ordered | | + // | parallel for simd| ordered | + (with simd clause) | // | parallel for simd| atomic | | // | parallel for simd| target | | // | parallel for simd| teams | | @@ -1877,9 +1877,12 @@ ShouldBeInOrderedRegion, ShouldBeInTargetRegion } Recommend = NoRecommend; - if (isOpenMPSimdDirective(ParentRegion)) { + if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { // OpenMP [2.16, Nesting of Regions] // OpenMP constructs may not be nested inside a simd region. + // OpenMP [2.8.1,simd Construct, Restrictions] + // An ordered construct with the simd clause is the only OpenMP construct + // that can appear in the simd region. SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); return true; } @@ -1987,9 +1990,13 @@ // atomic, or explicit task region. // An ordered region must be closely nested inside a loop region (or // parallel loop region) with an ordered clause. + // OpenMP [2.8.1,simd Construct, Restrictions] + // An ordered construct with the simd clause is the only OpenMP construct + // that can appear in the simd region. NestingProhibited = ParentRegion == OMPD_critical || ParentRegion == OMPD_task || - !Stack->isParentOrderedRegion(); + !(isOpenMPSimdDirective(ParentRegion) || + Stack->isParentOrderedRegion()); Recommend = ShouldBeInOrderedRegion; } else if (isOpenMPTeamsDirective(CurrentRegion)) { // OpenMP [2.16, Nesting of Regions] @@ -4146,9 +4153,12 @@ getCurFunction()->setHasBranchProtectedScope(); OMPThreadsClause *TC = nullptr; + OMPSIMDClause *SC = nullptr; for (auto *C: Clauses) { if (C->getClauseKind() == OMPC_threads) TC = cast(C); + else if (C->getClauseKind() == OMPC_simd) + SC = cast(C); } // TODO: this must happen only if 'threads' clause specified or if no clauses @@ -4159,6 +4169,13 @@ Diag(Param->getLocStart(), diag::note_omp_ordered_param); return StmtError(); } + if (!SC && isOpenMPSimdDirective(DSAStack->getParentDirective())) { + // OpenMP [2.8.1,simd Construct, Restrictions] + // An ordered construct with the simd clause is the only OpenMP construct + // that can appear in the simd region. + Diag(StartLoc, diag::err_omp_prohibited_region_simd); + return StmtError(); + } return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); } @@ -5009,6 +5026,7 @@ case OMPC_seq_cst: case OMPC_depend: case OMPC_threads: + case OMPC_simd: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -5270,6 +5288,7 @@ case OMPC_depend: case OMPC_device: case OMPC_threads: + case OMPC_simd: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -5398,6 +5417,7 @@ case OMPC_depend: case OMPC_device: case OMPC_threads: + case OMPC_simd: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -5504,6 +5524,9 @@ case OMPC_threads: Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); break; + case OMPC_simd: + Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); + break; case OMPC_if: case OMPC_final: case OMPC_num_threads: @@ -5578,6 +5601,11 @@ return new (Context) OMPThreadsClause(StartLoc, EndLoc); } +OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, + SourceLocation EndLoc) { + return new (Context) OMPSIMDClause(StartLoc, EndLoc); +} + OMPClause *Sema::ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef VarList, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, @@ -5644,6 +5672,7 @@ case OMPC_seq_cst: case OMPC_device: case OMPC_threads: + case OMPC_simd: case OMPC_unknown: llvm_unreachable("Clause is not allowed."); } @@ -6361,14 +6390,39 @@ // OpenMP [2.14.3.3, Restrictions, p.1] // A variable that is part of another variable (as an array or // structure element) cannot appear in a private clause. - auto DE = dyn_cast(RefExpr); - if (!DE || !isa(DE->getDecl())) { - Diag(ELoc, diag::err_omp_expected_var_name) << ERange; + auto *DE = dyn_cast(RefExpr); + auto *ASE = dyn_cast(RefExpr); + auto *OASE = dyn_cast(RefExpr); + if (!ASE && !OASE && (!DE || !isa(DE->getDecl()))) { + Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) << ERange; + continue; + } + QualType Type; + VarDecl *VD = nullptr; + if (DE) { + auto D = DE->getDecl(); + VD = cast(D); + Type = VD->getType(); + } else if (ASE) + Type = ASE->getType(); + else if (OASE) { + auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); + if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) + Type = ATy->getElementType(); + else + Type = BaseType->getPointeeType(); + } + // OpenMP [2.15.3.6, reduction Clause] + // If a list item is an array section, its lower-bound must be zero. + llvm::APSInt Result; + if (OASE && OASE->getLowerBound() && + OASE->getLowerBound()->EvaluateAsInt(Result, Context) && Result != 0) { + Diag(OASE->getLowerBound()->getExprLoc(), + diag::err_omp_expected_array_sect_reduction_lb_not_zero) + << OASE->getLowerBound()->getSourceRange(); continue; } - auto D = DE->getDecl(); - auto VD = cast(D); - auto Type = VD->getType(); + // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] // A variable that appears in a private clause must not have an incomplete // type or a reference type. @@ -6379,36 +6433,42 @@ // Arrays may not appear in a reduction clause. if (Type.getNonReferenceType()->isArrayType()) { Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange; - bool IsDecl = - VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + if (VD) { + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + } continue; } // OpenMP [2.14.3.6, reduction clause, Restrictions] // A list item that appears in a reduction clause must not be // const-qualified. if (Type.getNonReferenceType().isConstant(Context)) { - Diag(ELoc, diag::err_omp_const_variable) + Diag(ELoc, diag::err_omp_const_reduction_list_item) << getOpenMPClauseName(OMPC_reduction) << Type << ERange; - bool IsDecl = - VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + if (VD) { + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + } continue; } // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] // If a list-item is a reference type then it must bind to the same object // for all threads of the team. - VarDecl *VDDef = VD->getDefinition(); - if (Type->isReferenceType() && VDDef) { - DSARefChecker Check(DSAStack); - if (Check.Visit(VDDef->getInit())) { - Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; - Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; - continue; + if (VD) { + VarDecl *VDDef = VD->getDefinition(); + if (Type->isReferenceType() && VDDef) { + DSARefChecker Check(DSAStack); + if (Check.Visit(VDDef->getInit())) { + Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; + Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; + continue; + } } } // OpenMP [2.14.3.6, reduction clause, Restrictions] @@ -6424,21 +6484,25 @@ (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) << getLangOpts().CPlusPlus; - bool IsDecl = - VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + if (VD) { + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + } continue; } if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && !getLangOpts().CPlusPlus && Type->isFloatingType()) { Diag(ELoc, diag::err_omp_clause_floating_type_arg); - bool IsDecl = - VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + if (VD) { + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + } continue; } // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced @@ -6452,42 +6516,49 @@ // Any number of reduction clauses can be specified on the directive, // but a list item can appear only once in the reduction clauses for that // directive. - DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); - if (DVar.CKind == OMPC_reduction) { - Diag(ELoc, diag::err_omp_once_referenced) - << getOpenMPClauseName(OMPC_reduction); - if (DVar.RefExpr) { - Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); + DSAStackTy::DSAVarData DVar; + if (VD) { + DVar = DSAStack->getTopDSA(VD, false); + if (DVar.CKind == OMPC_reduction) { + Diag(ELoc, diag::err_omp_once_referenced) + << getOpenMPClauseName(OMPC_reduction); + if (DVar.RefExpr) { + Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); + } + } else if (DVar.CKind != OMPC_unknown) { + Diag(ELoc, diag::err_omp_wrong_dsa) + << getOpenMPClauseName(DVar.CKind) + << getOpenMPClauseName(OMPC_reduction); + ReportOriginalDSA(*this, DSAStack, VD, DVar); + continue; } - } else if (DVar.CKind != OMPC_unknown) { - Diag(ELoc, diag::err_omp_wrong_dsa) - << getOpenMPClauseName(DVar.CKind) - << getOpenMPClauseName(OMPC_reduction); - ReportOriginalDSA(*this, DSAStack, VD, DVar); - continue; } // OpenMP [2.14.3.6, Restrictions, p.1] // A list item that appears in a reduction clause of a worksharing // construct must be shared in the parallel regions to which any of the // worksharing regions arising from the worksharing construct bind. - OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); - if (isOpenMPWorksharingDirective(CurrDir) && - !isOpenMPParallelDirective(CurrDir)) { - DVar = DSAStack->getImplicitDSA(VD, true); - if (DVar.CKind != OMPC_shared) { - Diag(ELoc, diag::err_omp_required_access) - << getOpenMPClauseName(OMPC_reduction) - << getOpenMPClauseName(OMPC_shared); - ReportOriginalDSA(*this, DSAStack, VD, DVar); - continue; + if (VD) { + OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); + if (isOpenMPWorksharingDirective(CurrDir) && + !isOpenMPParallelDirective(CurrDir)) { + DVar = DSAStack->getImplicitDSA(VD, true); + if (DVar.CKind != OMPC_shared) { + Diag(ELoc, diag::err_omp_required_access) + << getOpenMPClauseName(OMPC_reduction) + << getOpenMPClauseName(OMPC_shared); + ReportOriginalDSA(*this, DSAStack, VD, DVar); + continue; + } } } Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); - auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", - VD->hasAttrs() ? &VD->getAttrs() : nullptr); - auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName(), - VD->hasAttrs() ? &VD->getAttrs() : nullptr); + auto *LHSVD = + buildVarDecl(*this, ELoc, Type, ".reduction.lhs", + VD && VD->hasAttrs() ? &VD->getAttrs() : nullptr); + auto *RHSVD = + buildVarDecl(*this, ELoc, Type, VD ? VD->getName() : ".item.", + VD && VD->hasAttrs() ? &VD->getAttrs() : nullptr); // Add initializer for private variable. Expr *Init = nullptr; switch (BOK) { @@ -6602,11 +6673,13 @@ if (!RHSVD->hasInit()) { Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type << ReductionIdRange; - bool IsDecl = - VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(VD->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; + if (VD) { + bool IsDecl = VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + Diag(VD->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) + << VD; + } continue; } auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); @@ -6632,8 +6705,9 @@ if (ReductionOp.isInvalid()) continue; - DSAStack->addDSA(VD, DE, OMPC_reduction); - Vars.push_back(DE); + if (VD) + DSAStack->addDSA(VD, DE, OMPC_reduction); + Vars.push_back(RefExpr); LHSs.push_back(LHSDRE); RHSs.push_back(RHSDRE); ReductionOps.push_back(ReductionOp.get()); Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -11664,16 +11664,6 @@ FoundDecl = MemExpr->getFoundDecl(); Qualifier = MemExpr->getQualifier(); UnbridgedCasts.restore(); - - if (const EnableIfAttr *Attr = CheckEnableIf(Method, Args, true)) { - Diag(MemExprE->getLocStart(), - diag::err_ovl_no_viable_member_function_in_call) - << Method << Method->getSourceRange(); - Diag(Method->getLocation(), - diag::note_ovl_candidate_disabled_by_enable_if_attr) - << Attr->getCond()->getSourceRange() << Attr->getMessage(); - return ExprError(); - } } else { UnresolvedMemberExpr *UnresExpr = cast(NakedMemExpr); Qualifier = UnresExpr->getQualifier(); @@ -11837,6 +11827,21 @@ if (CheckFunctionCall(Method, TheCall, Proto)) return ExprError(); + // In the case the method to call was not selected by the overloading + // resolution process, we still need to handle the enable_if attribute. Do + // that here, so it will not hide previous -- and more relevant -- errors + if (isa(NakedMemExpr)) { + if (const EnableIfAttr *Attr = CheckEnableIf(Method, Args, true)) { + Diag(MemExprE->getLocStart(), + diag::err_ovl_no_viable_member_function_in_call) + << Method << Method->getSourceRange(); + Diag(Method->getLocation(), + diag::note_ovl_candidate_disabled_by_enable_if_attr) + << Attr->getCond()->getSourceRange() << Attr->getMessage(); + return ExprError(); + } + } + if ((isa(CurContext) || isa(CurContext)) && TheCall->getMethodDecl()->isPure()) { Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1390,11 +1390,13 @@ if (Result.isNull()) { declarator.setInvalidType(true); } else if (S.getLangOpts().OpenCL) { - if (const AtomicType *AT = Result->getAs()) { - const BuiltinType *BT = AT->getValueType()->getAs(); - bool NoExtTypes = BT && (BT->getKind() == BuiltinType::Int || - BT->getKind() == BuiltinType::UInt || - BT->getKind() == BuiltinType::Float); + if (Result->getAs()) { + StringRef TypeName = Result.getBaseTypeIdentifier()->getName(); + bool NoExtTypes = + llvm::StringSwitch(TypeName) + .Cases("atomic_int", "atomic_uint", "atomic_float", + "atomic_flag", true) + .Default(false); if (!S.getOpenCLOptions().cl_khr_int64_base_atomics && !NoExtTypes) { S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) << Result << "cl_khr_int64_base_atomics"; @@ -1406,8 +1408,8 @@ << Result << "cl_khr_int64_extended_atomics"; declarator.setInvalidType(true); } - if (!S.getOpenCLOptions().cl_khr_fp64 && BT && - BT->getKind() == BuiltinType::Double) { + if (!S.getOpenCLOptions().cl_khr_fp64 && + !TypeName.compare("atomic_double")) { S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_requires_extension) << Result << "cl_khr_fp64"; declarator.setInvalidType(true); Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -7266,7 +7266,7 @@ TreeTransform::TransformOMPCollapseClause(OMPCollapseClause *C) { ExprResult E = getDerived().TransformExpr(C->getNumForLoops()); if (E.isInvalid()) - return 0; + return nullptr; return getDerived().RebuildOMPCollapseClause( E.get(), C->getLocStart(), C->getLParenLoc(), C->getLocEnd()); } @@ -7373,6 +7373,12 @@ } template +OMPClause *TreeTransform::TransformOMPSIMDClause(OMPSIMDClause *C) { + // No need to rebuild this clause, no template-dependent parameters. + return C; +} + +template OMPClause * TreeTransform::TransformOMPPrivateClause(OMPPrivateClause *C) { llvm::SmallVector Vars; @@ -11292,4 +11298,4 @@ } // end namespace clang -#endif +#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -129,7 +129,6 @@ public: RedeclarableResult(GlobalDeclID FirstID, Decl *MergeWith, bool IsKeyDecl) : FirstID(FirstID), MergeWith(MergeWith), IsKeyDecl(IsKeyDecl) {} - ~RedeclarableResult() {} /// \brief Retrieve the first ID. GlobalDeclID getFirstID() const { return FirstID; } @@ -882,7 +881,7 @@ } void ASTDeclReader::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) { - RedeclarableResult Redecl = VisitTypedefNameDecl(D); + VisitTypedefNameDecl(D); D->Variance = Record[Idx++]; D->Index = Record[Idx++]; Index: lib/Serialization/ASTReaderStmt.cpp =================================================================== --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -1780,6 +1780,9 @@ case OMPC_threads: C = new (Context) OMPThreadsClause(); break; + case OMPC_simd: + C = new (Context) OMPSIMDClause(); + break; case OMPC_private: C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]); break; @@ -1904,6 +1907,8 @@ void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {} +void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {} + void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) { C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); unsigned NumVars = C->varlist_size(); Index: lib/Serialization/ASTWriterDecl.cpp =================================================================== --- lib/Serialization/ASTWriterDecl.cpp +++ lib/Serialization/ASTWriterDecl.cpp @@ -208,7 +208,7 @@ auto &&PartialSpecializations = getPartialSpecializations(Common); ArrayRef LazySpecializations; if (auto *LS = Common->LazySpecializations) - LazySpecializations = ArrayRef(LS + 1, LS + 1 + LS[0]); + LazySpecializations = llvm::makeArrayRef(LS + 1, LS[0]); // Add a slot to the record for the number of specializations. unsigned I = Record.size(); Index: lib/Serialization/ASTWriterStmt.cpp =================================================================== --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -1812,6 +1812,8 @@ void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {} +void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {} + void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) { Record.push_back(C->varlist_size()); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); Index: test/CXX/drs/dr1xx.cpp =================================================================== --- test/CXX/drs/dr1xx.cpp +++ test/CXX/drs/dr1xx.cpp @@ -234,7 +234,7 @@ friend dr125_A::dr125_B (::dr125_C)(); // ok friend dr125_A (::dr125_B::dr125_C)(); // ok friend dr125_A::dr125_B::dr125_C(); // expected-error {{did you mean the constructor name 'dr125_B'?}} - // expected-warning@-1 {{missing exception specification}} + // expected-error@-1 {{missing exception specification}} #if __cplusplus >= 201103L // expected-error@-3 {{follows constexpr declaration}} expected-note@-10 {{here}} #endif Index: test/CXX/drs/dr5xx.cpp =================================================================== --- test/CXX/drs/dr5xx.cpp +++ test/CXX/drs/dr5xx.cpp @@ -7,7 +7,7 @@ // pointing at the implicit operator new. We can't match such a diagnostic // with -verify. __extension__ typedef __SIZE_TYPE__ size_t; -void *operator new(size_t); // expected-warning 0-1{{missing exception spec}} expected-note{{candidate}} +void *operator new(size_t); // expected-error 0-1{{missing exception spec}} expected-note{{candidate}} namespace dr500 { // dr500: dup 372 class D; Index: test/CXX/except/except.spec/p3.cpp =================================================================== --- test/CXX/except/except.spec/p3.cpp +++ test/CXX/except/except.spec/p3.cpp @@ -24,9 +24,9 @@ extern void (*r5)() throw(int); // expected-note {{previous declaration}} extern void (*r5)(); // expected-error {{exception specification in declaration does not match}} -// For functions, we accept this with a warning. +// throw(int) and no spec are not compatible extern void f5() throw(int); // expected-note {{previous declaration}} -extern void f5(); // expected-warning {{missing exception specification}} +extern void f5(); // expected-error {{missing exception specification}} // Different types are not compatible. extern void (*r7)() throw(int); // expected-note {{previous declaration}} Index: test/CXX/except/except.spec/p4.cpp =================================================================== --- test/CXX/except/except.spec/p4.cpp +++ test/CXX/except/except.spec/p4.cpp @@ -19,7 +19,7 @@ void operator delete(void*) noexcept; // expected-note {{here}} }; -void T::a() {} // expected-warning {{missing exception specification 'noexcept'}} +void T::a() {} // expected-error {{missing exception specification 'noexcept'}} T::~T() {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}} void T::operator delete(void*) {} // expected-warning {{function previously declared with an explicit exception specification redeclared with an implicit exception specification}} Index: test/CXX/except/except.spec/p5-pointers.cpp =================================================================== --- test/CXX/except/except.spec/p5-pointers.cpp +++ test/CXX/except/except.spec/p5-pointers.cpp @@ -73,7 +73,7 @@ // Member function stuff struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}} -void Str1::f() // expected-warning {{missing exception specification}} +void Str1::f() // expected-error {{missing exception specification}} { } Index: test/CodeGen/alignment.c =================================================================== --- test/CodeGen/alignment.c +++ test/CodeGen/alignment.c @@ -59,3 +59,11 @@ // CHECK: @test4( // CHECK: store <4 x float> {{.*}}, <4 x float>* {{.*}}, align 64 +// PR24944 - Typedef alignment not honored on no-op cast. +typedef float __attribute__((vector_size(16), aligned(16))) float4align16; +typedef float __attribute__((vector_size(16), aligned(2))) float4align2; +void test6(float4align64 *p) { + float4align64 vec = *(float4align2*) p; +} +// CHECK-LABEL: @test6 +// CHECK: load <4 x float>, <4 x float>* {{.*}}, align 2 Index: test/CodeGen/arm-neon-misc.c =================================================================== --- test/CodeGen/arm-neon-misc.c +++ test/CodeGen/arm-neon-misc.c @@ -14,20 +14,20 @@ void t1(uint64_t *src, uint8_t *dst) { // CHECK: @t1 uint64x2_t q = vld1q_u64(src); -// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64 +// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64.p0i8 vst1q_lane_u64(dst, q, 1); // CHECK: bitcast <16 x i8> %{{.*}} to <2 x i64> // CHECK: shufflevector <2 x i64> -// CHECK: call void @llvm.arm.neon.vst1.v1i64 +// CHECK: call void @llvm.arm.neon.vst1.p0i8.v1i64 } void t2(uint64_t *src1, uint8_t *src2, uint64x2_t *dst) { // CHECK: @t2 uint64x2_t q = vld1q_u64(src1); -// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64 +// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64.p0i8 q = vld1q_lane_u64(src2, q, 0); // CHECK: shufflevector <2 x i64> -// CHECK: call <1 x i64> @llvm.arm.neon.vld1.v1i64 +// CHECK: call <1 x i64> @llvm.arm.neon.vld1.v1i64.p0i8 // CHECK: shufflevector <1 x i64> *dst = q; // CHECK: store <2 x i64> Index: test/CodeGen/arm-vector-align.c =================================================================== --- test/CodeGen/arm-vector-align.c +++ test/CodeGen/arm-vector-align.c @@ -14,9 +14,9 @@ typedef float AlignedAddr __attribute__ ((aligned (16))); void t1(AlignedAddr *addr1, AlignedAddr *addr2) { // CHECK: @t1 -// CHECK: call <4 x float> @llvm.arm.neon.vld1.v4f32(i8* %{{.*}}, i32 16) +// CHECK: call <4 x float> @llvm.arm.neon.vld1.v4f32.p0i8(i8* %{{.*}}, i32 16) float32x4_t a = vld1q_f32(addr1); -// CHECK: call void @llvm.arm.neon.vst1.v4f32(i8* %{{.*}}, <4 x float> %{{.*}}, i32 16) +// CHECK: call void @llvm.arm.neon.vst1.p0i8.v4f32(i8* %{{.*}}, <4 x float> %{{.*}}, i32 16) vst1q_f32(addr2, a); } Index: test/CodeGen/builtins-nvptx.c =================================================================== --- test/CodeGen/builtins-nvptx.c +++ test/CodeGen/builtins-nvptx.c @@ -109,16 +109,15 @@ } -__device__ long read_clocks() { +__device__ long long read_clocks() { // CHECK: call i32 @llvm.ptx.read.clock() // CHECK: call i64 @llvm.ptx.read.clock64() int a = __builtin_ptx_read_clock(); - long b = __builtin_ptx_read_clock64(); - - return (long)a + b; + long long b = __builtin_ptx_read_clock64(); + return a + b; } __device__ int read_pms() { Index: test/CodeGen/builtins-ppc-altivec.c =================================================================== --- test/CodeGen/builtins-ppc-altivec.c +++ test/CodeGen/builtins-ppc-altivec.c @@ -940,6 +940,30 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpeqfp /* vec_cmpge */ + res_vbc = vec_cmpge(vsc, vsc); +// CHECK: @llvm.ppc.altivec.vcmpgtsb +// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb + + res_vbc = vec_cmpge(vuc, vuc); +// CHECK: @llvm.ppc.altivec.vcmpgtub +// CHECK-LE: @llvm.ppc.altivec.vcmpgtub + + res_vbs = vec_cmpge(vs, vs); +// CHECK: @llvm.ppc.altivec.vcmpgtsh +// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh + + res_vbs = vec_cmpge(vus, vus); +// CHECK: @llvm.ppc.altivec.vcmpgtuh +// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh + + res_vbi = vec_cmpge(vi, vi); +// CHECK: @llvm.ppc.altivec.vcmpgtsw +// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw + + res_vbi = vec_cmpge(vui, vui); +// CHECK: @llvm.ppc.altivec.vcmpgtuw +// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw + res_vbi = vec_cmpge(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp // CHECK-LE: @llvm.ppc.altivec.vcmpgefp @@ -1010,6 +1034,30 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtfp /* vec_cmple */ + res_vbc = vec_cmple(vsc, vsc); +// CHECK: @llvm.ppc.altivec.vcmpgtsb +// CHECK-LE: @llvm.ppc.altivec.vcmpgtsb + + res_vbc = vec_cmple(vuc, vuc); +// CHECK: @llvm.ppc.altivec.vcmpgtub +// CHECK-LE: @llvm.ppc.altivec.vcmpgtub + + res_vbs = vec_cmple(vs, vs); +// CHECK: @llvm.ppc.altivec.vcmpgtsh +// CHECK-LE: @llvm.ppc.altivec.vcmpgtsh + + res_vbs = vec_cmple(vus, vus); +// CHECK: @llvm.ppc.altivec.vcmpgtuh +// CHECK-LE: @llvm.ppc.altivec.vcmpgtuh + + res_vbi = vec_cmple(vi, vi); +// CHECK: @llvm.ppc.altivec.vcmpgtsw +// CHECK-LE: @llvm.ppc.altivec.vcmpgtsw + + res_vbi = vec_cmple(vui, vui); +// CHECK: @llvm.ppc.altivec.vcmpgtuw +// CHECK-LE: @llvm.ppc.altivec.vcmpgtuw + res_vbi = vec_cmple(vf, vf); // CHECK: @llvm.ppc.altivec.vcmpgefp // CHECK-LE: @llvm.ppc.altivec.vcmpgefp @@ -5666,6 +5714,10 @@ // CHECK: extractelement <16 x i8> // CHECK-LE: extractelement <16 x i8> + res_uc = vec_extract(vbc, param_i); +// CHECK: extractelement <16 x i8> +// CHECK-LE: extractelement <16 x i8> + res_s = vec_extract(vs, param_i); // CHECK: extractelement <8 x i16> // CHECK-LE: extractelement <8 x i16> @@ -5674,6 +5726,10 @@ // CHECK: extractelement <8 x i16> // CHECK-LE: extractelement <8 x i16> + res_us = vec_extract(vbs, param_i); +// CHECK: extractelement <8 x i16> +// CHECK-LE: extractelement <8 x i16> + res_i = vec_extract(vi, param_i); // CHECK: extractelement <4 x i32> // CHECK-LE: extractelement <4 x i32> @@ -5682,6 +5738,10 @@ // CHECK: extractelement <4 x i32> // CHECK-LE: extractelement <4 x i32> + res_ui = vec_extract(vbi, param_i); +// CHECK: extractelement <4 x i32> +// CHECK-LE: extractelement <4 x i32> + res_f = vec_extract(vf, param_i); // CHECK: extractelement <4 x float> // CHECK-LE: extractelement <4 x float> @@ -5695,6 +5755,10 @@ // CHECK: insertelement <16 x i8> // CHECK-LE: insertelement <16 x i8> + res_vbc = vec_insert(param_uc, vbc, param_i); +// CHECK: insertelement <16 x i8> +// CHECK-LE: insertelement <16 x i8> + res_vs = vec_insert(param_s, vs, param_i); // CHECK: insertelement <8 x i16> // CHECK-LE: insertelement <8 x i16> @@ -5703,6 +5767,10 @@ // CHECK: insertelement <8 x i16> // CHECK-LE: insertelement <8 x i16> + res_vbs = vec_insert(param_us, vbs, param_i); +// CHECK: insertelement <8 x i16> +// CHECK-LE: insertelement <8 x i16> + res_vi = vec_insert(param_i, vi, param_i); // CHECK: insertelement <4 x i32> // CHECK-LE: insertelement <4 x i32> @@ -5711,6 +5779,10 @@ // CHECK: insertelement <4 x i32> // CHECK-LE: insertelement <4 x i32> + res_vbi = vec_insert(param_ui, vbi, param_i); +// CHECK: insertelement <4 x i32> +// CHECK-LE: insertelement <4 x i32> + res_vf = vec_insert(param_f, vf, param_i); // CHECK: insertelement <4 x float> // CHECK-LE: insertelement <4 x float> Index: test/CodeGen/builtins-ppc-crypto.c =================================================================== --- test/CodeGen/builtins-ppc-crypto.c +++ test/CodeGen/builtins-ppc-crypto.c @@ -6,10 +6,6 @@ // RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-unknown \ // RUN: -target-feature +crypto -target-feature +power8-vector \ // RUN: -emit-llvm %s -o - | FileCheck %s - -// RUN: %clang_cc1 -faltivec -triple powerpc-unknown-unknown \ -// RUN: -target-feature +crypto -target-feature +power8-vector \ -// RUN: -emit-llvm %s -o - | FileCheck %s #include #define B_INIT1 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, \ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; @@ -130,7 +126,7 @@ // CHECK: @llvm.ppc.altivec.crypto.vcipherlast } -// CHECK: @llvm.ppc.altivec.crypto.vncipher +// CHECK-LABEL: @test_vncipher vector unsigned long long test_vncipher(void) { vector unsigned long long a = D_INIT1 @@ -302,3 +298,99 @@ // CHECK: @llvm.ppc.altivec.crypto.vshasigmad } +// CHECK-LABEL: @test_vec_sbox_be +vector unsigned char test_vec_sbox_be(void) +{ + vector unsigned char a = B_INIT1 + return vec_sbox_be(a); +// CHECK: @llvm.ppc.altivec.crypto.vsbox +} + +// CHECK-LABEL: @test_vec_cipher_be +vector unsigned char test_vec_cipher_be(void) +{ + vector unsigned char a = B_INIT1 + vector unsigned char b = B_INIT2 + return vec_cipher_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vcipher +} + +// CHECK-LABEL: @test_vec_cipherlast_be +vector unsigned char test_vec_cipherlast_be(void) +{ + vector unsigned char a = B_INIT1 + vector unsigned char b = B_INIT2 + return vec_cipherlast_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vcipherlast +} + +// CHECK-LABEL: @test_vec_ncipher_be +vector unsigned char test_vec_ncipher_be(void) +{ + vector unsigned char a = B_INIT1 + vector unsigned char b = B_INIT2 + return vec_ncipher_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vncipher +} + +// CHECK-LABEL: @test_vec_ncipherlast_be +vector unsigned char test_vec_ncipherlast_be(void) +{ + vector unsigned char a = B_INIT1 + vector unsigned char b = B_INIT2 + return vec_ncipherlast_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vncipherlast +} + +// CHECK-LABEL: @test_vec_shasigma_bew +vector unsigned int test_vec_shasigma_bew(void) +{ + vector unsigned int a = W_INIT1 + return vec_shasigma_be(a, 1, 15); +// CHECK: @llvm.ppc.altivec.crypto.vshasigmaw +} + +// CHECK-LABEL: @test_vec_shasigma_bed +vector unsigned long long test_vec_shasigma_bed(void) +{ + vector unsigned long long a = D_INIT2 + return vec_shasigma_be(a, 1, 15); +// CHECK: @llvm.ppc.altivec.crypto.vshasigmad +} + +// CHECK-LABEL: @test_vec_pmsum_beb +vector unsigned short test_vec_pmsum_beb(void) +{ + vector unsigned char a = B_INIT1 + vector unsigned char b = B_INIT2 + return vec_pmsum_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vpmsumb +} + +// CHECK-LABEL: @test_vec_pmsum_beh +vector unsigned int test_vec_pmsum_beh(void) +{ + vector unsigned short a = H_INIT1 + vector unsigned short b = H_INIT2 + return vec_pmsum_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vpmsumh +} + +// CHECK-LABEL: @test_vec_pmsum_bew +vector unsigned long long test_vec_pmsum_bew(void) +{ + vector unsigned int a = W_INIT1 + vector unsigned int b = W_INIT2 + return vec_pmsum_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vpmsumw +} + +// CHECK-LABEL: @test_vec_pmsum_bed +vector unsigned __int128 test_vec_pmsum_bed(void) +{ + vector unsigned long long a = D_INIT1 + vector unsigned long long b = D_INIT2 + return vec_pmsum_be(a, b); +// CHECK: @llvm.ppc.altivec.crypto.vpmsumd +} + Index: test/CodeGen/builtins-ppc-p8vector.c =================================================================== --- test/CodeGen/builtins-ppc-p8vector.c +++ test/CodeGen/builtins-ppc-p8vector.c @@ -7,6 +7,13 @@ // (vec_cmpge, vec_cmple). Without this option, there is only one overload so // it is selected. +void dummy() { } +signed int si; +signed long long sll; +unsigned long long ull; +signed __int128 sx; +unsigned __int128 ux; +double d; vector signed char vsc = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; vector unsigned char vuc = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 }; vector bool char vbc = { 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1 }; @@ -23,10 +30,17 @@ vector unsigned long long vull = { 1, 2 }; vector bool long long vbll = { 1, 0 }; +vector signed __int128 vsx = { 1 }; +vector unsigned __int128 vux = { 1 }; + vector float vfa = { 1.e-4f, -132.23f, -22.1, 32.00f }; vector double vda = { 1.e-11, -132.23e10 }; int res_i; +double res_d; +signed long long res_sll; +unsigned long long res_ull; + vector signed char res_vsc; vector unsigned char res_vuc; vector bool char res_vbc; @@ -43,7 +57,10 @@ vector unsigned long long res_vull; vector bool long long res_vbll; -vector double res_vf; +vector signed __int128 res_vsx; +vector unsigned __int128 res_vux; + +vector float res_vf; vector double res_vd; // CHECK-LABEL: define void @test1 @@ -73,6 +90,37 @@ // CHECK-LE: add <2 x i64> // CHECK-PPC: error: call to 'vec_add' is ambiguous + /* vec_addc */ + res_vsi = vec_addc(vsi, vsi); +// CHECK: @llvm.ppc.altivec.vaddcuw +// CHECK-LE: @llvm.ppc.altivec.vaddcuw + + res_vui = vec_addc(vui, vui); +// CHECK: @llvm.ppc.altivec.vaddcuw +// CHECK-LE: @llvm.ppc.altivec.vaddcuw + + res_vsx = vec_addc(vsx, vsx); +// CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq + + res_vux = vec_addc(vux, vux); +// CHECK: @llvm.ppc.altivec.vaddcuq +// CHECK-LE: @llvm.ppc.altivec.vaddcuq + + /* vec_adde */ + res_vsx = vec_adde(vsx, vsx, vsx); +// CHECK: @llvm.ppc.altivec.vaddeuqm +// CHECK-LE: @llvm.ppc.altivec.vaddeuqm + + res_vux = vec_adde(vux, vux, vux); +// CHECK: @llvm.ppc.altivec.vaddeuqm +// CHECK-LE: @llvm.ppc.altivec.vaddeuqm + + /* vec_addec */ + res_vsx = vec_addec(vsx, vsx, vsx); +// CHECK: @llvm.ppc.altivec.vaddecuq +// CHECK-LE: @llvm.ppc.altivec.vaddecuq + /* vec_mergee */ res_vbi = vec_mergee(vbi, vbi); // CHECK: @llvm.ppc.altivec.vperm @@ -156,6 +204,15 @@ // CHECK-LE: call <2 x i64> @llvm.ppc.altivec.vcmpgtud(<2 x i64> %{{[0-9]*}}, <2 x i64> %{{[0-9]*}}) // CHECK-PPC: error: call to 'vec_cmplt' is ambiguous + /* vec_double */ + res_vd = vec_double(vsll); +// CHECK: sitofp i64 {{.+}} to double +// CHECK-BE: sitofp i64 {{.+}} to double + + res_vd = vec_double(vull); +// CHECK: uitofp i64 {{.+}} to double +// CHECK-BE: uitofp i64 {{.+}} to double + /* vec_eqv */ res_vsc = vec_eqv(vsc, vsc); // CHECK: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> @@ -168,18 +225,7 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <16 x i8> // CHECK-PPC: error: assigning to - res_vsc = vec_eqv(vbc, vsc); -// CHECK: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <16 x i8> -// CHECK-LE: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <16 x i8> -// CHECK-PPC: error: assigning to - - res_vsc = vec_eqv(vsc, vbc); + res_vsc = vec_eqv(vbc, vbc); // CHECK: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> // CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) @@ -201,28 +247,6 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <16 x i8> // CHECK-PPC: error: assigning to - res_vuc = vec_eqv(vbc, vuc); -// CHECK: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <16 x i8> -// CHECK-LE: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <16 x i8> -// CHECK-PPC: error: assigning to - - res_vuc = vec_eqv(vuc, vbc); -// CHECK: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <16 x i8> -// CHECK-LE: [[T1:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <16 x i8> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <16 x i8> -// CHECK-PPC: error: assigning to - res_vss = vec_eqv(vss, vss); // CHECK: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> @@ -234,18 +258,7 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <8 x i16> // CHECK-PPC: error: assigning to - res_vss = vec_eqv(vbs, vss); -// CHECK: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <8 x i16> -// CHECK-LE: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <8 x i16> -// CHECK-PPC: error: assigning to - - res_vss = vec_eqv(vss, vbs); + res_vss = vec_eqv(vbs, vbs); // CHECK: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> // CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) @@ -267,39 +280,12 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <8 x i16> // CHECK-PPC: error: assigning to - res_vus = vec_eqv(vbs, vus); -// CHECK: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <8 x i16> -// CHECK-LE: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <8 x i16> -// CHECK-PPC: error: assigning to - - res_vus = vec_eqv(vus, vbs); -// CHECK: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <8 x i16> -// CHECK-LE: [[T1:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <8 x i16> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <8 x i16> -// CHECK-PPC: error: assigning to - res_vsi = vec_eqv(vsi, vsi); // CHECK: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) // CHECK-LE: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) // CHECK-PPC: error: assigning to - res_vsi = vec_eqv(vbi, vsi); -// CHECK: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) -// CHECK-LE: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) -// CHECK-PPC: error: assigning to - - res_vsi = vec_eqv(vsi, vbi); + res_vsi = vec_eqv(vbi, vbi); // CHECK: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) // CHECK-LE: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) // CHECK-PPC: error: assigning to @@ -309,16 +295,6 @@ // CHECK-LE: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) // CHECK-PPC: error: assigning to - res_vui = vec_eqv(vbi, vui); -// CHECK: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) -// CHECK-LE: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) -// CHECK-PPC: error: assigning to - - res_vui = vec_eqv(vui, vbi); -// CHECK: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) -// CHECK-LE: call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.*}}, <4 x i32> {{.+}}) -// CHECK-PPC: error: assigning to - res_vsll = vec_eqv(vsll, vsll); // CHECK: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> @@ -330,18 +306,7 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x i64> // CHECK-PPC: error: assigning to - res_vsll = vec_eqv(vbll, vsll); -// CHECK: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <2 x i64> -// CHECK-LE: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x i64> -// CHECK-PPC: error: assigning to - - res_vsll = vec_eqv(vsll, vbll); + res_vsll = vec_eqv(vbll, vbll); // CHECK: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> // CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) @@ -363,28 +328,6 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x i64> // CHECK-PPC: error: assigning to - res_vull = vec_eqv(vbll, vull); -// CHECK: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <2 x i64> -// CHECK-LE: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x i64> -// CHECK-PPC: error: assigning to - - res_vull = vec_eqv(vull, vbll); -// CHECK: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <2 x i64> -// CHECK-LE: [[T1:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK-LE: [[T2:%.+]] = bitcast <2 x i64> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x i64> -// CHECK-PPC: error: assigning to - res_vf = vec_eqv(vfa, vfa); // CHECK: [[T1:%.+]] = bitcast <4 x float> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <4 x float> {{.+}} to <4 x i32> @@ -396,23 +339,6 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <4 x float> // CHECK-PPC: error: assigning to - res_vf = vec_eqv(vbi, vfa); -// CHECK: [[T2:%.+]] = bitcast <4 x float> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.+}}, <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <4 x float> -// CHECK-LE: [[T2:%.+]] = bitcast <4 x float> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.+}}, <4 x i32> [[T2]]) -// CHECK-PPC: error: assigning to - - res_vf = vec_eqv(vfa, vbi); -// CHECK: [[T1:%.+]] = bitcast <4 x float> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> -// CHECK: bitcast <4 x i32> [[T3]] to <4 x float> -// CHECK-LE: [[T1:%.+]] = bitcast <4 x float> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> -// CHECK-LE: bitcast <4 x i32> [[T3]] to <4 x float> -// CHECK-PPC: error: assigning to - res_vd = vec_eqv(vda, vda); // CHECK: [[T1:%.+]] = bitcast <2 x double> {{.+}} to <4 x i32> // CHECK: [[T2:%.+]] = bitcast <2 x double> {{.+}} to <4 x i32> @@ -424,24 +350,41 @@ // CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x double> // CHECK-PPC: error: assigning to - res_vd = vec_eqv(vbll, vda); -// CHECK: [[T2:%.+]] = bitcast <2 x double> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.+}}, <4 x i32> [[T2]]) -// CHECK: bitcast <4 x i32> [[T3]] to <2 x double> -// CHECK-LE: [[T2:%.+]] = bitcast <2 x double> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> {{.+}}, <4 x i32> [[T2]]) -// CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x double> -// CHECK-PPC: error: assigning to + /* vec_extract */ + res_sll = vec_extract(vsll, si); +// CHECK: extractelement <2 x i64> +// CHECK-LE: extractelement <2 x i64> - res_vd = vec_eqv(vda, vbll); -// CHECK: [[T1:%.+]] = bitcast <2 x double> {{.+}} to <4 x i32> -// CHECK: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> -// CHECK: bitcast <4 x i32> [[T3]] to <2 x double> -// CHECK-LE: [[T1:%.+]] = bitcast <2 x double> {{.+}} to <4 x i32> -// CHECK-LE: [[T3:%.+]] = call <4 x i32> @llvm.ppc.vsx.xxleqv(<4 x i32> [[T1]], <4 x i32> -// CHECK-LE: bitcast <4 x i32> [[T3]] to <2 x double> -// CHECK-PPC: error: assigning to + res_ull = vec_extract(vull, si); +// CHECK: extractelement <2 x i64> +// CHECK-LE: extractelement <2 x i64> + + res_ull = vec_extract(vbll, si); +// CHECK: extractelement <2 x i64> +// CHECK-LE: extractelement <2 x i64> + + res_d = vec_extract(vda, si); +// CHECK: extractelement <2 x double> +// CHECK-LE: extractelement <2 x double> + + /* vec_insert */ + res_vsll = vec_insert(sll, vsll, si); +// CHECK: insertelement <2 x i64> +// CHECK-LE: insertelement <2 x i64> + + res_vbll = vec_insert(ull, vbll, si); +// CHECK: insertelement <2 x i64> +// CHECK-LE: insertelement <2 x i64> + + res_vull = vec_insert(ull, vull, si); +// CHECK: insertelement <2 x i64> +// CHECK-LE: insertelement <2 x i64> + res_vd = vec_insert(d, vda, si); +// CHECK: insertelement <2 x double> +// CHECK-LE: insertelement <2 x double> + + /* vec_cntlz */ res_vsc = vec_cntlz(vsc); // CHECK: call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %{{.+}}, i1 false) // CHECK-LE: call <16 x i8> @llvm.ctlz.v16i8(<16 x i8> %{{.+}}, i1 false) @@ -512,6 +455,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpequd.p // CHECK-PPC: error: call to 'vec_all_eq' is ambiguous + res_i = vec_all_eq(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + /* vec_all_ne */ res_i = vec_all_ne(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpequd.p @@ -548,6 +495,24 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpequd.p // CHECK-PPC: error: call to 'vec_all_ne' is ambiguous + dummy(); +// CHECK: @dummy + + res_i = vec_all_ne(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + + dummy(); +// CHECK: @dummy + + res_i = vec_all_nge(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + + res_i = vec_all_ngt(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + /* vec_any_eq */ res_i = vec_any_eq(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpequd.p @@ -584,6 +549,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpequd.p // CHECK-PPC: error: call to 'vec_any_eq' is ambiguous + res_i = vec_any_eq(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + /* vec_any_ne */ res_i = vec_any_ne(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpequd.p @@ -620,6 +589,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpequd.p // CHECK-PPC: error: call to 'vec_any_ne' is ambiguous + res_i = vec_any_ne(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + /* vec_all_ge */ res_i = vec_all_ge(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -656,6 +629,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_all_ge' is ambiguous + res_i = vec_all_ge(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + /* vec_all_gt */ res_i = vec_all_gt(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -692,6 +669,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_all_gt' is ambiguous + res_i = vec_all_gt(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + /* vec_all_le */ res_i = vec_all_le(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -728,6 +709,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_all_le' is ambiguous + res_i = vec_all_le(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + /* vec_all_lt */ res_i = vec_all_lt(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -764,6 +749,14 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_all_lt' is ambiguous + res_i = vec_all_lt(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + + res_i = vec_all_nan(vda); +// CHECK: @llvm.ppc.vsx.xvcmpeqdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpeqdp.p + /* vec_any_ge */ res_i = vec_any_ge(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -800,6 +793,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_any_ge' is ambiguous + res_i = vec_any_ge(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + /* vec_any_gt */ res_i = vec_any_gt(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -836,6 +833,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_any_gt' is ambiguous + res_i = vec_any_gt(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + /* vec_any_le */ res_i = vec_any_le(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -872,6 +873,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_any_le' is ambiguous + res_i = vec_any_le(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgedp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgedp.p + /* vec_any_lt */ res_i = vec_any_lt(vsll, vsll); // CHECK: @llvm.ppc.altivec.vcmpgtsd.p @@ -908,6 +913,10 @@ // CHECK-LE: @llvm.ppc.altivec.vcmpgtud.p // CHECK-PPC: error: call to 'vec_any_lt' is ambiguous + res_i = vec_any_lt(vda, vda); +// CHECK: @llvm.ppc.vsx.xvcmpgtdp.p +// CHECK-LE: @llvm.ppc.vsx.xvcmpgtdp.p + /* vec_max */ res_vsll = vec_max(vsll, vsll); // CHECK: @llvm.ppc.altivec.vmaxsd @@ -939,6 +948,15 @@ // CHECK-LE: @llvm.ppc.altivec.vmaxud // CHECK-PPC: error: call to 'vec_max' is ambiguous + /* vec_mergeh */ + res_vbll = vec_mergeh(vbll, vbll); +// CHECK: @llvm.ppc.altivec.vperm +// CHECK-LE: @llvm.ppc.altivec.vperm + + res_vbll = vec_mergel(vbll, vbll); +// CHECK: @llvm.ppc.altivec.vperm +// CHECK-LE: @llvm.ppc.altivec.vperm + /* vec_min */ res_vsll = vec_min(vsll, vsll); // CHECK: @llvm.ppc.altivec.vminsd @@ -1058,6 +1076,28 @@ // CHECK-LE: ashr <2 x i64> // CHECK-PPC: error: call to 'vec_sra' is ambiguous + /* vec_splats */ + res_vsll = vec_splats(sll); +// CHECK: insertelement <2 x i64> +// CHECK-LE: insertelement <2 x i64> + + res_vull = vec_splats(ull); +// CHECK: insertelement <2 x i64> +// CHECK-LE: insertelement <2 x i64> + + res_vsx = vec_splats(sx); +// CHECK: insertelement <1 x i128> +// CHECK-LE: insertelement <1 x i128> + + res_vux = vec_splats(ux); +// CHECK: insertelement <1 x i128> +// CHECK-LE: insertelement <1 x i128> + + res_vd = vec_splats(d); +// CHECK: insertelement <2 x double> +// CHECK-LE: insertelement <2 x double> + + /* vec_unpackh */ res_vsll = vec_unpackh(vsi); // CHECK: llvm.ppc.altivec.vupkhsw @@ -1177,13 +1217,7 @@ // CHECK-LE: xor <16 x i8> [[T1]], // CHECK-PPC: warning: implicit declaration of function 'vec_nand' is invalid in C99 - res_vsc = vec_nand(vsc, vbc); -// CHECK: [[T1:%.+]] = and <16 x i8> -// CHECK: xor <16 x i8> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <16 x i8> -// CHECK-LE: xor <16 x i8> [[T1]], - - res_vsc = vec_nand(vbc, vsc); + res_vsc = vec_nand(vbc, vbc); // CHECK: [[T1:%.+]] = and <16 x i8> // CHECK: xor <16 x i8> [[T1]], // CHECK-LE: [[T1:%.+]] = and <16 x i8> @@ -1195,31 +1229,13 @@ // CHECK-LE: [[T1:%.+]] = and <16 x i8> // CHECK-LE: xor <16 x i8> [[T1]], - res_vuc = vec_nand(vuc, vbc); -// CHECK: [[T1:%.+]] = and <16 x i8> -// CHECK: xor <16 x i8> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <16 x i8> -// CHECK-LE: xor <16 x i8> [[T1]], - - res_vuc = vec_nand(vbc, vuc); -// CHECK: [[T1:%.+]] = and <16 x i8> -// CHECK: xor <16 x i8> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <16 x i8> -// CHECK-LE: xor <16 x i8> [[T1]], - res_vss = vec_nand(vss, vss); // CHECK: [[T1:%.+]] = and <8 x i16> // CHECK: xor <8 x i16> [[T1]], // CHECK-LE: [[T1:%.+]] = and <8 x i16> // CHECK-LE: xor <8 x i16> [[T1]], - res_vss = vec_nand(vss, vbs); -// CHECK: [[T1:%.+]] = and <8 x i16> -// CHECK: xor <8 x i16> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <8 x i16> -// CHECK-LE: xor <8 x i16> [[T1]], - - res_vss = vec_nand(vbs, vss); + res_vss = vec_nand(vbs, vbs); // CHECK: [[T1:%.+]] = and <8 x i16> // CHECK: xor <8 x i16> [[T1]], // CHECK-LE: [[T1:%.+]] = and <8 x i16> @@ -1231,31 +1247,13 @@ // CHECK-LE: [[T1:%.+]] = and <8 x i16> // CHECK-LE: xor <8 x i16> [[T1]], - res_vus = vec_nand(vus, vbs); -// CHECK: [[T1:%.+]] = and <8 x i16> -// CHECK: xor <8 x i16> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <8 x i16> -// CHECK-LE: xor <8 x i16> [[T1]], - - res_vus = vec_nand(vbs, vus); -// CHECK: [[T1:%.+]] = and <8 x i16> -// CHECK: xor <8 x i16> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <8 x i16> -// CHECK-LE: xor <8 x i16> [[T1]], - res_vsi = vec_nand(vsi, vsi); // CHECK: [[T1:%.+]] = and <4 x i32> // CHECK: xor <4 x i32> [[T1]], // CHECK-LE: [[T1:%.+]] = and <4 x i32> // CHECK-LE: xor <4 x i32> [[T1]], - res_vsi = vec_nand(vsi, vbi); -// CHECK: [[T1:%.+]] = and <4 x i32> -// CHECK: xor <4 x i32> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <4 x i32> -// CHECK-LE: xor <4 x i32> [[T1]], - - res_vsi = vec_nand(vbi, vsi); + res_vsi = vec_nand(vbi, vbi); // CHECK: [[T1:%.+]] = and <4 x i32> // CHECK: xor <4 x i32> [[T1]], // CHECK-LE: [[T1:%.+]] = and <4 x i32> @@ -1267,31 +1265,13 @@ // CHECK-LE: [[T1:%.+]] = and <4 x i32> // CHECK-LE: xor <4 x i32> [[T1]], - res_vui = vec_nand(vui, vbi); -// CHECK: [[T1:%.+]] = and <4 x i32> -// CHECK: xor <4 x i32> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <4 x i32> -// CHECK-LE: xor <4 x i32> [[T1]], - - res_vui = vec_nand(vbi, vui); -// CHECK: [[T1:%.+]] = and <4 x i32> -// CHECK: xor <4 x i32> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <4 x i32> -// CHECK-LE: xor <4 x i32> [[T1]], - res_vsll = vec_nand(vsll, vsll); // CHECK: [[T1:%.+]] = and <2 x i64> // CHECK: xor <2 x i64> [[T1]], // CHECK-LE: [[T1:%.+]] = and <2 x i64> // CHECK-LE: xor <2 x i64> [[T1]], - res_vsll = vec_nand(vsll, vbll); -// CHECK: [[T1:%.+]] = and <2 x i64> -// CHECK: xor <2 x i64> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <2 x i64> -// CHECK-LE: xor <2 x i64> [[T1]], - - res_vsll = vec_nand(vbll, vsll); + res_vsll = vec_nand(vbll, vbll); // CHECK: [[T1:%.+]] = and <2 x i64> // CHECK: xor <2 x i64> [[T1]], // CHECK-LE: [[T1:%.+]] = and <2 x i64> @@ -1303,18 +1283,6 @@ // CHECK-LE: [[T1:%.+]] = and <2 x i64> // CHECK-LE: xor <2 x i64> [[T1]], - res_vull = vec_nand(vull, vbll); -// CHECK: [[T1:%.+]] = and <2 x i64> -// CHECK: xor <2 x i64> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <2 x i64> -// CHECK-LE: xor <2 x i64> [[T1]], - - res_vull = vec_nand(vbll, vull); -// CHECK: [[T1:%.+]] = and <2 x i64> -// CHECK: xor <2 x i64> [[T1]], -// CHECK-LE: [[T1:%.+]] = and <2 x i64> -// CHECK-LE: xor <2 x i64> [[T1]], - /* vec_orc */ res_vsc = vec_orc(vsc, vsc); // CHECK: [[T1:%.+]] = xor <16 x i8> {{%.+}}, @@ -1353,6 +1321,12 @@ // CHECK-LE: [[T1:%.+]] = xor <16 x i8> {{%.+}}, // CHECK-LE: or <16 x i8> {{%.+}}, [[T1]] + res_vbc = vec_orc(vbc, vbc); +// CHECK: [[T1:%.+]] = xor <16 x i8> {{%.+}}, +// CHECK: or <16 x i8> {{%.+}}, [[T1]] +// CHECK-LE: [[T1:%.+]] = xor <16 x i8> {{%.+}}, +// CHECK-LE: or <16 x i8> {{%.+}}, [[T1]] + res_vss = vec_orc(vss, vss); // CHECK: [[T1:%.+]] = xor <8 x i16> {{%.+}}, // CHECK: or <8 x i16> {{%.+}}, [[T1]] @@ -1389,6 +1363,12 @@ // CHECK-LE: [[T1:%.+]] = xor <8 x i16> {{%.+}}, // CHECK-LE: or <8 x i16> {{%.+}}, [[T1]] + res_vbs = vec_orc(vbs, vbs); +// CHECK: [[T1:%.+]] = xor <8 x i16> {{%.+}}, +// CHECK: or <8 x i16> {{%.+}}, [[T1]] +// CHECK-LE: [[T1:%.+]] = xor <8 x i16> {{%.+}}, +// CHECK-LE: or <8 x i16> {{%.+}}, [[T1]] + res_vsi = vec_orc(vsi, vsi); // CHECK: [[T1:%.+]] = xor <4 x i32> {{%.+}}, // CHECK: or <4 x i32> {{%.+}}, [[T1]] @@ -1425,6 +1405,12 @@ // CHECK-LE: [[T1:%.+]] = xor <4 x i32> {{%.+}}, // CHECK-LE: or <4 x i32> {{%.+}}, [[T1]] + res_vbi = vec_orc(vbi, vbi); +// CHECK: [[T1:%.+]] = xor <4 x i32> {{%.+}}, +// CHECK: or <4 x i32> {{%.+}}, [[T1]] +// CHECK-LE: [[T1:%.+]] = xor <4 x i32> {{%.+}}, +// CHECK-LE: or <4 x i32> {{%.+}}, [[T1]] + res_vsll = vec_orc(vsll, vsll); // CHECK: [[T1:%.+]] = xor <2 x i64> {{%.+}}, // CHECK: or <2 x i64> {{%.+}}, [[T1]] @@ -1461,6 +1447,33 @@ // CHECK-LE: [[T1:%.+]] = xor <2 x i64> {{%.+}}, // CHECK-LE: or <2 x i64> {{%.+}}, [[T1]] + res_vbll = vec_orc(vbll, vbll); +// CHECK: [[T1:%.+]] = xor <2 x i64> {{%.+}}, +// CHECK: or <2 x i64> {{%.+}}, [[T1]] +// CHECK-LE: [[T1:%.+]] = xor <2 x i64> {{%.+}}, +// CHECK-LE: or <2 x i64> {{%.+}}, [[T1]] + + /* vec_sub */ + res_vsll = vec_sub(vsll, vsll); +// CHECK: sub <2 x i64> +// CHECK-LE: sub <2 x i64> + + res_vull = vec_sub(vull, vull); +// CHECK: sub <2 x i64> +// CHECK-LE: sub <2 x i64> + + res_vd = vec_sub(vda, vda); +// CHECK: fsub <2 x double> +// CHECK-LE: fsub <2 x double> + + res_vsx = vec_sub(vsx, vsx); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> + + res_vux = vec_sub(vux, vux); +// CHECK: sub <1 x i128> +// CHECK-LE: sub <1 x i128> + /* vec_vbpermq */ res_vsll = vec_vbpermq(vsc, vsc); // CHECK: llvm.ppc.altivec.vbpermq @@ -1480,4 +1493,14 @@ // CHECK: llvm.ppc.altivec.vgbbd // CHECK-LE: llvm.ppc.altivec.vgbbd // CHECK-PPC: warning: implicit declaration of function 'vec_vgbbd' + + res_vuc = vec_gb(vuc); +// CHECK: llvm.ppc.altivec.vgbbd +// CHECK-LE: llvm.ppc.altivec.vgbbd +// CHECK-PPC: warning: implicit declaration of function 'vec_gb' + + res_vull = vec_bperm(vux, vux); +// CHECK: llvm.ppc.altivec.vbpermq +// CHECK-LE: llvm.ppc.altivec.vbpermq +// CHECK-PPC: warning: implicit declaration of function 'vec_bperm' } Index: test/CodeGen/nvptx-inlineasm-ptx.c =================================================================== --- test/CodeGen/nvptx-inlineasm-ptx.c +++ test/CodeGen/nvptx-inlineasm-ptx.c @@ -8,8 +8,8 @@ unsigned short us; int i; unsigned int ui; - long l; - unsigned long ul; + long long ll; + unsigned long long ull; float f; double d; @@ -29,9 +29,9 @@ asm volatile ("mov.b32 %0, %1;" : "=r"(ui) : "r"(ui)); // CHECK: i64 asm sideeffect "mov.b64 $0, $1;", "=l,l" - asm volatile ("mov.b64 %0, %1;" : "=l"(l) : "l"(l)); + asm volatile ("mov.b64 %0, %1;" : "=l"(ll) : "l"(ll)); // CHECK: i64 asm sideeffect "mov.b64 $0, $1;", "=l,l" - asm volatile ("mov.b64 %0, %1;" : "=l"(ul) : "l"(ul)); + asm volatile ("mov.b64 %0, %1;" : "=l"(ull) : "l"(ull)); // CHECK: float asm sideeffect "mov.b32 $0, $1;", "=f,f" asm volatile ("mov.b32 %0, %1;" : "=f"(f) : "f"(f)); Index: test/CodeGen/vld_dup.c =================================================================== --- test/CodeGen/vld_dup.c +++ test/CodeGen/vld_dup.c @@ -14,7 +14,7 @@ int64_t v7[4]; v1 = vld3_dup_s32(v0); -// CHECK: [[T168:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld3lane.v2i32(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) +// CHECK: [[T168:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld3lane.v2i32.p0i8(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) // CHECK-NEXT: [[T169:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T168]], 0 // CHECK-NEXT: [[T170:%.*]] = shufflevector <2 x i32> [[T169]], <2 x i32> [[T169]], <2 x i32> zeroinitializer // CHECK-NEXT: [[T171:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T168]], <2 x i32> [[T170]], 0 @@ -26,7 +26,7 @@ // CHECK-NEXT: [[T177:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32> } [[T174]], <2 x i32> [[T176]], 2 v3 = vld4_dup_s32(v2); -// CHECK: [[T178:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld4lane.v2i32(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) +// CHECK: [[T178:%.*]] = call { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } @llvm.arm.neon.vld4lane.v2i32.p0i8(i8* {{.*}}, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, <2 x i32> undef, i32 {{[0-9]+}}, i32 {{[0-9]+}}) // CHECK-NEXT: [[T179:%.*]] = extractvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T178]], 0 // CHECK-NEXT: [[T180:%.*]] = shufflevector <2 x i32> [[T179]], <2 x i32> [[T179]], <2 x i32> zeroinitializer // CHECK-NEXT: [[T181:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T178]], <2 x i32> [[T180]], 0 @@ -41,10 +41,10 @@ // CHECK-NEXT: [[T190:%.*]] = insertvalue { <2 x i32>, <2 x i32>, <2 x i32>, <2 x i32> } [[T187]], <2 x i32> [[T189]], 3 v4 = vld3_dup_s64(v6); -// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld3.v1i64(i8* {{.*}}, i32 {{[0-9]+}}) +// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld3.v1i64.p0i8(i8* {{.*}}, i32 {{[0-9]+}}) v5 = vld4_dup_s64(v7); -// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld4.v1i64(i8* {{.*}}, i32 {{[0-9]+}}) +// CHECK: {{%.*}} = call { <1 x i64>, <1 x i64>, <1 x i64>, <1 x i64> } @llvm.arm.neon.vld4.v1i64.p0i8(i8* {{.*}}, i32 {{[0-9]+}}) return 0; } Index: test/CodeGenCXX/exceptions.cpp =================================================================== --- test/CodeGenCXX/exceptions.cpp +++ test/CodeGenCXX/exceptions.cpp @@ -2,6 +2,9 @@ typedef __typeof(sizeof(0)) size_t; +// Declare the reserved global placement new. +void *operator new(size_t, void*); + // This just shouldn't crash. namespace test0 { struct allocator { @@ -526,4 +529,21 @@ // (After this is a terminate landingpad.) } +namespace test12 { + struct A { + void operator delete(void *, void *); + A(); + }; + + A *test(void *ptr) { + return new (ptr) A(); + } + // CHECK-LABEL: define {{.*}} @_ZN6test124testEPv( + // CHECK: [[PTR:%.*]] = load i8*, i8* + // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[PTR]] to [[A:%.*]]* + // CHECK-NEXT: invoke void @_ZN6test121AC1Ev([[A]]* [[CAST]]) + // CHECK: ret [[A]]* [[CAST]] + // CHECK: invoke void @_ZN6test121AdlEPvS1_(i8* [[PTR]], i8* [[PTR]]) +} + // CHECK: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind } Index: test/CodeGenCXX/vtable-assume-load.cpp =================================================================== --- test/CodeGenCXX/vtable-assume-load.cpp +++ test/CodeGenCXX/vtable-assume-load.cpp @@ -1,5 +1,6 @@ -// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions -// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o %t.ll -O1 -disable-llvm-optzns -fms-extensions -fstrict-vtable-pointers +// RUN: %clang_cc1 %s -triple i686-pc-win32 -emit-llvm -o %t.ms.ll -O1 -disable-llvm-optzns -fms-extensions -fstrict-vtable-pointers +// FIXME: Assume load should not require -fstrict-vtable-pointers // RUN: FileCheck --check-prefix=CHECK1 --input-file=%t.ll %s // RUN: FileCheck --check-prefix=CHECK2 --input-file=%t.ll %s Index: test/CodeGenObjCXX/arc-cxx11-init-list.mm =================================================================== --- test/CodeGenObjCXX/arc-cxx11-init-list.mm +++ test/CodeGenObjCXX/arc-cxx11-init-list.mm @@ -41,8 +41,6 @@ } // CHECK: [[INSTANCE:%.*]] = {{.*}} call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* {{.*}}, i8* {{.*}}) -// CHECK-NEXT: [[CAST:%.*]] = bitcast [1 x %0*]* %{{.*}} to i8** -// CHECK-NEXT: store i8* [[INSTANCE]], i8** [[CAST]], // CHECK: {{.*}} call void @_Z8externalv() // CHECK: {{.*}} call void @objc_release(i8* {{.*}}) Index: test/Driver/arm-compiler-rt.c =================================================================== --- /dev/null +++ test/Driver/arm-compiler-rt.c @@ -0,0 +1,21 @@ +// RUN: %clang -target arm-linux-gnueabi -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABI +// ARM-GNUEABI: "{{.*[/\\]}}libclang_rt.builtins-arm.a" + +// RUN: %clang -target arm-linux-gnueabi -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABI-ABI +// ARM-GNUEABI-ABI: "{{.*[/\\]}}libclang_rt.builtins-armhf.a" + +// RUN: %clang -target arm-linux-gnueabihf -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABIHF +// ARM-GNUEABIHF: "{{.*[/\\]}}libclang_rt.builtins-armhf.a" + +// RUN: %clang -target arm-linux-gnueabihf -rtlib=compiler-rt -mfloat-abi=soft -### %s 2>&1 | FileCheck %s -check-prefix ARM-GNUEABIHF-ABI +// ARM-GNUEABIHF-ABI: "{{.*[/\\]}}libclang_rt.builtins-arm.a" + +// RUN: %clang -target arm-windows-itanium -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-WINDOWS +// ARM-WINDOWS: "{{.*[/\\]}}clang_rt.builtins-arm.lib" + +// RUN: %clang -target arm-linux-androideabi -rtlib=compiler-rt -### %s 2>&1 | FileCheck %s -check-prefix ARM-ANDROID +// ARM-ANDROID: "{{.*[/\\]}}libclang_rt.builtins-arm-android.a" + +// RUN: %clang -target arm-linux-androideabi -rtlib=compiler-rt -mfloat-abi=hard -### %s 2>&1 | FileCheck %s -check-prefix ARM-ANDROIDHF +// ARM-ANDROIDHF: "{{.*[/\\]}}libclang_rt.builtins-armhf-android.a" + Index: test/FixIt/fixit.cpp =================================================================== --- test/FixIt/fixit.cpp +++ test/FixIt/fixit.cpp @@ -45,7 +45,7 @@ }; void f() throw(); // expected-note{{previous}} -void f(); // expected-warning{{missing exception specification}} +void f(); // expected-error{{missing exception specification}} namespace rdar7853795 { struct A { Index: test/Frontend/Inputs/profile-sample-use-loc-tracking.prof =================================================================== --- test/Frontend/Inputs/profile-sample-use-loc-tracking.prof +++ test/Frontend/Inputs/profile-sample-use-loc-tracking.prof @@ -1,2 +1,2 @@ bar:100:100 -1: 2000 + 1: 2000 Index: test/Index/availability.cpp =================================================================== --- /dev/null +++ test/Index/availability.cpp @@ -0,0 +1,13 @@ +void foo() = delete; + +struct Foo { + int foo() = delete; + Foo() = delete; +}; + + +// RUN: c-index-test -test-print-type --std=c++11 %s | FileCheck %s +// CHECK: FunctionDecl=foo:1:6 (unavailable) [type=void ()] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] +// CHECK: StructDecl=Foo:3:8 (Definition) [type=Foo] [typekind=Record] [isPOD=1] +// CHECK: CXXMethod=foo:4:7 (unavailable) [type=int (){{.*}}] [typekind=FunctionProto] [resulttype=int] [resulttypekind=Int] [isPOD=0] +// CHECK: CXXConstructor=Foo:5:3 (unavailable) [type=void (){{.*}}] [typekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [isPOD=0] Index: test/Misc/warning-flags.c =================================================================== --- test/Misc/warning-flags.c +++ test/Misc/warning-flags.c @@ -18,7 +18,7 @@ The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (90): +CHECK: Warnings without flags (89): CHECK-NEXT: ext_excess_initializers CHECK-NEXT: ext_excess_initializers_in_char_array_initializer CHECK-NEXT: ext_expected_semi_decl_list @@ -80,7 +80,6 @@ CHECK-NEXT: warn_method_param_redefinition CHECK-NEXT: warn_missing_case_for_condition CHECK-NEXT: warn_missing_dependent_template_keyword -CHECK-NEXT: warn_missing_exception_specification CHECK-NEXT: warn_missing_whitespace_after_macro_name CHECK-NEXT: warn_mt_message CHECK-NEXT: warn_no_constructor_for_refconst Index: test/OpenMP/for_reduction_messages.cpp =================================================================== --- test/OpenMP/for_reduction_messages.cpp +++ test/OpenMP/for_reduction_messages.cpp @@ -128,27 +128,27 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp for reduction(max : qa[1]) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -160,7 +160,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -184,7 +184,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) @@ -277,27 +277,27 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp for reduction(max : argv[1]) for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -309,7 +309,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -341,7 +341,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) Index: test/OpenMP/for_simd_reduction_messages.cpp =================================================================== --- test/OpenMP/for_simd_reduction_messages.cpp +++ test/OpenMP/for_simd_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -112,7 +113,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -128,27 +129,27 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -160,7 +161,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -184,7 +185,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) @@ -261,7 +262,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -277,27 +278,27 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -309,7 +310,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -337,7 +338,7 @@ for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) Index: test/OpenMP/ordered_ast_print.cpp =================================================================== --- test/OpenMP/ordered_ast_print.cpp +++ test/OpenMP/ordered_ast_print.cpp @@ -24,6 +24,24 @@ { a=2; } + #pragma omp simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp parallel for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } return (0); } @@ -40,6 +58,24 @@ // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } // CHECK: static T a; // CHECK-NEXT: #pragma omp for ordered @@ -54,6 +90,24 @@ // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } int main (int argc, char **argv) { int b = argc, c, d, e, f, g; @@ -71,6 +125,24 @@ { a=2; } + #pragma omp simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } + #pragma omp parallel for simd + for (int i =0 ; i < argc; ++i) + #pragma omp ordered simd + { + a=2; + } // CHECK-NEXT: #pragma omp for ordered // CHECK-NEXT: for (int i = 0; i < argc; ++i) // CHECK-NEXT: #pragma omp ordered @@ -83,6 +155,24 @@ // CHECK-NEXT: { // CHECK-NEXT: a = 2; // CHECK-NEXT: } +// CHECK-NEXT: #pragma omp simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } +// CHECK-NEXT: #pragma omp parallel for simd +// CHECK-NEXT: for (int i = 0; i < argc; ++i) +// CHECK-NEXT: #pragma omp ordered simd +// CHECK-NEXT: { +// CHECK-NEXT: a = 2; +// CHECK-NEXT: } return tmain(argc); } Index: test/OpenMP/ordered_codegen.cpp =================================================================== --- test/OpenMP/ordered_codegen.cpp +++ test/OpenMP/ordered_codegen.cpp @@ -213,5 +213,22 @@ // CHECK: ret void } +float f[10]; +// CHECK-LABEL: foo_simd +void foo_simd(int low, int up) { + // CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}, !llvm.mem.parallel_loop_access ! + // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}) #{{[0-9]+}}, !llvm.mem.parallel_loop_access ! +#pragma omp simd + for (int i = low; i < up; ++i) { + f[i] = 0.0; +#pragma omp ordered simd + f[i] = 1.0; + } +} + +// CHECK: define internal void [[CAP_FUNC]](i32* dereferenceable({{[0-9]+}}) %{{.+}}) # +// CHECK: store float 1.000000e+00, float* %{{.+}}, align +// CHECK-NEXT: ret void + #endif // HEADER Index: test/OpenMP/ordered_messages.cpp =================================================================== --- test/OpenMP/ordered_messages.cpp +++ test/OpenMP/ordered_messages.cpp @@ -45,6 +45,52 @@ foo(); } } + #pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}} + { + foo(); + } + #pragma omp simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } return T(); } @@ -91,6 +137,52 @@ foo(); } } + #pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}} + { + foo(); + } + #pragma omp simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } + #pragma omp parallel for simd + for (int i = 0; i < 10; ++i) { + #pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}} + { + foo(); + } + } return foo(); } Index: test/OpenMP/parallel_ast_print.cpp =================================================================== --- test/OpenMP/parallel_ast_print.cpp +++ test/OpenMP/parallel_ast_print.cpp @@ -33,11 +33,12 @@ T b = argc, c, d, e, f, g; static T a; S s; + T arr[C][10], arr1[C]; #pragma omp parallel a=2; -#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+:c) reduction(max:e) +#pragma omp parallel default(none), private(argc,b) firstprivate(argv) shared (d) if (parallel:argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+:c, arr1[argc]) reduction(max:e, arr[:C][0:10]) foo(); -#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f) reduction(&& : g) +#pragma omp parallel if (C) num_threads(s) proc_bind(close) reduction(^:e, f, arr[0:C][:argc]) reduction(&& : g) foo(); return 0; } @@ -46,31 +47,34 @@ // CHECK-NEXT: int b = argc, c, d, e, f, g; // CHECK-NEXT: static int a; // CHECK-NEXT: S s; +// CHECK-NEXT: int arr[5][10], arr1[5]; // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(5) copyin(S::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:5][0:10]) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(5) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:5][:argc]) reduction(&&: g) // CHECK-NEXT: foo() // CHECK: template long tmain(long argc, long *argv) { // CHECK-NEXT: long b = argc, c, d, e, f, g; // CHECK-NEXT: static long a; // CHECK-NEXT: S s; +// CHECK-NEXT: long arr[1][10], arr1[1]; // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(1) copyin(S::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:1][0:10]) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(1) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:1][:argc]) reduction(&&: g) // CHECK-NEXT: foo() // CHECK: template T tmain(T argc, T *argv) { // CHECK-NEXT: T b = argc, c, d, e, f, g; // CHECK-NEXT: static T a; // CHECK-NEXT: S s; +// CHECK-NEXT: T arr[C][10], arr1[C]; // CHECK-NEXT: #pragma omp parallel // CHECK-NEXT: a = 2; -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+: c) reduction(max: e) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) shared(d) if(parallel: argc > 0) num_threads(C) copyin(S::TS) proc_bind(master) reduction(+: c,arr1[argc]) reduction(max: e,arr[:C][0:10]) // CHECK-NEXT: foo() -// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(C) num_threads(s) proc_bind(close) reduction(^: e,f,arr[0:C][:argc]) reduction(&&: g) // CHECK-NEXT: foo() enum Enum { }; @@ -80,19 +84,20 @@ int b = argc, c, d, e, f, g; static int a; #pragma omp threadprivate(a) + int arr[10][argc], arr1[2]; Enum ee; // CHECK: Enum ee; #pragma omp parallel // CHECK-NEXT: #pragma omp parallel a=2; // CHECK-NEXT: a = 2; -#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d) reduction(* : e) -// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d) reduction(*: e) +#pragma omp parallel default(none), private(argc,b) firstprivate(argv) if (parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(| : c, d, arr1[argc]) reduction(* : e, arr[:10][0:argc]) +// CHECK-NEXT: #pragma omp parallel default(none) private(argc,b) firstprivate(argv) if(parallel: argc > 0) num_threads(ee) copyin(a) proc_bind(spread) reduction(|: c,d,arr1[argc]) reduction(*: e,arr[:10][0:argc]) foo(); // CHECK-NEXT: foo(); -// CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g) +// CHECK-NEXT: #pragma omp parallel if(b) num_threads(c) proc_bind(close) reduction(^: e,f) reduction(&&: g,arr[0:argc][:10]) // CHECK-NEXT: foo() -#pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g) +#pragma omp parallel if (b) num_threads(c) proc_bind(close) reduction(^:e, f) reduction(&& : g, arr[0:argc][:10]) foo(); return tmain(b, &b) + tmain(x, &x); } Index: test/OpenMP/parallel_for_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_for_reduction_messages.cpp +++ test/OpenMP/parallel_for_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -102,7 +103,7 @@ #pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp parallel for reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} @@ -114,22 +115,22 @@ #pragma omp parallel for reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -138,7 +139,7 @@ #pragma omp parallel for reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -157,7 +158,7 @@ #pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) @@ -224,7 +225,7 @@ #pragma omp parallel for reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp parallel for reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -236,22 +237,22 @@ #pragma omp parallel for reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp parallel for reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -260,7 +261,7 @@ #pragma omp parallel for reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} @@ -282,7 +283,7 @@ #pragma omp parallel for reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) Index: test/OpenMP/parallel_for_simd_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -102,7 +103,7 @@ #pragma omp parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp parallel for simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} @@ -114,22 +115,22 @@ #pragma omp parallel for simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -138,7 +139,7 @@ #pragma omp parallel for simd reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -157,7 +158,7 @@ #pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) @@ -224,7 +225,7 @@ #pragma omp parallel for simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp parallel for simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -236,22 +237,22 @@ #pragma omp parallel for simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp parallel for simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -260,7 +261,7 @@ #pragma omp parallel for simd reduction(&& : S2::S2s) for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} @@ -282,7 +283,7 @@ #pragma omp parallel for simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel for simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) Index: test/OpenMP/parallel_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_reduction_messages.cpp +++ test/OpenMP/parallel_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -93,7 +94,7 @@ foo(); #pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); -#pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp parallel reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} foo(); #pragma omp parallel reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} foo(); @@ -101,23 +102,23 @@ foo(); #pragma omp parallel reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); -#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} foo(); -#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp parallel reduction(&& : S2::S2s) foo(); -#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} foo(); @@ -130,7 +131,7 @@ foo(); #pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} foo(); -#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) @@ -188,7 +189,7 @@ foo(); #pragma omp parallel reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); -#pragma omp parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp parallel reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp parallel reduction(~ : argc) // expected-error {{expected unqualified-id}} foo(); @@ -196,23 +197,23 @@ foo(); #pragma omp parallel reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} foo(); -#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp parallel reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} foo(); -#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp parallel reduction(&& : S2::S2s) foo(); -#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} foo(); @@ -227,7 +228,7 @@ foo(); #pragma omp parallel reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} foo(); -#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) Index: test/OpenMP/parallel_sections_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_reduction_messages.cpp +++ test/OpenMP/parallel_sections_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -111,7 +112,7 @@ { foo(); } -#pragma omp parallel sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp parallel sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} { foo(); } @@ -127,27 +128,27 @@ { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} { foo(); } -#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp parallel sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} { foo(); } @@ -159,7 +160,7 @@ { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -184,7 +185,7 @@ { foo(); } -#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} { foo(); } @@ -264,7 +265,7 @@ { foo(); } -#pragma omp parallel sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp parallel sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} { foo(); } @@ -280,27 +281,27 @@ { foo(); } -#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp parallel sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} { foo(); } -#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp parallel sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} { foo(); } @@ -312,7 +313,7 @@ { foo(); } -#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -341,7 +342,7 @@ { foo(); } -#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp parallel sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } Index: test/OpenMP/sections_reduction_messages.cpp =================================================================== --- test/OpenMP/sections_reduction_messages.cpp +++ test/OpenMP/sections_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -121,7 +122,7 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp sections reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} { foo(); } @@ -141,32 +142,32 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} { foo(); } @@ -181,7 +182,7 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -211,7 +212,7 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} { foo(); } @@ -301,7 +302,7 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp sections reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} { foo(); } @@ -321,32 +322,32 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp sections reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp sections reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} { foo(); } @@ -361,7 +362,7 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -396,7 +397,7 @@ foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp sections reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } Index: test/OpenMP/simd_reduction_messages.cpp =================================================================== --- test/OpenMP/simd_reduction_messages.cpp +++ test/OpenMP/simd_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -102,7 +103,7 @@ #pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp simd reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} @@ -114,22 +115,22 @@ #pragma omp simd reduction(^ : T) // expected-error {{'T' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -138,7 +139,7 @@ #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -160,7 +161,7 @@ #pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) @@ -227,7 +228,7 @@ #pragma omp simd reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp simd reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -239,22 +240,22 @@ #pragma omp simd reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp simd reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -263,7 +264,7 @@ #pragma omp simd reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} @@ -285,7 +286,7 @@ #pragma omp simd reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp simd reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel shared(i) Index: test/OpenMP/teams_reduction_messages.cpp =================================================================== --- test/OpenMP/teams_reduction_messages.cpp +++ test/OpenMP/teams_reduction_messages.cpp @@ -26,6 +26,7 @@ int a; public: + int b; S3() : a(0) {} S3(const S3 &s3) : a(s3.a) {} S3 operator+(const S3 &arg1) { return arg1; } @@ -103,7 +104,7 @@ #pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); #pragma omp target -#pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name}} +#pragma omp teams reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}} foo(); #pragma omp target #pragma omp teams reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}} @@ -115,22 +116,22 @@ #pragma omp teams reduction(^ : T) // expected-error {{'T' does not refer to a value}} foo(); #pragma omp target -#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 3 {{const-qualified variable cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 3 {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target -#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(max : qa[1]) // expected-error 2 {{expected variable name}} +#pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} expected-error {{a reduction variable with array type 'const float [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -139,7 +140,7 @@ #pragma omp teams reduction(&& : S2::S2s) foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}} @@ -158,7 +159,7 @@ #pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error 3 {{variable can appear only once in OpenMP 'reduction' clause}} expected-note 3 {{previously referenced here}} foo(); #pragma omp target -#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) @@ -231,7 +232,7 @@ #pragma omp teams reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target -#pragma omp teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}} +#pragma omp teams reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target #pragma omp teams reduction(~ : argc) // expected-error {{expected unqualified-id}} @@ -243,22 +244,22 @@ #pragma omp teams reduction(^ : S1) // expected-error {{'S1' does not refer to a value}} foo(); #pragma omp target -#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{const-qualified variable cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} +#pragma omp teams reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}} foo(); #pragma omp target -#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{reduction variable with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(max : argv[1]) // expected-error {{expected variable name}} +#pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(+ : ba) // expected-error {{a reduction variable with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction variable with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction variable with array type 'const int [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -267,7 +268,7 @@ #pragma omp teams reduction(&& : S2::S2s) foo(); #pragma omp target -#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{invalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}} @@ -289,7 +290,7 @@ #pragma omp teams reduction(+ : p), reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'reduction' clause}} expected-note {{previously referenced here}} foo(); #pragma omp target -#pragma omp teams reduction(+ : r) // expected-error {{const-qualified variable cannot be reduction}} +#pragma omp teams reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel shared(i) #pragma omp parallel reduction(min : i) Index: test/Parser/opencl-atomics-cl20.cl =================================================================== --- test/Parser/opencl-atomics-cl20.cl +++ test/Parser/opencl-atomics-cl20.cl @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -verify -pedantic -fsyntax-only -// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -// RUN: %clang_cc1 %s -triple x86_64-unknown-unknown -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL2.0 -DCL20 +// RUN: %clang_cc1 %s -verify -fsyntax-only -cl-std=CL2.0 -DCL20 -DEXT #ifdef EXT #pragma OPENCL EXTENSION cl_khr_int64_base_atomics:enable @@ -54,3 +54,16 @@ // expected-error-re@-31 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_base_atomics extension to be enabled}} // expected-error-re@-32 {{use of type 'atomic_ptrdiff_t' (aka '_Atomic({{.+}})') requires cl_khr_int64_extended_atomics extension to be enabled}} #endif + +#ifdef CL20 +void foo(atomic_int * ptr) {} +void atomic_ops_test() { + atomic_int i; + foo(&i); +// OpenCL v2.0 s6.13.11.8, arithemtic operations are not permitted on atomic types. + i++; // expected-error {{invalid argument type 'atomic_int' (aka '_Atomic(int)') to unary expression}} + i = 1; // expected-error {{atomic variable can only be assigned to a compile time constant in the declaration statement in the program scope}} + i += 1; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'int')}} + i = i + i; // expected-error {{invalid operands to binary expression ('atomic_int' (aka '_Atomic(int)') and 'atomic_int')}} +} +#endif Index: test/Preprocessor/init.c =================================================================== --- test/Preprocessor/init.c +++ test/Preprocessor/init.c @@ -4737,10 +4737,10 @@ // NVPTX32:#define __INT_FAST32_FMTi__ "i" // NVPTX32:#define __INT_FAST32_MAX__ 2147483647 // NVPTX32:#define __INT_FAST32_TYPE__ int -// NVPTX32:#define __INT_FAST64_FMTd__ "ld" -// NVPTX32:#define __INT_FAST64_FMTi__ "li" +// NVPTX32:#define __INT_FAST64_FMTd__ "lld" +// NVPTX32:#define __INT_FAST64_FMTi__ "lli" // NVPTX32:#define __INT_FAST64_MAX__ 9223372036854775807L -// NVPTX32:#define __INT_FAST64_TYPE__ long int +// NVPTX32:#define __INT_FAST64_TYPE__ long long int // NVPTX32:#define __INT_FAST8_FMTd__ "hhd" // NVPTX32:#define __INT_FAST8_FMTi__ "hhi" // NVPTX32:#define __INT_FAST8_MAX__ 127 @@ -4753,10 +4753,10 @@ // NVPTX32:#define __INT_LEAST32_FMTi__ "i" // NVPTX32:#define __INT_LEAST32_MAX__ 2147483647 // NVPTX32:#define __INT_LEAST32_TYPE__ int -// NVPTX32:#define __INT_LEAST64_FMTd__ "ld" -// NVPTX32:#define __INT_LEAST64_FMTi__ "li" +// NVPTX32:#define __INT_LEAST64_FMTd__ "lld" +// NVPTX32:#define __INT_LEAST64_FMTi__ "lli" // NVPTX32:#define __INT_LEAST64_MAX__ 9223372036854775807L -// NVPTX32:#define __INT_LEAST64_TYPE__ long int +// NVPTX32:#define __INT_LEAST64_TYPE__ long long int // NVPTX32:#define __INT_LEAST8_FMTd__ "hhd" // NVPTX32:#define __INT_LEAST8_FMTi__ "hhi" // NVPTX32:#define __INT_LEAST8_MAX__ 127 @@ -4777,7 +4777,7 @@ // NVPTX32:#define __LDBL_MIN__ 2.2250738585072014e-308L // NVPTX32:#define __LITTLE_ENDIAN__ 1 // NVPTX32:#define __LONG_LONG_MAX__ 9223372036854775807LL -// NVPTX32:#define __LONG_MAX__ 9223372036854775807L +// NVPTX32:#define __LONG_MAX__ 2147483647L // NVPTX32-NOT:#define __LP64__ // NVPTX32:#define __NVPTX__ 1 // NVPTX32:#define __POINTER_WIDTH__ 32 @@ -4794,7 +4794,7 @@ // NVPTX32:#define __SIZEOF_INT__ 4 // NVPTX32:#define __SIZEOF_LONG_DOUBLE__ 8 // NVPTX32:#define __SIZEOF_LONG_LONG__ 8 -// NVPTX32:#define __SIZEOF_LONG__ 8 +// NVPTX32:#define __SIZEOF_LONG__ 4 // NVPTX32:#define __SIZEOF_POINTER__ 4 // NVPTX32:#define __SIZEOF_PTRDIFF_T__ 4 // NVPTX32:#define __SIZEOF_SHORT__ 2 @@ -4828,7 +4828,7 @@ // NVPTX32:#define __UINT_FAST32_MAX__ 4294967295U // NVPTX32:#define __UINT_FAST32_TYPE__ unsigned int // NVPTX32:#define __UINT_FAST64_MAX__ 18446744073709551615UL -// NVPTX32:#define __UINT_FAST64_TYPE__ long unsigned int +// NVPTX32:#define __UINT_FAST64_TYPE__ long long unsigned int // NVPTX32:#define __UINT_FAST8_MAX__ 255 // NVPTX32:#define __UINT_FAST8_TYPE__ unsigned char // NVPTX32:#define __UINT_LEAST16_MAX__ 65535 @@ -4836,7 +4836,7 @@ // NVPTX32:#define __UINT_LEAST32_MAX__ 4294967295U // NVPTX32:#define __UINT_LEAST32_TYPE__ unsigned int // NVPTX32:#define __UINT_LEAST64_MAX__ 18446744073709551615UL -// NVPTX32:#define __UINT_LEAST64_TYPE__ long unsigned int +// NVPTX32:#define __UINT_LEAST64_TYPE__ long long unsigned int // NVPTX32:#define __UINT_LEAST8_MAX__ 255 // NVPTX32:#define __UINT_LEAST8_TYPE__ unsigned char // NVPTX32:#define __USER_LABEL_PREFIX__ _ Index: test/Sema/attr-capabilities.c =================================================================== --- test/Sema/attr-capabilities.c +++ test/Sema/attr-capabilities.c @@ -4,11 +4,15 @@ struct __attribute__((shared_capability("mutex"))) Mutex {}; struct NotACapability {}; +// Put capability attributes on unions +union __attribute__((capability("mutex"))) MutexUnion { int a; char* b; }; +typedef union { int a; char* b; } __attribute__((capability("mutex"))) MutexUnion2; + // Test an invalid capability name struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}} -int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs and typedefs}} -int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs and typedefs}} +int Test1 __attribute__((capability("test1"))); // expected-error {{'capability' attribute only applies to structs, unions, and typedefs}} +int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs, unions, and typedefs}} int Test3 __attribute__((acquire_capability("test3"))); // expected-warning {{'acquire_capability' attribute only applies to functions}} int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}} int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}} Index: test/Sema/warn-thread-safety-analysis.c =================================================================== --- test/Sema/warn-thread-safety-analysis.c +++ test/Sema/warn-thread-safety-analysis.c @@ -81,7 +81,8 @@ mutex_shared_lock(&mu2); Foo_fun1(1); - mutex_shared_lock(&mu1); // expected-warning{{acquiring mutex 'mu1' that is already held}} + mutex_shared_lock(&mu1); // expected-warning{{acquiring mutex 'mu1' that is already held}} \ + expected-warning{{mutex 'mu1' must be acquired before 'mu2'}} mutex_unlock(&mu1); mutex_unlock(&mu2); mutex_shared_lock(&mu1); Index: test/SemaCXX/enable_if.cpp =================================================================== --- test/SemaCXX/enable_if.cpp +++ test/SemaCXX/enable_if.cpp @@ -2,6 +2,8 @@ typedef int (*fp)(int); int surrogate(int); +struct Incomplete; // expected-note{{forward declaration of 'Incomplete'}} \ + // expected-note {{forward declaration of 'Incomplete'}} struct X { X() = default; // expected-note{{candidate constructor not viable: requires 0 arguments, but 1 was provided}} @@ -13,13 +15,16 @@ void g(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); // expected-note{{candidate disabled: chosen when 'n' is zero}} - void h(int n, int m = 0) __attribute((enable_if(m == 0, "chosen when 'm' is zero"))); // expected-note{{candidate disabled: chosen when 'm' is zero}} + void h(int n, int m = 0) __attribute__((enable_if(m == 0, "chosen when 'm' is zero"))); // expected-note{{candidate disabled: chosen when 'm' is zero}} static void s(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); // expected-note2{{candidate disabled: chosen when 'n' is zero}} void conflict(int n) __attribute__((enable_if(n+n == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}} void conflict(int n) __attribute__((enable_if(n*2 == 10, "chosen when 'n' is five"))); // expected-note{{candidate function}} + void hidden_by_argument_conversion(Incomplete n, int m = 0) __attribute__((enable_if(m == 10, "chosen when 'm' is ten"))); + Incomplete hidden_by_incomplete_return_value(int n = 0) __attribute__((enable_if(n == 10, "chosen when 'n' is ten"))); // expected-note{{'hidden_by_incomplete_return_value' declared here}} + operator long() __attribute__((enable_if(true, "chosen on your platform"))); operator int() __attribute__((enable_if(false, "chosen on other platform"))); @@ -85,6 +90,9 @@ x.conflict(5); // expected-error{{call to member function 'conflict' is ambiguous}} + x.hidden_by_argument_conversion(10); // expected-error{{argument type 'Incomplete' is incomplete}} + x.hidden_by_incomplete_return_value(10); // expected-error{{calling 'hidden_by_incomplete_return_value' with incomplete return type 'Incomplete'}} + deprec2(0); overloaded(x); Index: test/SemaCXX/exception-spec.cpp =================================================================== --- /dev/null +++ test/SemaCXX/exception-spec.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions -std=c++11 %s + +namespace MissingOnTemplate { + template void foo(T) noexcept(true); // expected-note {{previous}} + template void foo(T); // expected-error {{missing exception specification 'noexcept(true)'}} + void test() { foo(0); } +} Index: test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- test/SemaCXX/warn-thread-safety-analysis.cpp +++ test/SemaCXX/warn-thread-safety-analysis.cpp @@ -5145,4 +5145,40 @@ } // end namespace TestReferenceNoThreadSafetyAnalysis +namespace GlobalAcquiredBeforeAfterTest { + +Mutex mu1; +Mutex mu2 ACQUIRED_AFTER(mu1); + +void test3() { + mu2.Lock(); + mu1.Lock(); // expected-warning {{mutex 'mu1' must be acquired before 'mu2'}} + mu1.Unlock(); + mu2.Unlock(); +} + +} // end namespace GlobalAcquiredBeforeAfterTest + + +namespace LockableUnions { + +union LOCKABLE MutexUnion { + int a; + char* b; + + void Lock() EXCLUSIVE_LOCK_FUNCTION(); + void Unlock() UNLOCK_FUNCTION(); +}; + +MutexUnion muun2; +MutexUnion muun1 ACQUIRED_BEFORE(muun2); + +void test() { + muun2.Lock(); + muun1.Lock(); // expected-warning {{mutex 'muun1' must be acquired before 'muun2'}} + muun1.Unlock(); + muun2.Unlock(); +} + +} // end namespace LockableUnions Index: tools/clang-format/ClangFormat.cpp =================================================================== --- tools/clang-format/ClangFormat.cpp +++ tools/clang-format/ClangFormat.cpp @@ -73,7 +73,7 @@ cl::init("LLVM"), cl::cat(ClangFormatCategory)); static cl::opt -AssumeFilename("assume-filename", +AssumeFileName("assume-filename", cl::desc("When reading from stdin, clang-format assumes this\n" "filename to look for a style config file (with\n" "-style=file) and to determine the language."), @@ -239,13 +239,13 @@ std::vector Ranges; if (fillRanges(Code.get(), Ranges)) return true; - FormatStyle FormatStyle = getStyle( - Style, (FileName == "-") ? AssumeFilename : FileName, FallbackStyle); + StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName; + FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle); Replacements Replaces; std::string ChangedCode; if (SortIncludes) { Replaces = - sortIncludes(FormatStyle, Code->getBuffer(), Ranges, FileName); + sortIncludes(FormatStyle, Code->getBuffer(), Ranges, AssumedFileName); ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces); for (const auto &R : Replaces) Ranges.push_back({R.getOffset(), R.getLength()}); @@ -324,7 +324,7 @@ if (DumpConfig) { std::string Config = clang::format::configurationAsText(clang::format::getStyle( - Style, FileNames.empty() ? AssumeFilename : FileNames[0], + Style, FileNames.empty() ? AssumeFileName : FileNames[0], FallbackStyle)); llvm::outs() << Config << "\n"; return 0; Index: tools/driver/driver.cpp =================================================================== --- tools/driver/driver.cpp +++ tools/driver/driver.cpp @@ -18,6 +18,7 @@ #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "clang/Driver/ToolChain.h" #include "clang/Frontend/ChainedDiagnosticConsumer.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/SerializedDiagnosticPrinter.h" @@ -44,7 +45,6 @@ #include "llvm/Support/Regex.h" #include "llvm/Support/Signals.h" #include "llvm/Support/StringSaver.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" @@ -201,101 +201,22 @@ extern int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr); -struct DriverSuffix { - const char *Suffix; - const char *ModeFlag; -}; - -static const DriverSuffix *FindDriverSuffix(StringRef ProgName) { - // A list of known driver suffixes. Suffixes are compared against the - // program name in order. If there is a match, the frontend type if updated as - // necessary by applying the ModeFlag. - static const DriverSuffix DriverSuffixes[] = { - {"clang", nullptr}, - {"clang++", "--driver-mode=g++"}, - {"clang-c++", "--driver-mode=g++"}, - {"clang-cc", nullptr}, - {"clang-cpp", "--driver-mode=cpp"}, - {"clang-g++", "--driver-mode=g++"}, - {"clang-gcc", nullptr}, - {"clang-cl", "--driver-mode=cl"}, - {"cc", nullptr}, - {"cpp", "--driver-mode=cpp"}, - {"cl", "--driver-mode=cl"}, - {"++", "--driver-mode=g++"}, - }; - - for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) - if (ProgName.endswith(DriverSuffixes[i].Suffix)) - return &DriverSuffixes[i]; - return nullptr; -} - -/// Normalize the program name from argv[0] by stripping the file extension if -/// present and lower-casing the string on Windows. -static std::string normalizeProgramName(const char *Argv0) { - std::string ProgName = llvm::sys::path::stem(Argv0); -#ifdef LLVM_ON_WIN32 - // Transform to lowercase for case insensitive file systems. - std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower); -#endif - return ProgName; -} - -static const DriverSuffix *parseDriverSuffix(StringRef ProgName) { - // Try to infer frontend type and default target from the program name by - // comparing it against DriverSuffixes in order. - - // If there is a match, the function tries to identify a target as prefix. - // E.g. "x86_64-linux-clang" as interpreted as suffix "clang" with target - // prefix "x86_64-linux". If such a target prefix is found, is gets added via - // -target as implicit first argument. - const DriverSuffix *DS = FindDriverSuffix(ProgName); - - if (!DS) { - // Try again after stripping any trailing version number: - // clang++3.5 -> clang++ - ProgName = ProgName.rtrim("0123456789."); - DS = FindDriverSuffix(ProgName); - } - - if (!DS) { - // Try again after stripping trailing -component. - // clang++-tot -> clang++ - ProgName = ProgName.slice(0, ProgName.rfind('-')); - DS = FindDriverSuffix(ProgName); - } - return DS; -} - -static void insertArgsFromProgramName(StringRef ProgName, - const DriverSuffix *DS, - SmallVectorImpl &ArgVector, - std::set &SavedStrings) { - if (!DS) - return; - - if (const char *Flag = DS->ModeFlag) { - // Add Flag to the arguments. +static void insertTargetAndModeArgs(StringRef Target, StringRef Mode, + SmallVectorImpl &ArgVector, + std::set &SavedStrings) { + if (!Mode.empty()) { + // Add the mode flag to the arguments. auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; - ArgVector.insert(it, Flag); + ArgVector.insert(it, GetStableCStr(SavedStrings, Mode)); } - StringRef::size_type LastComponent = ProgName.rfind( - '-', ProgName.size() - strlen(DS->Suffix)); - if (LastComponent == StringRef::npos) - return; - - // Infer target from the prefix. - StringRef Prefix = ProgName.slice(0, LastComponent); - std::string IgnoredError; - if (llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError)) { + if (!Target.empty()) { auto it = ArgVector.begin(); if (it != ArgVector.end()) ++it; - const char *arr[] = { "-target", GetStableCStr(SavedStrings, Prefix) }; + const char *arr[] = {"-target", GetStableCStr(SavedStrings, Target)}; ArgVector.insert(it, std::begin(arr), std::end(arr)); } } @@ -402,8 +323,10 @@ return 1; } - std::string ProgName = normalizeProgramName(argv[0]); - const DriverSuffix *DS = parseDriverSuffix(ProgName); + llvm::InitializeAllTargets(); + std::string ProgName = argv[0]; + std::pair TargetAndMode = + ToolChain::getTargetAndModeFromProgramName(ProgName); llvm::BumpPtrAllocator A; llvm::StringSaver Saver(A); @@ -416,7 +339,7 @@ // Finally, our -cc1 tools don't care which tokenization mode we use because // response files written by clang will tokenize the same way in either mode. llvm::cl::TokenizerCallback Tokenizer = &llvm::cl::TokenizeGNUCommandLine; - if ((DS && DS->ModeFlag && strcmp(DS->ModeFlag, "--driver-mode=cl") == 0) || + if (TargetAndMode.second == "--driver-mode=cl" || std::find_if(argv.begin(), argv.end(), [](const char *F) { return F && strcmp(F, "--driver-mode=cl") == 0; }) != argv.end()) { @@ -511,8 +434,8 @@ Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags); SetInstallDir(argv, TheDriver, CanonicalPrefixes); - llvm::InitializeAllTargets(); - insertArgsFromProgramName(ProgName, DS, argv, SavedStrings); + insertTargetAndModeArgs(TargetAndMode.first, TargetAndMode.second, argv, + SavedStrings); SetBackdoorDriverOutputsFromEnvVars(TheDriver); Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -1523,10 +1523,7 @@ } bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) - return true; - - return false; + return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)); } bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) { @@ -1644,10 +1641,7 @@ } bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) { - if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc())) - return true; - - return false; + return VisitNestedNameSpecifierLoc(TL.getQualifierLoc()); } bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc( @@ -2068,6 +2062,8 @@ void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {} +void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {} + void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) { Visitor->AddStmt(C->getDevice()); } @@ -6412,7 +6408,7 @@ static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) { if (isa(D) && cast(D)->isDeleted()) - return CXAvailability_Available; + return CXAvailability_NotAvailable; switch (D->getAvailability()) { case AR_Available: Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -8645,6 +8645,189 @@ Alignment); } +TEST_F(FormatTest, AlignConsecutiveDeclarations) { + FormatStyle Alignment = getLLVMStyle(); + Alignment.AlignConsecutiveDeclarations = false; + verifyFormat("float const a = 5;\n" + "int oneTwoThree = 123;", + Alignment); + verifyFormat("int a = 5;\n" + "float const oneTwoThree = 123;", + Alignment); + + Alignment.AlignConsecutiveDeclarations = true; + verifyFormat("float const a = 5;\n" + "int oneTwoThree = 123;", + Alignment); + verifyFormat("int a = method();\n" + "float const oneTwoThree = 133;", + Alignment); + verifyFormat("int i = 1, j = 10;\n" + "something = 2000;", + Alignment); + verifyFormat("something = 2000;\n" + "int i = 1, j = 10;\n", + Alignment); + verifyFormat("float something = 2000;\n" + "double another = 911;\n" + "int i = 1, j = 10;\n" + "const int *oneMore = 1;\n" + "unsigned i = 2;", + Alignment); + verifyFormat("float a = 5;\n" + "int one = 1;\n" + "method();\n" + "const double oneTwoThree = 123;\n" + "const unsigned int oneTwo = 12;", + Alignment); + verifyFormat("int oneTwoThree{0}; // comment\n" + "unsigned oneTwo; // comment", + Alignment); + EXPECT_EQ("float const a = 5;\n" + "\n" + "int oneTwoThree = 123;", + format("float const a = 5;\n" + "\n" + "int oneTwoThree= 123;", + Alignment)); + EXPECT_EQ("float a = 5;\n" + "int one = 1;\n" + "\n" + "unsigned oneTwoThree = 123;", + format("float a = 5;\n" + "int one = 1;\n" + "\n" + "unsigned oneTwoThree = 123;", + Alignment)); + EXPECT_EQ("float a = 5;\n" + "int one = 1;\n" + "\n" + "unsigned oneTwoThree = 123;\n" + "int oneTwo = 12;", + format("float a = 5;\n" + "int one = 1;\n" + "\n" + "unsigned oneTwoThree = 123;\n" + "int oneTwo = 12;", + Alignment)); + Alignment.AlignConsecutiveAssignments = true; + verifyFormat("float something = 2000;\n" + "double another = 911;\n" + "int i = 1, j = 10;\n" + "const int *oneMore = 1;\n" + "unsigned i = 2;", + Alignment); + verifyFormat("int oneTwoThree = {0}; // comment\n" + "unsigned oneTwo = 0; // comment", + Alignment); + EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int * j = 2;\n" + " int big = 10000;\n" + "\n" + " unsigned oneTwoThree = 123;\n" + " int oneTwo = 12;\n" + " method();\n" + " float k = 2;\n" + " int ll = 10000;\n" + "}", + format("void SomeFunction(int parameter= 0) {\n" + " int const i= 1;\n" + " int *j=2;\n" + " int big = 10000;\n" + "\n" + "unsigned oneTwoThree =123;\n" + "int oneTwo = 12;\n" + " method();\n" + "float k= 2;\n" + "int ll=10000;\n" + "}", + Alignment)); + Alignment.AlignConsecutiveAssignments = false; + Alignment.AlignEscapedNewlinesLeft = true; + verifyFormat("#define A \\\n" + " int aaaa = 12; \\\n" + " float b = 23; \\\n" + " const int ccc = 234; \\\n" + " unsigned dddddddddd = 2345;", + Alignment); + Alignment.AlignEscapedNewlinesLeft = false; + Alignment.ColumnLimit = 30; + verifyFormat("#define A \\\n" + " int aaaa = 12; \\\n" + " float b = 23; \\\n" + " const int ccc = 234; \\\n" + " int dddddddddd = 2345;", + Alignment); + Alignment.ColumnLimit = 80; + verifyFormat("void SomeFunction(int parameter = 1, int i = 2, int j = 3, int " + "k = 4, int l = 5,\n" + " int m = 6) {\n" + " const int j = 10;\n" + " otherThing = 1;\n" + "}", + Alignment); + verifyFormat("void SomeFunction(int parameter = 0) {\n" + " int const i = 1;\n" + " int * j = 2;\n" + " int big = 10000;\n" + "}", + Alignment); + verifyFormat("class C {\n" + "public:\n" + " int i = 1;\n" + " virtual void f() = 0;\n" + "};", + Alignment); + verifyFormat("float i = 1;\n" + "if (SomeType t = getSomething()) {\n" + "}\n" + "const unsigned j = 2;\n" + "int big = 10000;", + Alignment); + verifyFormat("float j = 7;\n" + "for (int k = 0; k < N; ++k) {\n" + "}\n" + "unsigned j = 2;\n" + "int big = 10000;\n" + "}", + Alignment); + Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_All; + verifyFormat("float i = 1;\n" + "LooooooooooongType loooooooooooooooooooooongVariable\n" + " = someLooooooooooooooooongFunction();\n" + "int j = 2;", + Alignment); + Alignment.BreakBeforeBinaryOperators = FormatStyle::BOS_None; + verifyFormat("int i = 1;\n" + "LooooooooooongType loooooooooooooooooooooongVariable =\n" + " someLooooooooooooooooongFunction();\n" + "int j = 2;", + Alignment); + // FIXME: Should align all three declarations + verifyFormat( + "int i = 1;\n" + "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" + " loooooooooooooooooooooongParameterB);\n" + "int j = 2;", + Alignment); + + // Test interactions with ColumnLimit and AlignConsecutiveAssignments: + // We expect declarations and assignments to align, as long as it doesn't + // exceed the column limit, starting a new alignemnt sequence whenever it + // happens. + Alignment.AlignConsecutiveAssignments = true; + Alignment.ColumnLimit = 30; + verifyFormat("float ii = 1;\n" + "unsigned j = 2;\n" + "int someVerylongVariable = 1;\n" + "AnotherLongType ll = 123456;\n" + "VeryVeryLongType k = 2;\n" + "int myvar = 1;", + Alignment); + Alignment.ColumnLimit = 80; +} + TEST_F(FormatTest, LinuxBraceBreaking) { FormatStyle LinuxBraceStyle = getLLVMStyle(); LinuxBraceStyle.BreakBeforeBraces = FormatStyle::BS_Linux; @@ -9263,6 +9446,20 @@ #define CHECK_PARSE_BOOL(FIELD) CHECK_PARSE_BOOL_FIELD(FIELD, #FIELD) +#define CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, CONFIG_NAME) \ + Style.STRUCT.FIELD = false; \ + EXPECT_EQ(0, \ + parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": true", &Style) \ + .value()); \ + EXPECT_TRUE(Style.STRUCT.FIELD); \ + EXPECT_EQ(0, \ + parseConfiguration(#STRUCT ":\n " CONFIG_NAME ": false", &Style) \ + .value()); \ + EXPECT_FALSE(Style.STRUCT.FIELD); + +#define CHECK_PARSE_NESTED_BOOL(STRUCT, FIELD) \ + CHECK_PARSE_NESTED_BOOL_FIELD(STRUCT, FIELD, #FIELD) + #define CHECK_PARSE(TEXT, FIELD, VALUE) \ EXPECT_NE(VALUE, Style.FIELD); \ EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value()); \ @@ -9276,6 +9473,7 @@ CHECK_PARSE_BOOL(AlignOperands); CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AlignConsecutiveAssignments); + CHECK_PARSE_BOOL(AlignConsecutiveDeclarations); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); CHECK_PARSE_BOOL(AllowShortCaseLabelsOnASingleLine); @@ -9303,6 +9501,18 @@ CHECK_PARSE_BOOL(SpacesInCStyleCastParentheses); CHECK_PARSE_BOOL(SpaceAfterCStyleCast); CHECK_PARSE_BOOL(SpaceBeforeAssignmentOperators); + + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterClass); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterControlStatement); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterEnum); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterFunction); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterNamespace); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterObjCDeclaration); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterStruct); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, AfterUnion); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeCatch); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, BeforeElse); + CHECK_PARSE_NESTED_BOOL(BraceWrapping, IndentBraces); } #undef CHECK_PARSE_BOOL @@ -9414,7 +9624,10 @@ CHECK_PARSE("BreakBeforeBraces: Allman", BreakBeforeBraces, FormatStyle::BS_Allman); CHECK_PARSE("BreakBeforeBraces: GNU", BreakBeforeBraces, FormatStyle::BS_GNU); - CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces, FormatStyle::BS_WebKit); + CHECK_PARSE("BreakBeforeBraces: WebKit", BreakBeforeBraces, + FormatStyle::BS_WebKit); + CHECK_PARSE("BreakBeforeBraces: Custom", BreakBeforeBraces, + FormatStyle::BS_Custom); Style.AlwaysBreakAfterDefinitionReturnType = FormatStyle::DRTBS_All; CHECK_PARSE("AlwaysBreakAfterDefinitionReturnType: None", Index: unittests/Format/FormatTestJS.cpp =================================================================== --- unittests/Format/FormatTestJS.cpp +++ unittests/Format/FormatTestJS.cpp @@ -99,9 +99,24 @@ verifyFormat("not.and.or.not_eq = 1;"); } +TEST_F(FormatTestJS, ReservedWords) { + // JavaScript reserved words (aka keywords) are only illegal when used as + // Identifiers, but are legal as IdentifierNames. + verifyFormat("x.class.struct = 1;"); + verifyFormat("x.case = 1;"); + verifyFormat("x.interface = 1;"); + verifyFormat("x = {\n" + " a: 12,\n" + " interface: 1,\n" + " switch: 1,\n" + "};"); +} + TEST_F(FormatTestJS, ES6DestructuringAssignment) { verifyFormat("var [a, b, c] = [1, 2, 3];"); + verifyFormat("let [a, b, c] = [1, 2, 3];"); verifyFormat("var {a, b} = {a: 1, b: 2};"); + verifyFormat("let {a, b} = {a: 1, b: 2};"); } TEST_F(FormatTestJS, ContainerLiterals) { Index: unittests/Format/SortIncludesTest.cpp =================================================================== --- unittests/Format/SortIncludesTest.cpp +++ unittests/Format/SortIncludesTest.cpp @@ -20,13 +20,15 @@ class SortIncludesTest : public ::testing::Test { protected: - std::string sort(llvm::StringRef Code) { + std::string sort(llvm::StringRef Code, StringRef FileName = "input.cpp") { std::vector Ranges(1, tooling::Range(0, Code.size())); - std::string Sorted = applyAllReplacements( - Code, sortIncludes(getLLVMStyle(), Code, Ranges, "input.cpp")); - return applyAllReplacements( - Sorted, reformat(getLLVMStyle(), Sorted, Ranges, "input.cpp")); + std::string Sorted = + applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName)); + return applyAllReplacements(Sorted, + reformat(Style, Sorted, Ranges, FileName)); } + + FormatStyle Style = getLLVMStyle(); }; TEST_F(SortIncludesTest, BasicSorting) { @@ -76,13 +78,23 @@ "#include \"c.h\"\n" "\n" "#include \"b.h\"\n", - sort("#include \"c.h\"\n" - "#include \"a.h\"\n" + sort("#include \"a.h\"\n" + "#include \"c.h\"\n" "\n" "#include \"b.h\"\n")); } TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { + EXPECT_EQ("#include \"a.h\"\n" + "#include \"c.h\"\n" + "#include \n" + "#include \n", + sort("#include \n" + "#include \n" + "#include \"c.h\"\n" + "#include \"a.h\"\n")); + + Style = getGoogleStyle(FormatStyle::LK_Cpp); EXPECT_EQ("#include \n" "#include \n" "#include \"a.h\"\n" @@ -103,6 +115,24 @@ "#include \"b.h\"\n")); } +TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { + EXPECT_EQ("#include \"llvm/a.h\"\n" + "#include \"b.h\"\n" + "#include \"c.h\"\n", + sort("#include \"llvm/a.h\"\n" + "#include \"c.h\"\n" + "#include \"b.h\"\n")); + + // Don't do this in headers. + EXPECT_EQ("#include \"b.h\"\n" + "#include \"c.h\"\n" + "#include \"llvm/a.h\"\n", + sort("#include \"llvm/a.h\"\n" + "#include \"c.h\"\n" + "#include \"b.h\"\n", + "some_header.h")); +} + } // end namespace } // end namespace format } // end namespace clang Index: utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- utils/TableGen/ClangAttrEmitter.cpp +++ utils/TableGen/ClangAttrEmitter.cpp @@ -348,7 +348,7 @@ << "Length])"; } void writeCtorDefaultInitializers(raw_ostream &OS) const override { - OS << getLowerName() << "Length(0)," << getLowerName() << "(0)"; + OS << getLowerName() << "Length(0)," << getLowerName() << "(nullptr)"; } void writeCtorParameters(raw_ostream &OS) const override { OS << "llvm::StringRef " << getUpperName(); @@ -491,7 +491,7 @@ // The aligned attribute argument expression is optional. OS << " if (is" << getLowerName() << "Expr && " << getLowerName() << "Expr)\n"; - OS << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"; + OS << " " << getLowerName() << "Expr->printPretty(OS, nullptr, Policy);\n"; OS << " OS << \""; } void writeDump(raw_ostream &OS) const override { @@ -2158,7 +2158,7 @@ bool ShouldClone = R.getValueAsBit("Clone"); if (!ShouldClone) { - OS << " return NULL;\n"; + OS << " return nullptr;\n"; OS << " }\n"; continue; } @@ -2192,7 +2192,7 @@ } OS << " } // end switch\n" << " llvm_unreachable(\"Unknown attribute!\");\n" - << " return 0;\n" + << " return nullptr;\n" << "}\n\n" << "} // end namespace sema\n" << "} // end namespace clang\n"; Index: utils/TableGen/ClangCommentCommandInfoEmitter.cpp =================================================================== --- utils/TableGen/ClangCommentCommandInfoEmitter.cpp +++ utils/TableGen/ClangCommentCommandInfoEmitter.cpp @@ -72,7 +72,7 @@ OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n" << " StringRef Name) {\n"; StringMatcher("Name", Matches, OS).Emit(); - OS << " return NULL;\n" + OS << " return nullptr;\n" << "}\n\n"; } @@ -123,4 +123,3 @@ } } } // end namespace clang - Index: utils/clang.natvis =================================================================== --- utils/clang.natvis +++ utils/clang.natvis @@ -6,6 +6,14 @@ or create a symbolic link so it updates automatically. --> + + Builtin Type={(clang::BuiltinType::Kind)BuiltinTypeBits.Kind} + Modified Type={((clang::AttributedType*)this)->ModifiedType} Attribute={(clang::AttributedType::Kind)AttributedTypeBits.AttrKind} + Type Class={(clang::Type::TypeClass)TypeBits.TC} + + + {((clang::ExtQualsTypeCommonBase *)(((uintptr_t)Value.Value) & ~(uintptr_t)((1 << clang::TypeAlignmentInBits) - 1)))->BaseType} + ({((llvm::StringMapEntry<clang::IdentifierInfo *>*)Entry)+1,s})