| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 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 |  | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 14 | #include "RAIIObjectsForParser.h" | 
| Hans Wennborg | 899ded9 | 2014-10-16 20:52:46 +0000 | [diff] [blame] | 15 | #include "clang/AST/ASTContext.h" | 
| Nico Weber | 6622029 | 2016-03-02 17:28:48 +0000 | [diff] [blame] | 16 | #include "clang/Basic/PragmaKinds.h" | 
| David Majnemer | ad2986e | 2014-08-14 06:35:08 +0000 | [diff] [blame] | 17 | #include "clang/Basic/TargetInfo.h" | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 18 | #include "clang/Lex/Preprocessor.h" | 
|  | 19 | #include "clang/Parse/ParseDiagnostic.h" | 
|  | 20 | #include "clang/Parse/Parser.h" | 
|  | 21 | #include "clang/Sema/LoopHint.h" | 
|  | 22 | #include "clang/Sema/Scope.h" | 
|  | 23 | #include "llvm/ADT/StringSwitch.h" | 
|  | 24 | using namespace clang; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 25 |  | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 26 | namespace { | 
|  | 27 |  | 
|  | 28 | struct PragmaAlignHandler : public PragmaHandler { | 
|  | 29 | explicit PragmaAlignHandler() : PragmaHandler("align") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 30 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 31 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 32 | }; | 
|  | 33 |  | 
|  | 34 | struct PragmaGCCVisibilityHandler : public PragmaHandler { | 
|  | 35 | explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 36 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 37 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 38 | }; | 
|  | 39 |  | 
|  | 40 | struct PragmaOptionsHandler : public PragmaHandler { | 
|  | 41 | explicit PragmaOptionsHandler() : PragmaHandler("options") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 42 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 43 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 44 | }; | 
|  | 45 |  | 
|  | 46 | struct PragmaPackHandler : public PragmaHandler { | 
|  | 47 | explicit PragmaPackHandler() : PragmaHandler("pack") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 48 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 49 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 50 | }; | 
|  | 51 |  | 
|  | 52 | struct PragmaMSStructHandler : public PragmaHandler { | 
|  | 53 | explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 54 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 55 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 56 | }; | 
|  | 57 |  | 
|  | 58 | struct PragmaUnusedHandler : public PragmaHandler { | 
|  | 59 | PragmaUnusedHandler() : PragmaHandler("unused") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 60 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 61 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 62 | }; | 
|  | 63 |  | 
|  | 64 | struct PragmaWeakHandler : public PragmaHandler { | 
|  | 65 | explicit PragmaWeakHandler() : PragmaHandler("weak") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 66 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 67 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 68 | }; | 
|  | 69 |  | 
|  | 70 | struct PragmaRedefineExtnameHandler : public PragmaHandler { | 
|  | 71 | explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 72 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 73 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 74 | }; | 
|  | 75 |  | 
|  | 76 | struct PragmaOpenCLExtensionHandler : public PragmaHandler { | 
|  | 77 | PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 78 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 79 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 80 | }; | 
|  | 81 |  | 
|  | 82 |  | 
|  | 83 | struct PragmaFPContractHandler : public PragmaHandler { | 
|  | 84 | PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 85 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 86 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 87 | }; | 
|  | 88 |  | 
|  | 89 | struct PragmaNoOpenMPHandler : public PragmaHandler { | 
|  | 90 | PragmaNoOpenMPHandler() : PragmaHandler("omp") { } | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 91 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 92 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 93 | }; | 
|  | 94 |  | 
|  | 95 | struct PragmaOpenMPHandler : public PragmaHandler { | 
|  | 96 | PragmaOpenMPHandler() : PragmaHandler("omp") { } | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 97 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 98 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 99 | }; | 
|  | 100 |  | 
|  | 101 | /// PragmaCommentHandler - "\#pragma comment ...". | 
|  | 102 | struct PragmaCommentHandler : public PragmaHandler { | 
|  | 103 | PragmaCommentHandler(Sema &Actions) | 
|  | 104 | : PragmaHandler("comment"), Actions(Actions) {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 105 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 106 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 107 | private: | 
|  | 108 | Sema &Actions; | 
|  | 109 | }; | 
|  | 110 |  | 
|  | 111 | struct PragmaDetectMismatchHandler : public PragmaHandler { | 
|  | 112 | PragmaDetectMismatchHandler(Sema &Actions) | 
|  | 113 | : PragmaHandler("detect_mismatch"), Actions(Actions) {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 114 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 115 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 116 | private: | 
|  | 117 | Sema &Actions; | 
|  | 118 | }; | 
|  | 119 |  | 
|  | 120 | struct PragmaMSPointersToMembers : public PragmaHandler { | 
|  | 121 | explicit PragmaMSPointersToMembers() : PragmaHandler("pointers_to_members") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 122 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 123 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 124 | }; | 
|  | 125 |  | 
|  | 126 | struct PragmaMSVtorDisp : public PragmaHandler { | 
|  | 127 | explicit PragmaMSVtorDisp() : PragmaHandler("vtordisp") {} | 
| Craig Topper | 2b07f02 | 2014-03-12 05:09:18 +0000 | [diff] [blame] | 128 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 129 | Token &FirstToken) override; | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 130 | }; | 
|  | 131 |  | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 132 | struct PragmaMSPragma : public PragmaHandler { | 
|  | 133 | explicit PragmaMSPragma(const char *name) : PragmaHandler(name) {} | 
| Reid Kleckner | d3923aa | 2014-04-03 19:04:24 +0000 | [diff] [blame] | 134 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 135 | Token &FirstToken) override; | 
|  | 136 | }; | 
|  | 137 |  | 
| Dario Domizioli | 13a0a38 | 2014-05-23 12:13:25 +0000 | [diff] [blame] | 138 | /// PragmaOptimizeHandler - "\#pragma clang optimize on/off". | 
|  | 139 | struct PragmaOptimizeHandler : public PragmaHandler { | 
|  | 140 | PragmaOptimizeHandler(Sema &S) | 
|  | 141 | : PragmaHandler("optimize"), Actions(S) {} | 
|  | 142 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 143 | Token &FirstToken) override; | 
|  | 144 | private: | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 145 | Sema &Actions; | 
|  | 146 | }; | 
|  | 147 |  | 
|  | 148 | struct PragmaLoopHintHandler : public PragmaHandler { | 
|  | 149 | PragmaLoopHintHandler() : PragmaHandler("loop") {} | 
|  | 150 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 151 | Token &FirstToken) override; | 
|  | 152 | }; | 
|  | 153 |  | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 154 | struct PragmaUnrollHintHandler : public PragmaHandler { | 
|  | 155 | PragmaUnrollHintHandler(const char *name) : PragmaHandler(name) {} | 
|  | 156 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 157 | Token &FirstToken) override; | 
|  | 158 | }; | 
|  | 159 |  | 
| Hans Wennborg | 7357bbc | 2015-10-12 20:47:58 +0000 | [diff] [blame] | 160 | struct PragmaMSRuntimeChecksHandler : public EmptyPragmaHandler { | 
|  | 161 | PragmaMSRuntimeChecksHandler() : EmptyPragmaHandler("runtime_checks") {} | 
|  | 162 | }; | 
|  | 163 |  | 
| Reid Kleckner | 3f1ec62 | 2016-09-07 16:38:32 +0000 | [diff] [blame] | 164 | struct PragmaMSIntrinsicHandler : public PragmaHandler { | 
|  | 165 | PragmaMSIntrinsicHandler() : PragmaHandler("intrinsic") {} | 
|  | 166 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 167 | Token &FirstToken) override; | 
|  | 168 | }; | 
|  | 169 |  | 
| Justin Lebar | 67a78a6 | 2016-10-08 22:15:58 +0000 | [diff] [blame] | 170 | struct PragmaForceCUDAHostDeviceHandler : public PragmaHandler { | 
|  | 171 | PragmaForceCUDAHostDeviceHandler(Sema &Actions) | 
|  | 172 | : PragmaHandler("force_cuda_host_device"), Actions(Actions) {} | 
|  | 173 | void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, | 
|  | 174 | Token &FirstToken) override; | 
|  | 175 |  | 
|  | 176 | private: | 
|  | 177 | Sema &Actions; | 
|  | 178 | }; | 
|  | 179 |  | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 180 | }  // end namespace | 
|  | 181 |  | 
|  | 182 | void Parser::initializePragmaHandlers() { | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 183 | AlignHandler.reset(new PragmaAlignHandler()); | 
|  | 184 | PP.AddPragmaHandler(AlignHandler.get()); | 
|  | 185 |  | 
|  | 186 | GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler()); | 
|  | 187 | PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get()); | 
|  | 188 |  | 
|  | 189 | OptionsHandler.reset(new PragmaOptionsHandler()); | 
|  | 190 | PP.AddPragmaHandler(OptionsHandler.get()); | 
|  | 191 |  | 
|  | 192 | PackHandler.reset(new PragmaPackHandler()); | 
|  | 193 | PP.AddPragmaHandler(PackHandler.get()); | 
|  | 194 |  | 
|  | 195 | MSStructHandler.reset(new PragmaMSStructHandler()); | 
|  | 196 | PP.AddPragmaHandler(MSStructHandler.get()); | 
|  | 197 |  | 
|  | 198 | UnusedHandler.reset(new PragmaUnusedHandler()); | 
|  | 199 | PP.AddPragmaHandler(UnusedHandler.get()); | 
|  | 200 |  | 
|  | 201 | WeakHandler.reset(new PragmaWeakHandler()); | 
|  | 202 | PP.AddPragmaHandler(WeakHandler.get()); | 
|  | 203 |  | 
|  | 204 | RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler()); | 
|  | 205 | PP.AddPragmaHandler(RedefineExtnameHandler.get()); | 
|  | 206 |  | 
|  | 207 | FPContractHandler.reset(new PragmaFPContractHandler()); | 
|  | 208 | PP.AddPragmaHandler("STDC", FPContractHandler.get()); | 
|  | 209 |  | 
|  | 210 | if (getLangOpts().OpenCL) { | 
|  | 211 | OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler()); | 
|  | 212 | PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get()); | 
|  | 213 |  | 
|  | 214 | PP.AddPragmaHandler("OPENCL", FPContractHandler.get()); | 
|  | 215 | } | 
|  | 216 | if (getLangOpts().OpenMP) | 
|  | 217 | OpenMPHandler.reset(new PragmaOpenMPHandler()); | 
|  | 218 | else | 
|  | 219 | OpenMPHandler.reset(new PragmaNoOpenMPHandler()); | 
|  | 220 | PP.AddPragmaHandler(OpenMPHandler.get()); | 
|  | 221 |  | 
| Yunzhong Gao | 99efc03 | 2015-03-23 20:41:42 +0000 | [diff] [blame] | 222 | if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) { | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 223 | MSCommentHandler.reset(new PragmaCommentHandler(Actions)); | 
|  | 224 | PP.AddPragmaHandler(MSCommentHandler.get()); | 
| Yunzhong Gao | 99efc03 | 2015-03-23 20:41:42 +0000 | [diff] [blame] | 225 | } | 
|  | 226 |  | 
|  | 227 | if (getLangOpts().MicrosoftExt) { | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 228 | MSDetectMismatchHandler.reset(new PragmaDetectMismatchHandler(Actions)); | 
|  | 229 | PP.AddPragmaHandler(MSDetectMismatchHandler.get()); | 
|  | 230 | MSPointersToMembers.reset(new PragmaMSPointersToMembers()); | 
|  | 231 | PP.AddPragmaHandler(MSPointersToMembers.get()); | 
|  | 232 | MSVtorDisp.reset(new PragmaMSVtorDisp()); | 
|  | 233 | PP.AddPragmaHandler(MSVtorDisp.get()); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 234 | MSInitSeg.reset(new PragmaMSPragma("init_seg")); | 
| Reid Kleckner | d3923aa | 2014-04-03 19:04:24 +0000 | [diff] [blame] | 235 | PP.AddPragmaHandler(MSInitSeg.get()); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 236 | MSDataSeg.reset(new PragmaMSPragma("data_seg")); | 
|  | 237 | PP.AddPragmaHandler(MSDataSeg.get()); | 
|  | 238 | MSBSSSeg.reset(new PragmaMSPragma("bss_seg")); | 
|  | 239 | PP.AddPragmaHandler(MSBSSSeg.get()); | 
|  | 240 | MSConstSeg.reset(new PragmaMSPragma("const_seg")); | 
|  | 241 | PP.AddPragmaHandler(MSConstSeg.get()); | 
|  | 242 | MSCodeSeg.reset(new PragmaMSPragma("code_seg")); | 
|  | 243 | PP.AddPragmaHandler(MSCodeSeg.get()); | 
|  | 244 | MSSection.reset(new PragmaMSPragma("section")); | 
|  | 245 | PP.AddPragmaHandler(MSSection.get()); | 
| Hans Wennborg | 7357bbc | 2015-10-12 20:47:58 +0000 | [diff] [blame] | 246 | MSRuntimeChecks.reset(new PragmaMSRuntimeChecksHandler()); | 
|  | 247 | PP.AddPragmaHandler(MSRuntimeChecks.get()); | 
| Reid Kleckner | 3f1ec62 | 2016-09-07 16:38:32 +0000 | [diff] [blame] | 248 | MSIntrinsic.reset(new PragmaMSIntrinsicHandler()); | 
|  | 249 | PP.AddPragmaHandler(MSIntrinsic.get()); | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 250 | } | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 251 |  | 
| Justin Lebar | 67a78a6 | 2016-10-08 22:15:58 +0000 | [diff] [blame] | 252 | if (getLangOpts().CUDA) { | 
|  | 253 | CUDAForceHostDeviceHandler.reset( | 
|  | 254 | new PragmaForceCUDAHostDeviceHandler(Actions)); | 
|  | 255 | PP.AddPragmaHandler("clang", CUDAForceHostDeviceHandler.get()); | 
|  | 256 | } | 
|  | 257 |  | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 258 | OptimizeHandler.reset(new PragmaOptimizeHandler(Actions)); | 
|  | 259 | PP.AddPragmaHandler("clang", OptimizeHandler.get()); | 
|  | 260 |  | 
|  | 261 | LoopHintHandler.reset(new PragmaLoopHintHandler()); | 
|  | 262 | PP.AddPragmaHandler("clang", LoopHintHandler.get()); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 263 |  | 
|  | 264 | UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll")); | 
|  | 265 | PP.AddPragmaHandler(UnrollHintHandler.get()); | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 266 |  | 
|  | 267 | NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll")); | 
|  | 268 | PP.AddPragmaHandler(NoUnrollHintHandler.get()); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 269 | } | 
|  | 270 |  | 
|  | 271 | void Parser::resetPragmaHandlers() { | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 272 | // Remove the pragma handlers we installed. | 
|  | 273 | PP.RemovePragmaHandler(AlignHandler.get()); | 
|  | 274 | AlignHandler.reset(); | 
|  | 275 | PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get()); | 
|  | 276 | GCCVisibilityHandler.reset(); | 
|  | 277 | PP.RemovePragmaHandler(OptionsHandler.get()); | 
|  | 278 | OptionsHandler.reset(); | 
|  | 279 | PP.RemovePragmaHandler(PackHandler.get()); | 
|  | 280 | PackHandler.reset(); | 
|  | 281 | PP.RemovePragmaHandler(MSStructHandler.get()); | 
|  | 282 | MSStructHandler.reset(); | 
|  | 283 | PP.RemovePragmaHandler(UnusedHandler.get()); | 
|  | 284 | UnusedHandler.reset(); | 
|  | 285 | PP.RemovePragmaHandler(WeakHandler.get()); | 
|  | 286 | WeakHandler.reset(); | 
|  | 287 | PP.RemovePragmaHandler(RedefineExtnameHandler.get()); | 
|  | 288 | RedefineExtnameHandler.reset(); | 
|  | 289 |  | 
|  | 290 | if (getLangOpts().OpenCL) { | 
|  | 291 | PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get()); | 
|  | 292 | OpenCLExtensionHandler.reset(); | 
|  | 293 | PP.RemovePragmaHandler("OPENCL", FPContractHandler.get()); | 
|  | 294 | } | 
|  | 295 | PP.RemovePragmaHandler(OpenMPHandler.get()); | 
|  | 296 | OpenMPHandler.reset(); | 
|  | 297 |  | 
| Yunzhong Gao | 99efc03 | 2015-03-23 20:41:42 +0000 | [diff] [blame] | 298 | if (getLangOpts().MicrosoftExt || getTargetInfo().getTriple().isPS4()) { | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 299 | PP.RemovePragmaHandler(MSCommentHandler.get()); | 
|  | 300 | MSCommentHandler.reset(); | 
| Yunzhong Gao | 99efc03 | 2015-03-23 20:41:42 +0000 | [diff] [blame] | 301 | } | 
|  | 302 |  | 
|  | 303 | if (getLangOpts().MicrosoftExt) { | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 304 | PP.RemovePragmaHandler(MSDetectMismatchHandler.get()); | 
|  | 305 | MSDetectMismatchHandler.reset(); | 
|  | 306 | PP.RemovePragmaHandler(MSPointersToMembers.get()); | 
|  | 307 | MSPointersToMembers.reset(); | 
|  | 308 | PP.RemovePragmaHandler(MSVtorDisp.get()); | 
|  | 309 | MSVtorDisp.reset(); | 
| Reid Kleckner | d3923aa | 2014-04-03 19:04:24 +0000 | [diff] [blame] | 310 | PP.RemovePragmaHandler(MSInitSeg.get()); | 
|  | 311 | MSInitSeg.reset(); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 312 | PP.RemovePragmaHandler(MSDataSeg.get()); | 
|  | 313 | MSDataSeg.reset(); | 
|  | 314 | PP.RemovePragmaHandler(MSBSSSeg.get()); | 
|  | 315 | MSBSSSeg.reset(); | 
|  | 316 | PP.RemovePragmaHandler(MSConstSeg.get()); | 
|  | 317 | MSConstSeg.reset(); | 
|  | 318 | PP.RemovePragmaHandler(MSCodeSeg.get()); | 
|  | 319 | MSCodeSeg.reset(); | 
|  | 320 | PP.RemovePragmaHandler(MSSection.get()); | 
|  | 321 | MSSection.reset(); | 
| Hans Wennborg | 7357bbc | 2015-10-12 20:47:58 +0000 | [diff] [blame] | 322 | PP.RemovePragmaHandler(MSRuntimeChecks.get()); | 
|  | 323 | MSRuntimeChecks.reset(); | 
| Reid Kleckner | 3f1ec62 | 2016-09-07 16:38:32 +0000 | [diff] [blame] | 324 | PP.RemovePragmaHandler(MSIntrinsic.get()); | 
|  | 325 | MSIntrinsic.reset(); | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 326 | } | 
|  | 327 |  | 
| Justin Lebar | 67a78a6 | 2016-10-08 22:15:58 +0000 | [diff] [blame] | 328 | if (getLangOpts().CUDA) { | 
|  | 329 | PP.RemovePragmaHandler("clang", CUDAForceHostDeviceHandler.get()); | 
|  | 330 | CUDAForceHostDeviceHandler.reset(); | 
|  | 331 | } | 
|  | 332 |  | 
| Reid Kleckner | 5b08646 | 2014-02-20 22:52:09 +0000 | [diff] [blame] | 333 | PP.RemovePragmaHandler("STDC", FPContractHandler.get()); | 
|  | 334 | FPContractHandler.reset(); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 335 |  | 
|  | 336 | PP.RemovePragmaHandler("clang", OptimizeHandler.get()); | 
|  | 337 | OptimizeHandler.reset(); | 
|  | 338 |  | 
|  | 339 | PP.RemovePragmaHandler("clang", LoopHintHandler.get()); | 
|  | 340 | LoopHintHandler.reset(); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 341 |  | 
|  | 342 | PP.RemovePragmaHandler(UnrollHintHandler.get()); | 
|  | 343 | UnrollHintHandler.reset(); | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 344 |  | 
|  | 345 | PP.RemovePragmaHandler(NoUnrollHintHandler.get()); | 
|  | 346 | NoUnrollHintHandler.reset(); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 347 | } | 
|  | 348 |  | 
|  | 349 | /// \brief Handle the annotation token produced for #pragma unused(...) | 
| Argyrios Kyrtzidis | ee56962 | 2011-01-17 18:58:44 +0000 | [diff] [blame] | 350 | /// | 
|  | 351 | /// Each annot_pragma_unused is followed by the argument token so e.g. | 
|  | 352 | /// "#pragma unused(x,y)" becomes: | 
|  | 353 | /// annot_pragma_unused 'x' annot_pragma_unused 'y' | 
|  | 354 | void Parser::HandlePragmaUnused() { | 
|  | 355 | assert(Tok.is(tok::annot_pragma_unused)); | 
|  | 356 | SourceLocation UnusedLoc = ConsumeToken(); | 
|  | 357 | Actions.ActOnPragmaUnused(Tok, getCurScope(), UnusedLoc); | 
|  | 358 | ConsumeToken(); // The argument token. | 
|  | 359 | } | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 360 |  | 
| Rafael Espindola | 273fd77 | 2012-01-26 02:02:57 +0000 | [diff] [blame] | 361 | void Parser::HandlePragmaVisibility() { | 
|  | 362 | assert(Tok.is(tok::annot_pragma_vis)); | 
|  | 363 | const IdentifierInfo *VisType = | 
|  | 364 | static_cast<IdentifierInfo *>(Tok.getAnnotationValue()); | 
|  | 365 | SourceLocation VisLoc = ConsumeToken(); | 
|  | 366 | Actions.ActOnPragmaVisibility(VisType, VisLoc); | 
|  | 367 | } | 
|  | 368 |  | 
| Benjamin Kramer | e003ca2 | 2015-10-28 13:54:16 +0000 | [diff] [blame] | 369 | namespace { | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 370 | struct PragmaPackInfo { | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 371 | Sema::PragmaMsStackAction Action; | 
|  | 372 | StringRef SlotLabel; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 373 | Token Alignment; | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 374 | }; | 
| Benjamin Kramer | e003ca2 | 2015-10-28 13:54:16 +0000 | [diff] [blame] | 375 | } // end anonymous namespace | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 376 |  | 
|  | 377 | void Parser::HandlePragmaPack() { | 
|  | 378 | assert(Tok.is(tok::annot_pragma_pack)); | 
|  | 379 | PragmaPackInfo *Info = | 
|  | 380 | static_cast<PragmaPackInfo *>(Tok.getAnnotationValue()); | 
|  | 381 | SourceLocation PragmaLoc = ConsumeToken(); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 382 | ExprResult Alignment; | 
|  | 383 | if (Info->Alignment.is(tok::numeric_constant)) { | 
|  | 384 | Alignment = Actions.ActOnNumericConstant(Info->Alignment); | 
|  | 385 | if (Alignment.isInvalid()) | 
|  | 386 | return; | 
|  | 387 | } | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 388 | Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel, | 
|  | 389 | Alignment.get()); | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 390 | } | 
|  | 391 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 392 | void Parser::HandlePragmaMSStruct() { | 
|  | 393 | assert(Tok.is(tok::annot_pragma_msstruct)); | 
| Nico Weber | 779355f | 2016-03-02 23:22:00 +0000 | [diff] [blame] | 394 | PragmaMSStructKind Kind = static_cast<PragmaMSStructKind>( | 
|  | 395 | reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 396 | Actions.ActOnPragmaMSStruct(Kind); | 
|  | 397 | ConsumeToken(); // The annotation token. | 
|  | 398 | } | 
|  | 399 |  | 
|  | 400 | void Parser::HandlePragmaAlign() { | 
|  | 401 | assert(Tok.is(tok::annot_pragma_align)); | 
|  | 402 | Sema::PragmaOptionsAlignKind Kind = | 
|  | 403 | static_cast<Sema::PragmaOptionsAlignKind>( | 
|  | 404 | reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); | 
|  | 405 | SourceLocation PragmaLoc = ConsumeToken(); | 
|  | 406 | Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc); | 
|  | 407 | } | 
|  | 408 |  | 
| Richard Smith | ba3a4f9 | 2016-01-12 21:59:26 +0000 | [diff] [blame] | 409 | void Parser::HandlePragmaDump() { | 
|  | 410 | assert(Tok.is(tok::annot_pragma_dump)); | 
|  | 411 | IdentifierInfo *II = | 
|  | 412 | reinterpret_cast<IdentifierInfo *>(Tok.getAnnotationValue()); | 
|  | 413 | Actions.ActOnPragmaDump(getCurScope(), Tok.getLocation(), II); | 
|  | 414 | ConsumeToken(); | 
|  | 415 | } | 
|  | 416 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 417 | void Parser::HandlePragmaWeak() { | 
|  | 418 | assert(Tok.is(tok::annot_pragma_weak)); | 
|  | 419 | SourceLocation PragmaLoc = ConsumeToken(); | 
|  | 420 | Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc, | 
|  | 421 | Tok.getLocation()); | 
|  | 422 | ConsumeToken(); // The weak name. | 
|  | 423 | } | 
|  | 424 |  | 
|  | 425 | void Parser::HandlePragmaWeakAlias() { | 
|  | 426 | assert(Tok.is(tok::annot_pragma_weakalias)); | 
|  | 427 | SourceLocation PragmaLoc = ConsumeToken(); | 
|  | 428 | IdentifierInfo *WeakName = Tok.getIdentifierInfo(); | 
|  | 429 | SourceLocation WeakNameLoc = Tok.getLocation(); | 
|  | 430 | ConsumeToken(); | 
|  | 431 | IdentifierInfo *AliasName = Tok.getIdentifierInfo(); | 
|  | 432 | SourceLocation AliasNameLoc = Tok.getLocation(); | 
|  | 433 | ConsumeToken(); | 
|  | 434 | Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc, | 
|  | 435 | WeakNameLoc, AliasNameLoc); | 
|  | 436 |  | 
|  | 437 | } | 
|  | 438 |  | 
|  | 439 | void Parser::HandlePragmaRedefineExtname() { | 
|  | 440 | assert(Tok.is(tok::annot_pragma_redefine_extname)); | 
|  | 441 | SourceLocation RedefLoc = ConsumeToken(); | 
|  | 442 | IdentifierInfo *RedefName = Tok.getIdentifierInfo(); | 
|  | 443 | SourceLocation RedefNameLoc = Tok.getLocation(); | 
|  | 444 | ConsumeToken(); | 
|  | 445 | IdentifierInfo *AliasName = Tok.getIdentifierInfo(); | 
|  | 446 | SourceLocation AliasNameLoc = Tok.getLocation(); | 
|  | 447 | ConsumeToken(); | 
|  | 448 | Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc, | 
|  | 449 | RedefNameLoc, AliasNameLoc); | 
|  | 450 | } | 
|  | 451 |  | 
|  | 452 | void Parser::HandlePragmaFPContract() { | 
|  | 453 | assert(Tok.is(tok::annot_pragma_fp_contract)); | 
|  | 454 | tok::OnOffSwitch OOS = | 
|  | 455 | static_cast<tok::OnOffSwitch>( | 
|  | 456 | reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); | 
|  | 457 | Actions.ActOnPragmaFPContract(OOS); | 
|  | 458 | ConsumeToken(); // The annotation token. | 
|  | 459 | } | 
|  | 460 |  | 
| Tareq A. Siraj | 0de0dd4 | 2013-04-16 18:41:26 +0000 | [diff] [blame] | 461 | StmtResult Parser::HandlePragmaCaptured() | 
|  | 462 | { | 
|  | 463 | assert(Tok.is(tok::annot_pragma_captured)); | 
|  | 464 | ConsumeToken(); | 
|  | 465 |  | 
|  | 466 | if (Tok.isNot(tok::l_brace)) { | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 467 | PP.Diag(Tok, diag::err_expected) << tok::l_brace; | 
| Tareq A. Siraj | 0de0dd4 | 2013-04-16 18:41:26 +0000 | [diff] [blame] | 468 | return StmtError(); | 
|  | 469 | } | 
|  | 470 |  | 
| Tareq A. Siraj | 6dfa25a | 2013-04-16 19:37:38 +0000 | [diff] [blame] | 471 | SourceLocation Loc = Tok.getLocation(); | 
|  | 472 |  | 
|  | 473 | ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); | 
| Ben Langmuir | 37943a7 | 2013-05-03 19:00:33 +0000 | [diff] [blame] | 474 | Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default, | 
|  | 475 | /*NumParams=*/1); | 
| Tareq A. Siraj | 6dfa25a | 2013-04-16 19:37:38 +0000 | [diff] [blame] | 476 |  | 
|  | 477 | StmtResult R = ParseCompoundStatement(); | 
|  | 478 | CapturedRegionScope.Exit(); | 
|  | 479 |  | 
|  | 480 | if (R.isInvalid()) { | 
|  | 481 | Actions.ActOnCapturedRegionError(); | 
|  | 482 | return StmtError(); | 
|  | 483 | } | 
|  | 484 |  | 
|  | 485 | return Actions.ActOnCapturedRegionEnd(R.get()); | 
| Tareq A. Siraj | 0de0dd4 | 2013-04-16 18:41:26 +0000 | [diff] [blame] | 486 | } | 
|  | 487 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 488 | namespace { | 
|  | 489 | typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData; | 
|  | 490 | } | 
|  | 491 |  | 
|  | 492 | void Parser::HandlePragmaOpenCLExtension() { | 
|  | 493 | assert(Tok.is(tok::annot_pragma_opencl_extension)); | 
|  | 494 | OpenCLExtData data = | 
|  | 495 | OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue()); | 
|  | 496 | unsigned state = data.getInt(); | 
|  | 497 | IdentifierInfo *ename = data.getPointer(); | 
|  | 498 | SourceLocation NameLoc = Tok.getLocation(); | 
|  | 499 | ConsumeToken(); // The annotation token. | 
|  | 500 |  | 
|  | 501 | OpenCLOptions &f = Actions.getOpenCLOptions(); | 
| Yaxun Liu | 39cf40f | 2016-05-16 17:06:34 +0000 | [diff] [blame] | 502 | auto CLVer = getLangOpts().OpenCLVersion; | 
|  | 503 | auto &Supp = getTargetInfo().getSupportedOpenCLOpts(); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 504 | // OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions, | 
|  | 505 | // overriding all previously issued extension directives, but only if the | 
|  | 506 | // behavior is set to disable." | 
|  | 507 | if (state == 0 && ename->isStr("all")) { | 
| Yaxun Liu | 39cf40f | 2016-05-16 17:06:34 +0000 | [diff] [blame] | 508 | #define OPENCLEXT(nm) \ | 
|  | 509 | if (Supp.is_##nm##_supported_extension(CLVer)) \ | 
|  | 510 | f.nm = 0; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 511 | #include "clang/Basic/OpenCLExtensions.def" | 
|  | 512 | } | 
| Yaxun Liu | 39cf40f | 2016-05-16 17:06:34 +0000 | [diff] [blame] | 513 | #define OPENCLEXT(nm) else if (ename->isStr(#nm)) \ | 
|  | 514 | if (Supp.is_##nm##_supported_extension(CLVer)) \ | 
|  | 515 | f.nm = state; \ | 
|  | 516 | else if (Supp.is_##nm##_supported_core(CLVer)) \ | 
|  | 517 | PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << ename; \ | 
|  | 518 | else \ | 
|  | 519 | PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << ename; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 520 | #include "clang/Basic/OpenCLExtensions.def" | 
|  | 521 | else { | 
|  | 522 | PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename; | 
|  | 523 | return; | 
|  | 524 | } | 
|  | 525 | } | 
|  | 526 |  | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 527 | void Parser::HandlePragmaMSPointersToMembers() { | 
|  | 528 | assert(Tok.is(tok::annot_pragma_ms_pointers_to_members)); | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 529 | LangOptions::PragmaMSPointersToMembersKind RepresentationMethod = | 
|  | 530 | static_cast<LangOptions::PragmaMSPointersToMembersKind>( | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 531 | reinterpret_cast<uintptr_t>(Tok.getAnnotationValue())); | 
|  | 532 | SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. | 
|  | 533 | Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc); | 
|  | 534 | } | 
| Tareq A. Siraj | 0de0dd4 | 2013-04-16 18:41:26 +0000 | [diff] [blame] | 535 |  | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 536 | void Parser::HandlePragmaMSVtorDisp() { | 
|  | 537 | assert(Tok.is(tok::annot_pragma_ms_vtordisp)); | 
|  | 538 | uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()); | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 539 | Sema::PragmaMsStackAction Action = | 
|  | 540 | static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF); | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 541 | MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF); | 
|  | 542 | SourceLocation PragmaLoc = ConsumeToken(); // The annotation token. | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 543 | Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode); | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 544 | } | 
| Tareq A. Siraj | 0de0dd4 | 2013-04-16 18:41:26 +0000 | [diff] [blame] | 545 |  | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 546 | void Parser::HandlePragmaMSPragma() { | 
|  | 547 | assert(Tok.is(tok::annot_pragma_ms_pragma)); | 
|  | 548 | // Grab the tokens out of the annotation and enter them into the stream. | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 549 | auto TheTokens = | 
|  | 550 | (std::pair<std::unique_ptr<Token[]>, size_t> *)Tok.getAnnotationValue(); | 
|  | 551 | PP.EnterTokenStream(std::move(TheTokens->first), TheTokens->second, true); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 552 | SourceLocation PragmaLocation = ConsumeToken(); // The annotation token. | 
|  | 553 | assert(Tok.isAnyIdentifier()); | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 554 | StringRef PragmaName = Tok.getIdentifierInfo()->getName(); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 555 | PP.Lex(Tok); // pragma kind | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 556 |  | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 557 | // Figure out which #pragma we're dealing with.  The switch has no default | 
|  | 558 | // because lex shouldn't emit the annotation token for unrecognized pragmas. | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 559 | typedef bool (Parser::*PragmaHandler)(StringRef, SourceLocation); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 560 | PragmaHandler Handler = llvm::StringSwitch<PragmaHandler>(PragmaName) | 
|  | 561 | .Case("data_seg", &Parser::HandlePragmaMSSegment) | 
|  | 562 | .Case("bss_seg", &Parser::HandlePragmaMSSegment) | 
|  | 563 | .Case("const_seg", &Parser::HandlePragmaMSSegment) | 
|  | 564 | .Case("code_seg", &Parser::HandlePragmaMSSegment) | 
|  | 565 | .Case("section", &Parser::HandlePragmaMSSection) | 
|  | 566 | .Case("init_seg", &Parser::HandlePragmaMSInitSeg); | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 567 |  | 
|  | 568 | if (!(this->*Handler)(PragmaName, PragmaLocation)) { | 
|  | 569 | // Pragma handling failed, and has been diagnosed.  Slurp up the tokens | 
|  | 570 | // until eof (really end of line) to prevent follow-on errors. | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 571 | while (Tok.isNot(tok::eof)) | 
|  | 572 | PP.Lex(Tok); | 
|  | 573 | PP.Lex(Tok); | 
|  | 574 | } | 
|  | 575 | } | 
|  | 576 |  | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 577 | bool Parser::HandlePragmaMSSection(StringRef PragmaName, | 
|  | 578 | SourceLocation PragmaLocation) { | 
|  | 579 | if (Tok.isNot(tok::l_paren)) { | 
|  | 580 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName; | 
|  | 581 | return false; | 
|  | 582 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 583 | PP.Lex(Tok); // ( | 
|  | 584 | // Parsing code for pragma section | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 585 | if (Tok.isNot(tok::string_literal)) { | 
|  | 586 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_section_name) | 
|  | 587 | << PragmaName; | 
|  | 588 | return false; | 
|  | 589 | } | 
|  | 590 | ExprResult StringResult = ParseStringLiteralExpression(); | 
|  | 591 | if (StringResult.isInvalid()) | 
|  | 592 | return false; // Already diagnosed. | 
|  | 593 | StringLiteral *SegmentName = cast<StringLiteral>(StringResult.get()); | 
|  | 594 | if (SegmentName->getCharByteWidth() != 1) { | 
|  | 595 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string) | 
|  | 596 | << PragmaName; | 
|  | 597 | return false; | 
|  | 598 | } | 
| David Majnemer | 48c28fa | 2014-10-22 21:08:43 +0000 | [diff] [blame] | 599 | int SectionFlags = ASTContext::PSF_Read; | 
|  | 600 | bool SectionFlagsAreDefault = true; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 601 | while (Tok.is(tok::comma)) { | 
|  | 602 | PP.Lex(Tok); // , | 
| David Majnemer | 48c28fa | 2014-10-22 21:08:43 +0000 | [diff] [blame] | 603 | // Ignore "long" and "short". | 
|  | 604 | // They are undocumented, but widely used, section attributes which appear | 
|  | 605 | // to do nothing. | 
|  | 606 | if (Tok.is(tok::kw_long) || Tok.is(tok::kw_short)) { | 
|  | 607 | PP.Lex(Tok); // long/short | 
|  | 608 | continue; | 
|  | 609 | } | 
|  | 610 |  | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 611 | if (!Tok.isAnyIdentifier()) { | 
|  | 612 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_action_or_r_paren) | 
|  | 613 | << PragmaName; | 
|  | 614 | return false; | 
|  | 615 | } | 
| Hans Wennborg | 899ded9 | 2014-10-16 20:52:46 +0000 | [diff] [blame] | 616 | ASTContext::PragmaSectionFlag Flag = | 
|  | 617 | llvm::StringSwitch<ASTContext::PragmaSectionFlag>( | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 618 | Tok.getIdentifierInfo()->getName()) | 
| Hans Wennborg | 899ded9 | 2014-10-16 20:52:46 +0000 | [diff] [blame] | 619 | .Case("read", ASTContext::PSF_Read) | 
|  | 620 | .Case("write", ASTContext::PSF_Write) | 
|  | 621 | .Case("execute", ASTContext::PSF_Execute) | 
|  | 622 | .Case("shared", ASTContext::PSF_Invalid) | 
|  | 623 | .Case("nopage", ASTContext::PSF_Invalid) | 
|  | 624 | .Case("nocache", ASTContext::PSF_Invalid) | 
|  | 625 | .Case("discard", ASTContext::PSF_Invalid) | 
|  | 626 | .Case("remove", ASTContext::PSF_Invalid) | 
|  | 627 | .Default(ASTContext::PSF_None); | 
|  | 628 | if (Flag == ASTContext::PSF_None || Flag == ASTContext::PSF_Invalid) { | 
|  | 629 | PP.Diag(PragmaLocation, Flag == ASTContext::PSF_None | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 630 | ? diag::warn_pragma_invalid_specific_action | 
|  | 631 | : diag::warn_pragma_unsupported_action) | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 632 | << PragmaName << Tok.getIdentifierInfo()->getName(); | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 633 | return false; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 634 | } | 
|  | 635 | SectionFlags |= Flag; | 
| David Majnemer | 48c28fa | 2014-10-22 21:08:43 +0000 | [diff] [blame] | 636 | SectionFlagsAreDefault = false; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 637 | PP.Lex(Tok); // Identifier | 
|  | 638 | } | 
| David Majnemer | 48c28fa | 2014-10-22 21:08:43 +0000 | [diff] [blame] | 639 | // If no section attributes are specified, the section will be marked as | 
|  | 640 | // read/write. | 
|  | 641 | if (SectionFlagsAreDefault) | 
|  | 642 | SectionFlags |= ASTContext::PSF_Write; | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 643 | if (Tok.isNot(tok::r_paren)) { | 
|  | 644 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName; | 
|  | 645 | return false; | 
|  | 646 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 647 | PP.Lex(Tok); // ) | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 648 | if (Tok.isNot(tok::eof)) { | 
|  | 649 | PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol) | 
|  | 650 | << PragmaName; | 
|  | 651 | return false; | 
|  | 652 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 653 | PP.Lex(Tok); // eof | 
|  | 654 | Actions.ActOnPragmaMSSection(PragmaLocation, SectionFlags, SegmentName); | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 655 | return true; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 656 | } | 
|  | 657 |  | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 658 | bool Parser::HandlePragmaMSSegment(StringRef PragmaName, | 
|  | 659 | SourceLocation PragmaLocation) { | 
|  | 660 | if (Tok.isNot(tok::l_paren)) { | 
|  | 661 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_lparen) << PragmaName; | 
|  | 662 | return false; | 
|  | 663 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 664 | PP.Lex(Tok); // ( | 
|  | 665 | Sema::PragmaMsStackAction Action = Sema::PSK_Reset; | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 666 | StringRef SlotLabel; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 667 | if (Tok.isAnyIdentifier()) { | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 668 | StringRef PushPop = Tok.getIdentifierInfo()->getName(); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 669 | if (PushPop == "push") | 
|  | 670 | Action = Sema::PSK_Push; | 
|  | 671 | else if (PushPop == "pop") | 
|  | 672 | Action = Sema::PSK_Pop; | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 673 | else { | 
|  | 674 | PP.Diag(PragmaLocation, | 
|  | 675 | diag::warn_pragma_expected_section_push_pop_or_name) | 
|  | 676 | << PragmaName; | 
|  | 677 | return false; | 
|  | 678 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 679 | if (Action != Sema::PSK_Reset) { | 
|  | 680 | PP.Lex(Tok); // push | pop | 
|  | 681 | if (Tok.is(tok::comma)) { | 
|  | 682 | PP.Lex(Tok); // , | 
|  | 683 | // If we've got a comma, we either need a label or a string. | 
|  | 684 | if (Tok.isAnyIdentifier()) { | 
|  | 685 | SlotLabel = Tok.getIdentifierInfo()->getName(); | 
|  | 686 | PP.Lex(Tok); // identifier | 
|  | 687 | if (Tok.is(tok::comma)) | 
|  | 688 | PP.Lex(Tok); | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 689 | else if (Tok.isNot(tok::r_paren)) { | 
|  | 690 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) | 
|  | 691 | << PragmaName; | 
|  | 692 | return false; | 
|  | 693 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 694 | } | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 695 | } else if (Tok.isNot(tok::r_paren)) { | 
|  | 696 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_punc) << PragmaName; | 
|  | 697 | return false; | 
|  | 698 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 699 | } | 
|  | 700 | } | 
|  | 701 | // Grab the string literal for our section name. | 
|  | 702 | StringLiteral *SegmentName = nullptr; | 
|  | 703 | if (Tok.isNot(tok::r_paren)) { | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 704 | if (Tok.isNot(tok::string_literal)) { | 
|  | 705 | unsigned DiagID = Action != Sema::PSK_Reset ? !SlotLabel.empty() ? | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 706 | diag::warn_pragma_expected_section_name : | 
|  | 707 | diag::warn_pragma_expected_section_label_or_name : | 
|  | 708 | diag::warn_pragma_expected_section_push_pop_or_name; | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 709 | PP.Diag(PragmaLocation, DiagID) << PragmaName; | 
|  | 710 | return false; | 
|  | 711 | } | 
|  | 712 | ExprResult StringResult = ParseStringLiteralExpression(); | 
|  | 713 | if (StringResult.isInvalid()) | 
|  | 714 | return false; // Already diagnosed. | 
|  | 715 | SegmentName = cast<StringLiteral>(StringResult.get()); | 
|  | 716 | if (SegmentName->getCharByteWidth() != 1) { | 
|  | 717 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string) | 
|  | 718 | << PragmaName; | 
|  | 719 | return false; | 
|  | 720 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 721 | // Setting section "" has no effect | 
|  | 722 | if (SegmentName->getLength()) | 
|  | 723 | Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); | 
|  | 724 | } | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 725 | if (Tok.isNot(tok::r_paren)) { | 
|  | 726 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_rparen) << PragmaName; | 
|  | 727 | return false; | 
|  | 728 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 729 | PP.Lex(Tok); // ) | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 730 | if (Tok.isNot(tok::eof)) { | 
|  | 731 | PP.Diag(PragmaLocation, diag::warn_pragma_extra_tokens_at_eol) | 
|  | 732 | << PragmaName; | 
|  | 733 | return false; | 
|  | 734 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 735 | PP.Lex(Tok); // eof | 
|  | 736 | Actions.ActOnPragmaMSSeg(PragmaLocation, Action, SlotLabel, | 
|  | 737 | SegmentName, PragmaName); | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 738 | return true; | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 739 | } | 
|  | 740 |  | 
| Reid Kleckner | 1a711b1 | 2014-07-22 00:53:05 +0000 | [diff] [blame] | 741 | // #pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} ) | 
| Reid Kleckner | 722b1df | 2014-07-18 00:13:16 +0000 | [diff] [blame] | 742 | bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName, | 
|  | 743 | SourceLocation PragmaLocation) { | 
| David Majnemer | ad2986e | 2014-08-14 06:35:08 +0000 | [diff] [blame] | 744 | if (getTargetInfo().getTriple().getEnvironment() != llvm::Triple::MSVC) { | 
|  | 745 | PP.Diag(PragmaLocation, diag::warn_pragma_init_seg_unsupported_target); | 
|  | 746 | return false; | 
|  | 747 | } | 
|  | 748 |  | 
| Reid Kleckner | 1a711b1 | 2014-07-22 00:53:05 +0000 | [diff] [blame] | 749 | if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen, | 
|  | 750 | PragmaName)) | 
|  | 751 | return false; | 
|  | 752 |  | 
|  | 753 | // Parse either the known section names or the string section name. | 
|  | 754 | StringLiteral *SegmentName = nullptr; | 
|  | 755 | if (Tok.isAnyIdentifier()) { | 
|  | 756 | auto *II = Tok.getIdentifierInfo(); | 
|  | 757 | StringRef Section = llvm::StringSwitch<StringRef>(II->getName()) | 
|  | 758 | .Case("compiler", "\".CRT$XCC\"") | 
|  | 759 | .Case("lib", "\".CRT$XCL\"") | 
|  | 760 | .Case("user", "\".CRT$XCU\"") | 
|  | 761 | .Default(""); | 
|  | 762 |  | 
|  | 763 | if (!Section.empty()) { | 
|  | 764 | // Pretend the user wrote the appropriate string literal here. | 
|  | 765 | Token Toks[1]; | 
|  | 766 | Toks[0].startToken(); | 
|  | 767 | Toks[0].setKind(tok::string_literal); | 
|  | 768 | Toks[0].setLocation(Tok.getLocation()); | 
|  | 769 | Toks[0].setLiteralData(Section.data()); | 
|  | 770 | Toks[0].setLength(Section.size()); | 
|  | 771 | SegmentName = | 
|  | 772 | cast<StringLiteral>(Actions.ActOnStringLiteral(Toks, nullptr).get()); | 
|  | 773 | PP.Lex(Tok); | 
|  | 774 | } | 
|  | 775 | } else if (Tok.is(tok::string_literal)) { | 
|  | 776 | ExprResult StringResult = ParseStringLiteralExpression(); | 
|  | 777 | if (StringResult.isInvalid()) | 
|  | 778 | return false; | 
|  | 779 | SegmentName = cast<StringLiteral>(StringResult.get()); | 
|  | 780 | if (SegmentName->getCharByteWidth() != 1) { | 
|  | 781 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_non_wide_string) | 
|  | 782 | << PragmaName; | 
|  | 783 | return false; | 
|  | 784 | } | 
|  | 785 | // FIXME: Add support for the '[, func-name]' part of the pragma. | 
|  | 786 | } | 
|  | 787 |  | 
|  | 788 | if (!SegmentName) { | 
|  | 789 | PP.Diag(PragmaLocation, diag::warn_pragma_expected_init_seg) << PragmaName; | 
|  | 790 | return false; | 
|  | 791 | } | 
|  | 792 |  | 
|  | 793 | if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen, | 
|  | 794 | PragmaName) || | 
|  | 795 | ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol, | 
|  | 796 | PragmaName)) | 
|  | 797 | return false; | 
|  | 798 |  | 
|  | 799 | Actions.ActOnPragmaMSInitSeg(PragmaLocation, SegmentName); | 
|  | 800 | return true; | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 801 | } | 
|  | 802 |  | 
| Benjamin Kramer | e003ca2 | 2015-10-28 13:54:16 +0000 | [diff] [blame] | 803 | namespace { | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 804 | struct PragmaLoopHintInfo { | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 805 | Token PragmaName; | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 806 | Token Option; | 
| Benjamin Kramer | fa7f855 | 2015-08-05 09:39:57 +0000 | [diff] [blame] | 807 | ArrayRef<Token> Toks; | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 808 | }; | 
| Benjamin Kramer | e003ca2 | 2015-10-28 13:54:16 +0000 | [diff] [blame] | 809 | } // end anonymous namespace | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 810 |  | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 811 | static std::string PragmaLoopHintString(Token PragmaName, Token Option) { | 
|  | 812 | std::string PragmaString; | 
|  | 813 | if (PragmaName.getIdentifierInfo()->getName() == "loop") { | 
|  | 814 | PragmaString = "clang loop "; | 
|  | 815 | PragmaString += Option.getIdentifierInfo()->getName(); | 
|  | 816 | } else { | 
|  | 817 | assert(PragmaName.getIdentifierInfo()->getName() == "unroll" && | 
|  | 818 | "Unexpected pragma name"); | 
|  | 819 | PragmaString = "unroll"; | 
|  | 820 | } | 
|  | 821 | return PragmaString; | 
|  | 822 | } | 
|  | 823 |  | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 824 | bool Parser::HandlePragmaLoopHint(LoopHint &Hint) { | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 825 | assert(Tok.is(tok::annot_pragma_loop_hint)); | 
|  | 826 | PragmaLoopHintInfo *Info = | 
|  | 827 | static_cast<PragmaLoopHintInfo *>(Tok.getAnnotationValue()); | 
|  | 828 |  | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 829 | IdentifierInfo *PragmaNameInfo = Info->PragmaName.getIdentifierInfo(); | 
|  | 830 | Hint.PragmaNameLoc = IdentifierLoc::create( | 
|  | 831 | Actions.Context, Info->PragmaName.getLocation(), PragmaNameInfo); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 832 |  | 
| Aaron Ballman | ef940aa | 2014-07-31 21:24:32 +0000 | [diff] [blame] | 833 | // It is possible that the loop hint has no option identifier, such as | 
|  | 834 | // #pragma unroll(4). | 
|  | 835 | IdentifierInfo *OptionInfo = Info->Option.is(tok::identifier) | 
|  | 836 | ? Info->Option.getIdentifierInfo() | 
|  | 837 | : nullptr; | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 838 | Hint.OptionLoc = IdentifierLoc::create( | 
|  | 839 | Actions.Context, Info->Option.getLocation(), OptionInfo); | 
|  | 840 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 841 | llvm::ArrayRef<Token> Toks = Info->Toks; | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 842 |  | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 843 | // Return a valid hint if pragma unroll or nounroll were specified | 
|  | 844 | // without an argument. | 
|  | 845 | bool PragmaUnroll = PragmaNameInfo->getName() == "unroll"; | 
|  | 846 | bool PragmaNoUnroll = PragmaNameInfo->getName() == "nounroll"; | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 847 | if (Toks.empty() && (PragmaUnroll || PragmaNoUnroll)) { | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 848 | ConsumeToken(); // The annotation token. | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 849 | Hint.Range = Info->PragmaName.getLocation(); | 
|  | 850 | return true; | 
|  | 851 | } | 
|  | 852 |  | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 853 | // The constant expression is always followed by an eof token, which increases | 
|  | 854 | // the TokSize by 1. | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 855 | assert(!Toks.empty() && | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 856 | "PragmaLoopHintInfo::Toks must contain at least one token."); | 
|  | 857 |  | 
|  | 858 | // If no option is specified the argument is assumed to be a constant expr. | 
| Tyler Nowicki | 24853c1 | 2015-06-08 23:13:43 +0000 | [diff] [blame] | 859 | bool OptionUnroll = false; | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 860 | bool OptionDistribute = false; | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 861 | bool StateOption = false; | 
| Tyler Nowicki | 24853c1 | 2015-06-08 23:13:43 +0000 | [diff] [blame] | 862 | if (OptionInfo) { // Pragma Unroll does not specify an option. | 
|  | 863 | OptionUnroll = OptionInfo->isStr("unroll"); | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 864 | OptionDistribute = OptionInfo->isStr("distribute"); | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 865 | StateOption = llvm::StringSwitch<bool>(OptionInfo->getName()) | 
|  | 866 | .Case("vectorize", true) | 
|  | 867 | .Case("interleave", true) | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 868 | .Default(false) || | 
|  | 869 | OptionUnroll || OptionDistribute; | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 870 | } | 
|  | 871 |  | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 872 | bool AssumeSafetyArg = !OptionUnroll && !OptionDistribute; | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 873 | // Verify loop hint has an argument. | 
|  | 874 | if (Toks[0].is(tok::eof)) { | 
|  | 875 | ConsumeToken(); // The annotation token. | 
|  | 876 | Diag(Toks[0].getLocation(), diag::err_pragma_loop_missing_argument) | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 877 | << /*StateArgument=*/StateOption << /*FullKeyword=*/OptionUnroll | 
|  | 878 | << /*AssumeSafetyKeyword=*/AssumeSafetyArg; | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 879 | return false; | 
|  | 880 | } | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 881 |  | 
|  | 882 | // Validate the argument. | 
|  | 883 | if (StateOption) { | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 884 | ConsumeToken(); // The annotation token. | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 885 | SourceLocation StateLoc = Toks[0].getLocation(); | 
|  | 886 | IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo(); | 
| Adam Nemet | 50de4e8 | 2016-04-19 22:17:45 +0000 | [diff] [blame] | 887 |  | 
|  | 888 | bool Valid = StateInfo && | 
|  | 889 | llvm::StringSwitch<bool>(StateInfo->getName()) | 
|  | 890 | .Cases("enable", "disable", true) | 
|  | 891 | .Case("full", OptionUnroll) | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 892 | .Case("assume_safety", AssumeSafetyArg) | 
| Adam Nemet | 50de4e8 | 2016-04-19 22:17:45 +0000 | [diff] [blame] | 893 | .Default(false); | 
|  | 894 | if (!Valid) { | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 895 | Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword) | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 896 | << /*FullKeyword=*/OptionUnroll | 
|  | 897 | << /*AssumeSafetyKeyword=*/AssumeSafetyArg; | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 898 | return false; | 
|  | 899 | } | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 900 | if (Toks.size() > 2) | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 901 | Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 902 | << PragmaLoopHintString(Info->PragmaName, Info->Option); | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 903 | Hint.StateLoc = IdentifierLoc::create(Actions.Context, StateLoc, StateInfo); | 
|  | 904 | } else { | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 905 | // Enter constant expression including eof terminator into token stream. | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 906 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/false); | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 907 | ConsumeToken(); // The annotation token. | 
|  | 908 |  | 
|  | 909 | ExprResult R = ParseConstantExpression(); | 
|  | 910 |  | 
|  | 911 | // Tokens following an error in an ill-formed constant expression will | 
|  | 912 | // remain in the token stream and must be removed. | 
|  | 913 | if (Tok.isNot(tok::eof)) { | 
|  | 914 | Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 915 | << PragmaLoopHintString(Info->PragmaName, Info->Option); | 
|  | 916 | while (Tok.isNot(tok::eof)) | 
|  | 917 | ConsumeAnyToken(); | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 918 | } | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 919 |  | 
|  | 920 | ConsumeToken(); // Consume the constant expression eof terminator. | 
|  | 921 |  | 
|  | 922 | if (R.isInvalid() || | 
|  | 923 | Actions.CheckLoopHintExpr(R.get(), Toks[0].getLocation())) | 
|  | 924 | return false; | 
|  | 925 |  | 
|  | 926 | // Argument is a constant expression with an integer type. | 
|  | 927 | Hint.ValueExpr = R.get(); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 928 | } | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 929 |  | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 930 | Hint.Range = SourceRange(Info->PragmaName.getLocation(), | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 931 | Info->Toks.back().getLocation()); | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 932 | return true; | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 933 | } | 
|  | 934 |  | 
|  | 935 | // #pragma GCC visibility comes in two variants: | 
|  | 936 | //   'push' '(' [visibility] ')' | 
|  | 937 | //   'pop' | 
| Douglas Gregor | c7d6576 | 2010-09-09 22:45:38 +0000 | [diff] [blame] | 938 | void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, | 
|  | 939 | PragmaIntroducerKind Introducer, | 
|  | 940 | Token &VisTok) { | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 941 | SourceLocation VisLoc = VisTok.getLocation(); | 
|  | 942 |  | 
|  | 943 | Token Tok; | 
| Joerg Sonnenberger | 869f0b7 | 2011-07-20 01:03:50 +0000 | [diff] [blame] | 944 | PP.LexUnexpandedToken(Tok); | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 945 |  | 
|  | 946 | const IdentifierInfo *PushPop = Tok.getIdentifierInfo(); | 
|  | 947 |  | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 948 | const IdentifierInfo *VisType; | 
|  | 949 | if (PushPop && PushPop->isStr("pop")) { | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 950 | VisType = nullptr; | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 951 | } else if (PushPop && PushPop->isStr("push")) { | 
| Joerg Sonnenberger | 869f0b7 | 2011-07-20 01:03:50 +0000 | [diff] [blame] | 952 | PP.LexUnexpandedToken(Tok); | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 953 | if (Tok.isNot(tok::l_paren)) { | 
|  | 954 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) | 
|  | 955 | << "visibility"; | 
|  | 956 | return; | 
|  | 957 | } | 
| Joerg Sonnenberger | 869f0b7 | 2011-07-20 01:03:50 +0000 | [diff] [blame] | 958 | PP.LexUnexpandedToken(Tok); | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 959 | VisType = Tok.getIdentifierInfo(); | 
|  | 960 | if (!VisType) { | 
|  | 961 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) | 
|  | 962 | << "visibility"; | 
|  | 963 | return; | 
|  | 964 | } | 
| Joerg Sonnenberger | 869f0b7 | 2011-07-20 01:03:50 +0000 | [diff] [blame] | 965 | PP.LexUnexpandedToken(Tok); | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 966 | if (Tok.isNot(tok::r_paren)) { | 
|  | 967 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) | 
|  | 968 | << "visibility"; | 
|  | 969 | return; | 
|  | 970 | } | 
|  | 971 | } else { | 
|  | 972 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) | 
|  | 973 | << "visibility"; | 
|  | 974 | return; | 
|  | 975 | } | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 976 | SourceLocation EndLoc = Tok.getLocation(); | 
| Joerg Sonnenberger | 869f0b7 | 2011-07-20 01:03:50 +0000 | [diff] [blame] | 977 | PP.LexUnexpandedToken(Tok); | 
| Peter Collingbourne | 2f1e36b | 2011-02-28 02:37:51 +0000 | [diff] [blame] | 978 | if (Tok.isNot(tok::eod)) { | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 979 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 980 | << "visibility"; | 
|  | 981 | return; | 
|  | 982 | } | 
|  | 983 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 984 | auto Toks = llvm::make_unique<Token[]>(1); | 
| Rafael Espindola | 273fd77 | 2012-01-26 02:02:57 +0000 | [diff] [blame] | 985 | Toks[0].startToken(); | 
|  | 986 | Toks[0].setKind(tok::annot_pragma_vis); | 
|  | 987 | Toks[0].setLocation(VisLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 988 | Toks[0].setAnnotationEndLoc(EndLoc); | 
| Rafael Espindola | 273fd77 | 2012-01-26 02:02:57 +0000 | [diff] [blame] | 989 | Toks[0].setAnnotationValue( | 
|  | 990 | const_cast<void*>(static_cast<const void*>(VisType))); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 991 | PP.EnterTokenStream(std::move(Toks), 1, /*DisableMacroExpansion=*/true); | 
| Eli Friedman | 570024a | 2010-08-05 06:57:20 +0000 | [diff] [blame] | 992 | } | 
|  | 993 |  | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 994 | // #pragma pack(...) comes in the following delicious flavors: | 
|  | 995 | //   pack '(' [integer] ')' | 
|  | 996 | //   pack '(' 'show' ')' | 
|  | 997 | //   pack '(' ('push' | 'pop') [',' identifier] [, integer] ')' | 
| Douglas Gregor | c7d6576 | 2010-09-09 22:45:38 +0000 | [diff] [blame] | 998 | void PragmaPackHandler::HandlePragma(Preprocessor &PP, | 
|  | 999 | PragmaIntroducerKind Introducer, | 
|  | 1000 | Token &PackTok) { | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1001 | SourceLocation PackLoc = PackTok.getLocation(); | 
|  | 1002 |  | 
|  | 1003 | Token Tok; | 
|  | 1004 | PP.Lex(Tok); | 
|  | 1005 | if (Tok.isNot(tok::l_paren)) { | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1006 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "pack"; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1007 | return; | 
|  | 1008 | } | 
|  | 1009 |  | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1010 | Sema::PragmaMsStackAction Action = Sema::PSK_Reset; | 
|  | 1011 | StringRef SlotLabel; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1012 | Token Alignment; | 
|  | 1013 | Alignment.startToken(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1014 | PP.Lex(Tok); | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1015 | if (Tok.is(tok::numeric_constant)) { | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1016 | Alignment = Tok; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1017 |  | 
|  | 1018 | PP.Lex(Tok); | 
| Eli Friedman | 055c970 | 2011-11-02 01:53:16 +0000 | [diff] [blame] | 1019 |  | 
|  | 1020 | // In MSVC/gcc, #pragma pack(4) sets the alignment without affecting | 
|  | 1021 | // the push/pop stack. | 
|  | 1022 | // In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4) | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1023 | Action = | 
|  | 1024 | PP.getLangOpts().ApplePragmaPack ? Sema::PSK_Push_Set : Sema::PSK_Set; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1025 | } else if (Tok.is(tok::identifier)) { | 
|  | 1026 | const IdentifierInfo *II = Tok.getIdentifierInfo(); | 
| Chris Lattner | e3d20d9 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 1027 | if (II->isStr("show")) { | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1028 | Action = Sema::PSK_Show; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1029 | PP.Lex(Tok); | 
|  | 1030 | } else { | 
| Chris Lattner | e3d20d9 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 1031 | if (II->isStr("push")) { | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1032 | Action = Sema::PSK_Push; | 
| Chris Lattner | e3d20d9 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 1033 | } else if (II->isStr("pop")) { | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1034 | Action = Sema::PSK_Pop; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1035 | } else { | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1036 | PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) << "pack"; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1037 | return; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1038 | } | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1039 | PP.Lex(Tok); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1040 |  | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1041 | if (Tok.is(tok::comma)) { | 
|  | 1042 | PP.Lex(Tok); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1043 |  | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1044 | if (Tok.is(tok::numeric_constant)) { | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1045 | Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1046 | Alignment = Tok; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1047 |  | 
|  | 1048 | PP.Lex(Tok); | 
|  | 1049 | } else if (Tok.is(tok::identifier)) { | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1050 | SlotLabel = Tok.getIdentifierInfo()->getName(); | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1051 | PP.Lex(Tok); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1052 |  | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1053 | if (Tok.is(tok::comma)) { | 
|  | 1054 | PP.Lex(Tok); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1055 |  | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1056 | if (Tok.isNot(tok::numeric_constant)) { | 
| Chris Lattner | e3d20d9 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 1057 | PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1058 | return; | 
|  | 1059 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1060 |  | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1061 | Action = (Sema::PragmaMsStackAction)(Action | Sema::PSK_Set); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1062 | Alignment = Tok; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1063 |  | 
|  | 1064 | PP.Lex(Tok); | 
|  | 1065 | } | 
|  | 1066 | } else { | 
| Chris Lattner | e3d20d9 | 2008-11-23 21:45:46 +0000 | [diff] [blame] | 1067 | PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_malformed); | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1068 | return; | 
|  | 1069 | } | 
|  | 1070 | } | 
|  | 1071 | } | 
| David Blaikie | bbafb8a | 2012-03-11 07:00:24 +0000 | [diff] [blame] | 1072 | } else if (PP.getLangOpts().ApplePragmaPack) { | 
| Eli Friedman | 055c970 | 2011-11-02 01:53:16 +0000 | [diff] [blame] | 1073 | // In MSVC/gcc, #pragma pack() resets the alignment without affecting | 
|  | 1074 | // the push/pop stack. | 
|  | 1075 | // In Apple gcc #pragma pack() is equivalent to #pragma pack(pop). | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1076 | Action = Sema::PSK_Pop; | 
| Sebastian Redl | 17f2c7d | 2008-12-09 13:15:23 +0000 | [diff] [blame] | 1077 | } | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1078 |  | 
|  | 1079 | if (Tok.isNot(tok::r_paren)) { | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1080 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) << "pack"; | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1081 | return; | 
|  | 1082 | } | 
|  | 1083 |  | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1084 | SourceLocation RParenLoc = Tok.getLocation(); | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1085 | PP.Lex(Tok); | 
| Peter Collingbourne | 2f1e36b | 2011-02-28 02:37:51 +0000 | [diff] [blame] | 1086 | if (Tok.isNot(tok::eod)) { | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1087 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "pack"; | 
|  | 1088 | return; | 
|  | 1089 | } | 
|  | 1090 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1091 | PragmaPackInfo *Info = | 
|  | 1092 | PP.getPreprocessorAllocator().Allocate<PragmaPackInfo>(1); | 
| Denis Zobnin | 10c4f45 | 2016-04-29 18:17:40 +0000 | [diff] [blame] | 1093 | Info->Action = Action; | 
|  | 1094 | Info->SlotLabel = SlotLabel; | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1095 | Info->Alignment = Alignment; | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 1096 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1097 | MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), | 
|  | 1098 | 1); | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 1099 | Toks[0].startToken(); | 
|  | 1100 | Toks[0].setKind(tok::annot_pragma_pack); | 
|  | 1101 | Toks[0].setLocation(PackLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1102 | Toks[0].setAnnotationEndLoc(RParenLoc); | 
| Eli Friedman | ec52f92 | 2012-02-23 23:47:16 +0000 | [diff] [blame] | 1103 | Toks[0].setAnnotationValue(static_cast<void*>(Info)); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1104 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Daniel Dunbar | 921b968 | 2008-10-04 19:21:03 +0000 | [diff] [blame] | 1105 | } | 
|  | 1106 |  | 
| Fariborz Jahanian | 743dda4 | 2011-04-25 18:49:15 +0000 | [diff] [blame] | 1107 | // #pragma ms_struct on | 
|  | 1108 | // #pragma ms_struct off | 
|  | 1109 | void PragmaMSStructHandler::HandlePragma(Preprocessor &PP, | 
|  | 1110 | PragmaIntroducerKind Introducer, | 
|  | 1111 | Token &MSStructTok) { | 
| Nico Weber | 779355f | 2016-03-02 23:22:00 +0000 | [diff] [blame] | 1112 | PragmaMSStructKind Kind = PMSST_OFF; | 
|  | 1113 |  | 
| Fariborz Jahanian | 743dda4 | 2011-04-25 18:49:15 +0000 | [diff] [blame] | 1114 | Token Tok; | 
|  | 1115 | PP.Lex(Tok); | 
|  | 1116 | if (Tok.isNot(tok::identifier)) { | 
|  | 1117 | PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); | 
|  | 1118 | return; | 
|  | 1119 | } | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1120 | SourceLocation EndLoc = Tok.getLocation(); | 
| Fariborz Jahanian | 743dda4 | 2011-04-25 18:49:15 +0000 | [diff] [blame] | 1121 | const IdentifierInfo *II = Tok.getIdentifierInfo(); | 
|  | 1122 | if (II->isStr("on")) { | 
| Nico Weber | 779355f | 2016-03-02 23:22:00 +0000 | [diff] [blame] | 1123 | Kind = PMSST_ON; | 
| Fariborz Jahanian | 743dda4 | 2011-04-25 18:49:15 +0000 | [diff] [blame] | 1124 | PP.Lex(Tok); | 
|  | 1125 | } | 
|  | 1126 | else if (II->isStr("off") || II->isStr("reset")) | 
|  | 1127 | PP.Lex(Tok); | 
|  | 1128 | else { | 
|  | 1129 | PP.Diag(Tok.getLocation(), diag::warn_pragma_ms_struct); | 
|  | 1130 | return; | 
|  | 1131 | } | 
|  | 1132 |  | 
|  | 1133 | if (Tok.isNot(tok::eod)) { | 
| Daniel Dunbar | 340cf24 | 2012-02-29 01:38:22 +0000 | [diff] [blame] | 1134 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 1135 | << "ms_struct"; | 
| Fariborz Jahanian | 743dda4 | 2011-04-25 18:49:15 +0000 | [diff] [blame] | 1136 | return; | 
|  | 1137 | } | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1138 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1139 | MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), | 
|  | 1140 | 1); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1141 | Toks[0].startToken(); | 
|  | 1142 | Toks[0].setKind(tok::annot_pragma_msstruct); | 
|  | 1143 | Toks[0].setLocation(MSStructTok.getLocation()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1144 | Toks[0].setAnnotationEndLoc(EndLoc); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1145 | Toks[0].setAnnotationValue(reinterpret_cast<void*>( | 
|  | 1146 | static_cast<uintptr_t>(Kind))); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1147 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Fariborz Jahanian | 743dda4 | 2011-04-25 18:49:15 +0000 | [diff] [blame] | 1148 | } | 
|  | 1149 |  | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1150 | // #pragma 'align' '=' {'native','natural','mac68k','power','reset'} | 
|  | 1151 | // #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1152 | static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok, | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1153 | bool IsOptions) { | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1154 | Token Tok; | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1155 |  | 
|  | 1156 | if (IsOptions) { | 
|  | 1157 | PP.Lex(Tok); | 
|  | 1158 | if (Tok.isNot(tok::identifier) || | 
|  | 1159 | !Tok.getIdentifierInfo()->isStr("align")) { | 
|  | 1160 | PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align); | 
|  | 1161 | return; | 
|  | 1162 | } | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1163 | } | 
| Daniel Dunbar | 663e809 | 2010-05-27 18:42:09 +0000 | [diff] [blame] | 1164 |  | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1165 | PP.Lex(Tok); | 
|  | 1166 | if (Tok.isNot(tok::equal)) { | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1167 | PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal) | 
|  | 1168 | << IsOptions; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1169 | return; | 
|  | 1170 | } | 
|  | 1171 |  | 
|  | 1172 | PP.Lex(Tok); | 
|  | 1173 | if (Tok.isNot(tok::identifier)) { | 
|  | 1174 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1175 | << (IsOptions ? "options" : "align"); | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1176 | return; | 
|  | 1177 | } | 
|  | 1178 |  | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1179 | Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1180 | const IdentifierInfo *II = Tok.getIdentifierInfo(); | 
| Daniel Dunbar | 663e809 | 2010-05-27 18:42:09 +0000 | [diff] [blame] | 1181 | if (II->isStr("native")) | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1182 | Kind = Sema::POAK_Native; | 
| Daniel Dunbar | 663e809 | 2010-05-27 18:42:09 +0000 | [diff] [blame] | 1183 | else if (II->isStr("natural")) | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1184 | Kind = Sema::POAK_Natural; | 
| Daniel Dunbar | 9c84d4a | 2010-05-27 18:42:17 +0000 | [diff] [blame] | 1185 | else if (II->isStr("packed")) | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1186 | Kind = Sema::POAK_Packed; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1187 | else if (II->isStr("power")) | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1188 | Kind = Sema::POAK_Power; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1189 | else if (II->isStr("mac68k")) | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1190 | Kind = Sema::POAK_Mac68k; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1191 | else if (II->isStr("reset")) | 
| John McCall | faf5fb4 | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1192 | Kind = Sema::POAK_Reset; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1193 | else { | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1194 | PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option) | 
|  | 1195 | << IsOptions; | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1196 | return; | 
|  | 1197 | } | 
|  | 1198 |  | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1199 | SourceLocation EndLoc = Tok.getLocation(); | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1200 | PP.Lex(Tok); | 
| Peter Collingbourne | 2f1e36b | 2011-02-28 02:37:51 +0000 | [diff] [blame] | 1201 | if (Tok.isNot(tok::eod)) { | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1202 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1203 | << (IsOptions ? "options" : "align"); | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1204 | return; | 
|  | 1205 | } | 
|  | 1206 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1207 | MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), | 
|  | 1208 | 1); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1209 | Toks[0].startToken(); | 
|  | 1210 | Toks[0].setKind(tok::annot_pragma_align); | 
|  | 1211 | Toks[0].setLocation(FirstTok.getLocation()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1212 | Toks[0].setAnnotationEndLoc(EndLoc); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1213 | Toks[0].setAnnotationValue(reinterpret_cast<void*>( | 
|  | 1214 | static_cast<uintptr_t>(Kind))); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1215 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1216 | } | 
|  | 1217 |  | 
| Douglas Gregor | c7d6576 | 2010-09-09 22:45:38 +0000 | [diff] [blame] | 1218 | void PragmaAlignHandler::HandlePragma(Preprocessor &PP, | 
|  | 1219 | PragmaIntroducerKind Introducer, | 
|  | 1220 | Token &AlignTok) { | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1221 | ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false); | 
| Daniel Dunbar | cb82acb | 2010-07-31 19:17:07 +0000 | [diff] [blame] | 1222 | } | 
|  | 1223 |  | 
| Douglas Gregor | c7d6576 | 2010-09-09 22:45:38 +0000 | [diff] [blame] | 1224 | void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, | 
|  | 1225 | PragmaIntroducerKind Introducer, | 
|  | 1226 | Token &OptionsTok) { | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1227 | ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true); | 
| Daniel Dunbar | 75c9be7 | 2010-05-26 23:29:06 +0000 | [diff] [blame] | 1228 | } | 
|  | 1229 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1230 | // #pragma unused(identifier) | 
| Douglas Gregor | c7d6576 | 2010-09-09 22:45:38 +0000 | [diff] [blame] | 1231 | void PragmaUnusedHandler::HandlePragma(Preprocessor &PP, | 
|  | 1232 | PragmaIntroducerKind Introducer, | 
|  | 1233 | Token &UnusedTok) { | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1234 | // FIXME: Should we be expanding macros here? My guess is no. | 
|  | 1235 | SourceLocation UnusedLoc = UnusedTok.getLocation(); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1236 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1237 | // Lex the left '('. | 
|  | 1238 | Token Tok; | 
|  | 1239 | PP.Lex(Tok); | 
|  | 1240 | if (Tok.isNot(tok::l_paren)) { | 
|  | 1241 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) << "unused"; | 
|  | 1242 | return; | 
|  | 1243 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1244 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1245 | // Lex the declaration reference(s). | 
| Chris Lattner | 0e62c1c | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1246 | SmallVector<Token, 5> Identifiers; | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1247 | SourceLocation RParenLoc; | 
|  | 1248 | bool LexID = true; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1249 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1250 | while (true) { | 
|  | 1251 | PP.Lex(Tok); | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1252 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1253 | if (LexID) { | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1254 | if (Tok.is(tok::identifier)) { | 
| Ted Kremenek | fb50bf5 | 2009-08-03 23:24:57 +0000 | [diff] [blame] | 1255 | Identifiers.push_back(Tok); | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1256 | LexID = false; | 
|  | 1257 | continue; | 
|  | 1258 | } | 
|  | 1259 |  | 
| Ted Kremenek | fb50bf5 | 2009-08-03 23:24:57 +0000 | [diff] [blame] | 1260 | // Illegal token! | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1261 | PP.Diag(Tok.getLocation(), diag::warn_pragma_unused_expected_var); | 
|  | 1262 | return; | 
|  | 1263 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1264 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1265 | // We are execting a ')' or a ','. | 
|  | 1266 | if (Tok.is(tok::comma)) { | 
|  | 1267 | LexID = true; | 
|  | 1268 | continue; | 
|  | 1269 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1270 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1271 | if (Tok.is(tok::r_paren)) { | 
|  | 1272 | RParenLoc = Tok.getLocation(); | 
|  | 1273 | break; | 
|  | 1274 | } | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1275 |  | 
| Ted Kremenek | fb50bf5 | 2009-08-03 23:24:57 +0000 | [diff] [blame] | 1276 | // Illegal token! | 
| David Majnemer | 8896981 | 2014-02-10 19:06:37 +0000 | [diff] [blame] | 1277 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_punc) << "unused"; | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1278 | return; | 
|  | 1279 | } | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1280 |  | 
|  | 1281 | PP.Lex(Tok); | 
| Peter Collingbourne | 2f1e36b | 2011-02-28 02:37:51 +0000 | [diff] [blame] | 1282 | if (Tok.isNot(tok::eod)) { | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1283 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << | 
|  | 1284 | "unused"; | 
|  | 1285 | return; | 
|  | 1286 | } | 
|  | 1287 |  | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1288 | // Verify that we have a location for the right parenthesis. | 
|  | 1289 | assert(RParenLoc.isValid() && "Valid '#pragma unused' must have ')'"); | 
| Ted Kremenek | fb50bf5 | 2009-08-03 23:24:57 +0000 | [diff] [blame] | 1290 | assert(!Identifiers.empty() && "Valid '#pragma unused' must have arguments"); | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1291 |  | 
| Argyrios Kyrtzidis | ee56962 | 2011-01-17 18:58:44 +0000 | [diff] [blame] | 1292 | // For each identifier token, insert into the token stream a | 
|  | 1293 | // annot_pragma_unused token followed by the identifier token. | 
|  | 1294 | // This allows us to cache a "#pragma unused" that occurs inside an inline | 
|  | 1295 | // C++ member function. | 
|  | 1296 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1297 | MutableArrayRef<Token> Toks( | 
|  | 1298 | PP.getPreprocessorAllocator().Allocate<Token>(2 * Identifiers.size()), | 
|  | 1299 | 2 * Identifiers.size()); | 
| Argyrios Kyrtzidis | ee56962 | 2011-01-17 18:58:44 +0000 | [diff] [blame] | 1300 | for (unsigned i=0; i != Identifiers.size(); i++) { | 
|  | 1301 | Token &pragmaUnusedTok = Toks[2*i], &idTok = Toks[2*i+1]; | 
|  | 1302 | pragmaUnusedTok.startToken(); | 
|  | 1303 | pragmaUnusedTok.setKind(tok::annot_pragma_unused); | 
|  | 1304 | pragmaUnusedTok.setLocation(UnusedLoc); | 
|  | 1305 | idTok = Identifiers[i]; | 
|  | 1306 | } | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1307 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Ted Kremenek | fd14fad | 2009-03-23 22:28:25 +0000 | [diff] [blame] | 1308 | } | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1309 |  | 
|  | 1310 | // #pragma weak identifier | 
|  | 1311 | // #pragma weak identifier '=' identifier | 
| Douglas Gregor | c7d6576 | 2010-09-09 22:45:38 +0000 | [diff] [blame] | 1312 | void PragmaWeakHandler::HandlePragma(Preprocessor &PP, | 
|  | 1313 | PragmaIntroducerKind Introducer, | 
|  | 1314 | Token &WeakTok) { | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1315 | SourceLocation WeakLoc = WeakTok.getLocation(); | 
|  | 1316 |  | 
|  | 1317 | Token Tok; | 
|  | 1318 | PP.Lex(Tok); | 
|  | 1319 | if (Tok.isNot(tok::identifier)) { | 
|  | 1320 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << "weak"; | 
|  | 1321 | return; | 
|  | 1322 | } | 
|  | 1323 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1324 | Token WeakName = Tok; | 
|  | 1325 | bool HasAlias = false; | 
|  | 1326 | Token AliasName; | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1327 |  | 
|  | 1328 | PP.Lex(Tok); | 
|  | 1329 | if (Tok.is(tok::equal)) { | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1330 | HasAlias = true; | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1331 | PP.Lex(Tok); | 
|  | 1332 | if (Tok.isNot(tok::identifier)) { | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1333 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1334 | << "weak"; | 
|  | 1335 | return; | 
|  | 1336 | } | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1337 | AliasName = Tok; | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1338 | PP.Lex(Tok); | 
|  | 1339 | } | 
|  | 1340 |  | 
| Peter Collingbourne | 2f1e36b | 2011-02-28 02:37:51 +0000 | [diff] [blame] | 1341 | if (Tok.isNot(tok::eod)) { | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1342 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << "weak"; | 
|  | 1343 | return; | 
|  | 1344 | } | 
|  | 1345 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1346 | if (HasAlias) { | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1347 | MutableArrayRef<Token> Toks( | 
|  | 1348 | PP.getPreprocessorAllocator().Allocate<Token>(3), 3); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1349 | Token &pragmaUnusedTok = Toks[0]; | 
|  | 1350 | pragmaUnusedTok.startToken(); | 
|  | 1351 | pragmaUnusedTok.setKind(tok::annot_pragma_weakalias); | 
|  | 1352 | pragmaUnusedTok.setLocation(WeakLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1353 | pragmaUnusedTok.setAnnotationEndLoc(AliasName.getLocation()); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1354 | Toks[1] = WeakName; | 
|  | 1355 | Toks[2] = AliasName; | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1356 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1357 | } else { | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1358 | MutableArrayRef<Token> Toks( | 
|  | 1359 | PP.getPreprocessorAllocator().Allocate<Token>(2), 2); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1360 | Token &pragmaUnusedTok = Toks[0]; | 
|  | 1361 | pragmaUnusedTok.startToken(); | 
|  | 1362 | pragmaUnusedTok.setKind(tok::annot_pragma_weak); | 
|  | 1363 | pragmaUnusedTok.setLocation(WeakLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1364 | pragmaUnusedTok.setAnnotationEndLoc(WeakLoc); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1365 | Toks[1] = WeakName; | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1366 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Eli Friedman | f5867dd | 2009-06-05 00:49:58 +0000 | [diff] [blame] | 1367 | } | 
|  | 1368 | } | 
| Peter Collingbourne | 564c0fa | 2011-02-14 01:42:35 +0000 | [diff] [blame] | 1369 |  | 
| David Chisnall | 0867d9c | 2012-02-18 16:12:34 +0000 | [diff] [blame] | 1370 | // #pragma redefine_extname identifier identifier | 
|  | 1371 | void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP, | 
|  | 1372 | PragmaIntroducerKind Introducer, | 
|  | 1373 | Token &RedefToken) { | 
|  | 1374 | SourceLocation RedefLoc = RedefToken.getLocation(); | 
|  | 1375 |  | 
|  | 1376 | Token Tok; | 
|  | 1377 | PP.Lex(Tok); | 
|  | 1378 | if (Tok.isNot(tok::identifier)) { | 
|  | 1379 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << | 
|  | 1380 | "redefine_extname"; | 
|  | 1381 | return; | 
|  | 1382 | } | 
|  | 1383 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1384 | Token RedefName = Tok; | 
| David Chisnall | 0867d9c | 2012-02-18 16:12:34 +0000 | [diff] [blame] | 1385 | PP.Lex(Tok); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1386 |  | 
| David Chisnall | 0867d9c | 2012-02-18 16:12:34 +0000 | [diff] [blame] | 1387 | if (Tok.isNot(tok::identifier)) { | 
|  | 1388 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) | 
|  | 1389 | << "redefine_extname"; | 
|  | 1390 | return; | 
|  | 1391 | } | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1392 |  | 
|  | 1393 | Token AliasName = Tok; | 
| David Chisnall | 0867d9c | 2012-02-18 16:12:34 +0000 | [diff] [blame] | 1394 | PP.Lex(Tok); | 
|  | 1395 |  | 
|  | 1396 | if (Tok.isNot(tok::eod)) { | 
|  | 1397 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << | 
|  | 1398 | "redefine_extname"; | 
|  | 1399 | return; | 
|  | 1400 | } | 
|  | 1401 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1402 | MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(3), | 
|  | 1403 | 3); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1404 | Token &pragmaRedefTok = Toks[0]; | 
|  | 1405 | pragmaRedefTok.startToken(); | 
|  | 1406 | pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname); | 
|  | 1407 | pragmaRedefTok.setLocation(RedefLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1408 | pragmaRedefTok.setAnnotationEndLoc(AliasName.getLocation()); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1409 | Toks[1] = RedefName; | 
|  | 1410 | Toks[2] = AliasName; | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1411 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| David Chisnall | 0867d9c | 2012-02-18 16:12:34 +0000 | [diff] [blame] | 1412 | } | 
|  | 1413 |  | 
|  | 1414 |  | 
| Peter Collingbourne | 564c0fa | 2011-02-14 01:42:35 +0000 | [diff] [blame] | 1415 | void | 
|  | 1416 | PragmaFPContractHandler::HandlePragma(Preprocessor &PP, | 
|  | 1417 | PragmaIntroducerKind Introducer, | 
|  | 1418 | Token &Tok) { | 
|  | 1419 | tok::OnOffSwitch OOS; | 
|  | 1420 | if (PP.LexOnOffSwitch(OOS)) | 
|  | 1421 | return; | 
|  | 1422 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1423 | MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), | 
|  | 1424 | 1); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1425 | Toks[0].startToken(); | 
|  | 1426 | Toks[0].setKind(tok::annot_pragma_fp_contract); | 
|  | 1427 | Toks[0].setLocation(Tok.getLocation()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1428 | Toks[0].setAnnotationEndLoc(Tok.getLocation()); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1429 | Toks[0].setAnnotationValue(reinterpret_cast<void*>( | 
|  | 1430 | static_cast<uintptr_t>(OOS))); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1431 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Peter Collingbourne | 564c0fa | 2011-02-14 01:42:35 +0000 | [diff] [blame] | 1432 | } | 
| Peter Collingbourne | 7ce13fc | 2011-02-14 01:42:53 +0000 | [diff] [blame] | 1433 |  | 
|  | 1434 | void | 
|  | 1435 | PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP, | 
|  | 1436 | PragmaIntroducerKind Introducer, | 
|  | 1437 | Token &Tok) { | 
| Tanya Lattner | ee840b8 | 2011-04-14 23:35:31 +0000 | [diff] [blame] | 1438 | PP.LexUnexpandedToken(Tok); | 
| Peter Collingbourne | 7ce13fc | 2011-02-14 01:42:53 +0000 | [diff] [blame] | 1439 | if (Tok.isNot(tok::identifier)) { | 
|  | 1440 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) << | 
|  | 1441 | "OPENCL"; | 
|  | 1442 | return; | 
|  | 1443 | } | 
|  | 1444 | IdentifierInfo *ename = Tok.getIdentifierInfo(); | 
|  | 1445 | SourceLocation NameLoc = Tok.getLocation(); | 
|  | 1446 |  | 
|  | 1447 | PP.Lex(Tok); | 
|  | 1448 | if (Tok.isNot(tok::colon)) { | 
|  | 1449 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_colon) << ename; | 
|  | 1450 | return; | 
|  | 1451 | } | 
|  | 1452 |  | 
|  | 1453 | PP.Lex(Tok); | 
|  | 1454 | if (Tok.isNot(tok::identifier)) { | 
|  | 1455 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); | 
|  | 1456 | return; | 
|  | 1457 | } | 
|  | 1458 | IdentifierInfo *op = Tok.getIdentifierInfo(); | 
|  | 1459 |  | 
|  | 1460 | unsigned state; | 
|  | 1461 | if (op->isStr("enable")) { | 
|  | 1462 | state = 1; | 
|  | 1463 | } else if (op->isStr("disable")) { | 
|  | 1464 | state = 0; | 
|  | 1465 | } else { | 
|  | 1466 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_enable_disable); | 
|  | 1467 | return; | 
|  | 1468 | } | 
| Pekka Jaaskelainen | 1db1da2 | 2013-10-12 09:29:48 +0000 | [diff] [blame] | 1469 | SourceLocation StateLoc = Tok.getLocation(); | 
| Peter Collingbourne | 7ce13fc | 2011-02-14 01:42:53 +0000 | [diff] [blame] | 1470 |  | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1471 | PP.Lex(Tok); | 
|  | 1472 | if (Tok.isNot(tok::eod)) { | 
|  | 1473 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) << | 
|  | 1474 | "OPENCL EXTENSION"; | 
| Peter Collingbourne | 7ce13fc | 2011-02-14 01:42:53 +0000 | [diff] [blame] | 1475 | return; | 
|  | 1476 | } | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1477 |  | 
|  | 1478 | OpenCLExtData data(ename, state); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1479 | MutableArrayRef<Token> Toks(PP.getPreprocessorAllocator().Allocate<Token>(1), | 
|  | 1480 | 1); | 
| Eli Friedman | 68be164 | 2012-10-04 02:36:51 +0000 | [diff] [blame] | 1481 | Toks[0].startToken(); | 
|  | 1482 | Toks[0].setKind(tok::annot_pragma_opencl_extension); | 
|  | 1483 | Toks[0].setLocation(NameLoc); | 
|  | 1484 | Toks[0].setAnnotationValue(data.getOpaqueValue()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1485 | Toks[0].setAnnotationEndLoc(StateLoc); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1486 | PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); | 
| Pekka Jaaskelainen | 1db1da2 | 2013-10-12 09:29:48 +0000 | [diff] [blame] | 1487 |  | 
|  | 1488 | if (PP.getPPCallbacks()) | 
|  | 1489 | PP.getPPCallbacks()->PragmaOpenCLExtension(NameLoc, ename, | 
|  | 1490 | StateLoc, state); | 
| Peter Collingbourne | 7ce13fc | 2011-02-14 01:42:53 +0000 | [diff] [blame] | 1491 | } | 
|  | 1492 |  | 
| Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1493 | /// \brief Handle '#pragma omp ...' when OpenMP is disabled. | 
|  | 1494 | /// | 
|  | 1495 | void | 
|  | 1496 | PragmaNoOpenMPHandler::HandlePragma(Preprocessor &PP, | 
|  | 1497 | PragmaIntroducerKind Introducer, | 
|  | 1498 | Token &FirstTok) { | 
| Alp Toker | d4a3f0e | 2014-06-15 23:30:39 +0000 | [diff] [blame] | 1499 | if (!PP.getDiagnostics().isIgnored(diag::warn_pragma_omp_ignored, | 
|  | 1500 | FirstTok.getLocation())) { | 
| Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1501 | PP.Diag(FirstTok, diag::warn_pragma_omp_ignored); | 
| Alp Toker | d576e00 | 2014-06-12 11:13:52 +0000 | [diff] [blame] | 1502 | PP.getDiagnostics().setSeverity(diag::warn_pragma_omp_ignored, | 
|  | 1503 | diag::Severity::Ignored, SourceLocation()); | 
| Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1504 | } | 
|  | 1505 | PP.DiscardUntilEndOfDirective(); | 
|  | 1506 | } | 
|  | 1507 |  | 
|  | 1508 | /// \brief Handle '#pragma omp ...' when OpenMP is enabled. | 
|  | 1509 | /// | 
|  | 1510 | void | 
|  | 1511 | PragmaOpenMPHandler::HandlePragma(Preprocessor &PP, | 
|  | 1512 | PragmaIntroducerKind Introducer, | 
|  | 1513 | Token &FirstTok) { | 
|  | 1514 | SmallVector<Token, 16> Pragma; | 
|  | 1515 | Token Tok; | 
|  | 1516 | Tok.startToken(); | 
|  | 1517 | Tok.setKind(tok::annot_pragma_openmp); | 
|  | 1518 | Tok.setLocation(FirstTok.getLocation()); | 
|  | 1519 |  | 
|  | 1520 | while (Tok.isNot(tok::eod)) { | 
|  | 1521 | Pragma.push_back(Tok); | 
|  | 1522 | PP.Lex(Tok); | 
|  | 1523 | } | 
|  | 1524 | SourceLocation EodLoc = Tok.getLocation(); | 
|  | 1525 | Tok.startToken(); | 
|  | 1526 | Tok.setKind(tok::annot_pragma_openmp_end); | 
|  | 1527 | Tok.setLocation(EodLoc); | 
|  | 1528 | Pragma.push_back(Tok); | 
|  | 1529 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1530 | auto Toks = llvm::make_unique<Token[]>(Pragma.size()); | 
|  | 1531 | std::copy(Pragma.begin(), Pragma.end(), Toks.get()); | 
|  | 1532 | PP.EnterTokenStream(std::move(Toks), Pragma.size(), | 
|  | 1533 | /*DisableMacroExpansion=*/false); | 
| Alexey Bataev | a769e07 | 2013-03-22 06:34:35 +0000 | [diff] [blame] | 1534 | } | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1535 |  | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1536 | /// \brief Handle '#pragma pointers_to_members' | 
|  | 1537 | // The grammar for this pragma is as follows: | 
|  | 1538 | // | 
|  | 1539 | // <inheritance model> ::= ('single' | 'multiple' | 'virtual') '_inheritance' | 
|  | 1540 | // | 
|  | 1541 | // #pragma pointers_to_members '(' 'best_case' ')' | 
|  | 1542 | // #pragma pointers_to_members '(' 'full_generality' [',' inheritance-model] ')' | 
|  | 1543 | // #pragma pointers_to_members '(' inheritance-model ')' | 
|  | 1544 | void PragmaMSPointersToMembers::HandlePragma(Preprocessor &PP, | 
|  | 1545 | PragmaIntroducerKind Introducer, | 
|  | 1546 | Token &Tok) { | 
|  | 1547 | SourceLocation PointersToMembersLoc = Tok.getLocation(); | 
|  | 1548 | PP.Lex(Tok); | 
|  | 1549 | if (Tok.isNot(tok::l_paren)) { | 
|  | 1550 | PP.Diag(PointersToMembersLoc, diag::warn_pragma_expected_lparen) | 
|  | 1551 | << "pointers_to_members"; | 
|  | 1552 | return; | 
|  | 1553 | } | 
|  | 1554 | PP.Lex(Tok); | 
|  | 1555 | const IdentifierInfo *Arg = Tok.getIdentifierInfo(); | 
|  | 1556 | if (!Arg) { | 
|  | 1557 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) | 
|  | 1558 | << "pointers_to_members"; | 
|  | 1559 | return; | 
|  | 1560 | } | 
|  | 1561 | PP.Lex(Tok); | 
|  | 1562 |  | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 1563 | LangOptions::PragmaMSPointersToMembersKind RepresentationMethod; | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1564 | if (Arg->isStr("best_case")) { | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 1565 | RepresentationMethod = LangOptions::PPTMK_BestCase; | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1566 | } else { | 
|  | 1567 | if (Arg->isStr("full_generality")) { | 
|  | 1568 | if (Tok.is(tok::comma)) { | 
|  | 1569 | PP.Lex(Tok); | 
|  | 1570 |  | 
|  | 1571 | Arg = Tok.getIdentifierInfo(); | 
|  | 1572 | if (!Arg) { | 
|  | 1573 | PP.Diag(Tok.getLocation(), | 
|  | 1574 | diag::err_pragma_pointers_to_members_unknown_kind) | 
|  | 1575 | << Tok.getKind() << /*OnlyInheritanceModels*/ 0; | 
|  | 1576 | return; | 
|  | 1577 | } | 
|  | 1578 | PP.Lex(Tok); | 
|  | 1579 | } else if (Tok.is(tok::r_paren)) { | 
|  | 1580 | // #pragma pointers_to_members(full_generality) implicitly specifies | 
|  | 1581 | // virtual_inheritance. | 
| Craig Topper | 161e4db | 2014-05-21 06:02:52 +0000 | [diff] [blame] | 1582 | Arg = nullptr; | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 1583 | RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance; | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1584 | } else { | 
|  | 1585 | PP.Diag(Tok.getLocation(), diag::err_expected_punc) | 
|  | 1586 | << "full_generality"; | 
|  | 1587 | return; | 
|  | 1588 | } | 
|  | 1589 | } | 
|  | 1590 |  | 
|  | 1591 | if (Arg) { | 
|  | 1592 | if (Arg->isStr("single_inheritance")) { | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 1593 | RepresentationMethod = | 
|  | 1594 | LangOptions::PPTMK_FullGeneralitySingleInheritance; | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1595 | } else if (Arg->isStr("multiple_inheritance")) { | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 1596 | RepresentationMethod = | 
|  | 1597 | LangOptions::PPTMK_FullGeneralityMultipleInheritance; | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1598 | } else if (Arg->isStr("virtual_inheritance")) { | 
| David Majnemer | 86c318f | 2014-02-11 21:05:00 +0000 | [diff] [blame] | 1599 | RepresentationMethod = | 
|  | 1600 | LangOptions::PPTMK_FullGeneralityVirtualInheritance; | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1601 | } else { | 
|  | 1602 | PP.Diag(Tok.getLocation(), | 
|  | 1603 | diag::err_pragma_pointers_to_members_unknown_kind) | 
|  | 1604 | << Arg << /*HasPointerDeclaration*/ 1; | 
|  | 1605 | return; | 
|  | 1606 | } | 
|  | 1607 | } | 
|  | 1608 | } | 
|  | 1609 |  | 
|  | 1610 | if (Tok.isNot(tok::r_paren)) { | 
|  | 1611 | PP.Diag(Tok.getLocation(), diag::err_expected_rparen_after) | 
|  | 1612 | << (Arg ? Arg->getName() : "full_generality"); | 
|  | 1613 | return; | 
|  | 1614 | } | 
|  | 1615 |  | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1616 | SourceLocation EndLoc = Tok.getLocation(); | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1617 | PP.Lex(Tok); | 
|  | 1618 | if (Tok.isNot(tok::eod)) { | 
|  | 1619 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 1620 | << "pointers_to_members"; | 
|  | 1621 | return; | 
|  | 1622 | } | 
|  | 1623 |  | 
|  | 1624 | Token AnnotTok; | 
|  | 1625 | AnnotTok.startToken(); | 
|  | 1626 | AnnotTok.setKind(tok::annot_pragma_ms_pointers_to_members); | 
|  | 1627 | AnnotTok.setLocation(PointersToMembersLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1628 | AnnotTok.setAnnotationEndLoc(EndLoc); | 
| David Majnemer | 4bb0980 | 2014-02-10 19:50:15 +0000 | [diff] [blame] | 1629 | AnnotTok.setAnnotationValue( | 
|  | 1630 | reinterpret_cast<void *>(static_cast<uintptr_t>(RepresentationMethod))); | 
|  | 1631 | PP.EnterToken(AnnotTok); | 
|  | 1632 | } | 
|  | 1633 |  | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1634 | /// \brief Handle '#pragma vtordisp' | 
|  | 1635 | // The grammar for this pragma is as follows: | 
|  | 1636 | // | 
|  | 1637 | // <vtordisp-mode> ::= ('off' | 'on' | '0' | '1' | '2' ) | 
|  | 1638 | // | 
|  | 1639 | // #pragma vtordisp '(' ['push' ','] vtordisp-mode ')' | 
|  | 1640 | // #pragma vtordisp '(' 'pop' ')' | 
|  | 1641 | // #pragma vtordisp '(' ')' | 
|  | 1642 | void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP, | 
|  | 1643 | PragmaIntroducerKind Introducer, | 
|  | 1644 | Token &Tok) { | 
|  | 1645 | SourceLocation VtorDispLoc = Tok.getLocation(); | 
|  | 1646 | PP.Lex(Tok); | 
|  | 1647 | if (Tok.isNot(tok::l_paren)) { | 
|  | 1648 | PP.Diag(VtorDispLoc, diag::warn_pragma_expected_lparen) << "vtordisp"; | 
|  | 1649 | return; | 
|  | 1650 | } | 
|  | 1651 | PP.Lex(Tok); | 
|  | 1652 |  | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 1653 | Sema::PragmaMsStackAction Action = Sema::PSK_Set; | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1654 | const IdentifierInfo *II = Tok.getIdentifierInfo(); | 
|  | 1655 | if (II) { | 
|  | 1656 | if (II->isStr("push")) { | 
|  | 1657 | // #pragma vtordisp(push, mode) | 
|  | 1658 | PP.Lex(Tok); | 
|  | 1659 | if (Tok.isNot(tok::comma)) { | 
|  | 1660 | PP.Diag(VtorDispLoc, diag::warn_pragma_expected_punc) << "vtordisp"; | 
|  | 1661 | return; | 
|  | 1662 | } | 
|  | 1663 | PP.Lex(Tok); | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 1664 | Action = Sema::PSK_Push_Set; | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1665 | // not push, could be on/off | 
|  | 1666 | } else if (II->isStr("pop")) { | 
|  | 1667 | // #pragma vtordisp(pop) | 
|  | 1668 | PP.Lex(Tok); | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 1669 | Action = Sema::PSK_Pop; | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1670 | } | 
|  | 1671 | // not push or pop, could be on/off | 
|  | 1672 | } else { | 
|  | 1673 | if (Tok.is(tok::r_paren)) { | 
|  | 1674 | // #pragma vtordisp() | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 1675 | Action = Sema::PSK_Reset; | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1676 | } | 
|  | 1677 | } | 
|  | 1678 |  | 
|  | 1679 |  | 
| Reid Kleckner | a4b3b2d | 2014-02-13 00:44:34 +0000 | [diff] [blame] | 1680 | uint64_t Value = 0; | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 1681 | if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) { | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1682 | const IdentifierInfo *II = Tok.getIdentifierInfo(); | 
|  | 1683 | if (II && II->isStr("off")) { | 
|  | 1684 | PP.Lex(Tok); | 
|  | 1685 | Value = 0; | 
|  | 1686 | } else if (II && II->isStr("on")) { | 
|  | 1687 | PP.Lex(Tok); | 
|  | 1688 | Value = 1; | 
|  | 1689 | } else if (Tok.is(tok::numeric_constant) && | 
|  | 1690 | PP.parseSimpleIntegerLiteral(Tok, Value)) { | 
|  | 1691 | if (Value > 2) { | 
|  | 1692 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_integer) | 
|  | 1693 | << 0 << 2 << "vtordisp"; | 
|  | 1694 | return; | 
|  | 1695 | } | 
|  | 1696 | } else { | 
|  | 1697 | PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action) | 
|  | 1698 | << "vtordisp"; | 
|  | 1699 | return; | 
|  | 1700 | } | 
|  | 1701 | } | 
|  | 1702 |  | 
|  | 1703 | // Finish the pragma: ')' $ | 
|  | 1704 | if (Tok.isNot(tok::r_paren)) { | 
|  | 1705 | PP.Diag(VtorDispLoc, diag::warn_pragma_expected_rparen) << "vtordisp"; | 
|  | 1706 | return; | 
|  | 1707 | } | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1708 | SourceLocation EndLoc = Tok.getLocation(); | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1709 | PP.Lex(Tok); | 
|  | 1710 | if (Tok.isNot(tok::eod)) { | 
|  | 1711 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 1712 | << "vtordisp"; | 
|  | 1713 | return; | 
|  | 1714 | } | 
|  | 1715 |  | 
|  | 1716 | // Enter the annotation. | 
|  | 1717 | Token AnnotTok; | 
|  | 1718 | AnnotTok.startToken(); | 
|  | 1719 | AnnotTok.setKind(tok::annot_pragma_ms_vtordisp); | 
|  | 1720 | AnnotTok.setLocation(VtorDispLoc); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1721 | AnnotTok.setAnnotationEndLoc(EndLoc); | 
| Reid Kleckner | a4b3b2d | 2014-02-13 00:44:34 +0000 | [diff] [blame] | 1722 | AnnotTok.setAnnotationValue(reinterpret_cast<void *>( | 
| Denis Zobnin | 2290dac | 2016-04-29 11:27:00 +0000 | [diff] [blame] | 1723 | static_cast<uintptr_t>((Action << 16) | (Value & 0xFFFF)))); | 
| Reid Kleckner | c0dca6d | 2014-02-12 23:50:26 +0000 | [diff] [blame] | 1724 | PP.EnterToken(AnnotTok); | 
|  | 1725 | } | 
|  | 1726 |  | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 1727 | /// \brief Handle all MS pragmas.  Simply forwards the tokens after inserting | 
|  | 1728 | /// an annotation token. | 
|  | 1729 | void PragmaMSPragma::HandlePragma(Preprocessor &PP, | 
|  | 1730 | PragmaIntroducerKind Introducer, | 
|  | 1731 | Token &Tok) { | 
|  | 1732 | Token EoF, AnnotTok; | 
|  | 1733 | EoF.startToken(); | 
|  | 1734 | EoF.setKind(tok::eof); | 
|  | 1735 | AnnotTok.startToken(); | 
|  | 1736 | AnnotTok.setKind(tok::annot_pragma_ms_pragma); | 
|  | 1737 | AnnotTok.setLocation(Tok.getLocation()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1738 | AnnotTok.setAnnotationEndLoc(Tok.getLocation()); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 1739 | SmallVector<Token, 8> TokenVector; | 
|  | 1740 | // Suck up all of the tokens before the eod. | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1741 | for (; Tok.isNot(tok::eod); PP.Lex(Tok)) { | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 1742 | TokenVector.push_back(Tok); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 1743 | AnnotTok.setAnnotationEndLoc(Tok.getLocation()); | 
|  | 1744 | } | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 1745 | // Add a sentinal EoF token to the end of the list. | 
|  | 1746 | TokenVector.push_back(EoF); | 
|  | 1747 | // We must allocate this array with new because EnterTokenStream is going to | 
|  | 1748 | // delete it later. | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1749 | auto TokenArray = llvm::make_unique<Token[]>(TokenVector.size()); | 
|  | 1750 | std::copy(TokenVector.begin(), TokenVector.end(), TokenArray.get()); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 1751 | auto Value = new (PP.getPreprocessorAllocator()) | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 1752 | std::pair<std::unique_ptr<Token[]>, size_t>(std::move(TokenArray), | 
|  | 1753 | TokenVector.size()); | 
| Warren Hunt | c3b1896 | 2014-04-08 22:30:47 +0000 | [diff] [blame] | 1754 | AnnotTok.setAnnotationValue(Value); | 
|  | 1755 | PP.EnterToken(AnnotTok); | 
| Reid Kleckner | d3923aa | 2014-04-03 19:04:24 +0000 | [diff] [blame] | 1756 | } | 
|  | 1757 |  | 
| Aaron Ballman | 5d041be | 2013-06-04 02:07:14 +0000 | [diff] [blame] | 1758 | /// \brief Handle the Microsoft \#pragma detect_mismatch extension. | 
|  | 1759 | /// | 
|  | 1760 | /// The syntax is: | 
|  | 1761 | /// \code | 
|  | 1762 | ///   #pragma detect_mismatch("name", "value") | 
|  | 1763 | /// \endcode | 
|  | 1764 | /// Where 'name' and 'value' are quoted strings.  The values are embedded in | 
|  | 1765 | /// the object file and passed along to the linker.  If the linker detects a | 
|  | 1766 | /// mismatch in the object file's values for the given name, a LNK2038 error | 
|  | 1767 | /// is emitted.  See MSDN for more details. | 
|  | 1768 | void PragmaDetectMismatchHandler::HandlePragma(Preprocessor &PP, | 
|  | 1769 | PragmaIntroducerKind Introducer, | 
|  | 1770 | Token &Tok) { | 
| Nico Weber | cbbaeb1 | 2016-03-02 19:28:54 +0000 | [diff] [blame] | 1771 | SourceLocation DetectMismatchLoc = Tok.getLocation(); | 
| Aaron Ballman | 5d041be | 2013-06-04 02:07:14 +0000 | [diff] [blame] | 1772 | PP.Lex(Tok); | 
|  | 1773 | if (Tok.isNot(tok::l_paren)) { | 
| Nico Weber | cbbaeb1 | 2016-03-02 19:28:54 +0000 | [diff] [blame] | 1774 | PP.Diag(DetectMismatchLoc, diag::err_expected) << tok::l_paren; | 
| Aaron Ballman | 5d041be | 2013-06-04 02:07:14 +0000 | [diff] [blame] | 1775 | return; | 
|  | 1776 | } | 
|  | 1777 |  | 
|  | 1778 | // Read the name to embed, which must be a string literal. | 
|  | 1779 | std::string NameString; | 
|  | 1780 | if (!PP.LexStringLiteral(Tok, NameString, | 
|  | 1781 | "pragma detect_mismatch", | 
|  | 1782 | /*MacroExpansion=*/true)) | 
|  | 1783 | return; | 
|  | 1784 |  | 
|  | 1785 | // Read the comma followed by a second string literal. | 
|  | 1786 | std::string ValueString; | 
|  | 1787 | if (Tok.isNot(tok::comma)) { | 
|  | 1788 | PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); | 
|  | 1789 | return; | 
|  | 1790 | } | 
|  | 1791 |  | 
|  | 1792 | if (!PP.LexStringLiteral(Tok, ValueString, "pragma detect_mismatch", | 
|  | 1793 | /*MacroExpansion=*/true)) | 
|  | 1794 | return; | 
|  | 1795 |  | 
|  | 1796 | if (Tok.isNot(tok::r_paren)) { | 
| Alp Toker | ec54327 | 2013-12-24 09:48:30 +0000 | [diff] [blame] | 1797 | PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; | 
| Aaron Ballman | 5d041be | 2013-06-04 02:07:14 +0000 | [diff] [blame] | 1798 | return; | 
|  | 1799 | } | 
|  | 1800 | PP.Lex(Tok);  // Eat the r_paren. | 
|  | 1801 |  | 
|  | 1802 | if (Tok.isNot(tok::eod)) { | 
|  | 1803 | PP.Diag(Tok.getLocation(), diag::err_pragma_detect_mismatch_malformed); | 
|  | 1804 | return; | 
|  | 1805 | } | 
|  | 1806 |  | 
| Reid Kleckner | 71966c9 | 2014-02-20 23:37:45 +0000 | [diff] [blame] | 1807 | // If the pragma is lexically sound, notify any interested PPCallbacks. | 
|  | 1808 | if (PP.getPPCallbacks()) | 
| Nico Weber | cbbaeb1 | 2016-03-02 19:28:54 +0000 | [diff] [blame] | 1809 | PP.getPPCallbacks()->PragmaDetectMismatch(DetectMismatchLoc, NameString, | 
| Reid Kleckner | 71966c9 | 2014-02-20 23:37:45 +0000 | [diff] [blame] | 1810 | ValueString); | 
|  | 1811 |  | 
| Nico Weber | cbbaeb1 | 2016-03-02 19:28:54 +0000 | [diff] [blame] | 1812 | Actions.ActOnPragmaDetectMismatch(DetectMismatchLoc, NameString, ValueString); | 
| Aaron Ballman | 5d041be | 2013-06-04 02:07:14 +0000 | [diff] [blame] | 1813 | } | 
|  | 1814 |  | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1815 | /// \brief Handle the microsoft \#pragma comment extension. | 
|  | 1816 | /// | 
|  | 1817 | /// The syntax is: | 
|  | 1818 | /// \code | 
|  | 1819 | ///   #pragma comment(linker, "foo") | 
|  | 1820 | /// \endcode | 
|  | 1821 | /// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user. | 
|  | 1822 | /// "foo" is a string, which is fully macro expanded, and permits string | 
|  | 1823 | /// concatenation, embedded escape characters etc.  See MSDN for more details. | 
|  | 1824 | void PragmaCommentHandler::HandlePragma(Preprocessor &PP, | 
|  | 1825 | PragmaIntroducerKind Introducer, | 
|  | 1826 | Token &Tok) { | 
|  | 1827 | SourceLocation CommentLoc = Tok.getLocation(); | 
|  | 1828 | PP.Lex(Tok); | 
|  | 1829 | if (Tok.isNot(tok::l_paren)) { | 
|  | 1830 | PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); | 
|  | 1831 | return; | 
|  | 1832 | } | 
|  | 1833 |  | 
|  | 1834 | // Read the identifier. | 
|  | 1835 | PP.Lex(Tok); | 
|  | 1836 | if (Tok.isNot(tok::identifier)) { | 
|  | 1837 | PP.Diag(CommentLoc, diag::err_pragma_comment_malformed); | 
|  | 1838 | return; | 
|  | 1839 | } | 
|  | 1840 |  | 
|  | 1841 | // Verify that this is one of the 5 whitelisted options. | 
| Reid Kleckner | e43f0fe | 2013-05-08 13:44:39 +0000 | [diff] [blame] | 1842 | IdentifierInfo *II = Tok.getIdentifierInfo(); | 
| Nico Weber | 6622029 | 2016-03-02 17:28:48 +0000 | [diff] [blame] | 1843 | PragmaMSCommentKind Kind = | 
|  | 1844 | llvm::StringSwitch<PragmaMSCommentKind>(II->getName()) | 
|  | 1845 | .Case("linker",   PCK_Linker) | 
|  | 1846 | .Case("lib",      PCK_Lib) | 
|  | 1847 | .Case("compiler", PCK_Compiler) | 
|  | 1848 | .Case("exestr",   PCK_ExeStr) | 
|  | 1849 | .Case("user",     PCK_User) | 
|  | 1850 | .Default(PCK_Unknown); | 
|  | 1851 | if (Kind == PCK_Unknown) { | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1852 | PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind); | 
|  | 1853 | return; | 
|  | 1854 | } | 
|  | 1855 |  | 
| Yunzhong Gao | 99efc03 | 2015-03-23 20:41:42 +0000 | [diff] [blame] | 1856 | // On PS4, issue a warning about any pragma comments other than | 
|  | 1857 | // #pragma comment lib. | 
| Nico Weber | 6622029 | 2016-03-02 17:28:48 +0000 | [diff] [blame] | 1858 | if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) { | 
| Yunzhong Gao | 99efc03 | 2015-03-23 20:41:42 +0000 | [diff] [blame] | 1859 | PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored) | 
|  | 1860 | << II->getName(); | 
|  | 1861 | return; | 
|  | 1862 | } | 
|  | 1863 |  | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1864 | // Read the optional string if present. | 
|  | 1865 | PP.Lex(Tok); | 
|  | 1866 | std::string ArgumentString; | 
|  | 1867 | if (Tok.is(tok::comma) && !PP.LexStringLiteral(Tok, ArgumentString, | 
|  | 1868 | "pragma comment", | 
|  | 1869 | /*MacroExpansion=*/true)) | 
|  | 1870 | return; | 
|  | 1871 |  | 
| Reid Kleckner | e43f0fe | 2013-05-08 13:44:39 +0000 | [diff] [blame] | 1872 | // FIXME: warn that 'exestr' is deprecated. | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1873 | // FIXME: If the kind is "compiler" warn if the string is present (it is | 
|  | 1874 | // ignored). | 
| Reid Kleckner | e43f0fe | 2013-05-08 13:44:39 +0000 | [diff] [blame] | 1875 | // The MSDN docs say that "lib" and "linker" require a string and have a short | 
|  | 1876 | // whitelist of linker options they support, but in practice MSVC doesn't | 
|  | 1877 | // issue a diagnostic.  Therefore neither does clang. | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1878 |  | 
|  | 1879 | if (Tok.isNot(tok::r_paren)) { | 
|  | 1880 | PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); | 
|  | 1881 | return; | 
|  | 1882 | } | 
|  | 1883 | PP.Lex(Tok);  // eat the r_paren. | 
|  | 1884 |  | 
|  | 1885 | if (Tok.isNot(tok::eod)) { | 
|  | 1886 | PP.Diag(Tok.getLocation(), diag::err_pragma_comment_malformed); | 
|  | 1887 | return; | 
|  | 1888 | } | 
|  | 1889 |  | 
| Reid Kleckner | 71966c9 | 2014-02-20 23:37:45 +0000 | [diff] [blame] | 1890 | // If the pragma is lexically sound, notify any interested PPCallbacks. | 
|  | 1891 | if (PP.getPPCallbacks()) | 
|  | 1892 | PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString); | 
|  | 1893 |  | 
| Nico Weber | 6622029 | 2016-03-02 17:28:48 +0000 | [diff] [blame] | 1894 | Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString); | 
| Reid Kleckner | 002562a | 2013-05-06 21:02:12 +0000 | [diff] [blame] | 1895 | } | 
| Dario Domizioli | 13a0a38 | 2014-05-23 12:13:25 +0000 | [diff] [blame] | 1896 |  | 
|  | 1897 | // #pragma clang optimize off | 
|  | 1898 | // #pragma clang optimize on | 
|  | 1899 | void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP, | 
|  | 1900 | PragmaIntroducerKind Introducer, | 
|  | 1901 | Token &FirstToken) { | 
|  | 1902 | Token Tok; | 
|  | 1903 | PP.Lex(Tok); | 
|  | 1904 | if (Tok.is(tok::eod)) { | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1905 | PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument) | 
| Mark Heffernan | 450c238 | 2014-07-23 17:31:31 +0000 | [diff] [blame] | 1906 | << "clang optimize" << /*Expected=*/true << "'on' or 'off'"; | 
| Dario Domizioli | 13a0a38 | 2014-05-23 12:13:25 +0000 | [diff] [blame] | 1907 | return; | 
|  | 1908 | } | 
|  | 1909 | if (Tok.isNot(tok::identifier)) { | 
|  | 1910 | PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument) | 
|  | 1911 | << PP.getSpelling(Tok); | 
|  | 1912 | return; | 
|  | 1913 | } | 
|  | 1914 | const IdentifierInfo *II = Tok.getIdentifierInfo(); | 
|  | 1915 | // The only accepted values are 'on' or 'off'. | 
|  | 1916 | bool IsOn = false; | 
|  | 1917 | if (II->isStr("on")) { | 
|  | 1918 | IsOn = true; | 
|  | 1919 | } else if (!II->isStr("off")) { | 
|  | 1920 | PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument) | 
|  | 1921 | << PP.getSpelling(Tok); | 
|  | 1922 | return; | 
|  | 1923 | } | 
|  | 1924 | PP.Lex(Tok); | 
|  | 1925 |  | 
|  | 1926 | if (Tok.isNot(tok::eod)) { | 
|  | 1927 | PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument) | 
|  | 1928 | << PP.getSpelling(Tok); | 
|  | 1929 | return; | 
|  | 1930 | } | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 1931 |  | 
|  | 1932 | Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation()); | 
|  | 1933 | } | 
|  | 1934 |  | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1935 | /// \brief Parses loop or unroll pragma hint value and fills in Info. | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 1936 | static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName, | 
|  | 1937 | Token Option, bool ValueInParens, | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1938 | PragmaLoopHintInfo &Info) { | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 1939 | SmallVector<Token, 1> ValueList; | 
|  | 1940 | int OpenParens = ValueInParens ? 1 : 0; | 
|  | 1941 | // Read constant expression. | 
|  | 1942 | while (Tok.isNot(tok::eod)) { | 
|  | 1943 | if (Tok.is(tok::l_paren)) | 
|  | 1944 | OpenParens++; | 
|  | 1945 | else if (Tok.is(tok::r_paren)) { | 
|  | 1946 | OpenParens--; | 
|  | 1947 | if (OpenParens == 0 && ValueInParens) | 
|  | 1948 | break; | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1949 | } | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1950 |  | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 1951 | ValueList.push_back(Tok); | 
|  | 1952 | PP.Lex(Tok); | 
|  | 1953 | } | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1954 |  | 
|  | 1955 | if (ValueInParens) { | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 1956 | // Read ')' | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1957 | if (Tok.isNot(tok::r_paren)) { | 
|  | 1958 | PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren; | 
|  | 1959 | return true; | 
|  | 1960 | } | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 1961 | PP.Lex(Tok); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1962 | } | 
|  | 1963 |  | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 1964 | Token EOFTok; | 
|  | 1965 | EOFTok.startToken(); | 
|  | 1966 | EOFTok.setKind(tok::eof); | 
|  | 1967 | EOFTok.setLocation(Tok.getLocation()); | 
|  | 1968 | ValueList.push_back(EOFTok); // Terminates expression for parsing. | 
|  | 1969 |  | 
| Benjamin Kramer | fa7f855 | 2015-08-05 09:39:57 +0000 | [diff] [blame] | 1970 | Info.Toks = llvm::makeArrayRef(ValueList).copy(PP.getPreprocessorAllocator()); | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 1971 |  | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1972 | Info.PragmaName = PragmaName; | 
|  | 1973 | Info.Option = Option; | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 1974 | return false; | 
|  | 1975 | } | 
|  | 1976 |  | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 1977 | /// \brief Handle the \#pragma clang loop directive. | 
|  | 1978 | ///  #pragma clang 'loop' loop-hints | 
|  | 1979 | /// | 
|  | 1980 | ///  loop-hints: | 
|  | 1981 | ///    loop-hint loop-hints[opt] | 
|  | 1982 | /// | 
|  | 1983 | ///  loop-hint: | 
|  | 1984 | ///    'vectorize' '(' loop-hint-keyword ')' | 
|  | 1985 | ///    'interleave' '(' loop-hint-keyword ')' | 
| Mark Heffernan | 450c238 | 2014-07-23 17:31:31 +0000 | [diff] [blame] | 1986 | ///    'unroll' '(' unroll-hint-keyword ')' | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 1987 | ///    'vectorize_width' '(' loop-hint-value ')' | 
|  | 1988 | ///    'interleave_count' '(' loop-hint-value ')' | 
| Eli Bendersky | 86483b3 | 2014-06-11 17:56:26 +0000 | [diff] [blame] | 1989 | ///    'unroll_count' '(' loop-hint-value ')' | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 1990 | /// | 
|  | 1991 | ///  loop-hint-keyword: | 
|  | 1992 | ///    'enable' | 
|  | 1993 | ///    'disable' | 
| Tyler Nowicki | 9d268e1 | 2015-06-11 23:23:17 +0000 | [diff] [blame] | 1994 | ///    'assume_safety' | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 1995 | /// | 
| Mark Heffernan | 450c238 | 2014-07-23 17:31:31 +0000 | [diff] [blame] | 1996 | ///  unroll-hint-keyword: | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 1997 | ///    'enable' | 
| Mark Heffernan | 450c238 | 2014-07-23 17:31:31 +0000 | [diff] [blame] | 1998 | ///    'disable' | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 1999 | ///    'full' | 
| Mark Heffernan | 450c238 | 2014-07-23 17:31:31 +0000 | [diff] [blame] | 2000 | /// | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2001 | ///  loop-hint-value: | 
|  | 2002 | ///    constant-expression | 
|  | 2003 | /// | 
|  | 2004 | /// Specifying vectorize(enable) or vectorize_width(_value_) instructs llvm to | 
|  | 2005 | /// try vectorizing the instructions of the loop it precedes. Specifying | 
|  | 2006 | /// interleave(enable) or interleave_count(_value_) instructs llvm to try | 
|  | 2007 | /// interleaving multiple iterations of the loop it precedes. The width of the | 
|  | 2008 | /// vector instructions is specified by vectorize_width() and the number of | 
|  | 2009 | /// interleaved loop iterations is specified by interleave_count(). Specifying a | 
|  | 2010 | /// value of 1 effectively disables vectorization/interleaving, even if it is | 
|  | 2011 | /// possible and profitable, and 0 is invalid. The loop vectorizer currently | 
|  | 2012 | /// only works on inner loops. | 
|  | 2013 | /// | 
| Eli Bendersky | 86483b3 | 2014-06-11 17:56:26 +0000 | [diff] [blame] | 2014 | /// The unroll and unroll_count directives control the concatenation | 
| Mark Heffernan | 397a98d | 2015-08-10 17:29:39 +0000 | [diff] [blame] | 2015 | /// unroller. Specifying unroll(enable) instructs llvm to unroll the loop | 
|  | 2016 | /// completely if the trip count is known at compile time and unroll partially | 
|  | 2017 | /// if the trip count is not known.  Specifying unroll(full) is similar to | 
|  | 2018 | /// unroll(enable) but will unroll the loop only if the trip count is known at | 
|  | 2019 | /// compile time.  Specifying unroll(disable) disables unrolling for the | 
|  | 2020 | /// loop. Specifying unroll_count(_value_) instructs llvm to try to unroll the | 
|  | 2021 | /// loop the number of times indicated by the value. | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2022 | void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP, | 
|  | 2023 | PragmaIntroducerKind Introducer, | 
|  | 2024 | Token &Tok) { | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2025 | // Incoming token is "loop" from "#pragma clang loop". | 
|  | 2026 | Token PragmaName = Tok; | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2027 | SmallVector<Token, 1> TokenList; | 
|  | 2028 |  | 
|  | 2029 | // Lex the optimization option and verify it is an identifier. | 
|  | 2030 | PP.Lex(Tok); | 
|  | 2031 | if (Tok.isNot(tok::identifier)) { | 
|  | 2032 | PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option) | 
|  | 2033 | << /*MissingOption=*/true << ""; | 
|  | 2034 | return; | 
|  | 2035 | } | 
|  | 2036 |  | 
|  | 2037 | while (Tok.is(tok::identifier)) { | 
|  | 2038 | Token Option = Tok; | 
|  | 2039 | IdentifierInfo *OptionInfo = Tok.getIdentifierInfo(); | 
|  | 2040 |  | 
| Eli Bendersky | 86483b3 | 2014-06-11 17:56:26 +0000 | [diff] [blame] | 2041 | bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName()) | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2042 | .Case("vectorize", true) | 
|  | 2043 | .Case("interleave", true) | 
|  | 2044 | .Case("unroll", true) | 
| Adam Nemet | 2de463e | 2016-06-14 12:04:26 +0000 | [diff] [blame] | 2045 | .Case("distribute", true) | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2046 | .Case("vectorize_width", true) | 
|  | 2047 | .Case("interleave_count", true) | 
|  | 2048 | .Case("unroll_count", true) | 
|  | 2049 | .Default(false); | 
| Eli Bendersky | 86483b3 | 2014-06-11 17:56:26 +0000 | [diff] [blame] | 2050 | if (!OptionValid) { | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2051 | PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option) | 
|  | 2052 | << /*MissingOption=*/false << OptionInfo; | 
|  | 2053 | return; | 
|  | 2054 | } | 
| NAKAMURA Takumi | db9552f | 2014-07-31 01:52:33 +0000 | [diff] [blame] | 2055 | PP.Lex(Tok); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2056 |  | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 2057 | // Read '(' | 
|  | 2058 | if (Tok.isNot(tok::l_paren)) { | 
|  | 2059 | PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren; | 
| NAKAMURA Takumi | db9552f | 2014-07-31 01:52:33 +0000 | [diff] [blame] | 2060 | return; | 
|  | 2061 | } | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 2062 | PP.Lex(Tok); | 
|  | 2063 |  | 
|  | 2064 | auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; | 
|  | 2065 | if (ParseLoopHintValue(PP, Tok, PragmaName, Option, /*ValueInParens=*/true, | 
|  | 2066 | *Info)) | 
|  | 2067 | return; | 
| NAKAMURA Takumi | db9552f | 2014-07-31 01:52:33 +0000 | [diff] [blame] | 2068 |  | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2069 | // Generate the loop hint token. | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2070 | Token LoopHintTok; | 
|  | 2071 | LoopHintTok.startToken(); | 
|  | 2072 | LoopHintTok.setKind(tok::annot_pragma_loop_hint); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2073 | LoopHintTok.setLocation(PragmaName.getLocation()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 2074 | LoopHintTok.setAnnotationEndLoc(PragmaName.getLocation()); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2075 | LoopHintTok.setAnnotationValue(static_cast<void *>(Info)); | 
|  | 2076 | TokenList.push_back(LoopHintTok); | 
|  | 2077 | } | 
|  | 2078 |  | 
|  | 2079 | if (Tok.isNot(tok::eod)) { | 
|  | 2080 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 2081 | << "clang loop"; | 
|  | 2082 | return; | 
|  | 2083 | } | 
|  | 2084 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 2085 | auto TokenArray = llvm::make_unique<Token[]>(TokenList.size()); | 
|  | 2086 | std::copy(TokenList.begin(), TokenList.end(), TokenArray.get()); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2087 |  | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 2088 | PP.EnterTokenStream(std::move(TokenArray), TokenList.size(), | 
|  | 2089 | /*DisableMacroExpansion=*/false); | 
| Eli Bendersky | 06a4042 | 2014-06-06 20:31:48 +0000 | [diff] [blame] | 2090 | } | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2091 |  | 
|  | 2092 | /// \brief Handle the loop unroll optimization pragmas. | 
|  | 2093 | ///  #pragma unroll | 
|  | 2094 | ///  #pragma unroll unroll-hint-value | 
|  | 2095 | ///  #pragma unroll '(' unroll-hint-value ')' | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 2096 | ///  #pragma nounroll | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2097 | /// | 
|  | 2098 | ///  unroll-hint-value: | 
|  | 2099 | ///    constant-expression | 
|  | 2100 | /// | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 2101 | /// Loop unrolling hints can be specified with '#pragma unroll' or | 
|  | 2102 | /// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally | 
|  | 2103 | /// contained in parentheses. With no argument the directive instructs llvm to | 
|  | 2104 | /// try to unroll the loop completely. A positive integer argument can be | 
|  | 2105 | /// specified to indicate the number of times the loop should be unrolled.  To | 
|  | 2106 | /// maximize compatibility with other compilers the unroll count argument can be | 
|  | 2107 | /// specified with or without parentheses.  Specifying, '#pragma nounroll' | 
|  | 2108 | /// disables unrolling of the loop. | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2109 | void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP, | 
|  | 2110 | PragmaIntroducerKind Introducer, | 
|  | 2111 | Token &Tok) { | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 2112 | // Incoming token is "unroll" for "#pragma unroll", or "nounroll" for | 
|  | 2113 | // "#pragma nounroll". | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2114 | Token PragmaName = Tok; | 
|  | 2115 | PP.Lex(Tok); | 
|  | 2116 | auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo; | 
|  | 2117 | if (Tok.is(tok::eod)) { | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 2118 | // nounroll or unroll pragma without an argument. | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2119 | Info->PragmaName = PragmaName; | 
| Aaron Ballman | d6807da | 2014-08-01 12:41:37 +0000 | [diff] [blame] | 2120 | Info->Option.startToken(); | 
| Mark Heffernan | c888e41 | 2014-07-24 18:09:38 +0000 | [diff] [blame] | 2121 | } else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") { | 
|  | 2122 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 2123 | << "nounroll"; | 
|  | 2124 | return; | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2125 | } else { | 
|  | 2126 | // Unroll pragma with an argument: "#pragma unroll N" or | 
|  | 2127 | // "#pragma unroll(N)". | 
| Tyler Nowicki | 0c9b34b | 2014-07-31 20:15:14 +0000 | [diff] [blame] | 2128 | // Read '(' if it exists. | 
|  | 2129 | bool ValueInParens = Tok.is(tok::l_paren); | 
|  | 2130 | if (ValueInParens) | 
|  | 2131 | PP.Lex(Tok); | 
|  | 2132 |  | 
| Aaron Ballman | d0b090d | 2014-08-01 12:20:20 +0000 | [diff] [blame] | 2133 | Token Option; | 
|  | 2134 | Option.startToken(); | 
|  | 2135 | if (ParseLoopHintValue(PP, Tok, PragmaName, Option, ValueInParens, *Info)) | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2136 | return; | 
|  | 2137 |  | 
|  | 2138 | // In CUDA, the argument to '#pragma unroll' should not be contained in | 
|  | 2139 | // parentheses. | 
|  | 2140 | if (PP.getLangOpts().CUDA && ValueInParens) | 
| Tyler Nowicki | c724a83e | 2014-10-12 20:46:07 +0000 | [diff] [blame] | 2141 | PP.Diag(Info->Toks[0].getLocation(), | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2142 | diag::warn_pragma_unroll_cuda_value_in_parens); | 
|  | 2143 |  | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2144 | if (Tok.isNot(tok::eod)) { | 
|  | 2145 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 2146 | << "unroll"; | 
|  | 2147 | return; | 
|  | 2148 | } | 
|  | 2149 | } | 
|  | 2150 |  | 
|  | 2151 | // Generate the hint token. | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 2152 | auto TokenArray = llvm::make_unique<Token[]>(1); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2153 | TokenArray[0].startToken(); | 
|  | 2154 | TokenArray[0].setKind(tok::annot_pragma_loop_hint); | 
|  | 2155 | TokenArray[0].setLocation(PragmaName.getLocation()); | 
| David Majnemer | a8f2f1d | 2015-03-19 00:10:23 +0000 | [diff] [blame] | 2156 | TokenArray[0].setAnnotationEndLoc(PragmaName.getLocation()); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2157 | TokenArray[0].setAnnotationValue(static_cast<void *>(Info)); | 
| David Blaikie | 2eabcc9 | 2016-02-09 18:52:09 +0000 | [diff] [blame] | 2158 | PP.EnterTokenStream(std::move(TokenArray), 1, | 
|  | 2159 | /*DisableMacroExpansion=*/false); | 
| Mark Heffernan | bd26f5e | 2014-07-21 18:08:34 +0000 | [diff] [blame] | 2160 | } | 
| Reid Kleckner | 3f1ec62 | 2016-09-07 16:38:32 +0000 | [diff] [blame] | 2161 |  | 
|  | 2162 | /// \brief Handle the Microsoft \#pragma intrinsic extension. | 
|  | 2163 | /// | 
|  | 2164 | /// The syntax is: | 
|  | 2165 | /// \code | 
|  | 2166 | ///  #pragma intrinsic(memset) | 
|  | 2167 | ///  #pragma intrinsic(strlen, memcpy) | 
|  | 2168 | /// \endcode | 
|  | 2169 | /// | 
|  | 2170 | /// Pragma intrisic tells the compiler to use a builtin version of the | 
|  | 2171 | /// function. Clang does it anyway, so the pragma doesn't really do anything. | 
|  | 2172 | /// Anyway, we emit a warning if the function specified in \#pragma intrinsic | 
|  | 2173 | /// isn't an intrinsic in clang and suggest to include intrin.h. | 
|  | 2174 | void PragmaMSIntrinsicHandler::HandlePragma(Preprocessor &PP, | 
|  | 2175 | PragmaIntroducerKind Introducer, | 
|  | 2176 | Token &Tok) { | 
|  | 2177 | PP.Lex(Tok); | 
|  | 2178 |  | 
|  | 2179 | if (Tok.isNot(tok::l_paren)) { | 
|  | 2180 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) | 
|  | 2181 | << "intrinsic"; | 
|  | 2182 | return; | 
|  | 2183 | } | 
|  | 2184 | PP.Lex(Tok); | 
|  | 2185 |  | 
|  | 2186 | bool SuggestIntrinH = !PP.isMacroDefined("__INTRIN_H"); | 
|  | 2187 |  | 
|  | 2188 | while (Tok.is(tok::identifier)) { | 
|  | 2189 | IdentifierInfo *II = Tok.getIdentifierInfo(); | 
|  | 2190 | if (!II->getBuiltinID()) | 
|  | 2191 | PP.Diag(Tok.getLocation(), diag::warn_pragma_intrinsic_builtin) | 
|  | 2192 | << II << SuggestIntrinH; | 
|  | 2193 |  | 
|  | 2194 | PP.Lex(Tok); | 
|  | 2195 | if (Tok.isNot(tok::comma)) | 
|  | 2196 | break; | 
|  | 2197 | PP.Lex(Tok); | 
|  | 2198 | } | 
|  | 2199 |  | 
|  | 2200 | if (Tok.isNot(tok::r_paren)) { | 
|  | 2201 | PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) | 
|  | 2202 | << "intrinsic"; | 
|  | 2203 | return; | 
|  | 2204 | } | 
|  | 2205 | PP.Lex(Tok); | 
|  | 2206 |  | 
|  | 2207 | if (Tok.isNot(tok::eod)) | 
|  | 2208 | PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) | 
|  | 2209 | << "intrinsic"; | 
|  | 2210 | } | 
| Justin Lebar | 67a78a6 | 2016-10-08 22:15:58 +0000 | [diff] [blame] | 2211 | void PragmaForceCUDAHostDeviceHandler::HandlePragma( | 
|  | 2212 | Preprocessor &PP, PragmaIntroducerKind Introducer, Token &Tok) { | 
|  | 2213 | Token FirstTok = Tok; | 
|  | 2214 |  | 
|  | 2215 | PP.Lex(Tok); | 
|  | 2216 | IdentifierInfo *Info = Tok.getIdentifierInfo(); | 
|  | 2217 | if (!Info || (!Info->isStr("begin") && !Info->isStr("end"))) { | 
|  | 2218 | PP.Diag(FirstTok.getLocation(), | 
|  | 2219 | diag::warn_pragma_force_cuda_host_device_bad_arg); | 
|  | 2220 | return; | 
|  | 2221 | } | 
|  | 2222 |  | 
|  | 2223 | if (Info->isStr("begin")) | 
|  | 2224 | Actions.PushForceCUDAHostDevice(); | 
|  | 2225 | else if (!Actions.PopForceCUDAHostDevice()) | 
|  | 2226 | PP.Diag(FirstTok.getLocation(), | 
|  | 2227 | diag::err_pragma_cannot_end_force_cuda_host_device); | 
|  | 2228 |  | 
|  | 2229 | PP.Lex(Tok); | 
|  | 2230 | if (!Tok.is(tok::eod)) | 
|  | 2231 | PP.Diag(FirstTok.getLocation(), | 
|  | 2232 | diag::warn_pragma_force_cuda_host_device_bad_arg); | 
|  | 2233 | } |