|
Intel SPMD Program Compiler
1.3.0
|
00001 /* 00002 Copyright (c) 2010-2012, Intel Corporation 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions are 00007 met: 00008 00009 * Redistributions of source code must retain the above copyright 00010 notice, this list of conditions and the following disclaimer. 00011 00012 * Redistributions in binary form must reproduce the above copyright 00013 notice, this list of conditions and the following disclaimer in the 00014 documentation and/or other materials provided with the distribution. 00015 00016 * Neither the name of Intel Corporation nor the names of its 00017 contributors may be used to endorse or promote products derived from 00018 this software without specific prior written permission. 00019 00020 00021 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00022 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00023 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00024 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00025 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00026 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00027 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 */ 00033 00034 /** @file decl.cpp 00035 @brief Implementations of classes related to turning declarations into 00036 symbol names and types. 00037 */ 00038 00039 #include "decl.h" 00040 #include "util.h" 00041 #include "module.h" 00042 #include "sym.h" 00043 #include "type.h" 00044 #include "stmt.h" 00045 #include "expr.h" 00046 #include <stdio.h> 00047 #include <string.h> 00048 #include <set> 00049 00050 static void 00051 lPrintTypeQualifiers(int typeQualifiers) { 00052 if (typeQualifiers & TYPEQUAL_INLINE) printf("inline "); 00053 if (typeQualifiers & TYPEQUAL_CONST) printf("const "); 00054 if (typeQualifiers & TYPEQUAL_UNIFORM) printf("uniform "); 00055 if (typeQualifiers & TYPEQUAL_VARYING) printf("varying "); 00056 if (typeQualifiers & TYPEQUAL_TASK) printf("task "); 00057 if (typeQualifiers & TYPEQUAL_SIGNED) printf("signed "); 00058 if (typeQualifiers & TYPEQUAL_UNSIGNED) printf("unsigned "); 00059 if (typeQualifiers & TYPEQUAL_EXPORT) printf("export "); 00060 if (typeQualifiers & TYPEQUAL_UNMASKED) printf("unmasked "); 00061 } 00062 00063 00064 /** Given a Type and a set of type qualifiers, apply the type qualifiers to 00065 the type, returning the type that is the result. 00066 */ 00067 static const Type * 00068 lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) { 00069 if (type == NULL) 00070 return NULL; 00071 00072 if ((typeQualifiers & TYPEQUAL_CONST) != 0) 00073 type = type->GetAsConstType(); 00074 00075 if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) { 00076 if (Type::Equal(type, AtomicType::Void)) 00077 Error(pos, "\"uniform\" qualifier is illegal with \"void\" type."); 00078 else 00079 type = type->GetAsUniformType(); 00080 } 00081 else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) { 00082 if (Type::Equal(type, AtomicType::Void)) 00083 Error(pos, "\"varying\" qualifier is illegal with \"void\" type."); 00084 else 00085 type = type->GetAsVaryingType(); 00086 } 00087 else 00088 if (Type::Equal(type, AtomicType::Void) == false) 00089 type = type->GetAsUnboundVariabilityType(); 00090 00091 if ((typeQualifiers & TYPEQUAL_UNSIGNED) != 0) { 00092 if ((typeQualifiers & TYPEQUAL_SIGNED) != 0) 00093 Error(pos, "Illegal to apply both \"signed\" and \"unsigned\" " 00094 "qualifiers."); 00095 00096 const Type *unsignedType = type->GetAsUnsignedType(); 00097 if (unsignedType != NULL) 00098 type = unsignedType; 00099 else { 00100 const Type *resolvedType = 00101 type->ResolveUnboundVariability(Variability::Varying); 00102 Error(pos, "\"unsigned\" qualifier is illegal with \"%s\" type.", 00103 resolvedType->GetString().c_str()); 00104 } 00105 } 00106 00107 if ((typeQualifiers & TYPEQUAL_SIGNED) != 0 && type->IsIntType() == false) { 00108 const Type *resolvedType = 00109 type->ResolveUnboundVariability(Variability::Varying); 00110 Error(pos, "\"signed\" qualifier is illegal with non-integer type " 00111 "\"%s\".", resolvedType->GetString().c_str()); 00112 } 00113 00114 return type; 00115 } 00116 00117 00118 /////////////////////////////////////////////////////////////////////////// 00119 // DeclSpecs 00120 00121 DeclSpecs::DeclSpecs(const Type *t, StorageClass sc, int tq) { 00122 baseType = t; 00123 storageClass = sc; 00124 typeQualifiers = tq; 00125 soaWidth = 0; 00126 vectorSize = 0; 00127 } 00128 00129 00130 const Type * 00131 DeclSpecs::GetBaseType(SourcePos pos) const { 00132 const Type *retType = baseType; 00133 00134 if (retType == NULL) { 00135 Warning(pos, "No type specified in declaration. Assuming int32."); 00136 retType = AtomicType::UniformInt32->GetAsUnboundVariabilityType(); 00137 } 00138 00139 if (vectorSize > 0) { 00140 const AtomicType *atomicType = CastType<AtomicType>(retType); 00141 if (atomicType == NULL) { 00142 Error(pos, "Only atomic types (int, float, ...) are legal for vector " 00143 "types."); 00144 return NULL; 00145 } 00146 retType = new VectorType(atomicType, vectorSize); 00147 } 00148 00149 retType = lApplyTypeQualifiers(typeQualifiers, retType, pos); 00150 00151 if (soaWidth > 0) { 00152 const StructType *st = CastType<StructType>(retType); 00153 00154 if (st == NULL) { 00155 Error(pos, "Illegal to provide soa<%d> qualifier with non-struct " 00156 "type \"%s\".", soaWidth, retType->GetString().c_str()); 00157 return NULL; 00158 } 00159 else if (soaWidth <= 0 || (soaWidth & (soaWidth - 1)) != 0) { 00160 Error(pos, "soa<%d> width illegal. Value must be positive power " 00161 "of two.", soaWidth); 00162 return NULL; 00163 } 00164 00165 if (st->IsUniformType()) { 00166 Error(pos, "\"uniform\" qualifier and \"soa<%d>\" qualifier can't " 00167 "both be used in a type declaration.", soaWidth); 00168 return NULL; 00169 } 00170 else if (st->IsVaryingType()) { 00171 Error(pos, "\"varying\" qualifier and \"soa<%d>\" qualifier can't " 00172 "both be used in a type declaration.", soaWidth); 00173 return NULL; 00174 } 00175 else 00176 retType = st->GetAsSOAType(soaWidth); 00177 00178 if (soaWidth < g->target.vectorWidth) 00179 PerformanceWarning(pos, "soa<%d> width smaller than gang size %d " 00180 "currently leads to inefficient code to access " 00181 "soa types.", soaWidth, g->target.vectorWidth); 00182 } 00183 00184 return retType; 00185 } 00186 00187 00188 static const char * 00189 lGetStorageClassName(StorageClass storageClass) { 00190 switch (storageClass) { 00191 case SC_NONE: return ""; 00192 case SC_EXTERN: return "extern"; 00193 case SC_EXTERN_C: return "extern \"C\""; 00194 case SC_STATIC: return "static"; 00195 case SC_TYPEDEF: return "typedef"; 00196 default: FATAL("Unhandled storage class in lGetStorageClassName"); 00197 return ""; 00198 } 00199 } 00200 00201 00202 void 00203 DeclSpecs::Print() const { 00204 printf("Declspecs: [%s ", lGetStorageClassName(storageClass)); 00205 00206 if (soaWidth > 0) printf("soa<%d> ", soaWidth); 00207 lPrintTypeQualifiers(typeQualifiers); 00208 printf("base type: %s", baseType->GetString().c_str()); 00209 00210 if (vectorSize > 0) printf("<%d>", vectorSize); 00211 printf("]"); 00212 } 00213 00214 00215 /////////////////////////////////////////////////////////////////////////// 00216 // Declarator 00217 00218 Declarator::Declarator(DeclaratorKind dk, SourcePos p) 00219 : pos(p), kind(dk) { 00220 child = NULL; 00221 typeQualifiers = 0; 00222 storageClass = SC_NONE; 00223 arraySize = -1; 00224 type = NULL; 00225 initExpr = NULL; 00226 } 00227 00228 00229 void 00230 Declarator::InitFromDeclSpecs(DeclSpecs *ds) { 00231 const Type *baseType = ds->GetBaseType(pos); 00232 InitFromType(baseType, ds); 00233 00234 if (type == NULL) { 00235 AssertPos(pos, m->errorCount > 0); 00236 return; 00237 } 00238 00239 storageClass = ds->storageClass; 00240 00241 if (ds->declSpecList.size() > 0 && 00242 CastType<FunctionType>(type) == NULL) { 00243 Error(pos, "__declspec specifiers for non-function type \"%s\" are " 00244 "not used.", type->GetString().c_str()); 00245 } 00246 } 00247 00248 00249 void 00250 Declarator::Print(int indent) const { 00251 printf("%*cdeclarator: [", indent, ' '); 00252 pos.Print(); 00253 00254 lPrintTypeQualifiers(typeQualifiers); 00255 printf("%s ", lGetStorageClassName(storageClass)); 00256 if (name.size() > 0) 00257 printf("%s", name.c_str()); 00258 else 00259 printf("(unnamed)"); 00260 00261 printf(", array size = %d", arraySize); 00262 00263 printf(", kind = "); 00264 switch (kind) { 00265 case DK_BASE: printf("base"); break; 00266 case DK_POINTER: printf("pointer"); break; 00267 case DK_REFERENCE: printf("reference"); break; 00268 case DK_ARRAY: printf("array"); break; 00269 case DK_FUNCTION: printf("function"); break; 00270 default: FATAL("Unhandled declarator kind"); 00271 } 00272 00273 if (initExpr != NULL) { 00274 printf(" = ("); 00275 initExpr->Print(); 00276 printf(")"); 00277 } 00278 00279 if (functionParams.size() > 0) { 00280 for (unsigned int i = 0; i < functionParams.size(); ++i) { 00281 printf("\n%*cfunc param %d:\n", indent, ' ', i); 00282 functionParams[i]->Print(indent+4); 00283 } 00284 } 00285 00286 if (child != NULL) 00287 child->Print(indent + 4); 00288 00289 printf("]\n"); 00290 } 00291 00292 00293 void 00294 Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) { 00295 bool hasUniformQual = ((typeQualifiers & TYPEQUAL_UNIFORM) != 0); 00296 bool hasVaryingQual = ((typeQualifiers & TYPEQUAL_VARYING) != 0); 00297 bool isTask = ((typeQualifiers & TYPEQUAL_TASK) != 0); 00298 bool isExported = ((typeQualifiers & TYPEQUAL_EXPORT) != 0); 00299 bool isConst = ((typeQualifiers & TYPEQUAL_CONST) != 0); 00300 bool isUnmasked = ((typeQualifiers & TYPEQUAL_UNMASKED) != 0); 00301 00302 if (hasUniformQual && hasVaryingQual) { 00303 Error(pos, "Can't provide both \"uniform\" and \"varying\" qualifiers."); 00304 return; 00305 } 00306 if (kind != DK_FUNCTION && isTask) { 00307 Error(pos, "\"task\" qualifier illegal in variable declaration."); 00308 return; 00309 } 00310 if (kind != DK_FUNCTION && isUnmasked) { 00311 Error(pos, "\"unmasked\" qualifier illegal in variable declaration."); 00312 return; 00313 } 00314 if (kind != DK_FUNCTION && isExported) { 00315 Error(pos, "\"export\" qualifier illegal in variable declaration."); 00316 return; 00317 } 00318 00319 Variability variability(Variability::Unbound); 00320 if (hasUniformQual) 00321 variability = Variability::Uniform; 00322 else if (hasVaryingQual) 00323 variability = Variability::Varying; 00324 00325 if (kind == DK_BASE) { 00326 // All of the type qualifiers should be in the DeclSpecs for the 00327 // base declarator 00328 AssertPos(pos, typeQualifiers == 0); 00329 AssertPos(pos, child == NULL); 00330 type = baseType; 00331 } 00332 else if (kind == DK_POINTER) { 00333 /* For now, any pointer to an SOA type gets the slice property; if 00334 we add the capability to declare pointers as slices or not, 00335 we'll want to set this based on a type qualifier here. */ 00336 const Type *ptrType = new PointerType(baseType, variability, isConst, 00337 baseType->IsSOAType()); 00338 if (child != NULL) { 00339 child->InitFromType(ptrType, ds); 00340 type = child->type; 00341 name = child->name; 00342 } 00343 else 00344 type = ptrType; 00345 } 00346 else if (kind == DK_REFERENCE) { 00347 if (hasUniformQual) { 00348 Error(pos, "\"uniform\" qualifier is illegal to apply to references."); 00349 return; 00350 } 00351 if (hasVaryingQual) { 00352 Error(pos, "\"varying\" qualifier is illegal to apply to references."); 00353 return; 00354 } 00355 if (isConst) { 00356 Error(pos, "\"const\" qualifier is to illegal apply to references."); 00357 return; 00358 } 00359 // The parser should disallow this already, but double check. 00360 if (CastType<ReferenceType>(baseType) != NULL) { 00361 Error(pos, "References to references are illegal."); 00362 return; 00363 } 00364 00365 const Type *refType = new ReferenceType(baseType); 00366 if (child != NULL) { 00367 child->InitFromType(refType, ds); 00368 type = child->type; 00369 name = child->name; 00370 } 00371 else 00372 type = refType; 00373 } 00374 else if (kind == DK_ARRAY) { 00375 if (Type::Equal(baseType, AtomicType::Void)) { 00376 Error(pos, "Arrays of \"void\" type are illegal."); 00377 return; 00378 } 00379 if (CastType<ReferenceType>(baseType)) { 00380 Error(pos, "Arrays of references (type \"%s\") are illegal.", 00381 baseType->GetString().c_str()); 00382 return; 00383 } 00384 00385 const Type *arrayType = new ArrayType(baseType, arraySize); 00386 if (child != NULL) { 00387 child->InitFromType(arrayType, ds); 00388 type = child->type; 00389 name = child->name; 00390 } 00391 else 00392 type = arrayType; 00393 } 00394 else if (kind == DK_FUNCTION) { 00395 llvm::SmallVector<const Type *, 8> args; 00396 llvm::SmallVector<std::string, 8> argNames; 00397 llvm::SmallVector<Expr *, 8> argDefaults; 00398 llvm::SmallVector<SourcePos, 8> argPos; 00399 00400 // Loop over the function arguments and store the names, types, 00401 // default values (if any), and source file positions each one in 00402 // the corresponding vector. 00403 for (unsigned int i = 0; i < functionParams.size(); ++i) { 00404 Declaration *d = functionParams[i]; 00405 00406 if (d == NULL) { 00407 AssertPos(pos, m->errorCount > 0); 00408 continue; 00409 } 00410 if (d->declarators.size() == 0) { 00411 // function declaration like foo(float), w/o a name for the 00412 // parameter; wire up a placeholder Declarator for it 00413 d->declarators.push_back(new Declarator(DK_BASE, pos)); 00414 d->declarators[0]->InitFromDeclSpecs(d->declSpecs); 00415 } 00416 00417 AssertPos(pos, d->declarators.size() == 1); 00418 Declarator *decl = d->declarators[0]; 00419 if (decl == NULL || decl->type == NULL) { 00420 AssertPos(pos, m->errorCount > 0); 00421 continue; 00422 } 00423 00424 if (decl->name == "") { 00425 // Give a name to any anonymous parameter declarations 00426 char buf[32]; 00427 sprintf(buf, "__anon_parameter_%d", i); 00428 decl->name = buf; 00429 } 00430 decl->type = decl->type->ResolveUnboundVariability(Variability::Varying); 00431 00432 if (d->declSpecs->storageClass != SC_NONE) 00433 Error(decl->pos, "Storage class \"%s\" is illegal in " 00434 "function parameter declaration for parameter \"%s\".", 00435 lGetStorageClassName(d->declSpecs->storageClass), 00436 decl->name.c_str()); 00437 if (Type::Equal(decl->type, AtomicType::Void)) { 00438 Error(decl->pos, "Parameter with type \"void\" illegal in function " 00439 "parameter list."); 00440 decl->type = NULL; 00441 } 00442 00443 const ArrayType *at = CastType<ArrayType>(decl->type); 00444 if (at != NULL) { 00445 // As in C, arrays are passed to functions as pointers to 00446 // their element type. We'll just immediately make this 00447 // change now. (One shortcoming of losing the fact that 00448 // the it was originally an array is that any warnings or 00449 // errors later issued that print the function type will 00450 // report this differently than it was originally declared 00451 // in the function, but it's not clear that this is a 00452 // significant problem.) 00453 const Type *targetType = at->GetElementType(); 00454 if (targetType == NULL) { 00455 AssertPos(pos, m->errorCount > 0); 00456 return; 00457 } 00458 00459 decl->type = PointerType::GetUniform(targetType); 00460 00461 // Make sure there are no unsized arrays (other than the 00462 // first dimension) in function parameter lists. 00463 at = CastType<ArrayType>(targetType); 00464 while (at != NULL) { 00465 if (at->GetElementCount() == 0) 00466 Error(decl->pos, "Arrays with unsized dimensions in " 00467 "dimensions after the first one are illegal in " 00468 "function parameter lists."); 00469 at = CastType<ArrayType>(at->GetElementType()); 00470 } 00471 } 00472 00473 args.push_back(decl->type); 00474 argNames.push_back(decl->name); 00475 argPos.push_back(decl->pos); 00476 00477 Expr *init = NULL; 00478 // Try to find an initializer expression. 00479 while (decl != NULL) { 00480 if (decl->initExpr != NULL) { 00481 decl->initExpr = TypeCheck(decl->initExpr); 00482 decl->initExpr = Optimize(decl->initExpr); 00483 if (decl->initExpr != NULL) { 00484 init = dynamic_cast<ConstExpr *>(decl->initExpr); 00485 if (init == NULL) 00486 init = dynamic_cast<NullPointerExpr *>(decl->initExpr); 00487 if (init == NULL) 00488 Error(decl->initExpr->pos, "Default value for parameter " 00489 "\"%s\" must be a compile-time constant.", 00490 decl->name.c_str()); 00491 } 00492 break; 00493 } 00494 else 00495 decl = decl->child; 00496 } 00497 argDefaults.push_back(init); 00498 } 00499 00500 const Type *returnType = baseType; 00501 if (returnType == NULL) { 00502 Error(pos, "No return type provided in function declaration."); 00503 return; 00504 } 00505 00506 if (CastType<FunctionType>(returnType) != NULL) { 00507 Error(pos, "Illegal to return function type from function."); 00508 return; 00509 } 00510 00511 returnType = returnType->ResolveUnboundVariability(Variability::Varying); 00512 00513 bool isExternC = ds && (ds->storageClass == SC_EXTERN_C); 00514 bool isExported = ds && ((ds->typeQualifiers & TYPEQUAL_EXPORT) != 0); 00515 bool isTask = ds && ((ds->typeQualifiers & TYPEQUAL_TASK) != 0); 00516 bool isUnmasked = ds && ((ds->typeQualifiers & TYPEQUAL_UNMASKED) != 0); 00517 00518 if (isExported && isTask) { 00519 Error(pos, "Function can't have both \"task\" and \"export\" " 00520 "qualifiers"); 00521 return; 00522 } 00523 if (isExternC && isTask) { 00524 Error(pos, "Function can't have both \"extern \"C\"\" and \"task\" " 00525 "qualifiers"); 00526 return; 00527 } 00528 if (isExternC && isExported) { 00529 Error(pos, "Function can't have both \"extern \"C\"\" and \"export\" " 00530 "qualifiers"); 00531 return; 00532 } 00533 if (isUnmasked && isExported) 00534 Warning(pos, "\"unmasked\" qualifier is redundant for exported " 00535 "functions."); 00536 00537 if (child == NULL) { 00538 AssertPos(pos, m->errorCount > 0); 00539 return; 00540 } 00541 00542 const FunctionType *functionType = 00543 new FunctionType(returnType, args, argNames, argDefaults, 00544 argPos, isTask, isExported, isExternC, isUnmasked); 00545 00546 // handle any explicit __declspecs on the function 00547 if (ds != NULL) { 00548 for (int i = 0; i < (int)ds->declSpecList.size(); ++i) { 00549 std::string str = ds->declSpecList[i].first; 00550 SourcePos pos = ds->declSpecList[i].second; 00551 00552 if (str == "safe") 00553 (const_cast<FunctionType *>(functionType))->isSafe = true; 00554 else if (!strncmp(str.c_str(), "cost", 4)) { 00555 int cost = atoi(str.c_str() + 4); 00556 if (cost < 0) 00557 Error(pos, "Negative function cost %d is illegal.", 00558 cost); 00559 (const_cast<FunctionType *>(functionType))->costOverride = cost; 00560 } 00561 else 00562 Error(pos, "__declspec parameter \"%s\" unknown.", str.c_str()); 00563 } 00564 } 00565 00566 child->InitFromType(functionType, ds); 00567 type = child->type; 00568 name = child->name; 00569 } 00570 } 00571 00572 /////////////////////////////////////////////////////////////////////////// 00573 // Declaration 00574 00575 Declaration::Declaration(DeclSpecs *ds, std::vector<Declarator *> *dlist) { 00576 declSpecs = ds; 00577 if (dlist != NULL) 00578 declarators = *dlist; 00579 for (unsigned int i = 0; i < declarators.size(); ++i) 00580 if (declarators[i] != NULL) 00581 declarators[i]->InitFromDeclSpecs(declSpecs); 00582 } 00583 00584 00585 Declaration::Declaration(DeclSpecs *ds, Declarator *d) { 00586 declSpecs = ds; 00587 if (d != NULL) { 00588 d->InitFromDeclSpecs(ds); 00589 declarators.push_back(d); 00590 } 00591 } 00592 00593 00594 std::vector<VariableDeclaration> 00595 Declaration::GetVariableDeclarations() const { 00596 Assert(declSpecs->storageClass != SC_TYPEDEF); 00597 std::vector<VariableDeclaration> vars; 00598 00599 for (unsigned int i = 0; i < declarators.size(); ++i) { 00600 Declarator *decl = declarators[i]; 00601 if (decl == NULL || decl->type == NULL) { 00602 // Ignore earlier errors 00603 Assert(m->errorCount > 0); 00604 continue; 00605 } 00606 00607 if (Type::Equal(decl->type, AtomicType::Void)) 00608 Error(decl->pos, "\"void\" type variable illegal in declaration."); 00609 else if (CastType<FunctionType>(decl->type) == NULL) { 00610 decl->type = decl->type->ResolveUnboundVariability(Variability::Varying); 00611 Symbol *sym = new Symbol(decl->name, decl->pos, decl->type, 00612 decl->storageClass); 00613 m->symbolTable->AddVariable(sym); 00614 vars.push_back(VariableDeclaration(sym, decl->initExpr)); 00615 } 00616 } 00617 00618 return vars; 00619 } 00620 00621 00622 void 00623 Declaration::DeclareFunctions() { 00624 Assert(declSpecs->storageClass != SC_TYPEDEF); 00625 00626 for (unsigned int i = 0; i < declarators.size(); ++i) { 00627 Declarator *decl = declarators[i]; 00628 if (decl == NULL || decl->type == NULL) { 00629 // Ignore earlier errors 00630 Assert(m->errorCount > 0); 00631 continue; 00632 } 00633 00634 const FunctionType *ftype = CastType<FunctionType>(decl->type); 00635 if (ftype == NULL) 00636 continue; 00637 00638 bool isInline = (declSpecs->typeQualifiers & TYPEQUAL_INLINE); 00639 m->AddFunctionDeclaration(decl->name, ftype, decl->storageClass, 00640 isInline, decl->pos); 00641 } 00642 } 00643 00644 00645 void 00646 Declaration::Print(int indent) const { 00647 printf("%*cDeclaration: specs [", indent, ' '); 00648 declSpecs->Print(); 00649 printf("], declarators:\n"); 00650 for (unsigned int i = 0 ; i < declarators.size(); ++i) 00651 declarators[i]->Print(indent+4); 00652 } 00653 00654 00655 /////////////////////////////////////////////////////////////////////////// 00656 00657 void 00658 GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd, 00659 llvm::SmallVector<const Type *, 8> *elementTypes, 00660 llvm::SmallVector<std::string, 8> *elementNames, 00661 llvm::SmallVector<SourcePos, 8> *elementPositions) { 00662 std::set<std::string> seenNames; 00663 for (unsigned int i = 0; i < sd.size(); ++i) { 00664 const Type *type = sd[i]->type; 00665 if (type == NULL) 00666 continue; 00667 00668 // FIXME: making this fake little DeclSpecs here is really 00669 // disgusting 00670 DeclSpecs ds(type); 00671 if (Type::Equal(type, AtomicType::Void) == false) { 00672 if (type->IsUniformType()) 00673 ds.typeQualifiers |= TYPEQUAL_UNIFORM; 00674 else if (type->IsVaryingType()) 00675 ds.typeQualifiers |= TYPEQUAL_VARYING; 00676 else if (type->GetSOAWidth() != 0) 00677 ds.soaWidth = type->GetSOAWidth(); 00678 // FIXME: ds.vectorSize? 00679 } 00680 00681 for (unsigned int j = 0; j < sd[i]->declarators->size(); ++j) { 00682 Declarator *d = (*sd[i]->declarators)[j]; 00683 d->InitFromDeclSpecs(&ds); 00684 00685 if (Type::Equal(d->type, AtomicType::Void)) 00686 Error(d->pos, "\"void\" type illegal for struct member."); 00687 00688 elementTypes->push_back(d->type); 00689 00690 if (seenNames.find(d->name) != seenNames.end()) 00691 Error(d->pos, "Struct member \"%s\" has same name as a " 00692 "previously-declared member.", d->name.c_str()); 00693 else 00694 seenNames.insert(d->name); 00695 00696 elementNames->push_back(d->name); 00697 elementPositions->push_back(d->pos); 00698 } 00699 } 00700 00701 for (int i = 0; i < (int)elementTypes->size() - 1; ++i) { 00702 const ArrayType *arrayType = CastType<ArrayType>((*elementTypes)[i]); 00703 00704 if (arrayType != NULL && arrayType->GetElementCount() == 0) 00705 Error((*elementPositions)[i], "Unsized arrays aren't allowed except " 00706 "for the last member in a struct definition."); 00707 } 00708 }
1.7.5.1