//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Streams.h"
+#include "llvm/ParamAttrsList.h"
#include <algorithm>
#include <list>
#include <map>
// Check to make sure that "Ty" is an integral type, and that our
// value will fit into the specified type...
case ValID::ConstSIntVal: // Is it a constant pool reference??
- if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+ if (!isa<IntegerType>(Ty) ||
+ !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
GenerateError("Signed integral constant '" +
itostr(D.ConstPool64) + "' is invalid for type '" +
Ty->getDescription() + "'");
return ConstantInt::get(Ty, D.ConstPool64, true);
case ValID::ConstUIntVal: // Is it an unsigned const pool reference?
- if (!ConstantInt::isValueValidForType(Ty, D.UConstPool64)) {
- if (!ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
- GenerateError("Integral constant '" + utostr(D.UConstPool64) +
- "' is invalid or out of range");
- return 0;
- } else { // This is really a signed reference. Transmogrify.
- return ConstantInt::get(Ty, D.ConstPool64, true);
- }
- } else {
+ if (isa<IntegerType>(Ty) &&
+ ConstantInt::isValueValidForType(Ty, D.UConstPool64))
return ConstantInt::get(Ty, D.UConstPool64);
+
+ if (!isa<IntegerType>(Ty) ||
+ !ConstantInt::isValueValidForType(Ty, D.ConstPool64)) {
+ GenerateError("Integral constant '" + utostr(D.UConstPool64) +
+ "' is invalid or out of range for type '" +
+ Ty->getDescription() + "'");
+ return 0;
}
+ // This is really a signed reference. Transmogrify.
+ return ConstantInt::get(Ty, D.ConstPool64, true);
case ValID::ConstFPVal: // Is it a floating point const pool reference?
- if (!ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) {
+ if (!Ty->isFloatingPoint() ||
+ !ConstantFP::isValueValidForType(Ty, *D.ConstPoolFP)) {
GenerateError("FP constant invalid for type");
return 0;
}
if (const FunctionType *FTy = dyn_cast<FunctionType>(ElTy))
V = new Function(FTy, GlobalValue::ExternalLinkage);
else
- V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage);
+ V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage, 0, "",
+ (Module*)0, false, PTy->getAddressSpace());
break;
}
default:
} if (ID.Type == ValID::LocalName) {
std::string Name = ID.getName();
Value *N = CurFun.CurrentFunction->getValueSymbolTable().lookup(Name);
- if (N)
+ if (N) {
if (N->getType()->getTypeID() == Type::LabelTyID)
BB = cast<BasicBlock>(N);
else
GenerateError("Reference to label '" + Name + "' is actually of type '"+
N->getType()->getDescription() + "'");
+ }
} else if (ID.Type == ValID::LocalID) {
if (ID.Num < CurFun.NextValNum && ID.Num < CurFun.Values.size()) {
if (CurFun.Values[ID.Num]->getType()->getTypeID() == Type::LabelTyID)
GlobalValue::LinkageTypes Linkage,
GlobalValue::VisibilityTypes Visibility,
bool isConstantGlobal, const Type *Ty,
- Constant *Initializer, bool IsThreadLocal) {
+ Constant *Initializer, bool IsThreadLocal,
+ unsigned AddressSpace = 0) {
if (isa<FunctionType>(Ty)) {
GenerateError("Cannot declare global vars of function type");
return 0;
}
- const PointerType *PTy = PointerType::get(Ty);
+ const PointerType *PTy = PointerType::get(Ty, AddressSpace);
std::string Name;
if (NameStr) {
// Otherwise there is no existing GV to use, create one now.
GlobalVariable *GV =
new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
- CurModule.CurrentModule, IsThreadLocal);
+ CurModule.CurrentModule, IsThreadLocal, AddressSpace);
GV->setVisibility(Visibility);
InsertValue(GV, CurModule.Values);
return GV;
llvm::GlobalValue::LinkageTypes Linkage;
llvm::GlobalValue::VisibilityTypes Visibility;
- uint16_t ParamAttrs;
+ llvm::ParameterAttributes ParamAttrs;
llvm::APInt *APIntVal;
int64_t SInt64Val;
uint64_t UInt64Val;
// ValueRef - Unresolved reference to a definition or BB
%type <ValIDVal> ValueRef ConstValueRef SymbolicValueRef
%type <ValueVal> ResolvedVal // <type> <valref> pair
+%type <ValueList> ReturnedVal
// Tokens and types for handling constant integer values
//
// ESINT64VAL - A negative number within long long range
%token<StrVal> STRINGCONSTANT ATSTRINGCONSTANT PCTSTRINGCONSTANT
%type <StrVal> LocalName OptLocalName OptLocalAssign
%type <StrVal> GlobalName OptGlobalAssign GlobalAssign
-%type <StrVal> OptSection SectionString
+%type <StrVal> OptSection SectionString OptGC
-%type <UIntVal> OptAlign OptCAlign
+%type <UIntVal> OptAlign OptCAlign OptAddrSpace
%token ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
%token DECLARE DEFINE GLOBAL CONSTANT SECTION ALIAS VOLATILE THREAD_LOCAL
%token TO DOTDOTDOT NULL_TOK UNDEF INTERNAL LINKONCE WEAK APPENDING
%token DLLIMPORT DLLEXPORT EXTERN_WEAK
-%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN
+%token OPAQUE EXTERNAL TARGET TRIPLE ALIGN ADDRSPACE
%token DEPLIBS CALL TAIL ASM_TOK MODULE SIDEEFFECT
%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
%token DATALAYOUT
// Other Operators
%token <OtherOpVal> PHI_TOK SELECT VAARG
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
+%token <OtherOpVal> GETRESULT
// Function Attributes
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
-%token READNONE READONLY
+%token READNONE READONLY GC
// Visibility Styles
%token DEFAULT HIDDEN PROTECTED
LocalName : LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
OptLocalName : LocalName | /*empty*/ { $$ = 0; };
+OptAddrSpace : ADDRSPACE '(' EUINT64VAL ')' { $$=$3; }
+ | /*empty*/ { $$=0; };
+
/// OptLocalAssign - Value producing statements have an optional assignment
/// component.
OptLocalAssign : LocalName '=' {
| NOALIAS { $$ = ParamAttr::NoAlias; }
| BYVAL { $$ = ParamAttr::ByVal; }
| NEST { $$ = ParamAttr::Nest; }
+ | ALIGN EUINT64VAL { $$ =
+ ParamAttr::constructAlignmentFromInt($2); }
;
OptParamAttrs : /* empty */ { $$ = ParamAttr::None; }
}
;
+OptGC : /* empty */ { $$ = 0; }
+ | GC STRINGCONSTANT {
+ $$ = $2;
+ }
+ ;
+
// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
// a comma before it.
OptAlign : /*empty*/ { $$ = 0; } |
};
+
SectionString : SECTION STRINGCONSTANT {
for (unsigned i = 0, e = $2->length(); i != e; ++i)
if ((*$2)[i] == '"' || (*$2)[i] == '\\')
$$ = new PATypeHolder($1);
CHECK_FOR_ERROR
}
- | Types '*' { // Pointer type?
+ | Types OptAddrSpace '*' { // Pointer type?
if (*$1 == Type::LabelTy)
GEN_ERROR("Cannot form a pointer to a basic block");
- $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1)));
+ $$ = new PATypeHolder(HandleUpRefs(PointerType::get(*$1, $2)));
delete $1;
CHECK_FOR_ERROR
}
| Types '(' ArgTypeListI ')' OptFuncAttrs {
// Allow but ignore attributes on function types; this permits auto-upgrade.
// FIXME: remove in LLVM 3.0.
+ const Type* RetTy = *$1;
+ if (!(RetTy->isFirstClassType() || RetTy == Type::VoidTy ||
+ isa<OpaqueType>(RetTy)))
+ GEN_ERROR("LLVM Functions cannot return aggregates");
+
std::vector<const Type*> Params;
TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
for (; I != E; ++I ) {
const Type *Ty = I->Ty->get();
Params.push_back(Ty);
}
+
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
- FunctionType *FT = FunctionType::get(*$1, Params, isVarArg);
+ for (unsigned i = 0; i != Params.size(); ++i)
+ if (!(Params[i]->isFirstClassType() || isa<OpaqueType>(Params[i])))
+ GEN_ERROR("Function arguments must be value types!");
+
+ CHECK_FOR_ERROR
+
+ FunctionType *FT = FunctionType::get(RetTy, Params, isVarArg);
delete $3; // Delete the argument list
delete $1; // Delete the return type handle
$$ = new PATypeHolder(HandleUpRefs(FT));
const Type* Ty = I->Ty->get();
Params.push_back(Ty);
}
+
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
+ for (unsigned i = 0; i != Params.size(); ++i)
+ if (!(Params[i]->isFirstClassType() || isa<OpaqueType>(Params[i])))
+ GEN_ERROR("Function arguments must be value types!");
+
+ CHECK_FOR_ERROR
+
FunctionType *FT = FunctionType::get($1, Params, isVarArg);
delete $3; // Delete the argument list
$$ = new PATypeHolder(HandleUpRefs(FT));
: Types {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
- if (!(*$1)->isFirstClassType())
+ if (!(*$1)->isFirstClassType() && !isa<StructType>($1->get()))
GEN_ERROR("LLVM functions cannot return aggregate types");
$$ = $1;
}
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
const PointerType *Ty = dyn_cast<PointerType>($1->get());
if (Ty == 0)
- GEN_ERROR("Global const reference must be a pointer type");
+ GEN_ERROR("Global const reference must be a pointer type " + (*$1)->getDescription());
// ConstExprs can exist in the body of a function, thus creating
// GlobalValues whenever they refer to a variable. Because we are in
}
CHECK_FOR_ERROR
}
- | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal {
+ | OptGlobalAssign GVVisibilityStyle ThreadLocal GlobalType ConstVal
+ OptAddrSpace {
/* "Externally Visible" Linkage */
if ($5 == 0)
GEN_ERROR("Global value initializer is not a constant");
CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage,
- $2, $4, $5->getType(), $5, $3);
+ $2, $4, $5->getType(), $5, $3, $6);
CHECK_FOR_ERROR
} GlobalVarAttributes {
CurGV = 0;
}
| OptGlobalAssign GVInternalLinkage GVVisibilityStyle ThreadLocal GlobalType
- ConstVal {
+ ConstVal OptAddrSpace {
if ($6 == 0)
GEN_ERROR("Global value initializer is not a constant");
- CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4);
+ CurGV = ParseGlobalVariable($1, $2, $3, $5, $6->getType(), $6, $4, $7);
CHECK_FOR_ERROR
} GlobalVarAttributes {
CurGV = 0;
}
| OptGlobalAssign GVExternalLinkage GVVisibilityStyle ThreadLocal GlobalType
- Types {
+ Types OptAddrSpace {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$6)->getDescription());
- CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4);
+ CurGV = ParseGlobalVariable($1, $2, $3, $5, *$6, 0, $4, $7);
CHECK_FOR_ERROR
delete $6;
} GlobalVarAttributes {
};
FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
- OptFuncAttrs OptSection OptAlign {
+ OptFuncAttrs OptSection OptAlign OptGC {
std::string FunctionName(*$3);
delete $3; // Free strdup'd memory!
PAL = ParamAttrsList::get(Attrs);
FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg);
- const PointerType *PFT = PointerType::get(FT);
+ const PointerType *PFT = PointerType::getUnqual(FT);
delete $2;
ValID ID;
Fn->setSection(*$8);
delete $8;
}
+ if ($10) {
+ Fn->setCollector($10->c_str());
+ delete $10;
+ }
// Add all of the arguments we parsed to the function...
if ($5) { // Is null if empty...
}
;
+ReturnedVal : ResolvedVal {
+ $$ = new std::vector<Value *>();
+ $$->push_back($1);
+ CHECK_FOR_ERROR
+ }
+ | ReturnedVal ',' ResolvedVal {
+ ($$=$1)->push_back($3);
+ CHECK_FOR_ERROR
+ };
+
BasicBlockList : BasicBlockList BasicBlock {
$$ = $1;
CHECK_FOR_ERROR
};
-BBTerminatorInst : RET ResolvedVal { // Return with a result...
- $$ = new ReturnInst($2);
+BBTerminatorInst :
+ RET ReturnedVal { // Return with a result...
+ ValueList &VL = *$2;
+ assert(!VL.empty() && "Invalid ret operands!");
+ $$ = new ReturnInst(&VL[0], VL.size());
+ delete $2;
CHECK_FOR_ERROR
}
| RET VOID { // Return with no result...
ParamTypes.push_back(Ty);
}
Ty = FunctionType::get($3->get(), ParamTypes, false);
- PFTy = PointerType::get(Ty);
+ PFTy = PointerType::getUnqual(Ty);
}
delete $3;
if (Ty->isVarArg()) {
if (I == E)
- for (; ArgI != ArgE; ++ArgI)
+ for (; ArgI != ArgE; ++ArgI, ++index) {
Args.push_back(ArgI->Val); // push the remaining varargs
+ if (ArgI->Attrs != ParamAttr::None) {
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = index;
+ PAWI.attrs = ArgI->Attrs;
+ Attrs.push_back(PAWI);
+ }
+ }
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
ParamTypes.push_back(Ty);
}
Ty = FunctionType::get($3->get(), ParamTypes, false);
- PFTy = PointerType::get(Ty);
+ PFTy = PointerType::getUnqual(Ty);
}
Value *V = getVal(PFTy, $4); // Get the function we're calling...
}
if (Ty->isVarArg()) {
if (I == E)
- for (; ArgI != ArgE; ++ArgI)
+ for (; ArgI != ArgE; ++ArgI, ++index) {
Args.push_back(ArgI->Val); // push the remaining varargs
+ if (ArgI->Attrs != ParamAttr::None) {
+ ParamAttrsWithIndex PAWI;
+ PAWI.index = index;
+ PAWI.attrs = ArgI->Attrs;
+ Attrs.push_back(PAWI);
+ }
+ }
} else if (I != E || ArgI != ArgE)
GEN_ERROR("Invalid number of parameters detected");
}
$$ = new StoreInst($3, tmpVal, $1, $7);
delete $5;
}
+| GETRESULT Types SymbolicValueRef ',' EUINT64VAL {
+ Value *TmpVal = getVal($2->get(), $3);
+ if (!GetResultInst::isValidOperands(TmpVal, $5))
+ GEN_ERROR("Invalid getresult operands");
+ $$ = new GetResultInst(TmpVal, $5);
+ delete $2;
+ CHECK_FOR_ERROR
+ }
| GETELEMENTPTR Types ValueRef IndexList {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());