+ " arguments, but has size of " + itostr(NumElements) +"!");
+ $$ = ConstantArray::get(ATy, vector<Constant*>());
+ delete $1;
+ }
+ | Types 'c' STRINGCONSTANT {
+ const ArrayType *ATy = dyn_cast<const ArrayType>($1->get());
+ if (ATy == 0)
+ ThrowException("Cannot make array constant with type: '" +
+ (*$1)->getDescription() + "'!");
+
+ int NumElements = ATy->getNumElements();
+ const Type *ETy = ATy->getElementType();
+ char *EndStr = UnEscapeLexed($3, true);
+ if (NumElements != -1 && NumElements != (EndStr-$3))
+ ThrowException("Can't build string constant of size " +
+ itostr((int)(EndStr-$3)) +
+ " when array has size " + itostr(NumElements) + "!");
+ vector<Constant*> Vals;
+ if (ETy == Type::SByteTy) {
+ for (char *C = $3; C != EndStr; ++C)
+ Vals.push_back(ConstantSInt::get(ETy, *C));
+ } else if (ETy == Type::UByteTy) {
+ for (char *C = $3; C != EndStr; ++C)
+ Vals.push_back(ConstantUInt::get(ETy, *C));
+ } else {
+ free($3);
+ ThrowException("Cannot build string arrays of non byte sized elements!");
+ }
+ free($3);
+ $$ = ConstantArray::get(ATy, Vals);
+ delete $1;
+ }
+ | Types '{' ConstVector '}' {
+ const StructType *STy = dyn_cast<const StructType>($1->get());
+ if (STy == 0)
+ ThrowException("Cannot make struct constant with type: '" +
+ (*$1)->getDescription() + "'!");
+ // FIXME: TODO: Check to see that the constants are compatible with the type
+ // initializer!
+ $$ = ConstantStruct::get(STy, *$3);
+ delete $1; delete $3;
+ }
+ | Types NULL_TOK {
+ const PointerType *PTy = dyn_cast<const PointerType>($1->get());
+ if (PTy == 0)
+ ThrowException("Cannot make null pointer constant with type: '" +
+ (*$1)->getDescription() + "'!");
+
+ $$ = ConstantPointerNull::get(PTy);
+ delete $1;
+ }
+ | Types SymbolicValueRef {
+ const PointerType *Ty = dyn_cast<const PointerType>($1->get());
+ if (Ty == 0)
+ ThrowException("Global const reference must be a pointer type!");
+
+ Value *V = getValNonImprovising(Ty, $2);
+
+ // If this is an initializer for a constant pointer, which is referencing a
+ // (currently) undefined variable, create a stub now that shall be replaced
+ // in the future with the right type of variable.
+ //
+ if (V == 0) {
+ assert(isa<PointerType>(Ty) && "Globals may only be used as pointers!");
+ const PointerType *PT = cast<PointerType>(Ty);
+
+ // First check to see if the forward references value is already created!
+ PerModuleInfo::GlobalRefsType::iterator I =
+ CurModule.GlobalRefs.find(make_pair(PT, $2));
+
+ if (I != CurModule.GlobalRefs.end()) {
+ V = I->second; // Placeholder already exists, use it...
+ } else {
+ // TODO: Include line number info by creating a subclass of
+ // TODO: GlobalVariable here that includes the said information!
+
+ // Create a placeholder for the global variable reference...
+ GlobalVariable *GV = new GlobalVariable(PT->getElementType(),
+ false, true);
+ // Keep track of the fact that we have a forward ref to recycle it
+ CurModule.GlobalRefs.insert(make_pair(make_pair(PT, $2), GV));
+
+ // Must temporarily push this value into the module table...
+ CurModule.CurrentModule->getGlobalList().push_back(GV);
+ V = GV;
+ }
+ }
+
+ GlobalValue *GV = cast<GlobalValue>(V);
+ $$ = ConstantPointerRef::get(GV);
+ delete $1; // Free the type handle