Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Papyrus/Codegen/Cpp description"

m (C++ profile)
(C++ profile)
(16 intermediate revisions by the same user not shown)
Line 1: Line 1:
The C++ code generation is available in the extra plugins of Papyrus. Make sure to unselect "Group features by category" and install "Papyrus C++ profile, view and code generation (Incubation)". C++ code generation is also automatically installed with [Papyrus_Qompass Qompass].
+
The C++ code generation is an add-on of Papyrus. Once Papyrus is installed, the C++ code generation can be installed via the menu entry "Help->Install Papyrus additional components". Pick  "C++ code generation" from the list. Alternatively, you install the code generation manually:  Go to "Help->Install New Software". Choose the [[Papyrus_Designer|Papyrus SW designer]] update site http://download.eclipse.org/modeling/mdt/papyrus/components/designer/, then search for C++ code generation.
  
 
The C++ code generation comes with the following elements
 
The C++ code generation comes with the following elements
Line 27: Line 27:
 
| Operation, Property or Parameter
 
| Operation, Property or Parameter
 
| Declare that an operation, property or parameter is constant. Refer to the C++ semantics
 
| Declare that an operation, property or parameter is constant. Refer to the C++ semantics
 +
|-
 +
| ConstInit
 +
| Operation
 +
| Constructor initialization. The field "initialisation" is used to initialize members.
 +
|-
 +
| Create (StandardProfile::)
 +
| Operation
 +
| Declare that an operation is a constructor. Please note that this is an operation of the standard profile and not of the C++ profile. As it is not obvious that a constructor declaration is based on this stereotype (and not on the name), it's useful to mention it here. See also "Destroy".
 +
|-
 +
| Destroy (StandardProfile::)
 +
| Operation
 +
| Declare that an operation is a destructor. Please note that this is an operation of the standard profile and not of the C++ profile. As it is not obvious that a destructor declaration is based on this stereotype (and not on the name), it's useful to mention it here.
 
|-
 
|-
 
| External
 
| External
 
| Classifier
 
| Classifier
| Indicate that no code should be generated for this classifier. Other classifiers will import this classifier with the include path specified in the "definition" attribute
+
| Indicate that no code should be generated for this classifier. Other classifiers will import this classifier with the include path specified in the "incPath" attribute (if it is empty, a header file corresponding to the classifier name with the ".h" postfix is used). The attribute "name" indicates which name is used when the type is referenced by others. If empty, the UML name is used (non-qualified).
 
|-
 
|-
 
| ExternLibrary
 
| ExternLibrary
 
| Package
 
| Package
| Mark a package as External Library. If an element of this package is used, the associated CDT project will be configured accordingly (include and library paths)
+
| Mark a package as External Library. For all elements within that package, no code is generated. The elements are referenced by the UML name (non-qualified), optionally using a prefix that is defined in the stereotype attribute "prefix". If an element of this package is used, the associated CDT project will be configured accordingly (include and library paths).
 
|-
 
|-
 
| Friend
 
| Friend
Line 54: Line 66:
 
| Ptr
 
| Ptr
 
| Parameter or Property
 
| Parameter or Property
| Make attribute or parameter declaration a pointer.
+
| Make attribute or parameter declaration a pointer. This stereotype has an attribute called "declaration". If undefined, it simply corresponds to a star. It can be used for more complex pointer definitions. For instance, "**" can be used to obtain a double pointer
 
|-
 
|-
 
| Ref
 
| Ref
 
| Parameter or Property
 
| Parameter or Property
| Call call by references semantics to the parameter
+
| Use call-by-reference semantics for the property or parameter
 
|-
 
|-
 
| Template
 
| Template
 
| Class
 
| Class
 
| Indicate that the class is a C++ template
 
| Indicate that the class is a C++ template
 +
|-
 +
| Typedef
 +
| Primitive Type
 +
| Declare a new type that is based on another type. Has a definition attribute (if empty, it corresponds to name of the primitive type) Can be used to declare primitive types like int32_t (as defined in the ANSI-C library). Can also be used for function pointers, e.g. the definition "void (*typeName) (void*)" defines a function pointer that takes a void* argument and return type. If a primitive type with this definition is used as argument in a function, the code generator will replace the magic word "typeName" with the concrete type. E.g. a UML declaration of an argument "myParameter" with the primitive type "MyFunctionPointer" (with the definition above) would result in the generated parameter "void (*myParameter) (void*)"
 
