static Value *lookupInSymbolTable(const Type *Ty, const std::string &Name) {
SymbolTable &SymTab =
- inFunctionScope() ? CurFun.CurrentFunction->getSymbolTable() :
- CurModule.CurrentModule->getSymbolTable();
+ inFunctionScope() ? CurFun.CurrentFunction->getValueSymbolTable() :
+ CurModule.CurrentModule->getValueSymbolTable();
return SymTab.lookup(Ty, Name);
}
case ValID::NameVal: // Is it a named definition?
Name = ID.Name;
if (Value *N = CurFun.CurrentFunction->
- getSymbolTable().lookup(Type::LabelTy, Name))
+ getValueSymbolTable().lookup(Type::LabelTy, Name))
BB = cast<BasicBlock>(N);
break;
}
}
assert(inFunctionScope() && "Must be in function scope!");
- SymbolTable &ST = CurFun.CurrentFunction->getSymbolTable();
+ SymbolTable &ST = CurFun.CurrentFunction->getValueSymbolTable();
if (ST.lookup(V->getType(), Name)) {
- GenerateError("Redefinition of value named '" + Name + "' in the '" +
- V->getType()->getDescription() + "' type plane!");
+ GenerateError("Redefinition of value '" + Name + "' of type '" +
+ V->getType()->getDescription() + "'!");
return;
}
}
// If this global has a name, check to see if there is already a definition
- // of this global in the module. If so, merge as appropriate. Note that
- // this is really just a hack around problems in the CFE. :(
+ // of this global in the module. If so, it is an error.
if (!Name.empty()) {
// We are a simple redefinition of a value, check to see if it is defined
// the same as the old one.
- if (GlobalVariable *EGV =
- CurModule.CurrentModule->getGlobalVariable(Name, Ty)) {
- // We are allowed to redefine a global variable in two circumstances:
- // 1. If at least one of the globals is uninitialized or
- // 2. If both initializers have the same value.
- //
- if (!EGV->hasInitializer() || !Initializer ||
- EGV->getInitializer() == Initializer) {
-
- // Make sure the existing global version gets the initializer! Make
- // sure that it also gets marked const if the new version is.
- if (Initializer && !EGV->hasInitializer())
- EGV->setInitializer(Initializer);
- if (isConstantGlobal)
- EGV->setConstant(true);
- EGV->setLinkage(Linkage);
- return EGV;
- }
-
+ if (CurModule.CurrentModule->getGlobalVariable(Name, Ty)) {
GenerateError("Redefinition of global variable named '" + Name +
- "' in the '" + Ty->getDescription() + "' type plane!");
+ "' of type '" + Ty->getDescription() + "'!");
return 0;
}
}
if (Existing == T) return true; // Yes, it's equal.
// Any other kind of (non-equivalent) redefinition is an error.
- GenerateError("Redefinition of type named '" + Name + "' in the '" +
- T->getDescription() + "' type plane!");
+ GenerateError("Redefinition of type named '" + Name + "' of type '" +
+ T->getDescription() + "'!");
}
return false;
%type <ValueList> IndexList // For GEP indices
%type <TypeList> TypeListI
%type <TypeWithAttrsList> ArgTypeList ArgTypeListI
-%type <TypeWithAttrs> ArgType ResultType
+%type <TypeWithAttrs> ArgType
%type <JumpTable> JumpTable
%type <BoolVal> GlobalType // GLOBAL or CONSTANT?
%type <BoolVal> OptVolatile // 'volatile' or not
%token <FPVal> FPVAL // Float or Double constant
// Built in types...
-%type <TypeVal> Types
+%type <TypeVal> Types ResultTypes
%type <PrimType> IntType FPType PrimType // Classifications
%token <PrimType> VOID BOOL INT8 INT16 INT32 INT64
%token <PrimType> FLOAT DOUBLE LABEL
%token X86_STDCALLCC_TOK X86_FASTCALLCC_TOK
%token DATALAYOUT
%type <UIntVal> OptCallingConv
-%type <ParamAttrs> OptParamAttrs ParamAttrList ParamAttr
+%type <ParamAttrs> OptParamAttrs ParamAttr
+%type <ParamAttrs> OptFuncAttrs FuncAttr
// Basic Block Terminating Operators
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
%token <OtherOpVal> PHI_TOK SELECT SHL LSHR ASHR VAARG
%token <OtherOpVal> EXTRACTELEMENT INSERTELEMENT SHUFFLEVECTOR
+// Function Attributes
+%token NORETURN
%start Module
%%
| SEXT { $$ = FunctionType::SExtAttribute; }
;
-ParamAttrList : ParamAttr { $$ = $1; }
- | ParamAttrList ',' ParamAttr {
- $$ = FunctionType::ParameterAttributes($1 | $3);
+OptParamAttrs : /* empty */ { $$ = FunctionType::NoAttributeSet; }
+ | OptParamAttrs ParamAttr {
+ $$ = FunctionType::ParameterAttributes($1 | $2);
}
;
-OptParamAttrs : /* empty */ { $$ = FunctionType::NoAttributeSet; }
- | '@' ParamAttr { $$ = $2; }
- | '@' '(' ParamAttrList ')' { $$ = $3; }
+FuncAttr : NORETURN { $$ = FunctionType::NoReturnAttribute; }
+ | ParamAttr
+ ;
+
+OptFuncAttrs : /* empty */ { $$ = FunctionType::NoAttributeSet; }
+ | OptFuncAttrs FuncAttr {
+ $$ = FunctionType::ParameterAttributes($1 | $2);
+ }
;
// OptAlign/OptCAlign - An optional alignment, and an optional alignment with
UR_OUT("New Upreference!\n");
CHECK_FOR_ERROR
}
- | Types OptParamAttrs '(' ArgTypeListI ')' {
+ | Types '(' ArgTypeListI ')' OptFuncAttrs {
std::vector<const Type*> Params;
std::vector<FunctionType::ParameterAttributes> Attrs;
- Attrs.push_back($2);
- for (TypeWithAttrsList::iterator I=$4->begin(), E=$4->end(); I != E; ++I) {
+ Attrs.push_back($5);
+ for (TypeWithAttrsList::iterator I=$3->begin(), E=$3->end(); I != E; ++I) {
Params.push_back(I->Ty->get());
if (I->Ty->get() != Type::VoidTy)
Attrs.push_back(I->Attrs);
if (isVarArg) Params.pop_back();
FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, Attrs);
- delete $4; // Delete the argument list
+ delete $3; // Delete the argument list
delete $1; // Delete the return type handle
$$ = new PATypeHolder(HandleUpRefs(FT));
CHECK_FOR_ERROR
}
- | VOID OptParamAttrs '(' ArgTypeListI ')' {
+ | VOID '(' ArgTypeListI ')' OptFuncAttrs {
std::vector<const Type*> Params;
std::vector<FunctionType::ParameterAttributes> Attrs;
- Attrs.push_back($2);
- for (TypeWithAttrsList::iterator I=$4->begin(), E=$4->end(); I != E; ++I) {
+ Attrs.push_back($5);
+ for (TypeWithAttrsList::iterator I=$3->begin(), E=$3->end(); I != E; ++I) {
Params.push_back(I->Ty->get());
if (I->Ty->get() != Type::VoidTy)
Attrs.push_back(I->Attrs);
if (isVarArg) Params.pop_back();
FunctionType *FT = FunctionType::get($1, Params, isVarArg, Attrs);
- delete $4; // Delete the argument list
+ delete $3; // Delete the argument list
$$ = new PATypeHolder(HandleUpRefs(FT));
CHECK_FOR_ERROR
}
}
;
-ResultType
- : Types OptParamAttrs {
+ResultTypes
+ : Types {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
if (!(*$1)->isFirstClassType())
GEN_ERROR("LLVM functions cannot return aggregate types!");
- $$.Ty = $1;
- $$.Attrs = $2;
+ $$ = $1;
}
- | VOID OptParamAttrs {
- $$.Ty = new PATypeHolder(Type::VoidTy);
- $$.Attrs = $2;
+ | VOID {
+ $$ = new PATypeHolder(Type::VoidTy);
}
;
"' for element #" + utostr(i) +
" of structure initializer!");
+ // Check to ensure that Type is not packed
+ if (STy->isPacked())
+ GEN_ERROR("Unpacked Initializer to packed type '" + STy->getDescription() + "'");
+
$$ = ConstantStruct::get(STy, *$3);
delete $1; delete $3;
CHECK_FOR_ERROR
if (STy->getNumContainedTypes() != 0)
GEN_ERROR("Illegal number of initializers for structure type!");
+ // Check to ensure that Type is not packed
+ if (STy->isPacked())
+ GEN_ERROR("Unpacked Initializer to packed type '" + STy->getDescription() + "'");
+
+ $$ = ConstantStruct::get(STy, std::vector<Constant*>());
+ delete $1;
+ CHECK_FOR_ERROR
+ }
+ | Types '<' '{' ConstVector '}' '>' {
+ const StructType *STy = dyn_cast<StructType>($1->get());
+ if (STy == 0)
+ GEN_ERROR("Cannot make struct constant with type: '" +
+ (*$1)->getDescription() + "'!");
+
+ if ($4->size() != STy->getNumContainedTypes())
+ GEN_ERROR("Illegal number of initializers for structure type!");
+
+ // Check to ensure that constants are compatible with the type initializer!
+ for (unsigned i = 0, e = $4->size(); i != e; ++i)
+ if ((*$4)[i]->getType() != STy->getElementType(i))
+ GEN_ERROR("Expected type '" +
+ STy->getElementType(i)->getDescription() +
+ "' for element #" + utostr(i) +
+ " of structure initializer!");
+
+ // Check to ensure that Type is packed
+ if (!STy->isPacked())
+ GEN_ERROR("Packed Initializer to unpacked type '" + STy->getDescription() + "'");
+
+ $$ = ConstantStruct::get(STy, *$4);
+ delete $1; delete $4;
+ CHECK_FOR_ERROR
+ }
+ | Types '<' '{' '}' '>' {
+ if (!UpRefs.empty())
+ GEN_ERROR("Invalid upreference in type: " + (*$1)->getDescription());
+ const StructType *STy = dyn_cast<StructType>($1->get());
+ if (STy == 0)
+ GEN_ERROR("Cannot make struct constant with type: '" +
+ (*$1)->getDescription() + "'!");
+
+ if (STy->getNumContainedTypes() != 0)
+ GEN_ERROR("Illegal number of initializers for structure type!");
+
+ // Check to ensure that Type is packed
+ if (!STy->isPacked())
+ GEN_ERROR("Packed Initializer to unpacked type '" + STy->getDescription() + "'");
+
$$ = ConstantStruct::get(STy, std::vector<Constant*>());
delete $1;
CHECK_FOR_ERROR
CHECK_FOR_ERROR
};
-FunctionHeaderH : OptCallingConv ResultType Name '(' ArgList ')'
- OptSection OptAlign {
+FunctionHeaderH : OptCallingConv ResultTypes Name '(' ArgList ')'
+ OptFuncAttrs OptSection OptAlign {
UnEscapeLexed($3);
std::string FunctionName($3);
free($3); // Free strdup'd memory!
// Check the function result for abstractness if this is a define. We should
// have no abstract types at this point
- if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2.Ty))
- GEN_ERROR("Reference to abstract result: "+ $2.Ty->get()->getDescription());
+ if (!CurFun.isDeclare && CurModule.TypeIsUnresolved($2))
+ GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
std::vector<const Type*> ParamTypeList;
std::vector<FunctionType::ParameterAttributes> ParamAttrs;
- ParamAttrs.push_back($2.Attrs);
+ ParamAttrs.push_back($7);
if ($5) { // If there are arguments...
for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I) {
const Type* Ty = I->Ty->get();
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
if (isVarArg) ParamTypeList.pop_back();
- FunctionType *FT = FunctionType::get(*$2.Ty, ParamTypeList, isVarArg,
+ FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg,
ParamAttrs);
const PointerType *PFT = PointerType::get(FT);
- delete $2.Ty;
+ delete $2;
ValID ID;
if (!FunctionName.empty()) {
Fn->setLinkage(CurFun.Linkage);
}
Fn->setCallingConv($1);
- Fn->setAlignment($8);
- if ($7) {
- Fn->setSection($7);
- free($7);
+ Fn->setAlignment($9);
+ if ($8) {
+ Fn->setSection($8);
+ free($8);
}
// Add all of the arguments we parsed to the function...
$$ = S;
CHECK_FOR_ERROR
}
- | INVOKE OptCallingConv ResultType ValueRef '(' ValueRefList ')'
+ | INVOKE OptCallingConv ResultTypes ValueRef '(' ValueRefList ')' OptFuncAttrs
TO LABEL ValueRef UNWIND LABEL ValueRef {
// Handle the short syntax
const PointerType *PFTy = 0;
const FunctionType *Ty = 0;
- if (!(PFTy = dyn_cast<PointerType>($3.Ty->get())) ||
+ if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes;
FunctionType::ParamAttrsList ParamAttrs;
- ParamAttrs.push_back($3.Attrs);
+ ParamAttrs.push_back($8);
for (ValueRefList::iterator I = $6->begin(), E = $6->end(); I != E; ++I) {
const Type *Ty = I->Val->getType();
if (Ty == Type::VoidTy)
ParamAttrs.push_back(I->Attrs);
}
- Ty = FunctionType::get($3.Ty->get(), ParamTypes, false, ParamAttrs);
+ Ty = FunctionType::get($3->get(), ParamTypes, false, ParamAttrs);
PFTy = PointerType::get(Ty);
}
Value *V = getVal(PFTy, $4); // Get the function we're calling...
CHECK_FOR_ERROR
- BasicBlock *Normal = getBBVal($10);
+ BasicBlock *Normal = getBBVal($11);
CHECK_FOR_ERROR
- BasicBlock *Except = getBBVal($13);
+ BasicBlock *Except = getBBVal($14);
CHECK_FOR_ERROR
// Check the arguments
delete $2; // Free the list...
CHECK_FOR_ERROR
}
- | OptTailCall OptCallingConv ResultType ValueRef '(' ValueRefList ')' {
+ | OptTailCall OptCallingConv ResultTypes ValueRef '(' ValueRefList ')'
+ OptFuncAttrs {
// Handle the short syntax
const PointerType *PFTy = 0;
const FunctionType *Ty = 0;
- if (!(PFTy = dyn_cast<PointerType>($3.Ty->get())) ||
+ if (!(PFTy = dyn_cast<PointerType>($3->get())) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
std::vector<const Type*> ParamTypes;
FunctionType::ParamAttrsList ParamAttrs;
- ParamAttrs.push_back($3.Attrs);
+ ParamAttrs.push_back($8);
for (ValueRefList::iterator I = $6->begin(), E = $6->end(); I != E; ++I) {
const Type *Ty = I->Val->getType();
if (Ty == Type::VoidTy)
ParamAttrs.push_back(I->Attrs);
}
- Ty = FunctionType::get($3.Ty->get(), ParamTypes, false, ParamAttrs);
+ Ty = FunctionType::get($3->get(), ParamTypes, false, ParamAttrs);
PFTy = PointerType::get(Ty);
}