1 //===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
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.
8 //===----------------------------------------------------------------------===//
10 // This header file defines the various variables that are shared among the
11 // different components of the parser...
13 //===----------------------------------------------------------------------===//
15 #ifndef PARSER_INTERNALS_H
16 #define PARSER_INTERNALS_H
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Function.h"
21 #include "llvm/Instructions.h"
22 #include "llvm/Assembly/Parser.h"
23 #include "llvm/ADT/StringExtras.h"
26 // Global variables exported from the lexer...
28 extern int llvmAsmlineno; /// FIXME: Not threading friendly
29 extern llvm::ParseError* TheParseError; /// FIXME: Not threading friendly
31 extern std::string &llvmAsmTextin;
33 // functions exported from the lexer
34 void set_scan_file(FILE * F);
35 void set_scan_string (const char * str);
37 // Globals exported by the parser...
38 extern char* llvmAsmtext;
39 extern int llvmAsmleng;
43 // Globals exported by the parser...
44 extern std::string CurFilename; /// FIXME: Not threading friendly
47 Module *RunVMAsmParser(const std::string &Filename, FILE *F);
49 // Parse a string directly
50 Module *RunVMAsmParser(const char * AsmString, Module * M);
53 // UnEscapeLexed - Run through the specified buffer and change \xx codes to the
54 // appropriate character. If AllowNull is set to false, a \00 value will cause
57 // If AllowNull is set to true, the return value of the function points to the
58 // last character of the string in memory.
60 char *UnEscapeLexed(char *Buffer, bool AllowNull = false);
63 // ThrowException - Wrapper around the ParseException class that automatically
64 // fills in file line number and column number and options info.
66 // This also helps me because I keep typing 'throw new ParseException' instead
67 // of just 'throw ParseException'... sigh...
69 extern void GenerateError(const std::string &message, int LineNo = -1);
71 /// InlineAsmDescriptor - This is a simple class that holds info about inline
72 /// asm blocks, for use by ValID.
73 struct InlineAsmDescriptor {
74 std::string AsmString, Constraints;
77 InlineAsmDescriptor(const std::string &as, const std::string &c, bool HSE)
78 : AsmString(as), Constraints(c), HasSideEffects(HSE) {}
82 // ValID - Represents a reference of a definition of some sort. This may either
83 // be a numeric reference or a symbolic (%var) reference. This is just a
84 // discriminated union.
86 // Note that I can't implement this class in a straight forward manner with
87 // constructors and stuff because it goes in a union.
91 NumberVal, NameVal, ConstSIntVal, ConstUIntVal, ConstFPVal, ConstNullVal,
92 ConstUndefVal, ConstZeroVal, ConstantVal, InlineAsmVal
96 int Num; // If it's a numeric reference
97 char *Name; // If it's a named reference. Memory must be free'd.
98 int64_t ConstPool64; // Constant pool reference. This is the value
99 uint64_t UConstPool64;// Unsigned constant pool reference.
100 double ConstPoolFP; // Floating point constant pool reference
101 Constant *ConstantValue; // Fully resolved constant for ConstantVal case.
102 InlineAsmDescriptor *IAD;
105 static ValID create(int Num) {
106 ValID D; D.Type = NumberVal; D.Num = Num; return D;
109 static ValID create(char *Name) {
110 ValID D; D.Type = NameVal; D.Name = Name; return D;
113 static ValID create(int64_t Val) {
114 ValID D; D.Type = ConstSIntVal; D.ConstPool64 = Val; return D;
117 static ValID create(uint64_t Val) {
118 ValID D; D.Type = ConstUIntVal; D.UConstPool64 = Val; return D;
121 static ValID create(double Val) {
122 ValID D; D.Type = ConstFPVal; D.ConstPoolFP = Val; return D;
125 static ValID createNull() {
126 ValID D; D.Type = ConstNullVal; return D;
129 static ValID createUndef() {
130 ValID D; D.Type = ConstUndefVal; return D;
133 static ValID createZeroInit() {
134 ValID D; D.Type = ConstZeroVal; return D;
137 static ValID create(Constant *Val) {
138 ValID D; D.Type = ConstantVal; D.ConstantValue = Val; return D;
141 static ValID createInlineAsm(const std::string &AsmString,
142 const std::string &Constraints,
143 bool HasSideEffects) {
145 D.Type = InlineAsmVal;
146 D.IAD = new InlineAsmDescriptor(AsmString, Constraints, HasSideEffects);
150 inline void destroy() const {
152 free(Name); // Free this strdup'd memory.
153 else if (Type == InlineAsmVal)
157 inline ValID copy() const {
158 if (Type != NameVal) return *this;
159 ValID Result = *this;
160 Result.Name = strdup(Name);
164 inline std::string getName() const {
166 case NumberVal : return std::string("#") + itostr(Num);
167 case NameVal : return Name;
168 case ConstFPVal : return ftostr(ConstPoolFP);
169 case ConstNullVal : return "null";
170 case ConstUndefVal : return "undef";
171 case ConstZeroVal : return "zeroinitializer";
173 case ConstSIntVal : return std::string("%") + itostr(ConstPool64);
175 if (ConstantValue == ConstantBool::getTrue()) return "true";
176 if (ConstantValue == ConstantBool::getFalse()) return "false";
177 return "<constant expression>";
179 assert(0 && "Unknown value!");
185 bool operator<(const ValID &V) const {
186 if (Type != V.Type) return Type < V.Type;
188 case NumberVal: return Num < V.Num;
189 case NameVal: return strcmp(Name, V.Name) < 0;
190 case ConstSIntVal: return ConstPool64 < V.ConstPool64;
191 case ConstUIntVal: return UConstPool64 < V.UConstPool64;
192 case ConstFPVal: return ConstPoolFP < V.ConstPoolFP;
193 case ConstNullVal: return false;
194 case ConstUndefVal: return false;
195 case ConstZeroVal: return false;
196 case ConstantVal: return ConstantValue < V.ConstantValue;
197 default: assert(0 && "Unknown value type!"); return false;
202 } // End llvm namespace
204 // This structure is used to keep track of obsolete opcodes. The lexer will
205 // retain the ability to parse obsolete opcode mnemonics. In this case it will
206 // set "obsolete" to true and the opcode will be the replacement opcode. For
207 // example if "rem" is encountered then opcode will be set to "urem" and the
208 // "obsolete" flag will be true. If the opcode is not obsolete then "obsolete"
210 template <class Enum>
215 typedef OpcodeInfo<llvm::Instruction::BinaryOps> BinaryOpInfo;
216 typedef OpcodeInfo<llvm::Instruction::TermOps> TermOpInfo;
217 typedef OpcodeInfo<llvm::Instruction::MemoryOps> MemOpInfo;
218 typedef OpcodeInfo<llvm::Instruction::CastOps> CastOpInfo;
219 typedef OpcodeInfo<llvm::Instruction::OtherOps> OtherOpInfo;
221 /// This enumeration is used to indicate if a type is signed, signless or
222 /// unsigned. It is used for backwards compatibility with assembly code that
223 /// pre-dates the signless types conversion.
230 /// This structure is used to keep track of the signedness of the obsolete
231 /// integer types. Instead of creating an llvm::Type directly, the Lexer will
232 /// create instances of TypeInfo which retains the signedness indication so
233 /// it can be used by the parser for upgrade decisions.
234 /// For example if "uint" is encountered then the type will be set "int32"
235 /// and the "signedness" will be "isUnsigned". If the type is not obsolete
236 /// then "signedness" will be "isSignless".
238 llvm::PATypeHolder *type;
239 Signedness signedness;
243 std::vector<llvm::Value*> valuelist;
244 std::vector<Signedness> signlist;