 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
72.4% |
152 / 210 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
86.7% |
182 / 210 |
| |
|
Line Coverage: |
77.9% |
243 / 312 |
| |
 |
|
 |
1 : //===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
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 semantic analysis for declaration specifiers.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Parse/DeclSpec.h"
15 : #include "clang/Parse/ParseDiagnostic.h"
16 : #include "clang/Parse/Template.h"
17 : #include "clang/Lex/Preprocessor.h"
18 : #include "clang/Basic/LangOptions.h"
19 : #include "llvm/ADT/STLExtras.h"
20 : #include "llvm/Support/ErrorHandling.h"
21 : #include <cstring>
22 : using namespace clang;
23 :
24 :
25 : static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
26 61: SourceManager &SrcMgr, unsigned DiagID) {
27 61: return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
28 : }
29 :
30 :
31 230: void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
0: branch 0 not taken
230: branch 1 taken
32 230: assert(TemplateId && "NULL template-id annotation?");
33 230: Kind = IK_TemplateId;
34 230: this->TemplateId = TemplateId;
35 230: StartLocation = TemplateId->TemplateNameLoc;
36 230: EndLocation = TemplateId->RAngleLoc;
37 230: }
38 :
39 5: void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
0: branch 0 not taken
5: branch 1 taken
40 5: assert(TemplateId && "NULL template-id annotation?");
41 5: Kind = IK_ConstructorTemplateId;
42 5: this->TemplateId = TemplateId;
43 5: StartLocation = TemplateId->TemplateNameLoc;
44 5: EndLocation = TemplateId->RAngleLoc;
45 5: }
46 :
47 : /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
48 : /// "TheDeclarator" is the declarator that this will be added to.
49 : DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
50 : SourceLocation EllipsisLoc,
51 : ParamInfo *ArgInfo,
52 : unsigned NumArgs,
53 : unsigned TypeQuals,
54 : bool hasExceptionSpec,
55 : SourceLocation ThrowLoc,
56 : bool hasAnyExceptionSpec,
57 : ActionBase::TypeTy **Exceptions,
58 : SourceRange *ExceptionRanges,
59 : unsigned NumExceptions,
60 : SourceLocation LPLoc,
61 : SourceLocation RPLoc,
62 14754: Declarator &TheDeclarator) {
63 14754: DeclaratorChunk I;
64 14754: I.Kind = Function;
65 14754: I.Loc = LPLoc;
66 14754: I.EndLoc = RPLoc;
67 14754: I.Fun.hasPrototype = hasProto;
68 14754: I.Fun.isVariadic = isVariadic;
69 14754: I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
70 14754: I.Fun.DeleteArgInfo = false;
71 14754: I.Fun.TypeQuals = TypeQuals;
72 14754: I.Fun.NumArgs = NumArgs;
73 14754: I.Fun.ArgInfo = 0;
74 14754: I.Fun.hasExceptionSpec = hasExceptionSpec;
75 14754: I.Fun.ThrowLoc = ThrowLoc.getRawEncoding();
76 14754: I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
77 14754: I.Fun.NumExceptions = NumExceptions;
78 14754: I.Fun.Exceptions = 0;
79 :
80 : // new[] an argument array if needed.
9231: branch 0 taken
5523: branch 1 taken
81 14754: if (NumArgs) {
82 : // If the 'InlineParams' in Declarator is unused and big enough, put our
83 : // parameter list there (in an effort to avoid new/delete traffic). If it
84 : // is already used (consider a function returning a function pointer) or too
85 : // small (function taking too many arguments), go to the heap.
9225: branch 0 taken
6: branch 1 taken
9224: branch 3 taken
1: branch 4 taken
9224: branch 5 taken
7: branch 6 taken
86 9231: if (!TheDeclarator.InlineParamsUsed &&
87 : NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
88 9224: I.Fun.ArgInfo = TheDeclarator.InlineParams;
89 9224: I.Fun.DeleteArgInfo = false;
90 9224: TheDeclarator.InlineParamsUsed = true;
91 : } else {
49: branch 2 taken
7: branch 3 taken
92 7: I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
93 7: I.Fun.DeleteArgInfo = true;
94 : }
95 9231: memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
96 : }
97 : // new[] an exception array if needed
82: branch 0 taken
14672: branch 1 taken
98 14754: if (NumExceptions) {
102: branch 2 taken
82: branch 3 taken
99 82: I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
102: branch 0 taken
82: branch 1 taken
100 184: for (unsigned i = 0; i != NumExceptions; ++i) {
101 102: I.Fun.Exceptions[i].Ty = Exceptions[i];
102 102: I.Fun.Exceptions[i].Range = ExceptionRanges[i];
103 : }
104 : }
105 : return I;
106 : }
107 :
108 : /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
109 : /// declaration specifier includes.
110 : ///
111 31527: unsigned DeclSpec::getParsedSpecifiers() const {
112 31527: unsigned Res = 0;
31403: branch 0 taken
124: branch 1 taken
2: branch 2 taken
31401: branch 3 taken
113 31527: if (StorageClassSpec != SCS_unspecified ||
114 : SCS_thread_specified)
115 126: Res |= PQ_StorageClassSpecifier;
116 :
1496: branch 0 taken
30031: branch 1 taken
117 31527: if (TypeQualifiers != TQ_unspecified)
118 1496: Res |= PQ_TypeQualifier;
119 :
31373: branch 1 taken
154: branch 2 taken
120 31527: if (hasTypeSpecifier())
121 31373: Res |= PQ_TypeSpecifier;
122 :
31508: branch 0 taken
19: branch 1 taken
31508: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
31508: branch 5 taken
123 31527: if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
124 19: Res |= PQ_FunctionSpecifier;
125 31527: return Res;
126 : }
127 :
128 : template <class T> static bool BadSpecifier(T TNew, T TPrev,
129 : const char *&PrevSpec,
130 1: unsigned &DiagID) {
131 1: PrevSpec = DeclSpec::getSpecifierName(TPrev);
1: branch 0 taken
1: branch 1 taken
1: branch 2 taken
1: branch 3 taken
1: branch 4 taken
1: branch 5 taken
1: branch 6 taken
1: branch 7 taken
0: branch 8 not taken
1: branch 9 taken
132 1: DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
133 : : diag::err_invalid_decl_spec_combination);
134 1: return true;
135 : }
136 :
137 7: const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
0: branch 0 not taken
1: branch 1 taken
1: branch 2 taken
1: branch 3 taken
1: branch 4 taken
1: branch 5 taken
0: branch 6 not taken
2: branch 7 taken
0: branch 8 not taken
138 7: switch (S) {
139 0: case DeclSpec::SCS_unspecified: return "unspecified";
140 1: case DeclSpec::SCS_typedef: return "typedef";
141 1: case DeclSpec::SCS_extern: return "extern";
142 1: case DeclSpec::SCS_static: return "static";
143 1: case DeclSpec::SCS_auto: return "auto";
144 1: case DeclSpec::SCS_register: return "register";
145 0: case DeclSpec::SCS_private_extern: return "__private_extern__";
146 2: case DeclSpec::SCS_mutable: return "mutable";
147 : }
148 0: llvm_unreachable("Unknown typespec!");
149 : }
150 :
151 0: const char *DeclSpec::getSpecifierName(TSW W) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
152 0: switch (W) {
153 0: case TSW_unspecified: return "unspecified";
154 0: case TSW_short: return "short";
155 0: case TSW_long: return "long";
156 0: case TSW_longlong: return "long long";
157 : }
158 0: llvm_unreachable("Unknown typespec!");
159 : }
160 :
161 0: const char *DeclSpec::getSpecifierName(TSC C) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
162 0: switch (C) {
163 0: case TSC_unspecified: return "unspecified";
164 0: case TSC_imaginary: return "imaginary";
165 0: case TSC_complex: return "complex";
166 : }
167 0: llvm_unreachable("Unknown typespec!");
168 : }
169 :
170 :
171 0: const char *DeclSpec::getSpecifierName(TSS S) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
172 0: switch (S) {
173 0: case TSS_unspecified: return "unspecified";
174 0: case TSS_signed: return "signed";
175 0: case TSS_unsigned: return "unsigned";
176 : }
177 0: llvm_unreachable("Unknown typespec!");
178 : }
179 :
180 234: const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
32: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
2: branch 3 taken
0: branch 4 not taken
0: branch 5 not taken
4: branch 6 taken
0: branch 7 not taken
14: branch 8 taken
0: branch 9 not taken
0: branch 10 not taken
0: branch 11 not taken
0: branch 12 not taken
0: branch 13 not taken
1: branch 14 taken
6: branch 15 taken
172: branch 16 taken
1: branch 17 taken
1: branch 18 taken
1: branch 19 taken
0: branch 20 not taken
0: branch 21 not taken
0: branch 22 not taken
181 234: switch (T) {
182 32: case DeclSpec::TST_unspecified: return "unspecified";
183 0: case DeclSpec::TST_void: return "void";
184 0: case DeclSpec::TST_char: return "char";
185 2: case DeclSpec::TST_wchar: return "wchar_t";
186 0: case DeclSpec::TST_char16: return "char16_t";
187 0: case DeclSpec::TST_char32: return "char32_t";
188 4: case DeclSpec::TST_int: return "int";
189 0: case DeclSpec::TST_float: return "float";
190 14: case DeclSpec::TST_double: return "double";
191 0: case DeclSpec::TST_bool: return "_Bool";
192 0: case DeclSpec::TST_decimal32: return "_Decimal32";
193 0: case DeclSpec::TST_decimal64: return "_Decimal64";
194 0: case DeclSpec::TST_decimal128: return "_Decimal128";
195 0: case DeclSpec::TST_enum: return "enum";
196 1: case DeclSpec::TST_class: return "class";
197 6: case DeclSpec::TST_union: return "union";
198 172: case DeclSpec::TST_struct: return "struct";
199 1: case DeclSpec::TST_typename: return "type-name";
200 : case DeclSpec::TST_typeofType:
201 1: case DeclSpec::TST_typeofExpr: return "typeof";
202 1: case DeclSpec::TST_auto: return "auto";
203 0: case DeclSpec::TST_decltype: return "(decltype)";
204 0: case DeclSpec::TST_error: return "(error)";
205 : }
206 0: llvm_unreachable("Unknown typespec!");
207 : }
208 :
209 0: const char *DeclSpec::getSpecifierName(TQ T) {
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
0: branch 4 not taken
210 0: switch (T) {
211 0: case DeclSpec::TQ_unspecified: return "unspecified";
212 0: case DeclSpec::TQ_const: return "const";
213 0: case DeclSpec::TQ_restrict: return "restrict";
214 0: case DeclSpec::TQ_volatile: return "volatile";
215 : }
216 0: llvm_unreachable("Unknown typespec!");
217 : }
218 :
219 : bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
220 : const char *&PrevSpec,
221 10373: unsigned &DiagID) {
1: branch 0 taken
10372: branch 1 taken
222 10373: if (StorageClassSpec != SCS_unspecified)
223 1: return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
224 10372: StorageClassSpec = S;
225 10372: StorageClassSpecLoc = Loc;
0: branch 0 not taken
10372: branch 1 taken
226 10372: assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
227 10372: return false;
228 : }
229 :
230 : bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
231 : const char *&PrevSpec,
232 20: unsigned &DiagID) {
0: branch 0 not taken
20: branch 1 taken
233 20: if (SCS_thread_specified) {
234 0: PrevSpec = "__thread";
235 0: DiagID = diag::ext_duplicate_declspec;
236 0: return true;
237 : }
238 20: SCS_thread_specified = true;
239 20: SCS_threadLoc = Loc;
240 20: return false;
241 : }
242 :
243 :
244 : /// These methods set the specified attribute of the DeclSpec, but return true
245 : /// and ignore the request if invalid (e.g. "extern" then "auto" is
246 : /// specified).
247 : bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
248 : const char *&PrevSpec,
249 2837: unsigned &DiagID) {
520: branch 0 taken
2317: branch 1 taken
520: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
520: branch 5 taken
250 2837: if (TypeSpecWidth != TSW_unspecified &&
251 : // Allow turning long -> long long.
252 : (W != TSW_longlong || TypeSpecWidth != TSW_long))
253 0: return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
254 2837: TypeSpecWidth = W;
255 2837: TSWLoc = Loc;
56: branch 0 taken
2781: branch 1 taken
24: branch 2 taken
32: branch 3 taken
0: branch 4 not taken
24: branch 5 taken
256 2837: if (TypeAltiVecVector && ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
257 32: PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
258 32: DiagID = diag::warn_vector_long_decl_spec_combination;
259 32: return true;
260 : }
261 2805: return false;
262 : }
263 :
264 : bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
265 : const char *&PrevSpec,
266 196: unsigned &DiagID) {
0: branch 0 not taken
196: branch 1 taken
267 196: if (TypeSpecComplex != TSC_unspecified)
268 0: return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
269 196: TypeSpecComplex = C;
270 196: TSCLoc = Loc;
271 196: return false;
272 : }
273 :
274 : bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
275 : const char *&PrevSpec,
276 3073: unsigned &DiagID) {
0: branch 0 not taken
3073: branch 1 taken
277 3073: if (TypeSpecSign != TSS_unspecified)
278 0: return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
279 3073: TypeSpecSign = S;
280 3073: TSSLoc = Loc;
281 3073: return false;
282 : }
283 :
284 : bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
285 : const char *&PrevSpec,
286 : unsigned &DiagID,
287 65422: void *Rep, bool Owned) {
5: branch 0 taken
65417: branch 1 taken
288 65422: if (TypeSpecType != TST_unspecified) {
289 5: PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
290 5: DiagID = diag::err_invalid_decl_spec_combination;
291 5: return true;
292 : }
293 65417: TypeSpecType = T;
294 65417: TypeRep = Rep;
295 65417: TSTLoc = Loc;
296 65417: TypeSpecOwned = Owned;
112: branch 0 taken
65305: branch 1 taken
14: branch 2 taken
98: branch 3 taken
297 65417: if (TypeAltiVecVector && (TypeSpecType == TST_double)) {
298 14: PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
299 14: DiagID = diag::err_invalid_vector_double_decl_spec_combination;
300 14: return true;
301 : }
302 65403: return false;
303 : }
304 :
305 : bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
306 144: const char *&PrevSpec, unsigned &DiagID) {
0: branch 0 not taken
144: branch 1 taken
307 144: if (TypeSpecType != TST_unspecified) {
308 0: PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
309 0: DiagID = diag::err_invalid_vector_decl_spec_combination;
310 0: return true;
311 : }
312 144: TypeAltiVecVector = isAltiVecVector;
313 144: AltiVecLoc = Loc;
314 144: return false;
315 : }
316 :
317 : bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
318 8: const char *&PrevSpec, unsigned &DiagID) {
8: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
8: branch 3 taken
319 8: if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) {
320 0: PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
321 0: DiagID = diag::err_invalid_pixel_decl_spec_combination;
322 0: return true;
323 : }
324 8: TypeSpecType = TST_int;
325 8: TypeSpecSign = TSS_unsigned;
326 8: TypeSpecWidth = TSW_short;
327 8: TypeAltiVecPixel = isAltiVecPixel;
328 8: TSTLoc = Loc;
329 8: return false;
330 : }
331 :
332 74: bool DeclSpec::SetTypeSpecError() {
333 74: TypeSpecType = TST_error;
334 74: TypeRep = 0;
335 74: TSTLoc = SourceLocation();
336 74: return false;
337 : }
338 :
339 : bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
340 3583: unsigned &DiagID, const LangOptions &Lang) {
341 : // Duplicates turn into warnings pre-C99.
0: branch 0 not taken
3583: branch 1 taken
3583: branch 2 taken
3583: branch 3 taken
342 3583: if ((TypeQualifiers & T) && !Lang.C99)
343 0: return BadSpecifier(T, T, PrevSpec, DiagID);
344 3583: TypeQualifiers |= T;
345 :
0: branch 0 not taken
2736: branch 1 taken
643: branch 2 taken
204: branch 3 taken
346 3583: switch (T) {
347 0: default: assert(0 && "Unknown type qualifier!");
348 2736: case TQ_const: TQ_constLoc = Loc; break;
349 643: case TQ_restrict: TQ_restrictLoc = Loc; break;
350 204: case TQ_volatile: TQ_volatileLoc = Loc; break;
351 : }
352 3583: return false;
353 : }
354 :
355 : bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
356 1407: unsigned &DiagID) {
357 : // 'inline inline' is ok.
358 1407: FS_inline_specified = true;
359 1407: FS_inlineLoc = Loc;
360 1407: return false;
361 : }
362 :
363 : bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
364 557: unsigned &DiagID) {
365 : // 'virtual virtual' is ok.
366 557: FS_virtual_specified = true;
367 557: FS_virtualLoc = Loc;
368 557: return false;
369 : }
370 :
371 : bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
372 31: unsigned &DiagID) {
373 : // 'explicit explicit' is ok.
374 31: FS_explicit_specified = true;
375 31: FS_explicitLoc = Loc;
376 31: return false;
377 : }
378 :
379 : bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
380 91: unsigned &DiagID) {
0: branch 0 not taken
91: branch 1 taken
381 91: if (Friend_specified) {
382 0: PrevSpec = "friend";
383 0: DiagID = diag::ext_duplicate_declspec;
384 0: return true;
385 : }
386 :
387 91: Friend_specified = true;
388 91: FriendLoc = Loc;
389 91: return false;
390 : }
391 :
392 : bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
393 0: unsigned &DiagID) {
394 : // 'constexpr constexpr' is ok.
395 0: Constexpr_specified = true;
396 0: ConstexprLoc = Loc;
397 0: return false;
398 : }
399 :
400 : void DeclSpec::setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos,
401 : unsigned NP,
402 : SourceLocation *ProtoLocs,
403 337: SourceLocation LAngleLoc) {
333: branch 0 taken
4: branch 1 taken
404 337: if (NP == 0) return;
423: branch 2 taken
333: branch 3 taken
405 333: ProtocolQualifiers = new ActionBase::DeclPtrTy[NP];
423: branch 2 taken
333: branch 3 taken
406 333: ProtocolLocs = new SourceLocation[NP];
407 333: memcpy((void*)ProtocolQualifiers, Protos, sizeof(ActionBase::DeclPtrTy)*NP);
408 333: memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
409 333: NumProtocolQualifiers = NP;
410 333: ProtocolLAngleLoc = LAngleLoc;
411 : }
412 :
413 93368: void DeclSpec::SaveWrittenBuiltinSpecs() {
414 93368: writtenBS.Sign = getTypeSpecSign();
415 93368: writtenBS.Width = getTypeSpecWidth();
416 93368: writtenBS.Type = getTypeSpecType();
417 : // Search the list of attributes for the presence of a mode attribute.
418 93368: writtenBS.ModeAttr = false;
419 93368: AttributeList* attrs = getAttributes();
3070: branch 0 taken
93366: branch 1 taken
420 189804: while (attrs) {
2: branch 1 taken
3068: branch 2 taken
421 3070: if (attrs->getKind() == AttributeList::AT_mode) {
422 2: writtenBS.ModeAttr = true;
423 2: break;
424 : }
425 3068: attrs = attrs->getNext();
426 : }
427 93368: }
428 :
429 : /// Finish - This does final analysis of the declspec, rejecting things like
430 : /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
431 : /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method,
432 : /// DeclSpec is guaranteed self-consistent, even if an error occurred.
433 93368: void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
434 : // Before possibly changing their values, save specs as written.
435 93368: SaveWrittenBuiltinSpecs();
436 :
437 : // Check the type specifier components first.
438 93368: SourceManager &SrcMgr = PP.getSourceManager();
439 :
440 : // signed/unsigned are only valid with int/char/wchar_t.
3077: branch 0 taken
90291: branch 1 taken
441 93368: if (TypeSpecSign != TSS_unspecified) {
1387: branch 0 taken
1690: branch 1 taken
442 3077: if (TypeSpecType == TST_unspecified)
443 1387: TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
604: branch 0 taken
1086: branch 1 taken
2: branch 2 taken
602: branch 3 taken
0: branch 4 not taken
2: branch 5 taken
444 1690: else if (TypeSpecType != TST_int &&
445 : TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
446 : Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec)
447 0: << getSpecifierName((TST)TypeSpecType);
448 : // signed double -> double.
449 0: TypeSpecSign = TSS_unspecified;
450 : }
451 : }
452 :
453 : // Validate the width of the type.
91053: branch 0 taken
1270: branch 1 taken
1045: branch 2 taken
0: branch 3 not taken
454 93368: switch (TypeSpecWidth) {
455 91053: case TSW_unspecified: break;
456 : case TSW_short: // short int
457 : case TSW_longlong: // long long int
601: branch 0 taken
669: branch 1 taken
458 1270: if (TypeSpecType == TST_unspecified)
459 601: TypeSpecType = TST_int; // short -> short int, long long -> long long int.
2: branch 0 taken
667: branch 1 taken
460 669: else if (TypeSpecType != TST_int) {
461 : Diag(D, TSWLoc, SrcMgr,
462 : TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
463 : : diag::err_invalid_longlong_spec)
2: branch 1 taken
0: branch 2 not taken
464 2: << getSpecifierName((TST)TypeSpecType);
465 2: TypeSpecType = TST_int;
466 : }
467 1270: break;
468 : case TSW_long: // long double, long int
377: branch 0 taken
668: branch 1 taken
469 1045: if (TypeSpecType == TST_unspecified)
470 377: TypeSpecType = TST_int; // long -> long int.
116: branch 0 taken
552: branch 1 taken
0: branch 2 not taken
116: branch 3 taken
471 668: else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
472 : Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec)
473 0: << getSpecifierName((TST)TypeSpecType);
474 0: TypeSpecType = TST_int;
475 : }
476 : break;
477 : }
478 :
479 : // TODO: if the implementation does not implement _Complex or _Imaginary,
480 : // disallow their use. Need information about the backend.
195: branch 0 taken
93173: branch 1 taken
481 93368: if (TypeSpecComplex != TSC_unspecified) {
2: branch 0 taken
193: branch 1 taken
482 195: if (TypeSpecType == TST_unspecified) {
483 : Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
484 : << CodeModificationHint::CreateInsertion(
485 : PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
486 2: " double");
487 2: TypeSpecType = TST_double; // _Complex -> _Complex double.
147: branch 0 taken
46: branch 1 taken
5: branch 2 taken
142: branch 3 taken
488 244: } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
489 : // Note that this intentionally doesn't include _Complex _Bool.
490 51: Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
53: branch 0 taken
89: branch 1 taken
0: branch 2 not taken
53: branch 3 taken
491 142: } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
492 : Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec)
493 0: << getSpecifierName((TST)TypeSpecType);
494 0: TypeSpecComplex = TSC_unspecified;
495 : }
496 : }
497 :
498 : // C++ [class.friend]p6:
499 : // No storage-class-specifier shall appear in the decl-specifier-seq
500 : // of a friend declaration.
91: branch 1 taken
93277: branch 2 taken
6: branch 4 taken
85: branch 5 taken
6: branch 6 taken
93362: branch 7 taken
501 93368: if (isFriendSpecified() && getStorageClassSpec()) {
502 6: DeclSpec::SCS SC = getStorageClassSpec();
503 6: const char *SpecName = getSpecifierName(SC);
504 :
505 6: SourceLocation SCLoc = getStorageClassSpecLoc();
506 6: SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName));
507 :
508 : Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec)
509 : << SpecName
510 6: << CodeModificationHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
511 :
512 6: ClearStorageClassSpecs();
513 : }
514 :
515 :
516 : // Okay, now we can infer the real type.
517 :
518 : // TODO: return "auto function" and other bad things based on the real type.
519 :
520 : // 'data definition has no type or storage class'?
521 93368: }
522 :
523 4621: bool DeclSpec::isMissingDeclaratorOk() {
524 4621: TST tst = getTypeSpecType();
525 : return (tst == TST_union
526 : || tst == TST_struct
527 : || tst == TST_class
528 : || tst == TST_enum
4559: branch 0 taken
62: branch 1 taken
1126: branch 2 taken
3433: branch 3 taken
310: branch 4 taken
816: branch 5 taken
281: branch 6 taken
29: branch 7 taken
4592: branch 9 taken
0: branch 10 not taken
4588: branch 11 taken
4: branch 12 taken
529 4621: ) && getTypeRep() != 0 && StorageClassSpec != DeclSpec::SCS_typedef;
530 : }
531 :
532 165291: void UnqualifiedId::clear() {
230: branch 0 taken
165061: branch 1 taken
533 165291: if (Kind == IK_TemplateId)
534 230: TemplateId->Destroy();
535 :
536 165291: Kind = IK_Identifier;
537 165291: Identifier = 0;
538 165291: StartLocation = SourceLocation();
539 165291: EndLocation = SourceLocation();
540 165291: }
541 :
542 : void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc,
543 : OverloadedOperatorKind Op,
544 299: SourceLocation SymbolLocations[3]) {
545 299: Kind = IK_OperatorFunctionId;
546 299: StartLocation = OperatorLoc;
547 299: EndLocation = OperatorLoc;
548 299: OperatorFunctionId.Operator = Op;
897: branch 0 taken
299: branch 1 taken
549 1196: for (unsigned I = 0; I != 3; ++I) {
550 897: OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
551 :
353: branch 1 taken
544: branch 2 taken
552 897: if (SymbolLocations[I].isValid())
553 353: EndLocation = SymbolLocations[I];
554 : }
555 299: }
Generated: 2010-02-10 01:31 by zcov