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; }
|
||||
false { return FALSETOK; }
|
||||
declare { return DECLARE; }
|
||||
define { return DEFINE; }
|
||||
global { return GLOBAL; }
|
||||
constant { return CONSTANT; }
|
||||
internal { return INTERNAL; }
|
||||
|
|
|
@ -895,7 +895,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||
llvm::FCmpInst::Predicate FPredicate;
|
||||
}
|
||||
|
||||
%type <ModuleVal> Module FunctionList
|
||||
%type <ModuleVal> Module
|
||||
%type <FunctionVal> Function FunctionProto FunctionHeader BasicBlockList
|
||||
%type <BasicBlockVal> BasicBlock InstructionList
|
||||
%type <TermInstVal> BBTerminatorInst
|
||||
|
@ -913,7 +913,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||
%type <BoolVal> OptVolatile // 'volatile' or not
|
||||
%type <BoolVal> OptTailCall // TAIL CALL or plain CALL.
|
||||
%type <BoolVal> OptSideEffect // 'sideeffect' or not.
|
||||
%type <Linkage> OptLinkage
|
||||
%type <Linkage> FunctionLinkage GVInternalLinkage GVExternalLinkage
|
||||
%type <Endianness> BigOrLittle
|
||||
|
||||
// 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 <PrimType> SIntType UIntType IntType FPType PrimType // Classifications
|
||||
%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
|
||||
%type <StrVal> Name OptName OptAssign
|
||||
|
@ -944,7 +945,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) {
|
|||
%type <StrVal> OptSection SectionString
|
||||
|
||||
%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 DLLIMPORT DLLEXPORT EXTERN_WEAK
|
||||
%token OPAQUE NOT EXTERNAL TARGET TRIPLE ENDIAN POINTERSIZE LITTLE BIG ALIGN
|
||||
|
@ -1038,14 +1039,33 @@ OptAssign : Name '=' {
|
|||
CHECK_FOR_ERROR
|
||||
};
|
||||
|
||||
OptLinkage : INTERNAL { $$ = GlobalValue::InternalLinkage; } |
|
||||
LINKONCE { $$ = GlobalValue::LinkOnceLinkage; } |
|
||||
WEAK { $$ = GlobalValue::WeakLinkage; } |
|
||||
APPENDING { $$ = GlobalValue::AppendingLinkage; } |
|
||||
DLLIMPORT { $$ = GlobalValue::DLLImportLinkage; } |
|
||||
DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; } |
|
||||
EXTERN_WEAK { $$ = GlobalValue::ExternalWeakLinkage; } |
|
||||
/*empty*/ { $$ = GlobalValue::ExternalLinkage; };
|
||||
GVInternalLinkage
|
||||
: INTERNAL { $$ = GlobalValue::InternalLinkage; }
|
||||
| WEAK { $$ = GlobalValue::WeakLinkage; }
|
||||
| LINKONCE { $$ = GlobalValue::LinkOnceLinkage; }
|
||||
| APPENDING { $$ = GlobalValue::AppendingLinkage; }
|
||||
| DLLEXPORT { $$ = GlobalValue::DLLExportLinkage; }
|
||||
;
|
||||
|
||||
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; } |
|
||||
CCC_TOK { $$ = CallingConv::C; } |
|
||||
|
@ -1128,7 +1148,7 @@ Types : UpRTypes {
|
|||
// Derived types are added later...
|
||||
//
|
||||
PrimType : BOOL | SBYTE | UBYTE | SHORT | USHORT | INT | UINT ;
|
||||
PrimType : LONG | ULONG | FLOAT | DOUBLE | TYPE | LABEL;
|
||||
PrimType : LONG | ULONG | FLOAT | DOUBLE | LABEL ;
|
||||
UpRTypes : OPAQUE {
|
||||
$$ = new PATypeHolder(OpaqueType::get());
|
||||
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
|
||||
// variable...
|
||||
//
|
||||
Module : FunctionList {
|
||||
$$ = ParserResult = $1;
|
||||
CurModule.ModuleDone();
|
||||
CHECK_FOR_ERROR;
|
||||
};
|
||||
Module
|
||||
: DefinitionList {
|
||||
$$ = ParserResult = CurModule.CurrentModule;
|
||||
CurModule.ModuleDone();
|
||||
CHECK_FOR_ERROR;
|
||||
}
|
||||
| /*empty*/ {
|
||||
$$ = ParserResult = CurModule.CurrentModule;
|
||||
CurModule.ModuleDone();
|
||||
CHECK_FOR_ERROR;
|
||||
}
|
||||
;
|
||||
|
||||
// FunctionList - A list of functions, preceeded by a constant pool.
|
||||
//
|
||||
FunctionList : FunctionList Function {
|
||||
$$ = $1;
|
||||
DefinitionList
|
||||
: Definition
|
||||
| DefinitionList Definition
|
||||
;
|
||||
|
||||
Definition
|
||||
: DEFINE { CurFun.isDeclare = false } Function {
|
||||
CurFun.FunctionDone();
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| FunctionList FunctionProto {
|
||||
$$ = $1;
|
||||
}
|
||||
| DECLARE { CurFun.isDeclare = true; } FunctionProto {
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| FunctionList MODULE ASM_TOK AsmBlock {
|
||||
$$ = $1;
|
||||
| MODULE ASM_TOK AsmBlock {
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| FunctionList IMPLEMENTATION {
|
||||
$$ = $1;
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool {
|
||||
$$ = CurModule.CurrentModule;
|
||||
| IMPLEMENTATION {
|
||||
// Emit an error if there are any unresolved types left.
|
||||
if (!CurModule.LateResolveTypes.empty()) {
|
||||
const ValID &DID = CurModule.LateResolveTypes.begin()->first;
|
||||
|
@ -1671,10 +1694,8 @@ FunctionList : FunctionList Function {
|
|||
}
|
||||
}
|
||||
CHECK_FOR_ERROR
|
||||
};
|
||||
|
||||
// ConstPool - Constants with optional names assigned to them.
|
||||
ConstPool : ConstPool OptAssign TYPE TypesV {
|
||||
}
|
||||
| OptAssign TYPE TypesV {
|
||||
// Eagerly resolve types. This is not an optimization, this is a
|
||||
// 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
|
||||
// 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
|
||||
// If this is a named type that is not a redefinition, add it to the slot
|
||||
// table.
|
||||
CurModule.Types.push_back(*$4);
|
||||
CurModule.Types.push_back(*$3);
|
||||
}
|
||||
|
||||
delete $4;
|
||||
delete $3;
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool FunctionProto { // Function prototypes can be in const pool
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool MODULE ASM_TOK AsmBlock { // Asm blocks can be in the const pool
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool OptAssign OptLinkage GlobalType ConstVal {
|
||||
if ($5 == 0)
|
||||
| OptAssign GlobalType ConstVal { /* "Externally Visible" Linkage */
|
||||
if ($3 == 0)
|
||||
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
|
||||
} GlobalVarAttributes {
|
||||
CurGV = 0;
|
||||
}
|
||||
| ConstPool OptAssign EXTERNAL GlobalType Types {
|
||||
CurGV = ParseGlobalVariable($2, GlobalValue::ExternalLinkage, $4, *$5, 0);
|
||||
| OptAssign GVInternalLinkage GlobalType ConstVal {
|
||||
if ($4 == 0)
|
||||
GEN_ERROR("Global value initializer is not a constant!");
|
||||
CurGV = ParseGlobalVariable($1, $2, $3, $4->getType(), $4);
|
||||
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 {
|
||||
CurGV = 0;
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool OptAssign DLLIMPORT GlobalType Types {
|
||||
CurGV = ParseGlobalVariable($2, GlobalValue::DLLImportLinkage, $4, *$5, 0);
|
||||
CHECK_FOR_ERROR
|
||||
delete $5;
|
||||
} GlobalVarAttributes {
|
||||
CurGV = 0;
|
||||
| TARGET TargetDefinition {
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool OptAssign EXTERN_WEAK GlobalType Types {
|
||||
CurGV =
|
||||
ParseGlobalVariable($2, GlobalValue::ExternalWeakLinkage, $4, *$5, 0);
|
||||
CHECK_FOR_ERROR
|
||||
delete $5;
|
||||
} GlobalVarAttributes {
|
||||
CurGV = 0;
|
||||
| DEPLIBS '=' LibrariesDefinition {
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool TARGET TargetDefinition {
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| ConstPool DEPLIBS '=' LibrariesDefinition {
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
| /* empty: end of list */ {
|
||||
};
|
||||
;
|
||||
|
||||
|
||||
AsmBlock : STRINGCONSTANT {
|
||||
|
@ -1944,7 +1950,7 @@ FunctionHeaderH : OptCallingConv TypesV Name '(' ArgList ')'
|
|||
|
||||
BEGIN : BEGINTOK | '{'; // Allow BEGIN or '{' to start a function
|
||||
|
||||
FunctionHeader : OptLinkage FunctionHeaderH BEGIN {
|
||||
FunctionHeader : FunctionLinkage FunctionHeaderH BEGIN {
|
||||
$$ = CurFun.CurrentFunction;
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
FnDeclareLinkage: /*default*/ |
|
||||
DLLIMPORT { CurFun.Linkage = GlobalValue::DLLImportLinkage; } |
|
||||
EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; };
|
||||
|
||||
FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {
|
||||
FunctionProto : FnDeclareLinkage FunctionHeaderH {
|
||||
$$ = CurFun.CurrentFunction;
|
||||
CurFun.FunctionDone();
|
||||
CHECK_FOR_ERROR
|
||||
|
|
|
@ -921,7 +921,8 @@ void AssemblyWriter::printFunction(const Function *F) {
|
|||
case GlobalValue::ExternalWeakLinkage: Out << "declare extern_weak "; break;
|
||||
default: Out << "declare ";
|
||||
}
|
||||
else
|
||||
else {
|
||||
Out << "define ";
|
||||
switch (F->getLinkage()) {
|
||||
case GlobalValue::InternalLinkage: Out << "internal "; break;
|
||||
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
|
||||
|
@ -935,6 +936,7 @@ void AssemblyWriter::printFunction(const Function *F) {
|
|||
cerr << "GhostLinkage not allowed in AsmWriter!\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Print the calling convention.
|
||||
switch (F->getCallingConv()) {
|
||||
|
|
Loading…
Reference in New Issue