| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1 | //===-- llvmAsmParser.y - Parser for llvm assembly files --------*- C++ -*-===// | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 5 | // This file was developed by the LLVM research group and is distributed under | 
|  | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 10 | //  This file implements the bison parser for LLVM assembly languages files. | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 11 | // | 
|  | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | %{ | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 15 | #include "UpgradeInternals.h" | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 16 | #include "llvm/CallingConv.h" | 
|  | 17 | #include "llvm/InlineAsm.h" | 
|  | 18 | #include "llvm/Instructions.h" | 
|  | 19 | #include "llvm/Module.h" | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 20 | #include "llvm/ValueSymbolTable.h" | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 21 | #include "llvm/Support/GetElementPtrTypeIterator.h" | 
|  | 22 | #include "llvm/ADT/STLExtras.h" | 
|  | 23 | #include "llvm/Support/MathExtras.h" | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 24 | #include <algorithm> | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 25 | #include <iostream> | 
| Chris Lattner | 8adde28 | 2007-02-11 21:40:10 +0000 | [diff] [blame] | 26 | #include <map> | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 27 | #include <list> | 
|  | 28 | #include <utility> | 
|  | 29 |  | 
|  | 30 | // DEBUG_UPREFS - Define this symbol if you want to enable debugging output | 
|  | 31 | // relating to upreferences in the input stream. | 
|  | 32 | // | 
|  | 33 | //#define DEBUG_UPREFS 1 | 
|  | 34 | #ifdef DEBUG_UPREFS | 
|  | 35 | #define UR_OUT(X) std::cerr << X | 
|  | 36 | #else | 
|  | 37 | #define UR_OUT(X) | 
|  | 38 | #endif | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 39 |  | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 40 | #define YYERROR_VERBOSE 1 | 
| Reid Spencer | 96839be | 2006-11-30 16:50:26 +0000 | [diff] [blame] | 41 | #define YYINCLUDED_STDLIB_H | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 42 | #define YYDEBUG 1 | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 43 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 44 | int yylex(); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 45 | int yyparse(); | 
|  | 46 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 47 | int yyerror(const char*); | 
|  | 48 | static void warning(const std::string& WarningMsg); | 
|  | 49 |  | 
|  | 50 | namespace llvm { | 
|  | 51 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 52 | std::istream* LexInput; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 53 | static std::string CurFilename; | 
| Reid Spencer | 96839be | 2006-11-30 16:50:26 +0000 | [diff] [blame] | 54 |  | 
| Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 55 | // This bool controls whether attributes are ever added to function declarations | 
|  | 56 | // definitions and calls. | 
|  | 57 | static bool AddAttributes = false; | 
|  | 58 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 59 | static Module *ParserResult; | 
|  | 60 | static bool ObsoleteVarArgs; | 
|  | 61 | static bool NewVarArgs; | 
|  | 62 | static BasicBlock *CurBB; | 
|  | 63 | static GlobalVariable *CurGV; | 
| Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 64 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 65 | // This contains info used when building the body of a function.  It is | 
|  | 66 | // destroyed when the function is completed. | 
|  | 67 | // | 
|  | 68 | typedef std::vector<Value *> ValueList;           // Numbered defs | 
|  | 69 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 70 | typedef std::pair<std::string,TypeInfo> RenameMapKey; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 71 | typedef std::map<RenameMapKey,std::string> RenameMapType; | 
|  | 72 |  | 
|  | 73 | static void | 
|  | 74 | ResolveDefinitions(std::map<const Type *,ValueList> &LateResolvers, | 
|  | 75 | std::map<const Type *,ValueList> *FutureLateResolvers = 0); | 
|  | 76 |  | 
|  | 77 | static struct PerModuleInfo { | 
|  | 78 | Module *CurrentModule; | 
|  | 79 | std::map<const Type *, ValueList> Values; // Module level numbered definitions | 
|  | 80 | std::map<const Type *,ValueList> LateResolveValues; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 81 | std::vector<PATypeHolder> Types; | 
|  | 82 | std::vector<Signedness> TypeSigns; | 
|  | 83 | std::map<std::string,Signedness> NamedTypeSigns; | 
|  | 84 | std::map<std::string,Signedness> NamedValueSigns; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 85 | std::map<ValID, PATypeHolder> LateResolveTypes; | 
|  | 86 | static Module::Endianness Endian; | 
|  | 87 | static Module::PointerSize PointerSize; | 
|  | 88 | RenameMapType RenameMap; | 
|  | 89 |  | 
|  | 90 | /// PlaceHolderInfo - When temporary placeholder objects are created, remember | 
|  | 91 | /// how they were referenced and on which line of the input they came from so | 
|  | 92 | /// that we can resolve them later and print error messages as appropriate. | 
|  | 93 | std::map<Value*, std::pair<ValID, int> > PlaceHolderInfo; | 
|  | 94 |  | 
|  | 95 | // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward | 
|  | 96 | // references to global values.  Global values may be referenced before they | 
|  | 97 | // are defined, and if so, the temporary object that they represent is held | 
|  | 98 | // here.  This is used for forward references of GlobalValues. | 
|  | 99 | // | 
|  | 100 | typedef std::map<std::pair<const PointerType *, ValID>, GlobalValue*> | 
|  | 101 | GlobalRefsType; | 
|  | 102 | GlobalRefsType GlobalRefs; | 
|  | 103 |  | 
|  | 104 | void ModuleDone() { | 
|  | 105 | // If we could not resolve some functions at function compilation time | 
|  | 106 | // (calls to functions before they are defined), resolve them now...  Types | 
|  | 107 | // are resolved when the constant pool has been completely parsed. | 
|  | 108 | // | 
|  | 109 | ResolveDefinitions(LateResolveValues); | 
|  | 110 |  | 
|  | 111 | // Check to make sure that all global value forward references have been | 
|  | 112 | // resolved! | 
|  | 113 | // | 
|  | 114 | if (!GlobalRefs.empty()) { | 
|  | 115 | std::string UndefinedReferences = "Unresolved global references exist:\n"; | 
|  | 116 |  | 
|  | 117 | for (GlobalRefsType::iterator I = GlobalRefs.begin(), E =GlobalRefs.end(); | 
|  | 118 | I != E; ++I) { | 
|  | 119 | UndefinedReferences += "  " + I->first.first->getDescription() + " " + | 
|  | 120 | I->first.second.getName() + "\n"; | 
|  | 121 | } | 
|  | 122 | error(UndefinedReferences); | 
|  | 123 | return; | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | if (CurrentModule->getDataLayout().empty()) { | 
|  | 127 | std::string dataLayout; | 
|  | 128 | if (Endian != Module::AnyEndianness) | 
|  | 129 | dataLayout.append(Endian == Module::BigEndian ? "E" : "e"); | 
|  | 130 | if (PointerSize != Module::AnyPointerSize) { | 
|  | 131 | if (!dataLayout.empty()) | 
|  | 132 | dataLayout += "-"; | 
|  | 133 | dataLayout.append(PointerSize == Module::Pointer64 ? | 
|  | 134 | "p:64:64" : "p:32:32"); | 
|  | 135 | } | 
|  | 136 | CurrentModule->setDataLayout(dataLayout); | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | Values.clear();         // Clear out function local definitions | 
|  | 140 | Types.clear(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 141 | TypeSigns.clear(); | 
|  | 142 | NamedTypeSigns.clear(); | 
|  | 143 | NamedValueSigns.clear(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 144 | CurrentModule = 0; | 
|  | 145 | } | 
|  | 146 |  | 
|  | 147 | // GetForwardRefForGlobal - Check to see if there is a forward reference | 
|  | 148 | // for this global.  If so, remove it from the GlobalRefs map and return it. | 
|  | 149 | // If not, just return null. | 
|  | 150 | GlobalValue *GetForwardRefForGlobal(const PointerType *PTy, ValID ID) { | 
|  | 151 | // Check to see if there is a forward reference to this global variable... | 
|  | 152 | // if there is, eliminate it and patch the reference to use the new def'n. | 
|  | 153 | GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PTy, ID)); | 
|  | 154 | GlobalValue *Ret = 0; | 
|  | 155 | if (I != GlobalRefs.end()) { | 
|  | 156 | Ret = I->second; | 
|  | 157 | GlobalRefs.erase(I); | 
|  | 158 | } | 
|  | 159 | return Ret; | 
|  | 160 | } | 
|  | 161 | void setEndianness(Module::Endianness E) { Endian = E; } | 
|  | 162 | void setPointerSize(Module::PointerSize sz) { PointerSize = sz; } | 
|  | 163 | } CurModule; | 
|  | 164 |  | 
|  | 165 | Module::Endianness  PerModuleInfo::Endian = Module::AnyEndianness; | 
|  | 166 | Module::PointerSize PerModuleInfo::PointerSize = Module::AnyPointerSize; | 
|  | 167 |  | 
|  | 168 | static struct PerFunctionInfo { | 
|  | 169 | Function *CurrentFunction;     // Pointer to current function being created | 
|  | 170 |  | 
|  | 171 | std::map<const Type*, ValueList> Values; // Keep track of #'d definitions | 
|  | 172 | std::map<const Type*, ValueList> LateResolveValues; | 
|  | 173 | bool isDeclare;                   // Is this function a forward declararation? | 
|  | 174 | GlobalValue::LinkageTypes Linkage;// Linkage for forward declaration. | 
|  | 175 |  | 
|  | 176 | /// BBForwardRefs - When we see forward references to basic blocks, keep | 
|  | 177 | /// track of them here. | 
|  | 178 | std::map<BasicBlock*, std::pair<ValID, int> > BBForwardRefs; | 
|  | 179 | std::vector<BasicBlock*> NumberedBlocks; | 
|  | 180 | RenameMapType RenameMap; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 181 | unsigned NextBBNum; | 
|  | 182 |  | 
|  | 183 | inline PerFunctionInfo() { | 
|  | 184 | CurrentFunction = 0; | 
|  | 185 | isDeclare = false; | 
|  | 186 | Linkage = GlobalValue::ExternalLinkage; | 
|  | 187 | } | 
|  | 188 |  | 
|  | 189 | inline void FunctionStart(Function *M) { | 
|  | 190 | CurrentFunction = M; | 
|  | 191 | NextBBNum = 0; | 
|  | 192 | } | 
|  | 193 |  | 
|  | 194 | void FunctionDone() { | 
|  | 195 | NumberedBlocks.clear(); | 
|  | 196 |  | 
|  | 197 | // Any forward referenced blocks left? | 
|  | 198 | if (!BBForwardRefs.empty()) { | 
|  | 199 | error("Undefined reference to label " + | 
|  | 200 | BBForwardRefs.begin()->first->getName()); | 
|  | 201 | return; | 
|  | 202 | } | 
|  | 203 |  | 
|  | 204 | // Resolve all forward references now. | 
|  | 205 | ResolveDefinitions(LateResolveValues, &CurModule.LateResolveValues); | 
|  | 206 |  | 
|  | 207 | Values.clear();         // Clear out function local definitions | 
|  | 208 | RenameMap.clear(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 209 | CurrentFunction = 0; | 
|  | 210 | isDeclare = false; | 
|  | 211 | Linkage = GlobalValue::ExternalLinkage; | 
|  | 212 | } | 
|  | 213 | } CurFun;  // Info for the current function... | 
|  | 214 |  | 
|  | 215 | static bool inFunctionScope() { return CurFun.CurrentFunction != 0; } | 
|  | 216 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 217 | /// This function is just a utility to make a Key value for the rename map. | 
|  | 218 | /// The Key is a combination of the name, type, Signedness of the original | 
|  | 219 | /// value (global/function). This just constructs the key and ensures that | 
|  | 220 | /// named Signedness values are resolved to the actual Signedness. | 
|  | 221 | /// @brief Make a key for the RenameMaps | 
|  | 222 | static RenameMapKey makeRenameMapKey(const std::string &Name, const Type* Ty, | 
|  | 223 | const Signedness &Sign) { | 
|  | 224 | TypeInfo TI; | 
|  | 225 | TI.T = Ty; | 
|  | 226 | if (Sign.isNamed()) | 
|  | 227 | // Don't allow Named Signedness nodes because they won't match. The actual | 
|  | 228 | // Signedness must be looked up in the NamedTypeSigns map. | 
|  | 229 | TI.S.copy(CurModule.NamedTypeSigns[Sign.getName()]); | 
|  | 230 | else | 
|  | 231 | TI.S.copy(Sign); | 
|  | 232 | return std::make_pair(Name, TI); | 
|  | 233 | } | 
|  | 234 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 235 |  | 
|  | 236 | //===----------------------------------------------------------------------===// | 
|  | 237 | //               Code to handle definitions of all the types | 
|  | 238 | //===----------------------------------------------------------------------===// | 
|  | 239 |  | 
|  | 240 | static int InsertValue(Value *V, | 
|  | 241 | std::map<const Type*,ValueList> &ValueTab = CurFun.Values) { | 
|  | 242 | if (V->hasName()) return -1;           // Is this a numbered definition? | 
|  | 243 |  | 
|  | 244 | // Yes, insert the value into the value table... | 
|  | 245 | ValueList &List = ValueTab[V->getType()]; | 
|  | 246 | List.push_back(V); | 
|  | 247 | return List.size()-1; | 
|  | 248 | } | 
|  | 249 |  | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 250 | static const Type *getType(const ValID &D, bool DoNotImprovise = false) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 251 | switch (D.Type) { | 
|  | 252 | case ValID::NumberVal:               // Is it a numbered definition? | 
|  | 253 | // Module constants occupy the lowest numbered slots... | 
|  | 254 | if ((unsigned)D.Num < CurModule.Types.size()) { | 
|  | 255 | return CurModule.Types[(unsigned)D.Num]; | 
|  | 256 | } | 
|  | 257 | break; | 
|  | 258 | case ValID::NameVal:                 // Is it a named definition? | 
|  | 259 | if (const Type *N = CurModule.CurrentModule->getTypeByName(D.Name)) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 260 | return N; | 
|  | 261 | } | 
|  | 262 | break; | 
|  | 263 | default: | 
|  | 264 | error("Internal parser error: Invalid symbol type reference"); | 
|  | 265 | return 0; | 
|  | 266 | } | 
|  | 267 |  | 
|  | 268 | // If we reached here, we referenced either a symbol that we don't know about | 
|  | 269 | // or an id number that hasn't been read yet.  We may be referencing something | 
|  | 270 | // forward, so just create an entry to be resolved later and get to it... | 
|  | 271 | // | 
|  | 272 | if (DoNotImprovise) return 0;  // Do we just want a null to be returned? | 
|  | 273 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 274 | if (inFunctionScope()) { | 
|  | 275 | if (D.Type == ValID::NameVal) { | 
|  | 276 | error("Reference to an undefined type: '" + D.getName() + "'"); | 
|  | 277 | return 0; | 
|  | 278 | } else { | 
|  | 279 | error("Reference to an undefined type: #" + itostr(D.Num)); | 
|  | 280 | return 0; | 
|  | 281 | } | 
|  | 282 | } | 
|  | 283 |  | 
|  | 284 | std::map<ValID, PATypeHolder>::iterator I =CurModule.LateResolveTypes.find(D); | 
|  | 285 | if (I != CurModule.LateResolveTypes.end()) | 
|  | 286 | return I->second; | 
|  | 287 |  | 
|  | 288 | Type *Typ = OpaqueType::get(); | 
|  | 289 | CurModule.LateResolveTypes.insert(std::make_pair(D, Typ)); | 
|  | 290 | return Typ; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 291 | } | 
|  | 292 |  | 
|  | 293 | /// This is like the getType method except that instead of looking up the type | 
|  | 294 | /// for a given ID, it looks up that type's sign. | 
|  | 295 | /// @brief Get the signedness of a referenced type | 
|  | 296 | static Signedness getTypeSign(const ValID &D) { | 
|  | 297 | switch (D.Type) { | 
|  | 298 | case ValID::NumberVal:               // Is it a numbered definition? | 
|  | 299 | // Module constants occupy the lowest numbered slots... | 
|  | 300 | if ((unsigned)D.Num < CurModule.TypeSigns.size()) { | 
|  | 301 | return CurModule.TypeSigns[(unsigned)D.Num]; | 
|  | 302 | } | 
|  | 303 | break; | 
|  | 304 | case ValID::NameVal: {               // Is it a named definition? | 
|  | 305 | std::map<std::string,Signedness>::const_iterator I = | 
|  | 306 | CurModule.NamedTypeSigns.find(D.Name); | 
|  | 307 | if (I != CurModule.NamedTypeSigns.end()) | 
|  | 308 | return I->second; | 
|  | 309 | // Perhaps its a named forward .. just cache the name | 
|  | 310 | Signedness S; | 
|  | 311 | S.makeNamed(D.Name); | 
|  | 312 | return S; | 
|  | 313 | } | 
|  | 314 | default: | 
|  | 315 | break; | 
|  | 316 | } | 
|  | 317 | // If we don't find it, its signless | 
|  | 318 | Signedness S; | 
|  | 319 | S.makeSignless(); | 
|  | 320 | return S; | 
|  | 321 | } | 
|  | 322 |  | 
|  | 323 | /// This function is analagous to getElementType in LLVM. It provides the same | 
|  | 324 | /// function except that it looks up the Signedness instead of the type. This is | 
|  | 325 | /// used when processing GEP instructions that need to extract the type of an | 
|  | 326 | /// indexed struct/array/ptr member. | 
|  | 327 | /// @brief Look up an element's sign. | 
|  | 328 | static Signedness getElementSign(const ValueInfo& VI, | 
|  | 329 | const std::vector<Value*> &Indices) { | 
|  | 330 | const Type *Ptr = VI.V->getType(); | 
|  | 331 | assert(isa<PointerType>(Ptr) && "Need pointer type"); | 
|  | 332 |  | 
|  | 333 | unsigned CurIdx = 0; | 
|  | 334 | Signedness S(VI.S); | 
|  | 335 | while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) { | 
|  | 336 | if (CurIdx == Indices.size()) | 
|  | 337 | break; | 
|  | 338 |  | 
|  | 339 | Value *Index = Indices[CurIdx++]; | 
|  | 340 | assert(!isa<PointerType>(CT) || CurIdx == 1 && "Invalid type"); | 
|  | 341 | Ptr = CT->getTypeAtIndex(Index); | 
|  | 342 | if (const Type* Ty = Ptr->getForwardedType()) | 
|  | 343 | Ptr = Ty; | 
|  | 344 | assert(S.isComposite() && "Bad Signedness type"); | 
|  | 345 | if (isa<StructType>(CT)) { | 
|  | 346 | S = S.get(cast<ConstantInt>(Index)->getZExtValue()); | 
|  | 347 | } else { | 
|  | 348 | S = S.get(0UL); | 
|  | 349 | } | 
|  | 350 | if (S.isNamed()) | 
|  | 351 | S = CurModule.NamedTypeSigns[S.getName()]; | 
|  | 352 | } | 
|  | 353 | Signedness Result; | 
|  | 354 | Result.makeComposite(S); | 
|  | 355 | return Result; | 
|  | 356 | } | 
|  | 357 |  | 
|  | 358 | /// This function just translates a ConstantInfo into a ValueInfo and calls | 
|  | 359 | /// getElementSign(ValueInfo,...). Its just a convenience. | 
|  | 360 | /// @brief ConstantInfo version of getElementSign. | 
|  | 361 | static Signedness getElementSign(const ConstInfo& CI, | 
|  | 362 | const std::vector<Constant*> &Indices) { | 
|  | 363 | ValueInfo VI; | 
|  | 364 | VI.V = CI.C; | 
|  | 365 | VI.S.copy(CI.S); | 
|  | 366 | std::vector<Value*> Idx; | 
|  | 367 | for (unsigned i = 0; i < Indices.size(); ++i) | 
|  | 368 | Idx.push_back(Indices[i]); | 
|  | 369 | Signedness result = getElementSign(VI, Idx); | 
|  | 370 | VI.destroy(); | 
|  | 371 | return result; | 
|  | 372 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 373 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 374 | /// This function determines if two function types differ only in their use of | 
|  | 375 | /// the sret parameter attribute in the first argument. If they are identical | 
|  | 376 | /// in all other respects, it returns true. Otherwise, it returns false. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 377 | static bool FuncTysDifferOnlyBySRet(const FunctionType *F1, | 
|  | 378 | const FunctionType *F2) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 379 | if (F1->getReturnType() != F2->getReturnType() || | 
|  | 380 | F1->getNumParams() != F2->getNumParams() || | 
|  | 381 | F1->getParamAttrs(0) != F2->getParamAttrs(0)) | 
|  | 382 | return false; | 
|  | 383 | unsigned SRetMask = ~unsigned(FunctionType::StructRetAttribute); | 
|  | 384 | for (unsigned i = 0; i < F1->getNumParams(); ++i) { | 
|  | 385 | if (F1->getParamType(i) != F2->getParamType(i) || | 
|  | 386 | unsigned(F1->getParamAttrs(i+1)) & SRetMask != | 
|  | 387 | unsigned(F2->getParamAttrs(i+1)) & SRetMask) | 
|  | 388 | return false; | 
|  | 389 | } | 
|  | 390 | return true; | 
|  | 391 | } | 
|  | 392 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 393 | /// This function determines if the type of V and Ty differ only by the SRet | 
|  | 394 | /// parameter attribute. This is a more generalized case of | 
|  | 395 | /// FuncTysDIfferOnlyBySRet since it doesn't require FunctionType arguments. | 
|  | 396 | static bool TypesDifferOnlyBySRet(Value *V, const Type* Ty) { | 
|  | 397 | if (V->getType() == Ty) | 
|  | 398 | return true; | 
|  | 399 | const PointerType *PF1 = dyn_cast<PointerType>(Ty); | 
|  | 400 | const PointerType *PF2 = dyn_cast<PointerType>(V->getType()); | 
|  | 401 | if (PF1 && PF2) { | 
|  | 402 | const FunctionType* FT1 = dyn_cast<FunctionType>(PF1->getElementType()); | 
|  | 403 | const FunctionType* FT2 = dyn_cast<FunctionType>(PF2->getElementType()); | 
|  | 404 | if (FT1 && FT2) | 
|  | 405 | return FuncTysDifferOnlyBySRet(FT1, FT2); | 
|  | 406 | } | 
|  | 407 | return false; | 
|  | 408 | } | 
|  | 409 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 410 | // The upgrade of csretcc to sret param attribute may have caused a function | 
|  | 411 | // to not be found because the param attribute changed the type of the called | 
|  | 412 | // function. This helper function, used in getExistingValue, detects that | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 413 | // situation and bitcasts the function to the correct type. | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 414 | static Value* handleSRetFuncTypeMerge(Value *V, const Type* Ty) { | 
|  | 415 | // Handle degenerate cases | 
|  | 416 | if (!V) | 
|  | 417 | return 0; | 
|  | 418 | if (V->getType() == Ty) | 
|  | 419 | return V; | 
|  | 420 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 421 | const PointerType *PF1 = dyn_cast<PointerType>(Ty); | 
|  | 422 | const PointerType *PF2 = dyn_cast<PointerType>(V->getType()); | 
|  | 423 | if (PF1 && PF2) { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 424 | const FunctionType *FT1 = dyn_cast<FunctionType>(PF1->getElementType()); | 
|  | 425 | const FunctionType *FT2 = dyn_cast<FunctionType>(PF2->getElementType()); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 426 | if (FT1 && FT2 && FuncTysDifferOnlyBySRet(FT1, FT2)) | 
|  | 427 | if (FT2->paramHasAttr(1, FunctionType::StructRetAttribute)) | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 428 | return V; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 429 | else if (Constant *C = dyn_cast<Constant>(V)) | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 430 | return ConstantExpr::getBitCast(C, PF1); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 431 | else | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 432 | return new BitCastInst(V, PF1, "upgrd.cast", CurBB); | 
|  | 433 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 434 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 435 | return 0; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 436 | } | 
|  | 437 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 438 | // getExistingValue - Look up the value specified by the provided type and | 
|  | 439 | // the provided ValID.  If the value exists and has already been defined, return | 
|  | 440 | // it.  Otherwise return null. | 
|  | 441 | // | 
|  | 442 | static Value *getExistingValue(const Type *Ty, const ValID &D) { | 
|  | 443 | if (isa<FunctionType>(Ty)) { | 
|  | 444 | error("Functions are not values and must be referenced as pointers"); | 
|  | 445 | } | 
|  | 446 |  | 
|  | 447 | switch (D.Type) { | 
|  | 448 | case ValID::NumberVal: {                 // Is it a numbered definition? | 
|  | 449 | unsigned Num = (unsigned)D.Num; | 
|  | 450 |  | 
|  | 451 | // Module constants occupy the lowest numbered slots... | 
|  | 452 | std::map<const Type*,ValueList>::iterator VI = CurModule.Values.find(Ty); | 
|  | 453 | if (VI != CurModule.Values.end()) { | 
|  | 454 | if (Num < VI->second.size()) | 
|  | 455 | return VI->second[Num]; | 
|  | 456 | Num -= VI->second.size(); | 
|  | 457 | } | 
|  | 458 |  | 
|  | 459 | // Make sure that our type is within bounds | 
|  | 460 | VI = CurFun.Values.find(Ty); | 
|  | 461 | if (VI == CurFun.Values.end()) return 0; | 
|  | 462 |  | 
|  | 463 | // Check that the number is within bounds... | 
|  | 464 | if (VI->second.size() <= Num) return 0; | 
|  | 465 |  | 
|  | 466 | return VI->second[Num]; | 
|  | 467 | } | 
|  | 468 |  | 
|  | 469 | case ValID::NameVal: {                // Is it a named definition? | 
|  | 470 | // Get the name out of the ID | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 471 | RenameMapKey Key = makeRenameMapKey(D.Name, Ty, D.S); | 
|  | 472 | Value *V = 0; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 473 | if (inFunctionScope()) { | 
|  | 474 | // See if the name was renamed | 
|  | 475 | RenameMapType::const_iterator I = CurFun.RenameMap.find(Key); | 
|  | 476 | std::string LookupName; | 
|  | 477 | if (I != CurFun.RenameMap.end()) | 
|  | 478 | LookupName = I->second; | 
|  | 479 | else | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 480 | LookupName = D.Name; | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 481 | ValueSymbolTable &SymTab = CurFun.CurrentFunction->getValueSymbolTable(); | 
|  | 482 | V = SymTab.lookup(LookupName); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 483 | if (V && V->getType() != Ty) | 
|  | 484 | V = handleSRetFuncTypeMerge(V, Ty); | 
|  | 485 | assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 486 | } | 
|  | 487 | if (!V) { | 
|  | 488 | RenameMapType::const_iterator I = CurModule.RenameMap.find(Key); | 
|  | 489 | std::string LookupName; | 
|  | 490 | if (I != CurModule.RenameMap.end()) | 
|  | 491 | LookupName = I->second; | 
|  | 492 | else | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 493 | LookupName = D.Name; | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 494 | V = CurModule.CurrentModule->getValueSymbolTable().lookup(LookupName); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 495 | if (V && V->getType() != Ty) | 
|  | 496 | V = handleSRetFuncTypeMerge(V, Ty); | 
|  | 497 | assert((!V || TypesDifferOnlyBySRet(V, Ty)) && "Found wrong type"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 498 | } | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 499 | if (!V) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 500 | return 0; | 
|  | 501 |  | 
|  | 502 | D.destroy();  // Free old strdup'd memory... | 
|  | 503 | return V; | 
|  | 504 | } | 
|  | 505 |  | 
|  | 506 | // Check to make sure that "Ty" is an integral type, and that our | 
|  | 507 | // value will fit into the specified type... | 
|  | 508 | case ValID::ConstSIntVal:    // Is it a constant pool reference?? | 
|  | 509 | if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) { | 
|  | 510 | error("Signed integral constant '" + itostr(D.ConstPool64) + | 
|  | 511 | "' is invalid for type '" + Ty->getDescription() + "'"); | 
|  | 512 | } | 
|  | 513 | return ConstantInt::get(Ty, D.ConstPool64); | 
|  | 514 |  | 
|  | 515 | case ValID::ConstUIntVal:     // Is it an unsigned const pool reference? | 
|  | 516 | if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) { | 
|  | 517 | if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) | 
|  | 518 | error("Integral constant '" + utostr(D.UConstPool64) + | 
|  | 519 | "' is invalid or out of range"); | 
|  | 520 | else     // This is really a signed reference.  Transmogrify. | 
|  | 521 | return ConstantInt::get(Ty, D.ConstPool64); | 
|  | 522 | } else | 
|  | 523 | return ConstantInt::get(Ty, D.UConstPool64); | 
|  | 524 |  | 
|  | 525 | case ValID::ConstFPVal:        // Is it a floating point const pool reference? | 
|  | 526 | if (!ConstantFP::isValueValidForType(Ty, D.ConstPoolFP)) | 
|  | 527 | error("FP constant invalid for type"); | 
|  | 528 | return ConstantFP::get(Ty, D.ConstPoolFP); | 
|  | 529 |  | 
|  | 530 | case ValID::ConstNullVal:      // Is it a null value? | 
|  | 531 | if (!isa<PointerType>(Ty)) | 
|  | 532 | error("Cannot create a a non pointer null"); | 
|  | 533 | return ConstantPointerNull::get(cast<PointerType>(Ty)); | 
|  | 534 |  | 
|  | 535 | case ValID::ConstUndefVal:      // Is it an undef value? | 
|  | 536 | return UndefValue::get(Ty); | 
|  | 537 |  | 
|  | 538 | case ValID::ConstZeroVal:      // Is it a zero value? | 
|  | 539 | return Constant::getNullValue(Ty); | 
|  | 540 |  | 
|  | 541 | case ValID::ConstantVal:       // Fully resolved constant? | 
|  | 542 | if (D.ConstantValue->getType() != Ty) | 
|  | 543 | error("Constant expression type different from required type"); | 
|  | 544 | return D.ConstantValue; | 
|  | 545 |  | 
|  | 546 | case ValID::InlineAsmVal: {    // Inline asm expression | 
|  | 547 | const PointerType *PTy = dyn_cast<PointerType>(Ty); | 
|  | 548 | const FunctionType *FTy = | 
|  | 549 | PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0; | 
|  | 550 | if (!FTy || !InlineAsm::Verify(FTy, D.IAD->Constraints)) | 
|  | 551 | error("Invalid type for asm constraint string"); | 
|  | 552 | InlineAsm *IA = InlineAsm::get(FTy, D.IAD->AsmString, D.IAD->Constraints, | 
|  | 553 | D.IAD->HasSideEffects); | 
|  | 554 | D.destroy();   // Free InlineAsmDescriptor. | 
|  | 555 | return IA; | 
|  | 556 | } | 
|  | 557 | default: | 
|  | 558 | assert(0 && "Unhandled case"); | 
|  | 559 | return 0; | 
|  | 560 | }   // End of switch | 
|  | 561 |  | 
|  | 562 | assert(0 && "Unhandled case"); | 
|  | 563 | return 0; | 
|  | 564 | } | 
|  | 565 |  | 
|  | 566 | // getVal - This function is identical to getExistingValue, except that if a | 
|  | 567 | // value is not already defined, it "improvises" by creating a placeholder var | 
|  | 568 | // that looks and acts just like the requested variable.  When the value is | 
|  | 569 | // defined later, all uses of the placeholder variable are replaced with the | 
|  | 570 | // real thing. | 
|  | 571 | // | 
|  | 572 | static Value *getVal(const Type *Ty, const ValID &ID) { | 
|  | 573 | if (Ty == Type::LabelTy) | 
|  | 574 | error("Cannot use a basic block here"); | 
|  | 575 |  | 
|  | 576 | // See if the value has already been defined. | 
|  | 577 | Value *V = getExistingValue(Ty, ID); | 
|  | 578 | if (V) return V; | 
|  | 579 |  | 
|  | 580 | if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty)) | 
|  | 581 | error("Invalid use of a composite type"); | 
|  | 582 |  | 
|  | 583 | // If we reached here, we referenced either a symbol that we don't know about | 
|  | 584 | // or an id number that hasn't been read yet.  We may be referencing something | 
|  | 585 | // forward, so just create an entry to be resolved later and get to it... | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 586 | V = new Argument(Ty); | 
|  | 587 |  | 
|  | 588 | // Remember where this forward reference came from.  FIXME, shouldn't we try | 
|  | 589 | // to recycle these things?? | 
|  | 590 | CurModule.PlaceHolderInfo.insert( | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 591 | std::make_pair(V, std::make_pair(ID, Upgradelineno))); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 592 |  | 
|  | 593 | if (inFunctionScope()) | 
|  | 594 | InsertValue(V, CurFun.LateResolveValues); | 
|  | 595 | else | 
|  | 596 | InsertValue(V, CurModule.LateResolveValues); | 
|  | 597 | return V; | 
|  | 598 | } | 
|  | 599 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 600 | /// @brief This just makes any name given to it unique, up to MAX_UINT times. | 
|  | 601 | static std::string makeNameUnique(const std::string& Name) { | 
|  | 602 | static unsigned UniqueNameCounter = 1; | 
|  | 603 | std::string Result(Name); | 
|  | 604 | Result += ".upgrd." + llvm::utostr(UniqueNameCounter++); | 
|  | 605 | return Result; | 
|  | 606 | } | 
|  | 607 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 608 | /// getBBVal - This is used for two purposes: | 
|  | 609 | ///  * If isDefinition is true, a new basic block with the specified ID is being | 
|  | 610 | ///    defined. | 
|  | 611 | ///  * If isDefinition is true, this is a reference to a basic block, which may | 
|  | 612 | ///    or may not be a forward reference. | 
|  | 613 | /// | 
|  | 614 | static BasicBlock *getBBVal(const ValID &ID, bool isDefinition = false) { | 
|  | 615 | assert(inFunctionScope() && "Can't get basic block at global scope"); | 
|  | 616 |  | 
|  | 617 | std::string Name; | 
|  | 618 | BasicBlock *BB = 0; | 
|  | 619 | switch (ID.Type) { | 
|  | 620 | default: | 
|  | 621 | error("Illegal label reference " + ID.getName()); | 
|  | 622 | break; | 
|  | 623 | case ValID::NumberVal:                // Is it a numbered definition? | 
|  | 624 | if (unsigned(ID.Num) >= CurFun.NumberedBlocks.size()) | 
|  | 625 | CurFun.NumberedBlocks.resize(ID.Num+1); | 
|  | 626 | BB = CurFun.NumberedBlocks[ID.Num]; | 
|  | 627 | break; | 
|  | 628 | case ValID::NameVal:                  // Is it a named definition? | 
|  | 629 | Name = ID.Name; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 630 | if (Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name)) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 631 | if (N->getType() != Type::LabelTy) { | 
|  | 632 | // Register names didn't use to conflict with basic block names | 
|  | 633 | // because of type planes. Now they all have to be unique. So, we just | 
|  | 634 | // rename the register and treat this name as if no basic block | 
|  | 635 | // had been found. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 636 | RenameMapKey Key = makeRenameMapKey(ID.Name, N->getType(), ID.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 637 | N->setName(makeNameUnique(N->getName())); | 
|  | 638 | CurModule.RenameMap[Key] = N->getName(); | 
|  | 639 | BB = 0; | 
|  | 640 | } else { | 
|  | 641 | BB = cast<BasicBlock>(N); | 
|  | 642 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 643 | } | 
|  | 644 | break; | 
|  | 645 | } | 
|  | 646 |  | 
|  | 647 | // See if the block has already been defined. | 
|  | 648 | if (BB) { | 
|  | 649 | // If this is the definition of the block, make sure the existing value was | 
|  | 650 | // just a forward reference.  If it was a forward reference, there will be | 
|  | 651 | // an entry for it in the PlaceHolderInfo map. | 
|  | 652 | if (isDefinition && !CurFun.BBForwardRefs.erase(BB)) | 
|  | 653 | // The existing value was a definition, not a forward reference. | 
|  | 654 | error("Redefinition of label " + ID.getName()); | 
|  | 655 |  | 
|  | 656 | ID.destroy();                       // Free strdup'd memory. | 
|  | 657 | return BB; | 
|  | 658 | } | 
|  | 659 |  | 
|  | 660 | // Otherwise this block has not been seen before. | 
|  | 661 | BB = new BasicBlock("", CurFun.CurrentFunction); | 
|  | 662 | if (ID.Type == ValID::NameVal) { | 
|  | 663 | BB->setName(ID.Name); | 
|  | 664 | } else { | 
|  | 665 | CurFun.NumberedBlocks[ID.Num] = BB; | 
|  | 666 | } | 
|  | 667 |  | 
|  | 668 | // If this is not a definition, keep track of it so we can use it as a forward | 
|  | 669 | // reference. | 
|  | 670 | if (!isDefinition) { | 
|  | 671 | // Remember where this forward reference came from. | 
|  | 672 | CurFun.BBForwardRefs[BB] = std::make_pair(ID, Upgradelineno); | 
|  | 673 | } else { | 
|  | 674 | // The forward declaration could have been inserted anywhere in the | 
|  | 675 | // function: insert it into the correct place now. | 
|  | 676 | CurFun.CurrentFunction->getBasicBlockList().remove(BB); | 
|  | 677 | CurFun.CurrentFunction->getBasicBlockList().push_back(BB); | 
|  | 678 | } | 
|  | 679 | ID.destroy(); | 
|  | 680 | return BB; | 
|  | 681 | } | 
|  | 682 |  | 
|  | 683 |  | 
|  | 684 | //===----------------------------------------------------------------------===// | 
|  | 685 | //              Code to handle forward references in instructions | 
|  | 686 | //===----------------------------------------------------------------------===// | 
|  | 687 | // | 
|  | 688 | // This code handles the late binding needed with statements that reference | 
|  | 689 | // values not defined yet... for example, a forward branch, or the PHI node for | 
|  | 690 | // a loop body. | 
|  | 691 | // | 
|  | 692 | // This keeps a table (CurFun.LateResolveValues) of all such forward references | 
|  | 693 | // and back patchs after we are done. | 
|  | 694 | // | 
|  | 695 |  | 
|  | 696 | // ResolveDefinitions - If we could not resolve some defs at parsing | 
|  | 697 | // time (forward branches, phi functions for loops, etc...) resolve the | 
|  | 698 | // defs now... | 
|  | 699 | // | 
|  | 700 | static void | 
|  | 701 | ResolveDefinitions(std::map<const Type*,ValueList> &LateResolvers, | 
|  | 702 | std::map<const Type*,ValueList> *FutureLateResolvers) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 703 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 704 | // Loop over LateResolveDefs fixing up stuff that couldn't be resolved | 
|  | 705 | for (std::map<const Type*,ValueList>::iterator LRI = LateResolvers.begin(), | 
|  | 706 | E = LateResolvers.end(); LRI != E; ++LRI) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 707 | const Type* Ty = LRI->first; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 708 | ValueList &List = LRI->second; | 
|  | 709 | while (!List.empty()) { | 
|  | 710 | Value *V = List.back(); | 
|  | 711 | List.pop_back(); | 
|  | 712 |  | 
|  | 713 | std::map<Value*, std::pair<ValID, int> >::iterator PHI = | 
|  | 714 | CurModule.PlaceHolderInfo.find(V); | 
|  | 715 | assert(PHI != CurModule.PlaceHolderInfo.end() && "Placeholder error"); | 
|  | 716 |  | 
|  | 717 | ValID &DID = PHI->second.first; | 
|  | 718 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 719 | Value *TheRealValue = getExistingValue(Ty, DID); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 720 | if (TheRealValue) { | 
|  | 721 | V->replaceAllUsesWith(TheRealValue); | 
|  | 722 | delete V; | 
|  | 723 | CurModule.PlaceHolderInfo.erase(PHI); | 
|  | 724 | } else if (FutureLateResolvers) { | 
|  | 725 | // Functions have their unresolved items forwarded to the module late | 
|  | 726 | // resolver table | 
|  | 727 | InsertValue(V, *FutureLateResolvers); | 
|  | 728 | } else { | 
|  | 729 | if (DID.Type == ValID::NameVal) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 730 | error("Reference to an invalid definition: '" + DID.getName() + | 
|  | 731 | "' of type '" + V->getType()->getDescription() + "'", | 
|  | 732 | PHI->second.second); | 
| Reid Spencer | 7de2e01 | 2007-01-29 19:08:46 +0000 | [diff] [blame] | 733 | return; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 734 | } else { | 
|  | 735 | error("Reference to an invalid definition: #" + | 
|  | 736 | itostr(DID.Num) + " of type '" + | 
|  | 737 | V->getType()->getDescription() + "'", PHI->second.second); | 
|  | 738 | return; | 
|  | 739 | } | 
|  | 740 | } | 
|  | 741 | } | 
|  | 742 | } | 
|  | 743 |  | 
|  | 744 | LateResolvers.clear(); | 
|  | 745 | } | 
|  | 746 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 747 | /// This function is used for type resolution and upref handling. When a type | 
|  | 748 | /// becomes concrete, this function is called to adjust the signedness for the | 
|  | 749 | /// concrete type. | 
|  | 750 | static void ResolveTypeSign(const Type* oldTy, const Signedness &Sign) { | 
|  | 751 | std::string TyName = CurModule.CurrentModule->getTypeName(oldTy); | 
|  | 752 | if (!TyName.empty()) | 
|  | 753 | CurModule.NamedTypeSigns[TyName] = Sign; | 
|  | 754 | } | 
|  | 755 |  | 
|  | 756 | /// ResolveTypeTo - A brand new type was just declared.  This means that (if | 
|  | 757 | /// name is not null) things referencing Name can be resolved.  Otherwise, | 
|  | 758 | /// things refering to the number can be resolved.  Do this now. | 
|  | 759 | static void ResolveTypeTo(char *Name, const Type *ToTy, const Signedness& Sign){ | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 760 | ValID D; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 761 | if (Name) | 
|  | 762 | D = ValID::create(Name); | 
|  | 763 | else | 
|  | 764 | D = ValID::create((int)CurModule.Types.size()); | 
|  | 765 | D.S.copy(Sign); | 
|  | 766 |  | 
|  | 767 | CurModule.NamedTypeSigns[Name] = Sign; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 768 |  | 
|  | 769 | std::map<ValID, PATypeHolder>::iterator I = | 
|  | 770 | CurModule.LateResolveTypes.find(D); | 
|  | 771 | if (I != CurModule.LateResolveTypes.end()) { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 772 | const Type *OldTy = I->second.get(); | 
|  | 773 | ((DerivedType*)OldTy)->refineAbstractTypeTo(ToTy); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 774 | CurModule.LateResolveTypes.erase(I); | 
|  | 775 | } | 
|  | 776 | } | 
|  | 777 |  | 
| Anton Korobeynikov | ce13b85 | 2007-01-28 15:25:24 +0000 | [diff] [blame] | 778 | /// This is the implementation portion of TypeHasInteger. It traverses the | 
|  | 779 | /// type given, avoiding recursive types, and returns true as soon as it finds | 
|  | 780 | /// an integer type. If no integer type is found, it returns false. | 
|  | 781 | static bool TypeHasIntegerI(const Type *Ty, std::vector<const Type*> Stack) { | 
|  | 782 | // Handle some easy cases | 
|  | 783 | if (Ty->isPrimitiveType() || (Ty->getTypeID() == Type::OpaqueTyID)) | 
|  | 784 | return false; | 
|  | 785 | if (Ty->isInteger()) | 
|  | 786 | return true; | 
|  | 787 | if (const SequentialType *STy = dyn_cast<SequentialType>(Ty)) | 
|  | 788 | return STy->getElementType()->isInteger(); | 
|  | 789 |  | 
|  | 790 | // Avoid type structure recursion | 
|  | 791 | for (std::vector<const Type*>::iterator I = Stack.begin(), E = Stack.end(); | 
|  | 792 | I != E; ++I) | 
|  | 793 | if (Ty == *I) | 
|  | 794 | return false; | 
|  | 795 |  | 
|  | 796 | // Push us on the type stack | 
|  | 797 | Stack.push_back(Ty); | 
|  | 798 |  | 
|  | 799 | if (const FunctionType *FTy = dyn_cast<FunctionType>(Ty)) { | 
|  | 800 | if (TypeHasIntegerI(FTy->getReturnType(), Stack)) | 
|  | 801 | return true; | 
|  | 802 | FunctionType::param_iterator I = FTy->param_begin(); | 
|  | 803 | FunctionType::param_iterator E = FTy->param_end(); | 
|  | 804 | for (; I != E; ++I) | 
|  | 805 | if (TypeHasIntegerI(*I, Stack)) | 
|  | 806 | return true; | 
|  | 807 | return false; | 
|  | 808 | } else if (const StructType *STy = dyn_cast<StructType>(Ty)) { | 
|  | 809 | StructType::element_iterator I = STy->element_begin(); | 
|  | 810 | StructType::element_iterator E = STy->element_end(); | 
|  | 811 | for (; I != E; ++I) { | 
|  | 812 | if (TypeHasIntegerI(*I, Stack)) | 
|  | 813 | return true; | 
|  | 814 | } | 
|  | 815 | return false; | 
|  | 816 | } | 
|  | 817 | // There shouldn't be anything else, but its definitely not integer | 
|  | 818 | assert(0 && "What type is this?"); | 
|  | 819 | return false; | 
|  | 820 | } | 
|  | 821 |  | 
|  | 822 | /// This is the interface to TypeHasIntegerI. It just provides the type stack, | 
|  | 823 | /// to avoid recursion, and then calls TypeHasIntegerI. | 
|  | 824 | static inline bool TypeHasInteger(const Type *Ty) { | 
|  | 825 | std::vector<const Type*> TyStack; | 
|  | 826 | return TypeHasIntegerI(Ty, TyStack); | 
|  | 827 | } | 
|  | 828 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 829 | // setValueName - Set the specified value to the name given.  The name may be | 
|  | 830 | // null potentially, in which case this is a noop.  The string passed in is | 
|  | 831 | // assumed to be a malloc'd string buffer, and is free'd by this function. | 
|  | 832 | // | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 833 | static void setValueName(const ValueInfo &V, char *NameStr) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 834 | if (NameStr) { | 
|  | 835 | std::string Name(NameStr);      // Copy string | 
|  | 836 | free(NameStr);                  // Free old string | 
|  | 837 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 838 | if (V.V->getType() == Type::VoidTy) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 839 | error("Can't assign name '" + Name + "' to value with void type"); | 
|  | 840 | return; | 
|  | 841 | } | 
|  | 842 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 843 | assert(inFunctionScope() && "Must be in function scope"); | 
|  | 844 |  | 
|  | 845 | // Search the function's symbol table for an existing value of this name | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 846 | ValueSymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable(); | 
|  | 847 | Value* Existing = ST.lookup(Name); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 848 | if (Existing) { | 
| Anton Korobeynikov | ce13b85 | 2007-01-28 15:25:24 +0000 | [diff] [blame] | 849 | // An existing value of the same name was found. This might have happened | 
|  | 850 | // because of the integer type planes collapsing in LLVM 2.0. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 851 | if (Existing->getType() == V.V->getType() && | 
| Anton Korobeynikov | ce13b85 | 2007-01-28 15:25:24 +0000 | [diff] [blame] | 852 | !TypeHasInteger(Existing->getType())) { | 
|  | 853 | // If the type does not contain any integers in them then this can't be | 
|  | 854 | // a type plane collapsing issue. It truly is a redefinition and we | 
|  | 855 | // should error out as the assembly is invalid. | 
|  | 856 | error("Redefinition of value named '" + Name + "' of type '" + | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 857 | V.V->getType()->getDescription() + "'"); | 
| Anton Korobeynikov | ce13b85 | 2007-01-28 15:25:24 +0000 | [diff] [blame] | 858 | return; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 859 | } | 
|  | 860 | // In LLVM 2.0 we don't allow names to be re-used for any values in a | 
|  | 861 | // function, regardless of Type. Previously re-use of names was okay as | 
|  | 862 | // long as they were distinct types. With type planes collapsing because | 
|  | 863 | // of the signedness change and because of PR411, this can no longer be | 
|  | 864 | // supported. We must search the entire symbol table for a conflicting | 
|  | 865 | // name and make the name unique. No warning is needed as this can't | 
|  | 866 | // cause a problem. | 
|  | 867 | std::string NewName = makeNameUnique(Name); | 
|  | 868 | // We're changing the name but it will probably be used by other | 
|  | 869 | // instructions as operands later on. Consequently we have to retain | 
|  | 870 | // a mapping of the renaming that we're doing. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 871 | RenameMapKey Key = makeRenameMapKey(Name, V.V->getType(), V.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 872 | CurFun.RenameMap[Key] = NewName; | 
|  | 873 | Name = NewName; | 
|  | 874 | } | 
|  | 875 |  | 
|  | 876 | // Set the name. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 877 | V.V->setName(Name); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 878 | } | 
|  | 879 | } | 
|  | 880 |  | 
|  | 881 | /// ParseGlobalVariable - Handle parsing of a global.  If Initializer is null, | 
|  | 882 | /// this is a declaration, otherwise it is a definition. | 
|  | 883 | static GlobalVariable * | 
|  | 884 | ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage, | 
|  | 885 | bool isConstantGlobal, const Type *Ty, | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 886 | Constant *Initializer, | 
|  | 887 | const Signedness &Sign) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 888 | if (isa<FunctionType>(Ty)) | 
|  | 889 | error("Cannot declare global vars of function type"); | 
|  | 890 |  | 
|  | 891 | const PointerType *PTy = PointerType::get(Ty); | 
|  | 892 |  | 
|  | 893 | std::string Name; | 
|  | 894 | if (NameStr) { | 
|  | 895 | Name = NameStr;      // Copy string | 
|  | 896 | free(NameStr);       // Free old string | 
|  | 897 | } | 
|  | 898 |  | 
|  | 899 | // See if this global value was forward referenced.  If so, recycle the | 
|  | 900 | // object. | 
|  | 901 | ValID ID; | 
|  | 902 | if (!Name.empty()) { | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 903 | ID = ValID::create((char*)Name.c_str()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 904 | } else { | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 905 | ID = ValID::create((int)CurModule.Values[PTy].size()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 906 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 907 | ID.S.makeComposite(Sign); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 908 |  | 
|  | 909 | if (GlobalValue *FWGV = CurModule.GetForwardRefForGlobal(PTy, ID)) { | 
|  | 910 | // Move the global to the end of the list, from whereever it was | 
|  | 911 | // previously inserted. | 
|  | 912 | GlobalVariable *GV = cast<GlobalVariable>(FWGV); | 
|  | 913 | CurModule.CurrentModule->getGlobalList().remove(GV); | 
|  | 914 | CurModule.CurrentModule->getGlobalList().push_back(GV); | 
|  | 915 | GV->setInitializer(Initializer); | 
|  | 916 | GV->setLinkage(Linkage); | 
|  | 917 | GV->setConstant(isConstantGlobal); | 
|  | 918 | InsertValue(GV, CurModule.Values); | 
|  | 919 | return GV; | 
|  | 920 | } | 
|  | 921 |  | 
|  | 922 | // If this global has a name, check to see if there is already a definition | 
|  | 923 | // of this global in the module and emit warnings if there are conflicts. | 
|  | 924 | if (!Name.empty()) { | 
|  | 925 | // The global has a name. See if there's an existing one of the same name. | 
|  | 926 | if (CurModule.CurrentModule->getNamedGlobal(Name)) { | 
|  | 927 | // We found an existing global ov the same name. This isn't allowed | 
|  | 928 | // in LLVM 2.0. Consequently, we must alter the name of the global so it | 
|  | 929 | // can at least compile. This can happen because of type planes | 
|  | 930 | // There is alread a global of the same name which means there is a | 
|  | 931 | // conflict. Let's see what we can do about it. | 
|  | 932 | std::string NewName(makeNameUnique(Name)); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 933 | if (Linkage != GlobalValue::InternalLinkage) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 934 | // The linkage of this gval is external so we can't reliably rename | 
|  | 935 | // it because it could potentially create a linking problem. | 
|  | 936 | // However, we can't leave the name conflict in the output either or | 
|  | 937 | // it won't assemble with LLVM 2.0.  So, all we can do is rename | 
|  | 938 | // this one to something unique and emit a warning about the problem. | 
|  | 939 | warning("Renaming global variable '" + Name + "' to '" + NewName + | 
|  | 940 | "' may cause linkage errors"); | 
|  | 941 | } | 
|  | 942 |  | 
|  | 943 | // Put the renaming in the global rename map | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 944 | RenameMapKey Key = makeRenameMapKey(Name, PointerType::get(Ty), ID.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 945 | CurModule.RenameMap[Key] = NewName; | 
|  | 946 |  | 
|  | 947 | // Rename it | 
|  | 948 | Name = NewName; | 
|  | 949 | } | 
|  | 950 | } | 
|  | 951 |  | 
|  | 952 | // Otherwise there is no existing GV to use, create one now. | 
|  | 953 | GlobalVariable *GV = | 
|  | 954 | new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name, | 
|  | 955 | CurModule.CurrentModule); | 
|  | 956 | InsertValue(GV, CurModule.Values); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 957 | // Remember the sign of this global. | 
|  | 958 | CurModule.NamedValueSigns[Name] = ID.S; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 959 | return GV; | 
|  | 960 | } | 
|  | 961 |  | 
|  | 962 | // setTypeName - Set the specified type to the name given.  The name may be | 
|  | 963 | // null potentially, in which case this is a noop.  The string passed in is | 
|  | 964 | // assumed to be a malloc'd string buffer, and is freed by this function. | 
|  | 965 | // | 
|  | 966 | // This function returns true if the type has already been defined, but is | 
|  | 967 | // allowed to be redefined in the specified context.  If the name is a new name | 
|  | 968 | // for the type plane, it is inserted and false is returned. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 969 | static bool setTypeName(const PATypeInfo& TI, char *NameStr) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 970 | assert(!inFunctionScope() && "Can't give types function-local names"); | 
|  | 971 | if (NameStr == 0) return false; | 
|  | 972 |  | 
|  | 973 | std::string Name(NameStr);      // Copy string | 
|  | 974 | free(NameStr);                  // Free old string | 
|  | 975 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 976 | const Type* Ty = TI.PAT->get(); | 
|  | 977 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 978 | // We don't allow assigning names to void type | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 979 | if (Ty == Type::VoidTy) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 980 | error("Can't assign name '" + Name + "' to the void type"); | 
|  | 981 | return false; | 
|  | 982 | } | 
|  | 983 |  | 
|  | 984 | // Set the type name, checking for conflicts as we do so. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 985 | bool AlreadyExists = CurModule.CurrentModule->addTypeName(Name, Ty); | 
|  | 986 |  | 
|  | 987 | // Save the sign information for later use | 
|  | 988 | CurModule.NamedTypeSigns[Name] = TI.S; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 989 |  | 
|  | 990 | if (AlreadyExists) {   // Inserting a name that is already defined??? | 
|  | 991 | const Type *Existing = CurModule.CurrentModule->getTypeByName(Name); | 
|  | 992 | assert(Existing && "Conflict but no matching type?"); | 
|  | 993 |  | 
|  | 994 | // There is only one case where this is allowed: when we are refining an | 
|  | 995 | // opaque type.  In this case, Existing will be an opaque type. | 
|  | 996 | if (const OpaqueType *OpTy = dyn_cast<OpaqueType>(Existing)) { | 
|  | 997 | // We ARE replacing an opaque type! | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 998 | const_cast<OpaqueType*>(OpTy)->refineAbstractTypeTo(Ty); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 999 | return true; | 
|  | 1000 | } | 
|  | 1001 |  | 
|  | 1002 | // Otherwise, this is an attempt to redefine a type. That's okay if | 
|  | 1003 | // the redefinition is identical to the original. This will be so if | 
|  | 1004 | // Existing and T point to the same Type object. In this one case we | 
|  | 1005 | // allow the equivalent redefinition. | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1006 | if (Existing == Ty) return true;  // Yes, it's equal. | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1007 |  | 
|  | 1008 | // Any other kind of (non-equivalent) redefinition is an error. | 
|  | 1009 | error("Redefinition of type named '" + Name + "' in the '" + | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1010 | Ty->getDescription() + "' type plane"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1011 | } | 
|  | 1012 |  | 
|  | 1013 | return false; | 
|  | 1014 | } | 
|  | 1015 |  | 
|  | 1016 | //===----------------------------------------------------------------------===// | 
|  | 1017 | // Code for handling upreferences in type names... | 
|  | 1018 | // | 
|  | 1019 |  | 
|  | 1020 | // TypeContains - Returns true if Ty directly contains E in it. | 
|  | 1021 | // | 
|  | 1022 | static bool TypeContains(const Type *Ty, const Type *E) { | 
|  | 1023 | return std::find(Ty->subtype_begin(), Ty->subtype_end(), | 
|  | 1024 | E) != Ty->subtype_end(); | 
|  | 1025 | } | 
|  | 1026 |  | 
|  | 1027 | namespace { | 
|  | 1028 | struct UpRefRecord { | 
|  | 1029 | // NestingLevel - The number of nesting levels that need to be popped before | 
|  | 1030 | // this type is resolved. | 
|  | 1031 | unsigned NestingLevel; | 
|  | 1032 |  | 
|  | 1033 | // LastContainedTy - This is the type at the current binding level for the | 
|  | 1034 | // type.  Every time we reduce the nesting level, this gets updated. | 
|  | 1035 | const Type *LastContainedTy; | 
|  | 1036 |  | 
|  | 1037 | // UpRefTy - This is the actual opaque type that the upreference is | 
|  | 1038 | // represented with. | 
|  | 1039 | OpaqueType *UpRefTy; | 
|  | 1040 |  | 
|  | 1041 | UpRefRecord(unsigned NL, OpaqueType *URTy) | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1042 | : NestingLevel(NL), LastContainedTy(URTy), UpRefTy(URTy) { } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1043 | }; | 
|  | 1044 | } | 
|  | 1045 |  | 
|  | 1046 | // UpRefs - A list of the outstanding upreferences that need to be resolved. | 
|  | 1047 | static std::vector<UpRefRecord> UpRefs; | 
|  | 1048 |  | 
|  | 1049 | /// HandleUpRefs - Every time we finish a new layer of types, this function is | 
|  | 1050 | /// called.  It loops through the UpRefs vector, which is a list of the | 
|  | 1051 | /// currently active types.  For each type, if the up reference is contained in | 
|  | 1052 | /// the newly completed type, we decrement the level count.  When the level | 
|  | 1053 | /// count reaches zero, the upreferenced type is the type that is passed in: | 
|  | 1054 | /// thus we can complete the cycle. | 
|  | 1055 | /// | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1056 | static PATypeHolder HandleUpRefs(const Type *ty, const Signedness& Sign) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1057 | // If Ty isn't abstract, or if there are no up-references in it, then there is | 
|  | 1058 | // nothing to resolve here. | 
|  | 1059 | if (!ty->isAbstract() || UpRefs.empty()) return ty; | 
|  | 1060 |  | 
|  | 1061 | PATypeHolder Ty(ty); | 
|  | 1062 | UR_OUT("Type '" << Ty->getDescription() << | 
|  | 1063 | "' newly formed.  Resolving upreferences.\n" << | 
|  | 1064 | UpRefs.size() << " upreferences active!\n"); | 
|  | 1065 |  | 
|  | 1066 | // If we find any resolvable upreferences (i.e., those whose NestingLevel goes | 
|  | 1067 | // to zero), we resolve them all together before we resolve them to Ty.  At | 
|  | 1068 | // the end of the loop, if there is anything to resolve to Ty, it will be in | 
|  | 1069 | // this variable. | 
|  | 1070 | OpaqueType *TypeToResolve = 0; | 
|  | 1071 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1072 | unsigned i = 0; | 
|  | 1073 | for (; i != UpRefs.size(); ++i) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1074 | UR_OUT("  UR#" << i << " - TypeContains(" << Ty->getDescription() << ", " | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1075 | << UpRefs[i].UpRefTy->getDescription() << ") = " | 
|  | 1076 | << (TypeContains(Ty, UpRefs[i].UpRefTy) ? "true" : "false") << "\n"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1077 | if (TypeContains(Ty, UpRefs[i].LastContainedTy)) { | 
|  | 1078 | // Decrement level of upreference | 
|  | 1079 | unsigned Level = --UpRefs[i].NestingLevel; | 
|  | 1080 | UpRefs[i].LastContainedTy = Ty; | 
|  | 1081 | UR_OUT("  Uplevel Ref Level = " << Level << "\n"); | 
|  | 1082 | if (Level == 0) {                     // Upreference should be resolved! | 
|  | 1083 | if (!TypeToResolve) { | 
|  | 1084 | TypeToResolve = UpRefs[i].UpRefTy; | 
|  | 1085 | } else { | 
|  | 1086 | UR_OUT("  * Resolving upreference for " | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1087 | << UpRefs[i].UpRefTy->getDescription() << "\n"; | 
|  | 1088 | std::string OldName = UpRefs[i].UpRefTy->getDescription()); | 
|  | 1089 | ResolveTypeSign(UpRefs[i].UpRefTy, Sign); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1090 | UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve); | 
|  | 1091 | UR_OUT("  * Type '" << OldName << "' refined upreference to: " | 
|  | 1092 | << (const void*)Ty << ", " << Ty->getDescription() << "\n"); | 
|  | 1093 | } | 
|  | 1094 | UpRefs.erase(UpRefs.begin()+i);     // Remove from upreference list... | 
|  | 1095 | --i;                                // Do not skip the next element... | 
|  | 1096 | } | 
|  | 1097 | } | 
|  | 1098 | } | 
|  | 1099 |  | 
|  | 1100 | if (TypeToResolve) { | 
|  | 1101 | UR_OUT("  * Resolving upreference for " | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1102 | << UpRefs[i].UpRefTy->getDescription() << "\n"; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1103 | std::string OldName = TypeToResolve->getDescription()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1104 | ResolveTypeSign(TypeToResolve, Sign); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1105 | TypeToResolve->refineAbstractTypeTo(Ty); | 
|  | 1106 | } | 
|  | 1107 |  | 
|  | 1108 | return Ty; | 
|  | 1109 | } | 
|  | 1110 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1111 | bool Signedness::operator<(const Signedness &that) const { | 
|  | 1112 | if (isNamed()) { | 
|  | 1113 | if (that.isNamed()) | 
|  | 1114 | return *(this->name) < *(that.name); | 
|  | 1115 | else | 
|  | 1116 | return CurModule.NamedTypeSigns[*name] < that; | 
|  | 1117 | } else if (that.isNamed()) { | 
|  | 1118 | return *this < CurModule.NamedTypeSigns[*that.name]; | 
|  | 1119 | } | 
|  | 1120 |  | 
|  | 1121 | if (isComposite() && that.isComposite()) { | 
|  | 1122 | if (sv->size() == that.sv->size()) { | 
|  | 1123 | SignVector::const_iterator thisI = sv->begin(), thisE = sv->end(); | 
|  | 1124 | SignVector::const_iterator thatI = that.sv->begin(), | 
|  | 1125 | thatE = that.sv->end(); | 
|  | 1126 | for (; thisI != thisE; ++thisI, ++thatI) { | 
|  | 1127 | if (*thisI < *thatI) | 
|  | 1128 | return true; | 
|  | 1129 | else if (!(*thisI == *thatI)) | 
|  | 1130 | return false; | 
|  | 1131 | } | 
|  | 1132 | return false; | 
|  | 1133 | } | 
|  | 1134 | return sv->size() < that.sv->size(); | 
|  | 1135 | } | 
|  | 1136 | return kind < that.kind; | 
|  | 1137 | } | 
|  | 1138 |  | 
|  | 1139 | bool Signedness::operator==(const Signedness &that) const { | 
|  | 1140 | if (isNamed()) | 
|  | 1141 | if (that.isNamed()) | 
|  | 1142 | return *(this->name) == *(that.name); | 
|  | 1143 | else | 
|  | 1144 | return CurModule.NamedTypeSigns[*(this->name)] == that; | 
|  | 1145 | else if (that.isNamed()) | 
|  | 1146 | return *this == CurModule.NamedTypeSigns[*(that.name)]; | 
|  | 1147 | if (isComposite() && that.isComposite()) { | 
|  | 1148 | if (sv->size() == that.sv->size()) { | 
|  | 1149 | SignVector::const_iterator thisI = sv->begin(), thisE = sv->end(); | 
|  | 1150 | SignVector::const_iterator thatI = that.sv->begin(), | 
|  | 1151 | thatE = that.sv->end(); | 
|  | 1152 | for (; thisI != thisE; ++thisI, ++thatI) { | 
|  | 1153 | if (!(*thisI == *thatI)) | 
|  | 1154 | return false; | 
|  | 1155 | } | 
|  | 1156 | return true; | 
|  | 1157 | } | 
|  | 1158 | return false; | 
|  | 1159 | } | 
|  | 1160 | return kind == that.kind; | 
|  | 1161 | } | 
|  | 1162 |  | 
|  | 1163 | void Signedness::copy(const Signedness &that) { | 
|  | 1164 | if (that.isNamed()) { | 
|  | 1165 | kind = Named; | 
|  | 1166 | name = new std::string(*that.name); | 
|  | 1167 | } else if (that.isComposite()) { | 
|  | 1168 | kind = Composite; | 
|  | 1169 | sv = new SignVector(); | 
|  | 1170 | *sv = *that.sv; | 
|  | 1171 | } else { | 
|  | 1172 | kind = that.kind; | 
|  | 1173 | sv = 0; | 
|  | 1174 | } | 
|  | 1175 | } | 
|  | 1176 |  | 
|  | 1177 | void Signedness::destroy() { | 
|  | 1178 | if (isNamed()) { | 
|  | 1179 | delete name; | 
|  | 1180 | } else if (isComposite()) { | 
|  | 1181 | delete sv; | 
|  | 1182 | } | 
|  | 1183 | } | 
|  | 1184 |  | 
|  | 1185 | void Signedness::dump() const { | 
|  | 1186 | if (isComposite()) { | 
|  | 1187 | if (sv->size() == 1) { | 
|  | 1188 | (*sv)[0].dump(); | 
|  | 1189 | std::cerr << "*"; | 
|  | 1190 | } else { | 
|  | 1191 | std::cerr << "{ " ; | 
|  | 1192 | for (unsigned i = 0; i < sv->size(); ++i) { | 
|  | 1193 | if (i != 0) | 
|  | 1194 | std::cerr << ", "; | 
|  | 1195 | (*sv)[i].dump(); | 
|  | 1196 | } | 
|  | 1197 | std::cerr << "} " ; | 
|  | 1198 | } | 
|  | 1199 | } else if (isNamed()) { | 
|  | 1200 | std::cerr << *name; | 
|  | 1201 | } else if (isSigned()) { | 
|  | 1202 | std::cerr << "S"; | 
|  | 1203 | } else if (isUnsigned()) { | 
|  | 1204 | std::cerr << "U"; | 
|  | 1205 | } else | 
|  | 1206 | std::cerr << "."; | 
|  | 1207 | } | 
|  | 1208 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1209 | static inline Instruction::TermOps | 
|  | 1210 | getTermOp(TermOps op) { | 
|  | 1211 | switch (op) { | 
|  | 1212 | default           : assert(0 && "Invalid OldTermOp"); | 
|  | 1213 | case RetOp        : return Instruction::Ret; | 
|  | 1214 | case BrOp         : return Instruction::Br; | 
|  | 1215 | case SwitchOp     : return Instruction::Switch; | 
|  | 1216 | case InvokeOp     : return Instruction::Invoke; | 
|  | 1217 | case UnwindOp     : return Instruction::Unwind; | 
|  | 1218 | case UnreachableOp: return Instruction::Unreachable; | 
|  | 1219 | } | 
|  | 1220 | } | 
|  | 1221 |  | 
|  | 1222 | static inline Instruction::BinaryOps | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1223 | getBinaryOp(BinaryOps op, const Type *Ty, const Signedness& Sign) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1224 | switch (op) { | 
|  | 1225 | default     : assert(0 && "Invalid OldBinaryOps"); | 
|  | 1226 | case SetEQ  : | 
|  | 1227 | case SetNE  : | 
|  | 1228 | case SetLE  : | 
|  | 1229 | case SetGE  : | 
|  | 1230 | case SetLT  : | 
|  | 1231 | case SetGT  : assert(0 && "Should use getCompareOp"); | 
|  | 1232 | case AddOp  : return Instruction::Add; | 
|  | 1233 | case SubOp  : return Instruction::Sub; | 
|  | 1234 | case MulOp  : return Instruction::Mul; | 
|  | 1235 | case DivOp  : { | 
|  | 1236 | // This is an obsolete instruction so we must upgrade it based on the | 
|  | 1237 | // types of its operands. | 
|  | 1238 | bool isFP = Ty->isFloatingPoint(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 1239 | if (const VectorType* PTy = dyn_cast<VectorType>(Ty)) | 
| Chris Lattner | 4227bdb | 2007-02-19 07:34:02 +0000 | [diff] [blame] | 1240 | // If its a vector type we want to use the element type | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1241 | isFP = PTy->getElementType()->isFloatingPoint(); | 
|  | 1242 | if (isFP) | 
|  | 1243 | return Instruction::FDiv; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1244 | else if (Sign.isSigned()) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1245 | return Instruction::SDiv; | 
|  | 1246 | return Instruction::UDiv; | 
|  | 1247 | } | 
|  | 1248 | case UDivOp : return Instruction::UDiv; | 
|  | 1249 | case SDivOp : return Instruction::SDiv; | 
|  | 1250 | case FDivOp : return Instruction::FDiv; | 
|  | 1251 | case RemOp  : { | 
|  | 1252 | // This is an obsolete instruction so we must upgrade it based on the | 
|  | 1253 | // types of its operands. | 
|  | 1254 | bool isFP = Ty->isFloatingPoint(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 1255 | if (const VectorType* PTy = dyn_cast<VectorType>(Ty)) | 
| Chris Lattner | 4227bdb | 2007-02-19 07:34:02 +0000 | [diff] [blame] | 1256 | // If its a vector type we want to use the element type | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1257 | isFP = PTy->getElementType()->isFloatingPoint(); | 
|  | 1258 | // Select correct opcode | 
|  | 1259 | if (isFP) | 
|  | 1260 | return Instruction::FRem; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1261 | else if (Sign.isSigned()) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1262 | return Instruction::SRem; | 
|  | 1263 | return Instruction::URem; | 
|  | 1264 | } | 
|  | 1265 | case URemOp : return Instruction::URem; | 
|  | 1266 | case SRemOp : return Instruction::SRem; | 
|  | 1267 | case FRemOp : return Instruction::FRem; | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1268 | case LShrOp : return Instruction::LShr; | 
|  | 1269 | case AShrOp : return Instruction::AShr; | 
|  | 1270 | case ShlOp  : return Instruction::Shl; | 
|  | 1271 | case ShrOp  : | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1272 | if (Sign.isSigned()) | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1273 | return Instruction::AShr; | 
|  | 1274 | return Instruction::LShr; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1275 | case AndOp  : return Instruction::And; | 
|  | 1276 | case OrOp   : return Instruction::Or; | 
|  | 1277 | case XorOp  : return Instruction::Xor; | 
|  | 1278 | } | 
|  | 1279 | } | 
|  | 1280 |  | 
|  | 1281 | static inline Instruction::OtherOps | 
|  | 1282 | getCompareOp(BinaryOps op, unsigned short &predicate, const Type* &Ty, | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1283 | const Signedness &Sign) { | 
|  | 1284 | bool isSigned = Sign.isSigned(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1285 | bool isFP = Ty->isFloatingPoint(); | 
|  | 1286 | switch (op) { | 
|  | 1287 | default     : assert(0 && "Invalid OldSetCC"); | 
|  | 1288 | case SetEQ  : | 
|  | 1289 | if (isFP) { | 
|  | 1290 | predicate = FCmpInst::FCMP_OEQ; | 
|  | 1291 | return Instruction::FCmp; | 
|  | 1292 | } else { | 
|  | 1293 | predicate = ICmpInst::ICMP_EQ; | 
|  | 1294 | return Instruction::ICmp; | 
|  | 1295 | } | 
|  | 1296 | case SetNE  : | 
|  | 1297 | if (isFP) { | 
|  | 1298 | predicate = FCmpInst::FCMP_UNE; | 
|  | 1299 | return Instruction::FCmp; | 
|  | 1300 | } else { | 
|  | 1301 | predicate = ICmpInst::ICMP_NE; | 
|  | 1302 | return Instruction::ICmp; | 
|  | 1303 | } | 
|  | 1304 | case SetLE  : | 
|  | 1305 | if (isFP) { | 
|  | 1306 | predicate = FCmpInst::FCMP_OLE; | 
|  | 1307 | return Instruction::FCmp; | 
|  | 1308 | } else { | 
|  | 1309 | if (isSigned) | 
|  | 1310 | predicate = ICmpInst::ICMP_SLE; | 
|  | 1311 | else | 
|  | 1312 | predicate = ICmpInst::ICMP_ULE; | 
|  | 1313 | return Instruction::ICmp; | 
|  | 1314 | } | 
|  | 1315 | case SetGE  : | 
|  | 1316 | if (isFP) { | 
|  | 1317 | predicate = FCmpInst::FCMP_OGE; | 
|  | 1318 | return Instruction::FCmp; | 
|  | 1319 | } else { | 
|  | 1320 | if (isSigned) | 
|  | 1321 | predicate = ICmpInst::ICMP_SGE; | 
|  | 1322 | else | 
|  | 1323 | predicate = ICmpInst::ICMP_UGE; | 
|  | 1324 | return Instruction::ICmp; | 
|  | 1325 | } | 
|  | 1326 | case SetLT  : | 
|  | 1327 | if (isFP) { | 
|  | 1328 | predicate = FCmpInst::FCMP_OLT; | 
|  | 1329 | return Instruction::FCmp; | 
|  | 1330 | } else { | 
|  | 1331 | if (isSigned) | 
|  | 1332 | predicate = ICmpInst::ICMP_SLT; | 
|  | 1333 | else | 
|  | 1334 | predicate = ICmpInst::ICMP_ULT; | 
|  | 1335 | return Instruction::ICmp; | 
|  | 1336 | } | 
|  | 1337 | case SetGT  : | 
|  | 1338 | if (isFP) { | 
|  | 1339 | predicate = FCmpInst::FCMP_OGT; | 
|  | 1340 | return Instruction::FCmp; | 
|  | 1341 | } else { | 
|  | 1342 | if (isSigned) | 
|  | 1343 | predicate = ICmpInst::ICMP_SGT; | 
|  | 1344 | else | 
|  | 1345 | predicate = ICmpInst::ICMP_UGT; | 
|  | 1346 | return Instruction::ICmp; | 
|  | 1347 | } | 
|  | 1348 | } | 
|  | 1349 | } | 
|  | 1350 |  | 
|  | 1351 | static inline Instruction::MemoryOps getMemoryOp(MemoryOps op) { | 
|  | 1352 | switch (op) { | 
|  | 1353 | default              : assert(0 && "Invalid OldMemoryOps"); | 
|  | 1354 | case MallocOp        : return Instruction::Malloc; | 
|  | 1355 | case FreeOp          : return Instruction::Free; | 
|  | 1356 | case AllocaOp        : return Instruction::Alloca; | 
|  | 1357 | case LoadOp          : return Instruction::Load; | 
|  | 1358 | case StoreOp         : return Instruction::Store; | 
|  | 1359 | case GetElementPtrOp : return Instruction::GetElementPtr; | 
|  | 1360 | } | 
|  | 1361 | } | 
|  | 1362 |  | 
|  | 1363 | static inline Instruction::OtherOps | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1364 | getOtherOp(OtherOps op, const Signedness &Sign) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1365 | switch (op) { | 
|  | 1366 | default               : assert(0 && "Invalid OldOtherOps"); | 
|  | 1367 | case PHIOp            : return Instruction::PHI; | 
|  | 1368 | case CallOp           : return Instruction::Call; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1369 | case SelectOp         : return Instruction::Select; | 
|  | 1370 | case UserOp1          : return Instruction::UserOp1; | 
|  | 1371 | case UserOp2          : return Instruction::UserOp2; | 
|  | 1372 | case VAArg            : return Instruction::VAArg; | 
|  | 1373 | case ExtractElementOp : return Instruction::ExtractElement; | 
|  | 1374 | case InsertElementOp  : return Instruction::InsertElement; | 
|  | 1375 | case ShuffleVectorOp  : return Instruction::ShuffleVector; | 
|  | 1376 | case ICmpOp           : return Instruction::ICmp; | 
|  | 1377 | case FCmpOp           : return Instruction::FCmp; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1378 | }; | 
|  | 1379 | } | 
|  | 1380 |  | 
|  | 1381 | static inline Value* | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1382 | getCast(CastOps op, Value *Src, const Signedness &SrcSign, const Type *DstTy, | 
|  | 1383 | const Signedness &DstSign, bool ForceInstruction = false) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1384 | Instruction::CastOps Opcode; | 
|  | 1385 | const Type* SrcTy = Src->getType(); | 
|  | 1386 | if (op == CastOp) { | 
|  | 1387 | if (SrcTy->isFloatingPoint() && isa<PointerType>(DstTy)) { | 
|  | 1388 | // fp -> ptr cast is no longer supported but we must upgrade this | 
|  | 1389 | // by doing a double cast: fp -> int -> ptr | 
|  | 1390 | SrcTy = Type::Int64Ty; | 
|  | 1391 | Opcode = Instruction::IntToPtr; | 
|  | 1392 | if (isa<Constant>(Src)) { | 
|  | 1393 | Src = ConstantExpr::getCast(Instruction::FPToUI, | 
|  | 1394 | cast<Constant>(Src), SrcTy); | 
|  | 1395 | } else { | 
|  | 1396 | std::string NewName(makeNameUnique(Src->getName())); | 
|  | 1397 | Src = new FPToUIInst(Src, SrcTy, NewName, CurBB); | 
|  | 1398 | } | 
|  | 1399 | } else if (isa<IntegerType>(DstTy) && | 
|  | 1400 | cast<IntegerType>(DstTy)->getBitWidth() == 1) { | 
|  | 1401 | // cast type %x to bool was previously defined as setne type %x, null | 
|  | 1402 | // The cast semantic is now to truncate, not compare so we must retain | 
|  | 1403 | // the original intent by replacing the cast with a setne | 
|  | 1404 | Constant* Null = Constant::getNullValue(SrcTy); | 
|  | 1405 | Instruction::OtherOps Opcode = Instruction::ICmp; | 
|  | 1406 | unsigned short predicate = ICmpInst::ICMP_NE; | 
|  | 1407 | if (SrcTy->isFloatingPoint()) { | 
|  | 1408 | Opcode = Instruction::FCmp; | 
|  | 1409 | predicate = FCmpInst::FCMP_ONE; | 
|  | 1410 | } else if (!SrcTy->isInteger() && !isa<PointerType>(SrcTy)) { | 
|  | 1411 | error("Invalid cast to bool"); | 
|  | 1412 | } | 
|  | 1413 | if (isa<Constant>(Src) && !ForceInstruction) | 
|  | 1414 | return ConstantExpr::getCompare(predicate, cast<Constant>(Src), Null); | 
|  | 1415 | else | 
|  | 1416 | return CmpInst::create(Opcode, predicate, Src, Null); | 
|  | 1417 | } | 
|  | 1418 | // Determine the opcode to use by calling CastInst::getCastOpcode | 
|  | 1419 | Opcode = | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1420 | CastInst::getCastOpcode(Src, SrcSign.isSigned(), DstTy, | 
|  | 1421 | DstSign.isSigned()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1422 |  | 
|  | 1423 | } else switch (op) { | 
|  | 1424 | default: assert(0 && "Invalid cast token"); | 
|  | 1425 | case TruncOp:    Opcode = Instruction::Trunc; break; | 
|  | 1426 | case ZExtOp:     Opcode = Instruction::ZExt; break; | 
|  | 1427 | case SExtOp:     Opcode = Instruction::SExt; break; | 
|  | 1428 | case FPTruncOp:  Opcode = Instruction::FPTrunc; break; | 
|  | 1429 | case FPExtOp:    Opcode = Instruction::FPExt; break; | 
|  | 1430 | case FPToUIOp:   Opcode = Instruction::FPToUI; break; | 
|  | 1431 | case FPToSIOp:   Opcode = Instruction::FPToSI; break; | 
|  | 1432 | case UIToFPOp:   Opcode = Instruction::UIToFP; break; | 
|  | 1433 | case SIToFPOp:   Opcode = Instruction::SIToFP; break; | 
|  | 1434 | case PtrToIntOp: Opcode = Instruction::PtrToInt; break; | 
|  | 1435 | case IntToPtrOp: Opcode = Instruction::IntToPtr; break; | 
|  | 1436 | case BitCastOp:  Opcode = Instruction::BitCast; break; | 
|  | 1437 | } | 
|  | 1438 |  | 
|  | 1439 | if (isa<Constant>(Src) && !ForceInstruction) | 
|  | 1440 | return ConstantExpr::getCast(Opcode, cast<Constant>(Src), DstTy); | 
|  | 1441 | return CastInst::create(Opcode, Src, DstTy); | 
|  | 1442 | } | 
|  | 1443 |  | 
|  | 1444 | static Instruction * | 
|  | 1445 | upgradeIntrinsicCall(const Type* RetTy, const ValID &ID, | 
|  | 1446 | std::vector<Value*>& Args) { | 
|  | 1447 |  | 
|  | 1448 | std::string Name = ID.Type == ValID::NameVal ? ID.Name : ""; | 
|  | 1449 | if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") { | 
|  | 1450 | if (Args.size() != 2) | 
|  | 1451 | error("Invalid prototype for " + Name + " prototype"); | 
|  | 1452 | return new FCmpInst(FCmpInst::FCMP_UNO, Args[0], Args[1]); | 
|  | 1453 | } else { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1454 | const Type* PtrTy = PointerType::get(Type::Int8Ty); | 
|  | 1455 | std::vector<const Type*> Params; | 
|  | 1456 | if (Name == "llvm.va_start" || Name == "llvm.va_end") { | 
|  | 1457 | if (Args.size() != 1) | 
|  | 1458 | error("Invalid prototype for " + Name + " prototype"); | 
|  | 1459 | Params.push_back(PtrTy); | 
|  | 1460 | const FunctionType *FTy = FunctionType::get(Type::VoidTy, Params, false); | 
|  | 1461 | const PointerType *PFTy = PointerType::get(FTy); | 
|  | 1462 | Value* Func = getVal(PFTy, ID); | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1463 | Args[0] = new BitCastInst(Args[0], PtrTy, makeNameUnique("va"), CurBB); | 
| Chris Lattner | cf3d061 | 2007-02-13 06:04:17 +0000 | [diff] [blame] | 1464 | return new CallInst(Func, &Args[0], Args.size()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1465 | } else if (Name == "llvm.va_copy") { | 
|  | 1466 | if (Args.size() != 2) | 
|  | 1467 | error("Invalid prototype for " + Name + " prototype"); | 
|  | 1468 | Params.push_back(PtrTy); | 
|  | 1469 | Params.push_back(PtrTy); | 
|  | 1470 | const FunctionType *FTy = FunctionType::get(Type::VoidTy, Params, false); | 
|  | 1471 | const PointerType *PFTy = PointerType::get(FTy); | 
|  | 1472 | Value* Func = getVal(PFTy, ID); | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1473 | std::string InstName0(makeNameUnique("va0")); | 
|  | 1474 | std::string InstName1(makeNameUnique("va1")); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1475 | Args[0] = new BitCastInst(Args[0], PtrTy, InstName0, CurBB); | 
|  | 1476 | Args[1] = new BitCastInst(Args[1], PtrTy, InstName1, CurBB); | 
| Chris Lattner | cf3d061 | 2007-02-13 06:04:17 +0000 | [diff] [blame] | 1477 | return new CallInst(Func, &Args[0], Args.size()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1478 | } | 
|  | 1479 | } | 
|  | 1480 | return 0; | 
|  | 1481 | } | 
|  | 1482 |  | 
|  | 1483 | const Type* upgradeGEPIndices(const Type* PTy, | 
|  | 1484 | std::vector<ValueInfo> *Indices, | 
|  | 1485 | std::vector<Value*>    &VIndices, | 
|  | 1486 | std::vector<Constant*> *CIndices = 0) { | 
|  | 1487 | // Traverse the indices with a gep_type_iterator so we can build the list | 
|  | 1488 | // of constant and value indices for use later. Also perform upgrades | 
|  | 1489 | VIndices.clear(); | 
|  | 1490 | if (CIndices) CIndices->clear(); | 
|  | 1491 | for (unsigned i = 0, e = Indices->size(); i != e; ++i) | 
|  | 1492 | VIndices.push_back((*Indices)[i].V); | 
|  | 1493 | generic_gep_type_iterator<std::vector<Value*>::iterator> | 
|  | 1494 | GTI = gep_type_begin(PTy, VIndices.begin(),  VIndices.end()), | 
|  | 1495 | GTE = gep_type_end(PTy,  VIndices.begin(),  VIndices.end()); | 
|  | 1496 | for (unsigned i = 0, e = Indices->size(); i != e && GTI != GTE; ++i, ++GTI) { | 
|  | 1497 | Value *Index = VIndices[i]; | 
|  | 1498 | if (CIndices && !isa<Constant>(Index)) | 
|  | 1499 | error("Indices to constant getelementptr must be constants"); | 
|  | 1500 | // LLVM 1.2 and earlier used ubyte struct indices.  Convert any ubyte | 
|  | 1501 | // struct indices to i32 struct indices with ZExt for compatibility. | 
|  | 1502 | else if (isa<StructType>(*GTI)) {        // Only change struct indices | 
|  | 1503 | if (ConstantInt *CUI = dyn_cast<ConstantInt>(Index)) | 
|  | 1504 | if (CUI->getType()->getBitWidth() == 8) | 
|  | 1505 | Index = | 
|  | 1506 | ConstantExpr::getCast(Instruction::ZExt, CUI, Type::Int32Ty); | 
|  | 1507 | } else { | 
|  | 1508 | // Make sure that unsigned SequentialType indices are zext'd to | 
|  | 1509 | // 64-bits if they were smaller than that because LLVM 2.0 will sext | 
|  | 1510 | // all indices for SequentialType elements. We must retain the same | 
|  | 1511 | // semantic (zext) for unsigned types. | 
|  | 1512 | if (const IntegerType *Ity = dyn_cast<IntegerType>(Index->getType())) | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1513 | if (Ity->getBitWidth() < 64 && (*Indices)[i].S.isUnsigned()) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1514 | if (CIndices) | 
|  | 1515 | Index = ConstantExpr::getCast(Instruction::ZExt, | 
|  | 1516 | cast<Constant>(Index), Type::Int64Ty); | 
|  | 1517 | else | 
|  | 1518 | Index = CastInst::create(Instruction::ZExt, Index, Type::Int64Ty, | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1519 | makeNameUnique("gep"), CurBB); | 
| Reid Spencer | 38f682b | 2007-01-26 20:31:18 +0000 | [diff] [blame] | 1520 | VIndices[i] = Index; | 
|  | 1521 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1522 | } | 
|  | 1523 | // Add to the CIndices list, if requested. | 
|  | 1524 | if (CIndices) | 
|  | 1525 | CIndices->push_back(cast<Constant>(Index)); | 
|  | 1526 | } | 
|  | 1527 |  | 
|  | 1528 | const Type *IdxTy = | 
| Chris Lattner | 1bc3fa6 | 2007-02-12 22:58:38 +0000 | [diff] [blame] | 1529 | GetElementPtrInst::getIndexedType(PTy, &VIndices[0], VIndices.size(), true); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1530 | if (!IdxTy) | 
|  | 1531 | error("Index list invalid for constant getelementptr"); | 
|  | 1532 | return IdxTy; | 
|  | 1533 | } | 
|  | 1534 |  | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 1535 | unsigned upgradeCallingConv(unsigned CC) { | 
|  | 1536 | switch (CC) { | 
|  | 1537 | case OldCallingConv::C           : return CallingConv::C; | 
|  | 1538 | case OldCallingConv::CSRet       : return CallingConv::C; | 
|  | 1539 | case OldCallingConv::Fast        : return CallingConv::Fast; | 
|  | 1540 | case OldCallingConv::Cold        : return CallingConv::Cold; | 
|  | 1541 | case OldCallingConv::X86_StdCall : return CallingConv::X86_StdCall; | 
|  | 1542 | case OldCallingConv::X86_FastCall: return CallingConv::X86_FastCall; | 
|  | 1543 | default: | 
|  | 1544 | return CC; | 
|  | 1545 | } | 
|  | 1546 | } | 
|  | 1547 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1548 | Module* UpgradeAssembly(const std::string &infile, std::istream& in, | 
|  | 1549 | bool debug, bool addAttrs) | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1550 | { | 
|  | 1551 | Upgradelineno = 1; | 
|  | 1552 | CurFilename = infile; | 
| Reid Spencer | 96839be | 2006-11-30 16:50:26 +0000 | [diff] [blame] | 1553 | LexInput = ∈ | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1554 | yydebug = debug; | 
| Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 1555 | AddAttributes = addAttrs; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1556 | ObsoleteVarArgs = false; | 
|  | 1557 | NewVarArgs = false; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1558 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1559 | CurModule.CurrentModule = new Module(CurFilename); | 
|  | 1560 |  | 
|  | 1561 | // Check to make sure the parser succeeded | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1562 | if (yyparse()) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1563 | if (ParserResult) | 
|  | 1564 | delete ParserResult; | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 1565 | std::cerr << "llvm-upgrade: parse failed.\n"; | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 1566 | return 0; | 
|  | 1567 | } | 
|  | 1568 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1569 | // Check to make sure that parsing produced a result | 
|  | 1570 | if (!ParserResult) { | 
|  | 1571 | std::cerr << "llvm-upgrade: no parse result.\n"; | 
|  | 1572 | return 0; | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 1573 | } | 
|  | 1574 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1575 | // Reset ParserResult variable while saving its value for the result. | 
|  | 1576 | Module *Result = ParserResult; | 
|  | 1577 | ParserResult = 0; | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 1578 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1579 | //Not all functions use vaarg, so make a second check for ObsoleteVarArgs | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 1580 | { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1581 | Function* F; | 
| Reid Spencer | 688b049 | 2007-02-05 21:19:13 +0000 | [diff] [blame] | 1582 | if ((F = Result->getFunction("llvm.va_start")) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1583 | && F->getFunctionType()->getNumParams() == 0) | 
|  | 1584 | ObsoleteVarArgs = true; | 
| Reid Spencer | 688b049 | 2007-02-05 21:19:13 +0000 | [diff] [blame] | 1585 | if((F = Result->getFunction("llvm.va_copy")) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1586 | && F->getFunctionType()->getNumParams() == 1) | 
|  | 1587 | ObsoleteVarArgs = true; | 
| Reid Spencer | 280d801 | 2006-12-01 23:40:53 +0000 | [diff] [blame] | 1588 | } | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1589 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1590 | if (ObsoleteVarArgs && NewVarArgs) { | 
|  | 1591 | error("This file is corrupt: it uses both new and old style varargs"); | 
|  | 1592 | return 0; | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1593 | } | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1594 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1595 | if(ObsoleteVarArgs) { | 
| Reid Spencer | 688b049 | 2007-02-05 21:19:13 +0000 | [diff] [blame] | 1596 | if(Function* F = Result->getFunction("llvm.va_start")) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1597 | if (F->arg_size() != 0) { | 
|  | 1598 | error("Obsolete va_start takes 0 argument"); | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1599 | return 0; | 
|  | 1600 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1601 |  | 
|  | 1602 | //foo = va_start() | 
|  | 1603 | // -> | 
|  | 1604 | //bar = alloca typeof(foo) | 
|  | 1605 | //va_start(bar) | 
|  | 1606 | //foo = load bar | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1607 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1608 | const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); | 
|  | 1609 | const Type* ArgTy = F->getFunctionType()->getReturnType(); | 
|  | 1610 | const Type* ArgTyPtr = PointerType::get(ArgTy); | 
|  | 1611 | Function* NF = cast<Function>(Result->getOrInsertFunction( | 
|  | 1612 | "llvm.va_start", RetTy, ArgTyPtr, (Type *)0)); | 
|  | 1613 |  | 
|  | 1614 | while (!F->use_empty()) { | 
|  | 1615 | CallInst* CI = cast<CallInst>(F->use_back()); | 
|  | 1616 | AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI); | 
|  | 1617 | new CallInst(NF, bar, "", CI); | 
|  | 1618 | Value* foo = new LoadInst(bar, "vastart.fix.2", CI); | 
|  | 1619 | CI->replaceAllUsesWith(foo); | 
|  | 1620 | CI->getParent()->getInstList().erase(CI); | 
| Reid Spencer | f8383de | 2007-01-06 06:04:32 +0000 | [diff] [blame] | 1621 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1622 | Result->getFunctionList().erase(F); | 
| Reid Spencer | f8383de | 2007-01-06 06:04:32 +0000 | [diff] [blame] | 1623 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1624 |  | 
| Reid Spencer | 688b049 | 2007-02-05 21:19:13 +0000 | [diff] [blame] | 1625 | if(Function* F = Result->getFunction("llvm.va_end")) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1626 | if(F->arg_size() != 1) { | 
|  | 1627 | error("Obsolete va_end takes 1 argument"); | 
|  | 1628 | return 0; | 
| Reid Spencer | f8383de | 2007-01-06 06:04:32 +0000 | [diff] [blame] | 1629 | } | 
| Reid Spencer | f8383de | 2007-01-06 06:04:32 +0000 | [diff] [blame] | 1630 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1631 | //vaend foo | 
|  | 1632 | // -> | 
|  | 1633 | //bar = alloca 1 of typeof(foo) | 
|  | 1634 | //vaend bar | 
|  | 1635 | const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); | 
|  | 1636 | const Type* ArgTy = F->getFunctionType()->getParamType(0); | 
|  | 1637 | const Type* ArgTyPtr = PointerType::get(ArgTy); | 
|  | 1638 | Function* NF = cast<Function>(Result->getOrInsertFunction( | 
|  | 1639 | "llvm.va_end", RetTy, ArgTyPtr, (Type *)0)); | 
| Reid Spencer | f8383de | 2007-01-06 06:04:32 +0000 | [diff] [blame] | 1640 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1641 | while (!F->use_empty()) { | 
|  | 1642 | CallInst* CI = cast<CallInst>(F->use_back()); | 
|  | 1643 | AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI); | 
|  | 1644 | new StoreInst(CI->getOperand(1), bar, CI); | 
|  | 1645 | new CallInst(NF, bar, "", CI); | 
|  | 1646 | CI->getParent()->getInstList().erase(CI); | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1647 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1648 | Result->getFunctionList().erase(F); | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1649 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1650 |  | 
| Reid Spencer | 688b049 | 2007-02-05 21:19:13 +0000 | [diff] [blame] | 1651 | if(Function* F = Result->getFunction("llvm.va_copy")) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1652 | if(F->arg_size() != 1) { | 
|  | 1653 | error("Obsolete va_copy takes 1 argument"); | 
|  | 1654 | return 0; | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1655 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1656 | //foo = vacopy(bar) | 
|  | 1657 | // -> | 
|  | 1658 | //a = alloca 1 of typeof(foo) | 
|  | 1659 | //b = alloca 1 of typeof(foo) | 
|  | 1660 | //store bar -> b | 
|  | 1661 | //vacopy(a, b) | 
|  | 1662 | //foo = load a | 
|  | 1663 |  | 
|  | 1664 | const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID); | 
|  | 1665 | const Type* ArgTy = F->getFunctionType()->getReturnType(); | 
|  | 1666 | const Type* ArgTyPtr = PointerType::get(ArgTy); | 
|  | 1667 | Function* NF = cast<Function>(Result->getOrInsertFunction( | 
|  | 1668 | "llvm.va_copy", RetTy, ArgTyPtr, ArgTyPtr, (Type *)0)); | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1669 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1670 | while (!F->use_empty()) { | 
|  | 1671 | CallInst* CI = cast<CallInst>(F->use_back()); | 
|  | 1672 | AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI); | 
|  | 1673 | AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI); | 
|  | 1674 | new StoreInst(CI->getOperand(1), b, CI); | 
|  | 1675 | new CallInst(NF, a, b, "", CI); | 
|  | 1676 | Value* foo = new LoadInst(a, "vacopy.fix.3", CI); | 
|  | 1677 | CI->replaceAllUsesWith(foo); | 
|  | 1678 | CI->getParent()->getInstList().erase(CI); | 
|  | 1679 | } | 
|  | 1680 | Result->getFunctionList().erase(F); | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1681 | } | 
|  | 1682 | } | 
|  | 1683 |  | 
| Reid Spencer | 52402b0 | 2007-01-02 05:45:11 +0000 | [diff] [blame] | 1684 | return Result; | 
|  | 1685 | } | 
|  | 1686 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1687 | } // end llvm namespace | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 1688 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1689 | using namespace llvm; | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 1690 |  | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1691 | %} | 
|  | 1692 |  | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1693 | %union { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1694 | llvm::Module                           *ModuleVal; | 
|  | 1695 | llvm::Function                         *FunctionVal; | 
|  | 1696 | std::pair<llvm::PATypeInfo, char*>     *ArgVal; | 
|  | 1697 | llvm::BasicBlock                       *BasicBlockVal; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 1698 | llvm::TermInstInfo                     TermInstVal; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1699 | llvm::InstrInfo                        InstVal; | 
|  | 1700 | llvm::ConstInfo                        ConstVal; | 
|  | 1701 | llvm::ValueInfo                        ValueVal; | 
|  | 1702 | llvm::PATypeInfo                       TypeVal; | 
|  | 1703 | llvm::TypeInfo                         PrimType; | 
|  | 1704 | llvm::PHIListInfo                      PHIList; | 
|  | 1705 | std::list<llvm::PATypeInfo>            *TypeList; | 
|  | 1706 | std::vector<llvm::ValueInfo>           *ValueList; | 
|  | 1707 | std::vector<llvm::ConstInfo>           *ConstVector; | 
|  | 1708 |  | 
|  | 1709 |  | 
|  | 1710 | std::vector<std::pair<llvm::PATypeInfo,char*> > *ArgList; | 
|  | 1711 | // Represent the RHS of PHI node | 
|  | 1712 | std::vector<std::pair<llvm::Constant*, llvm::BasicBlock*> > *JumpTable; | 
|  | 1713 |  | 
|  | 1714 | llvm::GlobalValue::LinkageTypes         Linkage; | 
|  | 1715 | int64_t                           SInt64Val; | 
|  | 1716 | uint64_t                          UInt64Val; | 
|  | 1717 | int                               SIntVal; | 
|  | 1718 | unsigned                          UIntVal; | 
|  | 1719 | double                            FPVal; | 
|  | 1720 | bool                              BoolVal; | 
|  | 1721 |  | 
|  | 1722 | char                             *StrVal;   // This memory is strdup'd! | 
|  | 1723 | llvm::ValID                       ValIDVal; // strdup'd memory maybe! | 
|  | 1724 |  | 
|  | 1725 | llvm::BinaryOps                   BinaryOpVal; | 
|  | 1726 | llvm::TermOps                     TermOpVal; | 
|  | 1727 | llvm::MemoryOps                   MemOpVal; | 
|  | 1728 | llvm::OtherOps                    OtherOpVal; | 
|  | 1729 | llvm::CastOps                     CastOpVal; | 
|  | 1730 | llvm::ICmpInst::Predicate         IPred; | 
|  | 1731 | llvm::FCmpInst::Predicate         FPred; | 
|  | 1732 | llvm::Module::Endianness          Endianness; | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1733 | } | 
|  | 1734 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1735 | %type <ModuleVal>     Module FunctionList | 
|  | 1736 | %type <FunctionVal>   Function FunctionProto FunctionHeader BasicBlockList | 
|  | 1737 | %type <BasicBlockVal> BasicBlock InstructionList | 
|  | 1738 | %type <TermInstVal>   BBTerminatorInst | 
|  | 1739 | %type <InstVal>       Inst InstVal MemoryInst | 
|  | 1740 | %type <ConstVal>      ConstVal ConstExpr | 
|  | 1741 | %type <ConstVector>   ConstVector | 
|  | 1742 | %type <ArgList>       ArgList ArgListH | 
|  | 1743 | %type <ArgVal>        ArgVal | 
|  | 1744 | %type <PHIList>       PHIList | 
|  | 1745 | %type <ValueList>     ValueRefList ValueRefListE  // For call param lists | 
|  | 1746 | %type <ValueList>     IndexList                   // For GEP derived indices | 
|  | 1747 | %type <TypeList>      TypeListI ArgTypeListI | 
|  | 1748 | %type <JumpTable>     JumpTable | 
|  | 1749 | %type <BoolVal>       GlobalType                  // GLOBAL or CONSTANT? | 
|  | 1750 | %type <BoolVal>       OptVolatile                 // 'volatile' or not | 
|  | 1751 | %type <BoolVal>       OptTailCall                 // TAIL CALL or plain CALL. | 
|  | 1752 | %type <BoolVal>       OptSideEffect               // 'sideeffect' or not. | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 1753 | %type <Linkage>       OptLinkage FnDeclareLinkage | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1754 | %type <Endianness>    BigOrLittle | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1755 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1756 | // ValueRef - Unresolved reference to a definition or BB | 
|  | 1757 | %type <ValIDVal>      ValueRef ConstValueRef SymbolicValueRef | 
|  | 1758 | %type <ValueVal>      ResolvedVal            // <type> <valref> pair | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 1759 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1760 | // Tokens and types for handling constant integer values | 
|  | 1761 | // | 
|  | 1762 | // ESINT64VAL - A negative number within long long range | 
|  | 1763 | %token <SInt64Val> ESINT64VAL | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1764 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1765 | // EUINT64VAL - A positive number within uns. long long range | 
|  | 1766 | %token <UInt64Val> EUINT64VAL | 
|  | 1767 | %type  <SInt64Val> EINT64VAL | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1768 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1769 | %token  <SIntVal>   SINTVAL   // Signed 32 bit ints... | 
|  | 1770 | %token  <UIntVal>   UINTVAL   // Unsigned 32 bit ints... | 
|  | 1771 | %type   <SIntVal>   INTVAL | 
|  | 1772 | %token  <FPVal>     FPVAL     // Float or Double constant | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1773 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1774 | // Built in types... | 
|  | 1775 | %type  <TypeVal> Types TypesV UpRTypes UpRTypesV | 
|  | 1776 | %type  <PrimType> SIntType UIntType IntType FPType PrimType // Classifications | 
|  | 1777 | %token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG | 
|  | 1778 | %token <PrimType> FLOAT DOUBLE TYPE LABEL | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 1779 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1780 | %token <StrVal> VAR_ID LABELSTR STRINGCONSTANT | 
|  | 1781 | %type  <StrVal> Name OptName OptAssign | 
|  | 1782 | %type  <UIntVal> OptAlign OptCAlign | 
|  | 1783 | %type <StrVal> OptSection SectionString | 
|  | 1784 |  | 
|  | 1785 | %token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK | 
|  | 1786 | %token DECLARE GLOBAL CONSTANT SECTION VOLATILE | 
|  | 1787 | %token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING | 
|  | 1788 | %token DLLIMPORT DLLEXPORT EXTERN_WEAK | 
|  | 1789 | %token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN | 
|  | 1790 | %token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT | 
|  | 1791 | %token CC_TOK CCC_TOK CSRETCC_TOK FASTCC_TOK COLDCC_TOK | 
|  | 1792 | %token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK | 
|  | 1793 | %token DATALAYOUT | 
|  | 1794 | %type <UIntVal> OptCallingConv | 
|  | 1795 |  | 
|  | 1796 | // Basic Block Terminating Operators | 
|  | 1797 | %token <TermOpVal> RET BR SWITCH INVOKE UNREACHABLE | 
|  | 1798 | %token UNWIND EXCEPT | 
|  | 1799 |  | 
|  | 1800 | // Binary Operators | 
|  | 1801 | %type  <BinaryOpVal> ArithmeticOps LogicalOps SetCondOps // Binops Subcatagories | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1802 | %type  <BinaryOpVal> ShiftOps | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1803 | %token <BinaryOpVal> ADD SUB MUL DIV UDIV SDIV FDIV REM UREM SREM FREM | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1804 | %token <BinaryOpVal> AND OR XOR SHL SHR ASHR LSHR | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1805 | %token <BinaryOpVal> SETLE SETGE SETLT SETGT SETEQ SETNE  // Binary Comparators | 
|  | 1806 | %token <OtherOpVal> ICMP FCMP | 
|  | 1807 |  | 
|  | 1808 | // Memory Instructions | 
|  | 1809 | %token <MemOpVal> MALLOC ALLOCA FREE LOAD STORE GETELEMENTPTR | 
|  | 1810 |  | 
|  | 1811 | // Other Operators | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 1812 | %token <OtherOpVal> PHI_TOK SELECT VAARG | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1813 | %token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR | 
|  | 1814 | %token VAARG_old VANEXT_old //OBSOLETE | 
|  | 1815 |  | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 1816 | // Support for ICmp/FCmp Predicates, which is 1.9++ but not 2.0 | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1817 | %type  <IPred> IPredicates | 
|  | 1818 | %type  <FPred> FPredicates | 
|  | 1819 | %token  EQ NE SLT SGT SLE SGE ULT UGT ULE UGE | 
|  | 1820 | %token  OEQ ONE OLT OGT OLE OGE ORD UNO UEQ UNE | 
|  | 1821 |  | 
|  | 1822 | %token <CastOpVal> CAST TRUNC ZEXT SEXT FPTRUNC FPEXT FPTOUI FPTOSI | 
|  | 1823 | %token <CastOpVal> UITOFP SITOFP PTRTOINT INTTOPTR BITCAST | 
|  | 1824 | %type  <CastOpVal> CastOps | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1825 |  | 
|  | 1826 | %start Module | 
|  | 1827 |  | 
|  | 1828 | %% | 
|  | 1829 |  | 
|  | 1830 | // Handle constant integer size restriction and conversion... | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1831 | // | 
|  | 1832 | INTVAL | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 1833 | : SINTVAL | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1834 | | UINTVAL { | 
|  | 1835 | if ($1 > (uint32_t)INT32_MAX)     // Outside of my range! | 
|  | 1836 | error("Value too large for type"); | 
|  | 1837 | $$ = (int32_t)$1; | 
|  | 1838 | } | 
|  | 1839 | ; | 
|  | 1840 |  | 
|  | 1841 | EINT64VAL | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 1842 | : ESINT64VAL       // These have same type and can't cause problems... | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1843 | | EUINT64VAL { | 
|  | 1844 | if ($1 > (uint64_t)INT64_MAX)     // Outside of my range! | 
|  | 1845 | error("Value too large for type"); | 
|  | 1846 | $$ = (int64_t)$1; | 
|  | 1847 | }; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1848 |  | 
|  | 1849 | // Operations that are notably excluded from this list include: | 
|  | 1850 | // RET, BR, & SWITCH because they end basic blocks and are treated specially. | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1851 | // | 
|  | 1852 | ArithmeticOps | 
|  | 1853 | : ADD | SUB | MUL | DIV | UDIV | SDIV | FDIV | REM | UREM | SREM | FREM | 
|  | 1854 | ; | 
|  | 1855 |  | 
|  | 1856 | LogicalOps | 
|  | 1857 | : AND | OR | XOR | 
|  | 1858 | ; | 
|  | 1859 |  | 
|  | 1860 | SetCondOps | 
|  | 1861 | : SETLE | SETGE | SETLT | SETGT | SETEQ | SETNE | 
|  | 1862 | ; | 
|  | 1863 |  | 
|  | 1864 | IPredicates | 
|  | 1865 | : EQ   { $$ = ICmpInst::ICMP_EQ; }  | NE   { $$ = ICmpInst::ICMP_NE; } | 
|  | 1866 | | SLT  { $$ = ICmpInst::ICMP_SLT; } | SGT  { $$ = ICmpInst::ICMP_SGT; } | 
|  | 1867 | | SLE  { $$ = ICmpInst::ICMP_SLE; } | SGE  { $$ = ICmpInst::ICMP_SGE; } | 
|  | 1868 | | ULT  { $$ = ICmpInst::ICMP_ULT; } | UGT  { $$ = ICmpInst::ICMP_UGT; } | 
|  | 1869 | | ULE  { $$ = ICmpInst::ICMP_ULE; } | UGE  { $$ = ICmpInst::ICMP_UGE; } | 
|  | 1870 | ; | 
|  | 1871 |  | 
|  | 1872 | FPredicates | 
|  | 1873 | : OEQ  { $$ = FCmpInst::FCMP_OEQ; } | ONE  { $$ = FCmpInst::FCMP_ONE; } | 
|  | 1874 | | OLT  { $$ = FCmpInst::FCMP_OLT; } | OGT  { $$ = FCmpInst::FCMP_OGT; } | 
|  | 1875 | | OLE  { $$ = FCmpInst::FCMP_OLE; } | OGE  { $$ = FCmpInst::FCMP_OGE; } | 
|  | 1876 | | ORD  { $$ = FCmpInst::FCMP_ORD; } | UNO  { $$ = FCmpInst::FCMP_UNO; } | 
|  | 1877 | | UEQ  { $$ = FCmpInst::FCMP_UEQ; } | UNE  { $$ = FCmpInst::FCMP_UNE; } | 
|  | 1878 | | ULT  { $$ = FCmpInst::FCMP_ULT; } | UGT  { $$ = FCmpInst::FCMP_UGT; } | 
|  | 1879 | | ULE  { $$ = FCmpInst::FCMP_ULE; } | UGE  { $$ = FCmpInst::FCMP_UGE; } | 
|  | 1880 | | TRUETOK { $$ = FCmpInst::FCMP_TRUE; } | 
|  | 1881 | | FALSETOK { $$ = FCmpInst::FCMP_FALSE; } | 
|  | 1882 | ; | 
|  | 1883 | ShiftOps | 
|  | 1884 | : SHL | SHR | ASHR | LSHR | 
|  | 1885 | ; | 
|  | 1886 |  | 
|  | 1887 | CastOps | 
|  | 1888 | : TRUNC | ZEXT | SEXT | FPTRUNC | FPEXT | FPTOUI | FPTOSI | 
|  | 1889 | | UITOFP | SITOFP | PTRTOINT | INTTOPTR | BITCAST | CAST | 
|  | 1890 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1891 |  | 
|  | 1892 | // These are some types that allow classification if we only want a particular | 
|  | 1893 | // thing... for example, only a signed, unsigned, or integral type. | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1894 | SIntType | 
|  | 1895 | :  LONG |  INT |  SHORT | SBYTE | 
|  | 1896 | ; | 
|  | 1897 |  | 
|  | 1898 | UIntType | 
|  | 1899 | : ULONG | UINT | USHORT | UBYTE | 
|  | 1900 | ; | 
|  | 1901 |  | 
|  | 1902 | IntType | 
|  | 1903 | : SIntType | UIntType | 
|  | 1904 | ; | 
|  | 1905 |  | 
|  | 1906 | FPType | 
|  | 1907 | : FLOAT | DOUBLE | 
|  | 1908 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1909 |  | 
|  | 1910 | // OptAssign - Value producing statements have an optional assignment component | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1911 | OptAssign | 
|  | 1912 | : Name '=' { | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1913 | $$ = $1; | 
|  | 1914 | } | 
|  | 1915 | | /*empty*/ { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1916 | $$ = 0; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1917 | }; | 
|  | 1918 |  | 
|  | 1919 | OptLinkage | 
| Reid Spencer | 785a5ae | 2007-02-08 00:21:40 +0000 | [diff] [blame] | 1920 | : INTERNAL    { $$ = GlobalValue::InternalLinkage; } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1921 | | LINKONCE    { $$ = GlobalValue::LinkOnceLinkage; } | 
|  | 1922 | | WEAK        { $$ = GlobalValue::WeakLinkage; } | 
|  | 1923 | | APPENDING   { $$ = GlobalValue::AppendingLinkage; } | 
|  | 1924 | | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } | 
|  | 1925 | | DLLEXPORT   { $$ = GlobalValue::DLLExportLinkage; } | 
| Reid Spencer | 785a5ae | 2007-02-08 00:21:40 +0000 | [diff] [blame] | 1926 | | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1927 | | /*empty*/   { $$ = GlobalValue::ExternalLinkage; } | 
|  | 1928 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1929 |  | 
|  | 1930 | OptCallingConv | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 1931 | : /*empty*/          { $$ = OldCallingConv::C; } | 
|  | 1932 | | CCC_TOK            { $$ = OldCallingConv::C; } | 
|  | 1933 | | CSRETCC_TOK        { $$ = OldCallingConv::CSRet; } | 
|  | 1934 | | FASTCC_TOK         { $$ = OldCallingConv::Fast; } | 
|  | 1935 | | COLDCC_TOK         { $$ = OldCallingConv::Cold; } | 
|  | 1936 | | X86_STDCALLCC_TOK  { $$ = OldCallingConv::X86_StdCall; } | 
|  | 1937 | | X86_FASTCALLCC_TOK { $$ = OldCallingConv::X86_FastCall; } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1938 | | CC_TOK EUINT64VAL  { | 
|  | 1939 | if ((unsigned)$2 != $2) | 
|  | 1940 | error("Calling conv too large"); | 
|  | 1941 | $$ = $2; | 
|  | 1942 | } | 
|  | 1943 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1944 |  | 
|  | 1945 | // OptAlign/OptCAlign - An optional alignment, and an optional alignment with | 
|  | 1946 | // a comma before it. | 
|  | 1947 | OptAlign | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1948 | : /*empty*/        { $$ = 0; } | 
|  | 1949 | | ALIGN EUINT64VAL { | 
|  | 1950 | $$ = $2; | 
|  | 1951 | if ($$ != 0 && !isPowerOf2_32($$)) | 
|  | 1952 | error("Alignment must be a power of two"); | 
|  | 1953 | } | 
|  | 1954 | ; | 
| Reid Spencer | f0cf132 | 2006-12-07 04:23:03 +0000 | [diff] [blame] | 1955 |  | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1956 | OptCAlign | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1957 | : /*empty*/ { $$ = 0; } | 
|  | 1958 | | ',' ALIGN EUINT64VAL { | 
|  | 1959 | $$ = $3; | 
|  | 1960 | if ($$ != 0 && !isPowerOf2_32($$)) | 
|  | 1961 | error("Alignment must be a power of two"); | 
|  | 1962 | } | 
|  | 1963 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1964 |  | 
|  | 1965 | SectionString | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1966 | : SECTION STRINGCONSTANT { | 
|  | 1967 | for (unsigned i = 0, e = strlen($2); i != e; ++i) | 
|  | 1968 | if ($2[i] == '"' || $2[i] == '\\') | 
|  | 1969 | error("Invalid character in section name"); | 
|  | 1970 | $$ = $2; | 
|  | 1971 | } | 
|  | 1972 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1973 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1974 | OptSection | 
|  | 1975 | : /*empty*/ { $$ = 0; } | 
|  | 1976 | | SectionString { $$ = $1; } | 
|  | 1977 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1978 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1979 | // GlobalVarAttributes - Used to pass the attributes string on a global.  CurGV | 
|  | 1980 | // is set to be the global we are processing. | 
|  | 1981 | // | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1982 | GlobalVarAttributes | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1983 | : /* empty */ {} | 
|  | 1984 | | ',' GlobalVarAttribute GlobalVarAttributes {} | 
|  | 1985 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1986 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 1987 | GlobalVarAttribute | 
|  | 1988 | : SectionString { | 
|  | 1989 | CurGV->setSection($1); | 
|  | 1990 | free($1); | 
|  | 1991 | } | 
|  | 1992 | | ALIGN EUINT64VAL { | 
|  | 1993 | if ($2 != 0 && !isPowerOf2_32($2)) | 
|  | 1994 | error("Alignment must be a power of two"); | 
|  | 1995 | CurGV->setAlignment($2); | 
|  | 1996 |  | 
|  | 1997 | } | 
|  | 1998 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 1999 |  | 
|  | 2000 | //===----------------------------------------------------------------------===// | 
|  | 2001 | // Types includes all predefined types... except void, because it can only be | 
|  | 2002 | // used in specific contexts (function returning void for example).  To have | 
|  | 2003 | // access to it, a user must explicitly use TypesV. | 
|  | 2004 | // | 
|  | 2005 |  | 
|  | 2006 | // TypesV includes all of 'Types', but it also includes the void type. | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2007 | TypesV | 
|  | 2008 | : Types | 
|  | 2009 | | VOID { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2010 | $$.PAT = new PATypeHolder($1.T); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2011 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2012 | } | 
|  | 2013 | ; | 
|  | 2014 |  | 
|  | 2015 | UpRTypesV | 
|  | 2016 | : UpRTypes | 
|  | 2017 | | VOID { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2018 | $$.PAT = new PATypeHolder($1.T); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2019 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2020 | } | 
|  | 2021 | ; | 
|  | 2022 |  | 
|  | 2023 | Types | 
|  | 2024 | : UpRTypes { | 
|  | 2025 | if (!UpRefs.empty()) | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2026 | error("Invalid upreference in type: " + (*$1.PAT)->getDescription()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2027 | $$ = $1; | 
|  | 2028 | } | 
|  | 2029 | ; | 
|  | 2030 |  | 
|  | 2031 | PrimType | 
|  | 2032 | : BOOL | SBYTE | UBYTE | SHORT  | USHORT | INT   | UINT | 
|  | 2033 | | LONG | ULONG | FLOAT | DOUBLE | LABEL | 
|  | 2034 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2035 |  | 
|  | 2036 | // Derived types are added later... | 
| Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 2037 | UpRTypes | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2038 | : PrimType { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2039 | $$.PAT = new PATypeHolder($1.T); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2040 | $$.S.copy($1.S); | 
| Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 2041 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2042 | | OPAQUE { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2043 | $$.PAT = new PATypeHolder(OpaqueType::get()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2044 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2045 | } | 
|  | 2046 | | SymbolicValueRef {            // Named types are also simple types... | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2047 | $$.S.copy(getTypeSign($1)); | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 2048 | const Type* tmp = getType($1); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2049 | $$.PAT = new PATypeHolder(tmp); | 
| Reid Spencer | 7872074 | 2006-12-02 20:21:22 +0000 | [diff] [blame] | 2050 | } | 
|  | 2051 | | '\\' EUINT64VAL {                   // Type UpReference | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2052 | if ($2 > (uint64_t)~0U) | 
|  | 2053 | error("Value out of range"); | 
|  | 2054 | OpaqueType *OT = OpaqueType::get();        // Use temporary placeholder | 
|  | 2055 | UpRefs.push_back(UpRefRecord((unsigned)$2, OT));  // Add to vector... | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2056 | $$.PAT = new PATypeHolder(OT); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2057 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2058 | UR_OUT("New Upreference!\n"); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2059 | } | 
|  | 2060 | | UpRTypesV '(' ArgTypeListI ')' {           // Function derived type? | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2061 | $$.S.makeComposite($1.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2062 | std::vector<const Type*> Params; | 
|  | 2063 | for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(), | 
|  | 2064 | E = $3->end(); I != E; ++I) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2065 | Params.push_back(I->PAT->get()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2066 | $$.S.add(I->S); | 
| Reid Spencer | 52402b0 | 2007-01-02 05:45:11 +0000 | [diff] [blame] | 2067 | } | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 2068 | FunctionType::ParamAttrsList ParamAttrs; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2069 | bool isVarArg = Params.size() && Params.back() == Type::VoidTy; | 
|  | 2070 | if (isVarArg) Params.pop_back(); | 
|  | 2071 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2072 | $$.PAT = new PATypeHolder( | 
|  | 2073 | HandleUpRefs(FunctionType::get($1.PAT->get(), Params, isVarArg, | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2074 | ParamAttrs), $$.S)); | 
|  | 2075 | delete $1.PAT;  // Delete the return type handle | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2076 | delete $3;      // Delete the argument list | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2077 | } | 
|  | 2078 | | '[' EUINT64VAL 'x' UpRTypes ']' {          // Sized array type? | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2079 | $$.S.makeComposite($4.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2080 | $$.PAT = new PATypeHolder(HandleUpRefs(ArrayType::get($4.PAT->get(), | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2081 | (unsigned)$2), $$.S)); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2082 | delete $4.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2083 | } | 
| Chris Lattner | 4227bdb | 2007-02-19 07:34:02 +0000 | [diff] [blame] | 2084 | | '<' EUINT64VAL 'x' UpRTypes '>' {          // Vector type? | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2085 | const llvm::Type* ElemTy = $4.PAT->get(); | 
|  | 2086 | if ((unsigned)$2 != $2) | 
|  | 2087 | error("Unsigned result not equal to signed result"); | 
|  | 2088 | if (!(ElemTy->isInteger() || ElemTy->isFloatingPoint())) | 
|  | 2089 | error("Elements of a VectorType must be integer or floating point"); | 
|  | 2090 | if (!isPowerOf2_32($2)) | 
|  | 2091 | error("VectorType length should be a power of 2"); | 
|  | 2092 | $$.S.makeComposite($4.S); | 
|  | 2093 | $$.PAT = new PATypeHolder(HandleUpRefs(VectorType::get(ElemTy, | 
|  | 2094 | (unsigned)$2), $$.S)); | 
|  | 2095 | delete $4.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2096 | } | 
|  | 2097 | | '{' TypeListI '}' {                        // Structure type? | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2098 | std::vector<const Type*> Elements; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2099 | $$.S.makeComposite(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2100 | for (std::list<llvm::PATypeInfo>::iterator I = $2->begin(), | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2101 | E = $2->end(); I != E; ++I) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2102 | Elements.push_back(I->PAT->get()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2103 | $$.S.add(I->S); | 
|  | 2104 | } | 
|  | 2105 | $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements), $$.S)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2106 | delete $2; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2107 | } | 
|  | 2108 | | '{' '}' {                                  // Empty structure type? | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2109 | $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>())); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2110 | $$.S.makeComposite(); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2111 | } | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 2112 | | '<' '{' TypeListI '}' '>' {                // Packed Structure type? | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2113 | $$.S.makeComposite(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2114 | std::vector<const Type*> Elements; | 
|  | 2115 | for (std::list<llvm::PATypeInfo>::iterator I = $3->begin(), | 
|  | 2116 | E = $3->end(); I != E; ++I) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2117 | Elements.push_back(I->PAT->get()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2118 | $$.S.add(I->S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2119 | delete I->PAT; | 
| Reid Spencer | 52402b0 | 2007-01-02 05:45:11 +0000 | [diff] [blame] | 2120 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2121 | $$.PAT = new PATypeHolder(HandleUpRefs(StructType::get(Elements, true), | 
|  | 2122 | $$.S)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2123 | delete $3; | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 2124 | } | 
|  | 2125 | | '<' '{' '}' '>' {                          // Empty packed structure type? | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2126 | $$.PAT = new PATypeHolder(StructType::get(std::vector<const Type*>(),true)); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2127 | $$.S.makeComposite(); | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 2128 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2129 | | UpRTypes '*' {                             // Pointer type? | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2130 | if ($1.PAT->get() == Type::LabelTy) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2131 | error("Cannot form a pointer to a basic block"); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2132 | $$.S.makeComposite($1.S); | 
|  | 2133 | $$.PAT = new PATypeHolder(HandleUpRefs(PointerType::get($1.PAT->get()), | 
|  | 2134 | $$.S)); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2135 | delete $1.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2136 | } | 
|  | 2137 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2138 |  | 
|  | 2139 | // TypeList - Used for struct declarations and as a basis for function type | 
|  | 2140 | // declaration type lists | 
|  | 2141 | // | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2142 | TypeListI | 
|  | 2143 | : UpRTypes { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2144 | $$ = new std::list<PATypeInfo>(); | 
|  | 2145 | $$->push_back($1); | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2146 | } | 
|  | 2147 | | TypeListI ',' UpRTypes { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2148 | ($$=$1)->push_back($3); | 
|  | 2149 | } | 
|  | 2150 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2151 |  | 
|  | 2152 | // ArgTypeList - List of types for a function type declaration... | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2153 | ArgTypeListI | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2154 | : TypeListI | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2155 | | TypeListI ',' DOTDOTDOT { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2156 | PATypeInfo VoidTI; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2157 | VoidTI.PAT = new PATypeHolder(Type::VoidTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2158 | VoidTI.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2159 | ($$=$1)->push_back(VoidTI); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2160 | } | 
|  | 2161 | | DOTDOTDOT { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2162 | $$ = new std::list<PATypeInfo>(); | 
|  | 2163 | PATypeInfo VoidTI; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2164 | VoidTI.PAT = new PATypeHolder(Type::VoidTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2165 | VoidTI.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2166 | $$->push_back(VoidTI); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2167 | } | 
|  | 2168 | | /*empty*/ { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2169 | $$ = new std::list<PATypeInfo>(); | 
|  | 2170 | } | 
|  | 2171 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2172 |  | 
|  | 2173 | // ConstVal - The various declarations that go into the constant pool.  This | 
|  | 2174 | // production is used ONLY to represent constants that show up AFTER a 'const', | 
|  | 2175 | // 'constant' or 'global' token at global scope.  Constants that can be inlined | 
|  | 2176 | // into other expressions (such as integers and constexprs) are handled by the | 
|  | 2177 | // ResolvedVal, ValueRef and ConstValueRef productions. | 
|  | 2178 | // | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2179 | ConstVal | 
|  | 2180 | : Types '[' ConstVector ']' { // Nonempty unsized arr | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2181 | const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2182 | if (ATy == 0) | 
|  | 2183 | error("Cannot make array constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2184 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2185 | const Type *ETy = ATy->getElementType(); | 
|  | 2186 | int NumElements = ATy->getNumElements(); | 
|  | 2187 |  | 
|  | 2188 | // Verify that we have the correct size... | 
|  | 2189 | if (NumElements != -1 && NumElements != (int)$3->size()) | 
|  | 2190 | error("Type mismatch: constant sized array initialized with " + | 
|  | 2191 | utostr($3->size()) +  " arguments, but has size of " + | 
|  | 2192 | itostr(NumElements) + ""); | 
|  | 2193 |  | 
|  | 2194 | // Verify all elements are correct type! | 
|  | 2195 | std::vector<Constant*> Elems; | 
|  | 2196 | for (unsigned i = 0; i < $3->size(); i++) { | 
|  | 2197 | Constant *C = (*$3)[i].C; | 
|  | 2198 | const Type* ValTy = C->getType(); | 
|  | 2199 | if (ETy != ValTy) | 
|  | 2200 | error("Element #" + utostr(i) + " is not of type '" + | 
|  | 2201 | ETy->getDescription() +"' as required!\nIt is of type '"+ | 
|  | 2202 | ValTy->getDescription() + "'"); | 
|  | 2203 | Elems.push_back(C); | 
|  | 2204 | } | 
|  | 2205 | $$.C = ConstantArray::get(ATy, Elems); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2206 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2207 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2208 | delete $3; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2209 | } | 
|  | 2210 | | Types '[' ']' { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2211 | const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2212 | if (ATy == 0) | 
|  | 2213 | error("Cannot make array constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2214 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2215 | int NumElements = ATy->getNumElements(); | 
|  | 2216 | if (NumElements != -1 && NumElements != 0) | 
|  | 2217 | error("Type mismatch: constant sized array initialized with 0" | 
|  | 2218 | " arguments, but has size of " + itostr(NumElements) +""); | 
|  | 2219 | $$.C = ConstantArray::get(ATy, std::vector<Constant*>()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2220 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2221 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2222 | } | 
|  | 2223 | | Types 'c' STRINGCONSTANT { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2224 | const ArrayType *ATy = dyn_cast<ArrayType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2225 | if (ATy == 0) | 
|  | 2226 | error("Cannot make array constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2227 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2228 | int NumElements = ATy->getNumElements(); | 
|  | 2229 | const Type *ETy = dyn_cast<IntegerType>(ATy->getElementType()); | 
|  | 2230 | if (!ETy || cast<IntegerType>(ETy)->getBitWidth() != 8) | 
|  | 2231 | error("String arrays require type i8, not '" + ETy->getDescription() + | 
|  | 2232 | "'"); | 
|  | 2233 | char *EndStr = UnEscapeLexed($3, true); | 
|  | 2234 | if (NumElements != -1 && NumElements != (EndStr-$3)) | 
|  | 2235 | error("Can't build string constant of size " + | 
|  | 2236 | itostr((int)(EndStr-$3)) + " when array has size " + | 
|  | 2237 | itostr(NumElements) + ""); | 
|  | 2238 | std::vector<Constant*> Vals; | 
|  | 2239 | for (char *C = (char *)$3; C != (char *)EndStr; ++C) | 
|  | 2240 | Vals.push_back(ConstantInt::get(ETy, *C)); | 
|  | 2241 | free($3); | 
|  | 2242 | $$.C = ConstantArray::get(ATy, Vals); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2243 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2244 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2245 | } | 
|  | 2246 | | Types '<' ConstVector '>' { // Nonempty unsized arr | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 2247 | const VectorType *PTy = dyn_cast<VectorType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2248 | if (PTy == 0) | 
|  | 2249 | error("Cannot make packed constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2250 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2251 | const Type *ETy = PTy->getElementType(); | 
|  | 2252 | int NumElements = PTy->getNumElements(); | 
|  | 2253 | // Verify that we have the correct size... | 
|  | 2254 | if (NumElements != -1 && NumElements != (int)$3->size()) | 
|  | 2255 | error("Type mismatch: constant sized packed initialized with " + | 
|  | 2256 | utostr($3->size()) +  " arguments, but has size of " + | 
|  | 2257 | itostr(NumElements) + ""); | 
|  | 2258 | // Verify all elements are correct type! | 
|  | 2259 | std::vector<Constant*> Elems; | 
|  | 2260 | for (unsigned i = 0; i < $3->size(); i++) { | 
|  | 2261 | Constant *C = (*$3)[i].C; | 
|  | 2262 | const Type* ValTy = C->getType(); | 
|  | 2263 | if (ETy != ValTy) | 
|  | 2264 | error("Element #" + utostr(i) + " is not of type '" + | 
|  | 2265 | ETy->getDescription() +"' as required!\nIt is of type '"+ | 
|  | 2266 | ValTy->getDescription() + "'"); | 
|  | 2267 | Elems.push_back(C); | 
|  | 2268 | } | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 2269 | $$.C = ConstantVector::get(PTy, Elems); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2270 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2271 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2272 | delete $3; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2273 | } | 
|  | 2274 | | Types '{' ConstVector '}' { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2275 | const StructType *STy = dyn_cast<StructType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2276 | if (STy == 0) | 
|  | 2277 | error("Cannot make struct constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2278 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2279 | if ($3->size() != STy->getNumContainedTypes()) | 
|  | 2280 | error("Illegal number of initializers for structure type"); | 
|  | 2281 |  | 
|  | 2282 | // Check to ensure that constants are compatible with the type initializer! | 
|  | 2283 | std::vector<Constant*> Fields; | 
|  | 2284 | for (unsigned i = 0, e = $3->size(); i != e; ++i) { | 
|  | 2285 | Constant *C = (*$3)[i].C; | 
|  | 2286 | if (C->getType() != STy->getElementType(i)) | 
|  | 2287 | error("Expected type '" + STy->getElementType(i)->getDescription() + | 
|  | 2288 | "' for element #" + utostr(i) + " of structure initializer"); | 
|  | 2289 | Fields.push_back(C); | 
|  | 2290 | } | 
|  | 2291 | $$.C = ConstantStruct::get(STy, Fields); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2292 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2293 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2294 | delete $3; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2295 | } | 
|  | 2296 | | Types '{' '}' { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2297 | const StructType *STy = dyn_cast<StructType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2298 | if (STy == 0) | 
|  | 2299 | error("Cannot make struct constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2300 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2301 | if (STy->getNumContainedTypes() != 0) | 
|  | 2302 | error("Illegal number of initializers for structure type"); | 
|  | 2303 | $$.C = ConstantStruct::get(STy, std::vector<Constant*>()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2304 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2305 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2306 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2307 | | Types '<' '{' ConstVector '}' '>' { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2308 | const StructType *STy = dyn_cast<StructType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2309 | if (STy == 0) | 
|  | 2310 | error("Cannot make packed struct constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2311 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2312 | if ($4->size() != STy->getNumContainedTypes()) | 
|  | 2313 | error("Illegal number of initializers for packed structure type"); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2314 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2315 | // Check to ensure that constants are compatible with the type initializer! | 
|  | 2316 | std::vector<Constant*> Fields; | 
|  | 2317 | for (unsigned i = 0, e = $4->size(); i != e; ++i) { | 
|  | 2318 | Constant *C = (*$4)[i].C; | 
|  | 2319 | if (C->getType() != STy->getElementType(i)) | 
|  | 2320 | error("Expected type '" + STy->getElementType(i)->getDescription() + | 
|  | 2321 | "' for element #" + utostr(i) + " of packed struct initializer"); | 
|  | 2322 | Fields.push_back(C); | 
| Reid Spencer | 280d801 | 2006-12-01 23:40:53 +0000 | [diff] [blame] | 2323 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2324 | $$.C = ConstantStruct::get(STy, Fields); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2325 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2326 | delete $1.PAT; | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2327 | delete $4; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2328 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2329 | | Types '<' '{' '}' '>' { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2330 | const StructType *STy = dyn_cast<StructType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2331 | if (STy == 0) | 
|  | 2332 | error("Cannot make packed struct constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2333 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2334 | if (STy->getNumContainedTypes() != 0) | 
|  | 2335 | error("Illegal number of initializers for packed structure type"); | 
|  | 2336 | $$.C = ConstantStruct::get(STy, std::vector<Constant*>()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2337 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2338 | delete $1.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2339 | } | 
|  | 2340 | | Types NULL_TOK { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2341 | const PointerType *PTy = dyn_cast<PointerType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2342 | if (PTy == 0) | 
|  | 2343 | error("Cannot make null pointer constant with type: '" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2344 | $1.PAT->get()->getDescription() + "'"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2345 | $$.C = ConstantPointerNull::get(PTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2346 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2347 | delete $1.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2348 | } | 
|  | 2349 | | Types UNDEF { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2350 | $$.C = UndefValue::get($1.PAT->get()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2351 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2352 | delete $1.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2353 | } | 
|  | 2354 | | Types SymbolicValueRef { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2355 | const PointerType *Ty = dyn_cast<PointerType>($1.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2356 | if (Ty == 0) | 
|  | 2357 | error("Global const reference must be a pointer type, not" + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2358 | $1.PAT->get()->getDescription()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2359 |  | 
|  | 2360 | // ConstExprs can exist in the body of a function, thus creating | 
|  | 2361 | // GlobalValues whenever they refer to a variable.  Because we are in | 
|  | 2362 | // the context of a function, getExistingValue will search the functions | 
|  | 2363 | // symbol table instead of the module symbol table for the global symbol, | 
|  | 2364 | // which throws things all off.  To get around this, we just tell | 
|  | 2365 | // getExistingValue that we are at global scope here. | 
|  | 2366 | // | 
|  | 2367 | Function *SavedCurFn = CurFun.CurrentFunction; | 
|  | 2368 | CurFun.CurrentFunction = 0; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2369 | $2.S.copy($1.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2370 | Value *V = getExistingValue(Ty, $2); | 
|  | 2371 | CurFun.CurrentFunction = SavedCurFn; | 
|  | 2372 |  | 
|  | 2373 | // If this is an initializer for a constant pointer, which is referencing a | 
|  | 2374 | // (currently) undefined variable, create a stub now that shall be replaced | 
|  | 2375 | // in the future with the right type of variable. | 
|  | 2376 | // | 
|  | 2377 | if (V == 0) { | 
|  | 2378 | assert(isa<PointerType>(Ty) && "Globals may only be used as pointers"); | 
|  | 2379 | const PointerType *PT = cast<PointerType>(Ty); | 
|  | 2380 |  | 
|  | 2381 | // First check to see if the forward references value is already created! | 
|  | 2382 | PerModuleInfo::GlobalRefsType::iterator I = | 
|  | 2383 | CurModule.GlobalRefs.find(std::make_pair(PT, $2)); | 
|  | 2384 |  | 
|  | 2385 | if (I != CurModule.GlobalRefs.end()) { | 
|  | 2386 | V = I->second;             // Placeholder already exists, use it... | 
|  | 2387 | $2.destroy(); | 
|  | 2388 | } else { | 
|  | 2389 | std::string Name; | 
|  | 2390 | if ($2.Type == ValID::NameVal) Name = $2.Name; | 
|  | 2391 |  | 
|  | 2392 | // Create the forward referenced global. | 
|  | 2393 | GlobalValue *GV; | 
|  | 2394 | if (const FunctionType *FTy = | 
|  | 2395 | dyn_cast<FunctionType>(PT->getElementType())) { | 
|  | 2396 | GV = new Function(FTy, GlobalValue::ExternalLinkage, Name, | 
|  | 2397 | CurModule.CurrentModule); | 
|  | 2398 | } else { | 
|  | 2399 | GV = new GlobalVariable(PT->getElementType(), false, | 
|  | 2400 | GlobalValue::ExternalLinkage, 0, | 
|  | 2401 | Name, CurModule.CurrentModule); | 
|  | 2402 | } | 
|  | 2403 |  | 
|  | 2404 | // Keep track of the fact that we have a forward ref to recycle it | 
|  | 2405 | CurModule.GlobalRefs.insert(std::make_pair(std::make_pair(PT, $2), GV)); | 
|  | 2406 | V = GV; | 
|  | 2407 | } | 
|  | 2408 | } | 
|  | 2409 | $$.C = cast<GlobalValue>(V); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2410 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2411 | delete $1.PAT;            // Free the type handle | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2412 | } | 
|  | 2413 | | Types ConstExpr { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2414 | if ($1.PAT->get() != $2.C->getType()) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2415 | error("Mismatched types for constant expression"); | 
|  | 2416 | $$ = $2; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2417 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2418 | delete $1.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2419 | } | 
|  | 2420 | | Types ZEROINITIALIZER { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2421 | const Type *Ty = $1.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2422 | if (isa<FunctionType>(Ty) || Ty == Type::LabelTy || isa<OpaqueType>(Ty)) | 
|  | 2423 | error("Cannot create a null initialized value of this type"); | 
|  | 2424 | $$.C = Constant::getNullValue(Ty); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2425 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2426 | delete $1.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2427 | } | 
|  | 2428 | | SIntType EINT64VAL {      // integral constants | 
|  | 2429 | const Type *Ty = $1.T; | 
|  | 2430 | if (!ConstantInt::isValueValidForType(Ty, $2)) | 
|  | 2431 | error("Constant value doesn't fit in type"); | 
|  | 2432 | $$.C = ConstantInt::get(Ty, $2); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2433 | $$.S.makeSigned(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2434 | } | 
|  | 2435 | | UIntType EUINT64VAL {            // integral constants | 
|  | 2436 | const Type *Ty = $1.T; | 
|  | 2437 | if (!ConstantInt::isValueValidForType(Ty, $2)) | 
|  | 2438 | error("Constant value doesn't fit in type"); | 
|  | 2439 | $$.C = ConstantInt::get(Ty, $2); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2440 | $$.S.makeUnsigned(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2441 | } | 
|  | 2442 | | BOOL TRUETOK {                      // Boolean constants | 
|  | 2443 | $$.C = ConstantInt::get(Type::Int1Ty, true); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2444 | $$.S.makeUnsigned(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2445 | } | 
|  | 2446 | | BOOL FALSETOK {                     // Boolean constants | 
|  | 2447 | $$.C = ConstantInt::get(Type::Int1Ty, false); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2448 | $$.S.makeUnsigned(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2449 | } | 
|  | 2450 | | FPType FPVAL {                   // Float & Double constants | 
|  | 2451 | if (!ConstantFP::isValueValidForType($1.T, $2)) | 
|  | 2452 | error("Floating point constant invalid for type"); | 
|  | 2453 | $$.C = ConstantFP::get($1.T, $2); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2454 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2455 | } | 
|  | 2456 | ; | 
|  | 2457 |  | 
|  | 2458 | ConstExpr | 
|  | 2459 | : CastOps '(' ConstVal TO Types ')' { | 
|  | 2460 | const Type* SrcTy = $3.C->getType(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2461 | const Type* DstTy = $5.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2462 | Signedness SrcSign($3.S); | 
|  | 2463 | Signedness DstSign($5.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2464 | if (!SrcTy->isFirstClassType()) | 
|  | 2465 | error("cast constant expression from a non-primitive type: '" + | 
|  | 2466 | SrcTy->getDescription() + "'"); | 
|  | 2467 | if (!DstTy->isFirstClassType()) | 
|  | 2468 | error("cast constant expression to a non-primitive type: '" + | 
|  | 2469 | DstTy->getDescription() + "'"); | 
|  | 2470 | $$.C = cast<Constant>(getCast($1, $3.C, SrcSign, DstTy, DstSign)); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2471 | $$.S.copy(DstSign); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2472 | delete $5.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2473 | } | 
|  | 2474 | | GETELEMENTPTR '(' ConstVal IndexList ')' { | 
|  | 2475 | const Type *Ty = $3.C->getType(); | 
|  | 2476 | if (!isa<PointerType>(Ty)) | 
|  | 2477 | error("GetElementPtr requires a pointer operand"); | 
|  | 2478 |  | 
|  | 2479 | std::vector<Value*> VIndices; | 
|  | 2480 | std::vector<Constant*> CIndices; | 
|  | 2481 | upgradeGEPIndices($3.C->getType(), $4, VIndices, &CIndices); | 
|  | 2482 |  | 
|  | 2483 | delete $4; | 
| Chris Lattner | 4227bdb | 2007-02-19 07:34:02 +0000 | [diff] [blame] | 2484 | $$.C = ConstantExpr::getGetElementPtr($3.C, &CIndices[0], CIndices.size()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2485 | $$.S.copy(getElementSign($3, CIndices)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2486 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2487 | | SELECT '(' ConstVal ',' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2488 | if (!$3.C->getType()->isInteger() || | 
|  | 2489 | cast<IntegerType>($3.C->getType())->getBitWidth() != 1) | 
|  | 2490 | error("Select condition must be bool type"); | 
|  | 2491 | if ($5.C->getType() != $7.C->getType()) | 
|  | 2492 | error("Select operand types must match"); | 
|  | 2493 | $$.C = ConstantExpr::getSelect($3.C, $5.C, $7.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2494 | $$.S.copy($5.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2495 | } | 
|  | 2496 | | ArithmeticOps '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2497 | const Type *Ty = $3.C->getType(); | 
|  | 2498 | if (Ty != $5.C->getType()) | 
|  | 2499 | error("Binary operator types must match"); | 
|  | 2500 | // First, make sure we're dealing with the right opcode by upgrading from | 
|  | 2501 | // obsolete versions. | 
|  | 2502 | Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S); | 
|  | 2503 |  | 
|  | 2504 | // HACK: llvm 1.3 and earlier used to emit invalid pointer constant exprs. | 
|  | 2505 | // To retain backward compatibility with these early compilers, we emit a | 
|  | 2506 | // cast to the appropriate integer type automatically if we are in the | 
|  | 2507 | // broken case.  See PR424 for more information. | 
|  | 2508 | if (!isa<PointerType>(Ty)) { | 
|  | 2509 | $$.C = ConstantExpr::get(Opcode, $3.C, $5.C); | 
|  | 2510 | } else { | 
|  | 2511 | const Type *IntPtrTy = 0; | 
|  | 2512 | switch (CurModule.CurrentModule->getPointerSize()) { | 
|  | 2513 | case Module::Pointer32: IntPtrTy = Type::Int32Ty; break; | 
|  | 2514 | case Module::Pointer64: IntPtrTy = Type::Int64Ty; break; | 
|  | 2515 | default: error("invalid pointer binary constant expr"); | 
|  | 2516 | } | 
|  | 2517 | $$.C = ConstantExpr::get(Opcode, | 
|  | 2518 | ConstantExpr::getCast(Instruction::PtrToInt, $3.C, IntPtrTy), | 
|  | 2519 | ConstantExpr::getCast(Instruction::PtrToInt, $5.C, IntPtrTy)); | 
|  | 2520 | $$.C = ConstantExpr::getCast(Instruction::IntToPtr, $$.C, Ty); | 
|  | 2521 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2522 | $$.S.copy($3.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2523 | } | 
|  | 2524 | | LogicalOps '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2525 | const Type* Ty = $3.C->getType(); | 
|  | 2526 | if (Ty != $5.C->getType()) | 
|  | 2527 | error("Logical operator types must match"); | 
|  | 2528 | if (!Ty->isInteger()) { | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 2529 | if (!isa<VectorType>(Ty) || | 
|  | 2530 | !cast<VectorType>(Ty)->getElementType()->isInteger()) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2531 | error("Logical operator requires integer operands"); | 
|  | 2532 | } | 
|  | 2533 | Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $3.S); | 
|  | 2534 | $$.C = ConstantExpr::get(Opcode, $3.C, $5.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2535 | $$.S.copy($3.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2536 | } | 
|  | 2537 | | SetCondOps '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2538 | const Type* Ty = $3.C->getType(); | 
|  | 2539 | if (Ty != $5.C->getType()) | 
|  | 2540 | error("setcc operand types must match"); | 
|  | 2541 | unsigned short pred; | 
|  | 2542 | Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $3.S); | 
|  | 2543 | $$.C = ConstantExpr::getCompare(Opcode, $3.C, $5.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2544 | $$.S.makeUnsigned(); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2545 | } | 
| Reid Spencer | 57f28f9 | 2006-12-03 07:10:26 +0000 | [diff] [blame] | 2546 | | ICMP IPredicates '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2547 | if ($4.C->getType() != $6.C->getType()) | 
|  | 2548 | error("icmp operand types must match"); | 
|  | 2549 | $$.C = ConstantExpr::getCompare($2, $4.C, $6.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2550 | $$.S.makeUnsigned(); | 
| Reid Spencer | 57f28f9 | 2006-12-03 07:10:26 +0000 | [diff] [blame] | 2551 | } | 
|  | 2552 | | FCMP FPredicates '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2553 | if ($4.C->getType() != $6.C->getType()) | 
|  | 2554 | error("fcmp operand types must match"); | 
|  | 2555 | $$.C = ConstantExpr::getCompare($2, $4.C, $6.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2556 | $$.S.makeUnsigned(); | 
| Reid Spencer | 229e936 | 2006-12-02 22:14:11 +0000 | [diff] [blame] | 2557 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2558 | | ShiftOps '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2559 | if (!$5.C->getType()->isInteger() || | 
|  | 2560 | cast<IntegerType>($5.C->getType())->getBitWidth() != 8) | 
|  | 2561 | error("Shift count for shift constant must be unsigned byte"); | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 2562 | const Type* Ty = $3.C->getType(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2563 | if (!$3.C->getType()->isInteger()) | 
|  | 2564 | error("Shift constant expression requires integer operand"); | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 2565 | Constant *ShiftAmt = ConstantExpr::getZExt($5.C, Ty); | 
|  | 2566 | $$.C = ConstantExpr::get(getBinaryOp($1, Ty, $3.S), $3.C, ShiftAmt); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2567 | $$.S.copy($3.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2568 | } | 
|  | 2569 | | EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2570 | if (!ExtractElementInst::isValidOperands($3.C, $5.C)) | 
|  | 2571 | error("Invalid extractelement operands"); | 
|  | 2572 | $$.C = ConstantExpr::getExtractElement($3.C, $5.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2573 | $$.S.copy($3.S.get(0)); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2574 | } | 
|  | 2575 | | INSERTELEMENT '(' ConstVal ',' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2576 | if (!InsertElementInst::isValidOperands($3.C, $5.C, $7.C)) | 
|  | 2577 | error("Invalid insertelement operands"); | 
|  | 2578 | $$.C = ConstantExpr::getInsertElement($3.C, $5.C, $7.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2579 | $$.S.copy($3.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2580 | } | 
|  | 2581 | | SHUFFLEVECTOR '(' ConstVal ',' ConstVal ',' ConstVal ')' { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2582 | if (!ShuffleVectorInst::isValidOperands($3.C, $5.C, $7.C)) | 
|  | 2583 | error("Invalid shufflevector operands"); | 
|  | 2584 | $$.C = ConstantExpr::getShuffleVector($3.C, $5.C, $7.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2585 | $$.S.copy($3.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2586 | } | 
|  | 2587 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2588 |  | 
|  | 2589 |  | 
|  | 2590 | // ConstVector - A list of comma separated constants. | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2591 | ConstVector | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2592 | : ConstVector ',' ConstVal { ($$ = $1)->push_back($3); } | 
|  | 2593 | | ConstVal { | 
|  | 2594 | $$ = new std::vector<ConstInfo>(); | 
|  | 2595 | $$->push_back($1); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2596 | } | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2597 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2598 |  | 
|  | 2599 |  | 
|  | 2600 | // GlobalType - Match either GLOBAL or CONSTANT for global declarations... | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2601 | GlobalType | 
|  | 2602 | : GLOBAL { $$ = false; } | 
|  | 2603 | | CONSTANT { $$ = true; } | 
|  | 2604 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2605 |  | 
|  | 2606 |  | 
|  | 2607 | //===----------------------------------------------------------------------===// | 
|  | 2608 | //                             Rules to match Modules | 
|  | 2609 | //===----------------------------------------------------------------------===// | 
|  | 2610 |  | 
|  | 2611 | // Module rule: Capture the result of parsing the whole file into a result | 
|  | 2612 | // variable... | 
|  | 2613 | // | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2614 | Module | 
|  | 2615 | : FunctionList { | 
|  | 2616 | $$ = ParserResult = $1; | 
|  | 2617 | CurModule.ModuleDone(); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2618 | } | 
| Jeff Cohen | ac2dca9 | 2007-01-21 19:30:52 +0000 | [diff] [blame] | 2619 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2620 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2621 | // FunctionList - A list of functions, preceeded by a constant pool. | 
|  | 2622 | // | 
|  | 2623 | FunctionList | 
|  | 2624 | : FunctionList Function { $$ = $1; CurFun.FunctionDone(); } | 
|  | 2625 | | FunctionList FunctionProto { $$ = $1; } | 
|  | 2626 | | FunctionList MODULE ASM_TOK AsmBlock { $$ = $1; } | 
|  | 2627 | | FunctionList IMPLEMENTATION { $$ = $1; } | 
|  | 2628 | | ConstPool { | 
|  | 2629 | $$ = CurModule.CurrentModule; | 
|  | 2630 | // Emit an error if there are any unresolved types left. | 
|  | 2631 | if (!CurModule.LateResolveTypes.empty()) { | 
|  | 2632 | const ValID &DID = CurModule.LateResolveTypes.begin()->first; | 
|  | 2633 | if (DID.Type == ValID::NameVal) { | 
|  | 2634 | error("Reference to an undefined type: '"+DID.getName() + "'"); | 
|  | 2635 | } else { | 
|  | 2636 | error("Reference to an undefined type: #" + itostr(DID.Num)); | 
|  | 2637 | } | 
|  | 2638 | } | 
|  | 2639 | } | 
|  | 2640 | ; | 
| Reid Spencer | 7872074 | 2006-12-02 20:21:22 +0000 | [diff] [blame] | 2641 |  | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2642 | // ConstPool - Constants with optional names assigned to them. | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2643 | ConstPool | 
|  | 2644 | : ConstPool OptAssign TYPE TypesV { | 
|  | 2645 | // Eagerly resolve types.  This is not an optimization, this is a | 
|  | 2646 | // requirement that is due to the fact that we could have this: | 
|  | 2647 | // | 
|  | 2648 | // %list = type { %list * } | 
|  | 2649 | // %list = type { %list * }    ; repeated type decl | 
|  | 2650 | // | 
|  | 2651 | // If types are not resolved eagerly, then the two types will not be | 
|  | 2652 | // determined to be the same type! | 
|  | 2653 | // | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2654 | ResolveTypeTo($2, $4.PAT->get(), $4.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2655 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2656 | if (!setTypeName($4, $2) && !$2) { | 
|  | 2657 | // If this is a numbered type that is not a redefinition, add it to the | 
|  | 2658 | // slot table. | 
|  | 2659 | CurModule.Types.push_back($4.PAT->get()); | 
|  | 2660 | CurModule.TypeSigns.push_back($4.S); | 
| Reid Spencer | a50d596 | 2006-12-02 04:11:07 +0000 | [diff] [blame] | 2661 | } | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2662 | delete $4.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2663 | } | 
|  | 2664 | | ConstPool FunctionProto {       // Function prototypes can be in const pool | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2665 | } | 
|  | 2666 | | ConstPool MODULE ASM_TOK AsmBlock {  // Asm blocks can be in the const pool | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2667 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2668 | | ConstPool OptAssign OptLinkage GlobalType ConstVal { | 
|  | 2669 | if ($5.C == 0) | 
|  | 2670 | error("Global value initializer is not a constant"); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2671 | CurGV = ParseGlobalVariable($2, $3, $4, $5.C->getType(), $5.C, $5.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2672 | } GlobalVarAttributes { | 
|  | 2673 | CurGV = 0; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2674 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2675 | | ConstPool OptAssign EXTERNAL GlobalType Types { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2676 | const Type *Ty = $5.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2677 | CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, Ty, 0, | 
|  | 2678 | $5.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2679 | delete $5.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2680 | } GlobalVarAttributes { | 
|  | 2681 | CurGV = 0; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2682 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2683 | | ConstPool OptAssign DLLIMPORT GlobalType Types { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2684 | const Type *Ty = $5.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2685 | CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, Ty, 0, | 
|  | 2686 | $5.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2687 | delete $5.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2688 | } GlobalVarAttributes { | 
|  | 2689 | CurGV = 0; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2690 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2691 | | ConstPool OptAssign EXTERN_WEAK GlobalType Types { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2692 | const Type *Ty = $5.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2693 | CurGV = | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2694 | ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, Ty, 0, | 
|  | 2695 | $5.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2696 | delete $5.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2697 | } GlobalVarAttributes { | 
|  | 2698 | CurGV = 0; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2699 | } | 
|  | 2700 | | ConstPool TARGET TargetDefinition { | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2701 | } | 
|  | 2702 | | ConstPool DEPLIBS '=' LibrariesDefinition { | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2703 | } | 
|  | 2704 | | /* empty: end of list */ { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2705 | } | 
|  | 2706 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2707 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2708 | AsmBlock | 
|  | 2709 | : STRINGCONSTANT { | 
|  | 2710 | const std::string &AsmSoFar = CurModule.CurrentModule->getModuleInlineAsm(); | 
|  | 2711 | char *EndStr = UnEscapeLexed($1, true); | 
|  | 2712 | std::string NewAsm($1, EndStr); | 
|  | 2713 | free($1); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2714 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2715 | if (AsmSoFar.empty()) | 
|  | 2716 | CurModule.CurrentModule->setModuleInlineAsm(NewAsm); | 
|  | 2717 | else | 
|  | 2718 | CurModule.CurrentModule->setModuleInlineAsm(AsmSoFar+"\n"+NewAsm); | 
|  | 2719 | } | 
|  | 2720 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2721 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2722 | BigOrLittle | 
| Reid Spencer | d7c4f8c | 2007-01-26 19:59:25 +0000 | [diff] [blame] | 2723 | : BIG    { $$ = Module::BigEndian; } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2724 | | LITTLE { $$ = Module::LittleEndian; } | 
|  | 2725 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2726 |  | 
|  | 2727 | TargetDefinition | 
|  | 2728 | : ENDIAN '=' BigOrLittle { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2729 | CurModule.setEndianness($3); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2730 | } | 
|  | 2731 | | POINTERSIZE '=' EUINT64VAL { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2732 | if ($3 == 32) | 
|  | 2733 | CurModule.setPointerSize(Module::Pointer32); | 
|  | 2734 | else if ($3 == 64) | 
|  | 2735 | CurModule.setPointerSize(Module::Pointer64); | 
|  | 2736 | else | 
|  | 2737 | error("Invalid pointer size: '" + utostr($3) + "'"); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2738 | } | 
|  | 2739 | | TRIPLE '=' STRINGCONSTANT { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2740 | CurModule.CurrentModule->setTargetTriple($3); | 
|  | 2741 | free($3); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2742 | } | 
|  | 2743 | | DATALAYOUT '=' STRINGCONSTANT { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2744 | CurModule.CurrentModule->setDataLayout($3); | 
|  | 2745 | free($3); | 
|  | 2746 | } | 
|  | 2747 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2748 |  | 
|  | 2749 | LibrariesDefinition | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2750 | : '[' LibList ']' | 
|  | 2751 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2752 |  | 
|  | 2753 | LibList | 
|  | 2754 | : LibList ',' STRINGCONSTANT { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2755 | CurModule.CurrentModule->addLibrary($3); | 
|  | 2756 | free($3); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2757 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2758 | | STRINGCONSTANT { | 
|  | 2759 | CurModule.CurrentModule->addLibrary($1); | 
|  | 2760 | free($1); | 
|  | 2761 | } | 
|  | 2762 | | /* empty: end of list */ { } | 
|  | 2763 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2764 |  | 
|  | 2765 | //===----------------------------------------------------------------------===// | 
|  | 2766 | //                       Rules to match Function Headers | 
|  | 2767 | //===----------------------------------------------------------------------===// | 
|  | 2768 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2769 | Name | 
|  | 2770 | : VAR_ID | STRINGCONSTANT | 
|  | 2771 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2772 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2773 | OptName | 
|  | 2774 | : Name | 
|  | 2775 | | /*empty*/ { $$ = 0; } | 
|  | 2776 | ; | 
|  | 2777 |  | 
|  | 2778 | ArgVal | 
|  | 2779 | : Types OptName { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2780 | if ($1.PAT->get() == Type::VoidTy) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2781 | error("void typed arguments are invalid"); | 
|  | 2782 | $$ = new std::pair<PATypeInfo, char*>($1, $2); | 
| Reid Spencer | 52402b0 | 2007-01-02 05:45:11 +0000 | [diff] [blame] | 2783 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2784 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2785 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2786 | ArgListH | 
|  | 2787 | : ArgListH ',' ArgVal { | 
|  | 2788 | $$ = $1; | 
|  | 2789 | $$->push_back(*$3); | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 2790 | delete $3; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2791 | } | 
|  | 2792 | | ArgVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2793 | $$ = new std::vector<std::pair<PATypeInfo,char*> >(); | 
|  | 2794 | $$->push_back(*$1); | 
|  | 2795 | delete $1; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2796 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2797 | ; | 
|  | 2798 |  | 
|  | 2799 | ArgList | 
|  | 2800 | : ArgListH { $$ = $1; } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2801 | | ArgListH ',' DOTDOTDOT { | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2802 | $$ = $1; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2803 | PATypeInfo VoidTI; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2804 | VoidTI.PAT = new PATypeHolder(Type::VoidTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2805 | VoidTI.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2806 | $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0)); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2807 | } | 
|  | 2808 | | DOTDOTDOT { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2809 | $$ = new std::vector<std::pair<PATypeInfo,char*> >(); | 
|  | 2810 | PATypeInfo VoidTI; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2811 | VoidTI.PAT = new PATypeHolder(Type::VoidTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2812 | VoidTI.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2813 | $$->push_back(std::pair<PATypeInfo, char*>(VoidTI, 0)); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2814 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2815 | | /* empty */ { $$ = 0; } | 
|  | 2816 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2817 |  | 
| Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 2818 | FunctionHeaderH | 
|  | 2819 | : OptCallingConv TypesV Name '(' ArgList ')' OptSection OptAlign { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2820 | UnEscapeLexed($3); | 
|  | 2821 | std::string FunctionName($3); | 
|  | 2822 | free($3);  // Free strdup'd memory! | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 2823 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2824 | const Type* RetTy = $2.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2825 |  | 
|  | 2826 | if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy) | 
|  | 2827 | error("LLVM functions cannot return aggregate types"); | 
|  | 2828 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2829 | Signedness FTySign; | 
|  | 2830 | FTySign.makeComposite($2.S); | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2831 | std::vector<const Type*> ParamTyList; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2832 |  | 
|  | 2833 | // In LLVM 2.0 the signatures of three varargs intrinsics changed to take | 
|  | 2834 | // i8*. We check here for those names and override the parameter list | 
|  | 2835 | // types to ensure the prototype is correct. | 
|  | 2836 | if (FunctionName == "llvm.va_start" || FunctionName == "llvm.va_end") { | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2837 | ParamTyList.push_back(PointerType::get(Type::Int8Ty)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2838 | } else if (FunctionName == "llvm.va_copy") { | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2839 | ParamTyList.push_back(PointerType::get(Type::Int8Ty)); | 
|  | 2840 | ParamTyList.push_back(PointerType::get(Type::Int8Ty)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2841 | } else if ($5) {   // If there are arguments... | 
|  | 2842 | for (std::vector<std::pair<PATypeInfo,char*> >::iterator | 
|  | 2843 | I = $5->begin(), E = $5->end(); I != E; ++I) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2844 | const Type *Ty = I->first.PAT->get(); | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2845 | ParamTyList.push_back(Ty); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2846 | FTySign.add(I->first.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2847 | } | 
|  | 2848 | } | 
|  | 2849 |  | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2850 | bool isVarArg = ParamTyList.size() && ParamTyList.back() == Type::VoidTy; | 
|  | 2851 | if (isVarArg) | 
|  | 2852 | ParamTyList.pop_back(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2853 |  | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 2854 | // Convert the CSRet calling convention into the corresponding parameter | 
|  | 2855 | // attribute. | 
|  | 2856 | FunctionType::ParamAttrsList ParamAttrs; | 
|  | 2857 | if ($1 == OldCallingConv::CSRet) { | 
|  | 2858 | ParamAttrs.push_back(FunctionType::NoAttributeSet);     // result | 
|  | 2859 | ParamAttrs.push_back(FunctionType::StructRetAttribute); // first arg | 
|  | 2860 | } | 
|  | 2861 |  | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2862 | const FunctionType *FT = FunctionType::get(RetTy, ParamTyList, isVarArg, | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 2863 | ParamAttrs); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2864 | const PointerType *PFT = PointerType::get(FT); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2865 | delete $2.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2866 |  | 
|  | 2867 | ValID ID; | 
|  | 2868 | if (!FunctionName.empty()) { | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 2869 | ID = ValID::create((char*)FunctionName.c_str()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2870 | } else { | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 2871 | ID = ValID::create((int)CurModule.Values[PFT].size()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2872 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2873 | ID.S.makeComposite(FTySign); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2874 |  | 
|  | 2875 | Function *Fn = 0; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2876 | Module* M = CurModule.CurrentModule; | 
|  | 2877 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2878 | // See if this function was forward referenced.  If so, recycle the object. | 
|  | 2879 | if (GlobalValue *FWRef = CurModule.GetForwardRefForGlobal(PFT, ID)) { | 
|  | 2880 | // Move the function to the end of the list, from whereever it was | 
|  | 2881 | // previously inserted. | 
|  | 2882 | Fn = cast<Function>(FWRef); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2883 | M->getFunctionList().remove(Fn); | 
|  | 2884 | M->getFunctionList().push_back(Fn); | 
|  | 2885 | } else if (!FunctionName.empty()) { | 
|  | 2886 | GlobalValue *Conflict = M->getFunction(FunctionName); | 
|  | 2887 | if (!Conflict) | 
|  | 2888 | Conflict = M->getNamedGlobal(FunctionName); | 
|  | 2889 | if (Conflict && PFT == Conflict->getType()) { | 
|  | 2890 | if (!CurFun.isDeclare && !Conflict->isDeclaration()) { | 
|  | 2891 | // We have two function definitions that conflict, same type, same | 
|  | 2892 | // name. We should really check to make sure that this is the result | 
|  | 2893 | // of integer type planes collapsing and generate an error if it is | 
|  | 2894 | // not, but we'll just rename on the assumption that it is. However, | 
|  | 2895 | // let's do it intelligently and rename the internal linkage one | 
|  | 2896 | // if there is one. | 
|  | 2897 | std::string NewName(makeNameUnique(FunctionName)); | 
|  | 2898 | if (Conflict->hasInternalLinkage()) { | 
|  | 2899 | Conflict->setName(NewName); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2900 | RenameMapKey Key = | 
|  | 2901 | makeRenameMapKey(FunctionName, Conflict->getType(), ID.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2902 | CurModule.RenameMap[Key] = NewName; | 
|  | 2903 | Fn = new Function(FT, CurFun.Linkage, FunctionName, M); | 
|  | 2904 | InsertValue(Fn, CurModule.Values); | 
|  | 2905 | } else { | 
|  | 2906 | Fn = new Function(FT, CurFun.Linkage, NewName, M); | 
|  | 2907 | InsertValue(Fn, CurModule.Values); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2908 | RenameMapKey Key = | 
|  | 2909 | makeRenameMapKey(FunctionName, PFT, ID.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2910 | CurModule.RenameMap[Key] = NewName; | 
|  | 2911 | } | 
|  | 2912 | } else { | 
|  | 2913 | // If they are not both definitions, then just use the function we | 
|  | 2914 | // found since the types are the same. | 
|  | 2915 | Fn = cast<Function>(Conflict); | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2916 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2917 | // Make sure to strip off any argument names so we can't get | 
|  | 2918 | // conflicts. | 
|  | 2919 | if (Fn->isDeclaration()) | 
|  | 2920 | for (Function::arg_iterator AI = Fn->arg_begin(), | 
|  | 2921 | AE = Fn->arg_end(); AI != AE; ++AI) | 
|  | 2922 | AI->setName(""); | 
|  | 2923 | } | 
|  | 2924 | } else if (Conflict) { | 
|  | 2925 | // We have two globals with the same name and  different types. | 
|  | 2926 | // Previously, this was permitted because the symbol table had | 
|  | 2927 | // "type planes" and names only needed to be distinct within a | 
|  | 2928 | // type plane. After PR411 was fixed, this is no loner the case. | 
|  | 2929 | // To resolve this we must rename one of the two. | 
|  | 2930 | if (Conflict->hasInternalLinkage()) { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2931 | // We can safely rename the Conflict. | 
|  | 2932 | RenameMapKey Key = | 
|  | 2933 | makeRenameMapKey(Conflict->getName(), Conflict->getType(), | 
|  | 2934 | CurModule.NamedValueSigns[Conflict->getName()]); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2935 | Conflict->setName(makeNameUnique(Conflict->getName())); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2936 | CurModule.RenameMap[Key] = Conflict->getName(); | 
|  | 2937 | Fn = new Function(FT, CurFun.Linkage, FunctionName, M); | 
|  | 2938 | InsertValue(Fn, CurModule.Values); | 
| Reid Spencer | d2920cd | 2007-03-21 17:27:53 +0000 | [diff] [blame^] | 2939 | } else { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2940 | // We can't quietly rename either of these things, but we must | 
| Reid Spencer | d2920cd | 2007-03-21 17:27:53 +0000 | [diff] [blame^] | 2941 | // rename one of them. Only if the function's linkage is internal can | 
|  | 2942 | // we forgo a warning message about the renamed function. | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2943 | std::string NewName = makeNameUnique(FunctionName); | 
| Reid Spencer | d2920cd | 2007-03-21 17:27:53 +0000 | [diff] [blame^] | 2944 | if (CurFun.Linkage != GlobalValue::InternalLinkage) { | 
|  | 2945 | warning("Renaming function '" + FunctionName + "' as '" + NewName + | 
|  | 2946 | "' may cause linkage errors"); | 
|  | 2947 | } | 
|  | 2948 | // Elect to rename the thing we're now defining. | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2949 | Fn = new Function(FT, CurFun.Linkage, NewName, M); | 
|  | 2950 | InsertValue(Fn, CurModule.Values); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2951 | RenameMapKey Key = makeRenameMapKey(FunctionName, PFT, ID.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2952 | CurModule.RenameMap[Key] = NewName; | 
| Reid Spencer | d2920cd | 2007-03-21 17:27:53 +0000 | [diff] [blame^] | 2953 | } | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2954 | } else { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2955 | // There's no conflict, just define the function | 
|  | 2956 | Fn = new Function(FT, CurFun.Linkage, FunctionName, M); | 
|  | 2957 | InsertValue(Fn, CurModule.Values); | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2958 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2959 | } | 
|  | 2960 |  | 
|  | 2961 | CurFun.FunctionStart(Fn); | 
|  | 2962 |  | 
|  | 2963 | if (CurFun.isDeclare) { | 
|  | 2964 | // If we have declaration, always overwrite linkage.  This will allow us | 
|  | 2965 | // to correctly handle cases, when pointer to function is passed as | 
|  | 2966 | // argument to another function. | 
|  | 2967 | Fn->setLinkage(CurFun.Linkage); | 
|  | 2968 | } | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 2969 | Fn->setCallingConv(upgradeCallingConv($1)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2970 | Fn->setAlignment($8); | 
|  | 2971 | if ($7) { | 
|  | 2972 | Fn->setSection($7); | 
|  | 2973 | free($7); | 
|  | 2974 | } | 
|  | 2975 |  | 
|  | 2976 | // Add all of the arguments we parsed to the function... | 
|  | 2977 | if ($5) {                     // Is null if empty... | 
|  | 2978 | if (isVarArg) {  // Nuke the last entry | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2979 | assert($5->back().first.PAT->get() == Type::VoidTy && | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2980 | $5->back().second == 0 && "Not a varargs marker"); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2981 | delete $5->back().first.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2982 | $5->pop_back();  // Delete the last entry | 
|  | 2983 | } | 
|  | 2984 | Function::arg_iterator ArgIt = Fn->arg_begin(); | 
| Reid Spencer | ef9b9a7 | 2007-02-05 20:47:22 +0000 | [diff] [blame] | 2985 | Function::arg_iterator ArgEnd = Fn->arg_end(); | 
|  | 2986 | std::vector<std::pair<PATypeInfo,char*> >::iterator I = $5->begin(); | 
|  | 2987 | std::vector<std::pair<PATypeInfo,char*> >::iterator E = $5->end(); | 
|  | 2988 | for ( ; I != E && ArgIt != ArgEnd; ++I, ++ArgIt) { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 2989 | delete I->first.PAT;                      // Delete the typeholder... | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 2990 | ValueInfo VI; VI.V = ArgIt; VI.S.copy(I->first.S); | 
|  | 2991 | setValueName(VI, I->second);           // Insert arg into symtab... | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 2992 | InsertValue(ArgIt); | 
|  | 2993 | } | 
|  | 2994 | delete $5;                     // We're now done with the argument list | 
|  | 2995 | } | 
|  | 2996 | } | 
|  | 2997 | ; | 
|  | 2998 |  | 
|  | 2999 | BEGIN | 
|  | 3000 | : BEGINTOK | '{'                // Allow BEGIN or '{' to start a function | 
| Jeff Cohen | ac2dca9 | 2007-01-21 19:30:52 +0000 | [diff] [blame] | 3001 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3002 |  | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 3003 | FunctionHeader | 
| Reid Spencer | d2920cd | 2007-03-21 17:27:53 +0000 | [diff] [blame^] | 3004 | : OptLinkage { CurFun.Linkage = $1; } FunctionHeaderH BEGIN { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3005 | $$ = CurFun.CurrentFunction; | 
|  | 3006 |  | 
|  | 3007 | // Make sure that we keep track of the linkage type even if there was a | 
|  | 3008 | // previous "declare". | 
|  | 3009 | $$->setLinkage($1); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3010 | } | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 3011 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3012 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3013 | END | 
|  | 3014 | : ENDTOK | '}'                    // Allow end of '}' to end a function | 
|  | 3015 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3016 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3017 | Function | 
|  | 3018 | : BasicBlockList END { | 
|  | 3019 | $$ = $1; | 
|  | 3020 | }; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3021 |  | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 3022 | FnDeclareLinkage | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3023 | : /*default*/ { $$ = GlobalValue::ExternalLinkage; } | 
|  | 3024 | | DLLIMPORT   { $$ = GlobalValue::DLLImportLinkage; } | 
|  | 3025 | | EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3026 | ; | 
|  | 3027 |  | 
|  | 3028 | FunctionProto | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3029 | : DECLARE { CurFun.isDeclare = true; } | 
|  | 3030 | FnDeclareLinkage { CurFun.Linkage = $3; } FunctionHeaderH { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3031 | $$ = CurFun.CurrentFunction; | 
|  | 3032 | CurFun.FunctionDone(); | 
|  | 3033 |  | 
|  | 3034 | } | 
|  | 3035 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3036 |  | 
|  | 3037 | //===----------------------------------------------------------------------===// | 
|  | 3038 | //                        Rules to match Basic Blocks | 
|  | 3039 | //===----------------------------------------------------------------------===// | 
|  | 3040 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3041 | OptSideEffect | 
|  | 3042 | : /* empty */ { $$ = false; } | 
|  | 3043 | | SIDEEFFECT { $$ = true; } | 
|  | 3044 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3045 |  | 
| Reid Spencer | e77e35e | 2006-12-01 20:26:20 +0000 | [diff] [blame] | 3046 | ConstValueRef | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3047 | // A reference to a direct constant | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3048 | : ESINT64VAL { $$ = ValID::create($1); } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3049 | | EUINT64VAL { $$ = ValID::create($1); } | 
|  | 3050 | | FPVAL { $$ = ValID::create($1); } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3051 | | TRUETOK { | 
|  | 3052 | $$ = ValID::create(ConstantInt::get(Type::Int1Ty, true)); | 
|  | 3053 | $$.S.makeUnsigned(); | 
|  | 3054 | } | 
|  | 3055 | | FALSETOK { | 
|  | 3056 | $$ = ValID::create(ConstantInt::get(Type::Int1Ty, false)); | 
|  | 3057 | $$.S.makeUnsigned(); | 
|  | 3058 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3059 | | NULL_TOK { $$ = ValID::createNull(); } | 
|  | 3060 | | UNDEF { $$ = ValID::createUndef(); } | 
|  | 3061 | | ZEROINITIALIZER { $$ = ValID::createZeroInit(); } | 
|  | 3062 | | '<' ConstVector '>' { // Nonempty unsized packed vector | 
|  | 3063 | const Type *ETy = (*$2)[0].C->getType(); | 
|  | 3064 | int NumElements = $2->size(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3065 | VectorType* pt = VectorType::get(ETy, NumElements); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3066 | $$.S.makeComposite((*$2)[0].S); | 
|  | 3067 | PATypeHolder* PTy = new PATypeHolder(HandleUpRefs(pt, $$.S)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3068 |  | 
|  | 3069 | // Verify all elements are correct type! | 
|  | 3070 | std::vector<Constant*> Elems; | 
|  | 3071 | for (unsigned i = 0; i < $2->size(); i++) { | 
|  | 3072 | Constant *C = (*$2)[i].C; | 
|  | 3073 | const Type *CTy = C->getType(); | 
|  | 3074 | if (ETy != CTy) | 
|  | 3075 | error("Element #" + utostr(i) + " is not of type '" + | 
|  | 3076 | ETy->getDescription() +"' as required!\nIt is of type '" + | 
|  | 3077 | CTy->getDescription() + "'"); | 
|  | 3078 | Elems.push_back(C); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3079 | } | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 3080 | $$ = ValID::create(ConstantVector::get(pt, Elems)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3081 | delete PTy; delete $2; | 
|  | 3082 | } | 
|  | 3083 | | ConstExpr { | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 3084 | $$ = ValID::create($1.C); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3085 | $$.S.copy($1.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3086 | } | 
|  | 3087 | | ASM_TOK OptSideEffect STRINGCONSTANT ',' STRINGCONSTANT { | 
|  | 3088 | char *End = UnEscapeLexed($3, true); | 
|  | 3089 | std::string AsmStr = std::string($3, End); | 
|  | 3090 | End = UnEscapeLexed($5, true); | 
|  | 3091 | std::string Constraints = std::string($5, End); | 
|  | 3092 | $$ = ValID::createInlineAsm(AsmStr, Constraints, $2); | 
|  | 3093 | free($3); | 
|  | 3094 | free($5); | 
|  | 3095 | } | 
|  | 3096 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3097 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3098 | // SymbolicValueRef - Reference to one of two ways of symbolically refering to // another value. | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3099 | // | 
|  | 3100 | SymbolicValueRef | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3101 | : INTVAL {  $$ = ValID::create($1); $$.S.makeSignless(); } | 
|  | 3102 | | Name   {  $$ = ValID::create($1); $$.S.makeSignless(); } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3103 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3104 |  | 
|  | 3105 | // ValueRef - A reference to a definition... either constant or symbolic | 
| Reid Spencer | f459d39 | 2006-12-02 16:19:52 +0000 | [diff] [blame] | 3106 | ValueRef | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3107 | : SymbolicValueRef | ConstValueRef | 
| Reid Spencer | f459d39 | 2006-12-02 16:19:52 +0000 | [diff] [blame] | 3108 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3109 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3110 |  | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3111 | // ResolvedVal - a <type> <value> pair.  This is used only in cases where the | 
|  | 3112 | // type immediately preceeds the value reference, and allows complex constant | 
|  | 3113 | // pool references (for things like: 'ret [2 x int] [ int 12, int 42]') | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3114 | ResolvedVal | 
|  | 3115 | : Types ValueRef { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3116 | const Type *Ty = $1.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3117 | $2.S.copy($1.S); | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 3118 | $$.V = getVal(Ty, $2); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3119 | $$.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3120 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3121 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3122 | ; | 
|  | 3123 |  | 
|  | 3124 | BasicBlockList | 
|  | 3125 | : BasicBlockList BasicBlock { | 
|  | 3126 | $$ = $1; | 
|  | 3127 | } | 
|  | 3128 | | FunctionHeader BasicBlock { // Do not allow functions with 0 basic blocks | 
|  | 3129 | $$ = $1; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3130 | }; | 
|  | 3131 |  | 
|  | 3132 |  | 
|  | 3133 | // Basic blocks are terminated by branching instructions: | 
|  | 3134 | // br, br/cc, switch, ret | 
|  | 3135 | // | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3136 | BasicBlock | 
|  | 3137 | : InstructionList OptAssign BBTerminatorInst  { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3138 | ValueInfo VI; VI.V = $3.TI; VI.S.copy($3.S); | 
|  | 3139 | setValueName(VI, $2); | 
|  | 3140 | InsertValue($3.TI); | 
|  | 3141 | $1->getInstList().push_back($3.TI); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3142 | InsertValue($1); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3143 | $$ = $1; | 
|  | 3144 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3145 | ; | 
|  | 3146 |  | 
|  | 3147 | InstructionList | 
|  | 3148 | : InstructionList Inst { | 
|  | 3149 | if ($2.I) | 
|  | 3150 | $1->getInstList().push_back($2.I); | 
|  | 3151 | $$ = $1; | 
|  | 3152 | } | 
|  | 3153 | | /* empty */ { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3154 | $$ = CurBB = getBBVal(ValID::create((int)CurFun.NextBBNum++),true); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3155 | // Make sure to move the basic block to the correct location in the | 
|  | 3156 | // function, instead of leaving it inserted wherever it was first | 
|  | 3157 | // referenced. | 
|  | 3158 | Function::BasicBlockListType &BBL = | 
|  | 3159 | CurFun.CurrentFunction->getBasicBlockList(); | 
|  | 3160 | BBL.splice(BBL.end(), BBL, $$); | 
|  | 3161 | } | 
|  | 3162 | | LABELSTR { | 
| Reid Spencer | 5eb77c7 | 2007-03-15 03:26:42 +0000 | [diff] [blame] | 3163 | $$ = CurBB = getBBVal(ValID::create($1), true); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3164 | // Make sure to move the basic block to the correct location in the | 
|  | 3165 | // function, instead of leaving it inserted wherever it was first | 
|  | 3166 | // referenced. | 
|  | 3167 | Function::BasicBlockListType &BBL = | 
|  | 3168 | CurFun.CurrentFunction->getBasicBlockList(); | 
|  | 3169 | BBL.splice(BBL.end(), BBL, $$); | 
|  | 3170 | } | 
|  | 3171 | ; | 
|  | 3172 |  | 
|  | 3173 | Unwind : UNWIND | EXCEPT; | 
|  | 3174 |  | 
|  | 3175 | BBTerminatorInst | 
|  | 3176 | : RET ResolvedVal {              // Return with a result... | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3177 | $$.TI = new ReturnInst($2.V); | 
|  | 3178 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3179 | } | 
|  | 3180 | | RET VOID {                                       // Return with no result... | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3181 | $$.TI = new ReturnInst(); | 
|  | 3182 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3183 | } | 
|  | 3184 | | BR LABEL ValueRef {                         // Unconditional Branch... | 
|  | 3185 | BasicBlock* tmpBB = getBBVal($3); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3186 | $$.TI = new BranchInst(tmpBB); | 
|  | 3187 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3188 | }                                                  // Conditional Branch... | 
|  | 3189 | | BR BOOL ValueRef ',' LABEL ValueRef ',' LABEL ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3190 | $6.S.makeSignless(); | 
|  | 3191 | $9.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3192 | BasicBlock* tmpBBA = getBBVal($6); | 
|  | 3193 | BasicBlock* tmpBBB = getBBVal($9); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3194 | $3.S.makeUnsigned(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3195 | Value* tmpVal = getVal(Type::Int1Ty, $3); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3196 | $$.TI = new BranchInst(tmpBBA, tmpBBB, tmpVal); | 
|  | 3197 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3198 | } | 
|  | 3199 | | SWITCH IntType ValueRef ',' LABEL ValueRef '[' JumpTable ']' { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3200 | $3.S.copy($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3201 | Value* tmpVal = getVal($2.T, $3); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3202 | $6.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3203 | BasicBlock* tmpBB = getBBVal($6); | 
|  | 3204 | SwitchInst *S = new SwitchInst(tmpVal, tmpBB, $8->size()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3205 | $$.TI = S; | 
|  | 3206 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3207 | std::vector<std::pair<Constant*,BasicBlock*> >::iterator I = $8->begin(), | 
|  | 3208 | E = $8->end(); | 
|  | 3209 | for (; I != E; ++I) { | 
|  | 3210 | if (ConstantInt *CI = dyn_cast<ConstantInt>(I->first)) | 
|  | 3211 | S->addCase(CI, I->second); | 
|  | 3212 | else | 
|  | 3213 | error("Switch case is constant, but not a simple integer"); | 
|  | 3214 | } | 
|  | 3215 | delete $8; | 
|  | 3216 | } | 
|  | 3217 | | SWITCH IntType ValueRef ',' LABEL ValueRef '[' ']' { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3218 | $3.S.copy($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3219 | Value* tmpVal = getVal($2.T, $3); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3220 | $6.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3221 | BasicBlock* tmpBB = getBBVal($6); | 
|  | 3222 | SwitchInst *S = new SwitchInst(tmpVal, tmpBB, 0); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3223 | $$.TI = S; | 
|  | 3224 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3225 | } | 
|  | 3226 | | INVOKE OptCallingConv TypesV ValueRef '(' ValueRefListE ')' | 
|  | 3227 | TO LABEL ValueRef Unwind LABEL ValueRef { | 
|  | 3228 | const PointerType *PFTy; | 
|  | 3229 | const FunctionType *Ty; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3230 | Signedness FTySign; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3231 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3232 | if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) || | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3233 | !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { | 
|  | 3234 | // Pull out the types of all of the arguments... | 
|  | 3235 | std::vector<const Type*> ParamTypes; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3236 | FTySign.makeComposite($3.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3237 | if ($6) { | 
|  | 3238 | for (std::vector<ValueInfo>::iterator I = $6->begin(), E = $6->end(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3239 | I != E; ++I) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3240 | ParamTypes.push_back((*I).V->getType()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3241 | FTySign.add(I->S); | 
|  | 3242 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3243 | } | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 3244 | FunctionType::ParamAttrsList ParamAttrs; | 
|  | 3245 | if ($2 == OldCallingConv::CSRet) { | 
|  | 3246 | ParamAttrs.push_back(FunctionType::NoAttributeSet); | 
|  | 3247 | ParamAttrs.push_back(FunctionType::StructRetAttribute); | 
|  | 3248 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3249 | bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; | 
|  | 3250 | if (isVarArg) ParamTypes.pop_back(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3251 | Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, ParamAttrs); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3252 | PFTy = PointerType::get(Ty); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3253 | $$.S.copy($3.S); | 
|  | 3254 | } else { | 
|  | 3255 | FTySign = $3.S; | 
|  | 3256 | $$.S.copy($3.S.get(0)); // 0th element of FuncTy sign is result ty | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3257 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3258 | $4.S.makeComposite(FTySign); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3259 | Value *V = getVal(PFTy, $4);   // Get the function we're calling... | 
|  | 3260 | BasicBlock *Normal = getBBVal($10); | 
|  | 3261 | BasicBlock *Except = getBBVal($13); | 
|  | 3262 |  | 
|  | 3263 | // Create the call node... | 
|  | 3264 | if (!$6) {                                   // Has no arguments? | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3265 | $$.TI = new InvokeInst(V, Normal, Except, 0, 0); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3266 | } else {                                     // Has arguments? | 
|  | 3267 | // Loop through FunctionType's arguments and ensure they are specified | 
|  | 3268 | // correctly! | 
|  | 3269 | // | 
|  | 3270 | FunctionType::param_iterator I = Ty->param_begin(); | 
|  | 3271 | FunctionType::param_iterator E = Ty->param_end(); | 
|  | 3272 | std::vector<ValueInfo>::iterator ArgI = $6->begin(), ArgE = $6->end(); | 
|  | 3273 |  | 
|  | 3274 | std::vector<Value*> Args; | 
|  | 3275 | for (; ArgI != ArgE && I != E; ++ArgI, ++I) { | 
|  | 3276 | if ((*ArgI).V->getType() != *I) | 
|  | 3277 | error("Parameter " +(*ArgI).V->getName()+ " is not of type '" + | 
|  | 3278 | (*I)->getDescription() + "'"); | 
|  | 3279 | Args.push_back((*ArgI).V); | 
|  | 3280 | } | 
|  | 3281 |  | 
|  | 3282 | if (I != E || (ArgI != ArgE && !Ty->isVarArg())) | 
|  | 3283 | error("Invalid number of parameters detected"); | 
|  | 3284 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3285 | $$.TI = new InvokeInst(V, Normal, Except, &Args[0], Args.size()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3286 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3287 | cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2)); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3288 | delete $3.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3289 | delete $6; | 
|  | 3290 | } | 
|  | 3291 | | Unwind { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3292 | $$.TI = new UnwindInst(); | 
|  | 3293 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3294 | } | 
|  | 3295 | | UNREACHABLE { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3296 | $$.TI = new UnreachableInst(); | 
|  | 3297 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3298 | } | 
|  | 3299 | ; | 
|  | 3300 |  | 
|  | 3301 | JumpTable | 
|  | 3302 | : JumpTable IntType ConstValueRef ',' LABEL ValueRef { | 
|  | 3303 | $$ = $1; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3304 | $3.S.copy($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3305 | Constant *V = cast<Constant>(getExistingValue($2.T, $3)); | 
|  | 3306 |  | 
|  | 3307 | if (V == 0) | 
|  | 3308 | error("May only switch on a constant pool value"); | 
|  | 3309 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3310 | $6.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3311 | BasicBlock* tmpBB = getBBVal($6); | 
|  | 3312 | $$->push_back(std::make_pair(V, tmpBB)); | 
|  | 3313 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3314 | | IntType ConstValueRef ',' LABEL ValueRef { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3315 | $$ = new std::vector<std::pair<Constant*, BasicBlock*> >(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3316 | $2.S.copy($1.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3317 | Constant *V = cast<Constant>(getExistingValue($1.T, $2)); | 
|  | 3318 |  | 
|  | 3319 | if (V == 0) | 
|  | 3320 | error("May only switch on a constant pool value"); | 
|  | 3321 |  | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3322 | $5.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3323 | BasicBlock* tmpBB = getBBVal($5); | 
|  | 3324 | $$->push_back(std::make_pair(V, tmpBB)); | 
|  | 3325 | } | 
|  | 3326 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3327 |  | 
|  | 3328 | Inst | 
|  | 3329 | : OptAssign InstVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3330 | bool omit = false; | 
|  | 3331 | if ($1) | 
|  | 3332 | if (BitCastInst *BCI = dyn_cast<BitCastInst>($2.I)) | 
|  | 3333 | if (BCI->getSrcTy() == BCI->getDestTy() && | 
|  | 3334 | BCI->getOperand(0)->getName() == $1) | 
|  | 3335 | // This is a useless bit cast causing a name redefinition. It is | 
|  | 3336 | // a bit cast from a type to the same type of an operand with the | 
|  | 3337 | // same name as the name we would give this instruction. Since this | 
|  | 3338 | // instruction results in no code generation, it is safe to omit | 
|  | 3339 | // the instruction. This situation can occur because of collapsed | 
|  | 3340 | // type planes. For example: | 
|  | 3341 | //   %X = add int %Y, %Z | 
|  | 3342 | //   %X = cast int %Y to uint | 
|  | 3343 | // After upgrade, this looks like: | 
|  | 3344 | //   %X = add i32 %Y, %Z | 
|  | 3345 | //   %X = bitcast i32 to i32 | 
|  | 3346 | // The bitcast is clearly useless so we omit it. | 
|  | 3347 | omit = true; | 
|  | 3348 | if (omit) { | 
|  | 3349 | $$.I = 0; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3350 | $$.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3351 | } else { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3352 | ValueInfo VI; VI.V = $2.I; VI.S.copy($2.S); | 
|  | 3353 | setValueName(VI, $1); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3354 | InsertValue($2.I); | 
|  | 3355 | $$ = $2; | 
| Reid Spencer | f5626a3 | 2007-01-01 01:20:41 +0000 | [diff] [blame] | 3356 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3357 | }; | 
|  | 3358 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3359 | PHIList : Types '[' ValueRef ',' ValueRef ']' {    // Used for PHI nodes | 
|  | 3360 | $$.P = new std::list<std::pair<Value*, BasicBlock*> >(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3361 | $$.S.copy($1.S); | 
|  | 3362 | $3.S.copy($1.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3363 | Value* tmpVal = getVal($1.PAT->get(), $3); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3364 | $5.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3365 | BasicBlock* tmpBB = getBBVal($5); | 
|  | 3366 | $$.P->push_back(std::make_pair(tmpVal, tmpBB)); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3367 | delete $1.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3368 | } | 
|  | 3369 | | PHIList ',' '[' ValueRef ',' ValueRef ']' { | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3370 | $$ = $1; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3371 | $4.S.copy($1.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3372 | Value* tmpVal = getVal($1.P->front().first->getType(), $4); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3373 | $6.S.makeSignless(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3374 | BasicBlock* tmpBB = getBBVal($6); | 
|  | 3375 | $1.P->push_back(std::make_pair(tmpVal, tmpBB)); | 
|  | 3376 | } | 
|  | 3377 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3378 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3379 | ValueRefList : ResolvedVal {    // Used for call statements, and memory insts... | 
|  | 3380 | $$ = new std::vector<ValueInfo>(); | 
| Reid Spencer | f848365 | 2006-12-02 15:16:01 +0000 | [diff] [blame] | 3381 | $$->push_back($1); | 
|  | 3382 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3383 | | ValueRefList ',' ResolvedVal { | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3384 | $$ = $1; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3385 | $1->push_back($3); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3386 | }; | 
|  | 3387 |  | 
|  | 3388 | // ValueRefListE - Just like ValueRefList, except that it may also be empty! | 
|  | 3389 | ValueRefListE | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3390 | : ValueRefList | 
|  | 3391 | | /*empty*/ { $$ = 0; } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3392 | ; | 
|  | 3393 |  | 
|  | 3394 | OptTailCall | 
|  | 3395 | : TAIL CALL { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3396 | $$ = true; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3397 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3398 | | CALL { | 
|  | 3399 | $$ = false; | 
|  | 3400 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3401 | ; | 
|  | 3402 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3403 | InstVal | 
|  | 3404 | : ArithmeticOps Types ValueRef ',' ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3405 | $3.S.copy($2.S); | 
|  | 3406 | $5.S.copy($2.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3407 | const Type* Ty = $2.PAT->get(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3408 | if (!Ty->isInteger() && !Ty->isFloatingPoint() && !isa<VectorType>(Ty)) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3409 | error("Arithmetic operator requires integer, FP, or packed operands"); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3410 | if (isa<VectorType>(Ty) && | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3411 | ($1 == URemOp || $1 == SRemOp || $1 == FRemOp || $1 == RemOp)) | 
| Chris Lattner | 4227bdb | 2007-02-19 07:34:02 +0000 | [diff] [blame] | 3412 | error("Remainder not supported on vector types"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3413 | // Upgrade the opcode from obsolete versions before we do anything with it. | 
|  | 3414 | Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S); | 
|  | 3415 | Value* val1 = getVal(Ty, $3); | 
|  | 3416 | Value* val2 = getVal(Ty, $5); | 
|  | 3417 | $$.I = BinaryOperator::create(Opcode, val1, val2); | 
|  | 3418 | if ($$.I == 0) | 
|  | 3419 | error("binary operator returned null"); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3420 | $$.S.copy($2.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3421 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3422 | } | 
|  | 3423 | | LogicalOps Types ValueRef ',' ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3424 | $3.S.copy($2.S); | 
|  | 3425 | $5.S.copy($2.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3426 | const Type *Ty = $2.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3427 | if (!Ty->isInteger()) { | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3428 | if (!isa<VectorType>(Ty) || | 
|  | 3429 | !cast<VectorType>(Ty)->getElementType()->isInteger()) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3430 | error("Logical operator requires integral operands"); | 
|  | 3431 | } | 
|  | 3432 | Instruction::BinaryOps Opcode = getBinaryOp($1, Ty, $2.S); | 
|  | 3433 | Value* tmpVal1 = getVal(Ty, $3); | 
|  | 3434 | Value* tmpVal2 = getVal(Ty, $5); | 
|  | 3435 | $$.I = BinaryOperator::create(Opcode, tmpVal1, tmpVal2); | 
|  | 3436 | if ($$.I == 0) | 
|  | 3437 | error("binary operator returned null"); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3438 | $$.S.copy($2.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3439 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3440 | } | 
|  | 3441 | | SetCondOps Types ValueRef ',' ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3442 | $3.S.copy($2.S); | 
|  | 3443 | $5.S.copy($2.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3444 | const Type* Ty = $2.PAT->get(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3445 | if(isa<VectorType>(Ty)) | 
|  | 3446 | error("VectorTypes currently not supported in setcc instructions"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3447 | unsigned short pred; | 
|  | 3448 | Instruction::OtherOps Opcode = getCompareOp($1, pred, Ty, $2.S); | 
|  | 3449 | Value* tmpVal1 = getVal(Ty, $3); | 
|  | 3450 | Value* tmpVal2 = getVal(Ty, $5); | 
|  | 3451 | $$.I = CmpInst::create(Opcode, pred, tmpVal1, tmpVal2); | 
|  | 3452 | if ($$.I == 0) | 
|  | 3453 | error("binary operator returned null"); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3454 | $$.S.makeUnsigned(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3455 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3456 | } | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 3457 | | ICMP IPredicates Types ValueRef ',' ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3458 | $4.S.copy($3.S); | 
|  | 3459 | $6.S.copy($3.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3460 | const Type *Ty = $3.PAT->get(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3461 | if (isa<VectorType>(Ty)) | 
|  | 3462 | error("VectorTypes currently not supported in icmp instructions"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3463 | else if (!Ty->isInteger() && !isa<PointerType>(Ty)) | 
|  | 3464 | error("icmp requires integer or pointer typed operands"); | 
|  | 3465 | Value* tmpVal1 = getVal(Ty, $4); | 
|  | 3466 | Value* tmpVal2 = getVal(Ty, $6); | 
|  | 3467 | $$.I = new ICmpInst($2, tmpVal1, tmpVal2); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3468 | $$.S.makeUnsigned(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3469 | delete $3.PAT; | 
| Reid Spencer | 57f28f9 | 2006-12-03 07:10:26 +0000 | [diff] [blame] | 3470 | } | 
| Reid Spencer | 6fd36ab | 2006-12-29 20:35:03 +0000 | [diff] [blame] | 3471 | | FCMP FPredicates Types ValueRef ',' ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3472 | $4.S.copy($3.S); | 
|  | 3473 | $6.S.copy($3.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3474 | const Type *Ty = $3.PAT->get(); | 
| Reid Spencer | 9d6565a | 2007-02-15 02:26:10 +0000 | [diff] [blame] | 3475 | if (isa<VectorType>(Ty)) | 
|  | 3476 | error("VectorTypes currently not supported in fcmp instructions"); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3477 | else if (!Ty->isFloatingPoint()) | 
|  | 3478 | error("fcmp instruction requires floating point operands"); | 
|  | 3479 | Value* tmpVal1 = getVal(Ty, $4); | 
|  | 3480 | Value* tmpVal2 = getVal(Ty, $6); | 
|  | 3481 | $$.I = new FCmpInst($2, tmpVal1, tmpVal2); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3482 | $$.S.makeUnsigned(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3483 | delete $3.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3484 | } | 
|  | 3485 | | NOT ResolvedVal { | 
|  | 3486 | warning("Use of obsolete 'not' instruction: Replacing with 'xor"); | 
|  | 3487 | const Type *Ty = $2.V->getType(); | 
|  | 3488 | Value *Ones = ConstantInt::getAllOnesValue(Ty); | 
|  | 3489 | if (Ones == 0) | 
|  | 3490 | error("Expected integral type for not instruction"); | 
|  | 3491 | $$.I = BinaryOperator::create(Instruction::Xor, $2.V, Ones); | 
|  | 3492 | if ($$.I == 0) | 
|  | 3493 | error("Could not create a xor instruction"); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3494 | $$.S.copy($2.S); | 
| Reid Spencer | 229e936 | 2006-12-02 22:14:11 +0000 | [diff] [blame] | 3495 | } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3496 | | ShiftOps ResolvedVal ',' ResolvedVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3497 | if (!$4.V->getType()->isInteger() || | 
|  | 3498 | cast<IntegerType>($4.V->getType())->getBitWidth() != 8) | 
|  | 3499 | error("Shift amount must be int8"); | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 3500 | const Type* Ty = $2.V->getType(); | 
|  | 3501 | if (!Ty->isInteger()) | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3502 | error("Shift constant expression requires integer operand"); | 
| Reid Spencer | 832254e | 2007-02-02 02:16:23 +0000 | [diff] [blame] | 3503 | Value* ShiftAmt = 0; | 
|  | 3504 | if (cast<IntegerType>(Ty)->getBitWidth() > Type::Int8Ty->getBitWidth()) | 
|  | 3505 | if (Constant *C = dyn_cast<Constant>($4.V)) | 
|  | 3506 | ShiftAmt = ConstantExpr::getZExt(C, Ty); | 
|  | 3507 | else | 
|  | 3508 | ShiftAmt = new ZExtInst($4.V, Ty, makeNameUnique("shift"), CurBB); | 
|  | 3509 | else | 
|  | 3510 | ShiftAmt = $4.V; | 
|  | 3511 | $$.I = BinaryOperator::create(getBinaryOp($1, Ty, $2.S), $2.V, ShiftAmt); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3512 | $$.S.copy($2.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3513 | } | 
| Reid Spencer | fcb5df8 | 2006-12-01 22:34:43 +0000 | [diff] [blame] | 3514 | | CastOps ResolvedVal TO Types { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3515 | const Type *DstTy = $4.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3516 | if (!DstTy->isFirstClassType()) | 
|  | 3517 | error("cast instruction to a non-primitive type: '" + | 
|  | 3518 | DstTy->getDescription() + "'"); | 
|  | 3519 | $$.I = cast<Instruction>(getCast($1, $2.V, $2.S, DstTy, $4.S, true)); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3520 | $$.S.copy($4.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3521 | delete $4.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3522 | } | 
|  | 3523 | | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3524 | if (!$2.V->getType()->isInteger() || | 
|  | 3525 | cast<IntegerType>($2.V->getType())->getBitWidth() != 1) | 
|  | 3526 | error("select condition must be bool"); | 
|  | 3527 | if ($4.V->getType() != $6.V->getType()) | 
|  | 3528 | error("select value types should match"); | 
|  | 3529 | $$.I = new SelectInst($2.V, $4.V, $6.V); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3530 | $$.S.copy($4.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3531 | } | 
|  | 3532 | | VAARG ResolvedVal ',' Types { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3533 | const Type *Ty = $4.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3534 | NewVarArgs = true; | 
|  | 3535 | $$.I = new VAArgInst($2.V, Ty); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3536 | $$.S.copy($4.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3537 | delete $4.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3538 | } | 
|  | 3539 | | VAARG_old ResolvedVal ',' Types { | 
|  | 3540 | const Type* ArgTy = $2.V->getType(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3541 | const Type* DstTy = $4.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3542 | ObsoleteVarArgs = true; | 
|  | 3543 | Function* NF = cast<Function>(CurModule.CurrentModule-> | 
|  | 3544 | getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0)); | 
|  | 3545 |  | 
|  | 3546 | //b = vaarg a, t -> | 
|  | 3547 | //foo = alloca 1 of t | 
|  | 3548 | //bar = vacopy a | 
|  | 3549 | //store bar -> foo | 
|  | 3550 | //b = vaarg foo, t | 
|  | 3551 | AllocaInst* foo = new AllocaInst(ArgTy, 0, "vaarg.fix"); | 
|  | 3552 | CurBB->getInstList().push_back(foo); | 
|  | 3553 | CallInst* bar = new CallInst(NF, $2.V); | 
|  | 3554 | CurBB->getInstList().push_back(bar); | 
|  | 3555 | CurBB->getInstList().push_back(new StoreInst(bar, foo)); | 
|  | 3556 | $$.I = new VAArgInst(foo, DstTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3557 | $$.S.copy($4.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3558 | delete $4.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3559 | } | 
|  | 3560 | | VANEXT_old ResolvedVal ',' Types { | 
|  | 3561 | const Type* ArgTy = $2.V->getType(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3562 | const Type* DstTy = $4.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3563 | ObsoleteVarArgs = true; | 
|  | 3564 | Function* NF = cast<Function>(CurModule.CurrentModule-> | 
|  | 3565 | getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0)); | 
|  | 3566 |  | 
|  | 3567 | //b = vanext a, t -> | 
|  | 3568 | //foo = alloca 1 of t | 
|  | 3569 | //bar = vacopy a | 
|  | 3570 | //store bar -> foo | 
|  | 3571 | //tmp = vaarg foo, t | 
|  | 3572 | //b = load foo | 
|  | 3573 | AllocaInst* foo = new AllocaInst(ArgTy, 0, "vanext.fix"); | 
|  | 3574 | CurBB->getInstList().push_back(foo); | 
|  | 3575 | CallInst* bar = new CallInst(NF, $2.V); | 
|  | 3576 | CurBB->getInstList().push_back(bar); | 
|  | 3577 | CurBB->getInstList().push_back(new StoreInst(bar, foo)); | 
|  | 3578 | Instruction* tmp = new VAArgInst(foo, DstTy); | 
|  | 3579 | CurBB->getInstList().push_back(tmp); | 
|  | 3580 | $$.I = new LoadInst(foo); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3581 | $$.S.copy($4.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3582 | delete $4.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3583 | } | 
|  | 3584 | | EXTRACTELEMENT ResolvedVal ',' ResolvedVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3585 | if (!ExtractElementInst::isValidOperands($2.V, $4.V)) | 
|  | 3586 | error("Invalid extractelement operands"); | 
|  | 3587 | $$.I = new ExtractElementInst($2.V, $4.V); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3588 | $$.S.copy($2.S.get(0)); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3589 | } | 
|  | 3590 | | INSERTELEMENT ResolvedVal ',' ResolvedVal ',' ResolvedVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3591 | if (!InsertElementInst::isValidOperands($2.V, $4.V, $6.V)) | 
|  | 3592 | error("Invalid insertelement operands"); | 
|  | 3593 | $$.I = new InsertElementInst($2.V, $4.V, $6.V); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3594 | $$.S.copy($2.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3595 | } | 
|  | 3596 | | SHUFFLEVECTOR ResolvedVal ',' ResolvedVal ',' ResolvedVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3597 | if (!ShuffleVectorInst::isValidOperands($2.V, $4.V, $6.V)) | 
|  | 3598 | error("Invalid shufflevector operands"); | 
|  | 3599 | $$.I = new ShuffleVectorInst($2.V, $4.V, $6.V); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3600 | $$.S.copy($2.S); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3601 | } | 
|  | 3602 | | PHI_TOK PHIList { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3603 | const Type *Ty = $2.P->front().first->getType(); | 
|  | 3604 | if (!Ty->isFirstClassType()) | 
|  | 3605 | error("PHI node operands must be of first class type"); | 
|  | 3606 | PHINode *PHI = new PHINode(Ty); | 
|  | 3607 | PHI->reserveOperandSpace($2.P->size()); | 
|  | 3608 | while ($2.P->begin() != $2.P->end()) { | 
|  | 3609 | if ($2.P->front().first->getType() != Ty) | 
|  | 3610 | error("All elements of a PHI node must be of the same type"); | 
|  | 3611 | PHI->addIncoming($2.P->front().first, $2.P->front().second); | 
|  | 3612 | $2.P->pop_front(); | 
|  | 3613 | } | 
|  | 3614 | $$.I = PHI; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3615 | $$.S.copy($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3616 | delete $2.P;  // Free the list... | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3617 | } | 
|  | 3618 | | OptTailCall OptCallingConv TypesV ValueRef '(' ValueRefListE ')'  { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3619 | // Handle the short call syntax | 
|  | 3620 | const PointerType *PFTy; | 
|  | 3621 | const FunctionType *FTy; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3622 | Signedness FTySign; | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3623 | if (!(PFTy = dyn_cast<PointerType>($3.PAT->get())) || | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3624 | !(FTy = dyn_cast<FunctionType>(PFTy->getElementType()))) { | 
|  | 3625 | // Pull out the types of all of the arguments... | 
|  | 3626 | std::vector<const Type*> ParamTypes; | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3627 | FTySign.makeComposite($3.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3628 | if ($6) { | 
|  | 3629 | for (std::vector<ValueInfo>::iterator I = $6->begin(), E = $6->end(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3630 | I != E; ++I) { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3631 | ParamTypes.push_back((*I).V->getType()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3632 | FTySign.add(I->S); | 
|  | 3633 | } | 
| Reid Spencer | c4d9625 | 2007-01-13 00:03:30 +0000 | [diff] [blame] | 3634 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3635 |  | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 3636 | FunctionType::ParamAttrsList ParamAttrs; | 
|  | 3637 | if ($2 == OldCallingConv::CSRet) { | 
|  | 3638 | ParamAttrs.push_back(FunctionType::NoAttributeSet); | 
|  | 3639 | ParamAttrs.push_back(FunctionType::StructRetAttribute); | 
|  | 3640 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3641 | bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy; | 
|  | 3642 | if (isVarArg) ParamTypes.pop_back(); | 
|  | 3643 |  | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3644 | const Type *RetTy = $3.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3645 | if (!RetTy->isFirstClassType() && RetTy != Type::VoidTy) | 
|  | 3646 | error("Functions cannot return aggregate types"); | 
|  | 3647 |  | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 3648 | FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, ParamAttrs); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3649 | PFTy = PointerType::get(FTy); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3650 | $$.S.copy($3.S); | 
|  | 3651 | } else { | 
|  | 3652 | FTySign = $3.S; | 
|  | 3653 | $$.S.copy($3.S.get(0)); // 0th element of FuncTy signedness is result sign | 
| Reid Spencer | f848365 | 2006-12-02 15:16:01 +0000 | [diff] [blame] | 3654 | } | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3655 | $4.S.makeComposite(FTySign); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3656 |  | 
|  | 3657 | // First upgrade any intrinsic calls. | 
|  | 3658 | std::vector<Value*> Args; | 
|  | 3659 | if ($6) | 
|  | 3660 | for (unsigned i = 0, e = $6->size(); i < e; ++i) | 
|  | 3661 | Args.push_back((*$6)[i].V); | 
|  | 3662 | Instruction *Inst = upgradeIntrinsicCall(FTy, $4, Args); | 
|  | 3663 |  | 
|  | 3664 | // If we got an upgraded intrinsic | 
|  | 3665 | if (Inst) { | 
|  | 3666 | $$.I = Inst; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3667 | } else { | 
|  | 3668 | // Get the function we're calling | 
|  | 3669 | Value *V = getVal(PFTy, $4); | 
|  | 3670 |  | 
|  | 3671 | // Check the argument values match | 
|  | 3672 | if (!$6) {                                   // Has no arguments? | 
|  | 3673 | // Make sure no arguments is a good thing! | 
|  | 3674 | if (FTy->getNumParams() != 0) | 
|  | 3675 | error("No arguments passed to a function that expects arguments"); | 
|  | 3676 | } else {                                     // Has arguments? | 
|  | 3677 | // Loop through FunctionType's arguments and ensure they are specified | 
|  | 3678 | // correctly! | 
|  | 3679 | // | 
|  | 3680 | FunctionType::param_iterator I = FTy->param_begin(); | 
|  | 3681 | FunctionType::param_iterator E = FTy->param_end(); | 
|  | 3682 | std::vector<ValueInfo>::iterator ArgI = $6->begin(), ArgE = $6->end(); | 
|  | 3683 |  | 
|  | 3684 | for (; ArgI != ArgE && I != E; ++ArgI, ++I) | 
|  | 3685 | if ((*ArgI).V->getType() != *I) | 
|  | 3686 | error("Parameter " +(*ArgI).V->getName()+ " is not of type '" + | 
|  | 3687 | (*I)->getDescription() + "'"); | 
|  | 3688 |  | 
|  | 3689 | if (I != E || (ArgI != ArgE && !FTy->isVarArg())) | 
|  | 3690 | error("Invalid number of parameters detected"); | 
|  | 3691 | } | 
|  | 3692 |  | 
|  | 3693 | // Create the call instruction | 
| Chris Lattner | cf3d061 | 2007-02-13 06:04:17 +0000 | [diff] [blame] | 3694 | CallInst *CI = new CallInst(V, &Args[0], Args.size()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3695 | CI->setTailCall($1); | 
| Reid Spencer | b7046c7 | 2007-01-29 05:41:34 +0000 | [diff] [blame] | 3696 | CI->setCallingConv(upgradeCallingConv($2)); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3697 | $$.I = CI; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3698 | } | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3699 | delete $3.PAT; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3700 | delete $6; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3701 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3702 | | MemoryInst { | 
|  | 3703 | $$ = $1; | 
|  | 3704 | } | 
|  | 3705 | ; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3706 |  | 
|  | 3707 |  | 
|  | 3708 | // IndexList - List of indices for GEP based instructions... | 
|  | 3709 | IndexList | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3710 | : ',' ValueRefList { $$ = $2; } | 
|  | 3711 | | /* empty */ { $$ = new std::vector<ValueInfo>(); } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3712 | ; | 
|  | 3713 |  | 
|  | 3714 | OptVolatile | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3715 | : VOLATILE { $$ = true; } | 
|  | 3716 | | /* empty */ { $$ = false; } | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3717 | ; | 
|  | 3718 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3719 | MemoryInst | 
|  | 3720 | : MALLOC Types OptCAlign { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3721 | const Type *Ty = $2.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3722 | $$.S.makeComposite($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3723 | $$.I = new MallocInst(Ty, 0, $3); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3724 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3725 | } | 
|  | 3726 | | MALLOC Types ',' UINT ValueRef OptCAlign { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3727 | const Type *Ty = $2.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3728 | $5.S.makeUnsigned(); | 
|  | 3729 | $$.S.makeComposite($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3730 | $$.I = new MallocInst(Ty, getVal($4.T, $5), $6); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3731 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3732 | } | 
|  | 3733 | | ALLOCA Types OptCAlign { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3734 | const Type *Ty = $2.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3735 | $$.S.makeComposite($2.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3736 | $$.I = new AllocaInst(Ty, 0, $3); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3737 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3738 | } | 
|  | 3739 | | ALLOCA Types ',' UINT ValueRef OptCAlign { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3740 | const Type *Ty = $2.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3741 | $5.S.makeUnsigned(); | 
|  | 3742 | $$.S.makeComposite($4.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3743 | $$.I = new AllocaInst(Ty, getVal($4.T, $5), $6); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3744 | delete $2.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3745 | } | 
|  | 3746 | | FREE ResolvedVal { | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3747 | const Type *PTy = $2.V->getType(); | 
|  | 3748 | if (!isa<PointerType>(PTy)) | 
|  | 3749 | error("Trying to free nonpointer type '" + PTy->getDescription() + "'"); | 
|  | 3750 | $$.I = new FreeInst($2.V); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3751 | $$.S.makeSignless(); | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3752 | } | 
|  | 3753 | | OptVolatile LOAD Types ValueRef { | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3754 | const Type* Ty = $3.PAT->get(); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3755 | $4.S.copy($3.S); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3756 | if (!isa<PointerType>(Ty)) | 
|  | 3757 | error("Can't load from nonpointer type: " + Ty->getDescription()); | 
|  | 3758 | if (!cast<PointerType>(Ty)->getElementType()->isFirstClassType()) | 
|  | 3759 | error("Can't load from pointer of non-first-class type: " + | 
|  | 3760 | Ty->getDescription()); | 
|  | 3761 | Value* tmpVal = getVal(Ty, $4); | 
|  | 3762 | $$.I = new LoadInst(tmpVal, "", $1); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3763 | $$.S.copy($3.S.get(0)); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3764 | delete $3.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3765 | } | 
|  | 3766 | | OptVolatile STORE ResolvedVal ',' Types ValueRef { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3767 | $6.S.copy($5.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3768 | const PointerType *PTy = dyn_cast<PointerType>($5.PAT->get()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3769 | if (!PTy) | 
|  | 3770 | error("Can't store to a nonpointer type: " + | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3771 | $5.PAT->get()->getDescription()); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3772 | const Type *ElTy = PTy->getElementType(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3773 | Value *StoreVal = $3.V; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3774 | Value* tmpVal = getVal(PTy, $6); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3775 | if (ElTy != $3.V->getType()) { | 
|  | 3776 | StoreVal = handleSRetFuncTypeMerge($3.V, ElTy); | 
|  | 3777 | if (!StoreVal) | 
|  | 3778 | error("Can't store '" + $3.V->getType()->getDescription() + | 
|  | 3779 | "' into space of type '" + ElTy->getDescription() + "'"); | 
|  | 3780 | else { | 
|  | 3781 | PTy = PointerType::get(StoreVal->getType()); | 
|  | 3782 | if (Constant *C = dyn_cast<Constant>(tmpVal)) | 
|  | 3783 | tmpVal = ConstantExpr::getBitCast(C, PTy); | 
|  | 3784 | else | 
|  | 3785 | tmpVal = new BitCastInst(tmpVal, PTy, "upgrd.cast", CurBB); | 
|  | 3786 | } | 
|  | 3787 | } | 
|  | 3788 | $$.I = new StoreInst(StoreVal, tmpVal, $1); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3789 | $$.S.makeSignless(); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3790 | delete $5.PAT; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3791 | } | 
|  | 3792 | | GETELEMENTPTR Types ValueRef IndexList { | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3793 | $3.S.copy($2.S); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3794 | const Type* Ty = $2.PAT->get(); | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3795 | if (!isa<PointerType>(Ty)) | 
|  | 3796 | error("getelementptr insn requires pointer operand"); | 
|  | 3797 |  | 
|  | 3798 | std::vector<Value*> VIndices; | 
|  | 3799 | upgradeGEPIndices(Ty, $4, VIndices); | 
|  | 3800 |  | 
|  | 3801 | Value* tmpVal = getVal(Ty, $3); | 
| Chris Lattner | 1bc3fa6 | 2007-02-12 22:58:38 +0000 | [diff] [blame] | 3802 | $$.I = new GetElementPtrInst(tmpVal, &VIndices[0], VIndices.size()); | 
| Reid Spencer | bb1fd57 | 2007-03-21 17:15:50 +0000 | [diff] [blame] | 3803 | ValueInfo VI; VI.V = tmpVal; VI.S.copy($2.S); | 
|  | 3804 | $$.S.copy(getElementSign(VI, VIndices)); | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3805 | delete $2.PAT; | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 3806 | delete $4; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3807 | }; | 
|  | 3808 |  | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3809 |  | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3810 | %% | 
|  | 3811 |  | 
|  | 3812 | int yyerror(const char *ErrorMsg) { | 
|  | 3813 | std::string where | 
|  | 3814 | = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename) | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3815 | + ":" + llvm::utostr((unsigned) Upgradelineno) + ": "; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3816 | std::string errMsg = where + "error: " + std::string(ErrorMsg); | 
|  | 3817 | if (yychar != YYEMPTY && yychar != 0) | 
|  | 3818 | errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) + | 
|  | 3819 | "'."; | 
| Reid Spencer | 71d2ec9 | 2006-12-31 06:02:26 +0000 | [diff] [blame] | 3820 | std::cerr << "llvm-upgrade: " << errMsg << '\n'; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3821 | std::cout << "llvm-upgrade: parse failed.\n"; | 
| Reid Spencer | e7c3c60 | 2006-11-30 06:36:44 +0000 | [diff] [blame] | 3822 | exit(1); | 
|  | 3823 | } | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 3824 |  | 
| Reid Spencer | 30d0c58 | 2007-01-15 00:26:18 +0000 | [diff] [blame] | 3825 | void warning(const std::string& ErrorMsg) { | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 3826 | std::string where | 
|  | 3827 | = std::string((CurFilename == "-") ? std::string("<stdin>") : CurFilename) | 
| Reid Spencer | ed96d1e | 2007-02-08 09:08:52 +0000 | [diff] [blame] | 3828 | + ":" + llvm::utostr((unsigned) Upgradelineno) + ": "; | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3829 | std::string errMsg = where + "warning: " + std::string(ErrorMsg); | 
|  | 3830 | if (yychar != YYEMPTY && yychar != 0) | 
|  | 3831 | errMsg += " while reading token '" + std::string(Upgradetext, Upgradeleng) + | 
|  | 3832 | "'."; | 
| Reid Spencer | 319a730 | 2007-01-05 17:20:02 +0000 | [diff] [blame] | 3833 | std::cerr << "llvm-upgrade: " << errMsg << '\n'; | 
|  | 3834 | } | 
| Reid Spencer | 950bf60 | 2007-01-26 08:19:09 +0000 | [diff] [blame] | 3835 |  | 
|  | 3836 | void error(const std::string& ErrorMsg, int LineNo) { | 
|  | 3837 | if (LineNo == -1) LineNo = Upgradelineno; | 
|  | 3838 | Upgradelineno = LineNo; | 
|  | 3839 | yyerror(ErrorMsg.c_str()); | 
|  | 3840 | } | 
|  | 3841 |  |