mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 23:32:27 +00:00
7596fd0774
of structure contents, counts of packed and array types, etc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32847 91177308-0d34-0410-b5e6-96231b3b80d8
268 lines
8.0 KiB
C++
268 lines
8.0 KiB
C++
//===-- ParserInternals.h - Definitions internal to the parser --*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file was developed by Reid Spencer and is distributed under
|
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This header file defines the variables that are shared between the lexer,
|
|
// the parser, and the main program.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef PARSER_INTERNALS_H
|
|
#define PARSER_INTERNALS_H
|
|
|
|
#include <llvm/ADT/StringExtras.h>
|
|
#include <string>
|
|
#include <istream>
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
// Global variables exported from the lexer...
|
|
|
|
extern std::string CurFileName;
|
|
extern std::string Textin;
|
|
extern int Upgradelineno;
|
|
extern std::istream* LexInput;
|
|
|
|
struct TypeInfo;
|
|
typedef std::vector<TypeInfo*> TypeList;
|
|
|
|
void UpgradeAssembly(
|
|
const std::string & infile, std::istream& in, std::ostream &out, bool debug,
|
|
bool addAttrs);
|
|
|
|
TypeInfo* ResolveType(TypeInfo*& Ty);
|
|
|
|
// Globals exported by the parser...
|
|
extern char* Upgradetext;
|
|
extern int Upgradeleng;
|
|
extern unsigned SizeOfPointer;
|
|
|
|
int yyerror(const char *ErrorMsg) ;
|
|
|
|
/// This enum is used to keep track of the original (1.9) type used to form
|
|
/// a type. These are needed for type upgrades and to determine how to upgrade
|
|
/// signed instructions with signless operands.
|
|
enum Types {
|
|
BoolTy, SByteTy, UByteTy, ShortTy, UShortTy, IntTy, UIntTy, LongTy, ULongTy,
|
|
FloatTy, DoubleTy, PointerTy, PackedTy, ArrayTy, StructTy, PackedStructTy,
|
|
OpaqueTy, VoidTy, LabelTy, FunctionTy, UnresolvedTy, UpRefTy
|
|
};
|
|
|
|
/// This type is used to keep track of the signedness of values. Instead
|
|
/// of creating llvm::Value directly, the parser will create ValueInfo which
|
|
/// associates a Value* with a Signedness indication.
|
|
struct ValueInfo {
|
|
std::string* val;
|
|
TypeInfo* type;
|
|
bool constant;
|
|
bool isConstant() const { return constant; }
|
|
inline void destroy();
|
|
};
|
|
|
|
/// This type is used to keep track of the signedness of the obsolete
|
|
/// integer types. Instead of creating an llvm::Type directly, the Lexer will
|
|
/// create instances of TypeInfo which retains the signedness indication so
|
|
/// it can be used by the parser for upgrade decisions.
|
|
/// For example if "uint" is encountered then the "first" field will be set
|
|
/// to "int32" and the "second" field will be set to "isUnsigned". If the
|
|
/// type is not obsolete then "second" will be set to "isSignless".
|
|
struct TypeInfo {
|
|
TypeInfo()
|
|
: newTy(0), oldTy(UnresolvedTy), elemTy(0), resultTy(0), elements(0),
|
|
nelems(0) {
|
|
}
|
|
|
|
TypeInfo(const char * newType, Types oldType)
|
|
: newTy(0), oldTy(oldType), elemTy(0), resultTy(0), elements(0), nelems(0) {
|
|
newTy = new std::string(newType);
|
|
}
|
|
|
|
TypeInfo(std::string *newType, Types oldType, TypeInfo* eTy = 0,
|
|
TypeInfo *rTy = 0)
|
|
: newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(rTy), elements(0),
|
|
nelems(0) {
|
|
}
|
|
|
|
TypeInfo(std::string *newType, Types oldType, TypeInfo *eTy, uint64_t elems)
|
|
: newTy(newType), oldTy(oldType), elemTy(eTy), resultTy(0), elements(0),
|
|
nelems(elems) {
|
|
}
|
|
|
|
TypeInfo(std::string *newType, Types oldType, TypeList* TL)
|
|
: newTy(newType), oldTy(oldType), elemTy(0), resultTy(0), elements(TL),
|
|
nelems(0) {
|
|
}
|
|
|
|
TypeInfo(std::string *newType, TypeInfo* resTy, TypeList* TL)
|
|
: newTy(newType), oldTy(FunctionTy), elemTy(0), resultTy(resTy),
|
|
elements(TL), nelems(0) {
|
|
}
|
|
|
|
TypeInfo(const TypeInfo& that)
|
|
: newTy(0), oldTy(that.oldTy), elemTy(0), resultTy(0), elements(0),
|
|
nelems(0) {
|
|
*this = that;
|
|
}
|
|
|
|
TypeInfo& operator=(const TypeInfo& that) {
|
|
oldTy = that.oldTy;
|
|
nelems = that.nelems;
|
|
if (that.newTy)
|
|
newTy = new std::string(*that.newTy);
|
|
if (that.elemTy)
|
|
elemTy = that.elemTy->clone();
|
|
if (that.resultTy)
|
|
resultTy = that.resultTy->clone();
|
|
if (that.elements) {
|
|
elements = new std::vector<TypeInfo*>(that.elements->size());
|
|
*elements = *that.elements;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
~TypeInfo() {
|
|
delete newTy; delete elemTy; delete resultTy; delete elements;
|
|
}
|
|
|
|
TypeInfo* clone() const {
|
|
return new TypeInfo(*this);
|
|
}
|
|
|
|
Types getElementTy() const {
|
|
if (elemTy) {
|
|
return elemTy->oldTy;
|
|
}
|
|
return UnresolvedTy;
|
|
}
|
|
|
|
const std::string& getNewTy() const { return *newTy; }
|
|
void setOldTy(Types Ty) { oldTy = Ty; }
|
|
|
|
TypeInfo* getResultType() const { return resultTy; }
|
|
TypeInfo* getElementType() const { return elemTy; }
|
|
|
|
TypeInfo* getPointerType() const {
|
|
std::string* ty = new std::string(*newTy + "*");
|
|
return new TypeInfo(ty, PointerTy, this->clone(), (TypeInfo*)0);
|
|
}
|
|
|
|
bool isUnresolved() const { return oldTy == UnresolvedTy; }
|
|
bool isUpReference() const { return oldTy == UpRefTy; }
|
|
bool isVoid() const { return oldTy == VoidTy; }
|
|
bool isBool() const { return oldTy == BoolTy; }
|
|
bool isSigned() const {
|
|
return oldTy == SByteTy || oldTy == ShortTy ||
|
|
oldTy == IntTy || oldTy == LongTy;
|
|
}
|
|
|
|
bool isUnsigned() const {
|
|
return oldTy == UByteTy || oldTy == UShortTy ||
|
|
oldTy == UIntTy || oldTy == ULongTy;
|
|
}
|
|
|
|
|
|
bool isSignless() const { return !isSigned() && !isUnsigned(); }
|
|
bool isInteger() const { return isSigned() || isUnsigned(); }
|
|
bool isIntegral() const { return oldTy == BoolTy || isInteger(); }
|
|
bool isFloatingPoint() const { return oldTy == DoubleTy || oldTy == FloatTy; }
|
|
bool isPacked() const { return oldTy == PackedTy; }
|
|
bool isPointer() const { return oldTy == PointerTy; }
|
|
bool isStruct() const { return oldTy == StructTy || oldTy == PackedStructTy; }
|
|
bool isArray() const { return oldTy == ArrayTy; }
|
|
bool isOther() const {
|
|
return !isPacked() && !isPointer() && !isFloatingPoint() && !isIntegral(); }
|
|
bool isFunction() const { return oldTy == FunctionTy; }
|
|
bool isComposite() const {
|
|
return isStruct() || isPointer() || isArray() || isPacked();
|
|
}
|
|
|
|
bool isAttributeCandidate() const {
|
|
return isIntegral() && getBitWidth() < 32;
|
|
}
|
|
|
|
unsigned getBitWidth() const {
|
|
switch (oldTy) {
|
|
default:
|
|
case LabelTy:
|
|
case VoidTy : return 0;
|
|
case BoolTy : return 1;
|
|
case SByteTy: case UByteTy : return 8;
|
|
case ShortTy: case UShortTy : return 16;
|
|
case IntTy: case UIntTy: case FloatTy: return 32;
|
|
case LongTy: case ULongTy: case DoubleTy : return 64;
|
|
case PointerTy: return SizeOfPointer; // global var
|
|
case PackedTy:
|
|
case ArrayTy:
|
|
return nelems * elemTy->getBitWidth();
|
|
case StructTy:
|
|
case PackedStructTy: {
|
|
uint64_t size = 0;
|
|
for (unsigned i = 0; i < elements->size(); i++) {
|
|
ResolveType((*elements)[i]);
|
|
size += (*elements)[i]->getBitWidth();
|
|
}
|
|
return size;
|
|
}
|
|
}
|
|
}
|
|
|
|
TypeInfo* getIndexedType(const ValueInfo& VI) {
|
|
if (isStruct()) {
|
|
if (VI.isConstant() && VI.type->isInteger()) {
|
|
size_t pos = VI.val->find(' ') + 1;
|
|
if (pos < VI.val->size()) {
|
|
uint64_t idx = atoi(VI.val->substr(pos).c_str());
|
|
return (*elements)[idx];
|
|
} else {
|
|
yyerror("Invalid value for constant integer");
|
|
return 0;
|
|
}
|
|
} else {
|
|
yyerror("Structure requires constant index");
|
|
return 0;
|
|
}
|
|
}
|
|
if (isArray() || isPacked() || isPointer())
|
|
return elemTy;
|
|
yyerror("Invalid type for getIndexedType");
|
|
return 0;
|
|
}
|
|
|
|
unsigned getNumStructElements() const {
|
|
return (elements ? elements->size() : 0);
|
|
}
|
|
|
|
TypeInfo* getElement(unsigned idx) {
|
|
if (elements)
|
|
if (idx < elements->size())
|
|
return (*elements)[idx];
|
|
return 0;
|
|
}
|
|
|
|
private:
|
|
std::string* newTy;
|
|
Types oldTy;
|
|
TypeInfo *elemTy;
|
|
TypeInfo *resultTy;
|
|
TypeList *elements;
|
|
uint64_t nelems;
|
|
};
|
|
|
|
/// This type is used to keep track of the signedness of constants.
|
|
struct ConstInfo {
|
|
std::string *cnst;
|
|
TypeInfo *type;
|
|
void destroy() { delete cnst; }
|
|
};
|
|
|
|
typedef std::vector<ValueInfo> ValueList;
|
|
|
|
inline void ValueInfo::destroy() { delete val; }
|
|
|
|
#endif
|