+ | Types SymbolicValueRef {
+ const PointerType *Ty = dyn_cast<PointerType>($1->get());
+ if (Ty == 0)
+ ThrowException("Global const reference must be a pointer type!");
+
+ // ConstExprs can exist in the body of a function, thus creating
+ // ConstantPointerRefs whenever they refer to a variable. Because we are in
+ // the context of a function, getValNonImprovising will search the functions
+ // symbol table instead of the module symbol table for the global symbol,
+ // which throws things all off. To get around this, we just tell
+ // getValNonImprovising that we are at global scope here.
+ //
+ Function *SavedCurFn = CurMeth.CurrentFunction;
+ CurMeth.CurrentFunction = 0;
+
+ Value *V = getValNonImprovising(Ty, $2);
+
+ CurMeth.CurrentFunction = SavedCurFn;
+
+ // 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(std::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,
+ GlobalValue::ExternalLinkage);
+ // Keep track of the fact that we have a forward ref to recycle it
+ CurModule.GlobalRefs.insert(std::make_pair(std::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
+ }
+ | Types ConstExpr {
+ if ($1->get() != $2->getType())
+ ThrowException("Mismatched types for constant expression!");
+ $$ = $2;
+ delete $1;