#include "llvm/SymbolTable.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <iostream>
#include <list>
/// this is a declaration, otherwise it is a definition.
static void ParseGlobalVariable(char *NameStr,GlobalValue::LinkageTypes Linkage,
bool isConstantGlobal, const Type *Ty,
- Constant *Initializer) {
+ Constant *Initializer, char *Section,
+ unsigned Align) {
+ if (Align != 0 && !isPowerOf2_32(Align))
+ ThrowException("Global alignment must be a power of two!");
+
if (isa<FunctionType>(Ty))
ThrowException("Cannot declare global vars of function type!");
GV->setInitializer(Initializer);
GV->setLinkage(Linkage);
GV->setConstant(isConstantGlobal);
+ GV->setAlignment(Align);
+ if (Section) {
+ free(Section);
+ GV->setSection(Section);
+ }
InsertValue(GV, CurModule.Values);
return;
}
if (isConstantGlobal)
EGV->setConstant(true);
EGV->setLinkage(Linkage);
+ EGV->setAlignment(Align);
+ if (Section) {
+ free(Section);
+ EGV->setSection(Section);
+ }
return;
}
GlobalVariable *GV =
new GlobalVariable(Ty, isConstantGlobal, Linkage, Initializer, Name,
CurModule.CurrentModule);
+ GV->setAlignment(Align);
+ if (Section) {
+ free(Section);
+ GV->setSection(Section);
+ }
InsertValue(GV, CurModule.Values);
}
Module *Result = ParserResult;
ParserResult = 0;
- if (ObsoleteVarArgs && NewVarArgs)
+ //Not all functions use vaarg, so make a second check for ObsoleteVarArgs
{
- std::cerr << "This file is corrupt in that it uses both new and old style varargs\n";
- abort();
+ Function* F;
+ if ((F = Result->getNamedFunction("llvm.va_start"))
+ && F->getFunctionType()->getNumParams() == 0)
+ ObsoleteVarArgs = true;
+ if((F = Result->getNamedFunction("llvm.va_copy"))
+ && F->getFunctionType()->getNumParams() == 1)
+ ObsoleteVarArgs = true;
}
+ if (ObsoleteVarArgs && NewVarArgs)
+ ThrowException("This file is corrupt: it uses both new and old style varargs");
+
if(ObsoleteVarArgs) {
if(Function* F = Result->getNamedFunction("llvm.va_start")) {
- assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
+ if (F->arg_size() != 0)
+ ThrowException("Obsolete va_start takes 0 argument!");
//foo = va_start()
// ->
const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = Result->getOrInsertFunction("llvm.va_start",
- RetTy, ArgTyPtr, 0);
+ RetTy, ArgTyPtr, (Type *)0);
while (!F->use_empty()) {
CallInst* CI = cast<CallInst>(F->use_back());
}
if(Function* F = Result->getNamedFunction("llvm.va_end")) {
- assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!");
+ if(F->arg_size() != 1)
+ ThrowException("Obsolete va_end takes 1 argument!");
+
//vaend foo
// ->
//bar = alloca 1 of typeof(foo)
const Type* ArgTy = F->getFunctionType()->getParamType(0);
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = Result->getOrInsertFunction("llvm.va_end",
- RetTy, ArgTyPtr, 0);
+ RetTy, ArgTyPtr, (Type *)0);
while (!F->use_empty()) {
CallInst* CI = cast<CallInst>(F->use_back());
}
if(Function* F = Result->getNamedFunction("llvm.va_copy")) {
- assert(F->arg_size() == 1 && "Obsolete va_copy takes 1 argument!");
+ if(F->arg_size() != 1)
+ ThrowException("Obsolete va_copy takes 1 argument!");
//foo = vacopy(bar)
// ->
//a = alloca 1 of typeof(foo)
- //vacopy(a, bar)
+ //b = alloca 1 of typeof(foo)
+ //store bar -> b
+ //vacopy(a, b)
//foo = load a
const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
const Type* ArgTy = F->getFunctionType()->getReturnType();
const Type* ArgTyPtr = PointerType::get(ArgTy);
Function* NF = Result->getOrInsertFunction("llvm.va_copy",
- RetTy, ArgTyPtr, ArgTy, 0);
+ RetTy, ArgTyPtr, ArgTyPtr,
+ (Type *)0);
while (!F->use_empty()) {
CallInst* CI = cast<CallInst>(F->use_back());
AllocaInst* a = new AllocaInst(ArgTy, 0, "vacopy.fix.1", CI);
- new CallInst(NF, a, CI->getOperand(1), "", CI);
- Value* foo = new LoadInst(a, "vacopy.fix.2", CI);
+ AllocaInst* b = new AllocaInst(ArgTy, 0, "vacopy.fix.2", CI);
+ new StoreInst(CI->getOperand(1), b, CI);
+ new CallInst(NF, a, b, "", CI);
+ Value* foo = new LoadInst(a, "vacopy.fix.3", CI);
CI->replaceAllUsesWith(foo);
CI->getParent()->getInstList().erase(CI);
}
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
%type <StrVal> Name OptName OptAssign
-
+%type <UIntVal> OptAlign OptCAlign
+%type <StrVal> OptSection OptCSection SectionString
%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
-%token DECLARE GLOBAL CONSTANT VOLATILE
+%token DECLARE GLOBAL CONSTANT SECTION VOLATILE
%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
-%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG
+%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
%token DEPLIBS CALL TAIL
%token CC_TOK CCC_TOK FASTCC_TOK COLDCC_TOK
%type <UIntVal> OptCallingConv
$$ = $2;
};
+// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
+// a comma before it.
+OptAlign : /*empty*/ { $$ = 0; } |
+ ALIGN EUINT64VAL { $$ = $2; };
+OptCAlign : /*empty*/ { $$ = 0; } |
+ ',' ALIGN EUINT64VAL { $$ = $3; };
+
+SectionString : SECTION STRINGCONSTANT {
+ for (unsigned i = 0, e = strlen($2); i != e; ++i)
+ if ($2[i] == '"' || $2[i] == '\\')
+ ThrowException("Invalid character in section name!");
+ $$ = $2;
+};
+
+OptSection : /*empty*/ { $$ = 0; } |
+ SectionString { $$ = $1; };
+OptCSection : /*empty*/ { $$ = 0; } |
+ ',' SectionString { $$ = $2; };
+
+
//===----------------------------------------------------------------------===//
// Types includes all predefined types... except void, because it can only be
// used in specific contexts (function returning void for example). To have
}
| '<' EUINT64VAL 'x' UpRTypes '>' { // Packed array type?
const llvm::Type* ElemTy = $4->get();
- if ((unsigned)$2 != $2) {
+ if ((unsigned)$2 != $2)
ThrowException("Unsigned result not equal to signed result");
- }
- if(!ElemTy->isPrimitiveType()) {
+ if (!ElemTy->isPrimitiveType())
ThrowException("Elemental type of a PackedType must be primitive");
- }
+ if (!isPowerOf2_32($2))
+ ThrowException("Vector length should be a power of 2!");
$$ = new PATypeHolder(HandleUpRefs(PackedType::get(*$4, (unsigned)$2)));
delete $4;
}
}
| ConstPool FunctionProto { // Function prototypes can be in const pool
}
- | ConstPool OptAssign OptLinkage GlobalType ConstVal {
+ | ConstPool OptAssign OptLinkage GlobalType ConstVal OptCSection OptCAlign {
if ($5 == 0) ThrowException("Global value initializer is not a constant!");
- ParseGlobalVariable($2, $3, $4, $5->getType(), $5);
+ ParseGlobalVariable($2, $3, $4, $5->getType(), $5, $6, $7);
}
- | ConstPool OptAssign EXTERNAL GlobalType Types {
- ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0);
+ | ConstPool OptAssign EXTERNAL GlobalType Types OptCSection OptCAlign {
+ ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0, $6, $7);
delete $5;
}
| ConstPool TARGET TargetDefinition {
$$ = 0;
};
-FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')' {
+FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
+ OptSection OptAlign {
UnEscapeLexed($3);
std::string FunctionName($3);
free($3); // Free strdup'd memory!
if (!(*$2)->isFirstClassType() && *$2 != Type::VoidTy)
ThrowException("LLVM functions cannot return aggregate types!");
+ if ($8 != 0 && !isPowerOf2_32($8))
+ ThrowException("Function alignment must be a power of two!");
std::vector<const Type*> ParamTypeList;
if ($5) { // If there are arguments...
CurFun.FunctionStart(Fn);
Fn->setCallingConv($1);
+ Fn->setAlignment($8);
+ if ($7) {
+ Fn->setSection($7);
+ free($7);
+ }
// Add all of the arguments we parsed to the function...
if ($5) { // Is null if empty...
ObsoleteVarArgs = true;
const Type* ArgTy = $2->getType();
Function* NF = CurModule.CurrentModule->
- getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0);
//b = vaarg a, t ->
//foo = alloca 1 of t
ObsoleteVarArgs = true;
const Type* ArgTy = $2->getType();
Function* NF = CurModule.CurrentModule->
- getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, 0);
+ getOrInsertFunction("llvm.va_copy", ArgTy, ArgTy, (Type *)0);
//b = vanext a, t ->
//foo = alloca 1 of t
-MemoryInst : MALLOC Types {
- $$ = new MallocInst(*$2);
+MemoryInst : MALLOC Types OptCAlign {
+ if ($3 != 0 && !isPowerOf2_32($3))
+ ThrowException("Alignment amount '" + utostr($3) +
+ "' is not a power of 2!");
+ $$ = new MallocInst(*$2, 0, $3);
delete $2;
}
- | MALLOC Types ',' UINT ValueRef {
- $$ = new MallocInst(*$2, getVal($4, $5));
+ | MALLOC Types ',' UINT ValueRef OptCAlign {
+ if ($6 != 0 && !isPowerOf2_32($6))
+ ThrowException("Alignment amount '" + utostr($6) +
+ "' is not a power of 2!");
+ $$ = new MallocInst(*$2, getVal($4, $5), $6);
delete $2;
}
- | ALLOCA Types {
- $$ = new AllocaInst(*$2);
+ | ALLOCA Types OptCAlign {
+ if ($3 != 0 && !isPowerOf2_32($3))
+ ThrowException("Alignment amount '" + utostr($3) +
+ "' is not a power of 2!");
+ $$ = new AllocaInst(*$2, 0, $3);
delete $2;
}
- | ALLOCA Types ',' UINT ValueRef {
- $$ = new AllocaInst(*$2, getVal($4, $5));
+ | ALLOCA Types ',' UINT ValueRef OptCAlign {
+ if ($6 != 0 && !isPowerOf2_32($6))
+ ThrowException("Alignment amount '" + utostr($6) +
+ "' is not a power of 2!");
+ $$ = new AllocaInst(*$2, getVal($4, $5), $6);
delete $2;
}
| FREE ResolvedVal {