Bug Summary

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