|-
 
|-
 
| Union
 
| Union
Line 75: Line 91:
 
| Operation, Parameter or Property
 
| Operation, Parameter or Property
 
| Indicate the storage class
 
| Indicate the storage class
 +
|-
 +
| ListHint
 +
| Package
 +
| (The stereotype is from the Common code generation profile) Indicate how to handle attributes with non-1 multiplicity. By default, C++ produces an array, but this might not always be appropriate. The ListHint stereotype allows to change this behavior for a model or sub-package by defining how fixed length multiplicities (e.g. [0..5]) and variable ones ([0..*]) are translated into C++ code. The specific name "[typename]" in the hint is replaced by the specific type of an element. E.g. the hint "std::list<[typeName]>" will produce a std::list<MyType> for a attribute typed with MyType.
 
|}
 
|}
  
 
== Code generator ==
 
== Code generator ==
  
More information will be added soon.
+
The C++ code generator focuses on structural elements. It will generate code for classes, datatypes (C++ structs or unions) and primitive types along with their relationships such as inheritance and associations.
 +
 
 +
The behavior of operations must be supplied in form of an opaque behavior, i.e. a text block that is stored inside the model.
 +
The generator will produce a header and body file. Required #include directives are largely handled automatically, for instance if a certain type appears in the signature of one of your operations, the required #include will be added. For types that are only appearing within the opaque behavior, the user has to add an explicit dependency. An associated #include directive will be added to the body file. If additional definitions, e.g. #defines are required, it is possible to do that via the stereotype "Include" (see above).
 +
 
 +
The code generator places the created files in a folder hierarchy that corresponds to the package hierarchy in the model. By default, the files are generated into a CDT project with the name org.eclipse.papyrus.cppgen.<name of your model>. The prefix can be configured in the preferences. '''Note''': enumerations and primitive type definitions are currently not placed into a separate file, but added to the file generated for the (nearest) package of these types. So don't be surprised, if you do not find a file that has the name of your enumeration or primitive type. This might change in the future.
 +
 
 +
There is a support for external libraries that might include system libraries or legacy code. These libraries can be represented in your model by means of a stereotyped package. The stereotype "ExternalLibrary" provides information about include directories and library paths that are used to configure the generated CDT project - if there is an explicit or automatic dependency to the external library. For instance, the user can place a class called "pthread" into the external library package of the same name. No code is generated for this class. If the application classes reference a pthread class into their signature, the external library is taken into account.
 +
 
 +
=== Creating a Hello World example ===
 +
 
 +
[[Papyrus/Codegen/CppHelloWorld]]
 +
 
 +
=== Statemachine support ===
 +
 
 +
A design objective of the code generator is to keep it quite simple and focus on the structural parts. Advanced support for component based modeling (ports and connectors) is done in [[Papyrus_Qompass|Qompass designer]]. Qompass designer executes a model to model transformation for component based models. In the context of Qompass designer, there is also a support for (simple) state-machines.
  
 
== CDT integration ==
 
== CDT integration ==
Line 88: Line 123:
  
 
The CDT editor appears within a tab of Papyrus. This enables a side-by-side view of model and code. The editor can be invoked via the context menu of a class, operation or transition (within a statechart). Synchronisation is done, when the CDT editor looses focus. When model elements change, e.g. is you rename an operation, the code is regenerated and an update is done. It should not be possible to get conflicting changes, since a change in the model implies that the focus is no longer on the textual editor, i.e. changes in the texteditor should be already in the model.
 
The CDT editor appears within a tab of Papyrus. This enables a side-by-side view of model and code. The editor can be invoked via the context menu of a class, operation or transition (within a statechart). Synchronisation is done, when the CDT editor looses focus. When model elements change, e.g. is you rename an operation, the code is regenerated and an update is done. It should not be possible to get conflicting changes, since a change in the model implies that the focus is no longer on the textual editor, i.e. changes in the texteditor should be already in the model.
 +
 +
=== Limitations ===
 +
 +
