Skip to content

Commit 215f410

Browse files
author
git apple-llvm automerger
committed
Merge commit '79079c94699a' from llvm.org/main into next
2 parents 4d536ce + 79079c9 commit 215f410

34 files changed

+1355
-226
lines changed

clang/include/clang/AST/Attr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class ASTContext;
3939
class AttributeCommonInfo;
4040
class FunctionDecl;
4141
class OMPTraitInfo;
42+
class OpenACCClause;
4243

4344
/// Attr - This represents one attribute.
4445
class Attr : public AttributeCommonInfo {

clang/include/clang/AST/DeclOpenACC.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class OpenACCDeclareDecl final
102102
static bool classofKind(Kind K) { return K == OpenACCDeclare; }
103103
};
104104

105+
// Reprents a 'routine' directive with a name. When this has no name, it is
106+
// represented as an attribute.
105107
class OpenACCRoutineDecl final
106108
: public OpenACCConstructDecl,
107109
private llvm::TrailingObjects<OpenACCRoutineDecl, const OpenACCClause *> {
@@ -129,6 +131,8 @@ class OpenACCRoutineDecl final
129131
: OpenACCConstructDecl(OpenACCRoutine, DC, OpenACCDirectiveKind::Routine,
130132
StartLoc, DirLoc, EndLoc),
131133
FuncRef(FuncRef), ParensLoc(LParenLoc, RParenLoc) {
134+
assert(LParenLoc.isValid() &&
135+
"Cannot represent implicit name with this declaration");
132136
// Initialize the trailing storage.
133137
std::uninitialized_copy(Clauses.begin(), Clauses.end(),
134138
getTrailingObjects<const OpenACCClause *>());
@@ -148,13 +152,10 @@ class OpenACCRoutineDecl final
148152
static bool classofKind(Kind K) { return K == OpenACCRoutine; }
149153

150154
const Expr *getFunctionReference() const { return FuncRef; }
151-
152155
Expr *getFunctionReference() { return FuncRef; }
153156

154157
SourceLocation getLParenLoc() const { return ParensLoc.getBegin(); }
155158
SourceLocation getRParenLoc() const { return ParensLoc.getEnd(); }
156-
157-
bool hasNameSpecified() const { return !ParensLoc.getBegin().isInvalid(); }
158159
};
159160
} // namespace clang
160161

clang/include/clang/AST/OpenACCClause.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ class OpenACCBindClause final : public OpenACCClauseWithParams {
251251
}
252252
};
253253

254+
bool operator==(const OpenACCBindClause &LHS, const OpenACCBindClause &RHS);
255+
inline bool operator!=(const OpenACCBindClause &LHS,
256+
const OpenACCBindClause &RHS) {
257+
return !(LHS == RHS);
258+
}
259+
254260
using DeviceTypeArgument = std::pair<IdentifierInfo *, SourceLocation>;
255261
/// A 'device_type' or 'dtype' clause, takes a list of either an 'asterisk' or
256262
/// an identifier. The 'asterisk' means 'the rest'.

clang/include/clang/AST/TextNodeDumper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ class TextNodeDumper
430430
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
431431
void VisitOpenACCDeclareDecl(const OpenACCDeclareDecl *D);
432432
void VisitOpenACCRoutineDecl(const OpenACCRoutineDecl *D);
433+
void VisitOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);
433434
void VisitEmbedExpr(const EmbedExpr *S);
434435
void VisitAtomicExpr(const AtomicExpr *AE);
435436
void VisitConvertVectorExpr(const ConvertVectorExpr *S);

