On page 172, Stroustrup is doing something like so:
namespace Parser { //interface for users
double expr(bool);
}
namespace Parser { //interface for implementers
double prim(bool);
double term(bool);
double expr(bool);
using Lexer::get_token;
<SNIP>
}
Q1. does this imply that the first namespace is being inserted into (as an example) user.h and included from main.cpp - the driver; the second namespace into implementer.h and included from parse.cpp? Is this why he says:
"compiler doesn't have sufficient information to check the consistency
of the two definitions of the namespace"
because both implementer.h and user.h can't be included into "Parser implementation"(parse.cpp)?
172.png
173.png
On page 174, he has:
namespace Parser { //interface for implementers
// ...
double expr(bool);
// ...
}
namespace Parser_interface { //interface for users
using Parser::expr;
}
Is upper namespace going into implementer.h and lower one into user.h
In his "dependency graph" is he restating the obvious: that when Make is run, any change to "Parser"(parser.cpp/implementer.h) will result in driver/main.cpp being rebuilt - unnecessarily?
174.png
http://groups.google.com/group/alt.comp.lang.learn.c-c++/browse_thread/thread/3be9f35f2969f311/0d418ec6138a7e58#0d418ec6138a7e58
(the part about compiler consistency is wrong and the above thread states why:
Yes, the implementation can and should do that, but the checking of
consistency only works to a certain extent. If user.h uses things that are
not declared there, you will get a diagnostic. If you have "double
expr(bool);" declared in one place and "float expr(bool);" in another, the
compiler should also give you a diagnostic. However, if you change the
second one to "float expr(int);", then this is just an overload which is
perfectly legal C++. - Ulrich Eckhardt)
I believe the answers to all three your questions are "yes"
Related
I am developing a project in which I have a vendor library, say vendor.h, for the specific Arduino-compatible board I'm using which defines class HTTPClient that conflicts with an Arduino system library, HTTPClient.h, which also defines class HTTPClient.
These two classes are unrelated other than having the same name, and the vendor implementation of an HTTP client is far less capable than the Arduino system library's implementation, so I'd prefer to use the latter. But I can't omit including the former, because I need quite a bit from the vendor.h. Essentially, I have the problem posed here, but with classes rather than functions. I have the full code of both, but given that one is a system library and the other is a vendor library, I'm reluctant to fork and edit either, as that adds lots of merging work down the road if either of them are updated, so my preference would be to find a tidy solution that doesn't edit either header.
I've tried a variety of solutions posted in other SO questions:
I do not want to leave out either header, as I need vendor.h for quite a few things and need the capabilities of HTTPClient.h's client implementation
Proper namespaces in the headers would solve the problem, I would prefer to avoid editing either header
I tried wrapping the #include <HTTPClient.h> in a namespace in my main.cpp, but that caused linking errors, as it's not a header-only library, so the header & cpp weren't in the same namespace
I tried a simple wrapper as proposed for the function in the above linked SO question in which the header contained just a forward declaration of my wrapper class & the associated cpp contained the actual class definition. This gave a compiler error of error: aggregate 'HTTP::Client client' has incomplete type and cannot be defined (Code sample of this attempt below)
main.cpp:
#include <vendor.h>
#include "httpclientwrapper.h"
HTTP::Client client;
httpclientwrapper.h:
#ifndef INC_HTTPCLIENTWRAPPER_H
#define INC_HTTPCLIENTWRAPPER_H
namespace HTTP {
class Client;
}
#endif
httpclientwrapper.cpp:
#include "httpclientwrapper.h"
#include <HTTPClient.h>
namespace HTTP {
class Client : public ::HTTPClient {};
}
In that example, I can't inherit from HTTPClient in a class definition in my header, as that will reintroduce the duplicate class name to the global namespace in my main program (hence the perhaps misguided attempt to see if a forward declaration would do the trick). I suspect that I can resolve the issue by completely duplicating the class definition of HTTPClient in my wrapper class above rather than trying to use inheritance. I would then add member definitions to my wrapper cpp which pass the call to HTTPClient's members. Before I go through the trouble of rewriting (or more likely, copy/pasting) the entire HTTPClient definition from HTTPClient.h into my own wrapper, I was wondering if there was a better or more proper way to resolve the conflict?
Thanks for you help!
As a solution was never proposed, I'm posting an answer that summarizes my research and my ultimate resolution. Mostly, I encourage the use of namespaces, because proper uses of namespaces would have eliminated the conflict. However, Arduino environments try to keep things simple to lower the barrier of entry, eschewing "complicated" features of C++, so more advanced use cases will likely continue to run into issues like this. From other SO answers and forum posts (cited where I could), here are some methods for avoiding name conflicts like this:
If you can edit the source
Edit the source code to remove the conflict or add a namespace to one of both libraries. If this is an open source library, submit a pull request. This is the cleanest solution. However, if you can't push your changes back upstream (such as when one is a system library for some hardware), you may end up with merge issues down the road when the maintainer/developer updates the libraries.
If you can't edit the source
Credit for part of this: How to avoid variable/function conflicts from two libraries in C++
For libraries that are header only libraries (or all functions are inline)
(ie, they have only a .h file without a .o or .cpp)
Include the library inside a namespace. In most code, this is frowned upon as poor form, but if you're already in a situation where you are trying to cope with a library that doesn't contain itself nicely, it's a clean and simple way to contain the code in a namespace and avoid name conflicts.
main.cpp
namespace foo {
#include library.h
}
int main() {
foo::bar(1);
}
For libraries with functions
The above method will fail to link at compile time, because the declarations in the header will be inside the namespace, but the definitions of those functions are not.
Instead, create a wrapper header and implementation file. In the header, declare your namespace and functions you wish to use, but do not import the original library. In the implementation file, import your library, and use the functions inside your new namespaced functions. That way, the one conflicting library is not imported into the same place as the other.
wrapper.h
namespace foo {
int bar(int a);
}
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
int bar(int a) {
return ::bar(a);
}
}
main.cpp
#include "wrapper.h"
int main() {
foo::bar(1);
}
You could also, for the sake of consistency, wrap both libraries so they're each in their own namespace. This method does mean that you will have to put in the effort to write a wrapper for every function you plan to use. This gets more complicated, however, when you need to use classes from the library (see below).
For libraries with classes
This is an extension of the wrapper function model from above, but you will need to put in more work, and there are a few more drawbacks. You can't write a class that inherits from the library's class, as that would require importing the original library in your wrapper header prior to defining your class, so you must write a complete wrapper class. You also cannot have a private member of your class of the type from the original class that you can delegate calls to for the same reason. The attempt at using a forward declaration I described in my question also did not work, as the header file needs a complete declaration of the class to compile. This left me the below implementation, which only works in the cases of a singleton (which was my use case anyway).
The wrapper header file should almost completely duplicate the public interface of the class you want to use.
wrapper.h
namespace foo {
Class Bar() {
public:
void f(int a);
bool g(char* b, int c, bool d);
char* h();
};
}
The wrapper implementation file then creates an instance and passes the calls along.
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
::Bar obj;
void Bar::f(int a) {
return obj.f(a);
}
bool Bar::g(char* b, int c, bool d) {
return obj.g(b, c, d);
}
char* Bar::h() {
return obj.h();
}
}
The main file will interact with only a single instance of the original class, no matter how many times your wrapper class in instantiated.
main.cpp
#include "wrapper.h"
int main() {
foo::Bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
Overall, this strikes me as a flawed solution. To fully wrap this class, I think the this could be modified to add a factory class that would be fully contained inside the wrapper implementation file. This class would instantiate the original library class every time your wrapper class is instantiated, and then track these instances. In this way, your wrapper class could keep an index to its associated instance in the factory and bypass the need to have that instance as its own private member. This seemed like a significant amount of work, and I did not attempt to do so, but would look something like the code below. (This probably needs some polish and a real look at its memory usage!)
The wrapper header file adds a constructor & private member to store an instance id
wrapper.h
namespace foo {
Class Bar() {
public:
Bar();
void f(int a);
bool g(char* b, int c, bool d);
char* h();
private:
unsigned int instance;
};
}
The wrapper implementation file then adds a factory class to manage instances of the original library's class
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
class BarFactory {
public:
static unsigned int new() {
instances[count] = new ::Bar();
return count++;
}
static ::Bar* get(unsigned int i) {
return instances[i];
}
private:
BarFactory();
::Bar* instances[MAX_COUNT]
int count;
};
void Bar::Bar() {
instance = BarFactory.new();
}
void Bar::f(int a) {
return BarFactory.get(i)->f(a);
}
bool Bar::g(char* b, int c, bool d) {
return BarFactory.get(i)->g(b, c, d);
}
char* Bar::h() {
return BarFactory.get(i)->h();
}
}
The main file remains unchanged
main.cpp
#include "wrapper.h"
int main() {
foo::bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
If all of this seems like a lot of work, then you're thinking the same thing I did. I implemented the basic class wrapper, and realized it wasn't going to work for my use case. And given the hardware limitations of the Arduino, I ultimately decided that rather than add more code to be able to use the HTTPClient implementation in either library, I wrote my own HTTP implementation library in the end, and so used none of the above and saved several hundred kilobytes of memory. But I wanted to share here in case somebody else was looking to answer the same question!
I keep reading that it's bad to do so, but I don't feel those answers fully answer my specific question.
It seems like it could be really useful in some cases. I want to do something like the following:
class Example {
private:
int val;
public:
void my_function() {
#if defined (__AVX2__)
#include <function_internal_code_using_avx2.h>
#else
#include <function_internal_code_without_avx2.h>
#endif
}
};
If using #include in the middle of code is bad in this example, what would be a good practice approach for to achieve what I'm trying to do? That is, I'm trying to differentiate a member function implementation in cases where avx2 is and isn't available to be compiled.
No it is not intrinsically bad. #include was meant to allow include anywhere. It's just that it's uncommon to use it like this, and this goes against the principle of least astonishment.
The good practices that were developed around includes are all based on the assumption of an inclusion at the start of a compilation unit and in principle outside any namespace.
This is certainly why the C++ core guidelines recommend not to do it, being understood that they have normal reusable headers in mind:
SF.4: Include .h files before other declarations in a file
Reason
Minimize context dependencies and increase readability.
Additional remarks: How to solve your underlying problem
Not sure about the full context. But first of all, I wouldn't put the function body in the class definition. This would better encapsulate the implementation specific details for the class consumers, which should not need to know.
Then you could use conditional compilation in the body, or much better opt for some policy based design, using templates to configure the classes to be used at compile time.
I agree with what #Christophe said. In your case I would write the following code
Write a header commonInterface.h
#pragma once
#if defined (__AVX2__)
void commonInterface (...) {
#include <function_internal_code_using_avx2.h>
}
#else
void commonInterface (...) {
#include <function_internal_code_without_avx2.h>
}
#endif
so you hide the #if defined in the header and still have good readable code in the implementation file.
#include <commonInterface>
class Example {
private:
int val;
public:
void my_function() {
commonInterface(...);
}
};
#ifdef __AVX2__
# include <my_function_avx2.h>
#else
# include <my_function.h>
#endif
class Example {
int val;
public:
void my_function() {
# ifdef __AVX2__
my_function_avx2(this);
# else
my_function(this);
# endif
}
};
Whether it is good or bad really depends on the context.
The technique is often used if you have to write a great amount of boilerplate code. For example, the clang compiler uses it all over the place to match/make use of all possible types, identifiers, tokens, and so on. Here is an example, and here another one.
If you want to define a function differently depending on certain compile-time known parameters, it's seen cleaner to put the definitions where they belong to be.
You should not split up a definition of foo into two seperate files and choose the right one at compile time, as it increases the overhead for the programmer (which is often not just you) to understand your code.
Consider the following snippet which is, at least in my opinion, much more expressive:
// platform.hpp
constexpr static bool use_avx2 = #if defined (__AVX2__)
true;
#else
false;
#endif
// example.hpp
class Example {
private:
int val;
public:
void my_function() {
if constexpr(use_avx2) {
// code of "functional_internal_code_using_avx2.h"
}
else {
// code of "functional_internal_code_without_avx2.h"
}
};
The code can be improved further by generalizing more, adding layers of abstractions that "just define the algorithm" instead of both the algorithm and platform-specific weirdness.
Another important argument against your solution is the fact that both functional_internal_code_using_avx2.h and functional_internal_code_without_avx2.h require special attention:
They do not build without example.h and it is not obvious without opening any of the files that they require it. So, specific flags/treatment when building the project have to be added, which is difficult to maintain as soon as you use more than one such functional_internal_code-files.
I am not sure what you the bigger picture is in your case, so whatever follows should be taken with a grain of salt.
Anyway: #include COULD happen anywhere in the code, BUT you could think of it as a way of separating code / avoiding redundancy. For definitions, this is already well covered by other means. For declarations, it is the standard approach.
Now, this #includes are placed at the beginning as a courtesy to the reader who can catch up more quickly on what to expect in the code to follow, even for #ifdef guarded code.
In your case, it looks like you want a different implementation of the same functionality. The to-go approach in this case would be to link a different portion of code (containing a different implementation), rather than importing a different declaration.
Instead, if you want to really have a different signature based on your #ifdef then I would not see a more effective way than having #ifdef in the middle of the code. BUT, I would not consider this a good design choice!
I define this as bad coding for me. It makes code hard to read.
My approach would be to create a base class as an abstract interface and create specialized implementations and then create the needed class.
E.g.:
class base_functions_t
{
public:
virtual void function1() = 0;
}
class base_functions_avx2_t : public base_functions_t
{
public:
virtual void function1()
{
// code here
}
}
class base_functions_sse2_t : public base_functions_t
{
public:
virtual void function1()
{
// code here
}
}
Then you can have a pointer to your base_functions_t and instanciate different versions. E.g.:
base_functions_t *func;
if (avx2)
{
func = new base_functions_avx2_t();
}
else
{
func = new base_functions_sse2_t();
}
func->function1();
As a general rule I would say that it's best to put headers that define interfaces first in your implementation files.
There are of course also headers that don't define any interfaces. I'm thinking mainly of headers that use macro hackery and are intended to be included one or more times. This type of header typically doesn't have include guards. An example would be <cassert>. This allows you to write code something like this
#define NDEBUG 1
#include <cassert>
void foo() {
// do some stuff
assert(some_condition);
}
#undef NDEBUG
#include <cassert>
void bar() {
assert(another_condition);
}
If you only include <cassert> at the start of your file you will have no granularity for asserts in your implementation file other than all on or all off. See here for more discussion on this technique.
If you do go down the path of using conditional inclusion as per your example then I would strongly recommend that you use an editor like Eclipse or Netbeans that can do inline preprocessor expansion and visualization. Otherwise the loss of locality that inclusion brings can severely hurt readability.
Most classes appear to be separated between declaration and definition in the following form using namespace qualifier to define the class:
// test.h
class test
{
public:
void func1(void);
private:
void func2(void);
};
// test.cpp
void test::func1(void)
{
//whatever
}
void test::func2(void)
{
//whatever
}
Why don't we typically see people use the keyword class in the .cpp file? Like in the following form:
// test.cpp
class test {
void func1(void)
{
//whatever
}
void func2(void)
{
//whatever
}
};
Is it just convention to use the namespace qualifiers? Or because it make more sense when you starting implementing a class via multiple source files?
Let's view this question from another angle...
It is possible to use the same syntax for both, but it's "the other one"; the following is perfectly valid:
namespace ns
{
int foo();
}
int ns::foo() { return 0; }
Looked at like this, it's the opposite question that's interesting, "why is it common to include the word 'namespace' in .cpp files?"
There's one substantial difference between namespaces and classes that makes namespace {} necessary in so many places: namespaces are open to extension, but classes are defined entirely by their (one and only) definition.
Like with classes, you can't add anything to a namespace using the syntax above; you can't add a function bar above with only int ns::bar() { return 9; }, the only way to add names to a namespace is "from within".
And, as many have discovered, it's convenient to wrap an entire file in a namespace and not use the qualified names, even if you're not adding any names to it.
Hence the popularity of "namespace": it's a convenience enabled by the extensibility of namespaces.
Another issue is that the meaning of your "test.cpp" would depend on whether the class definition has already been seen by the compiler – without it, that's a valid and complete definition of a class with two private functions.
This kind of "action from a distance" depending on possibly very distant code is painful to work with.
It's also worth noting that namespaces were added some twenty years after "C with classes" was created, when C++ was a well established language, and changing the meaning of a construct that literally hasn't changed in decades is pretty much unthinkable.
Partularly if all it does is save a few keystrokes.
Is it at all possible to parse C++ with incomplete declarations with clang with its existing libclang API ? I.e. parse .cpp file without including all the headers, deducing declarations on the fly. so, e.g. The following text:
A B::Foo(){return stuff();}
Will detect unknown symbol A, call my callback that deducts A is a class using my magic heuristic, then call this callback the same way with B and Foo and stuff. In the end I want to be able to infer that I saw a member Foo of class B returning A, and stuff is a function.. Or something to that effect.
context: I wanna see if I can do sensible syntax highlighting and on the fly code analysis without parsing all the headers very quickly.
[EDIT] To clarify, I'm looking for very heavily restricted C++ parsing, possibly with some heuristic to lift some of the restrictions.
C++ grammar is full of context dependencies. Is Foo() a function call or a construction of a temporary of class Foo? Is Foo<Bar> stuff; a template Foo<Bar> instantiation and declaration of variable stuff, or is it weird-looking 2 calls to overloaded operator < and operator > ? It's only possible to tell in context, and context often comes from parsing the headers.
What I'm looking for is a way to plug my custom convention rules. E.g. I know that I don't overload Win32 symbols, so I can safely assume that CreateFile is always a function, and I even know its signature. I also know that all my classes start with a capital letter and are nouns, and functions are usually verbs, so I can reasonably guess that Foo and Bar are class names. In a more complex scenario, I know I don't write side-effect-free expressions like a < b > c; so I can assume that a is always a template instantiation. And so on.
So, the question is whether it's possible to use Clang API to call back every time it encounters an unknown symbol, and give it an answer using my own non-C++ heuristic. If my heuristic fails, then the parse fails, obviously. And I'm not talking about parsing Boost library :) I'm talking about very simple C++, probably without templates, restricted to some minimum that clang can handle in this case.
I know the question is fairly old, but have a look here :
LibFuzzy is a library for heuristically parsing C++ based on Clang's
Lexer. The fuzzy parser is fault-tolerant, works without knowledge of
the build system and on incomplete source files. As the parser
necessarily makes guesses, the resulting syntax tree may be partially
wrong.
It is a sub-project from clang-highlight, an (experimental?) tool which seems to be no longer developed.
I'm only interested in the fuzzy parsing part and forked it on my github page where I fixed several minor issues and made the tool autonomous (it can be compiled outside clang's source tree). Don't try to compile it with C++14 (which G++ 6's default mode), because there will be conflicts with make_unique.
According to this page, clang-format has its own fuzzy parser (and is actively developed), but the parser was (is ?) more tighly coupled to the tool.
Unless you heavily restrict the code that people are allowed to write, it is basically impossible to do a good job of parsing C++ (and hence syntax highlighting beyond keywords/regular expressions) without parsing all the headers. The pre-processor is particularly good at screwing things up for you.
There are some thoughts on the difficulties of fuzzy parsing (in the context of visual studio) here which might be of interest: http://blogs.msdn.com/b/vcblog/archive/2011/03/03/10136696.aspx
Another solution which I think will suit more the OP than fuzzy parsing.
When parsing, clang maintains Semantic information through the Sema part of the analyzer. When encountering an unknown symbol, Sema will fallback to ExternalSemaSource to get some information about this symbol. Through this, you could implement what you want.
Here is a quick example how to set up it. It is not entirely functional (I'm not doing anything in the LookupUnqualified method), you might need to do further investigations and I think it is a good start.
// Declares clang::SyntaxOnlyAction.
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <llvm/Support/CommandLine.h>
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Frontend/ASTConsumers.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Tooling/Tooling.h>
#include <clang/Rewrite/Core/Rewriter.h>
#include <llvm/Support/raw_ostream.h>
#include <clang/Sema/ExternalSemaSource.h>
#include <clang/Sema/Sema.h>
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/ParseAST.h"
#include <clang/Sema/Lookup.h>
#include <iostream>
using namespace clang;
using namespace clang::tooling;
using namespace llvm;
class ExampleVisitor : public RecursiveASTVisitor<ExampleVisitor> {
private:
ASTContext *astContext;
public:
explicit ExampleVisitor(CompilerInstance *CI, StringRef file)
: astContext(&(CI->getASTContext())) {}
virtual bool VisitVarDecl(VarDecl *d) {
std::cout << d->getNameAsString() << "#\n";
return true;
}
};
class ExampleASTConsumer : public ASTConsumer {
private:
ExampleVisitor visitor;
public:
explicit ExampleASTConsumer(CompilerInstance *CI, StringRef file)
: visitor(CI, file) {}
virtual void HandleTranslationUnit(ASTContext &Context) {
// de cette façon, on applique le visiteur sur l'ensemble de la translation
// unit
visitor.TraverseDecl(Context.getTranslationUnitDecl());
}
};
class DynamicIDHandler : public clang::ExternalSemaSource {
public:
DynamicIDHandler(clang::Sema *Sema)
: m_Sema(Sema), m_Context(Sema->getASTContext()) {}
~DynamicIDHandler() = default;
/// \brief Provides last resort lookup for failed unqualified lookups
///
/// If there is failed lookup, tell sema to create an artificial declaration
/// which is of dependent type. So the lookup result is marked as dependent
/// and the diagnostics are suppressed. After that is's an interpreter's
/// responsibility to fix all these fake declarations and lookups.
/// It is done by the DynamicExprTransformer.
///
/// #param[out] R The recovered symbol.
/// #param[in] S The scope in which the lookup failed.
virtual bool LookupUnqualified(clang::LookupResult &R, clang::Scope *S) {
DeclarationName Name = R.getLookupName();
std::cout << Name.getAsString() << "\n";
// IdentifierInfo *II = Name.getAsIdentifierInfo();
// SourceLocation Loc = R.getNameLoc();
// VarDecl *Result =
// // VarDecl::Create(m_Context, R.getSema().getFunctionLevelDeclContext(),
// // Loc, Loc, II, m_Context.DependentTy,
// // /*TypeSourceInfo*/ 0, SC_None, SC_None);
// if (Result) {
// R.addDecl(Result);
// // Say that we can handle the situation. Clang should try to recover
// return true;
// } else{
// return false;
// }
return false;
}
private:
clang::Sema *m_Sema;
clang::ASTContext &m_Context;
};
// *****************************************************************************/
LangOptions getFormattingLangOpts(bool Cpp03 = false) {
LangOptions LangOpts;
LangOpts.CPlusPlus = 1;
LangOpts.CPlusPlus11 = Cpp03 ? 0 : 1;
LangOpts.CPlusPlus14 = Cpp03 ? 0 : 1;
LangOpts.LineComment = 1;
LangOpts.Bool = 1;
LangOpts.ObjC1 = 1;
LangOpts.ObjC2 = 1;
return LangOpts;
}
int main() {
using clang::CompilerInstance;
using clang::TargetOptions;
using clang::TargetInfo;
using clang::FileEntry;
using clang::Token;
using clang::ASTContext;
using clang::ASTConsumer;
using clang::Parser;
using clang::DiagnosticOptions;
using clang::TextDiagnosticPrinter;
CompilerInstance ci;
ci.getLangOpts() = getFormattingLangOpts(false);
DiagnosticOptions diagnosticOptions;
ci.createDiagnostics();
std::shared_ptr<clang::TargetOptions> pto = std::make_shared<clang::TargetOptions>();
pto->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto);
ci.setTarget(pti);
ci.createFileManager();
ci.createSourceManager(ci.getFileManager());
ci.createPreprocessor(clang::TU_Complete);
ci.getPreprocessorOpts().UsePredefines = false;
ci.createASTContext();
ci.setASTConsumer(
llvm::make_unique<ExampleASTConsumer>(&ci, "../src/test.cpp"));
ci.createSema(TU_Complete, nullptr);
auto &sema = ci.getSema();
sema.Initialize();
DynamicIDHandler handler(&sema);
sema.addExternalSource(&handler);
const FileEntry *pFile = ci.getFileManager().getFile("../src/test.cpp");
ci.getSourceManager().setMainFileID(ci.getSourceManager().createFileID(
pFile, clang::SourceLocation(), clang::SrcMgr::C_User));
ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(),
&ci.getPreprocessor());
clang::ParseAST(sema,true,false);
ci.getDiagnosticClient().EndSourceFile();
return 0;
}
The idea and the DynamicIDHandler class are from cling project where unknown symbols are variable (hence the comments and the code).
OP doesn't want "fuzzy parsing". What he wants is full context-free parsing of the C++ source code, without any requirement for name and type resolution.
He plans to make educated guesses about the types based on the result of the parse.
Clang proper tangles parsing and name/type resolution, which means it must have all that background type information available when it parses. Other answers suggest a LibFuzzy that produces incorrect parse trees, and some fuzzy parser for clang-format about which I know nothing. If one insists on producing a classic AST, none of these solutions will produce the "right" tree in the face of ambiguous parses.
Our DMS Software Reengineering Toolkit with its C++ front end can parse C++ source without the type information, and produces accurate "ASTs"; these are actually abstract syntax dags where forks in trees represent different possible interpretations of the source code according to a language-precise grammar (ambiguous (sub)parses).
What Clang tries to do is avoid producing these multiple sub-parses by using type information as it parses. What DMS does is produce the ambiguous parses, and in (optional) post-parsing (attribute-grammar-evaluation) pass, collect symbol table information and eliminate the sub-parses which are inconsistent with the types; for well-formed programs, this produces a plain AST with no ambiguities left.
If OP wants to make heuristic guesses about the type information, he will need to know these possible interpretations. If they are eliminated in advance, he cannot straightforwardly guess what types might be needed. An interesting possibility is the idea of modifying the attribute grammar (provided in source form as part of the DMS's C++ front end), which already knows all of C++ type rules, to do this with partial information. That would be an enormous head start over building the heuristic analyzer from scratch, given that it has to know about 600 pages of arcane name and type resolution rules from the standard.
You can see examples of the (dag) produced by DMS's parser.
I've written a small program that utilizes the Fast Light Toolkit and for some reason a compiler error is generated when trying to access the functions in the cmath header.
Such as error ::acos has not been declared.
This goes on for pretty much every function it tries to use in the header. What could I be missing?
The header files I have included are
Simple_window.h
Graph.h
both of which are part of the FLTK.
The code is this:
#include "Simple_window.h" // get access to our windows library
#include "Graph.h" // get access to graphics library facilities
int main()
{
using namespace Graph_lib; // our graphics facilities are in Graph_lib
Point tl(100,100); // to become top left corner of window
Simple_window win(tl,600,400,"Canvas"); // make a simple window
Polygon poly; // make a shape (a polygon)
poly.add(Point(300,200)); // add a point
poly.add(Point(350,100)); // add another point
poly.add(Point(400,200)); // add a third point
poly.set_color(Color::red); // adjust properties of poly
win.attach(poly); // connect poly to the window
win.wait_for_button(); // give control to display engine
}
Edit: Here is example code of when the compiler error is generated. This is inside the cmath header.
namespace std
{
// Forward declaration of a helper function. This really should be
// an `exported' forward declaration.
template<typename _Tp> _Tp __cmath_power(_Tp, unsigned int);
inline double
abs(double __x)
{ return __builtin_fabs(__x); }
inline float
abs(float __x)
{ return __builtin_fabsf(__x); }
inline long double
abs(long double __x)
{ return __builtin_fabsl(__x); }
using ::acos; //ERROR HERE
inline float
acos(float __x)
{ return __builtin_acosf(__x); }
inline long double
acos(long double __x)
{ return __builtin_acosl(__x); }
template<typename _Tp>
inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type
acos(_Tp __x)
{
return __builtin_acos(__x);
}
Edit: Code::blocks is saving files as C files....
When you include the C++ version (<cXXXX>) of standard C libraries all the symbols are defined within the std namespace. In C++ you do not need to link against the math library (-lm is not required)
#include <cmath>
#include <iostream>
int main()
{
std::cout << std::fabs( -10.5 ) << std::endl;
}
I had this problem - it was driving me crazy but I tracked down the cause, and it was a little different than what I've seen reported on this issue.
In this case, the general cmath header (or math.h - the error and solution occur in C++ or C) had architectural environment switches to include architecture specific math subheaders. The architecture switch (environment variable) hadn't been defined, so it was punting and not actually including the headers that truly defined the math functions.
So there was indeed a single math.h or cmath.h, and it was included, but that wasn't enough to get the math functions. In my case, rather than define the architectural variable, I instead found the location of the correct sub math headers and added them to my compile path. Then the project worked!
This seems to be an issue that comes up a lot when porting Linux projects to OS-X. I'd imagine it might occur anytime a project was moved betwee platforms such that the standard library headers are arranged differently.
Jeff
Since your code as shown above does not directly call acos(), there is arguably a bug in one of the headers that you do use. It appears there is some (inline) code in one of the headers that invokes the acos() function without ensuring that the function is properly declared. This might be a macro or an inline function.
The best fix is to ensure that the headers are self-contained - change the headers.
If that is not possible, the hackaround is to include the appropriate header (#include <cmath>, probably) in the source code.
The program is able to access the cmath header, the error is in the cmath header itself.
In that case, you will probably need to provide a global acos() function (declaration at least, possibly definition too) that calls onto std::acos():
double acos(double x) { return std::acos(x); }
Just make sure this is not inside any namespace - not even the anonymous one. (Check compiled with G++ 4.0.1 on MacOS X, with '#include <cmath>' preceding it. Given that you have a problematic <cmath> header, you might need to get fancy:
extern double std::acos(double);
double acos(double x) { return std::acos(x); }
#include <cmath>
This is pretty nasty - are you sure there isn't a bug-fixed version of your compiler?
Is there any chance that you've got '#include <cmath>' inside a namespace?
It also happens in Visual C++, in programs that do not sapuse to use cmath.
I found that the problem is that I used main.c file instead of main.cpp file.
The error is most likely to be in your code and not in cmath... unless you changed something in cmath. Could you copy the errors and tell us what is the application you are using to program?