The synchronisation from code to model may not work for all possible types in the signature. Since the editor opens the body (.cpp) file, only changes that are made in this file are taken into account. Thus, it is currently not possible to add attributes to the class via the C++ synchronisation from C++. While static attributes are represented in the body file, their synchronisation is currently not supported.
 +
 +
Besides addition and modification of methods, an update of the "Include" stereotype is supported, but requires that modifications are done at the "right" place. An additional "#define" for instance must be added between the start and end tags that are part of the generated file (e.g. "// Include from CppInclude stereotype (pre-body)").
 +
 +
When the user toggles between source and header in CDT (F3), CDT will open a new editor outside of Papyrus.
 +
 +
[[Category:Modeling]]
 +
[[Category:Papyrus]]
 +
[[Category:Papyrus-Designer]]

Revision as of 06:24, 10 December 2020

The C++ code generation is an add-on of Papyrus. Once Papyrus is installed, the C++ code generation can be installed via the menu entry "Help->Install Papyrus additional components". Pick "C++ code generation" from the list. Alternatively, you install the code generation manually: Go to "Help->Install New Software". Choose the Papyrus SW designer update site http://download.eclipse.org/modeling/mdt/papyrus/components/designer/, then search for C++ code generation.

The C++ code generation comes with the following elements

  • A C++ specific profile and a view simplifying the edition
  • The code generator itself (enriched with the C++ profile)
  • A CDT editor integration, allowing you to edit the code of a class in a CDT editor


C++ profile

The C++ profile defines a set of stereotypes that add C++ specific information to a UML model. For instance, a parameter of an operation might be passed by value, reference or as a pointer. The latter can be specified via the stereotypes C_Cpp::Ref and C_Cpp::Ptr respectively.

In the sequence, we shortly describe all stereotypes in alphabetical order:

Stereotype Metaclass extension Description
Array Parameter or Property Indicate array with a given multiplicity. Unlike the multiplicities in UML, the array size can be an arbitrary expression, it must not be directly an integer.
Const Operation, Property or Parameter Declare that an operation, property or parameter is constant. Refer to the C++ semantics
ConstInit Operation Constructor initialization. The field "initialisation" is used to initialize members.
Create (StandardProfile::) Operation Declare that an operation is a constructor. Please note that this is an operation of the standard profile and not of the C++ profile. As it is not obvious that a constructor declaration is based on this stereotype (and not on the name), it's useful to mention it here. See also "Destroy".
Destroy (StandardProfile::) Operation Declare that an operation is a destructor. Please note that this is an operation of the standard profile and not of the C++ profile. As it is not obvious that a destructor declaration is based on this stereotype (and not on the name), it's useful to mention it here.
External Classifier Indicate that no code should be generated for this classifier. Other classifiers will import this classifier with the include path specified in the "incPath" attribute (if it is empty, a header file corresponding to the classifier name with the ".h" postfix is used). The attribute "name" indicates which name is used when the type is referenced by others. If empty, the UML name is used (non-qualified).
ExternLibrary Package Mark a package as External Library. For all elements within that package, no code is generated. The elements are referenced by the UML name (non-qualified), optionally using a prefix that is defined in the stereotype attribute "prefix". If an element of this package is used, the associated CDT project will be configured accordingly (include and library paths).
Friend Operation or Dependency Indicate that the operation is a C++ friend
Include Class, Package or PackageImport An arbitrary string that is added to header and body file. Although primarily intended for manual #include directives, it can be used for arbitrary definitions. The contents of the attribute "preBody" is added to a C++ body file before automatic #include statements, "body" after these.
Inline Operation Indicate that generator produces an inline method inside the header file
NoCodeGen Element Do not generate code for this element
Ptr Parameter or Property Make attribute or parameter declaration a pointer. This stereotype has an attribute called "declaration". If undefined, it simply corresponds to a star. It can be used for more complex pointer definitions. For instance, "**" can be used to obtain a double pointer
Ref Parameter or Property Use call-by-reference semantics for the property or parameter
Template Class Indicate that the class is a C++ template
Typedef Primitive Type Declare a new type that is based on another type. Has a definition attribute (if empty, it corresponds to name of the primitive type) Can be used to declare primitive types like int32_t (as defined in the ANSI-C library). Can also be used for function pointers, e.g. the definition "void (*typeName) (void*)" defines a function pointer that takes a void* argument and return type. If a primitive type with this definition is used as argument in a function, the code generator will replace the magic word "typeName" with the concrete type. E.g. a UML declaration of an argument "myParameter" with the primitive type "MyFunctionPointer" (with the definition above) would result in the generated parameter "void (*myParameter) (void*)"
Union DataType Generate a union instead of a struct for this data type
Virtual Operation Make operation virtual
Volatile Operation, Parameter or Property Indicate the storage class
ListHint Package (The stereotype is from the Common code generation profile) Indicate how to handle attributes with non-1 multiplicity. By default, C++ produces an array, but this might not always be appropriate. The ListHint stereotype allows to change this behavior for a model or sub-package by defining how fixed length multiplicities (e.g. [0..5]) and variable ones ([0..*]) are translated into C++ code. The specific name "[typename]" in the hint is replaced by the specific type of an element. E.g. the hint "std::list<[typeName]>" will produce a std::list<MyType> for a attribute typed with MyType.

