Bug Summary

File:tools/clang/lib/Parse/ParsePragma.cpp
Warning:line 3178, column 23
Access to field 'Namespace' results in a dereference of a null pointer (loaded from variable 'Info')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ParsePragma.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-9/lib/clang/9.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/lib/Parse -I /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse -I /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn362543/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-9~svn362543/build-llvm/tools/clang/lib/Parse -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn362543=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-06-05-060531-1271-1 -x c++ /build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp -faddrsig
1//===--- ParsePragma.cpp - Language specific pragma parsing ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the language specific #pragma handlers.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTContext.h"
14#include "clang/Basic/PragmaKinds.h"
15#include "clang/Basic/TargetInfo.h"
16#include "clang/Lex/Preprocessor.h"
17#include "clang/Parse/LoopHint.h"
18#include "clang/Parse/ParseDiagnostic.h"
19#include "clang/Parse/Parser.h"
20#include "clang/Parse/RAIIObjectsForParser.h"
21#include "clang/Sema/Scope.h"
22#include "llvm/ADT/StringSwitch.h"
23using namespace clang;
24
25namespace {
26
27struct PragmaAlignHandler : public PragmaHandler {
28 explicit PragmaAlignHandler() : PragmaHandler("align") {}
29 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
30 Token &FirstToken) override;
31};
32
33struct PragmaGCCVisibilityHandler : public PragmaHandler {
34 explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
35 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
36 Token &FirstToken) override;
37};
38
39struct PragmaOptionsHandler : public PragmaHandler {
40 explicit PragmaOptionsHandler() : PragmaHandler("options") {}
41 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
42 Token &FirstToken) override;
43};
44
45struct PragmaPackHandler : public PragmaHandler {
46 explicit PragmaPackHandler() : PragmaHandler("pack") {}
47 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
48 Token &FirstToken) override;
49};
50
51struct PragmaClangSectionHandler : public PragmaHandler {
52 explicit PragmaClangSectionHandler(Sema &S)
53 : PragmaHandler("section"), Actions(S) {}
54 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
55 Token &FirstToken) override;
56
57private:
58 Sema &Actions;
59};
60
61struct PragmaMSStructHandler : public PragmaHandler {
62 explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
63 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
64 Token &FirstToken) override;
65};
66
67struct PragmaUnusedHandler : public PragmaHandler {
68 PragmaUnusedHandler() : PragmaHandler("unused") {}
69 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
70 Token &FirstToken) override;
71};
72
73struct PragmaWeakHandler : public PragmaHandler {
74 explicit PragmaWeakHandler() : PragmaHandler("weak") {}
75 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
76 Token &FirstToken) override;
77};
78
79struct PragmaRedefineExtnameHandler : public PragmaHandler {
80 explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
81 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
82 Token &FirstToken) override;
83};
84
85struct PragmaOpenCLExtensionHandler : public PragmaHandler {
86 PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
87 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
88 Token &FirstToken) override;
89};
90
91
92struct PragmaFPContractHandler : public PragmaHandler {
93 PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
94 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
95 Token &FirstToken) override;
96};
97
98// Pragma STDC implementations.
99
100/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
101struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
102 PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
103
104 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
105 Token &Tok) override {
106 tok::OnOffSwitch OOS;
107 if (PP.LexOnOffSwitch(OOS))
108 return;
109 if (OOS == tok::OOS_ON) {
110 PP.Diag(Tok, diag::warn_stdc_fenv_access_not_supported);
111 }
112
113 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
114 1);
115 Toks[0].startToken();
116 Toks[0].setKind(tok::annot_pragma_fenv_access);
117 Toks[0].setLocation(Tok.getLocation());
118 Toks[0].setAnnotationEndLoc(Tok.getLocation());
119 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
120 static_cast<uintptr_t>(OOS)));
121 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
122 /*IsReinject=*/false);
123 }
124};
125
126/// PragmaSTDC_CX_LIMITED_RANGEHandler - "\#pragma STDC CX_LIMITED_RANGE ...".
127struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
128 PragmaSTDC_CX_LIMITED_RANGEHandler() : PragmaHandler("CX_LIMITED_RANGE") {}
129
130 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
131 Token &Tok) override {
132 tok::OnOffSwitch OOS;
133 PP.LexOnOffSwitch(OOS);
134 }
135};
136
137/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
138struct PragmaSTDC_UnknownHandler : public PragmaHandler {
139 PragmaSTDC_UnknownHandler() = default;
140
141 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
142 Token &UnknownTok) override {
143 // C99 6.10.6p2, unknown forms are not allowed.
144 PP.Diag(UnknownTok, diag::ext_stdc_pragma_ignored);
145 }
146};
147
148struct PragmaFPHandler : public PragmaHandler {
149 PragmaFPHandler() : PragmaHandler("fp") {}
150 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
151 Token &FirstToken) override;
152};
153
154struct PragmaNoOpenMPHandler : public PragmaHandler {
155 PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
156 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
157 Token &FirstToken) override;
158};
159
160struct PragmaOpenMPHandler : public PragmaHandler {
161 PragmaOpenMPHandler() : PragmaHandler("omp") { }
162 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
163 Token &FirstToken) override;
164};
165
166/// PragmaCommentHandler - "\#pragma comment ...".
167struct PragmaCommentHandler : public PragmaHandler {
168 PragmaCommentHandler(Sema &Actions)
169 : PragmaHandler("comment"), Actions(Actions) {}
170 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
171 Token &FirstToken) override;
172
173private:
174 Sema &Actions;
175};
176
177struct PragmaDetectMismatchHandler : public PragmaHandler {
178 PragmaDetectMismatchHandler(Sema &Actions)
179 : PragmaHandler("detect_mismatch"), Actions(Actions) {}
180 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
181 Token &FirstToken) override;
182
183private:
184 Sema &Actions;
185};
186
187struct PragmaMSPointersToMembers : public PragmaHandler {
188 explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {}
189 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
190 Token &FirstToken) override;
191};
192
193struct PragmaMSVtorDisp : public PragmaHandler {
194 explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {}
195 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
196 Token &FirstToken) override;
197};
198
199struct PragmaMSPragma : public PragmaHandler {
200 explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {}
201 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
202 Token &FirstToken) override;
203};
204
205/// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
206struct PragmaOptimizeHandler : public PragmaHandler {
207 PragmaOptimizeHandler(Sema &S)
208 : PragmaHandler("optimize"), Actions(S) {}
209 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
210 Token &FirstToken) override;
211
212private:
213 Sema &Actions;
214};
215
216struct PragmaLoopHintHandler : public PragmaHandler {
217 PragmaLoopHintHandler() : PragmaHandler("loop") {}
218 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
219 Token &FirstToken) override;
220};
221
222struct PragmaUnrollHintHandler : public PragmaHandler {
223 PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {}
224 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
225 Token &FirstToken) override;
226};
227
228struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler {
229 PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {}
230};
231
232struct PragmaMSIntrinsicHandler : public PragmaHandler {
233 PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {}
234 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
235 Token &FirstToken) override;
236};
237
238struct PragmaMSOptimizeHandler : public PragmaHandler {
239 PragmaMSOptimizeHandler() : PragmaHandler("optimize") {}
240 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
241 Token &FirstToken) override;
242};
243
244struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler {
245 PragmaForceCUDAHostDeviceHandler(Sema &Actions)
246 : PragmaHandler("force_cuda_host_device"), Actions(Actions) {}
247 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
248 Token &FirstToken) override;
249
250private:
251 Sema &Actions;
252};
253
254/// PragmaAttributeHandler - "\#pragma clang attribute ...".
255struct PragmaAttributeHandler : public PragmaHandler {
256 PragmaAttributeHandler(AttributeFactory &AttrFactory)
257 : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
258 void HandlePragma(Preprocessor &PP, PragmaIntroducer Introducer,
259 Token &FirstToken) override;
260
261 /// A pool of attributes that were parsed in \#pragma clang attribute.
262 ParsedAttributes AttributesForPragmaAttribute;
263};
264
265} // end namespace
266
267void Parser::initializePragmaHandlers() {
268 AlignHandler = llvm::make_unique<PragmaAlignHandler>();
269 PP.AddPragmaHandler(AlignHandler.get());
270
271 GCCVisibilityHandler = llvm::make_unique<PragmaGCCVisibilityHandler>();
272 PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
273
274 OptionsHandler = llvm::make_unique<PragmaOptionsHandler>();
275 PP.AddPragmaHandler(OptionsHandler.get());
276
277 PackHandler = llvm::make_unique<PragmaPackHandler>();
278 PP.AddPragmaHandler(PackHandler.get());
279
280 MSStructHandler = llvm::make_unique<PragmaMSStructHandler>();
281 PP.AddPragmaHandler(MSStructHandler.get());
282
283 UnusedHandler = llvm::make_unique<PragmaUnusedHandler>();
284 PP.AddPragmaHandler(UnusedHandler.get());
285
286 WeakHandler = llvm::make_unique<PragmaWeakHandler>();
287 PP.AddPragmaHandler(WeakHandler.get());
288
289 RedefineExtnameHandler = llvm::make_unique<PragmaRedefineExtnameHandler>();
290 PP.AddPragmaHandler(RedefineExtnameHandler.get());
291
292 FPContractHandler = llvm::make_unique<PragmaFPContractHandler>();
293 PP.AddPragmaHandler("STDC", FPContractHandler.get());
294
295 STDCFENVHandler = llvm::make_unique<PragmaSTDC_FENV_ACCESSHandler>();
296 PP.AddPragmaHandler("STDC", STDCFENVHandler.get());
297
298 STDCCXLIMITHandler = llvm::make_unique<PragmaSTDC_CX_LIMITED_RANGEHandler>();
299 PP.AddPragmaHandler("STDC", STDCCXLIMITHandler.get());
300
301 STDCUnknownHandler = llvm::make_unique<PragmaSTDC_UnknownHandler>();
302 PP.AddPragmaHandler("STDC", STDCUnknownHandler.get());
303
304 PCSectionHandler = llvm::make_unique<PragmaClangSectionHandler>(Actions);
305 PP.AddPragmaHandler("clang", PCSectionHandler.get());
306
307 if (getLangOpts().OpenCL) {
308 OpenCLExtensionHandler = llvm::make_unique<PragmaOpenCLExtensionHandler>();
309 PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
310
311 PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
312 }
313 if (getLangOpts().OpenMP)
314 OpenMPHandler = llvm::make_unique<PragmaOpenMPHandler>();
315 else
316 OpenMPHandler = llvm::make_unique<PragmaNoOpenMPHandler>();
317 PP.AddPragmaHandler(OpenMPHandler.get());
318
319 if (getLangOpts().MicrosoftExt ||
320 getTargetInfo().getTriple().isOSBinFormatELF()) {
321 MSCommentHandler = llvm::make_unique<PragmaCommentHandler>(Actions);
322 PP.AddPragmaHandler(MSCommentHandler.get());
323 }
324
325 if (getLangOpts().MicrosoftExt) {
326 MSDetectMismatchHandler =
327 llvm::make_unique<PragmaDetectMismatchHandler>(Actions);
328 PP.AddPragmaHandler(MSDetectMismatchHandler.get());
329 MSPointersToMembers = llvm::make_unique<PragmaMSPointersToMembers>();
330 PP.AddPragmaHandler(MSPointersToMembers.get());
331 MSVtorDisp = llvm::make_unique<PragmaMSVtorDisp>();
332 PP.AddPragmaHandler(MSVtorDisp.get());
333 MSInitSeg = llvm::make_unique<PragmaMSPragma>("init_seg");
334 PP.AddPragmaHandler(MSInitSeg.get());
335 MSDataSeg = llvm::make_unique<PragmaMSPragma>("data_seg");
336 PP.AddPragmaHandler(MSDataSeg.get());
337 MSBSSSeg = llvm::make_unique<PragmaMSPragma>("bss_seg");
338 PP.AddPragmaHandler(MSBSSSeg.get());
339 MSConstSeg = llvm::make_unique<PragmaMSPragma>("const_seg");
340 PP.AddPragmaHandler(MSConstSeg.get());
341 MSCodeSeg = llvm::make_unique<PragmaMSPragma>("code_seg");
342 PP.AddPragmaHandler(MSCodeSeg.get());
343 MSSection = llvm::make_unique<PragmaMSPragma>("section");
344 PP.AddPragmaHandler(MSSection.get());
345 MSRuntimeChecks = llvm::make_unique<PragmaMSRuntimeChecksHandler>();
346 PP.AddPragmaHandler(MSRuntimeChecks.get());
347 MSIntrinsic = llvm::make_unique<PragmaMSIntrinsicHandler>();
348 PP.AddPragmaHandler(MSIntrinsic.get());
349 MSOptimize = llvm::make_unique<PragmaMSOptimizeHandler>();
350 PP.AddPragmaHandler(MSOptimize.get());
351 }
352
353 if (getLangOpts().CUDA) {
354 CUDAForceHostDeviceHandler =
355 llvm::make_unique<PragmaForceCUDAHostDeviceHandler>(Actions);
356 PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get());
357 }
358
359 OptimizeHandler = llvm::make_unique<PragmaOptimizeHandler>(Actions);
360 PP.AddPragmaHandler("clang", OptimizeHandler.get());
361
362 LoopHintHandler = llvm::make_unique<PragmaLoopHintHandler>();
363 PP.AddPragmaHandler("clang", LoopHintHandler.get());
364
365 UnrollHintHandler = llvm::make_unique<PragmaUnrollHintHandler>("unroll");
366 PP.AddPragmaHandler(UnrollHintHandler.get());
367
368 NoUnrollHintHandler = llvm::make_unique<PragmaUnrollHintHandler>("nounroll");
369 PP.AddPragmaHandler(NoUnrollHintHandler.get());
370
371 UnrollAndJamHintHandler =
372 llvm::make_unique<PragmaUnrollHintHandler>("unroll_and_jam");
373 PP.AddPragmaHandler(UnrollAndJamHintHandler.get());
374
375 NoUnrollAndJamHintHandler =
376 llvm::make_unique<PragmaUnrollHintHandler>("nounroll_and_jam");
377 PP.AddPragmaHandler(NoUnrollAndJamHintHandler.get());
378
379 FPHandler = llvm::make_unique<PragmaFPHandler>();
380 PP.AddPragmaHandler("clang", FPHandler.get());
381
382 AttributePragmaHandler =
383 llvm::make_unique<PragmaAttributeHandler>(AttrFactory);
384 PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
385}
386
387void Parser::resetPragmaHandlers() {
388 // Remove the pragma handlers we installed.
389 PP.RemovePragmaHandler(AlignHandler.get());
390 AlignHandler.reset();
391 PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
392 GCCVisibilityHandler.reset();
393 PP.RemovePragmaHandler(OptionsHandler.get());
394 OptionsHandler.reset();
395 PP.RemovePragmaHandler(PackHandler.get());
396 PackHandler.reset();
397 PP.RemovePragmaHandler(MSStructHandler.get());
398 MSStructHandler.reset();
399 PP.RemovePragmaHandler(UnusedHandler.get());
400 UnusedHandler.reset();
401 PP.RemovePragmaHandler(WeakHandler.get());
402 WeakHandler.reset();
403 PP.RemovePragmaHandler(RedefineExtnameHandler.get());
404 RedefineExtnameHandler.reset();
405
406 if (getLangOpts().OpenCL) {
407 PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
408 OpenCLExtensionHandler.reset();
409 PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
410 }
411 PP.RemovePragmaHandler(OpenMPHandler.get());
412 OpenMPHandler.reset();
413
414 if (getLangOpts().MicrosoftExt ||
415 getTargetInfo().getTriple().isOSBinFormatELF()) {
416 PP.RemovePragmaHandler(MSCommentHandler.get());
417 MSCommentHandler.reset();
418 }
419
420 PP.RemovePragmaHandler("clang", PCSectionHandler.get());
421 PCSectionHandler.reset();
422
423 if (getLangOpts().MicrosoftExt) {
424 PP.RemovePragmaHandler(MSDetectMismatchHandler.get());
425 MSDetectMismatchHandler.reset();
426 PP.RemovePragmaHandler(MSPointersToMembers.get());
427 MSPointersToMembers.reset();
428 PP.RemovePragmaHandler(MSVtorDisp.get());
429 MSVtorDisp.reset();
430 PP.RemovePragmaHandler(MSInitSeg.get());
431 MSInitSeg.reset();
432 PP.RemovePragmaHandler(MSDataSeg.get());
433 MSDataSeg.reset();
434 PP.RemovePragmaHandler(MSBSSSeg.get());
435 MSBSSSeg.reset();
436 PP.RemovePragmaHandler(MSConstSeg.get());
437 MSConstSeg.reset();
438 PP.RemovePragmaHandler(MSCodeSeg.get());
439 MSCodeSeg.reset();
440 PP.RemovePragmaHandler(MSSection.get());
441 MSSection.reset();
442 PP.RemovePragmaHandler(MSRuntimeChecks.get());
443 MSRuntimeChecks.reset();
444 PP.RemovePragmaHandler(MSIntrinsic.get());
445 MSIntrinsic.reset();
446 PP.RemovePragmaHandler(MSOptimize.get());
447 MSOptimize.reset();
448 }
449
450 if (getLangOpts().CUDA) {
451 PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get());
452 CUDAForceHostDeviceHandler.reset();
453 }
454
455 PP.RemovePragmaHandler("STDC", FPContractHandler.get());
456 FPContractHandler.reset();
457
458 PP.RemovePragmaHandler("STDC", STDCFENVHandler.get());
459 STDCFENVHandler.reset();
460
461 PP.RemovePragmaHandler("STDC", STDCCXLIMITHandler.get());
462 STDCCXLIMITHandler.reset();
463
464 PP.RemovePragmaHandler("STDC", STDCUnknownHandler.get());
465 STDCUnknownHandler.reset();
466
467 PP.RemovePragmaHandler("clang", OptimizeHandler.get());
468 OptimizeHandler.reset();
469
470 PP.RemovePragmaHandler("clang", LoopHintHandler.get());
471 LoopHintHandler.reset();
472
473 PP.RemovePragmaHandler(UnrollHintHandler.get());
474 UnrollHintHandler.reset();
475
476 PP.RemovePragmaHandler(NoUnrollHintHandler.get());
477 NoUnrollHintHandler.reset();
478
479 PP.RemovePragmaHandler(UnrollAndJamHintHandler.get());
480 UnrollAndJamHintHandler.reset();
481
482 PP.RemovePragmaHandler(NoUnrollAndJamHintHandler.get());
483 NoUnrollAndJamHintHandler.reset();
484
485 PP.RemovePragmaHandler("clang", FPHandler.get());
486 FPHandler.reset();
487
488 PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
489 AttributePragmaHandler.reset();
490}
491
492/// Handle the annotation token produced for #pragma unused(...)
493///
494/// Each annot_pragma_unused is followed by the argument token so e.g.
495/// "#pragma unused(x,y)" becomes:
496/// annot_pragma_unused 'x' annot_pragma_unused 'y'
497void Parser::HandlePragmaUnused() {
498 assert(Tok.is(tok::annot_pragma_unused))((Tok.is(tok::annot_pragma_unused)) ? static_cast<void>
(0) : __assert_fail ("Tok.is(tok::annot_pragma_unused)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 498, __PRETTY_FUNCTION__))
;
499 SourceLocation UnusedLoc = ConsumeAnnotationToken();
500 Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc);
501 ConsumeToken(); // The argument token.
502}
503
504void Parser::HandlePragmaVisibility() {
505 assert(Tok.is(tok::annot_pragma_vis))((Tok.is(tok::annot_pragma_vis)) ? static_cast<void> (0
) : __assert_fail ("Tok.is(tok::annot_pragma_vis)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 505, __PRETTY_FUNCTION__))
;
506 const IdentifierInfo *VisType =
507 static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
508 SourceLocation VisLoc = ConsumeAnnotationToken();
509 Actions.ActOnPragmaVisibility(VisType, VisLoc);
510}
511
512namespace {
513struct PragmaPackInfo {
514 Sema::PragmaMsStackAction Action;
515 StringRef SlotLabel;
516 Token Alignment;
517};
518} // end anonymous namespace
519
520void Parser::HandlePragmaPack() {
521 assert(Tok.is(tok::annot_pragma_pack))((Tok.is(tok::annot_pragma_pack)) ? static_cast<void> (
0) : __assert_fail ("Tok.is(tok::annot_pragma_pack)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 521, __PRETTY_FUNCTION__))
;
522 PragmaPackInfo *Info =
523 static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
524 SourceLocation PragmaLoc = Tok.getLocation();
525 ExprResult Alignment;
526 if (Info->Alignment.is(tok::numeric_constant)) {
527 Alignment = Actions.ActOnNumericConstant(Info->Alignment);
528 if (Alignment.isInvalid()) {
529 ConsumeAnnotationToken();
530 return;
531 }
532 }
533 Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
534 Alignment.get());
535 // Consume the token after processing the pragma to enable pragma-specific
536 // #include warnings.
537 ConsumeAnnotationToken();
538}
539
540void Parser::HandlePragmaMSStruct() {
541 assert(Tok.is(tok::annot_pragma_msstruct))((Tok.is(tok::annot_pragma_msstruct)) ? static_cast<void>
(0) : __assert_fail ("Tok.is(tok::annot_pragma_msstruct)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 541, __PRETTY_FUNCTION__))
;
542 PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>(
543 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
544 Actions.ActOnPragmaMSStruct(Kind);
545 ConsumeAnnotationToken();
546}
547
548void Parser::HandlePragmaAlign() {
549 assert(Tok.is(tok::annot_pragma_align))((Tok.is(tok::annot_pragma_align)) ? static_cast<void> (
0) : __assert_fail ("Tok.is(tok::annot_pragma_align)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 549, __PRETTY_FUNCTION__))
;
550 Sema::PragmaOptionsAlignKind Kind =
551 static_cast<Sema::PragmaOptionsAlignKind>(
552 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
553 Actions.ActOnPragmaOptionsAlign(Kind, Tok.getLocation());
554 // Consume the token after processing the pragma to enable pragma-specific
555 // #include warnings.
556 ConsumeAnnotationToken();
557}
558
559void Parser::HandlePragmaDump() {
560 assert(Tok.is(tok::annot_pragma_dump))((Tok.is(tok::annot_pragma_dump)) ? static_cast<void> (
0) : __assert_fail ("Tok.is(tok::annot_pragma_dump)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 560, __PRETTY_FUNCTION__))
;
561 IdentifierInfo *II =
562 reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue());
563 Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II);
564 ConsumeAnnotationToken();
565}
566
567void Parser::HandlePragmaWeak() {
568 assert(Tok.is(tok::annot_pragma_weak))((Tok.is(tok::annot_pragma_weak)) ? static_cast<void> (
0) : __assert_fail ("Tok.is(tok::annot_pragma_weak)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 568, __PRETTY_FUNCTION__))
;
569 SourceLocation PragmaLoc = ConsumeAnnotationToken();
570 Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
571 Tok.getLocation());
572 ConsumeToken(); // The weak name.
573}
574
575void Parser::HandlePragmaWeakAlias() {
576 assert(Tok.is(tok::annot_pragma_weakalias))((Tok.is(tok::annot_pragma_weakalias)) ? static_cast<void>
(0) : __assert_fail ("Tok.is(tok::annot_pragma_weakalias)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 576, __PRETTY_FUNCTION__))
;
577 SourceLocation PragmaLoc = ConsumeAnnotationToken();
578 IdentifierInfo *WeakName = Tok.getIdentifierInfo();
579 SourceLocation WeakNameLoc = Tok.getLocation();
580 ConsumeToken();
581 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
582 SourceLocation AliasNameLoc = Tok.getLocation();
583 ConsumeToken();
584 Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
585 WeakNameLoc, AliasNameLoc);
586
587}
588
589void Parser::HandlePragmaRedefineExtname() {
590 assert(Tok.is(tok::annot_pragma_redefine_extname))((Tok.is(tok::annot_pragma_redefine_extname)) ? static_cast<
void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_redefine_extname)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 590, __PRETTY_FUNCTION__))
;
591 SourceLocation RedefLoc = ConsumeAnnotationToken();
592 IdentifierInfo *RedefName = Tok.getIdentifierInfo();
593 SourceLocation RedefNameLoc = Tok.getLocation();
594 ConsumeToken();
595 IdentifierInfo *AliasName = Tok.getIdentifierInfo();
596 SourceLocation AliasNameLoc = Tok.getLocation();
597 ConsumeToken();
598 Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
599 RedefNameLoc, AliasNameLoc);
600}
601
602void Parser::HandlePragmaFPContract() {
603 assert(Tok.is(tok::annot_pragma_fp_contract))((Tok.is(tok::annot_pragma_fp_contract)) ? static_cast<void
> (0) : __assert_fail ("Tok.is(tok::annot_pragma_fp_contract)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 603, __PRETTY_FUNCTION__))
;
604 tok::OnOffSwitch OOS =
605 static_cast<tok::OnOffSwitch>(
606 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
607
608 LangOptions::FPContractModeKind FPC;
609 switch (OOS) {
610 case tok::OOS_ON:
611 FPC = LangOptions::FPC_On;
612 break;
613 case tok::OOS_OFF:
614 FPC = LangOptions::FPC_Off;
615 break;
616 case tok::OOS_DEFAULT:
617 FPC = getLangOpts().getDefaultFPContractMode();
618 break;
619 }
620
621 Actions.ActOnPragmaFPContract(FPC);
622 ConsumeAnnotationToken();
623}
624
625void Parser::HandlePragmaFEnvAccess() {
626 assert(Tok.is(tok::annot_pragma_fenv_access))((Tok.is(tok::annot_pragma_fenv_access)) ? static_cast<void
> (0) : __assert_fail ("Tok.is(tok::annot_pragma_fenv_access)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 626, __PRETTY_FUNCTION__))
;
627 tok::OnOffSwitch OOS =
628 static_cast<tok::OnOffSwitch>(
629 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
630
631 LangOptions::FEnvAccessModeKind FPC;
632 switch (OOS) {
633 case tok::OOS_ON:
634 FPC = LangOptions::FEA_On;
635 break;
636 case tok::OOS_OFF:
637 FPC = LangOptions::FEA_Off;
638 break;
639 case tok::OOS_DEFAULT: // FIXME: Add this cli option when it makes sense.
640 FPC = LangOptions::FEA_Off;
641 break;
642 }
643
644 Actions.ActOnPragmaFEnvAccess(FPC);
645 ConsumeAnnotationToken();
646}
647
648
649StmtResult Parser::HandlePragmaCaptured()
650{
651 assert(Tok.is(tok::annot_pragma_captured))((Tok.is(tok::annot_pragma_captured)) ? static_cast<void>
(0) : __assert_fail ("Tok.is(tok::annot_pragma_captured)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 651, __PRETTY_FUNCTION__))
;
652 ConsumeAnnotationToken();
653
654 if (Tok.isNot(tok::l_brace)) {
655 PP.Diag(Tok, diag::err_expected) << tok::l_brace;
656 return StmtError();
657 }
658
659 SourceLocation Loc = Tok.getLocation();
660
661 ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope |
662 Scope::CompoundStmtScope);
663 Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default,
664 /*NumParams=*/1);
665
666 StmtResult R = ParseCompoundStatement();
667 CapturedRegionScope.Exit();
668
669 if (R.isInvalid()) {
670 Actions.ActOnCapturedRegionError();
671 return StmtError();
672 }
673
674 return Actions.ActOnCapturedRegionEnd(R.get());
675}
676
677namespace {
678 enum OpenCLExtState : char {
679 Disable, Enable, Begin, End
680 };
681 typedef std::pair<const IdentifierInfo *, OpenCLExtState> OpenCLExtData;
682}
683
684void Parser::HandlePragmaOpenCLExtension() {
685 assert(Tok.is(tok::annot_pragma_opencl_extension))((Tok.is(tok::annot_pragma_opencl_extension)) ? static_cast<
void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_opencl_extension)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 685, __PRETTY_FUNCTION__))
;
686 OpenCLExtData *Data = static_cast<OpenCLExtData*>(Tok.getAnnotationValue());
687 auto State = Data->second;
688 auto Ident = Data->first;
689 SourceLocation NameLoc = Tok.getLocation();
690 ConsumeAnnotationToken();
691
692 auto &Opt = Actions.getOpenCLOptions();
693 auto Name = Ident->getName();
694 // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
695 // overriding all previously issued extension directives, but only if the
696 // behavior is set to disable."
697 if (Name == "all") {
698 if (State == Disable) {
699 Opt.disableAll();
700 Opt.enableSupportedCore(getLangOpts());
701 } else {
702 PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
703 }
704 } else if (State == Begin) {
705 if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
706 Opt.support(Name);
707 }
708 Actions.setCurrentOpenCLExtension(Name);
709 } else if (State == End) {
710 if (Name != Actions.getCurrentOpenCLExtension())
711 PP.Diag(NameLoc, diag::warn_pragma_begin_end_mismatch);
712 Actions.setCurrentOpenCLExtension("");
713 } else if (!Opt.isKnown(Name))
714 PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
715 else if (Opt.isSupportedExtension(Name, getLangOpts()))
716 Opt.enable(Name, State == Enable);
717 else if (Opt.isSupportedCore(Name, getLangOpts()))
718 PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
719 else
720 PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
721}
722
723void Parser::HandlePragmaMSPointersToMembers() {
724 assert(Tok.is(tok::annot_pragma_ms_pointers_to_members))((Tok.is(tok::annot_pragma_ms_pointers_to_members)) ? static_cast
<void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_ms_pointers_to_members)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 724, __PRETTY_FUNCTION__))
;
725 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
726 static_cast<LangOptions::PragmaMSPointersToMembersKind>(
727 reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
728 SourceLocation PragmaLoc = ConsumeAnnotationToken();
729 Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
730}
731
732void Parser::HandlePragmaMSVtorDisp() {
733 assert(Tok.is(tok::annot_pragma_ms_vtordisp))((Tok.is(tok::annot_pragma_ms_vtordisp)) ? static_cast<void
> (0) : __assert_fail ("Tok.is(tok::annot_pragma_ms_vtordisp)"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 733, __PRETTY_FUNCTION__))
;
734 uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
735 Sema::PragmaMsStackAction Action =
736 static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
737 MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
738 SourceLocation PragmaLoc = ConsumeAnnotationToken();
739 Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
740}
741
742void Parser::HandlePragmaMSPragma() {
743 assert(Tok.is(tok::annot_pragma_ms_pragma))((Tok.is(tok::annot_pragma_ms_pragma)) ? static_cast<void>
(0) : __assert_fail ("Tok.is(tok::annot_pragma_ms_pragma)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 743, __PRETTY_FUNCTION__))
;
744 // Grab the tokens out of the annotation and enter them into the stream.
745 auto TheTokens =
746 (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue();
747 PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true,
748 /*IsReinject=*/true);
749 SourceLocation PragmaLocation = ConsumeAnnotationToken();
750 assert(Tok.isAnyIdentifier())((Tok.isAnyIdentifier()) ? static_cast<void> (0) : __assert_fail
("Tok.isAnyIdentifier()", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 750, __PRETTY_FUNCTION__))
;
751 StringRef PragmaName = Tok.getIdentifierInfo()->getName();
752 PP.Lex(Tok); // pragma kind
753
754 // Figure out which #pragma we're dealing with. The switch has no default
755 // because lex shouldn't emit the annotation token for unrecognized pragmas.
756 typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation);
757 PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName)
758 .Case("data_seg", &Parser::HandlePragmaMSSegment)
759 .Case("bss_seg", &Parser::HandlePragmaMSSegment)
760 .Case("const_seg", &Parser::HandlePragmaMSSegment)
761 .Case("code_seg", &Parser::HandlePragmaMSSegment)
762 .Case("section", &Parser::HandlePragmaMSSection)
763 .Case("init_seg", &Parser::HandlePragmaMSInitSeg);
764
765 if (!(this->*Handler)(PragmaName, PragmaLocation)) {
766 // Pragma handling failed, and has been diagnosed. Slurp up the tokens
767 // until eof (really end of line) to prevent follow-on errors.
768 while (Tok.isNot(tok::eof))
769 PP.Lex(Tok);
770 PP.Lex(Tok);
771 }
772}
773
774bool Parser::HandlePragmaMSSection(StringRef PragmaName,
775 SourceLocation PragmaLocation) {
776 if (Tok.isNot(tok::l_paren)) {
777 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
778 return false;
779 }
780 PP.Lex(Tok); // (
781 // Parsing code for pragma section
782 if (Tok.isNot(tok::string_literal)) {
783 PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name)
784 << PragmaName;
785 return false;
786 }
787 ExprResult StringResult = ParseStringLiteralExpression();
788 if (StringResult.isInvalid())
789 return false; // Already diagnosed.
790 StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get());
791 if (SegmentName->getCharByteWidth() != 1) {
792 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
793 << PragmaName;
794 return false;
795 }
796 int SectionFlags = ASTContext::PSF_Read;
797 bool SectionFlagsAreDefault = true;
798 while (Tok.is(tok::comma)) {
799 PP.Lex(Tok); // ,
800 // Ignore "long" and "short".
801 // They are undocumented, but widely used, section attributes which appear
802 // to do nothing.
803 if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) {
804 PP.Lex(Tok); // long/short
805 continue;
806 }
807
808 if (!Tok.isAnyIdentifier()) {
809 PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren)
810 << PragmaName;
811 return false;
812 }
813 ASTContext::PragmaSectionFlag Flag =
814 llvm::StringSwitch<ASTContext::PragmaSectionFlag>(
815 Tok.getIdentifierInfo()->getName())
816 .Case("read", ASTContext::PSF_Read)
817 .Case("write", ASTContext::PSF_Write)
818 .Case("execute", ASTContext::PSF_Execute)
819 .Case("shared", ASTContext::PSF_Invalid)
820 .Case("nopage", ASTContext::PSF_Invalid)
821 .Case("nocache", ASTContext::PSF_Invalid)
822 .Case("discard", ASTContext::PSF_Invalid)
823 .Case("remove", ASTContext::PSF_Invalid)
824 .Default(ASTContext::PSF_None);
825 if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) {
826 PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None
827 ? diag::warn_pragma_invalid_specific_action
828 : diag::warn_pragma_unsupported_action)
829 << PragmaName << Tok.getIdentifierInfo()->getName();
830 return false;
831 }
832 SectionFlags |= Flag;
833 SectionFlagsAreDefault = false;
834 PP.Lex(Tok); // Identifier
835 }
836 // If no section attributes are specified, the section will be marked as
837 // read/write.
838 if (SectionFlagsAreDefault)
839 SectionFlags |= ASTContext::PSF_Write;
840 if (Tok.isNot(tok::r_paren)) {
841 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
842 return false;
843 }
844 PP.Lex(Tok); // )
845 if (Tok.isNot(tok::eof)) {
846 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
847 << PragmaName;
848 return false;
849 }
850 PP.Lex(Tok); // eof
851 Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName);
852 return true;
853}
854
855bool Parser::HandlePragmaMSSegment(StringRef PragmaName,
856 SourceLocation PragmaLocation) {
857 if (Tok.isNot(tok::l_paren)) {
858 PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName;
859 return false;
860 }
861 PP.Lex(Tok); // (
862 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
863 StringRef SlotLabel;
864 if (Tok.isAnyIdentifier()) {
865 StringRef PushPop = Tok.getIdentifierInfo()->getName();
866 if (PushPop == "push")
867 Action = Sema::PSK_Push;
868 else if (PushPop == "pop")
869 Action = Sema::PSK_Pop;
870 else {
871 PP.Diag(PragmaLocation,
872 diag::warn_pragma_expected_section_push_pop_or_name)
873 << PragmaName;
874 return false;
875 }
876 if (Action != Sema::PSK_Reset) {
877 PP.Lex(Tok); // push | pop
878 if (Tok.is(tok::comma)) {
879 PP.Lex(Tok); // ,
880 // If we've got a comma, we either need a label or a string.
881 if (Tok.isAnyIdentifier()) {
882 SlotLabel = Tok.getIdentifierInfo()->getName();
883 PP.Lex(Tok); // identifier
884 if (Tok.is(tok::comma))
885 PP.Lex(Tok);
886 else if (Tok.isNot(tok::r_paren)) {
887 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc)
888 << PragmaName;
889 return false;
890 }
891 }
892 } else if (Tok.isNot(tok::r_paren)) {
893 PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName;
894 return false;
895 }
896 }
897 }
898 // Grab the string literal for our section name.
899 StringLiteral *SegmentName = nullptr;
900 if (Tok.isNot(tok::r_paren)) {
901 if (Tok.isNot(tok::string_literal)) {
902 unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ?
903 diag::warn_pragma_expected_section_name :
904 diag::warn_pragma_expected_section_label_or_name :
905 diag::warn_pragma_expected_section_push_pop_or_name;
906 PP.Diag(PragmaLocation, DiagID) << PragmaName;
907 return false;
908 }
909 ExprResult StringResult = ParseStringLiteralExpression();
910 if (StringResult.isInvalid())
911 return false; // Already diagnosed.
912 SegmentName = cast<StringLiteral>(StringResult.get());
913 if (SegmentName->getCharByteWidth() != 1) {
914 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
915 << PragmaName;
916 return false;
917 }
918 // Setting section "" has no effect
919 if (SegmentName->getLength())
920 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
921 }
922 if (Tok.isNot(tok::r_paren)) {
923 PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName;
924 return false;
925 }
926 PP.Lex(Tok); // )
927 if (Tok.isNot(tok::eof)) {
928 PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol)
929 << PragmaName;
930 return false;
931 }
932 PP.Lex(Tok); // eof
933 Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel,
934 SegmentName, PragmaName);
935 return true;
936}
937
938// #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )
939bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
940 SourceLocation PragmaLocation) {
941 if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) {
942 PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target);
943 return false;
944 }
945
946 if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
947 PragmaName))
948 return false;
949
950 // Parse either the known section names or the string section name.
951 StringLiteral *SegmentName = nullptr;
952 if (Tok.isAnyIdentifier()) {
953 auto *II = Tok.getIdentifierInfo();
954 StringRef Section = llvm::StringSwitch<StringRef>(II->getName())
955 .Case("compiler", "\".CRT$XCC\"")
956 .Case("lib", "\".CRT$XCL\"")
957 .Case("user", "\".CRT$XCU\"")
958 .Default("");
959
960 if (!Section.empty()) {
961 // Pretend the user wrote the appropriate string literal here.
962 Token Toks[1];
963 Toks[0].startToken();
964 Toks[0].setKind(tok::string_literal);
965 Toks[0].setLocation(Tok.getLocation());
966 Toks[0].setLiteralData(Section.data());
967 Toks[0].setLength(Section.size());
968 SegmentName =
969 cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get());
970 PP.Lex(Tok);
971 }
972 } else if (Tok.is(tok::string_literal)) {
973 ExprResult StringResult = ParseStringLiteralExpression();
974 if (StringResult.isInvalid())
975 return false;
976 SegmentName = cast<StringLiteral>(StringResult.get());
977 if (SegmentName->getCharByteWidth() != 1) {
978 PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string)
979 << PragmaName;
980 return false;
981 }
982 // FIXME: Add support for the '[, func-name]' part of the pragma.
983 }
984
985 if (!SegmentName) {
986 PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName;
987 return false;
988 }
989
990 if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
991 PragmaName) ||
992 ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
993 PragmaName))
994 return false;
995
996 Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName);
997 return true;
998}
999
1000namespace {
1001struct PragmaLoopHintInfo {
1002 Token PragmaName;
1003 Token Option;
1004 ArrayRef<Token> Toks;
1005};
1006} // end anonymous namespace
1007
1008static std::string PragmaLoopHintString(Token PragmaName, Token Option) {
1009 std::string PragmaString;
1010 if (PragmaName.getIdentifierInfo()->getName() == "loop") {
1011 PragmaString = "clang loop ";
1012 PragmaString += Option.getIdentifierInfo()->getName();
1013 } else if (PragmaName.getIdentifierInfo()->getName() == "unroll_and_jam") {
1014 PragmaString = "unroll_and_jam";
1015 } else {
1016 assert(PragmaName.getIdentifierInfo()->getName() == "unroll" &&((PragmaName.getIdentifierInfo()->getName() == "unroll" &&
"Unexpected pragma name") ? static_cast<void> (0) : __assert_fail
("PragmaName.getIdentifierInfo()->getName() == \"unroll\" && \"Unexpected pragma name\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1017, __PRETTY_FUNCTION__))
1017 "Unexpected pragma name")((PragmaName.getIdentifierInfo()->getName() == "unroll" &&
"Unexpected pragma name") ? static_cast<void> (0) : __assert_fail
("PragmaName.getIdentifierInfo()->getName() == \"unroll\" && \"Unexpected pragma name\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1017, __PRETTY_FUNCTION__))
;
1018 PragmaString = "unroll";
1019 }
1020 return PragmaString;
1021}
1022
1023bool Parser::HandlePragmaLoopHint(LoopHint &Hint) {
1024 assert(Tok.is(tok::annot_pragma_loop_hint))((Tok.is(tok::annot_pragma_loop_hint)) ? static_cast<void>
(0) : __assert_fail ("Tok.is(tok::annot_pragma_loop_hint)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1024, __PRETTY_FUNCTION__))
;
1025 PragmaLoopHintInfo *Info =
1026 static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue());
1027
1028 IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo();
1029 Hint.PragmaNameLoc = IdentifierLoc::create(
1030 Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo);
1031
1032 // It is possible that the loop hint has no option identifier, such as
1033 // #pragma unroll(4).
1034 IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier)
1035 ? Info->Option.getIdentifierInfo()
1036 : nullptr;
1037 Hint.OptionLoc = IdentifierLoc::create(
1038 Actions.Context, Info->Option.getLocation(), OptionInfo);
1039
1040 llvm::ArrayRef<Token> Toks = Info->Toks;
1041
1042 // Return a valid hint if pragma unroll or nounroll were specified
1043 // without an argument.
1044 bool PragmaUnroll = PragmaNameInfo->getName() == "unroll";
1045 bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll";
1046 bool PragmaUnrollAndJam = PragmaNameInfo->getName() == "unroll_and_jam";
1047 bool PragmaNoUnrollAndJam = PragmaNameInfo->getName() == "nounroll_and_jam";
1048 if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll || PragmaUnrollAndJam ||
1049 PragmaNoUnrollAndJam)) {
1050 ConsumeAnnotationToken();
1051 Hint.Range = Info->PragmaName.getLocation();
1052 return true;
1053 }
1054
1055 // The constant expression is always followed by an eof token, which increases
1056 // the TokSize by 1.
1057 assert(!Toks.empty() &&((!Toks.empty() && "PragmaLoopHintInfo::Toks must contain at least one token."
) ? static_cast<void> (0) : __assert_fail ("!Toks.empty() && \"PragmaLoopHintInfo::Toks must contain at least one token.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1058, __PRETTY_FUNCTION__))
1058 "PragmaLoopHintInfo::Toks must contain at least one token.")((!Toks.empty() && "PragmaLoopHintInfo::Toks must contain at least one token."
) ? static_cast<void> (0) : __assert_fail ("!Toks.empty() && \"PragmaLoopHintInfo::Toks must contain at least one token.\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1058, __PRETTY_FUNCTION__))
;
1059
1060 // If no option is specified the argument is assumed to be a constant expr.
1061 bool OptionUnroll = false;
1062 bool OptionUnrollAndJam = false;
1063 bool OptionDistribute = false;
1064 bool OptionPipelineDisabled = false;
1065 bool StateOption = false;
1066 if (OptionInfo) { // Pragma Unroll does not specify an option.
1067 OptionUnroll = OptionInfo->isStr("unroll");
1068 OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
1069 OptionDistribute = OptionInfo->isStr("distribute");
1070 OptionPipelineDisabled = OptionInfo->isStr("pipeline");
1071 StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
1072 .Case("vectorize", true)
1073 .Case("interleave", true)
1074 .Default(false) ||
1075 OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
1076 OptionPipelineDisabled;
1077 }
1078
1079 bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
1080 !OptionDistribute && !OptionPipelineDisabled;
1081 // Verify loop hint has an argument.
1082 if (Toks[0].is(tok::eof)) {
1083 ConsumeAnnotationToken();
1084 Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument)
1085 << /*StateArgument=*/StateOption
1086 << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
1087 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1088 return false;
1089 }
1090
1091 // Validate the argument.
1092 if (StateOption) {
1093 ConsumeAnnotationToken();
1094 SourceLocation StateLoc = Toks[0].getLocation();
1095 IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
1096
1097 bool Valid = StateInfo &&
1098 llvm::StringSwitch<bool>(StateInfo->getName())
1099 .Case("disable", true)
1100 .Case("enable", !OptionPipelineDisabled)
1101 .Case("full", OptionUnroll || OptionUnrollAndJam)
1102 .Case("assume_safety", AssumeSafetyArg)
1103 .Default(false);
1104 if (!Valid) {
1105 if (OptionPipelineDisabled) {
1106 Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
1107 } else {
1108 Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
1109 << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
1110 << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
1111 }
1112 return false;
1113 }
1114 if (Toks.size() > 2)
1115 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1116 << PragmaLoopHintString(Info->PragmaName, Info->Option);
1117 Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo);
1118 } else {
1119 // Enter constant expression including eof terminator into token stream.
1120 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false,
1121 /*IsReinject=*/false);
1122 ConsumeAnnotationToken();
1123
1124 ExprResult R = ParseConstantExpression();
1125
1126 // Tokens following an error in an ill-formed constant expression will
1127 // remain in the token stream and must be removed.
1128 if (Tok.isNot(tok::eof)) {
1129 Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1130 << PragmaLoopHintString(Info->PragmaName, Info->Option);
1131 while (Tok.isNot(tok::eof))
1132 ConsumeAnyToken();
1133 }
1134
1135 ConsumeToken(); // Consume the constant expression eof terminator.
1136
1137 if (R.isInvalid() ||
1138 Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation()))
1139 return false;
1140
1141 // Argument is a constant expression with an integer type.
1142 Hint.ValueExpr = R.get();
1143 }
1144
1145 Hint.Range = SourceRange(Info->PragmaName.getLocation(),
1146 Info->Toks.back().getLocation());
1147 return true;
1148}
1149
1150namespace {
1151struct PragmaAttributeInfo {
1152 enum ActionType { Push, Pop, Attribute };
1153 ParsedAttributes &Attributes;
1154 ActionType Action;
1155 const IdentifierInfo *Namespace = nullptr;
1156 ArrayRef<Token> Tokens;
1157
1158 PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
1159};
1160
1161#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
1162
1163} // end anonymous namespace
1164
1165static StringRef getIdentifier(const Token &Tok) {
1166 if (Tok.is(tok::identifier))
1167 return Tok.getIdentifierInfo()->getName();
1168 const char *S = tok::getKeywordSpelling(Tok.getKind());
1169 if (!S)
1170 return "";
1171 return S;
1172}
1173
1174static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
1175 using namespace attr;
1176 switch (Rule) {
1177#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) \
1178 case Value: \
1179 return IsAbstract;
1180#include "clang/Basic/AttrSubMatchRulesList.inc"
1181 }
1182 llvm_unreachable("Invalid attribute subject match rule")::llvm::llvm_unreachable_internal("Invalid attribute subject match rule"
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1182)
;
1183 return false;
1184}
1185
1186static void diagnoseExpectedAttributeSubjectSubRule(
1187 Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1188 SourceLocation SubRuleLoc) {
1189 auto Diagnostic =
1190 PRef.Diag(SubRuleLoc,
1191 diag::err_pragma_attribute_expected_subject_sub_identifier)
1192 << PrimaryRuleName;
1193 if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1194 Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1195 else
1196 Diagnostic << /*SubRulesSupported=*/0;
1197}
1198
1199static void diagnoseUnknownAttributeSubjectSubRule(
1200 Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
1201 StringRef SubRuleName, SourceLocation SubRuleLoc) {
1202
1203 auto Diagnostic =
1204 PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
1205 << SubRuleName << PrimaryRuleName;
1206 if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
1207 Diagnostic << /*SubRulesSupported=*/1 << SubRules;
1208 else
1209 Diagnostic << /*SubRulesSupported=*/0;
1210}
1211
1212bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
1213 attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
1214 SourceLocation &LastMatchRuleEndLoc) {
1215 bool IsAny = false;
1216 BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
1217 if (getIdentifier(Tok) == "any") {
1218 AnyLoc = ConsumeToken();
1219 IsAny = true;
1220 if (AnyParens.expectAndConsume())
1221 return true;
1222 }
1223
1224 do {
1225 // Parse the subject matcher rule.
1226 StringRef Name = getIdentifier(Tok);
1227 if (Name.empty()) {
1228 Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
1229 return true;
1230 }
1231 std::pair<Optional<attr::SubjectMatchRule>,
1232 Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
1233 Rule = isAttributeSubjectMatchRule(Name);
1234 if (!Rule.first) {
1235 Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
1236 return true;
1237 }
1238 attr::SubjectMatchRule PrimaryRule = *Rule.first;
1239 SourceLocation RuleLoc = ConsumeToken();
1240
1241 BalancedDelimiterTracker Parens(*this, tok::l_paren);
1242 if (isAbstractAttrMatcherRule(PrimaryRule)) {
1243 if (Parens.expectAndConsume())
1244 return true;
1245 } else if (Parens.consumeOpen()) {
1246 if (!SubjectMatchRules
1247 .insert(
1248 std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
1249 .second)
1250 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1251 << Name
1252 << FixItHint::CreateRemoval(SourceRange(
1253 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
1254 LastMatchRuleEndLoc = RuleLoc;
1255 continue;
1256 }
1257
1258 // Parse the sub-rules.
1259 StringRef SubRuleName = getIdentifier(Tok);
1260 if (SubRuleName.empty()) {
1261 diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1262 Tok.getLocation());
1263 return true;
1264 }
1265 attr::SubjectMatchRule SubRule;
1266 if (SubRuleName == "unless") {
1267 SourceLocation SubRuleLoc = ConsumeToken();
1268 BalancedDelimiterTracker Parens(*this, tok::l_paren);
1269 if (Parens.expectAndConsume())
1270 return true;
1271 SubRuleName = getIdentifier(Tok);
1272 if (SubRuleName.empty()) {
1273 diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
1274 SubRuleLoc);
1275 return true;
1276 }
1277 auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
1278 if (!SubRuleOrNone) {
1279 std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
1280 diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1281 SubRuleUnlessName, SubRuleLoc);
1282 return true;
1283 }
1284 SubRule = *SubRuleOrNone;
1285 ConsumeToken();
1286 if (Parens.consumeClose())
1287 return true;
1288 } else {
1289 auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
1290 if (!SubRuleOrNone) {
1291 diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
1292 SubRuleName, Tok.getLocation());
1293 return true;
1294 }
1295 SubRule = *SubRuleOrNone;
1296 ConsumeToken();
1297 }
1298 SourceLocation RuleEndLoc = Tok.getLocation();
1299 LastMatchRuleEndLoc = RuleEndLoc;
1300 if (Parens.consumeClose())
1301 return true;
1302 if (!SubjectMatchRules
1303 .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
1304 .second) {
1305 Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
1306 << attr::getSubjectMatchRuleSpelling(SubRule)
1307 << FixItHint::CreateRemoval(SourceRange(
1308 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
1309 continue;
1310 }
1311 } while (IsAny && TryConsumeToken(tok::comma));
1312
1313 if (IsAny)
1314 if (AnyParens.consumeClose())
1315 return true;
1316
1317 return false;
1318}
1319
1320namespace {
1321
1322/// Describes the stage at which attribute subject rule parsing was interrupted.
1323enum class MissingAttributeSubjectRulesRecoveryPoint {
1324 Comma,
1325 ApplyTo,
1326 Equals,
1327 Any,
1328 None,
1329};
1330
1331MissingAttributeSubjectRulesRecoveryPoint
1332getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
1333 if (const auto *II = Tok.getIdentifierInfo()) {
1334 if (II->isStr("apply_to"))
1335 return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
1336 if (II->isStr("any"))
1337 return MissingAttributeSubjectRulesRecoveryPoint::Any;
1338 }
1339 if (Tok.is(tok::equal))
1340 return MissingAttributeSubjectRulesRecoveryPoint::Equals;
1341 return MissingAttributeSubjectRulesRecoveryPoint::None;
1342}
1343
1344/// Creates a diagnostic for the attribute subject rule parsing diagnostic that
1345/// suggests the possible attribute subject rules in a fix-it together with
1346/// any other missing tokens.
1347DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
1348 unsigned DiagID, ParsedAttr &Attribute,
1349 MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
1350 SourceLocation Loc = PRef.getEndOfPreviousToken();
1351 if (Loc.isInvalid())
1352 Loc = PRef.getCurToken().getLocation();
1353 auto Diagnostic = PRef.Diag(Loc, DiagID);
1354 std::string FixIt;
1355 MissingAttributeSubjectRulesRecoveryPoint EndPoint =
1356 getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
1357 if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
1358 FixIt = ", ";
1359 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
1360 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
1361 FixIt += "apply_to";
1362 if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
1363 EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
1364 FixIt += " = ";
1365 SourceRange FixItRange(Loc);
1366 if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
1367 // Gather the subject match rules that are supported by the attribute.
1368 SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
1369 Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
1370 if (SubjectMatchRuleSet.empty()) {
1371 // FIXME: We can emit a "fix-it" with a subject list placeholder when
1372 // placeholders will be supported by the fix-its.
1373 return Diagnostic;
1374 }
1375 FixIt += "any(";
1376 bool NeedsComma = false;
1377 for (const auto &I : SubjectMatchRuleSet) {
1378 // Ensure that the missing rule is reported in the fix-it only when it's
1379 // supported in the current language mode.
1380 if (!I.second)
1381 continue;
1382 if (NeedsComma)
1383 FixIt += ", ";
1384 else
1385 NeedsComma = true;
1386 FixIt += attr::getSubjectMatchRuleSpelling(I.first);
1387 }
1388 FixIt += ")";
1389 // Check if we need to remove the range
1390 PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
1391 FixItRange.setEnd(PRef.getCurToken().getLocation());
1392 }
1393 if (FixItRange.getBegin() == FixItRange.getEnd())
1394 Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
1395 else
1396 Diagnostic << FixItHint::CreateReplacement(
1397 CharSourceRange::getCharRange(FixItRange), FixIt);
1398 return Diagnostic;
1399}
1400
1401} // end anonymous namespace
1402
1403void Parser::HandlePragmaAttribute() {
1404 assert(Tok.is(tok::annot_pragma_attribute) &&((Tok.is(tok::annot_pragma_attribute) && "Expected #pragma attribute annotation token"
) ? static_cast<void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_attribute) && \"Expected #pragma attribute annotation token\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1405, __PRETTY_FUNCTION__))
1405 "Expected #pragma attribute annotation token")((Tok.is(tok::annot_pragma_attribute) && "Expected #pragma attribute annotation token"
) ? static_cast<void> (0) : __assert_fail ("Tok.is(tok::annot_pragma_attribute) && \"Expected #pragma attribute annotation token\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1405, __PRETTY_FUNCTION__))
;
1406 SourceLocation PragmaLoc = Tok.getLocation();
1407 auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
1408 if (Info->Action == PragmaAttributeInfo::Pop) {
1409 ConsumeAnnotationToken();
1410 Actions.ActOnPragmaAttributePop(PragmaLoc, Info->Namespace);
1411 return;
1412 }
1413 // Parse the actual attribute with its arguments.
1414 assert((Info->Action == PragmaAttributeInfo::Push ||(((Info->Action == PragmaAttributeInfo::Push || Info->Action
== PragmaAttributeInfo::Attribute) && "Unexpected #pragma attribute command"
) ? static_cast<void> (0) : __assert_fail ("(Info->Action == PragmaAttributeInfo::Push || Info->Action == PragmaAttributeInfo::Attribute) && \"Unexpected #pragma attribute command\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1416, __PRETTY_FUNCTION__))
1415 Info->Action == PragmaAttributeInfo::Attribute) &&(((Info->Action == PragmaAttributeInfo::Push || Info->Action
== PragmaAttributeInfo::Attribute) && "Unexpected #pragma attribute command"
) ? static_cast<void> (0) : __assert_fail ("(Info->Action == PragmaAttributeInfo::Push || Info->Action == PragmaAttributeInfo::Attribute) && \"Unexpected #pragma attribute command\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1416, __PRETTY_FUNCTION__))
1416 "Unexpected #pragma attribute command")(((Info->Action == PragmaAttributeInfo::Push || Info->Action
== PragmaAttributeInfo::Attribute) && "Unexpected #pragma attribute command"
) ? static_cast<void> (0) : __assert_fail ("(Info->Action == PragmaAttributeInfo::Push || Info->Action == PragmaAttributeInfo::Attribute) && \"Unexpected #pragma attribute command\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1416, __PRETTY_FUNCTION__))
;
1417
1418 if (Info->Action == PragmaAttributeInfo::Push && Info->Tokens.empty()) {
1419 ConsumeAnnotationToken();
1420 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1421 return;
1422 }
1423
1424 PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false,
1425 /*IsReinject=*/false);
1426 ConsumeAnnotationToken();
1427
1428 ParsedAttributes &Attrs = Info->Attributes;
1429 Attrs.clearListOnly();
1430
1431 auto SkipToEnd = [this]() {
1432 SkipUntil(tok::eof, StopBeforeMatch);
1433 ConsumeToken();
1434 };
1435
1436 if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
1437 // Parse the CXX11 style attribute.
1438 ParseCXX11AttributeSpecifier(Attrs);
1439 } else if (Tok.is(tok::kw___attribute)) {
1440 ConsumeToken();
1441 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
1442 "attribute"))
1443 return SkipToEnd();
1444 if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
1445 return SkipToEnd();
1446
1447 if (Tok.isNot(tok::identifier)) {
1448 Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
1449 SkipToEnd();
1450 return;
1451 }
1452 IdentifierInfo *AttrName = Tok.getIdentifierInfo();
1453 SourceLocation AttrNameLoc = ConsumeToken();
1454
1455 if (Tok.isNot(tok::l_paren))
1456 Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
1457 ParsedAttr::AS_GNU);
1458 else
1459 ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
1460 /*ScopeName=*/nullptr,
1461 /*ScopeLoc=*/SourceLocation(), ParsedAttr::AS_GNU,
1462 /*Declarator=*/nullptr);
1463
1464 if (ExpectAndConsume(tok::r_paren))
1465 return SkipToEnd();
1466 if (ExpectAndConsume(tok::r_paren))
1467 return SkipToEnd();
1468 } else if (Tok.is(tok::kw___declspec)) {
1469 ParseMicrosoftDeclSpecs(Attrs);
1470 } else {
1471 Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
1472 if (Tok.getIdentifierInfo()) {
1473 // If we suspect that this is an attribute suggest the use of
1474 // '__attribute__'.
1475 if (ParsedAttr::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
1476 ParsedAttr::AS_GNU) !=
1477 ParsedAttr::UnknownAttribute) {
1478 SourceLocation InsertStartLoc = Tok.getLocation();
1479 ConsumeToken();
1480 if (Tok.is(tok::l_paren)) {
1481 ConsumeAnyToken();
1482 SkipUntil(tok::r_paren, StopBeforeMatch);
1483 if (Tok.isNot(tok::r_paren))
1484 return SkipToEnd();
1485 }
1486 Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
1487 << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
1488 << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
1489 }
1490 }
1491 SkipToEnd();
1492 return;
1493 }
1494
1495 if (Attrs.empty() || Attrs.begin()->isInvalid()) {
1496 SkipToEnd();
1497 return;
1498 }
1499
1500 // Ensure that we don't have more than one attribute.
1501 if (Attrs.size() > 1) {
1502 SourceLocation Loc = Attrs[1].getLoc();
1503 Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
1504 SkipToEnd();
1505 return;
1506 }
1507
1508 ParsedAttr &Attribute = *Attrs.begin();
1509 if (!Attribute.isSupportedByPragmaAttribute()) {
1510 Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
1511 << Attribute.getName();
1512 SkipToEnd();
1513 return;
1514 }
1515
1516 // Parse the subject-list.
1517 if (!TryConsumeToken(tok::comma)) {
1518 createExpectedAttributeSubjectRulesTokenDiagnostic(
1519 diag::err_expected, Attribute,
1520 MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
1521 << tok::comma;
1522 SkipToEnd();
1523 return;
1524 }
1525
1526 if (Tok.isNot(tok::identifier)) {
1527 createExpectedAttributeSubjectRulesTokenDiagnostic(
1528 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1529 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1530 SkipToEnd();
1531 return;
1532 }
1533 const IdentifierInfo *II = Tok.getIdentifierInfo();
1534 if (!II->isStr("apply_to")) {
1535 createExpectedAttributeSubjectRulesTokenDiagnostic(
1536 diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
1537 MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
1538 SkipToEnd();
1539 return;
1540 }
1541 ConsumeToken();
1542
1543 if (!TryConsumeToken(tok::equal)) {
1544 createExpectedAttributeSubjectRulesTokenDiagnostic(
1545 diag::err_expected, Attribute,
1546 MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
1547 << tok::equal;
1548 SkipToEnd();
1549 return;
1550 }
1551
1552 attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
1553 SourceLocation AnyLoc, LastMatchRuleEndLoc;
1554 if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
1555 LastMatchRuleEndLoc)) {
1556 SkipToEnd();
1557 return;
1558 }
1559
1560 // Tokens following an ill-formed attribute will remain in the token stream
1561 // and must be removed.
1562 if (Tok.isNot(tok::eof)) {
1563 Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
1564 SkipToEnd();
1565 return;
1566 }
1567
1568 // Consume the eof terminator token.
1569 ConsumeToken();
1570
1571 // Handle a mixed push/attribute by desurging to a push, then an attribute.
1572 if (Info->Action == PragmaAttributeInfo::Push)
1573 Actions.ActOnPragmaAttributeEmptyPush(PragmaLoc, Info->Namespace);
1574
1575 Actions.ActOnPragmaAttributeAttribute(Attribute, PragmaLoc,
1576 std::move(SubjectMatchRules));
1577}
1578
1579// #pragma GCC visibility comes in two variants:
1580// 'push' '(' [visibility] ')'
1581// 'pop'
1582void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
1583 PragmaIntroducer Introducer,
1584 Token &VisTok) {
1585 SourceLocation VisLoc = VisTok.getLocation();
1586
1587 Token Tok;
1588 PP.LexUnexpandedToken(Tok);
1589
1590 const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
1591
1592 const IdentifierInfo *VisType;
1593 if (PushPop && PushPop->isStr("pop")) {
1594 VisType = nullptr;
1595 } else if (PushPop && PushPop->isStr("push")) {
1596 PP.LexUnexpandedToken(Tok);
1597 if (Tok.isNot(tok::l_paren)) {
1598 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
1599 << "visibility";
1600 return;
1601 }
1602 PP.LexUnexpandedToken(Tok);
1603 VisType = Tok.getIdentifierInfo();
1604 if (!VisType) {
1605 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1606 << "visibility";
1607 return;
1608 }
1609 PP.LexUnexpandedToken(Tok);
1610 if (Tok.isNot(tok::r_paren)) {
1611 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
1612 << "visibility";
1613 return;
1614 }
1615 } else {
1616 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1617 << "visibility";
1618 return;
1619 }
1620 SourceLocation EndLoc = Tok.getLocation();
1621 PP.LexUnexpandedToken(Tok);
1622 if (Tok.isNot(tok::eod)) {
1623 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1624 << "visibility";
1625 return;
1626 }
1627
1628 auto Toks = llvm::make_unique<Token[]>(1);
1629 Toks[0].startToken();
1630 Toks[0].setKind(tok::annot_pragma_vis);
1631 Toks[0].setLocation(VisLoc);
1632 Toks[0].setAnnotationEndLoc(EndLoc);
1633 Toks[0].setAnnotationValue(
1634 const_cast<void *>(static_cast<const void *>(VisType)));
1635 PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true,
1636 /*IsReinject=*/false);
1637}
1638
1639// #pragma pack(...) comes in the following delicious flavors:
1640// pack '(' [integer] ')'
1641// pack '(' 'show' ')'
1642// pack '(' ('push' | 'pop') [',' identifier] [, integer] ')'
1643void PragmaPackHandler::HandlePragma(Preprocessor &PP,
1644 PragmaIntroducer Introducer,
1645 Token &PackTok) {
1646 SourceLocation PackLoc = PackTok.getLocation();
1647
1648 Token Tok;
1649 PP.Lex(Tok);
1650 if (Tok.isNot(tok::l_paren)) {
1651 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack";
1652 return;
1653 }
1654
1655 Sema::PragmaMsStackAction Action = Sema::PSK_Reset;
1656 StringRef SlotLabel;
1657 Token Alignment;
1658 Alignment.startToken();
1659 PP.Lex(Tok);
1660 if (Tok.is(tok::numeric_constant)) {
1661 Alignment = Tok;
1662
1663 PP.Lex(Tok);
1664
1665 // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
1666 // the push/pop stack.
1667 // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
1668 Action =
1669 PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set;
1670 } else if (Tok.is(tok::identifier)) {
1671 const IdentifierInfo *II = Tok.getIdentifierInfo();
1672 if (II->isStr("show")) {
1673 Action = Sema::PSK_Show;
1674 PP.Lex(Tok);
1675 } else {
1676 if (II->isStr("push")) {
1677 Action = Sema::PSK_Push;
1678 } else if (II->isStr("pop")) {
1679 Action = Sema::PSK_Pop;
1680 } else {
1681 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack";
1682 return;
1683 }
1684 PP.Lex(Tok);
1685
1686 if (Tok.is(tok::comma)) {
1687 PP.Lex(Tok);
1688
1689 if (Tok.is(tok::numeric_constant)) {
1690 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1691 Alignment = Tok;
1692
1693 PP.Lex(Tok);
1694 } else if (Tok.is(tok::identifier)) {
1695 SlotLabel = Tok.getIdentifierInfo()->getName();
1696 PP.Lex(Tok);
1697
1698 if (Tok.is(tok::comma)) {
1699 PP.Lex(Tok);
1700
1701 if (Tok.isNot(tok::numeric_constant)) {
1702 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1703 return;
1704 }
1705
1706 Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set);
1707 Alignment = Tok;
1708
1709 PP.Lex(Tok);
1710 }
1711 } else {
1712 PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed);
1713 return;
1714 }
1715 }
1716 }
1717 } else if (PP.getLangOpts().ApplePragmaPack) {
1718 // In MSVC/gcc, #pragma pack() resets the alignment without affecting
1719 // the push/pop stack.
1720 // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
1721 Action = Sema::PSK_Pop;
1722 }
1723
1724 if (Tok.isNot(tok::r_paren)) {
1725 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack";
1726 return;
1727 }
1728
1729 SourceLocation RParenLoc = Tok.getLocation();
1730 PP.Lex(Tok);
1731 if (Tok.isNot(tok::eod)) {
1732 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack";
1733 return;
1734 }
1735
1736 PragmaPackInfo *Info =
1737 PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1);
1738 Info->Action = Action;
1739 Info->SlotLabel = SlotLabel;
1740 Info->Alignment = Alignment;
1741
1742 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1743 1);
1744 Toks[0].startToken();
1745 Toks[0].setKind(tok::annot_pragma_pack);
1746 Toks[0].setLocation(PackLoc);
1747 Toks[0].setAnnotationEndLoc(RParenLoc);
1748 Toks[0].setAnnotationValue(static_cast<void*>(Info));
1749 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1750 /*IsReinject=*/false);
1751}
1752
1753// #pragma ms_struct on
1754// #pragma ms_struct off
1755void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
1756 PragmaIntroducer Introducer,
1757 Token &MSStructTok) {
1758 PragmaMSStructKind Kind = PMSST_OFF;
1759
1760 Token Tok;
1761 PP.Lex(Tok);
1762 if (Tok.isNot(tok::identifier)) {
1763 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1764 return;
1765 }
1766 SourceLocation EndLoc = Tok.getLocation();
1767 const IdentifierInfo *II = Tok.getIdentifierInfo();
1768 if (II->isStr("on")) {
1769 Kind = PMSST_ON;
1770 PP.Lex(Tok);
1771 }
1772 else if (II->isStr("off") || II->isStr("reset"))
1773 PP.Lex(Tok);
1774 else {
1775 PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct);
1776 return;
1777 }
1778
1779 if (Tok.isNot(tok::eod)) {
1780 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1781 << "ms_struct";
1782 return;
1783 }
1784
1785 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1786 1);
1787 Toks[0].startToken();
1788 Toks[0].setKind(tok::annot_pragma_msstruct);
1789 Toks[0].setLocation(MSStructTok.getLocation());
1790 Toks[0].setAnnotationEndLoc(EndLoc);
1791 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1792 static_cast<uintptr_t>(Kind)));
1793 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1794 /*IsReinject=*/false);
1795}
1796
1797// #pragma clang section bss="abc" data="" rodata="def" text=""
1798void PragmaClangSectionHandler::HandlePragma(Preprocessor &PP,
1799 PragmaIntroducer Introducer,
1800 Token &FirstToken) {
1801
1802 Token Tok;
1803 auto SecKind = Sema::PragmaClangSectionKind::PCSK_Invalid;
1804
1805 PP.Lex(Tok); // eat 'section'
1806 while (Tok.isNot(tok::eod)) {
1807 if (Tok.isNot(tok::identifier)) {
1808 PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1809 return;
1810 }
1811
1812 const IdentifierInfo *SecType = Tok.getIdentifierInfo();
1813 if (SecType->isStr("bss"))
1814 SecKind = Sema::PragmaClangSectionKind::PCSK_BSS;
1815 else if (SecType->isStr("data"))
1816 SecKind = Sema::PragmaClangSectionKind::PCSK_Data;
1817 else if (SecType->isStr("rodata"))
1818 SecKind = Sema::PragmaClangSectionKind::PCSK_Rodata;
1819 else if (SecType->isStr("text"))
1820 SecKind = Sema::PragmaClangSectionKind::PCSK_Text;
1821 else {
1822 PP.Diag(Tok.getLocation(), diag::err_pragma_expected_clang_section_name) << "clang section";
1823 return;
1824 }
1825
1826 PP.Lex(Tok); // eat ['bss'|'data'|'rodata'|'text']
1827 if (Tok.isNot(tok::equal)) {
1828 PP.Diag(Tok.getLocation(), diag::err_pragma_clang_section_expected_equal) << SecKind;
1829 return;
1830 }
1831
1832 std::string SecName;
1833 if (!PP.LexStringLiteral(Tok, SecName, "pragma clang section", false))
1834 return;
1835
1836 Actions.ActOnPragmaClangSection(Tok.getLocation(),
1837 (SecName.size()? Sema::PragmaClangSectionAction::PCSA_Set :
1838 Sema::PragmaClangSectionAction::PCSA_Clear),
1839 SecKind, SecName);
1840 }
1841}
1842
1843// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
1844// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
1845static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
1846 bool IsOptions) {
1847 Token Tok;
1848
1849 if (IsOptions) {
1850 PP.Lex(Tok);
1851 if (Tok.isNot(tok::identifier) ||
1852 !Tok.getIdentifierInfo()->isStr("align")) {
1853 PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align);
1854 return;
1855 }
1856 }
1857
1858 PP.Lex(Tok);
1859 if (Tok.isNot(tok::equal)) {
1860 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal)
1861 << IsOptions;
1862 return;
1863 }
1864
1865 PP.Lex(Tok);
1866 if (Tok.isNot(tok::identifier)) {
1867 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
1868 << (IsOptions ? "options" : "align");
1869 return;
1870 }
1871
1872 Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural;
1873 const IdentifierInfo *II = Tok.getIdentifierInfo();
1874 if (II->isStr("native"))
1875 Kind = Sema::POAK_Native;
1876 else if (II->isStr("natural"))
1877 Kind = Sema::POAK_Natural;
1878 else if (II->isStr("packed"))
1879 Kind = Sema::POAK_Packed;
1880 else if (II->isStr("power"))
1881 Kind = Sema::POAK_Power;
1882 else if (II->isStr("mac68k"))
1883 Kind = Sema::POAK_Mac68k;
1884 else if (II->isStr("reset"))
1885 Kind = Sema::POAK_Reset;
1886 else {
1887 PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option)
1888 << IsOptions;
1889 return;
1890 }
1891
1892 SourceLocation EndLoc = Tok.getLocation();
1893 PP.Lex(Tok);
1894 if (Tok.isNot(tok::eod)) {
1895 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
1896 << (IsOptions ? "options" : "align");
1897 return;
1898 }
1899
1900 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
1901 1);
1902 Toks[0].startToken();
1903 Toks[0].setKind(tok::annot_pragma_align);
1904 Toks[0].setLocation(FirstTok.getLocation());
1905 Toks[0].setAnnotationEndLoc(EndLoc);
1906 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
1907 static_cast<uintptr_t>(Kind)));
1908 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1909 /*IsReinject=*/false);
1910}
1911
1912void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
1913 PragmaIntroducer Introducer,
1914 Token &AlignTok) {
1915 ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
1916}
1917
1918void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
1919 PragmaIntroducer Introducer,
1920 Token &OptionsTok) {
1921 ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
1922}
1923
1924// #pragma unused(identifier)
1925void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
1926 PragmaIntroducer Introducer,
1927 Token &UnusedTok) {
1928 // FIXME: Should we be expanding macros here? My guess is no.
1929 SourceLocation UnusedLoc = UnusedTok.getLocation();
1930
1931 // Lex the left '('.
1932 Token Tok;
1933 PP.Lex(Tok);
1934 if (Tok.isNot(tok::l_paren)) {
1935 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused";
1936 return;
1937 }
1938
1939 // Lex the declaration reference(s).
1940 SmallVector<Token, 5> Identifiers;
1941 SourceLocation RParenLoc;
1942 bool LexID = true;
1943
1944 while (true) {
1945 PP.Lex(Tok);
1946
1947 if (LexID) {
1948 if (Tok.is(tok::identifier)) {
1949 Identifiers.push_back(Tok);
1950 LexID = false;
1951 continue;
1952 }
1953
1954 // Illegal token!
1955 PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var);
1956 return;
1957 }
1958
1959 // We are execting a ')' or a ','.
1960 if (Tok.is(tok::comma)) {
1961 LexID = true;
1962 continue;
1963 }
1964
1965 if (Tok.is(tok::r_paren)) {
1966 RParenLoc = Tok.getLocation();
1967 break;
1968 }
1969
1970 // Illegal token!
1971 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused";
1972 return;
1973 }
1974
1975 PP.Lex(Tok);
1976 if (Tok.isNot(tok::eod)) {
1977 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
1978 "unused";
1979 return;
1980 }
1981
1982 // Verify that we have a location for the right parenthesis.
1983 assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'")((RParenLoc.isValid() && "Valid '#pragma unused' must have ')'"
) ? static_cast<void> (0) : __assert_fail ("RParenLoc.isValid() && \"Valid '#pragma unused' must have ')'\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1983, __PRETTY_FUNCTION__))
;
1984 assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments")((!Identifiers.empty() && "Valid '#pragma unused' must have arguments"
) ? static_cast<void> (0) : __assert_fail ("!Identifiers.empty() && \"Valid '#pragma unused' must have arguments\""
, "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 1984, __PRETTY_FUNCTION__))
;
1985
1986 // For each identifier token, insert into the token stream a
1987 // annot_pragma_unused token followed by the identifier token.
1988 // This allows us to cache a "#pragma unused" that occurs inside an inline
1989 // C++ member function.
1990
1991 MutableArrayRef<Token> Toks(
1992 PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()),
1993 2 * Identifiers.size());
1994 for (unsigned i=0; i != Identifiers.size(); i++) {
1995 Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1];
1996 pragmaUnusedTok.startToken();
1997 pragmaUnusedTok.setKind(tok::annot_pragma_unused);
1998 pragmaUnusedTok.setLocation(UnusedLoc);
1999 idTok = Identifiers[i];
2000 }
2001 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2002 /*IsReinject=*/false);
2003}
2004
2005// #pragma weak identifier
2006// #pragma weak identifier '=' identifier
2007void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
2008 PragmaIntroducer Introducer,
2009 Token &WeakTok) {
2010 SourceLocation WeakLoc = WeakTok.getLocation();
2011
2012 Token Tok;
2013 PP.Lex(Tok);
2014 if (Tok.isNot(tok::identifier)) {
2015 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak";
2016 return;
2017 }
2018
2019 Token WeakName = Tok;
2020 bool HasAlias = false;
2021 Token AliasName;
2022
2023 PP.Lex(Tok);
2024 if (Tok.is(tok::equal)) {
2025 HasAlias = true;
2026 PP.Lex(Tok);
2027 if (Tok.isNot(tok::identifier)) {
2028 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2029 << "weak";
2030 return;
2031 }
2032 AliasName = Tok;
2033 PP.Lex(Tok);
2034 }
2035
2036 if (Tok.isNot(tok::eod)) {
2037 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak";
2038 return;
2039 }
2040
2041 if (HasAlias) {
2042 MutableArrayRef<Token> Toks(
2043 PP.getPreprocessorAllocator().Allocate<Token>(3), 3);
2044 Token &pragmaUnusedTok = Toks[0];
2045 pragmaUnusedTok.startToken();
2046 pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
2047 pragmaUnusedTok.setLocation(WeakLoc);
2048 pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation());
2049 Toks[1] = WeakName;
2050 Toks[2] = AliasName;
2051 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2052 /*IsReinject=*/false);
2053 } else {
2054 MutableArrayRef<Token> Toks(
2055 PP.getPreprocessorAllocator().Allocate<Token>(2), 2);
2056 Token &pragmaUnusedTok = Toks[0];
2057 pragmaUnusedTok.startToken();
2058 pragmaUnusedTok.setKind(tok::annot_pragma_weak);
2059 pragmaUnusedTok.setLocation(WeakLoc);
2060 pragmaUnusedTok.setAnnotationEndLoc(WeakLoc);
2061 Toks[1] = WeakName;
2062 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2063 /*IsReinject=*/false);
2064 }
2065}
2066
2067// #pragma redefine_extname identifier identifier
2068void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
2069 PragmaIntroducer Introducer,
2070 Token &RedefToken) {
2071 SourceLocation RedefLoc = RedefToken.getLocation();
2072
2073 Token Tok;
2074 PP.Lex(Tok);
2075 if (Tok.isNot(tok::identifier)) {
2076 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2077 "redefine_extname";
2078 return;
2079 }
2080
2081 Token RedefName = Tok;
2082 PP.Lex(Tok);
2083
2084 if (Tok.isNot(tok::identifier)) {
2085 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2086 << "redefine_extname";
2087 return;
2088 }
2089
2090 Token AliasName = Tok;
2091 PP.Lex(Tok);
2092
2093 if (Tok.isNot(tok::eod)) {
2094 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2095 "redefine_extname";
2096 return;
2097 }
2098
2099 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3),
2100 3);
2101 Token &pragmaRedefTok = Toks[0];
2102 pragmaRedefTok.startToken();
2103 pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
2104 pragmaRedefTok.setLocation(RedefLoc);
2105 pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation());
2106 Toks[1] = RedefName;
2107 Toks[2] = AliasName;
2108 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2109 /*IsReinject=*/false);
2110}
2111
2112void PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
2113 PragmaIntroducer Introducer,
2114 Token &Tok) {
2115 tok::OnOffSwitch OOS;
2116 if (PP.LexOnOffSwitch(OOS))
2117 return;
2118
2119 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2120 1);
2121 Toks[0].startToken();
2122 Toks[0].setKind(tok::annot_pragma_fp_contract);
2123 Toks[0].setLocation(Tok.getLocation());
2124 Toks[0].setAnnotationEndLoc(Tok.getLocation());
2125 Toks[0].setAnnotationValue(reinterpret_cast<void*>(
2126 static_cast<uintptr_t>(OOS)));
2127 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2128 /*IsReinject=*/false);
2129}
2130
2131void PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
2132 PragmaIntroducer Introducer,
2133 Token &Tok) {
2134 PP.LexUnexpandedToken(Tok);
2135 if (Tok.isNot(tok::identifier)) {
2136 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) <<
2137 "OPENCL";
2138 return;
2139 }
2140 IdentifierInfo *Ext = Tok.getIdentifierInfo();
2141 SourceLocation NameLoc = Tok.getLocation();
2142
2143 PP.Lex(Tok);
2144 if (Tok.isNot(tok::colon)) {
2145 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << Ext;
2146 return;
2147 }
2148
2149 PP.Lex(Tok);
2150 if (Tok.isNot(tok::identifier)) {
2151 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate) << 0;
2152 return;
2153 }
2154 IdentifierInfo *Pred = Tok.getIdentifierInfo();
2155
2156 OpenCLExtState State;
2157 if (Pred->isStr("enable")) {
2158 State = Enable;
2159 } else if (Pred->isStr("disable")) {
2160 State = Disable;
2161 } else if (Pred->isStr("begin"))
2162 State = Begin;
2163 else if (Pred->isStr("end"))
2164 State = End;
2165 else {
2166 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_predicate)
2167 << Ext->isStr("all");
2168 return;
2169 }
2170 SourceLocation StateLoc = Tok.getLocation();
2171
2172 PP.Lex(Tok);
2173 if (Tok.isNot(tok::eod)) {
2174 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
2175 "OPENCL EXTENSION";
2176 return;
2177 }
2178
2179 auto Info = PP.getPreprocessorAllocator().Allocate<OpenCLExtData>(1);
2180 Info->first = Ext;
2181 Info->second = State;
2182 MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1),
2183 1);
2184 Toks[0].startToken();
2185 Toks[0].setKind(tok::annot_pragma_opencl_extension);
2186 Toks[0].setLocation(NameLoc);
2187 Toks[0].setAnnotationValue(static_cast<void*>(Info));
2188 Toks[0].setAnnotationEndLoc(StateLoc);
2189 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
2190 /*IsReinject=*/false);
2191
2192 if (PP.getPPCallbacks())
2193 PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, Ext,
2194 StateLoc, State);
2195}
2196
2197/// Handle '#pragma omp ...' when OpenMP is disabled.
2198///
2199void PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP,
2200 PragmaIntroducer Introducer,
2201 Token &FirstTok) {
2202 if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored,
2203 FirstTok.getLocation())) {
2204 PP.Diag(FirstTok, diag::warn_pragma_omp_ignored);
2205 PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored,
2206 diag::Severity::Ignored, SourceLocation());
2207 }
2208 PP.DiscardUntilEndOfDirective();
2209}
2210
2211/// Handle '#pragma omp ...' when OpenMP is enabled.
2212///
2213void PragmaOpenMPHandler::HandlePragma(Preprocessor &PP,
2214 PragmaIntroducer Introducer,
2215 Token &FirstTok) {
2216 SmallVector<Token, 16> Pragma;
2217 Token Tok;
2218 Tok.startToken();
2219 Tok.setKind(tok::annot_pragma_openmp);
2220 Tok.setLocation(Introducer.Loc);
2221
2222 while (Tok.isNot(tok::eod) && Tok.isNot(tok::eof)) {
2223 Pragma.push_back(Tok);
2224 PP.Lex(Tok);
2225 if (Tok.is(tok::annot_pragma_openmp)) {
2226 PP.Diag(Tok, diag::err_omp_unexpected_directive) << 0;
2227 unsigned InnerPragmaCnt = 1;
2228 while (InnerPragmaCnt != 0) {
2229 PP.Lex(Tok);
2230 if (Tok.is(tok::annot_pragma_openmp))
2231 ++InnerPragmaCnt;
2232 else if (Tok.is(tok::annot_pragma_openmp_end))
2233 --InnerPragmaCnt;
2234 }
2235 PP.Lex(Tok);
2236 }
2237 }
2238 SourceLocation EodLoc = Tok.getLocation();
2239 Tok.startToken();
2240 Tok.setKind(tok::annot_pragma_openmp_end);
2241 Tok.setLocation(EodLoc);
2242 Pragma.push_back(Tok);
2243
2244 auto Toks = llvm::make_unique<Token[]>(Pragma.size());
2245 std::copy(Pragma.begin(), Pragma.end(), Toks.get());
2246 PP.EnterTokenStream(std::move(Toks), Pragma.size(),
2247 /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2248}
2249
2250/// Handle '#pragma pointers_to_members'
2251// The grammar for this pragma is as follows:
2252//
2253// <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance'
2254//
2255// #pragma pointers_to_members '(' 'best_case' ')'
2256// #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')'
2257// #pragma pointers_to_members '(' inheritance-model ')'
2258void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP,
2259 PragmaIntroducer Introducer,
2260 Token &Tok) {
2261 SourceLocation PointersToMembersLoc = Tok.getLocation();
2262 PP.Lex(Tok);
2263 if (Tok.isNot(tok::l_paren)) {
2264 PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen)
2265 << "pointers_to_members";
2266 return;
2267 }
2268 PP.Lex(Tok);
2269 const IdentifierInfo *Arg = Tok.getIdentifierInfo();
2270 if (!Arg) {
2271 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
2272 << "pointers_to_members";
2273 return;
2274 }
2275 PP.Lex(Tok);
2276
2277 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
2278 if (Arg->isStr("best_case")) {
2279 RepresentationMethod = LangOptions::PPTMK_BestCase;
2280 } else {
2281 if (Arg->isStr("full_generality")) {
2282 if (Tok.is(tok::comma)) {
2283 PP.Lex(Tok);
2284
2285 Arg = Tok.getIdentifierInfo();
2286 if (!Arg) {
2287 PP.Diag(Tok.getLocation(),
2288 diag::err_pragma_pointers_to_members_unknown_kind)
2289 << Tok.getKind() << /*OnlyInheritanceModels*/ 0;
2290 return;
2291 }
2292 PP.Lex(Tok);
2293 } else if (Tok.is(tok::r_paren)) {
2294 // #pragma pointers_to_members(full_generality) implicitly specifies
2295 // virtual_inheritance.
2296 Arg = nullptr;
2297 RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2298 } else {
2299 PP.Diag(Tok.getLocation(), diag::err_expected_punc)
2300 << "full_generality";
2301 return;
2302 }
2303 }
2304
2305 if (Arg) {
2306 if (Arg->isStr("single_inheritance")) {
2307 RepresentationMethod =
2308 LangOptions::PPTMK_FullGeneralitySingleInheritance;
2309 } else if (Arg->isStr("multiple_inheritance")) {
2310 RepresentationMethod =
2311 LangOptions::PPTMK_FullGeneralityMultipleInheritance;
2312 } else if (Arg->isStr("virtual_inheritance")) {
2313 RepresentationMethod =
2314 LangOptions::PPTMK_FullGeneralityVirtualInheritance;
2315 } else {
2316 PP.Diag(Tok.getLocation(),
2317 diag::err_pragma_pointers_to_members_unknown_kind)
2318 << Arg << /*HasPointerDeclaration*/ 1;
2319 return;
2320 }
2321 }
2322 }
2323
2324 if (Tok.isNot(tok::r_paren)) {
2325 PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after)
2326 << (Arg ? Arg->getName() : "full_generality");
2327 return;
2328 }
2329
2330 SourceLocation EndLoc = Tok.getLocation();
2331 PP.Lex(Tok);
2332 if (Tok.isNot(tok::eod)) {
2333 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2334 << "pointers_to_members";
2335 return;
2336 }
2337
2338 Token AnnotTok;
2339 AnnotTok.startToken();
2340 AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members);
2341 AnnotTok.setLocation(PointersToMembersLoc);
2342 AnnotTok.setAnnotationEndLoc(EndLoc);
2343 AnnotTok.setAnnotationValue(
2344 reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod)));
2345 PP.EnterToken(AnnotTok, /*IsReinject=*/true);
2346}
2347
2348/// Handle '#pragma vtordisp'
2349// The grammar for this pragma is as follows:
2350//
2351// <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' )
2352//
2353// #pragma vtordisp '(' ['push' ','] vtordisp-mode ')'
2354// #pragma vtordisp '(' 'pop' ')'
2355// #pragma vtordisp '(' ')'
2356void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP,
2357 PragmaIntroducer Introducer, Token &Tok) {
2358 SourceLocation VtorDispLoc = Tok.getLocation();
2359 PP.Lex(Tok);
2360 if (Tok.isNot(tok::l_paren)) {
2361 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp";
2362 return;
2363 }
2364 PP.Lex(Tok);
2365
2366 Sema::PragmaMsStackAction Action = Sema::PSK_Set;
2367 const IdentifierInfo *II = Tok.getIdentifierInfo();
2368 if (II) {
2369 if (II->isStr("push")) {
2370 // #pragma vtordisp(push, mode)
2371 PP.Lex(Tok);
2372 if (Tok.isNot(tok::comma)) {
2373 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp";
2374 return;
2375 }
2376 PP.Lex(Tok);
2377 Action = Sema::PSK_Push_Set;
2378 // not push, could be on/off
2379 } else if (II->isStr("pop")) {
2380 // #pragma vtordisp(pop)
2381 PP.Lex(Tok);
2382 Action = Sema::PSK_Pop;
2383 }
2384 // not push or pop, could be on/off
2385 } else {
2386 if (Tok.is(tok::r_paren)) {
2387 // #pragma vtordisp()
2388 Action = Sema::PSK_Reset;
2389 }
2390 }
2391
2392
2393 uint64_t Value = 0;
2394 if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
2395 const IdentifierInfo *II = Tok.getIdentifierInfo();
2396 if (II && II->isStr("off")) {
2397 PP.Lex(Tok);
2398 Value = 0;
2399 } else if (II && II->isStr("on")) {
2400 PP.Lex(Tok);
2401 Value = 1;
2402 } else if (Tok.is(tok::numeric_constant) &&
2403 PP.parseSimpleIntegerLiteral(Tok, Value)) {
2404 if (Value > 2) {
2405 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer)
2406 << 0 << 2 << "vtordisp";
2407 return;
2408 }
2409 } else {
2410 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
2411 << "vtordisp";
2412 return;
2413 }
2414 }
2415
2416 // Finish the pragma: ')' $
2417 if (Tok.isNot(tok::r_paren)) {
2418 PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp";
2419 return;
2420 }
2421 SourceLocation EndLoc = Tok.getLocation();
2422 PP.Lex(Tok);
2423 if (Tok.isNot(tok::eod)) {
2424 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2425 << "vtordisp";
2426 return;
2427 }
2428
2429 // Enter the annotation.
2430 Token AnnotTok;
2431 AnnotTok.startToken();
2432 AnnotTok.setKind(tok::annot_pragma_ms_vtordisp);
2433 AnnotTok.setLocation(VtorDispLoc);
2434 AnnotTok.setAnnotationEndLoc(EndLoc);
2435 AnnotTok.setAnnotationValue(reinterpret_cast<void *>(
2436 static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF))));
2437 PP.EnterToken(AnnotTok, /*IsReinject=*/false);
2438}
2439
2440/// Handle all MS pragmas. Simply forwards the tokens after inserting
2441/// an annotation token.
2442void PragmaMSPragma::HandlePragma(Preprocessor &PP,
2443 PragmaIntroducer Introducer, Token &Tok) {
2444 Token EoF, AnnotTok;
2445 EoF.startToken();
2446 EoF.setKind(tok::eof);
2447 AnnotTok.startToken();
2448 AnnotTok.setKind(tok::annot_pragma_ms_pragma);
2449 AnnotTok.setLocation(Tok.getLocation());
2450 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2451 SmallVector<Token, 8> TokenVector;
2452 // Suck up all of the tokens before the eod.
2453 for (; Tok.isNot(tok::eod); PP.Lex(Tok)) {
2454 TokenVector.push_back(Tok);
2455 AnnotTok.setAnnotationEndLoc(Tok.getLocation());
2456 }
2457 // Add a sentinel EoF token to the end of the list.
2458 TokenVector.push_back(EoF);
2459 // We must allocate this array with new because EnterTokenStream is going to
2460 // delete it later.
2461 auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size());
2462 std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get());
2463 auto Value = new (PP.getPreprocessorAllocator())
2464 std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray),
2465 TokenVector.size());
2466 AnnotTok.setAnnotationValue(Value);
2467 PP.EnterToken(AnnotTok, /*IsReinject*/ false);
2468}
2469
2470/// Handle the Microsoft \#pragma detect_mismatch extension.
2471///
2472/// The syntax is:
2473/// \code
2474/// #pragma detect_mismatch("name", "value")
2475/// \endcode
2476/// Where 'name' and 'value' are quoted strings. The values are embedded in
2477/// the object file and passed along to the linker. If the linker detects a
2478/// mismatch in the object file's values for the given name, a LNK2038 error
2479/// is emitted. See MSDN for more details.
2480void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP,
2481 PragmaIntroducer Introducer,
2482 Token &Tok) {
2483 SourceLocation DetectMismatchLoc = Tok.getLocation();
2484 PP.Lex(Tok);
2485 if (Tok.isNot(tok::l_paren)) {
2486 PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren;
2487 return;
2488 }
2489
2490 // Read the name to embed, which must be a string literal.
2491 std::string NameString;
2492 if (!PP.LexStringLiteral(Tok, NameString,
2493 "pragma detect_mismatch",
2494 /*MacroExpansion=*/true))
2495 return;
2496
2497 // Read the comma followed by a second string literal.
2498 std::string ValueString;
2499 if (Tok.isNot(tok::comma)) {
2500 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2501 return;
2502 }
2503
2504 if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch",
2505 /*MacroExpansion=*/true))
2506 return;
2507
2508 if (Tok.isNot(tok::r_paren)) {
2509 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2510 return;
2511 }
2512 PP.Lex(Tok); // Eat the r_paren.
2513
2514 if (Tok.isNot(tok::eod)) {
2515 PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed);
2516 return;
2517 }
2518
2519 // If the pragma is lexically sound, notify any interested PPCallbacks.
2520 if (PP.getPPCallbacks())
2521 PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString,
2522 ValueString);
2523
2524 Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString);
2525}
2526
2527/// Handle the microsoft \#pragma comment extension.
2528///
2529/// The syntax is:
2530/// \code
2531/// #pragma comment(linker, "foo")
2532/// \endcode
2533/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
2534/// "foo" is a string, which is fully macro expanded, and permits string
2535/// concatenation, embedded escape characters etc. See MSDN for more details.
2536void PragmaCommentHandler::HandlePragma(Preprocessor &PP,
2537 PragmaIntroducer Introducer,
2538 Token &Tok) {
2539 SourceLocation CommentLoc = Tok.getLocation();
2540 PP.Lex(Tok);
2541 if (Tok.isNot(tok::l_paren)) {
2542 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2543 return;
2544 }
2545
2546 // Read the identifier.
2547 PP.Lex(Tok);
2548 if (Tok.isNot(tok::identifier)) {
2549 PP.Diag(CommentLoc, diag::err_pragma_comment_malformed);
2550 return;
2551 }
2552
2553 // Verify that this is one of the 5 whitelisted options.
2554 IdentifierInfo *II = Tok.getIdentifierInfo();
2555 PragmaMSCommentKind Kind =
2556 llvm::StringSwitch<PragmaMSCommentKind>(II->getName())
2557 .Case("linker", PCK_Linker)
2558 .Case("lib", PCK_Lib)
2559 .Case("compiler", PCK_Compiler)
2560 .Case("exestr", PCK_ExeStr)
2561 .Case("user", PCK_User)
2562 .Default(PCK_Unknown);
2563 if (Kind == PCK_Unknown) {
2564 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
2565 return;
2566 }
2567
2568 if (PP.getTargetInfo().getTriple().isOSBinFormatELF() && Kind != PCK_Lib) {
2569 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2570 << II->getName();
2571 return;
2572 }
2573
2574 // On PS4, issue a warning about any pragma comments other than
2575 // #pragma comment lib.
2576 if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) {
2577 PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored)
2578 << II->getName();
2579 return;
2580 }
2581
2582 // Read the optional string if present.
2583 PP.Lex(Tok);
2584 std::string ArgumentString;
2585 if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString,
2586 "pragma comment",
2587 /*MacroExpansion=*/true))
2588 return;
2589
2590 // FIXME: warn that 'exestr' is deprecated.
2591 // FIXME: If the kind is "compiler" warn if the string is present (it is
2592 // ignored).
2593 // The MSDN docs say that "lib" and "linker" require a string and have a short
2594 // whitelist of linker options they support, but in practice MSVC doesn't
2595 // issue a diagnostic. Therefore neither does clang.
2596
2597 if (Tok.isNot(tok::r_paren)) {
2598 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2599 return;
2600 }
2601 PP.Lex(Tok); // eat the r_paren.
2602
2603 if (Tok.isNot(tok::eod)) {
2604 PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
2605 return;
2606 }
2607
2608 // If the pragma is lexically sound, notify any interested PPCallbacks.
2609 if (PP.getPPCallbacks())
2610 PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
2611
2612 Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
2613}
2614
2615// #pragma clang optimize off
2616// #pragma clang optimize on
2617void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
2618 PragmaIntroducer Introducer,
2619 Token &FirstToken) {
2620 Token Tok;
2621 PP.Lex(Tok);
2622 if (Tok.is(tok::eod)) {
2623 PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
2624 << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
2625 return;
2626 }
2627 if (Tok.isNot(tok::identifier)) {
2628 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2629 << PP.getSpelling(Tok);
2630 return;
2631 }
2632 const IdentifierInfo *II = Tok.getIdentifierInfo();
2633 // The only accepted values are 'on' or 'off'.
2634 bool IsOn = false;
2635 if (II->isStr("on")) {
2636 IsOn = true;
2637 } else if (!II->isStr("off")) {
2638 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
2639 << PP.getSpelling(Tok);
2640 return;
2641 }
2642 PP.Lex(Tok);
2643
2644 if (Tok.isNot(tok::eod)) {
2645 PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
2646 << PP.getSpelling(Tok);
2647 return;
2648 }
2649
2650 Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
2651}
2652
2653namespace {
2654/// Used as the annotation value for tok::annot_pragma_fp.
2655struct TokFPAnnotValue {
2656 enum FlagKinds { Contract };
2657 enum FlagValues { On, Off, Fast };
2658
2659 FlagKinds FlagKind;
2660 FlagValues FlagValue;
2661};
2662} // end anonymous namespace
2663
2664void PragmaFPHandler::HandlePragma(Preprocessor &PP,
2665 PragmaIntroducer Introducer, Token &Tok) {
2666 // fp
2667 Token PragmaName = Tok;
2668 SmallVector<Token, 1> TokenList;
2669
2670 PP.Lex(Tok);
2671 if (Tok.isNot(tok::identifier)) {
2672 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2673 << /*MissingOption=*/true << "";
2674 return;
2675 }
2676
2677 while (Tok.is(tok::identifier)) {
2678 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2679
2680 auto FlagKind =
2681 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
2682 OptionInfo->getName())
2683 .Case("contract", TokFPAnnotValue::Contract)
2684 .Default(None);
2685 if (!FlagKind) {
2686 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
2687 << /*MissingOption=*/false << OptionInfo;
2688 return;
2689 }
2690 PP.Lex(Tok);
2691
2692 // Read '('
2693 if (Tok.isNot(tok::l_paren)) {
2694 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2695 return;
2696 }
2697 PP.Lex(Tok);
2698
2699 if (Tok.isNot(tok::identifier)) {
2700 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2701 << PP.getSpelling(Tok) << OptionInfo->getName();
2702 return;
2703 }
2704 const IdentifierInfo *II = Tok.getIdentifierInfo();
2705
2706 auto FlagValue =
2707 llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
2708 II->getName())
2709 .Case("on", TokFPAnnotValue::On)
2710 .Case("off", TokFPAnnotValue::Off)
2711 .Case("fast", TokFPAnnotValue::Fast)
2712 .Default(llvm::None);
2713
2714 if (!FlagValue) {
2715 PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
2716 << PP.getSpelling(Tok) << OptionInfo->getName();
2717 return;
2718 }
2719 PP.Lex(Tok);
2720
2721 // Read ')'
2722 if (Tok.isNot(tok::r_paren)) {
2723 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2724 return;
2725 }
2726 PP.Lex(Tok);
2727
2728 auto *AnnotValue = new (PP.getPreprocessorAllocator())
2729 TokFPAnnotValue{*FlagKind, *FlagValue};
2730 // Generate the loop hint token.
2731 Token FPTok;
2732 FPTok.startToken();
2733 FPTok.setKind(tok::annot_pragma_fp);
2734 FPTok.setLocation(PragmaName.getLocation());
2735 FPTok.setAnnotationEndLoc(PragmaName.getLocation());
2736 FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
2737 TokenList.push_back(FPTok);
2738 }
2739
2740 if (Tok.isNot(tok::eod)) {
2741 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2742 << "clang fp";
2743 return;
2744 }
2745
2746 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2747 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2748
2749 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2750 /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2751}
2752
2753void Parser::HandlePragmaFP() {
2754 assert(Tok.is(tok::annot_pragma_fp))((Tok.is(tok::annot_pragma_fp)) ? static_cast<void> (0)
: __assert_fail ("Tok.is(tok::annot_pragma_fp)", "/build/llvm-toolchain-snapshot-9~svn362543/tools/clang/lib/Parse/ParsePragma.cpp"
, 2754, __PRETTY_FUNCTION__))
;
2755 auto *AnnotValue =
2756 reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
2757
2758 LangOptions::FPContractModeKind FPC;
2759 switch (AnnotValue->FlagValue) {
2760 case TokFPAnnotValue::On:
2761 FPC = LangOptions::FPC_On;
2762 break;
2763 case TokFPAnnotValue::Fast:
2764 FPC = LangOptions::FPC_Fast;
2765 break;
2766 case TokFPAnnotValue::Off:
2767 FPC = LangOptions::FPC_Off;
2768 break;
2769 }
2770
2771 Actions.ActOnPragmaFPContract(FPC);
2772 ConsumeAnnotationToken();
2773}
2774
2775/// Parses loop or unroll pragma hint value and fills in Info.
2776static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
2777 Token Option, bool ValueInParens,
2778 PragmaLoopHintInfo &Info) {
2779 SmallVector<Token, 1> ValueList;
2780 int OpenParens = ValueInParens ? 1 : 0;
2781 // Read constant expression.
2782 while (Tok.isNot(tok::eod)) {
2783 if (Tok.is(tok::l_paren))
2784 OpenParens++;
2785 else if (Tok.is(tok::r_paren)) {
2786 OpenParens--;
2787 if (OpenParens == 0 && ValueInParens)
2788 break;
2789 }
2790
2791 ValueList.push_back(Tok);
2792 PP.Lex(Tok);
2793 }
2794
2795 if (ValueInParens) {
2796 // Read ')'
2797 if (Tok.isNot(tok::r_paren)) {
2798 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
2799 return true;
2800 }
2801 PP.Lex(Tok);
2802 }
2803
2804 Token EOFTok;
2805 EOFTok.startToken();
2806 EOFTok.setKind(tok::eof);
2807 EOFTok.setLocation(Tok.getLocation());
2808 ValueList.push_back(EOFTok); // Terminates expression for parsing.
2809
2810 Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator());
2811
2812 Info.PragmaName = PragmaName;
2813 Info.Option = Option;
2814 return false;
2815}
2816
2817/// Handle the \#pragma clang loop directive.
2818/// #pragma clang 'loop' loop-hints
2819///
2820/// loop-hints:
2821/// loop-hint loop-hints[opt]
2822///
2823/// loop-hint:
2824/// 'vectorize' '(' loop-hint-keyword ')'
2825/// 'interleave' '(' loop-hint-keyword ')'
2826/// 'unroll' '(' unroll-hint-keyword ')'
2827/// 'vectorize_width' '(' loop-hint-value ')'
2828/// 'interleave_count' '(' loop-hint-value ')'
2829/// 'unroll_count' '(' loop-hint-value ')'
2830/// 'pipeline' '(' disable ')'
2831/// 'pipeline_initiation_interval' '(' loop-hint-value ')'
2832///
2833/// loop-hint-keyword:
2834/// 'enable'
2835/// 'disable'
2836/// 'assume_safety'
2837///
2838/// unroll-hint-keyword:
2839/// 'enable'
2840/// 'disable'
2841/// 'full'
2842///
2843/// loop-hint-value:
2844/// constant-expression
2845///
2846/// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to
2847/// try vectorizing the instructions of the loop it precedes. Specifying
2848/// interleave(enable) or interleave_count(_value_) instructs llvm to try
2849/// interleaving multiple iterations of the loop it precedes. The width of the
2850/// vector instructions is specified by vectorize_width() and the number of
2851/// interleaved loop iterations is specified by interleave_count(). Specifying a
2852/// value of 1 effectively disables vectorization/interleaving, even if it is
2853/// possible and profitable, and 0 is invalid. The loop vectorizer currently
2854/// only works on inner loops.
2855///
2856/// The unroll and unroll_count directives control the concatenation
2857/// unroller. Specifying unroll(enable) instructs llvm to unroll the loop
2858/// completely if the trip count is known at compile time and unroll partially
2859/// if the trip count is not known. Specifying unroll(full) is similar to
2860/// unroll(enable) but will unroll the loop only if the trip count is known at
2861/// compile time. Specifying unroll(disable) disables unrolling for the
2862/// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the
2863/// loop the number of times indicated by the value.
2864void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
2865 PragmaIntroducer Introducer,
2866 Token &Tok) {
2867 // Incoming token is "loop" from "#pragma clang loop".
2868 Token PragmaName = Tok;
2869 SmallVector<Token, 1> TokenList;
2870
2871 // Lex the optimization option and verify it is an identifier.
2872 PP.Lex(Tok);
2873 if (Tok.isNot(tok::identifier)) {
2874 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2875 << /*MissingOption=*/true << "";
2876 return;
2877 }
2878
2879 while (Tok.is(tok::identifier)) {
2880 Token Option = Tok;
2881 IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
2882
2883 bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())
2884 .Case("vectorize", true)
2885 .Case("interleave", true)
2886 .Case("unroll", true)
2887 .Case("distribute", true)
2888 .Case("vectorize_width", true)
2889 .Case("interleave_count", true)
2890 .Case("unroll_count", true)
2891 .Case("pipeline", true)
2892 .Case("pipeline_initiation_interval", true)
2893 .Default(false);
2894 if (!OptionValid) {
2895 PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
2896 << /*MissingOption=*/false << OptionInfo;
2897 return;
2898 }
2899 PP.Lex(Tok);
2900
2901 // Read '('
2902 if (Tok.isNot(tok::l_paren)) {
2903 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
2904 return;
2905 }
2906 PP.Lex(Tok);
2907
2908 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2909 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true,
2910 *Info))
2911 return;
2912
2913 // Generate the loop hint token.
2914 Token LoopHintTok;
2915 LoopHintTok.startToken();
2916 LoopHintTok.setKind(tok::annot_pragma_loop_hint);
2917 LoopHintTok.setLocation(PragmaName.getLocation());
2918 LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation());
2919 LoopHintTok.setAnnotationValue(static_cast<void *>(Info));
2920 TokenList.push_back(LoopHintTok);
2921 }
2922
2923 if (Tok.isNot(tok::eod)) {
2924 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2925 << "clang loop";
2926 return;
2927 }
2928
2929 auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
2930 std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
2931
2932 PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
2933 /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
2934}
2935
2936/// Handle the loop unroll optimization pragmas.
2937/// #pragma unroll
2938/// #pragma unroll unroll-hint-value
2939/// #pragma unroll '(' unroll-hint-value ')'
2940/// #pragma nounroll
2941/// #pragma unroll_and_jam
2942/// #pragma unroll_and_jam unroll-hint-value
2943/// #pragma unroll_and_jam '(' unroll-hint-value ')'
2944/// #pragma nounroll_and_jam
2945///
2946/// unroll-hint-value:
2947/// constant-expression
2948///
2949/// Loop unrolling hints can be specified with '#pragma unroll' or
2950/// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
2951/// contained in parentheses. With no argument the directive instructs llvm to
2952/// try to unroll the loop completely. A positive integer argument can be
2953/// specified to indicate the number of times the loop should be unrolled. To
2954/// maximize compatibility with other compilers the unroll count argument can be
2955/// specified with or without parentheses. Specifying, '#pragma nounroll'
2956/// disables unrolling of the loop.
2957void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
2958 PragmaIntroducer Introducer,
2959 Token &Tok) {
2960 // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
2961 // "#pragma nounroll".
2962 Token PragmaName = Tok;
2963 PP.Lex(Tok);
2964 auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
2965 if (Tok.is(tok::eod)) {
2966 // nounroll or unroll pragma without an argument.
2967 Info->PragmaName = PragmaName;
2968 Info->Option.startToken();
2969 } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll" ||
2970 PragmaName.getIdentifierInfo()->getName() == "nounroll_and_jam") {
2971 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2972 << PragmaName.getIdentifierInfo()->getName();
2973 return;
2974 } else {
2975 // Unroll pragma with an argument: "#pragma unroll N" or
2976 // "#pragma unroll(N)".
2977 // Read '(' if it exists.
2978 bool ValueInParens = Tok.is(tok::l_paren);
2979 if (ValueInParens)
2980 PP.Lex(Tok);
2981
2982 Token Option;
2983 Option.startToken();
2984 if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info))
2985 return;
2986
2987 // In CUDA, the argument to '#pragma unroll' should not be contained in
2988 // parentheses.
2989 if (PP.getLangOpts().CUDA && ValueInParens)
2990 PP.Diag(Info->Toks[0].getLocation(),
2991 diag::warn_pragma_unroll_cuda_value_in_parens);
2992
2993 if (Tok.isNot(tok::eod)) {
2994 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
2995 << "unroll";
2996 return;
2997 }
2998 }
2999
3000 // Generate the hint token.
3001 auto TokenArray = llvm::make_unique<Token[]>(1);
3002 TokenArray[0].startToken();
3003 TokenArray[0].setKind(tok::annot_pragma_loop_hint);
3004 TokenArray[0].setLocation(PragmaName.getLocation());
3005 TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation());
3006 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3007 PP.EnterTokenStream(std::move(TokenArray), 1,
3008 /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3009}
3010
3011/// Handle the Microsoft \#pragma intrinsic extension.
3012///
3013/// The syntax is:
3014/// \code
3015/// #pragma intrinsic(memset)
3016/// #pragma intrinsic(strlen, memcpy)
3017/// \endcode
3018///
3019/// Pragma intrisic tells the compiler to use a builtin version of the
3020/// function. Clang does it anyway, so the pragma doesn't really do anything.
3021/// Anyway, we emit a warning if the function specified in \#pragma intrinsic
3022/// isn't an intrinsic in clang and suggest to include intrin.h.
3023void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP,
3024 PragmaIntroducer Introducer,
3025 Token &Tok) {
3026 PP.Lex(Tok);
3027
3028 if (Tok.isNot(tok::l_paren)) {
3029 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
3030 << "intrinsic";
3031 return;
3032 }
3033 PP.Lex(Tok);
3034
3035 bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H");
3036
3037 while (Tok.is(tok::identifier)) {
3038 IdentifierInfo *II = Tok.getIdentifierInfo();
3039 if (!II->getBuiltinID())
3040 PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin)
3041 << II << SuggestIntrinH;
3042
3043 PP.Lex(Tok);
3044 if (Tok.isNot(tok::comma))
3045 break;
3046 PP.Lex(Tok);
3047 }
3048
3049 if (Tok.isNot(tok::r_paren)) {
3050 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
3051 << "intrinsic";
3052 return;
3053 }
3054 PP.Lex(Tok);
3055
3056 if (Tok.isNot(tok::eod))
3057 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3058 << "intrinsic";
3059}
3060
3061// #pragma optimize("gsty", on|off)
3062void PragmaMSOptimizeHandler::HandlePragma(Preprocessor &PP,
3063 PragmaIntroducer Introducer,
3064 Token &Tok) {
3065 SourceLocation StartLoc = Tok.getLocation();
3066 PP.Lex(Tok);
3067
3068 if (Tok.isNot(tok::l_paren)) {
3069 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "optimize";
3070 return;
3071 }
3072 PP.Lex(Tok);
3073
3074 if (Tok.isNot(tok::string_literal)) {
3075 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_string) << "optimize";
3076 return;
3077 }
3078 // We could syntax check the string but it's probably not worth the effort.
3079 PP.Lex(Tok);
3080
3081 if (Tok.isNot(tok::comma)) {
3082 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_comma) << "optimize";
3083 return;
3084 }
3085 PP.Lex(Tok);
3086
3087 if (Tok.is(tok::eod) || Tok.is(tok::r_paren)) {
3088 PP.Diag(Tok.getLocation(), diag::warn_pragma_missing_argument)
3089 << "optimize" << /*Expected=*/true << "'on' or 'off'";
3090 return;
3091 }
3092 IdentifierInfo *II = Tok.getIdentifierInfo();
3093 if (!II || (!II->isStr("on") && !II->isStr("off"))) {
3094 PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
3095 << PP.getSpelling(Tok) << "optimize" << /*Expected=*/true
3096 << "'on' or 'off'";
3097 return;
3098 }
3099 PP.Lex(Tok);
3100
3101 if (Tok.isNot(tok::r_paren)) {
3102 PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "optimize";
3103 return;
3104 }
3105 PP.Lex(Tok);
3106
3107 if (Tok.isNot(tok::eod)) {
3108 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3109 << "optimize";
3110 return;
3111 }
3112 PP.Diag(StartLoc, diag::warn_pragma_optimize);
3113}
3114
3115void PragmaForceCUDAHostDeviceHandler::HandlePragma(
3116 Preprocessor &PP, PragmaIntroducer Introducer, Token &Tok) {
3117 Token FirstTok = Tok;
3118
3119 PP.Lex(Tok);
3120 IdentifierInfo *Info = Tok.getIdentifierInfo();
3121 if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) {
3122 PP.Diag(FirstTok.getLocation(),
3123 diag::warn_pragma_force_cuda_host_device_bad_arg);
3124 return;
3125 }
3126
3127 if (Info->isStr("begin"))
3128 Actions.PushForceCUDAHostDevice();
3129 else if (!Actions.PopForceCUDAHostDevice())
3130 PP.Diag(FirstTok.getLocation(),
3131 diag::err_pragma_cannot_end_force_cuda_host_device);
3132
3133 PP.Lex(Tok);
3134 if (!Tok.is(tok::eod))
3135 PP.Diag(FirstTok.getLocation(),
3136 diag::warn_pragma_force_cuda_host_device_bad_arg);
3137}
3138
3139/// Handle the #pragma clang attribute directive.
3140///
3141/// The syntax is:
3142/// \code
3143/// #pragma clang attribute push (attribute, subject-set)
3144/// #pragma clang attribute push
3145/// #pragma clang attribute (attribute, subject-set)
3146/// #pragma clang attribute pop
3147/// \endcode
3148///
3149/// There are also 'namespace' variants of push and pop directives. The bare
3150/// '#pragma clang attribute (attribute, subject-set)' version doesn't require a
3151/// namespace, since it always applies attributes to the most recently pushed
3152/// group, regardless of namespace.
3153/// \code
3154/// #pragma clang attribute namespace.push (attribute, subject-set)
3155/// #pragma clang attribute namespace.push
3156/// #pragma clang attribute namespace.pop
3157/// \endcode
3158///
3159/// The subject-set clause defines the set of declarations which receive the
3160/// attribute. Its exact syntax is described in the LanguageExtensions document
3161/// in Clang's documentation.
3162///
3163/// This directive instructs the compiler to begin/finish applying the specified
3164/// attribute to the set of attribute-specific declarations in the active range
3165/// of the pragma.
3166void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
3167 PragmaIntroducer Introducer,
3168 Token &FirstToken) {
3169 Token Tok;
3170 PP.Lex(Tok);
3171 auto *Info = new (PP.getPreprocessorAllocator())
1
'Info' initialized to a null pointer value
3172 PragmaAttributeInfo(AttributesForPragmaAttribute);
3173
3174 // Parse the optional namespace followed by a period.
3175 if (Tok.is(tok::identifier)) {
2
Taking true branch
3176 IdentifierInfo *II = Tok.getIdentifierInfo();
3177 if (!II->isStr("push") && !II->isStr("pop")) {
3
Taking true branch
3178 Info->Namespace = II;
4
Access to field 'Namespace' results in a dereference of a null pointer (loaded from variable 'Info')
3179 PP.Lex(Tok);
3180
3181 if (!Tok.is(tok::period)) {
3182 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_period)
3183 << II;
3184 return;
3185 }
3186 PP.Lex(Tok);
3187 }
3188 }
3189
3190 if (!Tok.isOneOf(tok::identifier, tok::l_paren)) {
3191 PP.Diag(Tok.getLocation(),
3192 diag::err_pragma_attribute_expected_push_pop_paren);
3193 return;
3194 }
3195
3196 // Determine what action this pragma clang attribute represents.
3197 if (Tok.is(tok::l_paren)) {
3198 if (Info->Namespace) {
3199 PP.Diag(Tok.getLocation(),
3200 diag::err_pragma_attribute_namespace_on_attribute);
3201 PP.Diag(Tok.getLocation(),
3202 diag::note_pragma_attribute_namespace_on_attribute);
3203 return;
3204 }
3205 Info->Action = PragmaAttributeInfo::Attribute;
3206 } else {
3207 const IdentifierInfo *II = Tok.getIdentifierInfo();
3208 if (II->isStr("push"))
3209 Info->Action = PragmaAttributeInfo::Push;
3210 else if (II->isStr("pop"))
3211 Info->Action = PragmaAttributeInfo::Pop;
3212 else {
3213 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
3214 << PP.getSpelling(Tok);
3215 return;
3216 }
3217
3218 PP.Lex(Tok);
3219 }
3220
3221 // Parse the actual attribute.
3222 if ((Info->Action == PragmaAttributeInfo::Push && Tok.isNot(tok::eod)) ||
3223 Info->Action == PragmaAttributeInfo::Attribute) {
3224 if (Tok.isNot(tok::l_paren)) {
3225 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
3226 return;
3227 }
3228 PP.Lex(Tok);
3229
3230 // Lex the attribute tokens.
3231 SmallVector<Token, 16> AttributeTokens;
3232 int OpenParens = 1;
3233 while (Tok.isNot(tok::eod)) {
3234 if (Tok.is(tok::l_paren))
3235 OpenParens++;
3236 else if (Tok.is(tok::r_paren)) {
3237 OpenParens--;
3238 if (OpenParens == 0)
3239 break;
3240 }
3241
3242 AttributeTokens.push_back(Tok);
3243 PP.Lex(Tok);
3244 }
3245
3246 if (AttributeTokens.empty()) {
3247 PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
3248 return;
3249 }
3250 if (Tok.isNot(tok::r_paren)) {
3251 PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
3252 return;
3253 }
3254 SourceLocation EndLoc = Tok.getLocation();
3255 PP.Lex(Tok);
3256
3257 // Terminate the attribute for parsing.
3258 Token EOFTok;
3259 EOFTok.startToken();
3260 EOFTok.setKind(tok::eof);
3261 EOFTok.setLocation(EndLoc);
3262 AttributeTokens.push_back(EOFTok);
3263
3264 Info->Tokens =
3265 llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
3266 }
3267
3268 if (Tok.isNot(tok::eod))
3269 PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
3270 << "clang attribute";
3271
3272 // Generate the annotated pragma token.
3273 auto TokenArray = llvm::make_unique<Token[]>(1);
3274 TokenArray[0].startToken();
3275 TokenArray[0].setKind(tok::annot_pragma_attribute);
3276 TokenArray[0].setLocation(FirstToken.getLocation());
3277 TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
3278 TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
3279 PP.EnterTokenStream(std::move(TokenArray), 1,
3280 /*DisableMacroExpansion=*/false, /*IsReinject=*/false);
3281}