forked from OSchip/llvm-project
For PR950:
Remove all grammar conflicts from assembly parsing. This change involves: 1. Making the "type" keyword not a primitive type (removes several reduce/reduce conflicts) 2. Being more specific about which linkage types are allowed for functions and global variables. In particular "appending" can no longer be specified for a function. A differentiation was made between the various internal and external linkage types. 3. Introduced the "define" keyword which is now required when defining a function. This disambiguates several cases where a named function return type could get confused with the definition of a new type. Using the keyword eliminates all shift/reduce conflicts and the remaining reduce/reduce conflicts. These changes are necessary to implement the function parameter attributes that will be introduced soon. Adding the function parameter attributes in the presence of the shift/reduce and reduce/reduce conflicts led to severe ambiguities that caused the parser to report syntax errors that needed to be resolved. This patch resolves them. llvm-svn: 32770
This commit is contained in:
parent
399b10a48c
commit
7ce2d2a8fe
|
@ -192,6 +192,7 @@ end { return ENDTOK; }
|
||||||
true { return TRUETOK; }
|
true { return TRUETOK; }
|
||||||
false { return FALSETOK; }
|
false { return FALSETOK; }
|
||||||
declare { return DECLARE; }
|
declare { return DECLARE; }
|
||||||
|
define { return DEFINE; }
|
||||||
global { return GLOBAL; }
|
global { return GLOBAL; }
|
||||||
constant { return CONSTANT; }
|
constant { return CONSTANT; }
|
||||||
internal { return INTERNAL; }
|
internal { return INTERNAL; }
|
||||||
|
|
|
@ -895,7 +895,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
||||||
llvm::FCmpInst::Predicate FPredicate;
|
llvm::FCmpInst::Predicate FPredicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type <ModuleVal> Module FunctionList
|
%type <ModuleVal> Module
|
||||||
%type <FunctionVal> Function FunctionProto FunctionHeader BasicBlockList
|
%type <FunctionVal> Function FunctionProto FunctionHeader BasicBlockList
|
||||||
%type <BasicBlockVal> BasicBlock InstructionList
|
%type <BasicBlockVal> BasicBlock InstructionList
|
||||||
%type <TermInstVal> BBTerminatorInst
|
%type <TermInstVal> BBTerminatorInst
|
||||||
|
@ -913,7 +913,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
||||||
%type <BoolVal> OptVolatile // 'volatile' or not
|
%type <BoolVal> OptVolatile // 'volatile' or not
|
||||||
%type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
|
%type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
|
||||||
%type <BoolVal> OptSideEffect // 'sideeffect' or not.
|
%type <BoolVal> OptSideEffect // 'sideeffect' or not.
|
||||||
%type <Linkage> OptLinkage
|
%type <Linkage> FunctionLinkage GVInternalLinkage GVExternalLinkage
|
||||||
%type <Endianness> BigOrLittle
|
%type <Endianness> BigOrLittle
|
||||||
|
|
||||||
// ValueRef - Unresolved reference to a definition or BB
|
// ValueRef - Unresolved reference to a definition or BB
|
||||||
|
@ -936,7 +936,8 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
||||||
%type <TypeVal> Types TypesV UpRTypes UpRTypesV
|
%type <TypeVal> Types TypesV UpRTypes UpRTypesV
|
||||||
%type <PrimType> SIntType UIntType IntType FPType PrimType // Classifications
|
%type <PrimType> SIntType UIntType IntType FPType PrimType // Classifications
|
||||||
%token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
%token <PrimType> VOID BOOL SBYTE UBYTE SHORT USHORT INT UINT LONG ULONG
|
||||||
%token <PrimType> FLOAT DOUBLE TYPE LABEL
|
%token <PrimType> FLOAT DOUBLE LABEL
|
||||||
|
%token TYPE
|
||||||
|
|
||||||
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
|
%token <StrVal> VAR_ID LABELSTR STRINGCONSTANT
|
||||||
%type <StrVal> Name OptName OptAssign
|
%type <StrVal> Name OptName OptAssign
|
||||||
|
@ -944,7 +945,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
||||||
%type <StrVal> OptSection SectionString
|
%type <StrVal> OptSection SectionString
|
||||||
|
|
||||||
%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
|
%token IMPLEMENTATION ZEROINITIALIZER TRUETOK FALSETOK BEGINTOK ENDTOK
|
||||||
%token DECLARE GLOBAL CONSTANT SECTION VOLATILE
|
%token DECLARE DEFINE GLOBAL CONSTANT SECTION VOLATILE
|
||||||
%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
|
%token TO DOTDOTDOT NULL_TOK UNDEF CONST INTERNAL LINKONCE WEAK APPENDING
|
||||||
%token DLLIMPORT DLLEXPORT EXTERN_WEAK
|
%token DLLIMPORT DLLEXPORT EXTERN_WEAK
|
||||||
%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
|
%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
|
||||||
|
@ -1038,14 +1039,33 @@ OptAssign : Name '=' {
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } |
|
GVInternalLinkage
|
||||||
LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } |
|
: INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
||||||
WEAK { $$ = GlobalValue::WeakLinkage; } |
|
| WEAK { $$ = GlobalValue::WeakLinkage; }
|
||||||
APPENDING { $$ = GlobalValue::AppendingLinkage; } |
|
| LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
|
||||||
DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } |
|
| APPENDING { $$ = GlobalValue::AppendingLinkage; }
|
||||||
DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } |
|
| DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
|
||||||
EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
|
;
|
||||||
/*empty*/ { $$ = GlobalValue::ExternalLinkage; };
|
|
||||||
|
GVExternalLinkage
|
||||||
|
: DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; }
|
||||||
|
| EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; }
|
||||||
|
| EXTERNAL { $$ = GlobalValue::ExternalLinkage; }
|
||||||
|
;
|
||||||
|
|
||||||
|
FnDeclareLinkage
|
||||||
|
: /*empty*/ { /*default*/ }
|
||||||
|
| DLLIMPORT { CurFun.Linkage = GlobalValue::DLLImportLinkage; }
|
||||||
|
| EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; }
|
||||||
|
;
|
||||||
|
|
||||||
|
FunctionLinkage
|
||||||
|
: INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
||||||
|
| LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
|
||||||
|
| WEAK { $$ = GlobalValue::WeakLinkage; }
|
||||||
|
| DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
|
||||||
|
| /*empty*/ { $$ = GlobalValue::ExternalLinkage; }
|
||||||
|
;
|
||||||
|
|
||||||
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
|
OptCallingConv : /*empty*/ { $$ = CallingConv::C; } |
|
||||||
CCC_TOK { $$ = CallingConv::C; } |
|
CCC_TOK { $$ = CallingConv::C; } |
|
||||||
|
@ -1128,7 +1148,7 @@ Types : UpRTypes {
|
||||||
// Derived types are added later...
|
// Derived types are added later...
|
||||||
//
|
//
|
||||||
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
||||||
PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE | LABEL;
|
PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL ;
|
||||||
UpRTypes : OPAQUE {
|
UpRTypes : OPAQUE {
|
||||||
$$ = new PATypeHolder(OpaqueType::get());
|
$$ = new PATypeHolder(OpaqueType::get());
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
|
@ -1634,33 +1654,36 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; };
|
||||||
// Module rule: Capture the result of parsing the whole file into a result
|
// Module rule: Capture the result of parsing the whole file into a result
|
||||||
// variable...
|
// variable...
|
||||||
//
|
//
|
||||||
Module : FunctionList {
|
Module
|
||||||
$$ = ParserResult = $1;
|
: DefinitionList {
|
||||||
CurModule.ModuleDone();
|
$$ = ParserResult = CurModule.CurrentModule;
|
||||||
CHECK_FOR_ERROR;
|
CurModule.ModuleDone();
|
||||||
};
|
CHECK_FOR_ERROR;
|
||||||
|
}
|
||||||
|
| /*empty*/ {
|
||||||
|
$$ = ParserResult = CurModule.CurrentModule;
|
||||||
|
CurModule.ModuleDone();
|
||||||
|
CHECK_FOR_ERROR;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
// FunctionList - A list of functions, preceeded by a constant pool.
|
DefinitionList
|
||||||
//
|
: Definition
|
||||||
FunctionList : FunctionList Function {
|
| DefinitionList Definition
|
||||||
$$ = $1;
|
;
|
||||||
|
|
||||||
|
Definition
|
||||||
|
: DEFINE { CurFun.isDeclare = false } Function {
|
||||||
CurFun.FunctionDone();
|
CurFun.FunctionDone();
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| FunctionList FunctionProto {
|
| DECLARE { CurFun.isDeclare = true; } FunctionProto {
|
||||||
$$ = $1;
|
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| FunctionList MODULE ASM_TOK AsmBlock {
|
| MODULE ASM_TOK AsmBlock {
|
||||||
$$ = $1;
|
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| FunctionList IMPLEMENTATION {
|
| IMPLEMENTATION {
|
||||||
$$ = $1;
|
|
||||||
CHECK_FOR_ERROR
|
|
||||||
}
|
|
||||||
| ConstPool {
|
|
||||||
$$ = CurModule.CurrentModule;
|
|
||||||
// Emit an error if there are any unresolved types left.
|
// Emit an error if there are any unresolved types left.
|
||||||
if (!CurModule.LateResolveTypes.empty()) {
|
if (!CurModule.LateResolveTypes.empty()) {
|
||||||
const ValID &DID = CurModule.LateResolveTypes.begin()->first;
|
const ValID &DID = CurModule.LateResolveTypes.begin()->first;
|
||||||
|
@ -1671,10 +1694,8 @@ FunctionList : FunctionList Function {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
};
|
}
|
||||||
|
| OptAssign TYPE TypesV {
|
||||||
// ConstPool - Constants with optional names assigned to them.
|
|
||||||
ConstPool : ConstPool OptAssign TYPE TypesV {
|
|
||||||
// Eagerly resolve types. This is not an optimization, this is a
|
// Eagerly resolve types. This is not an optimization, this is a
|
||||||
// requirement that is due to the fact that we could have this:
|
// requirement that is due to the fact that we could have this:
|
||||||
//
|
//
|
||||||
|
@ -1684,65 +1705,50 @@ ConstPool : ConstPool OptAssign TYPE TypesV {
|
||||||
// If types are not resolved eagerly, then the two types will not be
|
// If types are not resolved eagerly, then the two types will not be
|
||||||
// determined to be the same type!
|
// determined to be the same type!
|
||||||
//
|
//
|
||||||
ResolveTypeTo($2, *$4);
|
ResolveTypeTo($1, *$3);
|
||||||
|
|
||||||
if (!setTypeName(*$4, $2) && !$2) {
|
if (!setTypeName(*$3, $1) && !$1) {
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
// If this is a named type that is not a redefinition, add it to the slot
|
// If this is a named type that is not a redefinition, add it to the slot
|
||||||
// table.
|
// table.
|
||||||
CurModule.Types.push_back(*$4);
|
CurModule.Types.push_back(*$3);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete $4;
|
delete $3;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
| OptAssign GlobalType ConstVal { /* "Externally Visible" Linkage */
|
||||||
CHECK_FOR_ERROR
|
if ($3 == 0)
|
||||||
}
|
|
||||||
| ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
|
|
||||||
CHECK_FOR_ERROR
|
|
||||||
}
|
|
||||||
| ConstPool OptAssign OptLinkage GlobalType ConstVal {
|
|
||||||
if ($5 == 0)
|
|
||||||
GEN_ERROR("Global value initializer is not a constant!");
|
GEN_ERROR("Global value initializer is not a constant!");
|
||||||
CurGV = ParseGlobalVariable($2, $3, $4, $5->getType(), $5);
|
CurGV = ParseGlobalVariable($1, GlobalValue::ExternalLinkage, $2,
|
||||||
|
$3->getType(), $3);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
} GlobalVarAttributes {
|
} GlobalVarAttributes {
|
||||||
CurGV = 0;
|
CurGV = 0;
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign EXTERNAL GlobalType Types {
|
| OptAssign GVInternalLinkage GlobalType ConstVal {
|
||||||
CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0);
|
if ($4 == 0)
|
||||||
|
GEN_ERROR("Global value initializer is not a constant!");
|
||||||
|
CurGV = ParseGlobalVariable($1, $2, $3, $4->getType(), $4);
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
delete $5;
|
} GlobalVarAttributes {
|
||||||
|
CurGV = 0;
|
||||||
|
}
|
||||||
|
| OptAssign GVExternalLinkage GlobalType Types {
|
||||||
|
CurGV = ParseGlobalVariable($1, $2, $3, *$4, 0);
|
||||||
|
CHECK_FOR_ERROR
|
||||||
|
delete $4;
|
||||||
} GlobalVarAttributes {
|
} GlobalVarAttributes {
|
||||||
CurGV = 0;
|
CurGV = 0;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign DLLIMPORT GlobalType Types {
|
| TARGET TargetDefinition {
|
||||||
CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, *$5, 0);
|
|
||||||
CHECK_FOR_ERROR
|
|
||||||
delete $5;
|
|
||||||
} GlobalVarAttributes {
|
|
||||||
CurGV = 0;
|
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| ConstPool OptAssign EXTERN_WEAK GlobalType Types {
|
| DEPLIBS '=' LibrariesDefinition {
|
||||||
CurGV =
|
|
||||||
ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
|
|
||||||
CHECK_FOR_ERROR
|
|
||||||
delete $5;
|
|
||||||
} GlobalVarAttributes {
|
|
||||||
CurGV = 0;
|
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
| ConstPool TARGET TargetDefinition {
|
;
|
||||||
CHECK_FOR_ERROR
|
|
||||||
}
|
|
||||||
| ConstPool DEPLIBS '=' LibrariesDefinition {
|
|
||||||
CHECK_FOR_ERROR
|
|
||||||
}
|
|
||||||
| /* empty: end of list */ {
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
AsmBlock : STRINGCONSTANT {
|
AsmBlock : STRINGCONSTANT {
|
||||||
|
@ -1944,7 +1950,7 @@ FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
|
||||||
|
|
||||||
BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function
|
BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function
|
||||||
|
|
||||||
FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
|
FunctionHeader : FunctionLinkage FunctionHeaderH BEGIN {
|
||||||
$$ = CurFun.CurrentFunction;
|
$$ = CurFun.CurrentFunction;
|
||||||
|
|
||||||
// Make sure that we keep track of the linkage type even if there was a
|
// Make sure that we keep track of the linkage type even if there was a
|
||||||
|
@ -1959,11 +1965,7 @@ Function : BasicBlockList END {
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
};
|
};
|
||||||
|
|
||||||
FnDeclareLinkage: /*default*/ |
|
FunctionProto : FnDeclareLinkage FunctionHeaderH {
|
||||||
DLLIMPORT { CurFun.Linkage = GlobalValue::DLLImportLinkage; } |
|
|
||||||
EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; };
|
|
||||||
|
|
||||||
FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
|
|
||||||
$$ = CurFun.CurrentFunction;
|
$$ = CurFun.CurrentFunction;
|
||||||
CurFun.FunctionDone();
|
CurFun.FunctionDone();
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
|
|
|
@ -921,7 +921,8 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||||
case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
|
case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
|
||||||
default: Out << "declare ";
|
default: Out << "declare ";
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
Out << "define ";
|
||||||
switch (F->getLinkage()) {
|
switch (F->getLinkage()) {
|
||||||
case GlobalValue::InternalLinkage: Out << "internal "; break;
|
case GlobalValue::InternalLinkage: Out << "internal "; break;
|
||||||
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
|
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
|
||||||
|
@ -935,6 +936,7 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||||
cerr << "GhostLinkage not allowed in AsmWriter!\n";
|
cerr << "GhostLinkage not allowed in AsmWriter!\n";
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print the calling convention.
|
// Print the calling convention.
|
||||||
switch (F->getCallingConv()) {
|
switch (F->getCallingConv()) {
|
||||||
|
|
Loading…
Reference in New Issue