Code generator

The C++ code generator focuses on structural elements. It will generate code for classes, datatypes (C++ structs or unions) and primitive types along with their relationships such as inheritance and associations.

The behavior of operations must be supplied in form of an opaque behavior, i.e. a text block that is stored inside the model. The generator will produce a header and body file. Required #include directives are largely handled automatically, for instance if a certain type appears in the signature of one of your operations, the required #include will be added. For types that are only appearing within the opaque behavior, the user has to add an explicit dependency. An associated #include directive will be added to the body file. If additional definitions, e.g. #defines are required, it is possible to do that via the stereotype "Include" (see above).

The code generator places the created files in a folder hierarchy that corresponds to the package hierarchy in the model. By default, the files are generated into a CDT project with the name org.eclipse.papyrus.cppgen.<name of your model>. The prefix can be configured in the preferences. Note: enumerations and primitive type definitions are currently not placed into a separate file, but added to the file generated for the (nearest) package of these types. So don't be surprised, if you do not find a file that has the name of your enumeration or primitive type. This might change in the future.

There is a support for external libraries that might include system libraries or legacy code. These libraries can be represented in your model by means of a stereotyped package. The stereotype "ExternalLibrary" provides information about include directories and library paths that are used to configure the generated CDT project - if there is an explicit or automatic dependency to the external library. For instance, the user can place a class called "pthread" into the external library package of the same name. No code is generated for this class. If the application classes reference a pthread class into their signature, the external library is taken into account.

Creating a Hello World example

Papyrus/Codegen/CppHelloWorld

Statemachine support

A design objective of the code generator is to keep it quite simple and focus on the structural parts. Advanced support for component based modeling (ports and connectors) is done in Qompass designer. Qompass designer executes a model to model transformation for component based models. In the context of Qompass designer, there is also a support for (simple) state-machines.

CDT integration

After installation, you can import the plugin org.eclipse.papyrus.cpp.test into your workspace. Within, you can find a sample model called "TestCDTintegration". Once opened, you should see the following screen.

Cdt-editor.png

The CDT editor appears within a tab of Papyrus. This enables a side-by-side view of model and code. The editor can be invoked via the context menu of a class, operation or transition (within a statechart). Synchronisation is done, when the CDT editor looses focus. When model elements change, e.g. is you rename an operation, the code is regenerated and an update is done. It should not be possible to get conflicting changes, since a change in the model implies that the focus is no longer on the textual editor, i.e. changes in the texteditor should be already in the model.

Limitations

The synchronisation from code to model may not work for all possible types in the signature. Since the editor opens the body (.cpp) file, only changes that are made in this file are taken into account. Thus, it is currently not possible to add attributes to the class via the C++ synchronisation from C++. While static attributes are represented in the body file, their synchronisation is currently not supported.

Besides addition and modification of methods, an update of the "Include" stereotype is supported, but requires that modifications are done at the "right" place. An additional "#define" for instance must be added between the start and end tags that are part of the generated file (e.g. "// Include from CppInclude stereotype (pre-body)").

When the user toggles between source and header in CDT (F3), CDT will open a new editor outside of Papyrus.

Back to the top