clang/include/clang/Basic/Attr.td

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,10 @@ class Attr {
712712
// content. Eg) It parses 3 args, but semantically takes 4 args. Opts out of
713713
// common attribute error checking.
714714
bit HasCustomParsing = 0;
715+
// Set to true if this attribute requires custom serialization after the
716+
// typical attribute serialization. This will cause tablegen to emit a call to
717+
// ASTRecordWriter::Add<Name>Attr and ASTRecordReader::read<Name>Attr.
718+
bit HasCustomSerialization = 0;
715719
// Set to true if all of the attribute's arguments should be parsed in an
716720
// unevaluated context.
717721
bit ParseArgumentsAsUnevaluated = 0;
@@ -5155,12 +5159,30 @@ def Atomic : StmtAttr {
51555159
}
51565160

51575161
def OpenACCRoutineAnnot : InheritableAttr {
5158-
// This attribute is used to mark that a function is targetted by a `routine`
5159-
// directive, so it dones't have a spelling and is always implicit.
5162+
// This attribute is used to mark that a function is targeted by a `routine`
5163+
// directive with a name for the purposes of checking the declaration later.
5164+
// We don't really need a link back to the declaration, as location is
5165+
// sufficient.
5166+
// We abuse the source locations on this a little, since we need two locations
5167+
// for various diagnostic purposes. The 'begin' location is the location of
5168+
// the Routine directive. We are using the 'end' location for any 'bind'
5169+
// clauses, since this is needed for a diagnostic.
51605170
let Spellings = [];
51615171
let Subjects = SubjectList<[Function]>;
51625172
let Documentation = [InternalOnly];
5173+
}
5174+
5175+
def OpenACCRoutineDecl :InheritableAttr {
5176+
// This attribute represents the 'routine' directive when spelled without a
5177+
// 'name'.
5178+
let Spellings = [Pragma<"acc", "routine">];
5179+
let Subjects = SubjectList<[Function]>;
5180+
let SemaHandler = 0;
5181+
let HasCustomParsing = 1;
5182+
let HasCustomSerialization = 1;
5183+
let Documentation = [InternalOnly];
51635184
let AdditionalMembers = [{
5164-
SourceLocation BindClause;
5185+
llvm::SmallVector<const OpenACCClause *> Clauses;
5186+
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const;
51655187
}];
51665188
}

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13976,6 +13976,16 @@ def err_acc_magic_static_in_routine
1397613976
def err_acc_duplicate_bind
1397713977
: Error<"multiple 'routine' directives with 'bind' clauses are not "
1397813978
"permitted to refer to the same function">;
13979+
def err_acc_duplicate_unnamed_bind
13980+
: Error<"OpenACC 'bind' clause on a declaration must bind to the same name "
13981+
"as previous bind clauses">;
13982+
def warn_acc_confusing_routine_name
13983+
: Warning<"OpenACC 'routine' directive with a name refers to a function "
13984+
"with the same name as the function on the following line; this "
13985+
"may be unintended">,
13986+
InGroup<DiagGroup<"openacc-confusing-routine-name">>;
13987+
def err_acc_decl_for_routine
13988+
: Error<"expected function or lambda declaration for 'routine' construct">;
1397913989

1398013990
// AMDGCN builtins diagnostics
1398113991
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;

clang/include/clang/Parse/Parser.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3767,7 +3767,10 @@ class Parser : public CodeCompletionHandler {
37673767
/// diagnostic. Eventually will be split into a few functions to parse
37683768
/// different situations.
37693769
public:
3770-
DeclGroupPtrTy ParseOpenACCDirectiveDecl();
3770+
DeclGroupPtrTy ParseOpenACCDirectiveDecl(AccessSpecifier &AS,
3771+
ParsedAttributes &Attrs,
3772+
DeclSpec::TST TagType,
3773+
Decl *TagDecl);
37713774
StmtResult ParseOpenACCDirectiveStmt();
37723775

37733776
private:
@@ -3901,6 +3904,11 @@ class Parser : public CodeCompletionHandler {
39013904
OpenACCGangArgRes ParseOpenACCGangArg(SourceLocation GangLoc);
39023905
/// Parses a 'condition' expr, ensuring it results in a
39033906
ExprResult ParseOpenACCConditionExpr();
3907+
DeclGroupPtrTy
3908+
ParseOpenACCAfterRoutineDecl(AccessSpecifier &AS, ParsedAttributes &Attrs,
3909+
DeclSpec::TST TagType, Decl *TagDecl,
3910+
OpenACCDirectiveParseInfo &DirInfo);
3911+
StmtResult ParseOpenACCAfterRoutineStmt(OpenACCDirectiveParseInfo &DirInfo);
39043912

39053913
private:
39063914
//===--------------------------------------------------------------------===//

clang/include/clang/Sema/SemaOpenACC.h

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
namespace clang {
3232
class IdentifierInfo;
3333
class OpenACCClause;
34+
class Scope;
3435

3536
class SemaOpenACC : public SemaBase {
3637
public:
@@ -172,6 +173,9 @@ class SemaOpenACC : public SemaBase {
172173
// check them later.
173174
llvm::SmallDenseMap<const clang::FunctionDecl *, SourceLocation>
174175
MagicStaticLocs;
176+
OpenACCRoutineDecl *LastRoutineDecl = nullptr;
177+
178+
void CheckLastRoutineDeclNameConflict(const NamedDecl *ND);
175179

176180
public:
177181
ComputeConstructInfo &getActiveComputeConstructInfo() {
@@ -763,10 +767,37 @@ class SemaOpenACC : public SemaBase {
763767

764768
/// Called after the directive has been completely parsed, including the
765769
/// declaration group or associated statement.
766-
DeclGroupRef ActOnEndDeclDirective(
767-
OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc,
768-
SourceLocation LParenLoc, Expr *FuncRef, SourceLocation RParenLoc,
769-
SourceLocation EndLoc, ArrayRef<OpenACCClause *> Clauses);
770+
DeclGroupRef
771+
ActOnEndDeclDirective(OpenACCDirectiveKind K, SourceLocation StartLoc,
772+
SourceLocation DirLoc, SourceLocation LParenLoc,
773+
SourceLocation RParenLoc, SourceLocation EndLoc,
774+
ArrayRef<OpenACCClause *> Clauses);
775+
776+
// Helper functions for ActOnEndRoutine*Directive, which does all the checking
777+
// given the proper list of declarations.
778+
void CheckRoutineDecl(SourceLocation DirLoc,
779+
ArrayRef<const OpenACCClause *> Clauses,
780+
Decl *NextParsedDecl);
781+
OpenACCRoutineDecl *CheckRoutineDecl(SourceLocation StartLoc,
782+
SourceLocation DirLoc,
783+
SourceLocation LParenLoc, Expr *FuncRef,
784+
SourceLocation RParenLoc,
785+
ArrayRef<const OpenACCClause *> Clauses,
786+
SourceLocation EndLoc);
787+
OpenACCRoutineDeclAttr *
788+
mergeRoutineDeclAttr(const OpenACCRoutineDeclAttr &Old);
789+
DeclGroupRef
790+
ActOnEndRoutineDeclDirective(SourceLocation StartLoc, SourceLocation DirLoc,
791+
SourceLocation LParenLoc, Expr *ReferencedFunc,
792+
SourceLocation RParenLoc,
793+
ArrayRef<const OpenACCClause *> Clauses,
794+
SourceLocation EndLoc, DeclGroupPtrTy NextDecl);
795+
StmtResult
796+
ActOnEndRoutineStmtDirective(SourceLocation StartLoc, SourceLocation DirLoc,
797+
SourceLocation LParenLoc, Expr *ReferencedFunc,
798+
SourceLocation RParenLoc,
799+
ArrayRef<const OpenACCClause *> Clauses,
800+
SourceLocation EndLoc, Stmt *NextStmt);
770801

771802
/// Called when encountering an 'int-expr' for OpenACC, and manages
772803
/// conversions and diagnostics to 'int'.
@@ -780,8 +811,14 @@ class SemaOpenACC : public SemaBase {
780811
/// Helper function called by ActonVar that is used to check a 'cache' var.
781812
ExprResult ActOnCacheVar(Expr *VarExpr);
782813
/// Function called when a variable declarator is created, which lets us
783-
/// impelment the 'routine' 'function static variables' restriction.
814+
/// implement the 'routine' 'function static variables' restriction.
784815
void ActOnVariableDeclarator(VarDecl *VD);
816+
/// Called when a function decl is created, which lets us implement the
817+
/// 'routine' 'doesn't match next thing' warning.
818+
void ActOnFunctionDeclarator(FunctionDecl *FD);
819+
/// Called when a variable is initialized, so we can implement the 'routine
820+
/// 'doesn't match the next thing' warning for lambda init.
821+
void ActOnVariableInit(VarDecl *VD, QualType InitType);
785822

786823
// Called after 'ActOnVar' specifically for a 'link' clause, which has to do
787824
// some minor additional checks.

clang/include/clang/Serialization/ASTRecordReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ class ASTRecordReader
288288
/// statement reading.
289289
void readOpenACCClauseList(MutableArrayRef<const OpenACCClause *> Clauses);
290290

291+
void readOpenACCRoutineDeclAttr(OpenACCRoutineDeclAttr *A);
292+
291293
/// Read a source location, advancing Idx.
292294
SourceLocation readSourceLocation(LocSeq *Seq = nullptr) {
293295
return Reader->ReadSourceLocation(*F, Record, Idx, Seq);

clang/include/clang/Serialization/ASTRecordWriter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,8 @@ class ASTRecordWriter
307307
/// Writes out a list of OpenACC clauses.
308308
void writeOpenACCClauseList(ArrayRef<const OpenACCClause *> Clauses);
309309

310+
void AddOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);
311+
310312
/// Emit a string.
311313
void AddString(StringRef Str) {
312314
return Writer->AddString(Str, *Record);

clang/lib/AST/DeclOpenACC.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "clang/AST/DeclOpenACC.h"
1414
#include "clang/AST/ASTContext.h"
15+
#include "clang/AST/Attr.h"
16+
#include "clang/AST/OpenACCClause.h"
1517

1618
using namespace clang;
1719

@@ -50,3 +52,12 @@ OpenACCRoutineDecl::CreateDeserialized(ASTContext &Ctx, GlobalDeclID ID,
5052
return new (Ctx, ID, additionalSizeToAlloc<const OpenACCClause *>(NumClauses))
5153
OpenACCRoutineDecl(NumClauses);
5254
}
55+
56+
void OpenACCRoutineDeclAttr::printPrettyPragma(
57+
llvm::raw_ostream &OS, const clang::PrintingPolicy &P) const {
58+
if (Clauses.size() > 0) {
59+
OS << ' ';
60+
OpenACCClausePrinter Printer{OS, P};
61+
Printer.VisitClauseList(Clauses);
62+
}
63+
}

clang/lib/AST/DeclPrinter.cpp

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace {
4949
QualType T);
5050

5151
void PrintObjCTypeParams(ObjCTypeParamList *Params);
52+
void PrintOpenACCRoutineOnLambda(Decl *D);
5253

5354
public:
5455
DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
@@ -292,10 +293,34 @@ bool DeclPrinter::prettyPrintAttributes(const Decl *D,
292293
return hasPrinted;
293294
}
294295

296+
void DeclPrinter::PrintOpenACCRoutineOnLambda(Decl *D) {
297+
CXXRecordDecl *CXXRD = nullptr;
298+
if (const auto *VD = dyn_cast<VarDecl>(D)) {
299+
if (const auto *Init = VD->getInit())
300+
CXXRD = Init->getType().isNull() ? nullptr
301+
: Init->getType()->getAsCXXRecordDecl();
302+
} else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
303+
CXXRD =
304+
FD->getType().isNull() ? nullptr : FD->getType()->getAsCXXRecordDecl();
305+
}
306+
307+
if (!CXXRD || !CXXRD->isLambda())
308+
return;
309+
310+
if (const auto *Call = CXXRD->getLambdaCallOperator()) {
311+
for (auto *A : Call->specific_attrs<OpenACCRoutineDeclAttr>()) {
312+
A->printPretty(Out, Policy);
313+
Indent();
314+
}
315+
}
316+
}
317+
295318
void DeclPrinter::prettyPrintPragmas(Decl *D) {
296319
if (Policy.PolishForDeclaration)
297320
return;
298321

322+
PrintOpenACCRoutineOnLambda(D);
323+
299324
if (D->hasAttrs()) {
300325
AttrVec &Attrs = D->getAttrs();
301326
for (auto *A : Attrs) {
@@ -896,6 +921,7 @@ void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
896921
}
897922

898923
void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
924+
prettyPrintPragmas(D);
899925
// FIXME: add printing of pragma attributes if required.
900926
if (!Policy.SuppressSpecifiers && D->isMutable())
901927
Out << "mutable ";
@@ -1932,19 +1958,17 @@ void DeclPrinter::VisitOpenACCRoutineDecl(OpenACCRoutineDecl *D) {
19321958
if (!D->isInvalidDecl()) {
19331959
Out << "#pragma acc routine";
19341960

1935-
if (D->hasNameSpecified()) {
1936-
Out << "(";
1961+
Out << "(";
19371962

1938-
// The referenced function was named here, but this makes us tolerant of
1939-
// errors.
1940-
if (D->getFunctionReference())
1941-
D->getFunctionReference()->printPretty(Out, nullptr, Policy,
1942-
Indentation, "\n", &Context);
1943-
else
1944-
Out << "<error>";
1963+
// The referenced function was named here, but this makes us tolerant of
1964+
// errors.
1965+
if (D->getFunctionReference())
1966+
D->getFunctionReference()->printPretty(Out, nullptr, Policy, Indentation,
1967+
"\n", &Context);
1968+
else
1969+
Out << "<error>";
19451970

1946-
Out << ")";
1947-
}
1971+
Out << ")";
19481972

19491973
if (!D->clauses().empty()) {
19501974
Out << ' ';

clang/lib/AST/OpenACCClause.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,18 @@ OpenACCBindClause *OpenACCBindClause::Create(const ASTContext &C,
628628
return new (Mem) OpenACCBindClause(BeginLoc, LParenLoc, ID, EndLoc);
629629
}
630630

631+
bool clang::operator==(const OpenACCBindClause &LHS,
632+
const OpenACCBindClause &RHS) {
633+
if (LHS.isStringArgument() != RHS.isStringArgument())
634+
return false;
635+
636+
if (LHS.isStringArgument())
637+
return LHS.getStringArgument()->getString() ==
638+
RHS.getStringArgument()->getString();
639+
return LHS.getIdentifierArgument()->getName() ==
640+
RHS.getIdentifierArgument()->getName();
641+
}
642+
631643
//===----------------------------------------------------------------------===//
632644
// OpenACC clauses printing methods
633645
//===----------------------------------------------------------------------===//

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3112,10 +3112,7 @@ void TextNodeDumper::VisitOpenACCDeclareDecl(const OpenACCDeclareDecl *D) {
31123112
void TextNodeDumper::VisitOpenACCRoutineDecl(const OpenACCRoutineDecl *D) {
31133113
OS << " " << D->getDirectiveKind();
31143114

3115-
if (D->hasNameSpecified()) {
3116-
OS << " name_specified";
3117-
dumpSourceRange(SourceRange{D->getLParenLoc(), D->getRParenLoc()});
3118-
}
3115+
dumpSourceRange(SourceRange{D->getLParenLoc(), D->getRParenLoc()});
31193116

31203117
AddChild([=] { Visit(D->getFunctionReference()); });
31213118

@@ -3127,6 +3124,16 @@ void TextNodeDumper::VisitOpenACCRoutineDecl(const OpenACCRoutineDecl *D) {
31273124
});
31283125
}
31293126

3127+
void TextNodeDumper::VisitOpenACCRoutineDeclAttr(
3128+
const OpenACCRoutineDeclAttr *A) {
3129+
for (const OpenACCClause *C : A->Clauses)
3130+
AddChild([=] {
3131+
Visit(C);
3132+
for (const Stmt *S : C->children())
3133+
AddChild([=] { Visit(S); });
3134+
});
3135+
}
3136+
31303137
void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
31313138
AddChild("begin", [=] { OS << S->getStartingElementPos(); });
31323139
AddChild("number of elements", [=] { OS << S->getDataElementCount(); });

0 commit comments

Comments
 (0)