diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -6703,6 +6703,9 @@ llvm::omp::VariantMatchInfo &VMI, bool DeviceSetOnly) const; + /// Return a string representation identifying this context selector. + std::string getMangledName() const; + /// Print a human readable representation into \p OS. void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; }; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1248,6 +1248,9 @@ "unexpected '%0' clause, '%1' is specified already">; def err_expected_end_declare_target_or_variant : Error< "expected '#pragma omp end declare %select{target|variant}0'">; +def err_expected_begin_declare_variant + : Error<"expected '#pragma omp begin declare variant' to match this stray " + "`#pragma omp end delcare variant`">; def err_omp_declare_target_unexpected_clause: Error< "unexpected '%0' clause, only %select{'to' or 'link'|'to', 'link' or 'device_type'}1 clauses expected">; def err_omp_expected_clause: Error< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10110,6 +10110,12 @@ "'flush' directive with memory order clause '%0' cannot have the list">; def note_omp_flush_order_clause_here : Note< "memory order clause '%0' is specified here">; + +def warn_nested_declare_variant + : Warning<"nesting `omp begin/end declare variant` is not supported yet; " + "nested context ignored">, + InGroup; + } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9708,14 +9708,50 @@ MapT &Map, unsigned Selector = 0, SourceRange SrcRange = SourceRange()); - /// Marks all the functions that might be required for the currently active - /// OpenMP context. - void markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, - FunctionDecl *Func, - bool MightBeOdrUse); + /// Helper to keep information about the current `omp begin/end declare + /// variant` nesting. + struct OMPDeclareVariantScope { + /// Mapping from specialized function definitions to their (implicit) base + /// variants. + llvm::DenseMap Variant2BaseMap; + + /// The associated OpenMP context selector. + OMPTraitInfo TI; + + /// The associated OpenMP context selector mangling. + std::string NameSuffix; + + OMPDeclareVariantScope(const OMPTraitInfo &TI) + : TI(TI), NameSuffix(TI.getMangledName()) {} + }; + + /// The current `omp begin/end declare variant` scopes. + SmallVector OMPDeclareVariantScopes; + + /// The declarator \p D defines a function in the socpe \p S which is nested + /// in an `omp begin/end declare variant` scope. In this method we create a + /// declaration for \p D and rename \p D according to the OpenMP context + /// selector of the surrounding scope. + FunctionDecl * + ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, Declarator &D); + + /// Register \p FD as specialization of \p BaseFD in the current `omp + /// begin/end declare variant` scope. + void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( + FunctionDecl *FD, FunctionDecl *BaseFD); public: - /// Struct to store the context selectors info for declare variant directive. + + /// Can we exit a scope at the moment. + bool isInOpenMPDeclareVariantScope() { + return !OMPDeclareVariantScopes.empty(); + } + + /// Handle a `omp begin declare variant`. + void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI); + + /// Handle a `omp end declare variant`. + void ActOnOpenMPEndDeclareVariant(); /// Checks if the variant/multiversion functions are compatible. bool areMultiversionVariantFunctionsCompatible( @@ -10181,6 +10217,14 @@ ArrayRef Alignments, ArrayRef Linears, ArrayRef LinModifiers, ArrayRef Steps, SourceRange SR); + /// Given the potential call expression \p Call, determine if there is a + /// specialization via the OpenMP declare variant mechanism available. If + /// there is, return the specialized callee expression, otherwise return + /// \p Call + ExprResult ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, + SourceLocation LParenLoc, MultiExprArg ArgExprs, + SourceLocation RParenLoc, Expr *ExecConfig); + /// Checks '\#pragma omp declare variant' variant function and original /// functions after parsing of the associated method/function. /// \param DG Function declaration to which declare variant directive is diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -1823,6 +1823,36 @@ } } +std::string OMPTraitInfo::getMangledName() const { + std::string MangledName; + llvm::raw_string_ostream OS(MangledName); + for (const OMPTraitInfo::OMPTraitSet &Set : Sets) { + OS << 'S' + << llvm::omp::getOpenMPContextTraitSetName(Set.Kind).take_front(3); + for (const OMPTraitInfo::OMPTraitSelector &Selector : Set.Selectors) { + + bool AllowsTraitScore = false; + bool RequiresProperty = false; + llvm::omp::isValidTraitSelectorForTraitSet( + Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty); + + if (!RequiresProperty || + Selector.Kind == llvm::omp::TraitSelector::user_condition) { + OS << 'T' + << llvm::omp::getOpenMPContextTraitSelectorName(Selector.Kind) + .take_front(3); + continue; + } + + for (const OMPTraitInfo::OMPTraitProperty &Property : Selector.Properties) + OS << 'P' + << llvm::omp::getOpenMPContextTraitPropertyName(Property.Kind) + .take_front(3); + } + } + return OS.str(); +} + llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI) { LangOptions LO; diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -333,17 +333,6 @@ /// default location. virtual unsigned getDefaultLocationReserved2Flags() const { return 0; } - /// Tries to emit declare variant function for \p OldGD from \p NewGD. - /// \param OrigAddr LLVM IR value for \p OldGD. - /// \param IsForDefinition true, if requested emission for the definition of - /// \p OldGD. - /// \returns true, was able to emit a definition function for \p OldGD, which - /// points to \p NewGD. - virtual bool tryEmitDeclareVariant(const GlobalDecl &NewGD, - const GlobalDecl &OldGD, - llvm::GlobalValue *OrigAddr, - bool IsForDefinition); - /// Returns default flags for the barriers depending on the directive, for /// which this barier is going to be emitted. static unsigned getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind); @@ -685,12 +674,6 @@ /// must be emitted. llvm::SmallDenseSet DeferredGlobalVariables; - /// Mapping of the original functions to their variants and original global - /// decl. - llvm::MapVector, - std::pair> - DeferredVariantFunction; - using NontemporalDeclsSet = llvm::SmallDenseSet>; /// Stack for list of declarations in current context marked as nontemporal. /// The set is the union of all current stack elements. @@ -1717,9 +1700,6 @@ /// Return whether the unified_shared_memory has been specified. bool hasRequiresUnifiedSharedMemory() const; - /// Emits the definition of the declare variant function. - virtual bool emitDeclareVariant(GlobalDecl GD, bool IsForDefinition); - /// Checks if the \p VD variable is marked as nontemporal declaration in /// current context. bool isNontemporalDecl(const ValueDecl *VD) const; diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1269,52 +1269,6 @@ loadOffloadInfoMetadata(); } -bool CGOpenMPRuntime::tryEmitDeclareVariant(const GlobalDecl &NewGD, - const GlobalDecl &OldGD, - llvm::GlobalValue *OrigAddr, - bool IsForDefinition) { - // Emit at least a definition for the aliasee if the the address of the - // original function is requested. - if (IsForDefinition || OrigAddr) - (void)CGM.GetAddrOfGlobal(NewGD); - StringRef NewMangledName = CGM.getMangledName(NewGD); - llvm::GlobalValue *Addr = CGM.GetGlobalValue(NewMangledName); - if (Addr && !Addr->isDeclaration()) { - const auto *D = cast(OldGD.getDecl()); - const CGFunctionInfo &FI = CGM.getTypes().arrangeGlobalDeclaration(NewGD); - llvm::Type *DeclTy = CGM.getTypes().GetFunctionType(FI); - - // Create a reference to the named value. This ensures that it is emitted - // if a deferred decl. - llvm::GlobalValue::LinkageTypes LT = CGM.getFunctionLinkage(OldGD); - - // Create the new alias itself, but don't set a name yet. - auto *GA = - llvm::GlobalAlias::create(DeclTy, 0, LT, "", Addr, &CGM.getModule()); - - if (OrigAddr) { - assert(OrigAddr->isDeclaration() && "Expected declaration"); - - GA->takeName(OrigAddr); - OrigAddr->replaceAllUsesWith( - llvm::ConstantExpr::getBitCast(GA, OrigAddr->getType())); - OrigAddr->eraseFromParent(); - } else { - GA->setName(CGM.getMangledName(OldGD)); - } - - // Set attributes which are particular to an alias; this is a - // specialization of the attributes which may be set on a global function. - if (D->hasAttr() || D->hasAttr() || - D->isWeakImported()) - GA->setLinkage(llvm::Function::WeakAnyLinkage); - - CGM.SetCommonAttributes(OldGD, GA); - return true; - } - return false; -} - void CGOpenMPRuntime::clear() { InternalVars.clear(); // Clean non-target variable declarations possibly used only in debug info. @@ -1328,14 +1282,6 @@ continue; GV->eraseFromParent(); } - // Emit aliases for the deferred aliasees. - for (const auto &Pair : DeferredVariantFunction) { - StringRef MangledName = CGM.getMangledName(Pair.second.second); - llvm::GlobalValue *Addr = CGM.GetGlobalValue(MangledName); - // If not able to emit alias, just emit original declaration. - (void)tryEmitDeclareVariant(Pair.second.first, Pair.second.second, Addr, - /*IsForDefinition=*/false); - } } std::string CGOpenMPRuntime::getName(ArrayRef Parts) const { @@ -11075,57 +11021,6 @@ return Address(Addr, Align); } -/// Finds the variant function that matches current context with its context -/// selector. -static const FunctionDecl *getDeclareVariantFunction(CodeGenModule &CGM, - const FunctionDecl *FD) { - if (!FD->hasAttrs() || !FD->hasAttr()) - return FD; - - SmallVector VariantExprs; - SmallVector VMIs; - for (const auto *A : FD->specific_attrs()) { - const OMPTraitInfo &TI = A->getTraitInfos(); - VMIs.push_back(VariantMatchInfo()); - TI.getAsVariantMatchInfo(CGM.getContext(), VMIs.back(), - /* DeviceSetOnly */ false); - VariantExprs.push_back(A->getVariantFuncRef()); - } - - OMPContext Ctx(CGM.getLangOpts().OpenMPIsDevice, CGM.getTriple()); - // FIXME: Keep the context in the OMPIRBuilder so we can add constructs as we - // build them. - - int BestMatchIdx = getBestVariantMatchForContext(VMIs, Ctx); - if (BestMatchIdx < 0) - return FD; - - return cast( - cast(VariantExprs[BestMatchIdx]->IgnoreParenImpCasts()) - ->getDecl()); -} - -bool CGOpenMPRuntime::emitDeclareVariant(GlobalDecl GD, bool IsForDefinition) { - const auto *D = cast(GD.getDecl()); - // If the original function is defined already, use its definition. - StringRef MangledName = CGM.getMangledName(GD); - llvm::GlobalValue *Orig = CGM.GetGlobalValue(MangledName); - if (Orig && !Orig->isDeclaration()) - return false; - const FunctionDecl *NewFD = getDeclareVariantFunction(CGM, D); - // Emit original function if it does not have declare variant attribute or the - // context does not match. - if (NewFD == D) - return false; - GlobalDecl NewGD = GD.getWithDecl(NewFD); - if (tryEmitDeclareVariant(NewGD, GD, Orig, IsForDefinition)) { - DeferredVariantFunction.erase(D); - return true; - } - DeferredVariantFunction.insert(std::make_pair(D, std::make_pair(NewGD, GD))); - return true; -} - CGOpenMPRuntime::NontemporalDeclsRAII::NontemporalDeclsRAII( CodeGenModule &CGM, const OMPLoopDirective &S) : CGM(CGM), NeedToPush(S.hasClausesOfKind()) { diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h @@ -193,18 +193,6 @@ /// Full/Lightweight runtime mode. Used for better optimization. unsigned getDefaultLocationReserved2Flags() const override; - /// Tries to emit declare variant function for \p OldGD from \p NewGD. - /// \param OrigAddr LLVM IR value for \p OldGD. - /// \param IsForDefinition true, if requested emission for the definition of - /// \p OldGD. - /// \returns true, was able to emit a definition function for \p OldGD, which - /// points to \p NewGD. - /// NVPTX backend does not support global aliases, so just use the function, - /// emitted for \p NewGD instead of \p OldGD. - bool tryEmitDeclareVariant(const GlobalDecl &NewGD, const GlobalDecl &OldGD, - llvm::GlobalValue *OrigAddr, - bool IsForDefinition) override; - public: explicit CGOpenMPRuntimeNVPTX(CodeGenModule &CGM); void clear() override; diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp --- a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -1923,19 +1923,6 @@ llvm_unreachable("Unknown flags are requested."); } -bool CGOpenMPRuntimeNVPTX::tryEmitDeclareVariant(const GlobalDecl &NewGD, - const GlobalDecl &OldGD, - llvm::GlobalValue *OrigAddr, - bool IsForDefinition) { - // Emit the function in OldGD with the body from NewGD, if NewGD is defined. - auto *NewFD = cast(NewGD.getDecl()); - if (NewFD->isDefined()) { - CGM.emitOpenMPDeviceFunctionRedefinition(OldGD, NewGD, OrigAddr); - return true; - } - return false; -} - CGOpenMPRuntimeNVPTX::CGOpenMPRuntimeNVPTX(CodeGenModule &CGM) : CGOpenMPRuntime(CGM, "_", "$") { if (!CGM.getLangOpts().OpenMPIsDevice) diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1293,11 +1293,6 @@ /// \param D Requires declaration void EmitOMPRequiresDecl(const OMPRequiresDecl *D); - /// Emits the definition of \p OldGD function with body from \p NewGD. - /// Required for proper handling of declare variant directive on the GPU. - void emitOpenMPDeviceFunctionRedefinition(GlobalDecl OldGD, GlobalDecl NewGD, - llvm::GlobalValue *GV); - /// Returns whether the given record has hidden LTO visibility and therefore /// may participate in (single-module) CFI and whole-program vtable /// optimization. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2579,11 +2579,6 @@ return; } - // Check if this must be emitted as declare variant. - if (LangOpts.OpenMP && isa(Global) && OpenMPRuntime && - OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/false)) - return; - // If we're deferring emission of a C++ variable with an // initializer, remember the order in which it appeared in the file. if (getLangOpts().CPlusPlus && isa(Global) && @@ -2789,50 +2784,6 @@ EmitGlobalFunctionDefinition(GD, GV); } -void CodeGenModule::emitOpenMPDeviceFunctionRedefinition( - GlobalDecl OldGD, GlobalDecl NewGD, llvm::GlobalValue *GV) { - assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && - OpenMPRuntime && "Expected OpenMP device mode."); - const auto *D = cast(OldGD.getDecl()); - - // Compute the function info and LLVM type. - const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(OldGD); - llvm::FunctionType *Ty = getTypes().GetFunctionType(FI); - - // Get or create the prototype for the function. - if (!GV || (GV->getType()->getElementType() != Ty)) { - GV = cast(GetOrCreateLLVMFunction( - getMangledName(OldGD), Ty, GlobalDecl(), /*ForVTable=*/false, - /*DontDefer=*/true, /*IsThunk=*/false, llvm::AttributeList(), - ForDefinition)); - SetFunctionAttributes(OldGD, cast(GV), - /*IsIncompleteFunction=*/false, - /*IsThunk=*/false); - } - // We need to set linkage and visibility on the function before - // generating code for it because various parts of IR generation - // want to propagate this information down (e.g. to local static - // declarations). - auto *Fn = cast(GV); - setFunctionLinkage(OldGD, Fn); - - // FIXME: this is redundant with part of - // setFunctionDefinitionAttributes - setGVProperties(Fn, OldGD); - - MaybeHandleStaticInExternC(D, Fn); - - maybeSetTrivialComdat(*D, *Fn); - - CodeGenFunction(*this).GenerateCode(NewGD, Fn, FI); - - setNonAliasAttributes(OldGD, Fn); - SetLLVMFunctionAttributesForDefinition(D, Fn); - - if (D->hasAttr()) - AddGlobalAnnotations(D, Fn); -} - void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { const auto *D = cast(GD.getDecl()); @@ -3147,10 +3098,6 @@ EmitGlobal(GDDef); } } - // Check if this must be emitted as declare variant and emit reference to - // the the declare variant function. - if (LangOpts.OpenMP && OpenMPRuntime) - (void)OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/true); if (FD->isMultiVersion()) { const auto *TA = FD->getAttr(); @@ -4446,11 +4393,6 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { - // Check if this must be emitted as declare variant. - if (LangOpts.OpenMP && OpenMPRuntime && - OpenMPRuntime->emitDeclareVariant(GD, /*IsForDefinition=*/true)) - return; - const auto *D = cast(GD.getDecl()); // Compute the function info and LLVM type. diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1782,8 +1782,10 @@ OMPContext OMPCtx(ASTCtx.getLangOpts().OpenMPIsDevice, ASTCtx.getTargetInfo().getTriple()); - if (isVariantApplicableInContext(VMI, OMPCtx)) + if (isVariantApplicableInContext(VMI, OMPCtx)) { + Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI); break; + } // Elide all the code till the matching end declare variant was found. unsigned Nesting = 1; @@ -1807,11 +1809,14 @@ return nullptr; break; } - case OMPD_end_declare_variant: - // FIXME: With the sema changes we will keep track of nesting and be able to - // diagnose unmatchend OMPD_end_declare_variant. + case OMPD_end_declare_variant: { + if (Actions.isInOpenMPDeclareVariantScope()) + Actions.ActOnOpenMPEndDeclareVariant(); + else + Diag(Loc, diag::err_expected_begin_declare_variant); ConsumeToken(); break; + } case OMPD_declare_variant: case OMPD_declare_simd: { // The syntax is: diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2720,6 +2720,11 @@ // honored it. ++I; continue; + } else if (isa(NewAttribute)) { + // We allow to add OMP[Begin]DeclareVariantAttr to be added to + // declarations after defintions. + ++I; + continue; } S.Diag(NewAttribute->getLocation(), @@ -13542,9 +13547,20 @@ assert(D.isFunctionDeclarator() && "Not a function declarator!"); Scope *ParentScope = FnBodyScope->getParent(); + FunctionDecl *BaseFD = nullptr; + if (LangOpts.OpenMP && isInOpenMPDeclareVariantScope()) + BaseFD = ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( + ParentScope, D); + D.setFunctionDefinitionKind(FDK_Definition); Decl *DP = HandleDeclarator(ParentScope, D, TemplateParameterLists); - return ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody); + Decl *Dcl = ActOnStartOfFunctionDef(FnBodyScope, DP, SkipBody); + + if (BaseFD) + ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( + cast(Dcl), BaseFD); + + return Dcl; } void Sema::ActOnFinishInlineFunctionDef(FunctionDecl *D) { diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5724,6 +5724,10 @@ } } + if (LangOpts.OpenMP) + Call = ActOnOpenMPCall(*this, Call, Scope, LParenLoc, ArgExprs, RParenLoc, + ExecConfig); + return Call; } @@ -15959,7 +15963,6 @@ } if (LangOpts.OpenMP) { - markOpenMPDeclareVariantFuncsReferenced(Loc, Func, MightBeOdrUse); if (LangOpts.OpenMPIsDevice) checkOpenMPDeviceFunction(Loc, Func); else diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2208,6 +2208,37 @@ void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } +void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, + OMPTraitInfo &TI) { + if (!OMPDeclareVariantScopes.empty()) { + Diag(Loc, diag::warn_nested_declare_variant); + return; + } + OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); +} + +void Sema::ActOnOpenMPEndDeclareVariant() { + assert(isInOpenMPDeclareVariantScope() && + "Not in OpenMP declare variant scope!"); + + OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); + for (auto &It : DVScope.Variant2BaseMap) { + FunctionDecl *FD = It.first; + FunctionDecl *BaseFD = It.second; + + Expr *VariantFuncRef = DeclRefExpr::Create( + Context, NestedNameSpecifierLoc(), SourceLocation(), FD, + /* RefersToEnclosingVariableOrCapture */ false, + /* NameLoc */ FD->getLocation(), FD->getType(), + ExprValueKind::VK_RValue); + auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( + Context, VariantFuncRef, DVScope.TI); + BaseFD->addAttr(OMPDeclareVariantA); + } + + OMPDeclareVariantScopes.pop_back(); +} + void Sema::finalizeOpenMPDelayedAnalysis() { assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); // Diagnose implicit declare target functions and their callees. @@ -5371,6 +5402,102 @@ FD->setParams(Params); } +FunctionDecl * +Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, + Declarator &D) { + OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); + auto *BaseFD = cast(ActOnDeclarator(S, D)); + + IdentifierInfo &VariangtII = Context.Idents.get( + (D.getIdentifier()->getName() + "." + DVScope.NameSuffix).str()); + D.SetIdentifier(&VariangtII, D.getBeginLoc()); + return BaseFD; +} + +void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( + FunctionDecl *FD, FunctionDecl *BaseFD) { + OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); + DVScope.Variant2BaseMap[FD] = BaseFD; +} + +ExprResult Sema::ActOnOpenMPCall(Sema &S, ExprResult Call, Scope *Scope, + SourceLocation LParenLoc, + MultiExprArg ArgExprs, + SourceLocation RParenLoc, Expr *ExecConfig) { + // The common case is a regular call we do not want to specialize at all. Try + // to make that case fast by bailing early. + CallExpr *CE = dyn_cast(Call.get()); + if (!CE) + return Call; + + FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); + if (!CalleeFnDecl) + return Call; + + if (!CalleeFnDecl->hasAttr()) + return Call; + + ASTContext &Context = S.getASTContext(); + OMPContext OMPCtx(S.getLangOpts().OpenMPIsDevice, + Context.getTargetInfo().getTriple()); + + SmallVector Exprs; + SmallVector VMIs; + while (CalleeFnDecl) { + for (OMPDeclareVariantAttr *A : + CalleeFnDecl->specific_attrs()) { + Expr *VariantRef = A->getVariantFuncRef(); + + VariantMatchInfo VMI; + OMPTraitInfo &TI = A->getTraitInfo(); + TI.getAsVariantMatchInfo(Context, VMI, /* DeviceSetOnly */ false); + if (!isVariantApplicableInContext(VMI, OMPCtx)) + continue; + + VMIs.push_back(VMI); + Exprs.push_back(VariantRef); + } + + CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); + } + + ExprResult NewCall; + do { + int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); + if (BestIdx < 0) + return Call; + Expr *BestExpr = cast(Exprs[BestIdx]); + Decl *BestDecl = cast(BestExpr)->getDecl(); + + { + // Try to build a (member) call expression for the current best applicable + // variant expression. We allow this to fail in which case we continue with + // the next best variant expression. + Sema::TentativeAnalysisScope Trap(*this); + + if (auto *SpecializedMethod = dyn_cast(BestDecl)) { + auto *MemberCall = dyn_cast(CE); + BestExpr = MemberExpr::CreateImplicit( + S.Context, MemberCall->getImplicitObjectArgument(), + /* IsArrow */ false, SpecializedMethod, S.Context.BoundMemberTy, + MemberCall->getValueKind(), MemberCall->getObjectKind()); + } + NewCall = S.BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, + ExecConfig); + if (NewCall.isUsable()) + break; + } + + VMIs.erase(VMIs.begin() + BestIdx); + Exprs.erase(Exprs.begin() + BestIdx); + } while (!VMIs.empty()); + + if (!NewCall.isUsable()) + return Call; + + return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); +} + Optional> Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, Expr *VariantRef, OMPTraitInfo &TI, @@ -5643,25 +5770,6 @@ FD->addAttr(NewAttr); } -void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, - FunctionDecl *Func, - bool MightBeOdrUse) { - assert(LangOpts.OpenMP && "Expected OpenMP mode."); - - if (!Func->isDependentContext() && Func->hasAttrs()) { - for (OMPDeclareVariantAttr *A : - Func->specific_attrs()) { - // TODO: add checks for active OpenMP context where possible. - Expr *VariantRef = A->getVariantFuncRef(); - auto *DRE = cast(VariantRef->IgnoreParenImpCasts()); - auto *F = cast(DRE->getDecl()); - if (!F->isDefined() && F->isTemplateInstantiation()) - InstantiateFunctionDefinition(Loc, F->getFirstDecl()); - MarkFunctionReferenced(Loc, F, MightBeOdrUse); - } - } -} - StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef Clauses, Stmt *AStmt, SourceLocation StartLoc, diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -334,6 +334,11 @@ } } else if (const PseudoObjectExpr *POE = dyn_cast(E)) { const Expr *Source = POE->getSyntacticForm(); + // Handle the actually selected call of an OpenMP specialized call. + if (LangOpts.OpenMP && isa(Source) && + POE->getNumSemanticExprs() == 1 && + isa(POE->getSemanticExpr(0))) + return DiagnoseUnusedExprResult(POE->getSemanticExpr(0)); if (isa(Source)) DiagID = diag::warn_unused_container_subscript_expr; else diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant.c deleted file mode 100644 --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant.c +++ /dev/null @@ -1,55 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -ast-dump %s | FileCheck %s - -#pragma omp begin declare variant match(device={kind(cpu)}) -int also_before(void) { - return 0; -} -#pragma omp end declare variant - -#pragma omp begin declare variant match(device={kind(gpu)}) -int also_after(void) { - return 2; -} -int also_before(void) { - return 2; -} -#pragma omp end declare variant - - -#pragma omp begin declare variant match(device={kind(fpga)}) - -This text is never parsed! - -#pragma omp end declare variant - -int also_after(void) { - return 0; -} - -int test() { - return also_after() + also_before(); -} - -// Make sure: -// - we do see the ast nodes for the cpu kind -// - we do not see the ast nodes for the gpu kind -// - we do not choke on the text in the kind(fpga) guarded scope. - -// CHECK: -FunctionDecl {{.*}} <{{.*}}4:1, line:{{.*}}:1> line:{{.*}}:5 used also_before 'int (void)' -// CHECK-NEXT: -CompoundStmt {{.*}} -// CHECK-NEXT: `-ReturnStmt {{.*}} -// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 0 -// CHECK-NEXT: -FunctionDecl {{.*}} line:{{.*}}:5 used also_after 'int (void)' -// CHECK-NEXT: -CompoundStmt {{.*}} -// CHECK-NEXT: `-ReturnStmt {{.*}} -// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 0 -// CHECK-NEXT: `-FunctionDecl {{.*}} line:{{.*}}:5 test 'int ()' -// CHECK-NEXT: `-CompoundStmt {{.*}} -// CHECK-NEXT: `-ReturnStmt {{.*}} -// CHECK-NEXT: `-BinaryOperator {{.*}} 'int' '+' -// CHECK-NEXT: |-CallExpr {{.*}} 'int' -// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'int (*)(void)' -// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int (void)' Function {{.*}} 'also_after' 'int (void)' -// CHECK-NEXT: `-CallExpr {{.*}} 'int' -// CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'int (*)(void)' -// CHECK-NEXT: `-DeclRefExpr {{.*}} 'int (void)' Function {{.*}} 'also_before' 'int (void)' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_1.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_1.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_1.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +int also_before(void) { + return 0; +} + +#pragma omp begin declare variant match(device={kind(gpu)}) +int also_after(void) { + return 1; +} +int also_before(void) { + return 2; +} +#pragma omp end declare variant + + +#pragma omp begin declare variant match(device={kind(fpga)}) + +This text is never parsed! + +#pragma omp end declare variant + +int also_after(void) { + return 0; +} + +int test() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we do not see the ast nodes for the gpu kind +// - we do not choke on the text in the kind(fpga) guarded scopes + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] line:25:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_6:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_7:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: `-FunctionDecl [[ADDR_8:0x[a-z0-9]*]] line:29:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_9:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_10:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_11:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_12:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_13:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_14:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_4]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_15:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_16:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_2.c @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +#pragma omp begin declare variant match(device={kind(cpu)}) +int also_before(void) { + return 0; +} +#pragma omp end declare variant + +#pragma omp begin declare variant match(implementation={vendor(score(100):llvm)}) +int also_after(void) { + return 0; +} +#pragma omp end declare variant +#pragma omp begin declare variant match(implementation={vendor(score(0):llvm)}) +int also_before(void) { + return 1; +} +#pragma omp end declare variant + +int also_after(void) { + return 2; +} + +int test() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we do see the ast nodes for the cpu kind +// - we do see the ast nodes for the llvm vendor +// - we pick the right callees + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before.SdevPcpu 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:12:1 also_after.SimpPllv 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Inherited Implicit device={kind(cpu)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:17:1 also_before.SimpPllv 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] prev [[ADDR_7]] line:22:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_27:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_30:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_31:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_32:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_33:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_37:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before.SdevPcpu' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_3.c @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +#pragma omp begin declare variant match(device={kind(cpu)}) +int also_before(void) { + return 1; +} +#pragma omp end declare variant + +#pragma omp begin declare variant match(implementation={vendor(score(0):llvm)}) +int also_after(void) { + return 0; +} +#pragma omp end declare variant +#pragma omp begin declare variant match(implementation={vendor(score(100):llvm)}) +int also_before(void) { + return 0; +} +#pragma omp end declare variant + +int also_after(void) { + return 2; +} + +int test() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we do see the ast nodes for the cpu kind +// - we do see the ast nodes for the llvm vendor +// - we pick the right callees + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before.SdevPcpu 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:12:1 also_after.SimpPllv 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Inherited Implicit device={kind(cpu)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:17:1 also_before.SimpPllv 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] prev [[ADDR_7]] line:22:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_27:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_30:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_31:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_32:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_33:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_37:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_17]] 'int ({{.*}})' Function [[ADDR_18]] 'also_before.SimpPllv' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_4.c @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +#pragma omp begin declare variant match(device={kind(cpu)}) +int also_before(void) { + return 0; +} +#pragma omp end declare variant + +int also_after(void) { + return 0; +} + +int test() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we do see the ast nodes for the cpu kind +// - we pick the right callees + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before.SdevPcpu 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] line:11:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: `-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] line:15:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_13:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_14:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_15:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_16:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_7]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_18:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_19:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_20:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_21:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_0]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_22:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_23:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before.SdevPcpu' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_5.c @@ -0,0 +1,158 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s --check-prefix=CXX +// expected-no-diagnostics + +int also_before(void) { + return 1; +} + +#pragma omp begin declare variant match(implementation={vendor(llvm)}) +int also_after(void) { + return 0; +} +int also_before(void) { + return 0; +} +#pragma omp end declare variant + +int also_after(void) { + return 2; +} + +int main() { + // Should return 0. + return (also_after)() + + (also_before)() + + (&also_after)() + + (&also_before)(); +} + +// Make sure: +// - we see the specialization in the AST +// - we pick the right callees + +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPllv 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPllv 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: `-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_27:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | | `-ParenExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_33:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// C-NEXT: | | | `-CallExpr [[ADDR_34:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: | | `-PseudoObjectExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-CallExpr [[ADDR_37:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-ParenExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// C-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before.SimpPllv' 'int ({{.*}})' +// C-NEXT: | `-PseudoObjectExpr [[ADDR_43:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-CallExpr [[ADDR_44:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ParenExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-UnaryOperator [[ADDR_46:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | | `-DeclRefExpr [[ADDR_47:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_48:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: `-PseudoObjectExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// C-NEXT: |-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ParenExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-UnaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// C-NEXT: `-CallExpr [[ADDR_55:0x[a-z0-9]*]] 'int' +// C-NEXT: `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before.SimpPllv' 'int ({{.*}})' + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPllv 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[CXX:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPllv 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: `-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_27:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_28:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-PseudoObjectExpr [[ADDR_29:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | | `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | | `-ParenExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' lvalue +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_33:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | | | `-CallExpr [[ADDR_34:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: | | `-PseudoObjectExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-CallExpr [[ADDR_37:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-ParenExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' lvalue +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[CXX]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: | `-PseudoObjectExpr [[ADDR_43:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-CallExpr [[ADDR_44:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ParenExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-UnaryOperator [[ADDR_46:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_47:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_48:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: `-PseudoObjectExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ParenExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-UnaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | `-DeclRefExpr [[ADDR_54:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[CXX]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: `-CallExpr [[ADDR_55:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: `-DeclRefExpr [[ADDR_13]] 'int ({{.*}})' Function [[ADDR_14]] 'also_before.SimpPllv' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_6.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +int also_before(void) { + return 0; +} + +#pragma omp begin declare variant match(implementation={vendor(ibm)}) +int also_after(void) { + return 1; +} +int also_before(void) { + return 2; +} +#pragma omp end declare variant + +int also_after(void) { + return 0; +} + +int main() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we see the specialization in the AST +// - we do use the original pointers for the calls as the variants are not applicable (this is not the ibm compiler). + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(ibm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPibm' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPibm 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(ibm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPibm' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPibm 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(ibm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPibm' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 main 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_24:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_25:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_26:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_27:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_30:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_31:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_32:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_7.c @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +int OK_1(void); + +#pragma omp begin declare variant match(implementation={vendor(intel)}) +int OK_1(void) { + return 1; +} +int OK_2(void) { + return 1; +} +int not_OK(void) { + return 1; +} +int OK_3(void) { + return 1; +} +#pragma omp end declare variant + +int OK_3(void); + +int test() { + // Should cause an error due to not_OK() + return OK_1() + not_OK() + OK_3(); +} + +// Make sure: +// - we see a single error for `not_OK` +// - we do not see errors for OK_{1,2,3} +// FIXME: We actually do not see there error here. +// This case is unlikely to happen in practise and hard to diagnose during SEMA. +// We will issue an error during code generation instead. This is similar to the +// diagnosis in other multi-versioning schemes. + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:14> col:5 used OK_1 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_1:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used OK_1 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_2:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_3:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_4:0x[a-z0-9]*]] 'OK_1.SimpPint' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_4]] line:8:1 OK_1.SimpPint 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_6:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_7:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_8:0x[a-z0-9]*]] col:5 OK_2 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_9:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_10:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11:0x[a-z0-9]*]] 'OK_2.SimpPint' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_11]] line:11:1 OK_2.SimpPint 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_13:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_14:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_15:0x[a-z0-9]*]] col:5 used not_OK 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'not_OK.SimpPint' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:14:1 not_OK.SimpPint 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] col:5 used OK_3 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_23:0x[a-z0-9]*]] <> Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_24:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_25:0x[a-z0-9]*]] 'OK_3.SimpPint' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_25]] line:17:1 OK_3.SimpPint 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_26:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_27:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_28:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] prev [[ADDR_22]] col:5 used OK_3 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_30:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(intel)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_24]] 'int ({{.*}})' Function [[ADDR_25]] 'OK_3.SimpPint' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_31:0x[a-z0-9]*]] line:24:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_32:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_33:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-BinaryOperator [[ADDR_35:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_1]] 'OK_1' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_39:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_40:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_41:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_15]] 'not_OK' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_42:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_43:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_44:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_29]] 'OK_3' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_8.c @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics + +#pragma omp begin declare variant match(device={kind(cpu)}) +int also_before(void) { + return 1; +} +#pragma omp end declare variant + +#pragma omp begin declare variant match(implementation={vendor(score(0):llvm)}) +int also_after(void) { + return 0; +} +#pragma omp end declare variant +#pragma omp begin declare variant match(implementation={vendor(score(100):llvm)}) +int also_before(void) { + return 0; +} +#pragma omp end declare variant + +int also_after(void) { + return 2; +} + +int test() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we do see the ast nodes for the cpu kind +// - we do see the ast nodes for the llvm vendor +// - we pick the right callees + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:21> col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_1:0x[a-z0-9]*]] <> Implicit device={kind(cpu)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_2:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_3:0x[a-z0-9]*]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_3]] line:6:1 also_before.SdevPcpu 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_4:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_5:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_6:0x[a-z0-9]*]] 'int' 1 +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_8:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_10:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_10]] line:12:1 also_after.SimpPllv 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_11:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_13:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_14:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | |-OMPDeclareVariantAttr [[ADDR_15:0x[a-z0-9]*]] <> Inherited Implicit device={kind(cpu)} +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_2]] 'int ({{.*}})' Function [[ADDR_3]] 'also_before.SdevPcpu' 'int ({{.*}})' +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_16:0x[a-z0-9]*]] <> Implicit implementation={vendor(score(100): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_18]] line:17:1 also_before.SimpPllv 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_22:0x[a-z0-9]*]] prev [[ADDR_7]] line:22:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | |-CompoundStmt [[ADDR_23:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-ReturnStmt [[ADDR_24:0x[a-z0-9]*]] +// CHECK-NEXT: | | `-IntegerLiteral [[ADDR_25:0x[a-z0-9]*]] 'int' 2 +// CHECK-NEXT: | `-OMPDeclareVariantAttr [[ADDR_26:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(score(0): llvm)} +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: `-FunctionDecl [[ADDR_27:0x[a-z0-9]*]] line:26:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_28:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_29:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_30:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-PseudoObjectExpr [[ADDR_31:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | |-CallExpr [[ADDR_32:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr [[ADDR_33:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_34:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_22]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: | `-CallExpr [[ADDR_35:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_36:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_9]] 'int ({{.*}})' Function [[ADDR_10]] 'also_after.SimpPllv' 'int ({{.*}})' +// CHECK-NEXT: `-PseudoObjectExpr [[ADDR_37:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: |-CallExpr [[ADDR_38:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_14]] 'also_before' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_17]] 'int ({{.*}})' Function [[ADDR_18]] 'also_before.SimpPllv' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_9.c @@ -0,0 +1,184 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s --check-prefix=CXX +// expected-no-diagnostics + +int also_before(void) { + return 0; +} + +#pragma omp begin declare variant match(implementation={vendor(llvm)}) +int also_after(void) { + return 1; +} +int also_before(void) { + return 2; +} +#pragma omp end declare variant + +int also_after(void) { + return 0; +} + +void foo(); +typedef int(*fd)(void); +int main() { + // Should return 0. + fd fns[2]; + fns[0] = &also_before; + fns[1] = also_after; + return (foo(), also_after)() + + (fns[0])() + + (1[fns])(); +} + +// Make sure: +// - we see the specialization in the AST +// - we pick the right callees + +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPllv 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPllv 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] col:6 used foo 'void ({{.*}})' +// C-NEXT: |-TypedefDecl [[ADDR_24:0x[a-z0-9]*]] col:14 referenced fd 'int (*)({{.*}})' +// C-NEXT: | `-PointerType [[ADDR_25:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-ParenType [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' sugar +// C-NEXT: | `-FunctionProtoType [[ADDR_27:0x[a-z0-9]*]] 'int ({{.*}})' cdecl +// C-NEXT: | `-BuiltinType [[ADDR_28:0x[a-z0-9]*]] 'int' +// C-NEXT: `-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:24:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] +// C-NEXT: |-DeclStmt [[ADDR_31:0x[a-z0-9]*]] +// C-NEXT: | `-VarDecl [[ADDR_32:0x[a-z0-9]*]] col:6 used fns 'fd [2]' +// C-NEXT: |-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' '=' +// C-NEXT: | |-ArraySubscriptExpr [[ADDR_34:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'fd *' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_36:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// C-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-UnaryOperator [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// C-NEXT: |-BinaryOperator [[ADDR_40:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' '=' +// C-NEXT: | |-ArraySubscriptExpr [[ADDR_41:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'fd *' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// C-NEXT: | | `-IntegerLiteral [[ADDR_44:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: | `-ImplicitCastExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_46:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// C-NEXT: `-ReturnStmt [[ADDR_47:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// C-NEXT: | | `-ParenExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-BinaryOperator [[ADDR_52:0x[a-z0-9]*]] 'int (*)({{.*}})' ',' +// C-NEXT: | | |-CallExpr [[ADDR_53:0x[a-z0-9]*]] 'void' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_54:0x[a-z0-9]*]] 'void (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'void ({{.*}})' Function [[ADDR_23]] 'foo' 'void ({{.*}})' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_56:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_57:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_58:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_59:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// C-NEXT: | `-ParenExpr [[ADDR_60:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | `-ArraySubscriptExpr [[ADDR_61:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: | |-ImplicitCastExpr [[ADDR_62:0x[a-z0-9]*]] 'fd *' +// C-NEXT: | | `-DeclRefExpr [[ADDR_63:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// C-NEXT: | `-IntegerLiteral [[ADDR_64:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: `-CallExpr [[ADDR_65:0x[a-z0-9]*]] 'int' +// C-NEXT: `-ImplicitCastExpr [[ADDR_66:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// C-NEXT: `-ParenExpr [[ADDR_67:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: `-ArraySubscriptExpr [[ADDR_68:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// C-NEXT: |-IntegerLiteral [[ADDR_69:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: `-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'fd *' +// C-NEXT: `-DeclRefExpr [[ADDR_71:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPllv 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPllv 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] col:6 used foo 'void ({{.*}})' +// CXX-NEXT: |-TypedefDecl [[ADDR_24:0x[a-z0-9]*]] col:14 referenced fd 'int (*)({{.*}})' +// CXX-NEXT: | `-PointerType [[ADDR_25:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-ParenType [[ADDR_26:0x[a-z0-9]*]] 'int ({{.*}})' sugar +// CXX-NEXT: | `-FunctionProtoType [[ADDR_27:0x[a-z0-9]*]] 'int ({{.*}})' cdecl +// CXX-NEXT: | `-BuiltinType [[ADDR_28:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-FunctionDecl [[ADDR_29:0x[a-z0-9]*]] line:24:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_30:0x[a-z0-9]*]] +// CXX-NEXT: |-DeclStmt [[ADDR_31:0x[a-z0-9]*]] +// CXX-NEXT: | `-VarDecl [[ADDR_32:0x[a-z0-9]*]] col:6 used fns 'fd [2]' +// CXX-NEXT: |-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' {{.*}}'=' +// CXX-NEXT: | |-ArraySubscriptExpr [[ADDR_34:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_35:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_36:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_37:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-UnaryOperator [[ADDR_38:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | `-DeclRefExpr [[ADDR_39:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: |-BinaryOperator [[ADDR_40:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' {{.*}}'=' +// CXX-NEXT: | |-ArraySubscriptExpr [[ADDR_41:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_44:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_45:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_46:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: `-ReturnStmt [[ADDR_47:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_48:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-CallExpr [[ADDR_50:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_51:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-ParenExpr [[ADDR_52:0x[a-z0-9]*]] 'int ({{.*}})' lvalue +// CXX-NEXT: | | `-BinaryOperator [[ADDR_53:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}',' +// CXX-NEXT: | | |-CallExpr [[ADDR_54:0x[a-z0-9]*]] 'void' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_55:0x[a-z0-9]*]] 'void (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_56:0x[a-z0-9]*]] 'void ({{.*}})' {{.*}}Function [[ADDR_23]] 'foo' 'void ({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_57:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_58:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_59:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// CXX-NEXT: | `-ParenExpr [[ADDR_60:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | `-ArraySubscriptExpr [[ADDR_61:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_62:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_63:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' +// CXX-NEXT: | `-IntegerLiteral [[ADDR_64:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: `-CallExpr [[ADDR_65:0x[a-z0-9]*]] 'int' +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_66:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' +// CXX-NEXT: `-ParenExpr [[ADDR_67:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: `-ArraySubscriptExpr [[ADDR_68:0x[a-z0-9]*]] 'fd':'int (*)({{.*}})' lvalue +// CXX-NEXT: |-IntegerLiteral [[ADDR_69:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: `-ImplicitCastExpr [[ADDR_70:0x[a-z0-9]*]] 'fd *' +// CXX-NEXT: `-DeclRefExpr [[ADDR_71:0x[a-z0-9]*]] 'fd [2]' {{.*}}Var [[ADDR_32]] 'fns' 'fd [2]' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_addr_1.c @@ -0,0 +1,151 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s --check-prefix=C +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s --check-prefix=CXX +// expected-no-diagnostics + +int also_before(void) { + return 0; +} + +#pragma omp begin declare variant match(implementation={vendor(llvm)}) +int also_after(void) { + return 1; +} +int also_before(void) { + return 2; +} +#pragma omp end declare variant + +int also_after(void) { + return 0; +} + +int test(int (*fd)(void)) { + return fd(); +} +int main() { + // Should return 0. + return test(also_after) + + test(also_before) + + test(&also_after) + + test(&also_before); +} + +// Make sure: +// - we see the specialization in the AST +// - we pick the right callees + +// C: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPllv 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// C-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPllv 'int ({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// C-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 +// C-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// C-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// C-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// C-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// C-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// C-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// C-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 used test 'int (int (*)({{.*}}))' +// C-NEXT: | |-ParmVarDecl [[ADDR_24:0x[a-z0-9]*]] col:16 used fd 'int (*)({{.*}})' +// C-NEXT: | `-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] +// C-NEXT: | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] +// C-NEXT: | `-CallExpr [[ADDR_27:0x[a-z0-9]*]] 'int' +// C-NEXT: | `-ImplicitCastExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int (*)({{.*}})' {{.*}}ParmVar [[ADDR_24]] 'fd' 'int (*)({{.*}})' +// C-NEXT: `-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] line:25:5 main 'int ({{.*}})' +// C-NEXT: `-CompoundStmt [[ADDR_31:0x[a-z0-9]*]] +// C-NEXT: `-ReturnStmt [[ADDR_32:0x[a-z0-9]*]] +// C-NEXT: `-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | |-BinaryOperator [[ADDR_35:0x[a-z0-9]*]] 'int' '+' +// C-NEXT: | | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// C-NEXT: | | | |-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | | | | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: | | | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// C-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// C-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: | | `-ImplicitCastExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' +// C-NEXT: | | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// C-NEXT: | `-CallExpr [[ADDR_46:0x[a-z0-9]*]] 'int' +// C-NEXT: | |-ImplicitCastExpr [[ADDR_47:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | | `-DeclRefExpr [[ADDR_48:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: | `-UnaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: | `-DeclRefExpr [[ADDR_50:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// C-NEXT: `-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// C-NEXT: |-ImplicitCastExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// C-NEXT: | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// C-NEXT: `-UnaryOperator [[ADDR_54:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// C-NEXT: `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_11]] 'also_before' 'int ({{.*}})' + +// CXX: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_5:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_7:0x[a-z0-9]*]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_7]] line:10:1 also_after.SimpPllv 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 1 +// CXX-NEXT: |-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_12:0x[a-z0-9]*]] <> Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_13:0x[a-z0-9]*]] 'int ({{.*}})' Function [[ADDR_14:0x[a-z0-9]*]] 'also_before.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_14]] line:13:1 also_before.SimpPllv 'int ({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_15:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_16:0x[a-z0-9]*]] +// CXX-NEXT: | `-IntegerLiteral [[ADDR_17:0x[a-z0-9]*]] 'int' 2 +// CXX-NEXT: |-FunctionDecl [[ADDR_18:0x[a-z0-9]*]] prev [[ADDR_4]] line:18:5 used also_after 'int ({{.*}})' +// CXX-NEXT: | |-CompoundStmt [[ADDR_19:0x[a-z0-9]*]] +// CXX-NEXT: | | `-ReturnStmt [[ADDR_20:0x[a-z0-9]*]] +// CXX-NEXT: | | `-IntegerLiteral [[ADDR_21:0x[a-z0-9]*]] 'int' 0 +// CXX-NEXT: | `-OMPDeclareVariantAttr [[ADDR_22:0x[a-z0-9]*]] <> Inherited Implicit implementation={vendor(llvm)} +// CXX-NEXT: | `-DeclRefExpr [[ADDR_6]] 'int ({{.*}})' Function [[ADDR_7]] 'also_after.SimpPllv' 'int ({{.*}})' +// CXX-NEXT: |-FunctionDecl [[ADDR_23:0x[a-z0-9]*]] line:22:5 used test 'int (int (*)({{.*}}))' +// CXX-NEXT: | |-ParmVarDecl [[ADDR_24:0x[a-z0-9]*]] col:16 used fd 'int (*)({{.*}})' +// CXX-NEXT: | `-CompoundStmt [[ADDR_25:0x[a-z0-9]*]] +// CXX-NEXT: | `-ReturnStmt [[ADDR_26:0x[a-z0-9]*]] +// CXX-NEXT: | `-CallExpr [[ADDR_27:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | `-ImplicitCastExpr [[ADDR_28:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_29:0x[a-z0-9]*]] 'int (*)({{.*}})' {{.*}}ParmVar [[ADDR_24]] 'fd' 'int (*)({{.*}})' +// CXX-NEXT: `-FunctionDecl [[ADDR_30:0x[a-z0-9]*]] line:25:5 main 'int ({{.*}})' +// CXX-NEXT: `-CompoundStmt [[ADDR_31:0x[a-z0-9]*]] +// CXX-NEXT: `-ReturnStmt [[ADDR_32:0x[a-z0-9]*]] +// CXX-NEXT: `-BinaryOperator [[ADDR_33:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: |-BinaryOperator [[ADDR_34:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | |-BinaryOperator [[ADDR_35:0x[a-z0-9]*]] 'int' '+' +// CXX-NEXT: | | |-CallExpr [[ADDR_36:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | | |-ImplicitCastExpr [[ADDR_37:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | | | | `-DeclRefExpr [[ADDR_38:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: | | | `-ImplicitCastExpr [[ADDR_39:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_40:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: | | `-CallExpr [[ADDR_41:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | | |-ImplicitCastExpr [[ADDR_42:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | | | `-DeclRefExpr [[ADDR_43:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: | | `-ImplicitCastExpr [[ADDR_44:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_45:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' +// CXX-NEXT: | `-CallExpr [[ADDR_46:0x[a-z0-9]*]] 'int' +// CXX-NEXT: | |-ImplicitCastExpr [[ADDR_47:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | | `-DeclRefExpr [[ADDR_48:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: | `-UnaryOperator [[ADDR_49:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: | `-DeclRefExpr [[ADDR_50:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_18]] 'also_after' 'int ({{.*}})' +// CXX-NEXT: `-CallExpr [[ADDR_51:0x[a-z0-9]*]] 'int' +// CXX-NEXT: |-ImplicitCastExpr [[ADDR_52:0x[a-z0-9]*]] 'int (*)(int (*)({{.*}}))' +// CXX-NEXT: | `-DeclRefExpr [[ADDR_53:0x[a-z0-9]*]] 'int (int (*)({{.*}}))' {{.*}}Function [[ADDR_23]] 'test' 'int (int (*)({{.*}}))' +// CXX-NEXT: `-UnaryOperator [[ADDR_54:0x[a-z0-9]*]] 'int (*)({{.*}})' prefix '&' cannot overflow +// CXX-NEXT: `-DeclRefExpr [[ADDR_55:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_11]] 'also_before' 'int ({{.*}})' diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_decl_1.c b/clang/test/AST/ast-dump-openmp-begin-declare-variant_decl_1.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_decl_1.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify -ast-dump %s -x c++| FileCheck %s +// expected-no-diagnostics +// FIXME: We have to improve the warnings here as nothing is impacted by the declare variant. +int also_before(void) { + return 0; +} + +#pragma omp begin declare variant match(device={kind(cpu)}) +int also_before(void); +#pragma omp end declare variant +#pragma omp begin declare variant match(implementation={vendor(score(100):llvm)}) +int also_after(void); +#pragma omp end declare variant +#pragma omp begin declare variant match(implementation={vendor(score(0):llvm)}) +int also_before(void); +#pragma omp end declare variant + +int also_after(void) { + return 0; +} + +int test() { + // Should return 0. + return also_after() + also_before(); +} + +// Make sure: +// - we do see the ast nodes for the cpu kind +// - we do see the ast nodes for the llvm vendor +// - we pick the right callees + +// CHECK: |-FunctionDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_1:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_2:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_3:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: |-FunctionDecl [[ADDR_4:0x[a-z0-9]*]] prev [[ADDR_0]] col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_5:0x[a-z0-9]*]] col:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_6:0x[a-z0-9]*]] prev [[ADDR_4]] col:5 used also_before 'int ({{.*}})' +// CHECK-NEXT: |-FunctionDecl [[ADDR_7:0x[a-z0-9]*]] prev [[ADDR_5]] line:19:5 used also_after 'int ({{.*}})' +// CHECK-NEXT: | `-CompoundStmt [[ADDR_8:0x[a-z0-9]*]] +// CHECK-NEXT: | `-ReturnStmt [[ADDR_9:0x[a-z0-9]*]] +// CHECK-NEXT: | `-IntegerLiteral [[ADDR_10:0x[a-z0-9]*]] 'int' 0 +// CHECK-NEXT: `-FunctionDecl [[ADDR_11:0x[a-z0-9]*]] line:23:5 test 'int ({{.*}})' +// CHECK-NEXT: `-CompoundStmt [[ADDR_12:0x[a-z0-9]*]] +// CHECK-NEXT: `-ReturnStmt [[ADDR_13:0x[a-z0-9]*]] +// CHECK-NEXT: `-BinaryOperator [[ADDR_14:0x[a-z0-9]*]] 'int' '+' +// CHECK-NEXT: |-CallExpr [[ADDR_15:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: | `-ImplicitCastExpr [[ADDR_16:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: | `-DeclRefExpr [[ADDR_17:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_7]] 'also_after' 'int ({{.*}})' +// CHECK-NEXT: `-CallExpr [[ADDR_18:0x[a-z0-9]*]] 'int' +// CHECK-NEXT: `-ImplicitCastExpr [[ADDR_19:0x[a-z0-9]*]] 'int (*)({{.*}})' +// CHECK-NEXT: `-DeclRefExpr [[ADDR_20:0x[a-z0-9]*]] 'int ({{.*}})' {{.*}}Function [[ADDR_6]] 'also_before' 'int ({{.*}})' diff --git a/clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c b/clang/test/OpenMP/begin_declare_variant_elided_range_withouth_end.c rename from clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c rename to clang/test/OpenMP/begin_declare_variant_elided_range_withouth_end.c --- a/clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c +++ b/clang/test/OpenMP/begin_declare_variant_elided_range_withouth_end.c @@ -1,21 +1,19 @@ // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c -std=c99 -fms-extensions -Wno-pragma-pack %s // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -x c -std=c99 -fms-extensions -Wno-pragma-pack %s -#pragma omp begin declare variant match(device={kind(cpu)}) +#pragma omp begin declare variant match(device={kind(gpu)}) // expected-note {{to match this '#pragma omp begin declare variant'}} int also_before(void) { return 0; } -#pragma omp end declare variant -#pragma omp begin declare variant match(device={kind(gpu)}) // expected-note {{to match this '#pragma omp begin declare variant'}} -// The matching end is missing. Since the device clause is not matching we will -// cause us to elide the rest of the file and emit and error. +#pragma omp begin declare variant match(device={kind(gpu)}) int also_after(void) { return 2; } int also_before(void) { return 2; } +#pragma omp end declare variant #pragma omp begin declare variant match(device={kind(fpga)}) diff --git a/clang/test/OpenMP/begin_declare_variant_messages.c b/clang/test/OpenMP/begin_declare_variant_messages.c --- a/clang/test/OpenMP/begin_declare_variant_messages.c +++ b/clang/test/OpenMP/begin_declare_variant_messages.c @@ -4,20 +4,20 @@ #pragma omp begin // expected-error {{expected an OpenMP directive}} -#pragma omp end declare variant +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} #pragma omp begin declare // expected-error {{expected an OpenMP directive}} -#pragma omp end declare variant +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} #pragma omp begin variant // expected-error {{expected an OpenMP directive}} -#pragma omp end declare variant +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} #pragma omp variant begin // expected-error {{expected an OpenMP directive}} #pragma omp declare variant end // expected-error {{function declaration is expected after 'declare variant' directive}} #pragma omp begin declare variant // expected-error {{expected 'match' clause on 'omp declare variant' directive}} #pragma omp end declare variant // TODO: Issue an error message -#pragma omp end declare variant -#pragma omp end declare variant -#pragma omp end declare variant -#pragma omp end declare variant +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} +#pragma omp end declare variant // expected-error {{expected '#pragma omp begin declare variant' to match this stray `#pragma omp end delcare variant`}} int foo(void); const int var; diff --git a/clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c b/clang/test/OpenMP/begin_declare_variant_no_end_for_matching_selector.c copy from clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c copy to clang/test/OpenMP/begin_declare_variant_no_end_for_matching_selector.c diff --git a/clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c b/clang/test/OpenMP/begin_declare_variant_range_withouth_end.c rename from clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c rename to clang/test/OpenMP/begin_declare_variant_range_withouth_end.c --- a/clang/test/OpenMP/begin-declare-variant_no_end_for_matching_selector.c +++ b/clang/test/OpenMP/begin_declare_variant_range_withouth_end.c @@ -1,21 +1,21 @@ // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c -std=c99 -fms-extensions -Wno-pragma-pack %s // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -x c -std=c99 -fms-extensions -Wno-pragma-pack %s +// TODO: Issue an eror message as the end is missing +// expected-no-diagnostics #pragma omp begin declare variant match(device={kind(cpu)}) int also_before(void) { return 0; } -#pragma omp end declare variant -#pragma omp begin declare variant match(device={kind(gpu)}) // expected-note {{to match this '#pragma omp begin declare variant'}} -// The matching end is missing. Since the device clause is not matching we will -// cause us to elide the rest of the file and emit and error. +#pragma omp begin declare variant match(device={kind(gpu)}) int also_after(void) { return 2; } int also_before(void) { return 2; } +#pragma omp end declare variant #pragma omp begin declare variant match(device={kind(fpga)}) @@ -30,4 +30,4 @@ int test() { return also_after() + also_before(); -} // expected-error {{expected '#pragma omp end declare variant'}} +} diff --git a/clang/test/OpenMP/begin_declare_variant_using_messages.cpp b/clang/test/OpenMP/begin_declare_variant_using_messages.cpp new file mode 100644 --- /dev/null +++ b/clang/test/OpenMP/begin_declare_variant_using_messages.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fopenmp -verify %s + +namespace BEFORE_AND_1 { +void before_and_1(); +} +namespace AFTER_AND_2 { +void after_and_2(); // expected-note {{'AFTER_AND_2::after_and_2' declared here}} expected-note {{'AFTER_AND_2::after_and_2' declared here}} +} +namespace ONLY_1 { +void only_1(); // expected-note {{'ONLY_1::only_1' declared here}} +} +namespace BEFORE_1_AND_2 { +void before_1_and_2(); +} + +using BEFORE_1_AND_2::before_1_and_2; +using BEFORE_AND_1::before_and_1; + +void test_before() { + before_and_1(); + after_and_2(); // expected-error {{use of undeclared identifier 'after_and_2'; did you mean 'AFTER_AND_2::after_and_2'?}} + only_1(); // expected-error {{use of undeclared identifier 'only_1'; did you mean 'ONLY_1::only_1'?}} + before_1_and_2(); +} + +#pragma omp begin declare variant match(implementation = {vendor(llvm)}) +using BEFORE_1_AND_2::before_1_and_2; +using BEFORE_AND_1::before_and_1; +using ONLY_1::only_1; +void test_1() { + before_and_1(); + after_and_2(); // expected-error {{use of undeclared identifier 'after_and_2'; did you mean 'AFTER_AND_2::after_and_2'?}} + only_1(); + before_1_and_2(); +} +#pragma omp end declare variant + +#pragma omp begin declare variant match(implementation = {vendor(llvm)}) +using AFTER_AND_2::after_and_2; +using BEFORE_1_AND_2::before_1_and_2; +void test_2() { + before_and_1(); + after_and_2(); + only_1(); + before_1_and_2(); +} +#pragma omp end declare variant + +void test_after() { + before_and_1(); + after_and_2(); + only_1(); + before_1_and_2(); +} + +using AFTER_AND_2::after_and_2; + +// Make sure: +// - we do not see the ast nodes for the gpu kind +// - we do not choke on the text in the kind(fpga) guarded scopes +// - we pick the right cbefore_1_and_2ees diff --git a/clang/test/OpenMP/declare_variant_ast_print.cpp b/clang/test/OpenMP/declare_variant_ast_print.cpp --- a/clang/test/OpenMP/declare_variant_ast_print.cpp +++ b/clang/test/OpenMP/declare_variant_ast_print.cpp @@ -64,8 +64,7 @@ // CHECK-NEXT: } // CHECK-NEXT: template<> void h_ref(double *hp, double *hp2, double *hq, double *lin) { // CHECK-NEXT: } -// CHECK-NEXT: template<> void h_ref(float *hp, float *hp2, float *hq, float *lin) { -// CHECK-NEXT: } +// CHECK-NEXT: template<> void h_ref(float *hp, float *hp2, float *hq, float *lin) template void h_ref(C *hp, C *hp2, C *hq, C *lin) { } diff --git a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp --- a/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp +++ b/clang/test/OpenMP/declare_variant_device_kind_codegen.cpp @@ -40,20 +40,11 @@ // expected-no-diagnostics +// CHECK-NOT: alias + // CHECK-NOT: ret i32 {{1|4|81|84}} -// CHECK-DAG: @_Z3barv = {{.*}}alias i32 (), i32 ()* @_Z3foov -// CHECK-DAG: @_ZN16SpecSpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev -// CHECK-DAG: @_ZN16SpecSpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev -// CHECK-DAG: @_ZN12SpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev -// CHECK-DAG: @_Z5prio_v = {{.*}}alias i32 (), i32 ()* @_Z5prio1v -// CHECK-DAG: @_ZL6prio1_v = internal alias i32 (), i32 ()* @_ZL5prio2v -// CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv -// CHECK-DAG: @_ZL9stat_usedv = internal alias i32 (), i32 ()* @_ZL10stat_used_v -// CHECK-DAG: @_ZN12SpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev -// CHECK-DAG: @fn_linkage = {{.*}}alias i32 (), i32 ()* @_Z18fn_linkage_variantv -// CHECK-DAG: @_Z11fn_linkage1v = {{.*}}alias i32 (), i32 ()* @fn_linkage_variant1 // CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv() -// CHECK-DAG: declare {{.*}}i32 @_Z3bazv() +// CHECK-DAG: define {{.*}}i32 @_Z3bazv() // CHECK-DAG: ret i32 2 // CHECK-DAG: ret i32 3 // CHECK-DAG: ret i32 5 @@ -64,7 +55,7 @@ // CHECK-DAG: ret i32 85 // CHECK-DAG: ret i32 86 // CHECK-DAG: ret i32 87 -// CHECK-NOT: ret i32 {{1|4|81|84}} +// CHECK-NOT: ret i32 {{4|81|84}} #ifndef HEADER #define HEADER diff --git a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp --- a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp +++ b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp @@ -1,33 +1,23 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple %itanium_abi_triple -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|19|21|22|23|24}}' // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple %itanium_abi_triple -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|19|21|22|23|24}}' // expected-no-diagnostics -// CHECK-NOT: ret i32 {{1|4|81|84}} -// CHECK-DAG: @_Z3barv = {{.*}}alias i32 (), i32 ()* @_Z3foov -// CHECK-DAG: @_ZN16SpecSpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev -// CHECK-DAG: @_ZN16SpecSpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev -// CHECK-DAG: @_ZN12SpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev -// CHECK-DAG: @_Z5prio_v = {{.*}}alias i32 (), i32 ()* @_Z5prio1v -// CHECK-DAG: @_ZL6prio1_v = internal alias i32 (), i32 ()* @_ZL5prio2v -// CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv -// CHECK-DAG: @_ZL9stat_usedv = internal alias i32 (), i32 ()* @_ZL10stat_used_v -// CHECK-DAG: @_ZN12SpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev -// CHECK-DAG: @fn_linkage = {{.*}}alias i32 (), i32 ()* @_Z18fn_linkage_variantv -// CHECK-DAG: @_Z11fn_linkage1v = {{.*}}alias i32 (), i32 ()* @fn_linkage_variant1 -// CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv() -// CHECK-DAG: declare {{.*}}i32 @_Z3bazv() -// CHECK-DAG: ret i32 2 -// CHECK-DAG: ret i32 3 -// CHECK-DAG: ret i32 5 -// CHECK-DAG: ret i32 6 -// CHECK-DAG: ret i32 7 -// CHECK-DAG: ret i32 82 -// CHECK-DAG: ret i32 83 -// CHECK-DAG: ret i32 85 -// CHECK-DAG: ret i32 86 -// CHECK-DAG: ret i32 87 -// CHECK-NOT: ret i32 {{1|4|81|84}} +// CHECK-DAG: ret i32 2 +// CHECK-DAG: ret i32 3 +// CHECK-DAG: ret i32 4 +// CHECK-DAG: ret i32 5 +// CHECK-DAG: ret i32 11 +// CHECK-DAG: ret i32 16 +// CHECK-DAG: ret i32 17 +// CHECK-DAG: ret i32 18 +// CHECK-DAG: ret i32 19 +// CHECK-DAG: ret i32 20 +// CHECK-DAG: ret i32 25 +// CHECK-DAG: ret i32 26 +// CHECK-DAG: ret i32 27 +// CHECK-DAG: ret i32 28 +// CHECK-DAG: ret i32 29 #ifndef HEADER #define HEADER @@ -35,45 +25,45 @@ int foo() { return 2; } #pragma omp declare variant(foo) match(implementation = {vendor(llvm)}) -int bar() { return 1; } +int bar() { return 3; } int bazzz(); #pragma omp declare variant(bazzz) match(implementation = {vendor(llvm)}) -int baz() { return 1; } +int baz() { return 4; } int test(); #pragma omp declare variant(test) match(implementation = {vendor(llvm)}) -int call() { return 1; } +int call() { return 5; } static int stat_unused_(); #pragma omp declare variant(stat_unused_) match(implementation = {vendor(llvm)}) -static int stat_unused() { return 1; } +static int stat_unused() { return 6; } static int stat_used_(); #pragma omp declare variant(stat_used_) match(implementation = {vendor(llvm)}) -static int stat_used() { return 1; } +static int stat_used() { return 7; } int main() { return bar() + baz() + call() + stat_used(); } -int test() { return 3; } -static int stat_unused_() { return 4; } -static int stat_used_() { return 5; } +int test() { return 8; } +static int stat_unused_() { return 9; } +static int stat_used_() { return 10; } struct SpecialFuncs { void vd() {} SpecialFuncs(); ~SpecialFuncs(); - int method_() { return 6; } + int method_() { return 11; } #pragma omp declare variant(SpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) - int method() { return 1; } + int method() { return 12; } #pragma omp declare variant(SpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) int Method(); } s; -int SpecialFuncs::Method() { return 1; } +int SpecialFuncs::Method() { return 13; } struct SpecSpecialFuncs { void vd() {} @@ -83,50 +73,50 @@ int method_(); #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) - int method() { return 1; } + int method() { return 14; } #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) int Method(); } s1; -int SpecSpecialFuncs::method_() { return 7; } -int SpecSpecialFuncs::Method() { return 1; } +int SpecSpecialFuncs::method_() { return 15; } +int SpecSpecialFuncs::Method() { return 16; } void xxx() { (void)s.method(); (void)s1.method(); } -int prio() { return 81; } -int prio1() { return 82; } +int prio() { return 17; } +int prio1() { return 18; } #pragma omp declare variant(prio) match(implementation = {vendor(llvm)}) #pragma omp declare variant(prio1) match(implementation = {vendor(score(1): llvm)}) -int prio_() { return 1; } +int prio_() { return 19; } -static int prio2() { return 83; } -static int prio3() { return 84; } -static int prio4() { return 84; } +static int prio2() { return 20; } +static int prio3() { return 21; } +static int prio4() { return 22; } #pragma omp declare variant(prio4) match(implementation = {vendor(score(3): llvm)}) #pragma omp declare variant(prio2) match(implementation = {vendor(score(5): llvm)}) #pragma omp declare variant(prio3) match(implementation = {vendor(score(1): llvm)}) -static int prio1_() { return 1; } +static int prio1_() { return 23; } int int_fn() { return prio1_(); } -int fn_linkage_variant() { return 85; } +int fn_linkage_variant() { return 24; } extern "C" { #pragma omp declare variant(fn_linkage_variant) match(implementation = {vendor(llvm)}) -int fn_linkage() { return 1; } +int fn_linkage() { return 25; } } -extern "C" int fn_linkage_variant1() { return 86; } +extern "C" int fn_linkage_variant1() { return 26; } #pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(llvm)}) -int fn_linkage1() { return 1; } +int fn_linkage1() { return 27; } -int fn_variant2() { return 1; } +int fn_variant2() { return 28; } #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm, ibm)}) -int fn2() { return 87; } +int fn2() { return 29; } #endif // HEADER diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -78,8 +78,8 @@ -#pragma omp declare variant(foo) match(xxx={}) // expected-error {{function declaration is expected after 'declare variant' directive}} -#pragma omp declare variant(foo) match(xxx={}) // expected-error {{function declaration is expected after 'declare variant' directive}} +#pragma omp declare variant(foo) match(implementation={vendor(llvm)}) // expected-error {{function declaration is expected after 'declare variant' directive}} +#pragma omp declare variant(foo) match(implementation={vendor(llvm)}) // expected-error {{function declaration is expected after 'declare variant' directive}} #pragma init_seg(compiler) int main(); diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp --- a/clang/test/OpenMP/declare_variant_messages.cpp +++ b/clang/test/OpenMP/declare_variant_messages.cpp @@ -130,10 +130,16 @@ template int score_and_cond_const_inst(); +__attribute__((pure)) int pure() { return 0; } + +#pragma omp declare variant(pure) match(user = {condition(1)}) // expected-warning {{ignoring return value of function declared with pure attribute}} +int unused_warning_after_specialization() { return foo(); } + void score_and_cond_inst() { score_and_cond_non_const(); score_and_cond_non_const_inst<8>(); // expected-note {{in instantiation of function template specialization 'score_and_cond_non_const_inst<8>' requested here}} score_and_cond_const_inst<9>(); + unused_warning_after_specialization(); } #pragma omp declare variant(barbar ) match(implementation = {}) // expected-warning {{expected identifier or string literal describing a context selector; selector skipped}} expected-note {{context selector options are: 'vendor' 'extension' 'unified_address' 'unified_shared_memory' 'reverse_offload' 'dynamic_allocators' 'atomic_default_mem_order'}} expected-note {{the ignored selector spans until here}} diff --git a/clang/test/OpenMP/declare_variant_mixed_codegen.c b/clang/test/OpenMP/declare_variant_mixed_codegen.c --- a/clang/test/OpenMP/declare_variant_mixed_codegen.c +++ b/clang/test/OpenMP/declare_variant_mixed_codegen.c @@ -7,7 +7,6 @@ // RUN: %clang_cc1 -verify -fopenmp -x c -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 | FileCheck %s --check-prefix GPU // expected-no-diagnostics -// HOST: @base = alias i32 (double), i32 (double)* @hst #ifndef HEADER #define HEADER @@ -20,9 +19,9 @@ int base(); // HOST-LABEL: define void @foo() -// HOST: call i32 (double, ...) bitcast (i32 (double)* @base to i32 (double, ...)*)(double -1.000000e+00) +// HOST: call i32 @hst(double -1.000000e+00) // HOST: call i32 @hst(double -2.000000e+00) -// HOST: call void [[OFFL:@.+_foo_l29]]() +// HOST: call void [[OFFL:@.+_foo_l28]]() void foo() { base(-1); hst(-2); @@ -34,15 +33,14 @@ } // HOST: define {{.*}}void [[OFFL]]() -// HOST: call i32 (double, ...) bitcast (i32 (double)* @base to i32 (double, ...)*)(double -3.000000e+00) +// HOST: call i32 @hst(double -3.000000e+00) // HOST: call i32 @dev(double -4.000000e+00) -// GPU: define {{.*}}void @__omp_offloading_{{.+}}_foo_l29() -// GPU: call i32 @base(double -3.000000e+00) +// GPU: define {{.*}}void @__omp_offloading_{{.+}}_foo_l28() +// GPU: call i32 @dev(double -3.000000e+00) // GPU: call i32 @dev(double -4.000000e+00) -// GPU: define {{.*}}i32 @base(double -// GPU: ret i32 0 +// GPU-NOT: @base // GPU: define {{.*}}i32 @dev(double // GPU: ret i32 0 diff --git a/clang/test/OpenMP/declare_variant_mixed_codegen.cpp b/clang/test/OpenMP/declare_variant_mixed_codegen.cpp --- a/clang/test/OpenMP/declare_variant_mixed_codegen.cpp +++ b/clang/test/OpenMP/declare_variant_mixed_codegen.cpp @@ -1,34 +1,30 @@ -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-linux -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fsanitize-address-use-after-scope | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|10|13|15|19|22|23|24}}' // RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -emit-pch -o %t -fopenmp-version=50 %s -// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s +// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-linux -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|10|13|15|19|22|23|24}}' + // expected-no-diagnostics -// CHECK-NOT: ret i32 {{1|4|81|84}} -// CHECK-DAG: @_Z3barv = {{.*}}alias i32 (), i32 ()* @_Z3foov -// CHECK-DAG: @_ZN16SpecSpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev -// CHECK-DAG: @_ZN16SpecSpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecSpecialFuncs*), i32 (%struct.SpecSpecialFuncs*)* @_ZN16SpecSpecialFuncs7method_Ev -// CHECK-DAG: @_ZN12SpecialFuncs6methodEv = linkonce_odr {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev -// CHECK-DAG: @_Z5prio_v = {{.*}}alias i32 (), i32 ()* @_Z5prio1v -// CHECK-DAG: @_ZL6prio1_v = internal alias i32 (), i32 ()* @_ZL5prio2v -// CHECK-DAG: @_Z4callv = {{.*}}alias i32 (), i32 ()* @_Z4testv -// CHECK-DAG: @_ZL9stat_usedv = internal alias i32 (), i32 ()* @_ZL10stat_used_v -// CHECK-DAG: @_ZN12SpecialFuncs6MethodEv = {{.*}}alias i32 (%struct.SpecialFuncs*), i32 (%struct.SpecialFuncs*)* @_ZN12SpecialFuncs7method_Ev -// CHECK-DAG: @fn_linkage = {{.*}}alias i32 (), i32 ()* @_Z18fn_linkage_variantv -// CHECK-DAG: @_Z11fn_linkage1v = {{.*}}alias i32 (), i32 ()* @fn_linkage_variant1 -// CHECK-DAG: declare {{.*}}i32 @_Z5bazzzv() -// CHECK-DAG: declare {{.*}}i32 @_Z3bazv() -// CHECK-DAG: ret i32 2 -// CHECK-DAG: ret i32 3 -// CHECK-DAG: ret i32 5 -// CHECK-DAG: ret i32 6 -// CHECK-DAG: ret i32 7 -// CHECK-DAG: ret i32 82 -// CHECK-DAG: ret i32 83 -// CHECK-DAG: ret i32 85 -// CHECK-DAG: ret i32 86 -// CHECK-DAG: ret i32 87 -// CHECK-DAG: ret i32 88 -// CHECK-NOT: ret i32 {{1|4|81|84}} +// CHECK-DAG: ret i32 2 +// CHECK-DAG: ret i32 3 +// CHECK-DAG: ret i32 4 +// CHECK-DAG: ret i32 5 +// CHECK-DAG: ret i32 9 +// CHECK-DAG: ret i32 11 +// CHECK-DAG: ret i32 12 +// CHECK-DAG: ret i32 14 +// CHECK-DAG: ret i32 16 +// CHECK-DAG: ret i32 17 +// CHECK-DAG: ret i32 18 +// CHECK-DAG: ret i32 19 +// CHECK-DAG: ret i32 20 +// CHECK-DAG: ret i32 21 +// CHECK-DAG: ret i32 25 +// CHECK-DAG: ret i32 26 +// CHECK-DAG: ret i32 27 +// CHECK-DAG: ret i32 28 +// CHECK-DAG: ret i32 29 +// CHECK-DAG: ret i32 30 +// CHECK-DAG: ret i32 31 #ifndef HEADER #define HEADER @@ -36,47 +32,47 @@ int foo() { return 2; } #pragma omp declare variant(foo) match(implementation = {vendor(llvm)}, device={kind(cpu)}) -int bar() { return 1; } +int bar() { return 3; } int bazzz(); #pragma omp declare variant(bazzz) match(implementation = {vendor(llvm)}, device={kind(host)}) -int baz() { return 1; } +int baz() { return 4; } int test(); #pragma omp declare variant(test) match(implementation = {vendor(llvm)}, device={kind(cpu)}) -int call() { return 1; } +int call() { return 5; } -static int stat_unused_no_emit() { return 1; } +static int stat_unused_no_emit() { return 6; } static int stat_unused_(); #pragma omp declare variant(stat_unused_) match(implementation = {vendor(llvm)}, device={kind(cpu)}) #pragma omp declare variant(stat_unused_no_emit) match(implementation = {vendor(unknown)}, device = {kind(gpu)}) -static int stat_unused() { return 1; } +static int stat_unused() { return 7; } static int stat_used_(); #pragma omp declare variant(stat_used_) match(implementation = {vendor(llvm)}, device={kind(host)}) -static int stat_used() { return 1; } +static int stat_used() { return 8; } int main() { return bar() + baz() + call() + stat_used(); } -int test() { return 3; } -static int stat_unused_() { return 4; } -static int stat_used_() { return 5; } +int test() { return 9; } +static int stat_unused_() { return 10; } +static int stat_used_() { return 11; } struct SpecialFuncs { void vd() {} SpecialFuncs(); ~SpecialFuncs(); - int method_() { return 6; } + int method_() { return 12; } #pragma omp declare variant(SpecialFuncs::method_) \ match(implementation = {vendor(llvm)}, device={kind(cpu)}) - int method() { return 1; } + int method() { return 13; } #pragma omp declare variant(SpecialFuncs::method_) \ match(implementation = {vendor(llvm)}, device={kind(host)}) int Method(); } s; -int SpecialFuncs::Method() { return 1; } +int SpecialFuncs::Method() { return 14; } struct SpecSpecialFuncs { void vd() {} @@ -86,60 +82,60 @@ int method_(); #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(implementation = {vendor(llvm)}, device={kind(cpu)}) - int method() { return 1; } + int method() { return 15; } #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(implementation = {vendor(llvm)}, device={kind(host)}) int Method(); } s1; -int SpecSpecialFuncs::method_() { return 7; } -int SpecSpecialFuncs::Method() { return 1; } +int SpecSpecialFuncs::method_() { return 16; } +int SpecSpecialFuncs::Method() { return 17; } void xxx() { (void)s.method(); (void)s1.method(); } -int prio() { return 81; } -int prio1() { return 82; } +int prio() { return 18; } +int prio1() { return 19; } #pragma omp declare variant(prio1) match(implementation = {vendor(score(2): llvm)}, device={kind(cpu,host)}) #pragma omp declare variant(prio) match(implementation = {vendor(score(1): llvm)}, device={kind(cpu)}) -int prio_() { return 1; } +int prio_() { return 20; } -static int prio2() { return 83; } -static int prio3() { return 84; } -static int prio4() { return 84; } +static int prio2() { return 21; } +static int prio3() { return 22; } +static int prio4() { return 23; } #pragma omp declare variant(prio4) match(implementation = {vendor(score(5): llvm)}) #pragma omp declare variant(prio2) match(implementation = {vendor(score(8): llvm)}, device={kind(cpu,host)}) #pragma omp declare variant(prio3) match(implementation = {vendor(score(7): llvm)}, device={kind(cpu)}) -static int prio1_() { return 1; } +static int prio1_() { return 24; } int int_fn() { return prio1_(); } -int fn_linkage_variant() { return 85; } +int fn_linkage_variant() { return 25; } extern "C" { #pragma omp declare variant(fn_linkage_variant) match(implementation = {vendor(llvm)}, device={kind(cpu)}) -int fn_linkage() { return 1; } +int fn_linkage() { return 26; } } -extern "C" int fn_linkage_variant1() { return 86; } +extern "C" int fn_linkage_variant1() { return 27; } #pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(llvm)}, device={kind(host)}) -int fn_linkage1() { return 1; } +int fn_linkage1() { return 28; } -int fn_variant2() { return 1; } +int fn_variant2() { return 29; } #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm, ibm)}, device={kind(cpu)}) #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm)}, device={kind(cpu,gpu)}) #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm)}, device={kind(nohost)}) #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm)}, device={kind(cpu,nohost)}) #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm)}, device={kind(gpu)}) #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm)}, device={kind(fpga)}) -int fn2() { return 87; } +int fn2() { return 30; } #pragma omp declare variant(stat_unused_no_emit) match(implementation = {vendor(unknown)}, device = {kind(gpu)}) template -static T stat_unused_T() { return 88; } +static T stat_unused_T() { return 31; } int bazzzzzzzz() { return stat_unused_T(); diff --git a/clang/test/OpenMP/nvptx_declare_variant_device_kind_codegen.cpp b/clang/test/OpenMP/nvptx_declare_variant_device_kind_codegen.cpp --- a/clang/test/OpenMP/nvptx_declare_variant_device_kind_codegen.cpp +++ b/clang/test/OpenMP/nvptx_declare_variant_device_kind_codegen.cpp @@ -1,43 +1,28 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -fopenmp-version=50 -DGPU -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 -DGPU | FileCheck %s --implicit-check-not='ret i32 {{1|81|84}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 -DGPU | FileCheck %s --implicit-check-not='ret i32 {{6|7|9|10|12|14|17|18|20|21|22|23|24|26}}' // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t -fopenmp-version=50 -DGPU -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 -DGPU | FileCheck %s --implicit-check-not='ret i32 {{1|81|84}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 -DGPU | FileCheck %s --implicit-check-not='ret i32 {{6|7|9|10|12|14|17|18|20|21|22|23|24|26}}' // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -fopenmp-version=50 -DNOHOST -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 -DNOHOST | FileCheck %s --implicit-check-not='ret i32 {{1|81|84}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 -DNOHOST | FileCheck %s --implicit-check-not='ret i32 {{6|7|9|10|12|14|17|18|20|21|22|23|24|26}}' // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t -fopenmp-version=50 -DNOHOST -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 -DNOHOST | FileCheck %s --implicit-check-not='ret i32 {{1|81|84}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 -DNOHOST | FileCheck %s --implicit-check-not='ret i32 {{6|7|9|10|12|14|17|18|20|21|22|23|24|26}}' // expected-no-diagnostics -// CHECK-NOT: ret i32 {{1|81|84}} -// CHECK-DAG: define {{.*}}i32 @_Z3barv() -// CHECK-DAG: define {{.*}}i32 @_ZN16SpecSpecialFuncs6MethodEv(%struct.SpecSpecialFuncs* %{{.+}}) -// CHECK-DAG: define {{.*}}i32 @_ZN12SpecialFuncs6MethodEv(%struct.SpecialFuncs* %{{.+}}) -// CHECK-DAG: define linkonce_odr {{.*}}i32 @_ZN16SpecSpecialFuncs6methodEv(%struct.SpecSpecialFuncs* %{{.+}}) -// CHECK-DAG: define linkonce_odr {{.*}}i32 @_ZN12SpecialFuncs6methodEv(%struct.SpecialFuncs* %{{.+}}) -// CHECK-DAG: define {{.*}}i32 @_Z5prio_v() -// CHECK-DAG: define internal i32 @_ZL6prio1_v() -// CHECK-DAG: define {{.*}}i32 @_Z4callv() -// CHECK-DAG: define internal i32 @_ZL9stat_usedv() -// CHECK-DAG: define {{.*}}i32 @fn_linkage() -// CHECK-DAG: define {{.*}}i32 @_Z11fn_linkage1v() - // CHECK-DAG: ret i32 2 // CHECK-DAG: ret i32 3 // CHECK-DAG: ret i32 4 // CHECK-DAG: ret i32 5 -// CHECK-DAG: ret i32 6 -// CHECK-DAG: ret i32 7 -// CHECK-DAG: ret i32 82 -// CHECK-DAG: ret i32 83 -// CHECK-DAG: ret i32 85 -// CHECK-DAG: ret i32 86 -// CHECK-DAG: ret i32 87 - -// Outputs for function members -// CHECK-DAG: ret i32 6 -// CHECK-DAG: ret i32 7 -// CHECK-NOT: ret i32 {{1|81|84}} +// CHECK-DAG: ret i32 8 +// CHECK-DAG: ret i32 11 +// CHECK-DAG: ret i32 13 +// CHECK-DAG: ret i32 15 +// CHECK-DAG: ret i32 16 +// CHECK-DAG: ret i32 19 +// CHECK-DAG: ret i32 25 + +// Outputs for function members checked via implicit filecheck flag + #ifndef HEADER #define HEADER @@ -62,19 +47,19 @@ #pragma omp declare target #pragma omp declare variant(foo) match(device = {kind(CORRECT)}) -int bar() { return 1; } +int bar() { return 3; } #pragma omp declare variant(bazzz) match(device = {kind(CORRECT)}) -int baz() { return 1; } +int baz() { return 4; } #pragma omp declare variant(test) match(device = {kind(CORRECT)}) -int call() { return 1; } +int call() { return 5; } #pragma omp declare variant(stat_unused_) match(device = {kind(CORRECT)}) -static int stat_unused() { return 1; } +static int stat_unused() { return 6; } #pragma omp declare variant(stat_used_) match(device = {kind(CORRECT)}) -static int stat_used() { return 1; } +static int stat_used() { return 7; } #pragma omp end declare target @@ -86,9 +71,9 @@ return res; } -int test() { return 3; } -static int stat_unused_() { return 4; } -static int stat_used_() { return 5; } +int test() { return 8; } +static int stat_unused_() { return 9; } +static int stat_used_() { return 10; } #pragma omp declare target @@ -96,17 +81,16 @@ void vd() {} SpecialFuncs(); ~SpecialFuncs(); - - int method_() { return 6; } + int method_() { return 11; } #pragma omp declare variant(SpecialFuncs::method_) \ match(device = {kind(CORRECT)}) - int method() { return 1; } + int method() { return 12; } #pragma omp declare variant(SpecialFuncs::method_) \ match(device = {kind(CORRECT)}) int Method(); } s; -int SpecialFuncs::Method() { return 1; } +int SpecialFuncs::Method() { return 13; } struct SpecSpecialFuncs { void vd() {} @@ -116,7 +100,7 @@ int method_(); #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(device = {kind(CORRECT)}) - int method() { return 1; } + int method() { return 14; } #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(device = {kind(CORRECT)}) int Method(); @@ -124,17 +108,17 @@ #pragma omp end declare target -int SpecSpecialFuncs::method_() { return 7; } -int SpecSpecialFuncs::Method() { return 1; } +int SpecSpecialFuncs::method_() { return 15; } +int SpecSpecialFuncs::Method() { return 16; } -int prio() { return 81; } -int prio1() { return 82; } -static int prio2() { return 83; } -static int prio3() { return 84; } -static int prio4() { return 84; } -int fn_linkage_variant() { return 85; } -extern "C" int fn_linkage_variant1() { return 86; } -int fn_variant2() { return 1; } +int prio() { return 17; } +int prio1() { return 18; } +static int prio2() { return 19; } +static int prio3() { return 20; } +static int prio4() { return 21; } +int fn_linkage_variant() { return 22; } +extern "C" int fn_linkage_variant1() { return 23; } +int fn_variant2() { return 24; } #pragma omp declare target @@ -145,25 +129,25 @@ #pragma omp declare variant(prio) match(device = {kind(SUBSET)}) #pragma omp declare variant(prio1) match(device = {kind(CORRECT)}) -int prio_() { return 1; } +int prio_() { return 25; } #pragma omp declare variant(prio4) match(device = {kind(SUBSET)}) #pragma omp declare variant(prio2) match(device = {kind(CORRECT)}) #pragma omp declare variant(prio3) match(device = {kind(SUBSET)}) -static int prio1_() { return 1; } +static int prio1_() { return 26; } int int_fn() { return prio1_(); } extern "C" { #pragma omp declare variant(fn_linkage_variant) match(device = {kind(CORRECT)}) -int fn_linkage() { return 1; } +int fn_linkage() { return 27; } } #pragma omp declare variant(fn_linkage_variant1) match(device = {kind(CORRECT)}) -int fn_linkage1() { return 1; } +int fn_linkage1() { return 28; } #pragma omp declare variant(fn_variant2) match(device = {kind(WRONG)}) -int fn2() { return 87; } +int fn2() { return 29; } #pragma omp end declare target diff --git a/clang/test/OpenMP/nvptx_declare_variant_implementation_vendor_codegen.cpp b/clang/test/OpenMP/nvptx_declare_variant_implementation_vendor_codegen.cpp --- a/clang/test/OpenMP/nvptx_declare_variant_implementation_vendor_codegen.cpp +++ b/clang/test/OpenMP/nvptx_declare_variant_implementation_vendor_codegen.cpp @@ -1,38 +1,20 @@ // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc -fopenmp-version=50 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{1|81|84}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|17|18|19|20|21|22|23|24|26}}' // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -emit-pch -o %t -fopenmp-version=50 -// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{1|81|84}}' +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -aux-triple powerpc64le-unknown-unknown -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -include-pch %t -o - -fopenmp-version=50 | FileCheck %s --implicit-check-not='ret i32 {{6|7|8|9|10|12|13|14|15|17|18|19|20|21|22|23|24|26}}' // expected-no-diagnostics -// CHECK-NOT: ret i32 {{1|81|84}} -// CHECK-DAG: define {{.*}}i32 @_Z3barv() -// CHECK-DAG: define {{.*}}i32 @_ZN16SpecSpecialFuncs6MethodEv(%struct.SpecSpecialFuncs* %{{.+}}) -// CHECK-DAG: define {{.*}}i32 @_ZN12SpecialFuncs6MethodEv(%struct.SpecialFuncs* %{{.+}}) -// CHECK-DAG: define linkonce_odr {{.*}}i32 @_ZN16SpecSpecialFuncs6methodEv(%struct.SpecSpecialFuncs* %{{.+}}) -// CHECK-DAG: define linkonce_odr {{.*}}i32 @_ZN12SpecialFuncs6methodEv(%struct.SpecialFuncs* %{{.+}}) -// CHECK-DAG: define {{.*}}i32 @_Z5prio_v() -// CHECK-DAG: define internal i32 @_ZL6prio1_v() -// CHECK-DAG: define {{.*}}i32 @_Z4callv() -// CHECK-DAG: define internal i32 @_ZL9stat_usedv() -// CHECK-DAG: define {{.*}}i32 @fn_linkage() -// CHECK-DAG: define {{.*}}i32 @_Z11fn_linkage1v() - -// CHECK-DAG: ret i32 2 -// CHECK-DAG: ret i32 3 -// CHECK-DAG: ret i32 4 -// CHECK-DAG: ret i32 5 -// CHECK-DAG: ret i32 6 -// CHECK-DAG: ret i32 7 -// CHECK-DAG: ret i32 82 -// CHECK-DAG: ret i32 83 -// CHECK-DAG: ret i32 85 -// CHECK-DAG: ret i32 86 -// CHECK-DAG: ret i32 87 - -// Outputs for function members -// CHECK-DAG: ret i32 6 -// CHECK-DAG: ret i32 7 -// CHECK-NOT: ret i32 {{1|81|84}} +// CHECK-DAG: ret i32 2 +// CHECK-DAG: ret i32 3 +// CHECK-DAG: ret i32 4 +// CHECK-DAG: ret i32 5 +// CHECK-DAG: ret i32 11 +// CHECK-DAG: ret i32 16 +// CHECK-DAG: ret i32 19 +// CHECK-DAG: ret i32 25 +// CHECK-DAG: ret i32 27 +// CHECK-DAG: ret i32 28 +// CHECK-DAG: ret i32 29 #ifndef HEADER #define HEADER @@ -46,19 +28,19 @@ #pragma omp declare target #pragma omp declare variant(foo) match(implementation = {vendor(llvm)}) -int bar() { return 1; } +int bar() { return 3; } #pragma omp declare variant(bazzz) match(implementation = {vendor(llvm)}) -int baz() { return 1; } +int baz() { return 4; } #pragma omp declare variant(test) match(implementation = {vendor(llvm)}) -int call() { return 1; } +int call() { return 5; } #pragma omp declare variant(stat_unused_) match(implementation = {vendor(llvm)}) -static int stat_unused() { return 1; } +static int stat_unused() { return 6; } #pragma omp declare variant(stat_used_) match(implementation = {vendor(llvm)}) -static int stat_used() { return 1; } +static int stat_used() { return 7; } #pragma omp end declare target @@ -70,9 +52,9 @@ return res; } -int test() { return 3; } -static int stat_unused_() { return 4; } -static int stat_used_() { return 5; } +int test() { return 8; } +static int stat_unused_() { return 9; } +static int stat_used_() { return 10; } #pragma omp declare target @@ -81,16 +63,16 @@ SpecialFuncs(); ~SpecialFuncs(); - int method_() { return 6; } + int method_() { return 11; } #pragma omp declare variant(SpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) - int method() { return 1; } + int method() { return 12; } #pragma omp declare variant(SpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) int Method(); } s; -int SpecialFuncs::Method() { return 1; } +int SpecialFuncs::Method() { return 13; } struct SpecSpecialFuncs { void vd() {} @@ -100,7 +82,7 @@ int method_(); #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) - int method() { return 1; } + int method() { return 14; } #pragma omp declare variant(SpecSpecialFuncs::method_) \ match(implementation = {vendor(llvm)}) int Method(); @@ -108,17 +90,17 @@ #pragma omp end declare target -int SpecSpecialFuncs::method_() { return 7; } -int SpecSpecialFuncs::Method() { return 1; } +int SpecSpecialFuncs::method_() { return 15; } +int SpecSpecialFuncs::Method() { return 16; } -int prio() { return 81; } -int prio1() { return 82; } -static int prio2() { return 83; } -static int prio3() { return 84; } -static int prio4() { return 84; } -int fn_linkage_variant() { return 85; } -extern "C" int fn_linkage_variant1() { return 86; } -int fn_variant2() { return 1; } +int prio() { return 17; } +int prio1() { return 18; } +static int prio2() { return 19; } +static int prio3() { return 20; } +static int prio4() { return 21; } +int fn_linkage_variant() { return 22; } +extern "C" int fn_linkage_variant1() { return 23; } +int fn_variant2() { return 24; } #pragma omp declare target @@ -130,7 +112,7 @@ #pragma omp declare variant(prio) match(implementation = {vendor(llvm)}) #pragma omp declare variant(prio1) match(implementation = {vendor(score(1) \ : llvm)}) -int prio_() { return 1; } +int prio_() { return 25; } #pragma omp declare variant(prio4) match(implementation = {vendor(score(3) \ : llvm)}) @@ -138,20 +120,20 @@ : llvm)}) #pragma omp declare variant(prio3) match(implementation = {vendor(score(1) \ : llvm)}) -static int prio1_() { return 1; } +static int prio1_() { return 26; } int int_fn() { return prio1_(); } extern "C" { #pragma omp declare variant(fn_linkage_variant) match(implementation = {vendor(llvm)}) -int fn_linkage() { return 1; } +int fn_linkage() { return 27; } } #pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(llvm)}) -int fn_linkage1() { return 1; } +int fn_linkage1() { return 28; } #pragma omp declare variant(fn_variant2) match(implementation = {vendor(llvm, ibm)}) -int fn2() { return 87; } +int fn2() { return 29; } #pragma omp end declare target